include/mscvpdb.h: Use flexible array members for the rest of structures.
[wine.git] / dlls / d3d9 / tests / visual.c
blob724d9ef1e39d0c8afddebcb8511e3d664a8f83e2
1 /*
2 * Copyright 2005, 2007-2008 Henri Verbeet
3 * Copyright (C) 2007-2013 Stefan Dösinger(for CodeWeavers)
4 * Copyright (C) 2008 Jason Green(for TransGaming)
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 /* This test framework allows limited testing of rendering results. Things are rendered, shown on
22 * the framebuffer, read back from there and compared to expected colors.
24 * However, neither d3d nor opengl is guaranteed to be pixel exact, and thus the capability of this test
25 * is rather limited. As a general guideline for adding tests, do not rely on corner pixels. Draw a big enough
26 * area which shows specific behavior(like a quad on the whole screen), and try to get resulting colors with
27 * all bits set or unset in all channels(like pure red, green, blue, white, black). Hopefully everything that
28 * causes visible results in games can be tested in a way that does not depend on pixel exactness
31 #include <stdbool.h>
32 #include <stdint.h>
33 #include <limits.h>
34 #include <math.h>
36 #define COBJMACROS
37 #include <d3d9.h>
38 #include "utils.h"
40 struct vec2
42 float x, y;
45 struct vec3
47 float x, y, z;
50 struct vec4
52 float x, y, z, w;
55 struct d3d9_test_context
57 HWND window;
58 IDirect3D9 *d3d;
59 IDirect3DDevice9 *device;
60 IDirect3DSurface9 *backbuffer;
63 static HWND create_window(void)
65 HWND hwnd;
66 RECT rect;
68 SetRect(&rect, 0, 0, 640, 480);
69 AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW | WS_VISIBLE, FALSE);
70 hwnd = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
71 0, 0, rect.right - rect.left, rect.bottom - rect.top, 0, 0, 0, 0);
72 return hwnd;
75 static BOOL compare_uint(unsigned int x, unsigned int y, unsigned int max_diff)
77 unsigned int diff = x > y ? x - y : y - x;
79 return diff <= max_diff;
82 static BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
84 return compare_uint(c1 & 0xff, c2 & 0xff, max_diff)
85 && compare_uint((c1 >> 8) & 0xff, (c2 >> 8) & 0xff, max_diff)
86 && compare_uint((c1 >> 16) & 0xff, (c2 >> 16) & 0xff, max_diff)
87 && compare_uint((c1 >> 24) & 0xff, (c2 >> 24) & 0xff, max_diff);
90 static BOOL compare_float(float f, float g, unsigned int ulps)
92 int x = *(int *)&f;
93 int y = *(int *)&g;
95 if (x < 0)
96 x = INT_MIN - x;
97 if (y < 0)
98 y = INT_MIN - y;
100 return compare_uint(x, y, ulps);
103 static BOOL compare_vec4(const struct vec4 *vec, float x, float y, float z, float w, unsigned int ulps)
105 return compare_float(vec->x, x, ulps)
106 && compare_float(vec->y, y, ulps)
107 && compare_float(vec->z, z, ulps)
108 && compare_float(vec->w, w, ulps);
111 static uint32_t float_to_int(float f)
113 union
115 uint32_t u;
116 float f;
117 } u;
119 u.f = f;
120 return u.u;
123 static BOOL adapter_is_warp(const D3DADAPTER_IDENTIFIER9 *identifier)
125 return !strcmp(identifier->Driver, "d3d10warp.dll");
128 static BOOL adapter_is_vendor(const D3DADAPTER_IDENTIFIER9 *identifier, DWORD vendor)
130 return identifier->VendorId == vendor;
133 static BOOL adapter_is_amd(const D3DADAPTER_IDENTIFIER9 *identifier)
135 return adapter_is_vendor(identifier, 0x1002);
138 static BOOL device_is_d3d10(IDirect3DDevice9 *device)
140 IDirect3D9 *d3d;
141 HRESULT hr;
143 IDirect3DDevice9_GetDirect3D(device, &d3d);
144 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
145 D3DUSAGE_QUERY_FILTER, D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F);
146 IDirect3D9_Release(d3d);
148 return SUCCEEDED(hr);
151 /* Locks a given surface and returns the color at (x,y). It's the caller's
152 * responsibility to only pass in lockable surfaces and valid x,y coordinates */
153 static DWORD getPixelColorFromSurface(IDirect3DSurface9 *surface, UINT x, UINT y)
155 DWORD color;
156 HRESULT hr;
157 D3DSURFACE_DESC desc;
158 RECT rectToLock = {x, y, x+1, y+1};
159 D3DLOCKED_RECT lockedRect;
161 hr = IDirect3DSurface9_GetDesc(surface, &desc);
162 ok(hr == S_OK, "Got hr %#lx.\n", hr);
164 hr = IDirect3DSurface9_LockRect(surface, &lockedRect, &rectToLock, D3DLOCK_READONLY);
165 ok(hr == S_OK, "Got hr %#lx.\n", hr);
167 switch(desc.Format) {
168 case D3DFMT_A8R8G8B8:
170 color = ((DWORD *) lockedRect.pBits)[0];
171 break;
173 default:
174 trace("Error: unknown surface format: %d\n", desc.Format);
175 color = 0xdeadbeef;
176 break;
178 hr = IDirect3DSurface9_UnlockRect(surface);
179 ok(hr == S_OK, "Got hr %#lx.\n", hr);
180 return color;
183 struct surface_readback
185 IDirect3DSurface9 *surface;
186 D3DLOCKED_RECT locked_rect;
189 static void get_rt_readback(IDirect3DSurface9 *surface, struct surface_readback *rb)
191 IDirect3DDevice9 *device;
192 D3DSURFACE_DESC desc;
193 HRESULT hr;
195 memset(rb, 0, sizeof(*rb));
196 hr = IDirect3DSurface9_GetDevice(surface, &device);
197 ok(SUCCEEDED(hr), "Failed to get device, hr %#lx.\n", hr);
198 hr = IDirect3DSurface9_GetDesc(surface, &desc);
199 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#lx.\n", hr);
200 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, desc.Width, desc.Height,
201 desc.Format, D3DPOOL_SYSTEMMEM, &rb->surface, NULL);
202 if (FAILED(hr) || !rb->surface)
204 trace("Can't create an offscreen plain surface to read the render target data, hr %#lx.\n", hr);
205 goto error;
208 hr = IDirect3DDevice9_GetRenderTargetData(device, surface, rb->surface);
209 if (FAILED(hr))
211 trace("Can't read the render target data, hr %#lx.\n", hr);
212 goto error;
215 hr = IDirect3DSurface9_LockRect(rb->surface, &rb->locked_rect, NULL, D3DLOCK_READONLY);
216 if (FAILED(hr))
218 trace("Can't lock the offscreen surface, hr %#lx.\n", hr);
219 goto error;
221 IDirect3DDevice9_Release(device);
223 return;
225 error:
226 if (rb->surface)
227 IDirect3DSurface9_Release(rb->surface);
228 rb->surface = NULL;
229 IDirect3DDevice9_Release(device);
232 static DWORD get_readback_color(struct surface_readback *rb, unsigned int x, unsigned int y)
234 return rb->locked_rect.pBits
235 ? ((DWORD *)rb->locked_rect.pBits)[y * rb->locked_rect.Pitch / sizeof(DWORD) + x] : 0xdeadbeef;
238 static void release_surface_readback(struct surface_readback *rb)
240 HRESULT hr;
242 if (!rb->surface)
243 return;
244 if (rb->locked_rect.pBits && FAILED(hr = IDirect3DSurface9_UnlockRect(rb->surface)))
245 trace("Can't unlock the offscreen surface, hr %#lx.\n", hr);
246 IDirect3DSurface9_Release(rb->surface);
249 static DWORD getPixelColor(IDirect3DDevice9 *device, UINT x, UINT y)
251 DWORD ret;
252 IDirect3DSurface9 *rt;
253 struct surface_readback rb;
254 HRESULT hr;
256 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &rt);
257 ok(hr == S_OK, "Got hr %#lx.\n", hr);
259 get_rt_readback(rt, &rb);
260 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
261 * really important for these tests
263 ret = get_readback_color(&rb, x, y) & 0x00ffffff;
264 release_surface_readback(&rb);
266 IDirect3DSurface9_Release(rt);
267 return ret;
270 static D3DCOLOR check_expected_rt_color(unsigned int line, IDirect3DSurface9 *rt, D3DCOLOR expected_color)
272 unsigned int color = 0xdeadbeef;
273 struct surface_readback rb;
274 D3DSURFACE_DESC desc;
275 unsigned int x, y;
276 HRESULT hr;
278 hr = IDirect3DSurface9_GetDesc(rt, &desc);
279 ok_(__FILE__, line)(hr == S_OK, "Failed to get surface desc, hr %#lx.\n", hr);
281 get_rt_readback(rt, &rb);
282 for (y = 0; y < desc.Height; ++y)
284 for (x = 0; x < desc.Width; ++x)
286 color = get_readback_color(&rb, x, y) & 0x00ffffff;
287 if (color != expected_color)
288 break;
290 if (color != expected_color)
291 break;
293 release_surface_readback(&rb);
294 return color;
297 #define check_rt_color(a, b) check_rt_color_(__LINE__, a, b, false, 0, false)
298 #define check_rt_color_broken(a, b, c, d) check_rt_color_(__LINE__, a, b, false, c, d)
299 #define check_rt_color_todo(a, b) check_rt_color_(__LINE__, a, b, true, 0, false)
300 #define check_rt_color_todo_if(a, b, c) check_rt_color_(__LINE__, a, b, c, 0, false)
301 static void check_rt_color_(unsigned int line, IDirect3DSurface9 *rt, D3DCOLOR expected_color, bool todo,
302 D3DCOLOR broken_color, bool is_broken)
304 unsigned int color = check_expected_rt_color(line, rt, expected_color);
306 todo_wine_if (todo)
307 ok_(__FILE__, line)(color == expected_color || broken(is_broken && color == broken_color),
308 "Got unexpected color 0x%08x.\n", color);
311 static IDirect3DDevice9 *create_device(IDirect3D9 *d3d, HWND device_window, HWND focus_window, BOOL windowed)
313 D3DPRESENT_PARAMETERS present_parameters = {0};
314 IDirect3DDevice9 *device;
316 present_parameters.Windowed = windowed;
317 present_parameters.hDeviceWindow = device_window;
318 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
319 present_parameters.BackBufferWidth = 640;
320 present_parameters.BackBufferHeight = 480;
321 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
322 present_parameters.EnableAutoDepthStencil = TRUE;
323 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
325 if (SUCCEEDED(IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
326 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device)))
327 return device;
329 return NULL;
332 static void cleanup_device(IDirect3DDevice9 *device)
334 if (device)
336 D3DPRESENT_PARAMETERS present_parameters;
337 IDirect3DSwapChain9 *swapchain;
338 ULONG ref;
340 IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
341 IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
342 IDirect3DSwapChain9_Release(swapchain);
343 ref = IDirect3DDevice9_Release(device);
344 ok(!ref, "Unexpected refcount %lu.\n", ref);
345 DestroyWindow(present_parameters.hDeviceWindow);
349 static bool init_test_context(struct d3d9_test_context *context)
351 HRESULT hr;
353 memset(context, 0, sizeof(*context));
355 context->window = create_window();
356 context->d3d = Direct3DCreate9(D3D_SDK_VERSION);
357 ok(!!context->d3d, "Failed to create a D3D object.\n");
358 if (!(context->device = create_device(context->d3d, context->window, context->window, TRUE)))
360 skip("Failed to create a D3D device.\n");
361 IDirect3D9_Release(context->d3d);
362 DestroyWindow(context->window);
363 return false;
366 hr = IDirect3DDevice9_GetRenderTarget(context->device, 0, &context->backbuffer);
367 ok(hr == S_OK, "Failed to get backbuffer, hr %#lx.\n", hr);
369 return true;
372 #define release_test_context(a) release_test_context_(__LINE__, a)
373 static void release_test_context_(unsigned int line, struct d3d9_test_context *context)
375 ULONG refcount;
377 IDirect3DSurface9_Release(context->backbuffer);
378 refcount = IDirect3DDevice9_Release(context->device);
379 ok(!refcount, "Device has %lu references left.\n", refcount);
380 refcount = IDirect3D9_Release(context->d3d);
381 ok(!refcount, "D3D object has %lu references left.\n", refcount);
382 DestroyWindow(context->window);
385 static void draw_textured_quad(struct d3d9_test_context *context, IDirect3DTexture9 *texture)
387 IDirect3DDevice9 *device = context->device;
388 HRESULT hr;
390 static const struct
392 struct vec3 position;
393 struct vec2 texcoord;
395 quad[] =
397 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f}},
398 {{-1.0f, 1.0f, 0.0f}, {0.0f, 1.0f}},
399 {{ 1.0f, -1.0f, 0.0f}, {1.0f, 0.0f}},
400 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 1.0f}},
403 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
404 ok(hr == S_OK, "Got hr %#lx.\n", hr);
405 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
406 ok(hr == S_OK, "Got hr %#lx.\n", hr);
407 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
408 ok(hr == S_OK, "Got hr %#lx.\n", hr);
409 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
410 ok(hr == S_OK, "Got hr %#lx.\n", hr);
411 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
412 ok(hr == S_OK, "Got hr %#lx.\n", hr);
413 hr = IDirect3DDevice9_BeginScene(device);
414 ok(hr == S_OK, "Got hr %#lx.\n", hr);
415 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad, sizeof(*quad));
416 ok(hr == S_OK, "Got hr %#lx.\n", hr);
417 hr = IDirect3DDevice9_EndScene(device);
418 ok(hr == S_OK, "Got hr %#lx.\n", hr);
421 static HRESULT reset_device(struct d3d9_test_context *context)
423 D3DPRESENT_PARAMETERS present_parameters = {0};
424 HRESULT hr;
426 IDirect3DSurface9_Release(context->backbuffer);
428 present_parameters.BackBufferWidth = 640;
429 present_parameters.BackBufferHeight = 480;
430 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
431 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
432 present_parameters.hDeviceWindow = context->window;
433 present_parameters.Windowed = TRUE;
434 present_parameters.EnableAutoDepthStencil = TRUE;
435 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
436 hr = IDirect3DDevice9_Reset(context->device, &present_parameters);
438 if (SUCCEEDED(hr))
439 IDirect3DDevice9_GetRenderTarget(context->device, 0, &context->backbuffer);
441 return hr;
444 static void test_sanity(void)
446 IDirect3DDevice9 *device;
447 unsigned int color;
448 IDirect3D9 *d3d;
449 ULONG refcount;
450 HWND window;
451 HRESULT hr;
453 window = create_window();
454 d3d = Direct3DCreate9(D3D_SDK_VERSION);
455 ok(!!d3d, "Failed to create a D3D object.\n");
456 if (!(device = create_device(d3d, window, window, TRUE)))
458 skip("Failed to create a D3D device, skipping tests.\n");
459 goto done;
462 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
463 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
464 color = getPixelColor(device, 1, 1);
465 ok(color == 0x00ff0000, "Got unexpected color 0x%08x.\n", color);
467 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
468 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
470 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
471 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
472 color = getPixelColor(device, 639, 479);
473 ok(color == 0x0000ddee, "Got unexpected color 0x%08x.\n", color);
475 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
476 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
478 refcount = IDirect3DDevice9_Release(device);
479 ok(!refcount, "Device has %lu references left.\n", refcount);
480 done:
481 IDirect3D9_Release(d3d);
482 DestroyWindow(window);
485 static void lighting_test(void)
487 DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
488 DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
489 IDirect3DDevice9 *device;
490 D3DMATERIAL9 material;
491 unsigned int color, i;
492 IDirect3D9 *d3d;
493 ULONG refcount;
494 HWND window;
495 HRESULT hr;
497 static const D3DMATRIX mat =
499 1.0f, 0.0f, 0.0f, 0.0f,
500 0.0f, 1.0f, 0.0f, 0.0f,
501 0.0f, 0.0f, 1.0f, 0.0f,
502 0.0f, 0.0f, 0.0f, 1.0f,
503 }}},
504 mat_singular =
506 1.0f, 0.0f, 1.0f, 0.0f,
507 0.0f, 1.0f, 0.0f, 0.0f,
508 1.0f, 0.0f, 1.0f, 0.0f,
509 0.0f, 0.0f, 0.5f, 1.0f,
510 }}},
511 mat_transf =
513 0.0f, 0.0f, 1.0f, 0.0f,
514 0.0f, 1.0f, 0.0f, 0.0f,
515 -1.0f, 0.0f, 0.0f, 0.0f,
516 10.f, 10.0f, 10.0f, 1.0f,
517 }}},
518 mat_nonaffine =
520 1.0f, 0.0f, 0.0f, 0.0f,
521 0.0f, 1.0f, 0.0f, 0.0f,
522 0.0f, 0.0f, 1.0f, -1.0f,
523 10.f, 10.0f, 10.0f, 0.0f,
524 }}};
525 static const struct
527 struct vec3 position;
528 DWORD diffuse;
530 unlitquad[] =
532 {{-1.0f, -1.0f, 0.1f}, 0xffff0000},
533 {{-1.0f, 0.0f, 0.1f}, 0xffff0000},
534 {{ 0.0f, 0.0f, 0.1f}, 0xffff0000},
535 {{ 0.0f, -1.0f, 0.1f}, 0xffff0000},
537 litquad[] =
539 {{-1.0f, 0.0f, 0.1f}, 0xff00ff00},
540 {{-1.0f, 1.0f, 0.1f}, 0xff00ff00},
541 {{ 0.0f, 1.0f, 0.1f}, 0xff00ff00},
542 {{ 0.0f, 0.0f, 0.1f}, 0xff00ff00},
544 lighting_test[] =
546 {{-1.0f, -1.0f, 0.1f}, 0x8000ff00},
547 {{ 1.0f, -1.0f, 0.1f}, 0x80000000},
548 {{-1.0f, 1.0f, 0.1f}, 0x8000ff00},
549 {{ 1.0f, 1.0f, 0.1f}, 0x80000000},
551 static const struct
553 struct vec3 position;
554 struct vec3 normal;
555 DWORD diffuse;
557 unlitnquad[] =
559 {{0.0f, -1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
560 {{0.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
561 {{1.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
562 {{1.0f, -1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
564 litnquad[] =
566 {{0.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
567 {{0.0f, 1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
568 {{1.0f, 1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
569 {{1.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
571 nquad[] =
573 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
574 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
575 {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
576 {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
578 rotatedquad[] =
580 {{-10.0f, -11.0f, 11.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
581 {{-10.0f, -9.0f, 11.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
582 {{-10.0f, -9.0f, 9.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
583 {{-10.0f, -11.0f, 9.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
585 translatedquad[] =
587 {{-11.0f, -11.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
588 {{-11.0f, -9.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
589 {{ -9.0f, -9.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
590 {{ -9.0f, -11.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
592 static const WORD indices[] = {0, 1, 2, 2, 3, 0};
593 static const struct
595 const D3DMATRIX *world_matrix;
596 const void *quad;
597 unsigned int size;
598 DWORD expected;
599 const char *message;
601 tests[] =
603 {&mat, nquad, sizeof(nquad[0]), 0x000000ff, "Lit quad with light"},
604 {&mat_singular, nquad, sizeof(nquad[0]), 0x000000ff, "Lit quad with singular world matrix"},
605 {&mat_transf, rotatedquad, sizeof(rotatedquad[0]), 0x000000ff, "Lit quad with transformation matrix"},
606 {&mat_nonaffine, translatedquad, sizeof(translatedquad[0]), 0x00000000, "Lit quad with non-affine matrix"},
609 window = create_window();
610 d3d = Direct3DCreate9(D3D_SDK_VERSION);
611 ok(!!d3d, "Failed to create a D3D object.\n");
612 if (!(device = create_device(d3d, window, window, TRUE)))
614 skip("Failed to create a D3D device, skipping tests.\n");
615 goto done;
618 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
619 ok(hr == S_OK, "Got hr %#lx.\n", hr);
621 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), &mat);
622 ok(hr == S_OK, "Got hr %#lx.\n", hr);
623 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &mat);
624 ok(hr == S_OK, "Got hr %#lx.\n", hr);
625 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &mat);
626 ok(hr == S_OK, "Got hr %#lx.\n", hr);
627 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
628 ok(hr == S_OK, "Got hr %#lx.\n", hr);
629 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
630 ok(hr == S_OK, "Got hr %#lx.\n", hr);
631 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
632 ok(hr == S_OK, "Got hr %#lx.\n", hr);
633 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
634 ok(hr == S_OK, "Got hr %#lx.\n", hr);
635 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
636 ok(hr == S_OK, "Got hr %#lx.\n", hr);
638 hr = IDirect3DDevice9_SetFVF(device, fvf);
639 ok(hr == S_OK, "Got hr %#lx.\n", hr);
641 hr = IDirect3DDevice9_BeginScene(device);
642 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
644 /* No lights are defined... That means, lit vertices should be entirely black */
645 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
646 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
647 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
648 2, indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
649 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
651 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
652 ok(SUCCEEDED(hr), "Failed to enable lighting, hr %#lx.\n", hr);
653 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
654 2, indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
655 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
657 hr = IDirect3DDevice9_SetFVF(device, nfvf);
658 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
660 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
661 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
662 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
663 2, indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
664 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
666 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
667 ok(SUCCEEDED(hr), "Failed to enable lighting, hr %#lx.\n", hr);
668 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
669 2, indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
670 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
672 hr = IDirect3DDevice9_EndScene(device);
673 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
675 color = getPixelColor(device, 160, 360); /* Lower left quad - unlit without normals */
676 ok(color == 0x00ff0000, "Unlit quad without normals has color 0x%08x, expected 0x00ff0000.\n", color);
677 color = getPixelColor(device, 160, 120); /* Upper left quad - lit without normals */
678 ok(color == 0x00000000, "Lit quad without normals has color 0x%08x, expected 0x00000000.\n", color);
679 color = getPixelColor(device, 480, 360); /* Lower left quad - unlit with normals */
680 ok(color == 0x000000ff, "Unlit quad with normals has color 0x%08x, expected 0x000000ff.\n", color);
681 color = getPixelColor(device, 480, 120); /* Upper left quad - lit with normals */
682 ok(color == 0x00000000, "Lit quad with normals has color 0x%08x, expected 0x00000000.\n", color);
684 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
686 hr = IDirect3DDevice9_LightEnable(device, 0, TRUE);
687 ok(SUCCEEDED(hr), "Failed to enable light 0, hr %#lx.\n", hr);
689 for (i = 0; i < ARRAY_SIZE(tests); ++i)
691 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, tests[i].world_matrix);
692 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#lx.\n", hr);
694 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
695 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
697 hr = IDirect3DDevice9_BeginScene(device);
698 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
700 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
701 2, indices, D3DFMT_INDEX16, tests[i].quad, tests[i].size);
702 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
704 hr = IDirect3DDevice9_EndScene(device);
705 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
707 color = getPixelColor(device, 320, 240);
708 ok(color == tests[i].expected, "%s has color 0x%08x.\n", tests[i].message, color);
711 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &mat);
712 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#lx.\n", hr);
713 hr = IDirect3DDevice9_LightEnable(device, 0, FALSE);
714 ok(SUCCEEDED(hr), "Failed to disable light 0, hr %#lx.\n", hr);
716 memset(&material, 0, sizeof(material));
717 material.Diffuse.r = 0.0;
718 material.Diffuse.g = 0.0;
719 material.Diffuse.b = 0.0;
720 material.Diffuse.a = 1.0;
721 material.Ambient.r = 0.0;
722 material.Ambient.g = 0.0;
723 material.Ambient.b = 0.0;
724 material.Ambient.a = 0.0;
725 material.Specular.r = 0.0;
726 material.Specular.g = 0.0;
727 material.Specular.b = 0.0;
728 material.Specular.a = 0.0;
729 material.Emissive.r = 0.0;
730 material.Emissive.g = 0.0;
731 material.Emissive.b = 0.0;
732 material.Emissive.a = 0.0;
733 material.Power = 0.0;
734 hr = IDirect3DDevice9_SetMaterial(device, &material);
735 ok(hr == S_OK, "Got hr %#lx.\n", hr);
737 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
738 ok(hr == S_OK, "Got hr %#lx.\n", hr);
739 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
740 ok(hr == S_OK, "Got hr %#lx.\n", hr);
742 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
743 ok(hr == S_OK, "Got hr %#lx.\n", hr);
744 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
745 ok(hr == S_OK, "Got hr %#lx.\n", hr);
747 hr = IDirect3DDevice9_BeginScene(device);
748 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
750 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
751 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
752 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, lighting_test, sizeof(lighting_test[0]));
753 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
755 hr = IDirect3DDevice9_EndScene(device);
756 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
758 color = getPixelColor(device, 320, 240);
759 ok(color == 0x00ffffff, "Lit vertex alpha test returned color %08x, expected 0x00ffffff\n", color);
760 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
762 refcount = IDirect3DDevice9_Release(device);
763 ok(!refcount, "Device has %lu references left.\n", refcount);
764 done:
765 IDirect3D9_Release(d3d);
766 DestroyWindow(window);
769 static void test_specular_lighting(void)
771 static const unsigned int vertices_side = 5;
772 const unsigned int indices_count = (vertices_side - 1) * (vertices_side - 1) * 2 * 3;
773 static const DWORD fvf = D3DFVF_XYZ | D3DFVF_NORMAL;
774 static const D3DMATRIX mat =
776 1.0f, 0.0f, 0.0f, 0.0f,
777 0.0f, 1.0f, 0.0f, 0.0f,
778 0.0f, 0.0f, 1.0f, 0.0f,
779 0.0f, 0.0f, 0.0f, 1.0f,
780 }}};
781 static const D3DLIGHT9 directional =
783 D3DLIGHT_DIRECTIONAL,
784 {0.0f, 0.0f, 0.0f, 0.0f},
785 {1.0f, 1.0f, 1.0f, 0.0f},
786 {0.0f, 0.0f, 0.0f, 0.0f},
787 {0.0f, 0.0f, 0.0f},
788 {0.0f, 0.0f, 1.0f},
790 point =
792 D3DLIGHT_POINT,
793 {0.0f, 0.0f, 0.0f, 0.0f},
794 {1.0f, 1.0f, 1.0f, 0.0f},
795 {0.0f, 0.0f, 0.0f, 0.0f},
796 {0.0f, 0.0f, 0.0f},
797 {0.0f, 0.0f, 0.0f},
798 100.0f,
799 0.0f,
800 0.0f, 0.0f, 1.0f,
802 spot =
804 D3DLIGHT_SPOT,
805 {0.0f, 0.0f, 0.0f, 0.0f},
806 {1.0f, 1.0f, 1.0f, 0.0f},
807 {0.0f, 0.0f, 0.0f, 0.0f},
808 {0.0f, 0.0f, 0.0f},
809 {0.0f, 0.0f, 1.0f},
810 100.0f,
811 1.0f,
812 0.0f, 0.0f, 1.0f,
813 M_PI / 12.0f, M_PI / 3.0f
815 /* The chosen range value makes the test fail when using a manhattan
816 * distance metric vs the correct euclidean distance. */
817 point_range =
819 D3DLIGHT_POINT,
820 {0.0f, 0.0f, 0.0f, 0.0f},
821 {1.0f, 1.0f, 1.0f, 0.0f},
822 {0.0f, 0.0f, 0.0f, 0.0f},
823 {0.0f, 0.0f, 0.0f},
824 {0.0f, 0.0f, 0.0f},
825 1.2f,
826 0.0f,
827 0.0f, 0.0f, 1.0f,
829 point_side =
831 D3DLIGHT_POINT,
832 {0.0f, 0.0f, 0.0f, 0.0f},
833 {1.0f, 1.0f, 1.0f, 0.0f},
834 {0.0f, 0.0f, 0.0f, 0.0f},
835 {-1.1f, 0.0f, 1.1f},
836 {0.0f, 0.0f, 0.0f},
837 100.0f,
838 0.0f,
839 0.0f, 0.0f, 1.0f,
841 static const struct expected_color
843 unsigned int x, y, color;
845 expected_directional[] =
847 {160, 120, 0x00ffffff},
848 {320, 120, 0x00ffffff},
849 {480, 120, 0x00ffffff},
850 {160, 240, 0x00ffffff},
851 {320, 240, 0x00ffffff},
852 {480, 240, 0x00ffffff},
853 {160, 360, 0x00ffffff},
854 {320, 360, 0x00ffffff},
855 {480, 360, 0x00ffffff},
857 expected_directional_local[] =
859 {160, 120, 0x003c3c3c},
860 {320, 120, 0x00717171},
861 {480, 120, 0x003c3c3c},
862 {160, 240, 0x00717171},
863 {320, 240, 0x00ffffff},
864 {480, 240, 0x00717171},
865 {160, 360, 0x003c3c3c},
866 {320, 360, 0x00717171},
867 {480, 360, 0x003c3c3c},
869 expected_point[] =
871 {160, 120, 0x00282828},
872 {320, 120, 0x005a5a5a},
873 {480, 120, 0x00282828},
874 {160, 240, 0x005a5a5a},
875 {320, 240, 0x00ffffff},
876 {480, 240, 0x005a5a5a},
877 {160, 360, 0x00282828},
878 {320, 360, 0x005a5a5a},
879 {480, 360, 0x00282828},
881 expected_point_local[] =
883 {160, 120, 0x00000000},
884 {320, 120, 0x00070707},
885 {480, 120, 0x00000000},
886 {160, 240, 0x00070707},
887 {320, 240, 0x00ffffff},
888 {480, 240, 0x00070707},
889 {160, 360, 0x00000000},
890 {320, 360, 0x00070707},
891 {480, 360, 0x00000000},
893 expected_spot[] =
895 {160, 120, 0x00000000},
896 {320, 120, 0x00141414},
897 {480, 120, 0x00000000},
898 {160, 240, 0x00141414},
899 {320, 240, 0x00ffffff},
900 {480, 240, 0x00141414},
901 {160, 360, 0x00000000},
902 {320, 360, 0x00141414},
903 {480, 360, 0x00000000},
905 expected_spot_local[] =
907 {160, 120, 0x00000000},
908 {320, 120, 0x00020202},
909 {480, 120, 0x00000000},
910 {160, 240, 0x00020202},
911 {320, 240, 0x00ffffff},
912 {480, 240, 0x00020202},
913 {160, 360, 0x00000000},
914 {320, 360, 0x00020202},
915 {480, 360, 0x00000000},
917 expected_point_range[] =
919 {160, 120, 0x00000000},
920 {320, 120, 0x005a5a5a},
921 {480, 120, 0x00000000},
922 {160, 240, 0x005a5a5a},
923 {320, 240, 0x00ffffff},
924 {480, 240, 0x005a5a5a},
925 {160, 360, 0x00000000},
926 {320, 360, 0x005a5a5a},
927 {480, 360, 0x00000000},
929 expected_point_side[] =
931 {160, 120, 0x00000000},
932 {320, 120, 0x00000000},
933 {480, 120, 0x00000000},
934 {160, 240, 0x00000000},
935 {320, 240, 0x00000000},
936 {480, 240, 0x00000000},
937 {160, 360, 0x00000000},
938 {320, 360, 0x00000000},
939 {480, 360, 0x00000000},
941 expected_directional_0[] =
943 {160, 120, 0x00ffffff},
944 {320, 120, 0x00ffffff},
945 {480, 120, 0x00ffffff},
946 {160, 240, 0x00ffffff},
947 {320, 240, 0x00ffffff},
948 {480, 240, 0x00ffffff},
949 {160, 360, 0x00ffffff},
950 {320, 360, 0x00ffffff},
951 {480, 360, 0x00ffffff},
953 expected_directional_local_0[] =
955 {160, 120, 0x00ffffff},
956 {320, 120, 0x00ffffff},
957 {480, 120, 0x00ffffff},
958 {160, 240, 0x00ffffff},
959 {320, 240, 0x00ffffff},
960 {480, 240, 0x00ffffff},
961 {160, 360, 0x00ffffff},
962 {320, 360, 0x00ffffff},
963 {480, 360, 0x00ffffff},
965 expected_point_0[] =
967 {160, 120, 0x00aaaaaa},
968 {320, 120, 0x00cccccc},
969 {480, 120, 0x00aaaaaa},
970 {160, 240, 0x00cccccc},
971 {320, 240, 0x00ffffff},
972 {480, 240, 0x00cccccc},
973 {160, 360, 0x00aaaaaa},
974 {320, 360, 0x00cccccc},
975 {480, 360, 0x00aaaaaa},
977 expected_spot_0[] =
979 {160, 120, 0x00000000},
980 {320, 120, 0x002e2e2e},
981 {480, 120, 0x00000000},
982 {160, 240, 0x002e2e2e},
983 {320, 240, 0x00ffffff},
984 {480, 240, 0x002e2e2e},
985 {160, 360, 0x00000000},
986 {320, 360, 0x002e2e2e},
987 {480, 360, 0x00000000},
989 expected_point_range_0[] =
991 {160, 120, 0x00000000},
992 {320, 120, 0x00cccccc},
993 {480, 120, 0x00000000},
994 {160, 240, 0x00cccccc},
995 {320, 240, 0x00ffffff},
996 {480, 240, 0x00cccccc},
997 {160, 360, 0x00000000},
998 {320, 360, 0x00cccccc},
999 {480, 360, 0x00000000},
1002 static const struct
1004 const D3DLIGHT9 *light;
1005 BOOL local_viewer;
1006 float specular_power;
1007 const struct expected_color *expected;
1008 unsigned int expected_count;
1010 tests[] =
1012 {&directional, FALSE, 30.0f, expected_directional, ARRAY_SIZE(expected_directional)},
1013 {&directional, TRUE, 30.0f, expected_directional_local, ARRAY_SIZE(expected_directional_local)},
1014 {&point, FALSE, 30.0f, expected_point, ARRAY_SIZE(expected_point)},
1015 {&point, TRUE, 30.0f, expected_point_local, ARRAY_SIZE(expected_point_local)},
1016 {&spot, FALSE, 30.0f, expected_spot, ARRAY_SIZE(expected_spot)},
1017 {&spot, TRUE, 30.0f, expected_spot_local, ARRAY_SIZE(expected_spot_local)},
1018 {&point_range, FALSE, 30.0f, expected_point_range, ARRAY_SIZE(expected_point_range)},
1019 {&point_side, TRUE, 0.0f, expected_point_side, ARRAY_SIZE(expected_point_side)},
1020 {&directional, FALSE, 0.0f, expected_directional_0, ARRAY_SIZE(expected_directional_0)},
1021 {&directional, TRUE, 0.0f, expected_directional_local_0, ARRAY_SIZE(expected_directional_local_0)},
1022 {&point, FALSE, 0.0f, expected_point_0, ARRAY_SIZE(expected_point_0)},
1023 {&point, TRUE, 0.0f, expected_point_0, ARRAY_SIZE(expected_point_0)},
1024 {&spot, FALSE, 0.0f, expected_spot_0, ARRAY_SIZE(expected_spot_0)},
1025 {&spot, TRUE, 0.0f, expected_spot_0, ARRAY_SIZE(expected_spot_0)},
1026 {&point_range, FALSE, 0.0f, expected_point_range_0, ARRAY_SIZE(expected_point_range_0)},
1028 unsigned int color, i, j, x, y;
1029 IDirect3DDevice9 *device;
1030 D3DMATERIAL9 material;
1031 IDirect3D9 *d3d;
1032 ULONG refcount;
1033 HWND window;
1034 HRESULT hr;
1035 struct
1037 struct vec3 position;
1038 struct vec3 normal;
1039 } *quad;
1040 WORD *indices;
1042 quad = malloc(vertices_side * vertices_side * sizeof(*quad));
1043 indices = malloc(indices_count * sizeof(*indices));
1044 for (i = 0, y = 0; y < vertices_side; ++y)
1046 for (x = 0; x < vertices_side; ++x)
1048 quad[i].position.x = x * 2.0f / (vertices_side - 1) - 1.0f;
1049 quad[i].position.y = y * 2.0f / (vertices_side - 1) - 1.0f;
1050 quad[i].position.z = 1.0f;
1051 quad[i].normal.x = 0.0f;
1052 quad[i].normal.y = 0.0f;
1053 quad[i++].normal.z = -1.0f;
1056 for (i = 0, y = 0; y < (vertices_side - 1); ++y)
1058 for (x = 0; x < (vertices_side - 1); ++x)
1060 indices[i++] = y * vertices_side + x + 1;
1061 indices[i++] = y * vertices_side + x;
1062 indices[i++] = (y + 1) * vertices_side + x;
1063 indices[i++] = y * vertices_side + x + 1;
1064 indices[i++] = (y + 1) * vertices_side + x;
1065 indices[i++] = (y + 1) * vertices_side + x + 1;
1069 window = create_window();
1070 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1071 ok(!!d3d, "Failed to create a D3D object.\n");
1072 if (!(device = create_device(d3d, window, window, TRUE)))
1074 skip("Failed to create a D3D device, skipping tests.\n");
1075 goto done;
1078 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &mat);
1079 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#lx.\n", hr);
1080 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &mat);
1081 ok(SUCCEEDED(hr), "Failed to set view transform, hr %#lx.\n", hr);
1082 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &mat);
1083 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#lx.\n", hr);
1084 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
1085 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#lx.\n", hr);
1086 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
1087 ok(SUCCEEDED(hr), "Failed to disable z test, hr %#lx.\n", hr);
1088 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1089 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#lx.\n", hr);
1091 hr = IDirect3DDevice9_SetFVF(device, fvf);
1092 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
1094 hr = IDirect3DDevice9_LightEnable(device, 0, TRUE);
1095 ok(SUCCEEDED(hr), "Failed to enable light 0, hr %#lx.\n", hr);
1096 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARENABLE, TRUE);
1097 ok(SUCCEEDED(hr), "Failed to enable specular lighting, hr %#lx.\n", hr);
1099 for (i = 0; i < ARRAY_SIZE(tests); ++i)
1101 hr = IDirect3DDevice9_SetLight(device, 0, tests[i].light);
1102 ok(SUCCEEDED(hr), "Failed to set light parameters, hr %#lx.\n", hr);
1104 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LOCALVIEWER, tests[i].local_viewer);
1105 ok(SUCCEEDED(hr), "Failed to set local viewer state, hr %#lx.\n", hr);
1107 memset(&material, 0, sizeof(material));
1108 material.Specular.r = 1.0f;
1109 material.Specular.g = 1.0f;
1110 material.Specular.b = 1.0f;
1111 material.Specular.a = 1.0f;
1112 material.Power = tests[i].specular_power;
1113 hr = IDirect3DDevice9_SetMaterial(device, &material);
1114 ok(SUCCEEDED(hr), "Failed to set material, hr %#lx.\n", hr);
1116 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
1117 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
1119 hr = IDirect3DDevice9_BeginScene(device);
1120 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
1122 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST,
1123 0, vertices_side * vertices_side, indices_count / 3, indices,
1124 D3DFMT_INDEX16, quad, sizeof(quad[0]));
1125 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
1127 hr = IDirect3DDevice9_EndScene(device);
1128 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
1130 for (j = 0; j < tests[i].expected_count; ++j)
1132 color = getPixelColor(device, tests[i].expected[j].x, tests[i].expected[j].y);
1133 ok(color_match(color, tests[i].expected[j].color, 1),
1134 "Expected color 0x%08x at location (%u, %u), got 0x%08x, case %u.\n",
1135 tests[i].expected[j].color, tests[i].expected[j].x,
1136 tests[i].expected[j].y, color, i);
1140 refcount = IDirect3DDevice9_Release(device);
1141 ok(!refcount, "Device has %lu references left.\n", refcount);
1142 done:
1143 IDirect3D9_Release(d3d);
1144 DestroyWindow(window);
1145 free(indices);
1146 free(quad);
1149 static void clear_test(void)
1151 static const D3DMATRIX mat =
1153 1.0f, 0.0f, 0.0f, 0.0f,
1154 0.0f, 1.0f, 0.0f, 0.0f,
1155 0.0f, 0.0f, 1.0f, 0.0f,
1156 0.0f, 0.0f, 0.0f, 1.0f,
1157 }}};
1158 static const struct
1160 struct vec3 position;
1161 DWORD diffuse;
1163 quad[] =
1165 {{-1.0f, -1.0f, 0.1f}, 0xff7f7f7f},
1166 {{ 1.0f, -1.0f, 0.1f}, 0xff7f7f7f},
1167 {{-1.0f, 1.0f, 0.1f}, 0xff7f7f7f},
1168 {{ 1.0f, 1.0f, 0.1f}, 0xff7f7f7f},
1170 IDirect3DSurface9 *surface0, *surface1, *backbuffer;
1171 IDirect3DTexture9 *texture;
1172 HRESULT hr;
1173 D3DRECT rect[2];
1174 D3DRECT rect_negneg;
1175 D3DVIEWPORT9 old_vp, vp;
1176 RECT scissor;
1177 DWORD oldColorWrite;
1178 BOOL invalid_clear_failed = FALSE, srgb_supported;
1179 IDirect3DDevice9 *device;
1180 unsigned int color;
1181 IDirect3D9 *d3d;
1182 ULONG refcount;
1183 HWND window;
1185 window = create_window();
1186 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1187 ok(!!d3d, "Failed to create a D3D object.\n");
1188 if (!(device = create_device(d3d, window, window, TRUE)))
1190 skip("Failed to create a D3D device, skipping tests.\n");
1191 goto done;
1194 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
1195 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1197 /* Positive x, negative y */
1198 rect[0].x1 = 0;
1199 rect[0].y1 = 480;
1200 rect[0].x2 = 320;
1201 rect[0].y2 = 240;
1203 /* Positive x, positive y */
1204 rect[1].x1 = 0;
1205 rect[1].y1 = 0;
1206 rect[1].x2 = 320;
1207 rect[1].y2 = 240;
1208 /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
1209 * returns D3D_OK, but ignores the rectangle silently
1211 hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1212 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
1213 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
1215 /* negative x, negative y */
1216 rect_negneg.x1 = 640;
1217 rect_negneg.y1 = 240;
1218 rect_negneg.x2 = 320;
1219 rect_negneg.y2 = 0;
1220 hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
1221 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
1222 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
1224 color = getPixelColor(device, 160, 360); /* lower left quad */
1225 ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
1226 color = getPixelColor(device, 160, 120); /* upper left quad */
1227 if(invalid_clear_failed) {
1228 /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
1229 ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
1230 } else {
1231 /* If the negative rectangle was dropped silently, the correct ones are cleared */
1232 ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
1234 color = getPixelColor(device, 480, 360); /* lower right quad */
1235 ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
1236 color = getPixelColor(device, 480, 120); /* upper right quad */
1237 ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
1239 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1241 /* Hack to work around a nvidia windows driver bug. The clear below is supposed to
1242 * clear the red quad in the top left part of the render target. For some reason it
1243 * doesn't work if the clear color is 0xffffffff on some versions of the Nvidia Windows
1244 * driver(tested on 8.17.12.5896, Win7). A clear with a different color works around
1245 * this bug and fixes the clear with the white color. Even 0xfeffffff works, but let's
1246 * pick some obvious value
1248 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbabe, 0.0, 0);
1249 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1251 /* Test how the viewport affects clears */
1252 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
1253 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1254 hr = IDirect3DDevice9_GetViewport(device, &old_vp);
1255 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1257 vp.X = 160;
1258 vp.Y = 120;
1259 vp.Width = 160;
1260 vp.Height = 120;
1261 vp.MinZ = 0.0;
1262 vp.MaxZ = 1.0;
1263 hr = IDirect3DDevice9_SetViewport(device, &vp);
1264 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1265 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
1266 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1268 vp.X = 320;
1269 vp.Y = 240;
1270 vp.Width = 320;
1271 vp.Height = 240;
1272 vp.MinZ = 0.0;
1273 vp.MaxZ = 1.0;
1274 hr = IDirect3DDevice9_SetViewport(device, &vp);
1275 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1276 rect[0].x1 = 160;
1277 rect[0].y1 = 120;
1278 rect[0].x2 = 480;
1279 rect[0].y2 = 360;
1280 hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
1281 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1283 hr = IDirect3DDevice9_SetViewport(device, &old_vp);
1284 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1286 color = getPixelColor(device, 158, 118);
1287 ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
1288 color = getPixelColor(device, 162, 118);
1289 ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
1290 color = getPixelColor(device, 158, 122);
1291 ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
1292 color = getPixelColor(device, 162, 122);
1293 ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
1295 color = getPixelColor(device, 318, 238);
1296 ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
1297 color = getPixelColor(device, 322, 238);
1298 ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
1299 color = getPixelColor(device, 318, 242);
1300 ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
1301 color = getPixelColor(device, 322, 242);
1302 ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
1304 color = getPixelColor(device, 478, 358);
1305 ok(color == 0x0000ff00, "(478,358) has color %08x\n", color);
1306 color = getPixelColor(device, 482, 358);
1307 ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
1308 color = getPixelColor(device, 478, 362);
1309 ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
1310 color = getPixelColor(device, 482, 362);
1311 ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
1313 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1315 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
1316 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1318 SetRect(&scissor, 160, 120, 480, 360);
1319 hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
1320 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1321 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
1322 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1324 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
1325 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1326 hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1327 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1329 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
1330 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1332 color = getPixelColor(device, 158, 118);
1333 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
1334 color = getPixelColor(device, 162, 118);
1335 ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
1336 color = getPixelColor(device, 158, 122);
1337 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
1338 color = getPixelColor(device, 162, 122);
1339 ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
1341 color = getPixelColor(device, 158, 358);
1342 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
1343 color = getPixelColor(device, 162, 358);
1344 ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
1345 color = getPixelColor(device, 158, 358);
1346 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
1347 color = getPixelColor(device, 162, 362);
1348 ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
1350 color = getPixelColor(device, 478, 118);
1351 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
1352 color = getPixelColor(device, 478, 122);
1353 ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
1354 color = getPixelColor(device, 482, 122);
1355 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
1356 color = getPixelColor(device, 482, 358);
1357 ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
1359 color = getPixelColor(device, 478, 358);
1360 ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
1361 color = getPixelColor(device, 478, 362);
1362 ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
1363 color = getPixelColor(device, 482, 358);
1364 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
1365 color = getPixelColor(device, 482, 362);
1366 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
1368 color = getPixelColor(device, 318, 238);
1369 ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
1370 color = getPixelColor(device, 318, 242);
1371 ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
1372 color = getPixelColor(device, 322, 238);
1373 ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
1374 color = getPixelColor(device, 322, 242);
1375 ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
1377 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1379 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
1380 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1381 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
1382 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1384 /* Same nvidia windows driver trouble with white clears as earlier in the same test */
1385 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbeef, 0.0, 0);
1386 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1388 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
1389 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1391 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
1392 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1394 /* Colorwriteenable does not affect the clear */
1395 color = getPixelColor(device, 320, 240);
1396 ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
1398 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1400 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
1401 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1403 rect[0].x1 = 0;
1404 rect[0].y1 = 0;
1405 rect[0].x2 = 640;
1406 rect[0].y2 = 480;
1407 hr = IDirect3DDevice9_Clear(device, 0, rect, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
1408 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1410 color = getPixelColor(device, 320, 240);
1411 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff), 1),
1412 "Clear with count = 0, rect != NULL has color %08x\n", color);
1414 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1416 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
1417 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1418 hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
1419 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1421 color = getPixelColor(device, 320, 240);
1422 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1423 "Clear with count = 1, rect = NULL has color %08x\n", color);
1425 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1427 /* Test D3DRS_SRGBWRITEENABLE interactions with clears. */
1428 srgb_supported = SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
1429 D3DUSAGE_QUERY_SRGBWRITE, D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8));
1430 trace("sRGB writing to D3DFMT_A8R8G8B8 is %ssupported.\n", srgb_supported ? "" : "not ");
1431 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f7f7f7f, 0.0, 0);
1432 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
1434 color = getPixelColor(device, 320, 240);
1435 ok(color_match(color, 0x007f7f7f, 1), "Clear has color %08x.\n", color);
1437 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
1438 ok(SUCCEEDED(hr), "Failed to enable sRGB write, hr %#lx.\n", hr);
1440 /* Draw something to make sure the SRGBWRITEENABLE setting is applied. */
1441 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &mat);
1442 ok(SUCCEEDED(hr), "Failed to set world matrix, hr %#lx.\n", hr);
1443 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
1444 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#lx.\n", hr);
1445 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
1446 ok(SUCCEEDED(hr), "Failed to disable z test, hr %#lx.\n", hr);
1447 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1448 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#lx.\n", hr);
1449 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
1450 ok(SUCCEEDED(hr), "Failed to disable stencil test, hr %#lx.\n", hr);
1451 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
1452 ok(SUCCEEDED(hr), "Failed to disable culling, hr %#lx.\n", hr);
1453 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1454 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
1455 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1456 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
1457 hr = IDirect3DDevice9_BeginScene(device);
1458 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
1459 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad));
1460 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
1461 hr = IDirect3DDevice9_EndScene(device);
1462 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
1464 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f7f7f7f, 0.0, 0);
1465 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
1467 color = getPixelColor(device, 320, 240);
1468 ok(color_match(color, 0x00bbbbbb, 1), "Clear has color %08x.\n", color);
1470 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
1471 ok(SUCCEEDED(hr), "Failed to disable sRGB write, hr %#lx.\n", hr);
1473 /* Switching to a new render target seems to be enough to make Windows pick
1474 * up on the changed render state. */
1475 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 2, D3DUSAGE_RENDERTARGET,
1476 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
1477 ok(SUCCEEDED(hr), "Failed to create the offscreen render target, hr %#lx.\n", hr);
1478 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1479 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#lx.\n", hr);
1480 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface0);
1481 ok(SUCCEEDED(hr), "Failed to get offscreen surface, hr %#lx.\n", hr);
1482 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface0);
1483 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
1485 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f7f7f7f, 0.0, 0);
1486 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
1488 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1489 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
1491 hr = IDirect3DDevice9_StretchRect(device, surface0, NULL, backbuffer, NULL, D3DTEXF_NONE);
1492 ok(SUCCEEDED(hr), "Failed to blit surface, hr %#lx.\n", hr);
1494 color = getPixelColor(device, 64, 64);
1495 ok(color_match(color, 0x007f7f7f, 1), "Clear has color %08x.\n", color);
1497 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
1498 ok(SUCCEEDED(hr), "Failed to enable sRGB write, hr %#lx.\n", hr);
1500 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface0);
1501 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
1503 hr = IDirect3DDevice9_BeginScene(device);
1504 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
1505 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad));
1506 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
1507 hr = IDirect3DDevice9_EndScene(device);
1508 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
1510 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f7f7f7f, 0.0, 0);
1511 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
1513 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1514 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
1516 hr = IDirect3DDevice9_StretchRect(device, surface0, NULL, backbuffer, NULL, D3DTEXF_NONE);
1517 ok(SUCCEEDED(hr), "Failed to blit surface, hr %#lx.\n", hr);
1519 color = getPixelColor(device, 320, 240);
1520 ok(color_match(color, 0x00bbbbbb, 1), "Clear has color %08x.\n", color);
1522 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
1523 ok(SUCCEEDED(hr), "Failed to disable sRGB write, hr %#lx.\n", hr);
1524 /* Switching to another surface of the same texture is also enough to make
1525 * the setting "stick". */
1526 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface1);
1527 ok(SUCCEEDED(hr), "Failed to get offscreen surface, hr %#lx.\n", hr);
1528 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface1);
1529 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
1531 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f7f7f7f, 0.0, 0);
1532 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx\n", hr);
1534 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1535 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
1537 hr = IDirect3DDevice9_StretchRect(device, surface1, NULL, backbuffer, NULL, D3DTEXF_NONE);
1538 ok(SUCCEEDED(hr), "Failed to blit surface, hr %#lx.\n", hr);
1540 color = getPixelColor(device, 320, 240);
1541 ok(color_match(color, 0x007f7f7f, 1), "Clear has color %08x.\n", color);
1543 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1545 IDirect3DSurface9_Release(surface1);
1546 IDirect3DSurface9_Release(surface0);
1547 IDirect3DSurface9_Release(backbuffer);
1548 IDirect3DTexture9_Release(texture);
1549 refcount = IDirect3DDevice9_Release(device);
1550 ok(!refcount, "Device has %lu references left.\n", refcount);
1551 done:
1552 IDirect3D9_Release(d3d);
1553 DestroyWindow(window);
1556 static void test_clear_different_size_surfaces(void)
1558 IDirect3DSurface9 *ds, *rt, *rt2;
1559 IDirect3DDevice9 *device;
1560 D3DFORMAT ds_format;
1561 D3DLOCKED_RECT lr;
1562 unsigned int x, y;
1563 D3DVIEWPORT9 vp;
1564 IDirect3D9 *d3d;
1565 D3DCAPS9 caps;
1566 WORD *depth;
1567 HWND window;
1568 HRESULT hr;
1570 window = create_window();
1571 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1572 ok(!!d3d, "Failed to create D3D object.\n");
1573 if (!(device = create_device(d3d, window, window, TRUE)))
1575 skip("Failed to create D3D device.\n");
1576 goto done;
1579 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
1580 ok(hr == D3D_OK, "Failed to get device caps, hr %#lx.\n", hr);
1582 hr = IDirect3DDevice9_CreateRenderTarget(device, 1, 1, D3DFMT_A8R8G8B8,
1583 D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL);
1584 ok(hr == D3D_OK, "Failed to create render target surface, hr %#lx.\n", hr);
1585 hr = IDirect3DDevice9_CreateRenderTarget(device, 1, 2, D3DFMT_A8R8G8B8,
1586 D3DMULTISAMPLE_NONE, 0, TRUE, &rt2, NULL);
1587 ok(hr == D3D_OK, "Failed to create render target surface, hr %#lx.\n", hr);
1589 if (SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
1590 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D16_LOCKABLE)))
1592 ds_format = D3DFMT_D16_LOCKABLE;
1594 else
1596 ds_format = D3DFMT_D24S8;
1599 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 4, 4, ds_format,
1600 D3DMULTISAMPLE_NONE, 0, FALSE, &ds, NULL);
1601 ok(hr == D3D_OK, "Failed to create depth surface, hr %#lx.\n", hr);
1603 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
1604 ok(hr == D3D_OK, "Failed to set depth stencil surface, hr %#lx.\n", hr);
1605 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
1606 ok(hr == D3D_OK, "Failed to set render target, hr %#lx.\n", hr);
1607 if (caps.NumSimultaneousRTs >= 2)
1609 hr = IDirect3DDevice9_SetRenderTarget(device, 1, rt2);
1610 ok(hr == D3D_OK, "Failed to set render target, hr %#lx.\n", hr);
1613 vp.X = 0;
1614 vp.Y = 0;
1615 vp.Width = 640;
1616 vp.Height = 640;
1617 vp.MinZ = 0.0f;
1618 vp.MaxZ = 1.0f;
1619 hr = IDirect3DDevice9_SetViewport(device, &vp);
1620 ok(hr == D3D_OK, "Failed to set viewport, hr %#lx.\n", hr);
1622 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.5f, 0);
1623 ok(hr == D3D_OK, "Failed to clear, hr %#lx.\n", hr);
1625 check_rt_color(rt, 0x00ff0000);
1627 if (caps.NumSimultaneousRTs >= 2)
1628 check_rt_color(rt2, 0x00ff0000);
1630 if (ds_format == D3DFMT_D16_LOCKABLE)
1632 hr = IDirect3DSurface9_LockRect(ds, &lr, NULL, D3DLOCK_READONLY);
1633 ok(hr == D3D_OK, "Failed to lock rect, hr %#lx.\n", hr);
1634 for (y = 0; y < 4; ++y)
1636 depth = (WORD *)((BYTE *)lr.pBits + y * lr.Pitch);
1637 for (x = 0; x < 4; ++x)
1639 ok(compare_uint(depth[x], 0x7fff, 2), "Got depth 0x%04x at %u, %u.\n", depth[x], x, y);
1642 hr = IDirect3DSurface9_UnlockRect(ds);
1643 ok(hr == D3D_OK, "Failed to unlock rect, hr %#lx.\n", hr);
1644 IDirect3DSurface9_Release(ds);
1646 else
1648 skip("D3DFMT_D16_LOCKABLE is not supported.\n");
1651 IDirect3DSurface9_Release(rt);
1652 IDirect3DSurface9_Release(rt2);
1653 done:
1654 IDirect3D9_Release(d3d);
1655 DestroyWindow(window);
1658 static void color_fill_test(void)
1660 unsigned int fill_color, color, fill_a, expected_a;
1661 IDirect3DSurface9 *surface;
1662 IDirect3DTexture9 *texture;
1663 IDirect3DDevice9 *device;
1664 IDirect3D9 *d3d;
1665 ULONG refcount;
1666 HWND window;
1667 HRESULT hr;
1668 static const struct
1670 D3DPOOL pool;
1671 DWORD usage;
1672 HRESULT hr;
1674 resource_types[] =
1676 {D3DPOOL_DEFAULT, 0, D3DERR_INVALIDCALL},
1677 {D3DPOOL_DEFAULT, D3DUSAGE_DYNAMIC, D3DERR_INVALIDCALL},
1678 {D3DPOOL_DEFAULT, D3DUSAGE_RENDERTARGET, D3D_OK},
1679 {D3DPOOL_SYSTEMMEM, 0, D3DERR_INVALIDCALL},
1680 {D3DPOOL_MANAGED, 0, D3DERR_INVALIDCALL},
1681 {D3DPOOL_SCRATCH, 0, D3DERR_INVALIDCALL},
1683 enum format_flags
1685 CHECK_FILL_VALUE = 0x1,
1686 BLOCKS = 0x2,
1687 FLOAT_VALUES = 0x4,
1689 static const struct
1691 D3DFORMAT format;
1692 const char *name;
1693 enum format_flags flags;
1694 unsigned int fill_i[4];
1695 float fill_f[4];
1697 formats[] =
1699 {D3DFMT_A8R8G8B8, "D3DFMT_A8R8G8B8", CHECK_FILL_VALUE,
1700 {0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef}},
1701 /* D3DFMT_X8R8G8B8 either set X = A or X = 0, depending on the driver. */
1702 {D3DFMT_R5G6B5, "D3DFMT_R5G6B5", CHECK_FILL_VALUE,
1703 {0xadfdadfd, 0xadfdadfd, 0xadfdadfd, 0xadfdadfd}},
1704 {D3DFMT_G16R16, "D3DFMT_G16R16", CHECK_FILL_VALUE,
1705 {0xbebeadad, 0xbebeadad, 0xbebeadad, 0xbebeadad}},
1706 {D3DFMT_A16B16G16R16, "D3DFMT_A16B16G16R16", CHECK_FILL_VALUE,
1707 {0xbebeadad, 0xdedeefef, 0xbebeadad, 0xdedeefef}},
1708 /* Real hardware reliably fills the surface with the blue channel but
1709 * the testbot fills it with 0x00. Wine incorrectly uses the alpha
1710 * channel. Don't bother checking the result because P8 surfaces are
1711 * essentially useless in d3d9. */
1712 {D3DFMT_P8, "D3DFMT_P8", 0,
1713 {0xefefefef, 0xefefefef, 0xefefefef, 0xefefefef}},
1714 /* Float formats. */
1715 {D3DFMT_R32F, "D3DFMT_R32F", CHECK_FILL_VALUE | FLOAT_VALUES,
1716 {0, 0, 0, 0}, {0xad / 255.0f, 0xad / 255.0f, 0xad / 255.0f, 0xad / 255.0f}},
1717 {D3DFMT_A32B32G32R32F, "D3DFMT_A32B32G32R32F", CHECK_FILL_VALUE | FLOAT_VALUES,
1718 {0, 0, 0, 0}, {0xad / 255.0f, 0xbe / 255.0f, 0xef / 255.0f, 0xde / 255.0f}},
1719 {D3DFMT_R16F, "D3DFMT_R16F", CHECK_FILL_VALUE,
1720 {0x396d396d, 0x396d396d, 0x396d396d, 0x396d396d}},
1721 {D3DFMT_G16R16F, "D3DFMT_G16R16F", CHECK_FILL_VALUE,
1722 {0x39f5396d, 0x39f5396d, 0x39f5396d, 0x39f5396d}},
1723 {D3DFMT_A16B16G16R16F, "D3DFMT_A16B16G16R16F", CHECK_FILL_VALUE,
1724 {0x39f5396d, 0x3af63b7f, 0x39f5396d, 0x3af63b7f}},
1725 /* Windows drivers produce different results for these formats.
1726 * No driver produces a YUV value that matches the input RGB
1727 * value, and no driver produces a proper DXT compression block.
1729 * Even the clear value 0 does not reliably produce a fill value
1730 * that will return vec4(0.0, 0.0, 0.0, 0.0) when sampled.
1732 * The YUV tests are disabled because they produce a driver-dependent
1733 * result on Wine.
1734 * {D3DFMT_YUY2, "D3DFMT_YUY2", BLOCKS},
1735 * {D3DFMT_UYVY, "D3DFMT_UYVY", BLOCKS}, */
1736 {D3DFMT_DXT1, "D3DFMT_DXT1", BLOCKS},
1737 /* Vendor-specific formats like ATI2N are a non-issue here since they're not
1738 * supported as offscreen plain surfaces and do not support D3DUSAGE_RENDERTARGET
1739 * when created as texture. */
1741 static const RECT rect = {4, 4, 8, 8}, rect2 = {5, 5, 7, 7};
1742 D3DLOCKED_RECT locked_rect;
1743 unsigned int i, j;
1745 window = create_window();
1746 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1747 ok(!!d3d, "Failed to create a D3D object.\n");
1748 if (!(device = create_device(d3d, window, window, TRUE)))
1750 skip("Failed to create a D3D device, skipping tests.\n");
1751 goto done;
1754 hr = IDirect3DDevice9_ColorFill(device, NULL, NULL, 0);
1755 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
1757 /* Test ColorFill on a the backbuffer (should pass) */
1758 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &surface);
1759 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1761 fill_color = 0x112233;
1762 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, fill_color);
1763 ok(SUCCEEDED(hr), "Color fill failed, hr %#lx.\n", hr);
1765 color = getPixelColor(device, 0, 0);
1766 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
1768 IDirect3DSurface9_Release(surface);
1770 /* Test ColorFill on a render target surface (should pass) */
1771 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8,
1772 D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL );
1773 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1775 fill_color = 0x445566;
1776 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, fill_color);
1777 ok(SUCCEEDED(hr), "Color fill failed, hr %#lx.\n", hr);
1779 color = getPixelColorFromSurface(surface, 0, 0);
1780 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
1782 IDirect3DSurface9_Release(surface);
1784 /* Test ColorFill on an offscreen plain surface in D3DPOOL_DEFAULT (should pass) */
1785 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
1786 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surface, NULL);
1787 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1789 fill_color = 0x778899;
1790 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, fill_color);
1791 ok(SUCCEEDED(hr), "Color fill failed, hr %#lx.\n", hr);
1793 color = getPixelColorFromSurface(surface, 0, 0);
1794 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
1796 IDirect3DSurface9_Release(surface);
1798 /* Try ColorFill on an offscreen surface in sysmem (should fail) */
1799 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
1800 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1801 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1803 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, 0);
1804 ok(hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
1806 IDirect3DSurface9_Release(surface);
1808 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 32, 32, D3DFMT_D16,
1809 D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL);
1810 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
1812 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, 0);
1813 ok(hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
1815 IDirect3DSurface9_Release(surface);
1817 for (i = 0; i < ARRAY_SIZE(resource_types); i++)
1819 texture = NULL;
1820 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, resource_types[i].usage,
1821 D3DFMT_A8R8G8B8, resource_types[i].pool, &texture, NULL);
1822 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx, i=%u.\n", hr, i);
1823 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
1824 ok(SUCCEEDED(hr), "Failed to get surface, hr %#lx, i=%u.\n", hr, i);
1826 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, fill_color);
1827 ok(hr == resource_types[i].hr, "Got unexpected hr %#lx, expected %#lx, i=%u.\n",
1828 hr, resource_types[i].hr, i);
1830 IDirect3DSurface9_Release(surface);
1831 IDirect3DTexture9_Release(texture);
1834 for (i = 0; i < ARRAY_SIZE(formats); i++)
1836 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
1837 D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, formats[i].format) != D3D_OK)
1839 skip("Offscreenplain %s surfaces not supported, skipping colorfill test\n", formats[i].name);
1840 continue;
1843 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
1844 formats[i].format, D3DPOOL_DEFAULT, &surface, NULL);
1845 ok(SUCCEEDED(hr), "Failed to create surface, hr %#lx, fmt=%s.\n", hr, formats[i].name);
1847 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, 0xdeadbeef);
1848 ok(SUCCEEDED(hr), "Failed to color fill, hr %#lx, fmt=%s.\n", hr, formats[i].name);
1850 hr = IDirect3DDevice9_ColorFill(device, surface, &rect, 0xdeadbeef);
1851 ok(SUCCEEDED(hr), "Failed to color fill, hr %#lx, fmt=%s.\n", hr, formats[i].name);
1853 if (SUCCEEDED(hr))
1855 hr = IDirect3DDevice9_ColorFill(device, surface, &rect2, 0xdeadbeef);
1856 if (formats[i].flags & BLOCKS)
1857 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx, fmt=%s.\n", hr, formats[i].name);
1858 else
1859 ok(SUCCEEDED(hr), "Failed to color fill, hr %#lx, fmt=%s.\n", hr, formats[i].name);
1862 if (!(formats[i].flags & CHECK_FILL_VALUE))
1864 IDirect3DSurface9_Release(surface);
1865 continue;
1868 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1869 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#lx, fmt=%s.\n", hr, formats[i].name);
1870 /* Windows drivers disagree on how to promote the 8 bit per channel
1871 * input argument to 16 bit for D3DFMT_G16R16. */
1872 if (formats[i].flags & FLOAT_VALUES)
1874 const struct vec4 *surface_data = locked_rect.pBits;
1875 ok(compare_vec4(surface_data, formats[i].fill_f[0], formats[i].fill_f[1],
1876 formats[i].fill_f[2], formats[i].fill_f[3], 1),
1877 "Expected clear values %f %f %f %f, got %f %f %f %f, fmt=%s\n",
1878 formats[i].fill_f[0], formats[i].fill_f[1],
1879 formats[i].fill_f[2], formats[i].fill_f[3],
1880 surface_data->x, surface_data->y, surface_data->z, surface_data->w,
1881 formats[i].name);
1883 else
1885 const unsigned int *surface_data = locked_rect.pBits;
1886 for (j = 0; j < 4; ++j)
1888 fill_a = (surface_data[j] & 0xff000000) >> 24;
1889 expected_a = (formats[i].fill_i[j] & 0xff000000) >> 24;
1890 ok(color_match(surface_data[j], formats[i].fill_i[j], 2) &&
1891 compare_uint(expected_a, fill_a, 2),
1892 "Expected clear value 0x%08x, got 0x%08x, fmt=%s, j=%u.\n",
1893 formats[i].fill_i[j], surface_data[j], formats[i].name, j);
1897 /* Fill the surface with something else to make sure the test below doesn't pass
1898 * due to stale contents by accident. */
1899 memset(locked_rect.pBits, 0x55, locked_rect.Pitch * 32);
1901 hr = IDirect3DSurface9_UnlockRect(surface);
1902 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#lx, fmt=%s.\n", hr, formats[i].name);
1904 /* Test clearing "to sysmem". Wined3d's delayed clear will perform the actual clear
1905 * in the lock call and try to fill the sysmem buffer instead of clearing on the
1906 * GPU and downloading it. */
1907 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, 0xdeadbeef);
1908 ok(SUCCEEDED(hr), "Failed to color fill, hr %#lx, fmt=%s.\n", hr, formats[i].name);
1909 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, D3DLOCK_READONLY);
1910 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#lx, fmt=%s.\n", hr, formats[i].name);
1912 if (formats[i].flags & FLOAT_VALUES)
1914 const struct vec4 *surface_data = locked_rect.pBits;
1915 ok(compare_vec4(surface_data, formats[i].fill_f[0], formats[i].fill_f[1],
1916 formats[i].fill_f[2], formats[i].fill_f[3], 1),
1917 "Expected clear values %f %f %f %f, got %f %f %f %f, fmt=%s\n",
1918 formats[i].fill_f[0], formats[i].fill_f[1],
1919 formats[i].fill_f[2], formats[i].fill_f[3],
1920 surface_data->x, surface_data->y, surface_data->z, surface_data->w,
1921 formats[i].name);
1923 else
1925 const unsigned int *surface_data = locked_rect.pBits;
1926 for (j = 0; j < 4; ++j)
1928 fill_a = (surface_data[j] & 0xff000000) >> 24;
1929 expected_a = (formats[i].fill_i[j] & 0xff000000) >> 24;
1930 ok(color_match(surface_data[j], formats[i].fill_i[j], 2) &&
1931 compare_uint(expected_a, fill_a, 2),
1932 "Expected clear value 0x%08x, got 0x%08x, fmt=%s, j=%u.\n",
1933 formats[i].fill_i[j], surface_data[j], formats[i].name, j);
1938 hr = IDirect3DSurface9_UnlockRect(surface);
1939 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#lx, fmt=%s.\n", hr, formats[i].name);
1941 IDirect3DSurface9_Release(surface);
1944 refcount = IDirect3DDevice9_Release(device);
1945 ok(!refcount, "Device has %lu references left.\n", refcount);
1946 done:
1947 IDirect3D9_Release(d3d);
1948 DestroyWindow(window);
1952 * c7 mova ARGB mov ARGB
1953 * -2.4 -2 0x00ffff00 -3 0x00ff0000
1954 * -1.6 -2 0x00ffff00 -2 0x00ffff00
1955 * -0.4 0 0x0000ffff -1 0x0000ff00
1956 * 0.4 0 0x0000ffff 0 0x0000ffff
1957 * 1.6 2 0x00ff00ff 1 0x000000ff
1958 * 2.4 2 0x00ff00ff 2 0x00ff00ff
1960 static void test_mova(void)
1962 IDirect3DVertexDeclaration9 *vertex_declaration;
1963 IDirect3DVertexShader9 *mova_shader;
1964 IDirect3DVertexShader9 *mov_shader;
1965 IDirect3DDevice9 *device;
1966 unsigned int i, j;
1967 IDirect3D9 *d3d;
1968 ULONG refcount;
1969 D3DCAPS9 caps;
1970 HWND window;
1971 HRESULT hr;
1973 static const DWORD mova_test[] =
1975 0xfffe0200, /* vs_2_0 */
1976 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1977 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
1978 0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
1979 0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
1980 0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
1981 0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
1982 0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
1983 0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
1984 0x0200002e, 0xb0010000, 0xa0000007, /* mova a0.x, c7.x */
1985 0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000, /* mov oD0, c[a0.x + 3] */
1986 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1987 0x0000ffff /* END */
1989 static const DWORD mov_test[] =
1991 0xfffe0101, /* vs_1_1 */
1992 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1993 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
1994 0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
1995 0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
1996 0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
1997 0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
1998 0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
1999 0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
2000 0x00000001, 0xb0010000, 0xa0000007, /* mov a0.x, c7.x */
2001 0x00000001, 0xd00f0000, 0xa0e42003, /* mov oD0, c[a0.x + 3] */
2002 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2003 0x0000ffff /* END */
2005 static const struct
2007 float in[4];
2008 unsigned int out;
2010 test_data[2][6] =
2013 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
2014 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
2015 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
2016 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
2017 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
2018 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
2021 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
2022 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
2023 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
2024 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
2025 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
2026 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
2029 static const struct vec3 quad[] =
2031 {-1.0f, -1.0f, 0.0f},
2032 {-1.0f, 1.0f, 0.0f},
2033 { 1.0f, -1.0f, 0.0f},
2034 { 1.0f, 1.0f, 0.0f},
2036 static const D3DVERTEXELEMENT9 decl_elements[] =
2038 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2039 D3DDECL_END()
2042 window = create_window();
2043 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2044 ok(!!d3d, "Failed to create a D3D object.\n");
2045 if (!(device = create_device(d3d, window, window, TRUE)))
2047 skip("Failed to create a D3D device, skipping tests.\n");
2048 goto done;
2051 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2052 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
2053 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
2055 skip("No vs_2_0 support, skipping tests.\n");
2056 IDirect3DDevice9_Release(device);
2057 goto done;
2060 hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
2061 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2062 hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
2063 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2064 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
2065 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2066 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
2067 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2069 hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
2070 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2071 for (j = 0; j < ARRAY_SIZE(test_data); ++j)
2073 for (i = 0; i < ARRAY_SIZE(*test_data); ++i)
2075 unsigned int color;
2077 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
2078 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2080 hr = IDirect3DDevice9_BeginScene(device);
2081 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2083 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2084 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2086 hr = IDirect3DDevice9_EndScene(device);
2087 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2089 color = getPixelColor(device, 320, 240);
2090 ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
2091 test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
2093 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2094 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2096 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
2097 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2099 hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
2100 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2103 IDirect3DVertexDeclaration9_Release(vertex_declaration);
2104 IDirect3DVertexShader9_Release(mova_shader);
2105 IDirect3DVertexShader9_Release(mov_shader);
2106 refcount = IDirect3DDevice9_Release(device);
2107 ok(!refcount, "Device has %lu references left.\n", refcount);
2108 done:
2109 IDirect3D9_Release(d3d);
2110 DestroyWindow(window);
2113 static void fog_test(void)
2115 float start = 0.0f, end = 1.0f;
2116 IDirect3DDevice9 *device;
2117 unsigned int color, i;
2118 IDirect3D9 *d3d;
2119 ULONG refcount;
2120 D3DCAPS9 caps;
2121 HWND window;
2122 HRESULT hr;
2124 /* Gets full z based fog with linear fog, no fog with specular color. */
2125 static const struct
2127 float x, y, z;
2128 D3DCOLOR diffuse;
2129 D3DCOLOR specular;
2131 untransformed_1[] =
2133 {-1.0f, -1.0f, 0.1f, 0xffff0000, 0xff000000},
2134 {-1.0f, 0.0f, 0.1f, 0xffff0000, 0xff000000},
2135 { 0.0f, 0.0f, 0.1f, 0xffff0000, 0xff000000},
2136 { 0.0f, -1.0f, 0.1f, 0xffff0000, 0xff000000},
2138 /* Ok, I am too lazy to deal with transform matrices. */
2139 untransformed_2[] =
2141 {-1.0f, 0.0f, 1.0f, 0xffff0000, 0xff000000},
2142 {-1.0f, 1.0f, 1.0f, 0xffff0000, 0xff000000},
2143 { 0.0f, 1.0f, 1.0f, 0xffff0000, 0xff000000},
2144 { 0.0f, 0.0f, 1.0f, 0xffff0000, 0xff000000},
2146 untransformed_3[] =
2148 {-1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
2149 {-1.0f, 1.0f, 0.5f, 0xffff0000, 0xff000000},
2150 { 1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
2151 { 1.0f, 1.0f, 0.5f, 0xffff0000, 0xff000000},
2153 far_quad1[] =
2155 {-1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
2156 {-1.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
2157 { 0.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
2158 { 0.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
2160 far_quad2[] =
2162 {-1.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
2163 {-1.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
2164 { 0.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
2165 { 0.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
2167 /* Untransformed ones. Give them a different diffuse color to make the
2168 * test look nicer. It also makes making sure that they are drawn
2169 * correctly easier. */
2170 static const struct
2172 float x, y, z, rhw;
2173 D3DCOLOR diffuse;
2174 D3DCOLOR specular;
2176 transformed_1[] =
2178 {320.0f, 0.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
2179 {640.0f, 0.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
2180 {640.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
2181 {320.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
2183 transformed_2[] =
2185 {320.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
2186 {640.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
2187 {640.0f, 480.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
2188 {320.0f, 480.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
2190 static const struct
2192 struct vec3 position;
2193 DWORD diffuse;
2195 rev_fog_quads[] =
2197 {{-1.0f, -1.0f, 0.1f}, 0x000000ff},
2198 {{-1.0f, 0.0f, 0.1f}, 0x000000ff},
2199 {{ 0.0f, 0.0f, 0.1f}, 0x000000ff},
2200 {{ 0.0f, -1.0f, 0.1f}, 0x000000ff},
2202 {{ 0.0f, -1.0f, 0.9f}, 0x000000ff},
2203 {{ 0.0f, 0.0f, 0.9f}, 0x000000ff},
2204 {{ 1.0f, 0.0f, 0.9f}, 0x000000ff},
2205 {{ 1.0f, -1.0f, 0.9f}, 0x000000ff},
2207 {{ 0.0f, 0.0f, 0.4f}, 0x000000ff},
2208 {{ 0.0f, 1.0f, 0.4f}, 0x000000ff},
2209 {{ 1.0f, 1.0f, 0.4f}, 0x000000ff},
2210 {{ 1.0f, 0.0f, 0.4f}, 0x000000ff},
2212 {{-1.0f, 0.0f, 0.7f}, 0x000000ff},
2213 {{-1.0f, 1.0f, 0.7f}, 0x000000ff},
2214 {{ 0.0f, 1.0f, 0.7f}, 0x000000ff},
2215 {{ 0.0f, 0.0f, 0.7f}, 0x000000ff},
2217 static const D3DMATRIX ident_mat =
2219 1.0f, 0.0f, 0.0f, 0.0f,
2220 0.0f, 1.0f, 0.0f, 0.0f,
2221 0.0f, 0.0f, 1.0f, 0.0f,
2222 0.0f, 0.0f, 0.0f, 1.0f
2223 }}};
2224 static const D3DMATRIX world_mat1 =
2226 1.0f, 0.0f, 0.0f, 0.0f,
2227 0.0f, 1.0f, 0.0f, 0.0f,
2228 0.0f, 0.0f, 1.0f, 0.0f,
2229 0.0f, 0.0f, -0.5f, 1.0f
2230 }}};
2231 static const D3DMATRIX world_mat2 =
2233 1.0f, 0.0f, 0.0f, 0.0f,
2234 0.0f, 1.0f, 0.0f, 0.0f,
2235 0.0f, 0.0f, 1.0f, 0.0f,
2236 0.0f, 0.0f, 1.0f, 1.0f
2237 }}};
2238 static const D3DMATRIX proj_mat =
2240 1.0f, 0.0f, 0.0f, 0.0f,
2241 0.0f, 1.0f, 0.0f, 0.0f,
2242 0.0f, 0.0f, 1.0f, 0.0f,
2243 0.0f, 0.0f, -1.0f, 1.0f
2244 }}};
2245 static const WORD Indices[] = {0, 1, 2, 2, 3, 0};
2246 static const WORD Indices2[] =
2248 0, 1, 2, 2, 3, 0,
2249 4, 5, 6, 6, 7, 4,
2250 8, 9, 10, 10, 11, 8,
2251 12, 13, 14, 14, 15, 12,
2254 window = create_window();
2255 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2256 ok(!!d3d, "Failed to create a D3D object.\n");
2257 if (!(device = create_device(d3d, window, window, TRUE)))
2259 skip("Failed to create a D3D device, skipping tests.\n");
2260 goto done;
2263 memset(&caps, 0, sizeof(caps));
2264 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2265 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2266 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
2267 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2269 /* Setup initial states: No lighting, fog on, fog color */
2270 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
2271 ok(SUCCEEDED(hr), "Failed to disable D3DRS_ZENABLE, hr %#lx.\n", hr);
2272 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2273 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2274 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
2275 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2276 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xff00ff00 /* A nice green */);
2277 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2278 /* Some of the tests seem to depend on the projection matrix explicitly
2279 * being set to an identity matrix, even though that's the default.
2280 * (AMD Radeon HD 6310, Windows 7) */
2281 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &ident_mat);
2282 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#lx.\n", hr);
2284 /* First test: Both table fog and vertex fog off */
2285 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
2286 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2287 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
2288 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2290 /* Start = 0, end = 1. Should be default, but set them */
2291 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
2292 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2293 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
2294 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2296 hr = IDirect3DDevice9_BeginScene(device);
2297 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
2299 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
2300 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
2302 /* Untransformed, vertex fog = NONE, table fog = NONE:
2303 * Read the fog weighting from the specular color. */
2304 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
2305 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
2306 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
2308 /* That makes it use the Z value */
2309 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
2310 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog vertex mode, hr %#lx.\n", hr);
2311 /* Untransformed, vertex fog != none (or table fog != none):
2312 * Use the Z value as input into the equation. */
2313 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
2314 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
2315 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
2317 /* transformed verts */
2318 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
2319 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
2320 /* Transformed, vertex fog != NONE, pixel fog == NONE:
2321 * Use specular color alpha component. */
2322 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
2323 2 /* PrimCount */, Indices, D3DFMT_INDEX16, transformed_1, sizeof(transformed_1[0]));
2324 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
2326 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
2327 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog table mode, hr %#lx.\n", hr);
2328 /* Transformed, table fog != none, vertex anything:
2329 * Use Z value as input to the fog equation. */
2330 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
2331 2 /* PrimCount */, Indices, D3DFMT_INDEX16, transformed_2, sizeof(transformed_2[0]));
2332 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
2334 hr = IDirect3DDevice9_EndScene(device);
2335 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2337 color = getPixelColor(device, 160, 360);
2338 ok(color == 0x00ff0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
2339 color = getPixelColor(device, 160, 120);
2340 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
2341 color = getPixelColor(device, 480, 120);
2342 ok(color == 0x00ffff00, "Transformed vertex with linear vertex fog has color %08x\n", color);
2343 if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
2345 color = getPixelColor(device, 480, 360);
2346 ok(color_match(color, 0x0000ff00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
2348 else
2350 /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
2351 * The settings above result in no fogging with vertex fog
2353 color = getPixelColor(device, 480, 120);
2354 ok(color == 0x00ffff00, "Transformed vertex with linear vertex fog has color %08x\n", color);
2355 trace("Info: Table fog not supported by this device\n");
2357 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2359 /* Now test the special case fogstart == fogend */
2360 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
2361 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2363 hr = IDirect3DDevice9_BeginScene(device);
2364 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
2366 start = 512;
2367 end = 512;
2368 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *)&start));
2369 ok(SUCCEEDED(hr), "Failed to set fog start, hr %#lx.\n", hr);
2370 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *)&end));
2371 ok(SUCCEEDED(hr), "Failed to set fog end, hr %#lx.\n", hr);
2373 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
2374 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
2375 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
2376 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog vertex mode, hr %#lx.\n", hr);
2377 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
2378 ok(SUCCEEDED(hr), "Failed to set D3DFOG_NONE fog table mode, hr %#lx.\n", hr);
2380 /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512.
2381 * Would result in a completely fog-free primitive because start > zcoord,
2382 * but because start == end, the primitive is fully covered by fog. The
2383 * same happens to the 2nd untransformed quad with z = 1.0. The third
2384 * transformed quad remains unfogged because the fogcoords are read from
2385 * the specular color and has fixed fogstart and fogend. */
2386 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
2387 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
2388 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
2389 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
2390 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
2391 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
2393 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
2394 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
2395 /* Transformed, vertex fog != NONE, pixel fog == NONE:
2396 * Use specular color alpha component. */
2397 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
2398 2 /* PrimCount */, Indices, D3DFMT_INDEX16, transformed_1, sizeof(transformed_1[0]));
2399 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
2401 hr = IDirect3DDevice9_EndScene(device);
2402 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
2404 color = getPixelColor(device, 160, 360);
2405 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
2406 color = getPixelColor(device, 160, 120);
2407 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
2408 color = getPixelColor(device, 480, 120);
2409 ok(color == 0x00ffff00, "Transformed vertex with linear vertex fog has color %08x\n", color);
2410 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2412 /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
2413 * but without shaders it seems to work everywhere
2415 end = 0.2;
2416 start = 0.8;
2417 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
2418 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2419 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
2420 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2421 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2422 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2424 /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
2425 * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
2426 * so skip this for now
2428 for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
2429 const char *mode = (i ? "table" : "vertex");
2430 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
2431 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2432 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
2433 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2434 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
2435 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2436 hr = IDirect3DDevice9_BeginScene(device);
2437 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
2438 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 16 /* NumVerts */,
2439 8 /* PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads, sizeof(rev_fog_quads[0]));
2440 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
2441 hr = IDirect3DDevice9_EndScene(device);
2442 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
2444 color = getPixelColor(device, 160, 360);
2445 ok(color_match(color, 0x0000ff00, 1),
2446 "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00 or 0x0000fe00\n", mode, color);
2448 color = getPixelColor(device, 160, 120);
2449 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x2b, 0xd4), 2),
2450 "Reversed %s fog: z=0.7 has color 0x%08x\n", mode, color);
2452 color = getPixelColor(device, 480, 120);
2453 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xaa, 0x55), 2),
2454 "Reversed %s fog: z=0.4 has color 0x%08x\n", mode, color);
2456 color = getPixelColor(device, 480, 360);
2457 ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
2459 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2461 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
2462 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
2463 break;
2467 if (caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
2469 /* A simple fog + non-identity world matrix test */
2470 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), &world_mat1);
2471 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2473 start = 0.0;
2474 end = 1.0;
2475 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *)&start));
2476 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2477 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *)&end));
2478 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2479 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
2480 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2481 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
2482 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2484 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
2485 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2487 hr = IDirect3DDevice9_BeginScene(device);
2488 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
2490 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
2491 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
2493 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
2494 2, Indices, D3DFMT_INDEX16, far_quad1, sizeof(far_quad1[0]));
2495 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
2496 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
2497 2, Indices, D3DFMT_INDEX16, far_quad2, sizeof(far_quad2[0]));
2498 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
2500 hr = IDirect3DDevice9_EndScene(device);
2501 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
2503 color = getPixelColor(device, 160, 360);
2504 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 4),
2505 "Unfogged quad has color %08x\n", color);
2506 color = getPixelColor(device, 160, 120);
2507 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2508 "Fogged out quad has color %08x\n", color);
2510 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2512 /* Test fog behavior with an orthogonal (but non-identity) projection matrix */
2513 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), &world_mat2);
2514 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2515 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &proj_mat);
2516 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2518 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
2519 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2521 hr = IDirect3DDevice9_BeginScene(device);
2522 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
2524 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
2525 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
2527 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
2528 2, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
2529 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
2530 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
2531 2, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
2532 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
2534 hr = IDirect3DDevice9_EndScene(device);
2535 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
2537 color = getPixelColor(device, 160, 360);
2538 ok(color_match(color, 0x00e51900, 4), "Partially fogged quad has color %08x\n", color);
2539 color = getPixelColor(device, 160, 120);
2540 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2541 "Fogged out quad has color %08x\n", color);
2543 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2545 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), &ident_mat);
2546 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2547 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &ident_mat);
2548 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2550 else
2552 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
2555 /* Test RANGEFOG vs FOGTABLEMODE */
2556 if ((caps.RasterCaps & (D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_FOGRANGE)) ==
2557 (D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_FOGRANGE))
2559 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
2560 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#lx.\n", hr);
2561 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
2562 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#lx.\n", hr);
2564 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_RANGEFOGENABLE, TRUE);
2565 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#lx.\n", hr);
2567 /* z=0.5, x = +/- 1.0, y = +/- 1.0. In case of z fog the fog coordinate is
2568 * 0.5. With range fog it is sqrt(x*x + y*y + z*z) = 1.5 for all vertices.
2569 * Note that the fog coordinate is interpolated linearly across the vertices,
2570 * so the different eye distance at the screen center should not matter. */
2571 start = 0.75f;
2572 end = 0.75001f;
2573 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
2574 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#lx.\n", hr);
2575 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
2576 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#lx.\n", hr);
2578 /* Table fog: Range fog is not used */
2579 hr = IDirect3DDevice9_BeginScene(device);
2580 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
2582 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
2583 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog table mode, hr %#lx.\n", hr);
2584 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
2585 untransformed_3, sizeof(*untransformed_3));
2586 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
2588 hr = IDirect3DDevice9_EndScene(device);
2589 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
2591 color = getPixelColor(device, 10, 10);
2592 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
2593 color = getPixelColor(device, 630, 10);
2594 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
2595 color = getPixelColor(device, 10, 470);
2596 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
2597 color = getPixelColor(device, 630, 470);
2598 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
2600 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2601 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed, hr %#lx.\n", hr);
2603 /* Vertex fog: Rangefog is used */
2604 hr = IDirect3DDevice9_BeginScene(device);
2605 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
2607 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
2608 ok(SUCCEEDED(hr), "Failed to set D3DFOG_NONE fog table mode, hr %#lx.\n", hr);
2609 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
2610 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog vertex mode, hr %#lx.\n", hr);
2611 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
2612 untransformed_3, sizeof(*untransformed_3));
2613 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
2615 hr = IDirect3DDevice9_EndScene(device);
2616 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
2618 color = getPixelColor(device, 10, 10);
2619 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2620 "Rangefog with vertex fog returned color 0x%08x\n", color);
2621 color = getPixelColor(device, 630, 10);
2622 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2623 "Rangefog with vertex fog returned color 0x%08x\n", color);
2624 color = getPixelColor(device, 10, 470);
2625 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2626 "Rangefog with vertex fog returned color 0x%08x\n", color);
2627 color = getPixelColor(device, 630, 470);
2628 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2629 "Rangefog with vertex fog returned color 0x%08x\n", color);
2631 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2632 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed, hr %#lx.\n", hr);
2634 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_RANGEFOGENABLE, FALSE);
2635 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#lx.\n", hr);
2637 else
2639 skip("Range fog or table fog not supported, skipping range fog tests\n");
2642 refcount = IDirect3DDevice9_Release(device);
2643 ok(!refcount, "Device has %lu references left.\n", refcount);
2644 done:
2645 IDirect3D9_Release(d3d);
2646 DestroyWindow(window);
2649 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
2650 * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
2651 * regardless of the actual addressing mode set. The way this test works is
2652 * that we sample in one of the corners of the cubemap with filtering enabled,
2653 * and check the interpolated color. There are essentially two reasonable
2654 * things an implementation can do: Either pick one of the faces and
2655 * interpolate the edge texel with itself (i.e., clamp within the face), or
2656 * interpolate between the edge texels of the three involved faces. It should
2657 * never involve the border color or the other side (texcoord wrapping) of a
2658 * face in the interpolation. */
2659 static void test_cube_wrap(void)
2661 IDirect3DVertexDeclaration9 *vertex_declaration;
2662 IDirect3DSurface9 *face_surface, *surface;
2663 IDirect3DCubeTexture9 *texture;
2664 D3DLOCKED_RECT locked_rect;
2665 IDirect3DDevice9 *device;
2666 unsigned int x, y, face;
2667 IDirect3D9 *d3d;
2668 ULONG refcount;
2669 D3DCAPS9 caps;
2670 HWND window;
2671 HRESULT hr;
2673 static const float quad[][6] =
2675 {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
2676 {-1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
2677 { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
2678 { 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
2680 static const D3DVERTEXELEMENT9 decl_elements[] =
2682 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2683 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2684 D3DDECL_END()
2686 static const struct
2688 D3DTEXTUREADDRESS mode;
2689 const char *name;
2691 address_modes[] =
2693 {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
2694 {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
2695 {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
2696 {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
2697 {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
2700 window = create_window();
2701 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2702 ok(!!d3d, "Failed to create a D3D object.\n");
2703 if (!(device = create_device(d3d, window, window, TRUE)))
2705 skip("Failed to create a D3D device, skipping tests.\n");
2706 goto done;
2709 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2710 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
2711 if (!(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP))
2713 skip("No cube texture support, skipping tests.\n");
2714 IDirect3DDevice9_Release(device);
2715 goto done;
2718 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
2719 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2720 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
2721 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2723 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
2724 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
2725 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2727 hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
2728 D3DPOOL_DEFAULT, &texture, NULL);
2729 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2731 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
2732 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2734 for (y = 0; y < 128; ++y)
2736 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2737 for (x = 0; x < 64; ++x)
2739 *ptr++ = 0xff0000ff;
2741 for (x = 64; x < 128; ++x)
2743 *ptr++ = 0xffff0000;
2747 hr = IDirect3DSurface9_UnlockRect(surface);
2748 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2750 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, 0, 0, &face_surface);
2751 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2753 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
2754 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2756 IDirect3DSurface9_Release(face_surface);
2758 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
2759 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2761 for (y = 0; y < 128; ++y)
2763 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2764 for (x = 0; x < 64; ++x)
2766 *ptr++ = 0xffff0000;
2768 for (x = 64; x < 128; ++x)
2770 *ptr++ = 0xff0000ff;
2774 hr = IDirect3DSurface9_UnlockRect(surface);
2775 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2777 /* Create cube faces */
2778 for (face = 1; face < 6; ++face)
2780 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
2781 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2783 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
2784 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2786 IDirect3DSurface9_Release(face_surface);
2789 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
2790 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2792 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
2793 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2794 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
2795 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2796 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
2797 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2799 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2800 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2802 for (x = 0; x < ARRAY_SIZE(address_modes); ++x)
2804 unsigned int color;
2806 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
2807 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2808 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
2809 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2811 hr = IDirect3DDevice9_BeginScene(device);
2812 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2814 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
2815 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2817 hr = IDirect3DDevice9_EndScene(device);
2818 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2820 color = getPixelColor(device, 320, 240);
2821 /* Modern AMD GPUs do slip into reading the border color. */
2822 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1)
2823 || broken(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xbf, 0x40), 1)
2824 && address_modes[x].mode == D3DTADDRESS_BORDER),
2825 "Got color 0x%08x for addressing mode %s, expected 0x000000ff.\n",
2826 color, address_modes[x].name);
2828 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2829 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2831 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
2832 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2835 IDirect3DVertexDeclaration9_Release(vertex_declaration);
2836 IDirect3DCubeTexture9_Release(texture);
2837 IDirect3DSurface9_Release(surface);
2838 refcount = IDirect3DDevice9_Release(device);
2839 ok(!refcount, "Device has %lu references left.\n", refcount);
2840 done:
2841 IDirect3D9_Release(d3d);
2842 DestroyWindow(window);
2845 static void offscreen_test(void)
2847 IDirect3DSurface9 *backbuffer, *offscreen;
2848 IDirect3DTexture9 *offscreenTexture;
2849 IDirect3DDevice9 *device;
2850 unsigned int color;
2851 IDirect3D9 *d3d;
2852 ULONG refcount;
2853 HWND window;
2854 HRESULT hr;
2856 static const float quad[][5] =
2858 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
2859 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
2860 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
2861 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
2864 window = create_window();
2865 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2866 ok(!!d3d, "Failed to create a D3D object.\n");
2867 if (!(device = create_device(d3d, window, window, TRUE)))
2869 skip("Failed to create a D3D device, skipping tests.\n");
2870 goto done;
2873 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
2874 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2876 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
2877 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
2878 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
2879 if (!offscreenTexture)
2881 trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5.\n");
2882 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
2883 D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
2884 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
2885 if (!offscreenTexture)
2887 skip("Cannot create an offscreen render target.\n");
2888 IDirect3DDevice9_Release(device);
2889 goto done;
2893 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2894 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2896 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
2897 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2899 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2900 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2902 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
2903 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2904 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
2905 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2906 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
2907 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2908 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
2909 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2910 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2911 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2913 hr = IDirect3DDevice9_BeginScene(device);
2914 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
2916 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
2917 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
2918 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 1.0f, 0);
2919 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
2921 /* Draw without textures - Should result in a white quad. */
2922 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
2923 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
2925 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
2926 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
2927 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)offscreenTexture);
2928 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
2930 /* This time with the texture. */
2931 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
2932 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
2934 hr = IDirect3DDevice9_EndScene(device);
2935 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
2937 /* Center quad - should be white */
2938 color = getPixelColor(device, 320, 240);
2939 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2940 /* Some quad in the cleared part of the texture */
2941 color = getPixelColor(device, 170, 240);
2942 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
2943 /* Part of the originally cleared back buffer */
2944 color = getPixelColor(device, 10, 10);
2945 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2946 color = getPixelColor(device, 10, 470);
2947 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2949 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2951 IDirect3DSurface9_Release(backbuffer);
2952 IDirect3DTexture9_Release(offscreenTexture);
2953 IDirect3DSurface9_Release(offscreen);
2954 refcount = IDirect3DDevice9_Release(device);
2955 ok(!refcount, "Device has %lu references left.\n", refcount);
2956 done:
2957 IDirect3D9_Release(d3d);
2958 DestroyWindow(window);
2961 /* This test tests fog in combination with shaders.
2962 * What's tested: linear fog (vertex and table) with pixel shader
2963 * linear table fog with non foggy vertex shader
2964 * vertex fog with foggy vertex shader, non-linear
2965 * fog with shader, non-linear fog with foggy shader,
2966 * linear table fog with foggy shader */
2967 static void fog_with_shader_test(void)
2969 IDirect3DVertexShader9 *vertex_shader[4] = {NULL, NULL, NULL, NULL};
2970 IDirect3DPixelShader9 *pixel_shader[3] = {NULL, NULL, NULL};
2971 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
2972 IDirect3DDevice9 *device;
2973 unsigned int color, i, j;
2974 IDirect3D9 *d3d;
2975 ULONG refcount;
2976 D3DCAPS9 caps;
2977 HWND window;
2978 HRESULT hr;
2979 union
2981 float f;
2982 DWORD i;
2983 } start, end;
2985 /* basic vertex shader without fog computation ("non foggy") */
2986 static const DWORD vertex_shader_code1[] =
2988 0xfffe0101, /* vs_1_1 */
2989 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2990 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
2991 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2992 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
2993 0x0000ffff
2995 /* basic vertex shader with reversed fog computation ("foggy") */
2996 static const DWORD vertex_shader_code2[] =
2998 0xfffe0101, /* vs_1_1 */
2999 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
3000 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
3001 0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
3002 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
3003 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
3004 0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
3005 0x00000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
3006 0x0000ffff
3008 /* basic vertex shader with reversed fog computation ("foggy"), vs_2_0 */
3009 static const DWORD vertex_shader_code3[] =
3011 0xfffe0200, /* vs_2_0 */
3012 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
3013 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
3014 0x05000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
3015 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
3016 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
3017 0x03000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
3018 0x03000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
3019 0x0000ffff
3021 /* basic pixel shader */
3022 static const DWORD pixel_shader_code[] =
3024 0xffff0101, /* ps_1_1 */
3025 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
3026 0x0000ffff
3028 static const DWORD pixel_shader_code2[] =
3030 0xffff0200, /* ps_2_0 */
3031 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
3032 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
3033 0x0000ffff
3035 struct
3037 struct vec3 position;
3038 DWORD diffuse;
3040 quad[] =
3042 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
3043 {{-1.0f, 1.0f, 0.0f}, 0xffff0000},
3044 {{ 1.0f, -1.0f, 0.0f}, 0xffff0000},
3045 {{ 1.0f, 1.0f, 0.0f}, 0xffff0000},
3047 static const D3DVERTEXELEMENT9 decl_elements[] =
3049 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3050 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
3051 D3DDECL_END()
3053 /* This reference data was collected on a nVidia GeForce 7600GS driver
3054 * version 84.19 DirectX version 9.0c on Windows XP. */
3055 static const struct test_data_t
3057 int vshader;
3058 int pshader;
3059 D3DFOGMODE vfog;
3060 D3DFOGMODE tfog;
3061 unsigned int color[11];
3063 test_data[] =
3065 /* only pixel shader: */
3066 {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
3067 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
3068 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
3069 {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
3070 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
3071 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
3072 {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
3073 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
3074 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
3075 {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
3076 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
3077 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
3078 {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
3079 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
3080 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
3082 /* vertex shader */
3083 {1, 0, D3DFOG_NONE, D3DFOG_NONE,
3084 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
3085 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
3086 {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
3087 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
3088 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
3089 {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
3090 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
3091 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
3093 {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
3094 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
3095 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
3096 {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
3097 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
3098 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
3100 /* vertex shader and pixel shader */
3101 /* The next 4 tests would read the fog coord output, but it isn't available.
3102 * The result is a fully fogged quad, no matter what the Z coord is. This is on
3103 * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
3104 * These tests should be disabled if some other hardware behaves differently
3106 {1, 1, D3DFOG_NONE, D3DFOG_NONE,
3107 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
3108 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
3109 {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
3110 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
3111 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
3112 {1, 1, D3DFOG_EXP, D3DFOG_NONE,
3113 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
3114 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
3115 {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
3116 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
3117 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
3119 /* These use the Z coordinate with linear table fog */
3120 {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
3121 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
3122 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
3123 {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
3124 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
3125 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
3126 {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
3127 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
3128 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
3129 {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
3130 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
3131 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
3133 /* Non-linear table fog without fog coord */
3134 {1, 1, D3DFOG_NONE, D3DFOG_EXP,
3135 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
3136 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
3137 {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
3138 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
3139 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
3141 /* These tests fail on older Nvidia drivers */
3142 /* foggy vertex shader */
3143 {2, 0, D3DFOG_NONE, D3DFOG_NONE,
3144 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
3145 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
3146 {2, 0, D3DFOG_EXP, D3DFOG_NONE,
3147 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
3148 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
3149 {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
3150 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
3151 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
3152 {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
3153 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
3154 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
3156 {3, 0, D3DFOG_NONE, D3DFOG_NONE,
3157 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
3158 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
3159 {3, 0, D3DFOG_EXP, D3DFOG_NONE,
3160 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
3161 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
3162 {3, 0, D3DFOG_EXP2, D3DFOG_NONE,
3163 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
3164 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
3165 {3, 0, D3DFOG_LINEAR, D3DFOG_NONE,
3166 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
3167 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
3169 /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
3170 * all using the fixed fog-coord linear fog
3172 /* vs_1_1 with ps_1_1 */
3173 {2, 1, D3DFOG_NONE, D3DFOG_NONE,
3174 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
3175 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
3176 {2, 1, D3DFOG_EXP, D3DFOG_NONE,
3177 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
3178 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
3179 {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
3180 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
3181 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
3182 {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
3183 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
3184 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
3186 /* vs_2_0 with ps_1_1 */
3187 {3, 1, D3DFOG_NONE, D3DFOG_NONE,
3188 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
3189 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
3190 {3, 1, D3DFOG_EXP, D3DFOG_NONE,
3191 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
3192 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
3193 {3, 1, D3DFOG_EXP2, D3DFOG_NONE,
3194 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
3195 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
3196 {3, 1, D3DFOG_LINEAR, D3DFOG_NONE,
3197 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
3198 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
3200 /* vs_1_1 with ps_2_0 */
3201 {2, 2, D3DFOG_NONE, D3DFOG_NONE,
3202 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
3203 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
3204 {2, 2, D3DFOG_EXP, D3DFOG_NONE,
3205 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
3206 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
3207 {2, 2, D3DFOG_EXP2, D3DFOG_NONE,
3208 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
3209 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
3210 {2, 2, D3DFOG_LINEAR, D3DFOG_NONE,
3211 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
3212 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
3214 /* vs_2_0 with ps_2_0 */
3215 {3, 2, D3DFOG_NONE, D3DFOG_NONE,
3216 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
3217 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
3218 {3, 2, D3DFOG_EXP, D3DFOG_NONE,
3219 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
3220 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
3221 {3, 2, D3DFOG_EXP2, D3DFOG_NONE,
3222 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
3223 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
3224 {3, 2, D3DFOG_LINEAR, D3DFOG_NONE,
3225 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
3226 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
3228 /* These use table fog. Here the shader-provided fog coordinate is
3229 * ignored and the z coordinate used instead
3231 {2, 1, D3DFOG_NONE, D3DFOG_EXP,
3232 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
3233 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
3234 {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
3235 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
3236 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
3237 {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
3238 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
3239 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
3241 static const D3DMATRIX identity =
3243 1.0f, 0.0f, 0.0f, 0.0f,
3244 0.0f, 1.0f, 0.0f, 0.0f,
3245 0.0f, 0.0f, 1.0f, 0.0f,
3246 0.0f, 0.0f, 0.0f, 1.0f,
3247 }}};
3249 window = create_window();
3250 d3d = Direct3DCreate9(D3D_SDK_VERSION);
3251 ok(!!d3d, "Failed to create a D3D object.\n");
3252 if (!(device = create_device(d3d, window, window, TRUE)))
3254 skip("Failed to create a D3D device, skipping tests.\n");
3255 goto done;
3258 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3259 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
3260 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0) || caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
3262 skip("No shader model 2 support, skipping tests.\n");
3263 IDirect3DDevice9_Release(device);
3264 goto done;
3267 /* NOTE: Changing these values will not affect the tests with foggy vertex
3268 * shader, as the values are hardcoded in the shader. */
3269 start.f = 0.1f;
3270 end.f = 0.9f;
3272 /* Some of the tests seem to depend on the projection matrix explicitly
3273 * being set to an identity matrix, even though that's the default.
3274 * (AMD Radeon HD 6310, Windows 7) */
3275 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
3276 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#lx.\n", hr);
3278 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
3279 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3280 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
3281 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3282 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code3, &vertex_shader[3]);
3283 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3284 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
3285 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3286 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code2, &pixel_shader[2]);
3287 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3288 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
3289 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3291 /* Setup initial states: No lighting, fog on, fog color */
3292 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3293 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3294 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
3295 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3296 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xff00ff00 /* A nice green */);
3297 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3298 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
3299 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3301 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
3302 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3303 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
3304 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3306 /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
3307 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
3308 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3309 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
3310 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3312 for (i = 0; i < ARRAY_SIZE(test_data); i++)
3314 hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
3315 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3316 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
3317 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3318 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
3319 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3320 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
3321 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3323 for(j=0; j < 11; j++)
3325 /* Don't use the whole zrange to prevent rounding errors */
3326 quad[0].position.z = 0.001f + (float)j / 10.02f;
3327 quad[1].position.z = 0.001f + (float)j / 10.02f;
3328 quad[2].position.z = 0.001f + (float)j / 10.02f;
3329 quad[3].position.z = 0.001f + (float)j / 10.02f;
3331 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff00ff, 1.0f, 0);
3332 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3334 hr = IDirect3DDevice9_BeginScene(device);
3335 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3337 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
3338 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3340 hr = IDirect3DDevice9_EndScene(device);
3341 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3343 /* As the red and green component are the result of blending use 5% tolerance on the expected value */
3344 color = getPixelColor(device, 128, 240);
3345 ok(color_match(color, test_data[i].color[j], 13),
3346 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
3347 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
3350 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3352 IDirect3DVertexShader9_Release(vertex_shader[1]);
3353 IDirect3DVertexShader9_Release(vertex_shader[2]);
3354 IDirect3DVertexShader9_Release(vertex_shader[3]);
3355 IDirect3DPixelShader9_Release(pixel_shader[1]);
3356 IDirect3DPixelShader9_Release(pixel_shader[2]);
3357 IDirect3DVertexDeclaration9_Release(vertex_declaration);
3358 refcount = IDirect3DDevice9_Release(device);
3359 ok(!refcount, "Device has %lu references left.\n", refcount);
3360 done:
3361 IDirect3D9_Release(d3d);
3362 DestroyWindow(window);
3365 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
3366 int i, x, y;
3367 HRESULT hr;
3368 IDirect3DTexture9 *texture[2] = {NULL, NULL};
3369 D3DLOCKED_RECT locked_rect;
3371 /* Generate the textures */
3372 for(i=0; i<2; i++)
3374 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
3375 D3DPOOL_MANAGED, &texture[i], NULL);
3376 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3378 hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
3379 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3380 for (y = 0; y < 128; ++y)
3382 if(i)
3384 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
3385 for (x = 0; x < 128; ++x)
3387 *ptr++ = D3DCOLOR_ARGB(0xff, x * 2, y * 2, 0);
3390 else
3391 { /* Set up a displacement map which points away from the center parallel to the closest axis.
3392 * (if multiplied with bumpenvmat)
3394 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
3395 for (x = 0; x < 128; ++x)
3397 if(abs(x-64)>abs(y-64))
3399 if(x < 64)
3400 *ptr++ = 0xc000;
3401 else
3402 *ptr++ = 0x4000;
3404 else
3406 if(y < 64)
3407 *ptr++ = 0x0040;
3408 else
3409 *ptr++ = 0x00c0;
3414 hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
3415 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3417 hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
3418 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3420 /* Disable texture filtering */
3421 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
3422 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3423 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
3424 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3426 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3427 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3428 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3429 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3433 /* Test the behavior of the texbem instruction with normal 2D and projective
3434 * 2D textures. */
3435 static void texbem_test(void)
3437 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
3438 /* Use asymmetric matrix to test loading. */
3439 float bumpenvmat[4] = {0.0f, 0.5f, -0.5f, 0.0f};
3440 IDirect3DPixelShader9 *pixel_shader = NULL;
3441 IDirect3DTexture9 *texture1, *texture2;
3442 IDirect3DTexture9 *texture = NULL;
3443 D3DLOCKED_RECT locked_rect;
3444 IDirect3DDevice9 *device;
3445 unsigned int color, i;
3446 IDirect3D9 *d3d;
3447 ULONG refcount;
3448 D3DCAPS9 caps;
3449 HWND window;
3450 HRESULT hr;
3452 static const DWORD pixel_shader_code[] =
3454 0xffff0101, /* ps_1_1*/
3455 0x00000042, 0xb00f0000, /* tex t0*/
3456 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
3457 0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
3458 0x0000ffff
3460 static const DWORD double_texbem_code[] =
3462 0xffff0103, /* ps_1_3 */
3463 0x00000042, 0xb00f0000, /* tex t0 */
3464 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0 */
3465 0x00000042, 0xb00f0002, /* tex t2 */
3466 0x00000043, 0xb00f0003, 0xb0e40002, /* texbem t3, t2 */
3467 0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003, /* add r0, t1, t3 */
3468 0x0000ffff /* end */
3470 static const float quad[][7] =
3472 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
3473 {-1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
3474 { 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
3475 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
3477 static const float quad_proj[][9] =
3479 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 128.0f},
3480 {-1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f, 128.0f, 0.0f, 128.0f},
3481 { 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 128.0f, 0.0f, 0.0f, 128.0f},
3482 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
3484 static const float double_quad[] =
3486 -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f,
3487 -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f,
3488 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f,
3489 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f,
3491 static const D3DVERTEXELEMENT9 decl_elements[][4] =
3494 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3495 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3496 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
3497 D3DDECL_END()
3500 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3501 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3502 {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
3503 D3DDECL_END()
3507 window = create_window();
3508 d3d = Direct3DCreate9(D3D_SDK_VERSION);
3509 ok(!!d3d, "Failed to create a D3D object.\n");
3510 if (!(device = create_device(d3d, window, window, TRUE)))
3512 skip("Failed to create a D3D device, skipping tests.\n");
3513 goto done;
3516 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3517 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
3518 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
3520 skip("No ps_1_1 support, skipping tests.\n");
3521 IDirect3DDevice9_Release(device);
3522 goto done;
3525 generate_bumpmap_textures(device);
3527 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, float_to_int(bumpenvmat[0]));
3528 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, float_to_int(bumpenvmat[1]));
3529 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, float_to_int(bumpenvmat[2]));
3530 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, float_to_int(bumpenvmat[3]));
3531 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3533 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
3534 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3536 for(i=0; i<2; i++)
3538 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
3539 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3541 if(i)
3543 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
3544 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3547 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
3548 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3549 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
3550 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3552 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
3553 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3554 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
3555 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3557 hr = IDirect3DDevice9_BeginScene(device);
3558 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3560 if(!i)
3561 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
3562 else
3563 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
3564 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3566 hr = IDirect3DDevice9_EndScene(device);
3567 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3569 /* The Window 8 testbot (WARP) seems to use the transposed
3570 * D3DTSS_BUMPENVMAT matrix. */
3571 color = getPixelColor(device, 160, 240);
3572 ok(color_match(color, 0x007e8000, 4) || broken(color_match(color, 0x00007e00, 4)),
3573 "Got unexpected color 0x%08x.\n", color);
3574 color = getPixelColor(device, 480, 240);
3575 ok(color_match(color, 0x007e8000, 4) || broken(color_match(color, 0x00fe7e00, 4)),
3576 "Got unexpected color 0x%08x.\n", color);
3577 color = getPixelColor(device, 320, 120);
3578 ok(color_match(color, 0x007e8000, 4) || broken(color_match(color, 0x0080fe00, 4)),
3579 "Got unexpected color 0x%08x.\n", color);
3580 color = getPixelColor(device, 320, 360);
3581 ok(color_match(color, 0x007e8000, 4) || broken(color_match(color, 0x00800000, 4)),
3582 "Got unexpected color 0x%08x.\n", color);
3584 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3585 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3587 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3588 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3589 IDirect3DPixelShader9_Release(pixel_shader);
3591 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
3592 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3593 IDirect3DVertexDeclaration9_Release(vertex_declaration);
3596 /* clean up */
3597 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
3598 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3600 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3601 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3603 for(i=0; i<2; i++)
3605 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
3606 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3607 IDirect3DTexture9_Release(texture); /* For the GetTexture */
3608 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
3609 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3610 IDirect3DTexture9_Release(texture);
3613 /* Test double texbem */
3614 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
3615 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3616 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
3617 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3618 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
3619 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3620 hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
3621 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3623 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
3624 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3625 ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
3626 ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
3628 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3629 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3631 hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
3632 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3633 ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
3634 ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
3635 hr = IDirect3DTexture9_UnlockRect(texture1, 0);
3636 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3639 /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
3640 #define tex 0x00ff0000
3641 #define tex1 0x0000ff00
3642 #define origin 0x000000ff
3643 static const DWORD pixel_data[] = {
3644 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3645 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3646 0x000000ff, tex1 , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3647 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3648 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin, 0x000000ff, tex , 0x000000ff,
3649 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3650 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3651 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3653 #undef tex
3654 #undef tex1
3655 #undef origin
3657 hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
3658 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3659 for(i = 0; i < 8; i++) {
3660 memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
3662 hr = IDirect3DTexture9_UnlockRect(texture2, 0);
3663 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3666 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3667 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3668 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
3669 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3670 hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
3671 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3672 hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
3673 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3674 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
3675 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3676 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
3677 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3679 bumpenvmat[0] =-1.0; bumpenvmat[2] = 2.0;
3680 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.0;
3681 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, float_to_int(bumpenvmat[0]));
3682 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3683 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, float_to_int(bumpenvmat[1]));
3684 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3685 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, float_to_int(bumpenvmat[2]));
3686 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3687 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, float_to_int(bumpenvmat[3]));
3688 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3690 bumpenvmat[0] = 1.5; bumpenvmat[2] = 0.0;
3691 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.5;
3692 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, float_to_int(bumpenvmat[0]));
3693 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3694 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, float_to_int(bumpenvmat[1]));
3695 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3696 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, float_to_int(bumpenvmat[2]));
3697 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3698 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, float_to_int(bumpenvmat[3]));
3699 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3701 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3702 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3703 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3704 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3705 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3706 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3707 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3708 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3709 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3710 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3711 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3712 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3713 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3714 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3715 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3716 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3718 hr = IDirect3DDevice9_BeginScene(device);
3719 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
3720 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
3721 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#lx.\n", hr);
3722 hr = IDirect3DDevice9_EndScene(device);
3723 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
3724 /* The Window 8 testbot (WARP) seems to use the transposed
3725 * D3DTSS_BUMPENVMAT matrix. */
3726 color = getPixelColor(device, 320, 240);
3727 ok(color_match(color, 0x00ffff00, 1) || broken(color_match(color, 0x0000ffff, 1)),
3728 "Got unexpected color 0x%08x.\n", color);
3730 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3731 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3733 IDirect3DPixelShader9_Release(pixel_shader);
3734 IDirect3DTexture9_Release(texture);
3735 IDirect3DTexture9_Release(texture1);
3736 IDirect3DTexture9_Release(texture2);
3737 refcount = IDirect3DDevice9_Release(device);
3738 ok(!refcount, "Device has %lu references left.\n", refcount);
3739 done:
3740 IDirect3D9_Release(d3d);
3741 DestroyWindow(window);
3744 static void z_range_test(void)
3746 IDirect3DVertexShader9 *shader;
3747 IDirect3DDevice9 *device;
3748 unsigned int color;
3749 IDirect3D9 *d3d;
3750 ULONG refcount;
3751 D3DCAPS9 caps;
3752 HWND window;
3753 HRESULT hr;
3755 static const struct
3757 struct vec3 position;
3758 DWORD diffuse;
3760 quad[] =
3762 {{-1.0f, 0.0f, 1.1f}, 0xffff0000},
3763 {{-1.0f, 1.0f, 1.1f}, 0xffff0000},
3764 {{ 1.0f, 0.0f, -1.1f}, 0xffff0000},
3765 {{ 1.0f, 1.0f, -1.1f}, 0xffff0000},
3767 quad2[] =
3769 {{-1.0f, 0.0f, 1.1f}, 0xff0000ff},
3770 {{-1.0f, 1.0f, 1.1f}, 0xff0000ff},
3771 {{ 1.0f, 0.0f, -1.1f}, 0xff0000ff},
3772 {{ 1.0f, 1.0f, -1.1f}, 0xff0000ff},
3774 static const struct
3776 struct vec4 position;
3777 DWORD diffuse;
3779 quad3[] =
3781 {{640.0f, 240.0f, -1.1f, 1.0f}, 0xffffff00},
3782 {{640.0f, 480.0f, -1.1f, 1.0f}, 0xffffff00},
3783 {{ 0.0f, 240.0f, 1.1f, 1.0f}, 0xffffff00},
3784 {{ 0.0f, 480.0f, 1.1f, 1.0f}, 0xffffff00},
3786 quad4[] =
3788 {{640.0f, 240.0f, -1.1f, 1.0f}, 0xff00ff00},
3789 {{640.0f, 480.0f, -1.1f, 1.0f}, 0xff00ff00},
3790 {{ 0.0f, 240.0f, 1.1f, 1.0f}, 0xff00ff00},
3791 {{ 0.0f, 480.0f, 1.1f, 1.0f}, 0xff00ff00},
3793 static const DWORD shader_code[] =
3795 0xfffe0101, /* vs_1_1 */
3796 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
3797 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
3798 0x00000001, 0xd00f0000, 0xa0e40000, /* mov oD0, c0 */
3799 0x0000ffff /* end */
3801 static const float color_const_1[] = {1.0f, 0.0f, 0.0f, 1.0f};
3802 static const float color_const_2[] = {0.0f, 0.0f, 1.0f, 1.0f};
3804 window = create_window();
3805 d3d = Direct3DCreate9(D3D_SDK_VERSION);
3806 ok(!!d3d, "Failed to create a D3D object.\n");
3807 if (!(device = create_device(d3d, window, window, TRUE)))
3809 skip("Failed to create a D3D device, skipping tests.\n");
3810 goto done;
3813 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3814 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
3816 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
3817 * then call Present. Then clear the color buffer to make sure it has some defined content
3818 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
3819 * by the depth value. */
3820 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75f, 0);
3821 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
3822 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3823 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
3824 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
3825 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
3827 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3828 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
3829 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
3830 ok(SUCCEEDED(hr), "Failed to enable clipping, hr %#lx.\n", hr);
3831 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3832 ok(SUCCEEDED(hr), "Failed to enable z test, hr %#lx.\n", hr);
3833 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3834 ok(SUCCEEDED(hr), "Failed to disable z writes, hr %#lx.\n", hr);
3835 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
3836 ok(SUCCEEDED(hr), "Failed to set z function, hr %#lx.\n", hr);
3837 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3838 ok(SUCCEEDED(hr), "Failed set FVF, hr %#lx.\n", hr);
3840 hr = IDirect3DDevice9_BeginScene(device);
3841 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
3843 /* Test the untransformed vertex path */
3844 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
3845 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
3846 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
3847 ok(SUCCEEDED(hr), "Failed to set z function, hr %#lx.\n", hr);
3848 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
3849 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
3851 /* Test the transformed vertex path */
3852 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
3853 ok(SUCCEEDED(hr), "Failed set FVF, hr %#lx.\n", hr);
3855 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
3856 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
3857 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
3858 ok(SUCCEEDED(hr), "Failed to set z function, hr %#lx.\n", hr);
3859 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
3860 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
3862 hr = IDirect3DDevice9_EndScene(device);
3863 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
3865 /* Do not test the exact corner pixels, but go pretty close to them */
3867 /* Clipped because z > 1.0 */
3868 color = getPixelColor(device, 28, 238);
3869 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3870 color = getPixelColor(device, 28, 241);
3871 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
3872 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3873 else
3874 ok(color_match(color, 0x00ffff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
3876 /* Not clipped, > z buffer clear value(0.75).
3878 * On the r500 driver on Windows D3DCMP_GREATER and D3DCMP_GREATEREQUAL are broken for depth
3879 * values > 0.5. The range appears to be distorted, apparently an incoming value of ~0.875 is
3880 * equal to a stored depth buffer value of 0.5. */
3881 color = getPixelColor(device, 31, 238);
3882 ok(color_match(color, 0x00ff0000, 0), "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
3883 color = getPixelColor(device, 31, 241);
3884 ok(color_match(color, 0x00ffff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
3885 color = getPixelColor(device, 100, 238);
3886 ok(color_match(color, 0x00ff0000, 0) || broken(color_match(color, 0x00ffffff, 0)),
3887 "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
3888 color = getPixelColor(device, 100, 241);
3889 ok(color_match(color, 0x00ffff00, 0) || broken(color_match(color, 0x00ffffff, 0)),
3890 "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
3892 /* Not clipped, < z buffer clear value */
3893 color = getPixelColor(device, 104, 238);
3894 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
3895 color = getPixelColor(device, 104, 241);
3896 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
3897 color = getPixelColor(device, 318, 238);
3898 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
3899 color = getPixelColor(device, 318, 241);
3900 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
3902 /* Clipped because z < 0.0 */
3903 color = getPixelColor(device, 321, 238);
3904 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3905 color = getPixelColor(device, 321, 241);
3906 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
3907 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3908 else
3909 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3911 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3912 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
3914 /* Test the shader path */
3915 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
3917 skip("Vertex shaders not supported, skipping tests.\n");
3918 IDirect3DDevice9_Release(device);
3919 goto done;
3921 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
3922 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#lx.\n", hr);
3924 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
3925 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
3927 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3928 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
3929 hr = IDirect3DDevice9_SetVertexShader(device, shader);
3930 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
3932 hr = IDirect3DDevice9_BeginScene(device);
3933 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
3935 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, color_const_1, 1);
3936 ok(SUCCEEDED(hr), "Failed to set vs constant 0, hr %#lx.\n", hr);
3937 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
3938 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
3940 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
3941 ok(SUCCEEDED(hr), "Failed to set z function, hr %#lx.\n", hr);
3942 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, color_const_2, 1);
3943 ok(SUCCEEDED(hr), "Failed to set vs constant 0, hr %#lx.\n", hr);
3944 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
3945 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
3947 hr = IDirect3DDevice9_EndScene(device);
3948 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
3950 IDirect3DVertexShader9_Release(shader);
3952 /* Z < 1.0 */
3953 color = getPixelColor(device, 28, 238);
3954 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3956 /* 1.0 < z < 0.75 */
3957 color = getPixelColor(device, 31, 238);
3958 ok(color_match(color, 0x00ff0000, 0), "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
3959 color = getPixelColor(device, 100, 238);
3960 ok(color_match(color, 0x00ff0000, 0) || broken(color_match(color, 0x00ffffff, 0)),
3961 "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
3963 /* 0.75 < z < 0.0 */
3964 color = getPixelColor(device, 104, 238);
3965 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
3966 color = getPixelColor(device, 318, 238);
3967 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
3969 /* 0.0 < z */
3970 color = getPixelColor(device, 321, 238);
3971 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3973 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3974 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
3976 refcount = IDirect3DDevice9_Release(device);
3977 ok(!refcount, "Device has %lu references left.\n", refcount);
3978 done:
3979 IDirect3D9_Release(d3d);
3980 DestroyWindow(window);
3983 static void fill_surface(IDirect3DSurface9 *surface, DWORD color, DWORD flags)
3985 unsigned int byte_count;
3986 D3DSURFACE_DESC desc;
3987 unsigned int x, y;
3988 D3DLOCKED_RECT l;
3989 HRESULT hr;
3990 void *mem;
3992 memset(&desc, 0, sizeof(desc));
3993 memset(&l, 0, sizeof(l));
3994 hr = IDirect3DSurface9_GetDesc(surface, &desc);
3995 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3997 switch(desc.Format)
3999 case D3DFMT_A8R8G8B8:
4000 case D3DFMT_X8R8G8B8:
4001 byte_count = 4;
4002 break;
4004 case D3DFMT_A1R5G5B5:
4005 case D3DFMT_X1R5G5B5:
4006 case D3DFMT_R5G6B5:
4007 byte_count = 2;
4008 break;
4010 default:
4011 ok(0, "Unsupported format %#x.\n", desc.Format);
4012 return;
4015 hr = IDirect3DSurface9_LockRect(surface, &l, NULL, flags);
4016 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4017 if(FAILED(hr)) return;
4019 for(y = 0; y < desc.Height; y++)
4021 mem = (BYTE *)l.pBits + y * l.Pitch;
4022 for(x = 0; x < l.Pitch / byte_count; ++x)
4024 if (byte_count == 4)
4025 ((DWORD *)mem)[x] = color;
4026 else
4027 ((WORD *)mem)[x] = color;
4030 hr = IDirect3DSurface9_UnlockRect(surface);
4031 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4034 static void fill_texture(IDirect3DTexture9 *texture, DWORD color, DWORD flags)
4036 IDirect3DSurface9 *surface;
4038 IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4039 fill_surface(surface, color, flags);
4040 IDirect3DSurface9_Release(surface);
4043 static void stretchrect_test(void)
4045 enum surface_type
4047 OFFSCREEN_32,
4048 OFFSCREEN_64,
4049 OFFSCREEN_DST_64,
4050 RT_32,
4051 RT_64,
4052 RT_DST_64,
4053 TEX_RT_32,
4054 TEX_RT_64,
4055 TEX_RT_DST_64,
4056 TEX_RT_DST_640_480,
4057 TEX_32,
4058 TEX_64,
4059 TEX_DST_64,
4060 BACKBUFFER,
4061 SURFACE_TYPE_COUNT,
4064 IDirect3DTexture9 *tex_rt32, *tex_rt64, *tex_rt_dest64, *tex_rt_dest640_480;
4065 IDirect3DSurface9 *surfaces[SURFACE_TYPE_COUNT];
4066 IDirect3DTexture9 *tex32, *tex64, *tex_dest64;
4067 IDirect3DSurface9 *surf_temp32, *surf_temp64;
4068 IDirect3DDevice9 *device;
4069 unsigned int color, i;
4070 IDirect3D9 *d3d;
4071 ULONG refcount;
4072 HWND window;
4073 HRESULT hr;
4075 static const RECT src_rect = {0, 0, 640, 480};
4076 static const RECT src_rect_flipy = {0, 480, 640, 0};
4077 static const RECT dst_rect = {0, 0, 640, 480};
4078 static const RECT dst_rect_flipy = {0, 480, 640, 0};
4079 static const RECT src_rect64 = {0, 0, 64, 64};
4080 static const RECT src_rect64_flipy = {0, 64, 64, 0};
4081 static const RECT dst_rect64 = {0, 0, 64, 64};
4082 static const RECT dst_rect64_flipy = {0, 64, 64, 0};
4084 static const struct error_condition_test
4086 enum surface_type src;
4087 const RECT *src_rect;
4088 enum surface_type dst;
4089 const RECT *dst_rect;
4090 D3DTEXTUREFILTERTYPE filter;
4091 BOOL allowed;
4092 BOOL todo;
4094 error_condition_tests[] =
4096 {OFFSCREEN_64, &src_rect64_flipy, OFFSCREEN_DST_64, &dst_rect64, D3DTEXF_NONE},
4097 {OFFSCREEN_64, &src_rect64, OFFSCREEN_DST_64, &dst_rect64_flipy, D3DTEXF_NONE},
4098 {OFFSCREEN_64, &src_rect64_flipy, TEX_RT_DST_64, &dst_rect64, D3DTEXF_NONE},
4099 {OFFSCREEN_64, &src_rect64, TEX_RT_DST_64, &dst_rect64_flipy, D3DTEXF_NONE},
4100 {OFFSCREEN_64, &src_rect64_flipy, RT_DST_64, &dst_rect64, D3DTEXF_NONE},
4101 {OFFSCREEN_64, &src_rect64, RT_DST_64, &dst_rect64_flipy, D3DTEXF_NONE},
4102 {OFFSCREEN_64, NULL, TEX_DST_64, NULL, D3DTEXF_NONE},
4103 {OFFSCREEN_32, NULL, OFFSCREEN_64, NULL, D3DTEXF_NONE, FALSE, TRUE},
4104 {OFFSCREEN_32, NULL, TEX_DST_64, NULL, D3DTEXF_NONE},
4105 {TEX_64, NULL, OFFSCREEN_64, NULL, D3DTEXF_NONE, FALSE, TRUE},
4106 {TEX_64, &src_rect64_flipy, TEX_RT_DST_64, &dst_rect64, D3DTEXF_NONE},
4107 {TEX_64, &src_rect64, TEX_RT_DST_64, &dst_rect64_flipy, D3DTEXF_NONE},
4108 {TEX_64, &src_rect64_flipy, RT_DST_64, &dst_rect64, D3DTEXF_NONE},
4109 {TEX_64, &src_rect64, RT_DST_64, &dst_rect64_flipy, D3DTEXF_NONE},
4110 {TEX_64, NULL, TEX_DST_64, NULL, D3DTEXF_NONE},
4111 {TEX_32, NULL, OFFSCREEN_64, NULL, D3DTEXF_NONE, FALSE, TRUE},
4112 {TEX_32, NULL, TEX_DST_64, NULL, D3DTEXF_NONE},
4113 {TEX_RT_64, NULL, OFFSCREEN_64, NULL, D3DTEXF_NONE, FALSE, TRUE},
4114 {TEX_RT_64, &src_rect64_flipy, TEX_RT_DST_64, &dst_rect64, D3DTEXF_NONE},
4115 {TEX_RT_64, &src_rect64, TEX_RT_DST_64, &dst_rect64_flipy, D3DTEXF_NONE},
4116 {TEX_RT_64, &src_rect64_flipy, RT_DST_64, &dst_rect64, D3DTEXF_NONE},
4117 {TEX_RT_64, &src_rect64, RT_DST_64, &dst_rect64_flipy, D3DTEXF_NONE},
4118 {TEX_RT_64, NULL, TEX_DST_64, NULL, D3DTEXF_NONE},
4119 {TEX_RT_32, NULL, OFFSCREEN_64, NULL, D3DTEXF_NONE, FALSE, TRUE},
4120 {TEX_RT_32, NULL, TEX_DST_64, NULL, D3DTEXF_NONE},
4121 {RT_64, NULL, OFFSCREEN_64, NULL, D3DTEXF_NONE, FALSE, TRUE},
4122 {RT_64, &src_rect64_flipy, TEX_RT_DST_64, &dst_rect64, D3DTEXF_NONE},
4123 {RT_64, &src_rect64, TEX_RT_DST_64, &dst_rect64_flipy, D3DTEXF_NONE},
4124 {RT_64, &src_rect64_flipy, RT_DST_64, &dst_rect64_flipy, D3DTEXF_NONE},
4125 {RT_64, &src_rect64, RT_DST_64, &dst_rect64_flipy, D3DTEXF_NONE},
4126 {RT_64, NULL, TEX_DST_64, NULL, D3DTEXF_NONE},
4127 {RT_32, NULL, OFFSCREEN_64, NULL, D3DTEXF_NONE, FALSE, TRUE},
4128 {RT_32, NULL, TEX_DST_64, NULL, D3DTEXF_NONE},
4129 {BACKBUFFER, &src_rect_flipy, TEX_RT_DST_640_480, &dst_rect, D3DTEXF_NONE},
4130 {BACKBUFFER, &src_rect, TEX_RT_DST_640_480, &dst_rect_flipy, D3DTEXF_NONE},
4131 /* Test filter. */
4132 {OFFSCREEN_64, NULL, OFFSCREEN_DST_64, NULL, D3DTEXF_NONE, TRUE},
4133 {OFFSCREEN_64, NULL, OFFSCREEN_DST_64, NULL, D3DTEXF_ANISOTROPIC},
4134 {OFFSCREEN_32, NULL, TEX_RT_DST_64, NULL, D3DTEXF_NONE, TRUE},
4135 {OFFSCREEN_32, NULL, TEX_RT_DST_64, NULL, D3DTEXF_ANISOTROPIC},
4136 {OFFSCREEN_64, NULL, TEX_RT_DST_64, NULL, D3DTEXF_ANISOTROPIC},
4137 {OFFSCREEN_64, NULL, TEX_RT_DST_64, NULL, D3DTEXF_PYRAMIDALQUAD},
4138 {OFFSCREEN_64, NULL, TEX_RT_DST_64, NULL, D3DTEXF_GAUSSIANQUAD},
4139 {OFFSCREEN_64, NULL, TEX_RT_DST_64, NULL, D3DTEXF_ANISOTROPIC},
4140 {OFFSCREEN_64, NULL, TEX_RT_DST_64, NULL, D3DTEXF_CONVOLUTIONMONO},
4141 {OFFSCREEN_64, NULL, TEX_RT_DST_64, NULL, 0xbadf},
4142 {TEX_64, NULL, RT_DST_64, NULL, D3DTEXF_NONE, TRUE},
4143 {TEX_64, NULL, RT_DST_64, NULL, D3DTEXF_ANISOTROPIC},
4144 {RT_64, NULL, RT_DST_64, NULL, D3DTEXF_ANISOTROPIC},
4145 {TEX_RT_64, NULL, TEX_RT_DST_64, NULL, D3DTEXF_NONE, TRUE},
4146 {TEX_RT_64, NULL, TEX_RT_DST_64, NULL, D3DTEXF_ANISOTROPIC},
4147 {RT_64, NULL, TEX_RT_DST_64, NULL, D3DTEXF_NONE, TRUE},
4148 {RT_64, NULL, TEX_RT_DST_64, NULL, D3DTEXF_ANISOTROPIC},
4149 {BACKBUFFER, NULL, TEX_RT_DST_640_480, NULL, D3DTEXF_NONE, TRUE},
4150 {BACKBUFFER, NULL, TEX_RT_DST_640_480, NULL, D3DTEXF_ANISOTROPIC},
4153 window = create_window();
4154 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4155 ok(!!d3d, "Failed to create a D3D object.\n");
4156 if (!(device = create_device(d3d, window, window, TRUE)))
4158 skip("Failed to create a D3D device, skipping tests.\n");
4159 goto done;
4162 /* Create our temporary surfaces in system memory. */
4163 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
4164 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
4165 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4166 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
4167 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
4168 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4170 /* Create offscreen plain surfaces in D3DPOOL_DEFAULT. */
4171 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
4172 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surfaces[OFFSCREEN_32], NULL);
4173 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4174 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
4175 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surfaces[OFFSCREEN_64], NULL);
4176 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4177 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
4178 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surfaces[OFFSCREEN_DST_64], NULL);
4179 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4181 /* Create render target surfaces. */
4182 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32,
4183 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surfaces[RT_32], NULL );
4184 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4185 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64,
4186 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surfaces[RT_64], NULL );
4187 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4188 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64,
4189 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surfaces[RT_DST_64], NULL );
4190 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4191 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &surfaces[BACKBUFFER]);
4192 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4194 /* Create render target textures. */
4195 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET,
4196 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
4197 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4198 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET,
4199 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
4200 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4201 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET,
4202 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
4203 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4204 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET,
4205 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest640_480, NULL);
4206 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4207 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surfaces[TEX_RT_32]);
4208 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4209 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surfaces[TEX_RT_64]);
4210 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4211 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surfaces[TEX_RT_DST_64]);
4212 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4213 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest640_480, 0, &surfaces[TEX_RT_DST_640_480]);
4214 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4216 /* Create regular textures in D3DPOOL_DEFAULT. */
4217 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
4218 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4219 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
4220 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4221 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
4222 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4223 hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surfaces[TEX_32]);
4224 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4225 hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surfaces[TEX_64]);
4226 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4227 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surfaces[TEX_DST_64]);
4228 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4230 /**********************************************************************
4231 * Tests for when the source parameter is an offscreen plain surface. *
4232 **********************************************************************/
4234 /* Fill the offscreen 64x64 surface with green. */
4235 fill_surface(surfaces[OFFSCREEN_64], 0xff00ff00, 0);
4237 /* offscreenplain ==> offscreenplain, same size. */
4238 hr = IDirect3DDevice9_StretchRect(device, surfaces[OFFSCREEN_64], NULL,
4239 surfaces[OFFSCREEN_DST_64], NULL, D3DTEXF_NONE);
4240 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4241 color = getPixelColorFromSurface(surfaces[OFFSCREEN_DST_64], 32, 32);
4242 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
4243 /* Blit without scaling. */
4244 hr = IDirect3DDevice9_StretchRect(device, surfaces[OFFSCREEN_64], &src_rect64,
4245 surfaces[OFFSCREEN_DST_64], &dst_rect64, D3DTEXF_NONE);
4246 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4248 /* offscreenplain ==> rendertarget texture, same size. */
4249 hr = IDirect3DDevice9_StretchRect(device, surfaces[OFFSCREEN_64], NULL,
4250 surfaces[TEX_RT_DST_64], NULL, D3DTEXF_NONE);
4251 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4252 /* We can't lock rendertarget textures, so copy to our temp surface first. */
4253 hr = IDirect3DDevice9_GetRenderTargetData(device, surfaces[TEX_RT_DST_64], surf_temp64);
4254 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4255 color = getPixelColorFromSurface(surf_temp64, 32, 32);
4256 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
4257 /* Blit without scaling. */
4258 hr = IDirect3DDevice9_StretchRect(device, surfaces[OFFSCREEN_64], &src_rect64,
4259 surfaces[TEX_RT_DST_64], &dst_rect64, D3DTEXF_NONE);
4260 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4262 /* offscreenplain ==> rendertarget surface, same size. */
4263 hr = IDirect3DDevice9_StretchRect(device, surfaces[OFFSCREEN_64], NULL, surfaces[RT_DST_64], NULL, D3DTEXF_NONE);
4264 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4265 color = getPixelColorFromSurface(surfaces[RT_DST_64], 32, 32);
4266 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
4267 /* Blit without scaling. */
4268 hr = IDirect3DDevice9_StretchRect(device, surfaces[OFFSCREEN_64], &src_rect64,
4269 surfaces[RT_DST_64], &dst_rect64, D3DTEXF_NONE);
4270 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4272 /* Fill the smaller offscreen surface with red. */
4273 fill_surface(surfaces[OFFSCREEN_32], 0xffff0000, 0);
4275 /* offscreenplain ==> rendertarget texture, scaling. */
4276 hr = IDirect3DDevice9_StretchRect(device, surfaces[OFFSCREEN_32], NULL,
4277 surfaces[TEX_RT_DST_64], NULL, D3DTEXF_NONE);
4278 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4279 /* We can't lock rendertarget textures, so copy to our temp surface first. */
4280 hr = IDirect3DDevice9_GetRenderTargetData(device, surfaces[TEX_RT_DST_64], surf_temp64);
4281 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4282 color = getPixelColorFromSurface(surf_temp64, 48, 48);
4283 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
4285 /* offscreenplain ==> rendertarget surface, scaling. */
4286 hr = IDirect3DDevice9_StretchRect(device, surfaces[OFFSCREEN_32], NULL, surfaces[RT_DST_64], NULL, D3DTEXF_NONE);
4287 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4288 color = getPixelColorFromSurface(surfaces[RT_DST_64], 48, 48);
4289 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
4291 /*************************************************************
4292 * Tests for when the source parameter is a regular texture. *
4293 *************************************************************/
4295 /* Fill the surface of the regular texture with blue. */
4296 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT. */
4297 fill_surface(surf_temp64, 0xff0000ff, 0);
4298 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surfaces[TEX_64], NULL);
4299 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4301 /* texture ==> rendertarget texture, same size. */
4302 hr = IDirect3DDevice9_StretchRect(device, surfaces[TEX_64], NULL, surfaces[TEX_RT_DST_64], NULL, D3DTEXF_NONE);
4303 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4304 /* We can't lock rendertarget textures, so copy to our temp surface first. */
4305 hr = IDirect3DDevice9_GetRenderTargetData(device, surfaces[TEX_RT_DST_64], surf_temp64);
4306 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4307 color = getPixelColorFromSurface(surf_temp64, 32, 32);
4308 ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
4309 /* Blit without scaling. */
4310 hr = IDirect3DDevice9_StretchRect(device, surfaces[TEX_64], &src_rect64,
4311 surfaces[TEX_RT_DST_64], &dst_rect64, D3DTEXF_NONE);
4312 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4314 /* texture ==> rendertarget surface, same size. */
4315 hr = IDirect3DDevice9_StretchRect(device, surfaces[TEX_64], NULL, surfaces[RT_DST_64], NULL, D3DTEXF_NONE);
4316 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4317 color = getPixelColorFromSurface(surfaces[RT_DST_64], 32, 32);
4318 ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
4319 /* Blit without scaling. */
4320 hr = IDirect3DDevice9_StretchRect(device, surfaces[TEX_64], &src_rect64,
4321 surfaces[RT_DST_64], &dst_rect64, D3DTEXF_NONE);
4322 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4324 /* Fill the surface of the smaller regular texture with red. */
4325 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT. */
4326 fill_surface(surf_temp32, 0xffff0000, 0);
4327 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surfaces[TEX_32], NULL);
4328 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4330 /* texture ==> rendertarget texture, scaling. */
4331 hr = IDirect3DDevice9_StretchRect(device, surfaces[TEX_32], NULL, surfaces[TEX_RT_DST_64], NULL, D3DTEXF_NONE);
4332 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4333 /* We can't lock rendertarget textures, so copy to our temp surface first. */
4334 hr = IDirect3DDevice9_GetRenderTargetData(device, surfaces[TEX_RT_DST_64], surf_temp64);
4335 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4336 color = getPixelColorFromSurface(surf_temp64, 48, 48);
4337 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
4339 /* texture ==> rendertarget surface, scaling. */
4340 hr = IDirect3DDevice9_StretchRect(device, surfaces[TEX_32], NULL, surfaces[RT_DST_64], NULL, D3DTEXF_NONE);
4341 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4342 color = getPixelColorFromSurface(surfaces[RT_DST_64], 48, 48);
4343 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
4345 /******************************************************************
4346 * Tests for when the source parameter is a rendertarget texture. *
4347 ******************************************************************/
4349 /* Fill the surface of the rendertarget texture with white. */
4350 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT. */
4351 fill_surface(surf_temp64, 0xffffffff, 0);
4352 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surfaces[TEX_RT_64], NULL);
4353 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4355 /* rendertarget texture ==> rendertarget texture, same size. */
4356 hr = IDirect3DDevice9_StretchRect(device, surfaces[TEX_RT_64], NULL, surfaces[TEX_RT_DST_64], NULL, D3DTEXF_NONE);
4357 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4358 /* We can't lock rendertarget textures, so copy to our temp surface first. */
4359 hr = IDirect3DDevice9_GetRenderTargetData(device, surfaces[TEX_RT_DST_64], surf_temp64);
4360 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4361 color = getPixelColorFromSurface(surf_temp64, 32, 32);
4362 ok(color == 0xffffffff, "Got unexpected color 0x%08x.\n", color);
4363 /* Blit without scaling. */
4364 hr = IDirect3DDevice9_StretchRect(device, surfaces[TEX_RT_64], &src_rect64,
4365 surfaces[TEX_RT_DST_64], &dst_rect64, D3DTEXF_NONE);
4366 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4368 /* rendertarget texture ==> rendertarget surface, same size. */
4369 hr = IDirect3DDevice9_StretchRect(device, surfaces[TEX_RT_64], NULL, surfaces[RT_DST_64], NULL, D3DTEXF_NONE);
4370 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4371 color = getPixelColorFromSurface(surfaces[RT_DST_64], 32, 32);
4372 ok(color == 0xffffffff, "Got unexpected color 0x%08x.\n", color);
4373 /* Blit without scaling. */
4374 hr = IDirect3DDevice9_StretchRect(device, surfaces[TEX_RT_64], &src_rect64,
4375 surfaces[RT_DST_64], &dst_rect64, D3DTEXF_NONE);
4376 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4378 /* Fill the surface of the smaller rendertarget texture with red. */
4379 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT. */
4380 fill_surface(surf_temp32, 0xffff0000, 0);
4381 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surfaces[TEX_RT_32], NULL);
4382 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4384 /* rendertarget texture ==> rendertarget texture, scaling. */
4385 hr = IDirect3DDevice9_StretchRect(device, surfaces[TEX_RT_32], NULL, surfaces[TEX_RT_DST_64], NULL, D3DTEXF_NONE);
4386 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4387 /* We can't lock rendertarget textures, so copy to our temp surface first. */
4388 hr = IDirect3DDevice9_GetRenderTargetData(device, surfaces[TEX_RT_DST_64], surf_temp64);
4389 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4390 color = getPixelColorFromSurface(surf_temp64, 48, 48);
4391 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
4393 /* rendertarget texture ==> rendertarget surface, scaling. */
4394 hr = IDirect3DDevice9_StretchRect(device, surfaces[TEX_RT_32], NULL, surfaces[RT_DST_64], NULL, D3DTEXF_NONE);
4395 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4396 color = getPixelColorFromSurface(surfaces[RT_DST_64], 48, 48);
4397 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
4399 /******************************************************************
4400 * Tests for when the source parameter is a rendertarget surface. *
4401 ******************************************************************/
4403 /* Fill the surface of the rendertarget surface with black. */
4404 fill_surface(surfaces[RT_64], 0xff000000, 0);
4406 /* rendertarget surface ==> rendertarget texture, same size. */
4407 hr = IDirect3DDevice9_StretchRect(device, surfaces[RT_64], NULL, surfaces[TEX_RT_DST_64], NULL, D3DTEXF_NONE);
4408 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4409 /* We can't lock rendertarget textures, so copy to our temp surface first. */
4410 hr = IDirect3DDevice9_GetRenderTargetData(device, surfaces[TEX_RT_DST_64], surf_temp64);
4411 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4412 color = getPixelColorFromSurface(surf_temp64, 32, 32);
4413 ok(color == 0xff000000, "Got unexpected color 0x%08x.\n", color);
4414 /* Blit without scaling. */
4415 hr = IDirect3DDevice9_StretchRect(device, surfaces[RT_64], &src_rect64,
4416 surfaces[TEX_RT_DST_64], &dst_rect64, D3DTEXF_NONE);
4417 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4419 /* rendertarget surface ==> rendertarget surface, same size. */
4420 hr = IDirect3DDevice9_StretchRect(device, surfaces[RT_64], NULL, surfaces[RT_DST_64], NULL, D3DTEXF_NONE);
4421 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4422 color = getPixelColorFromSurface(surfaces[RT_DST_64], 32, 32);
4423 ok(color == 0xff000000, "Got unexpected color 0x%08x.\n", color);
4424 /* Blit without scaling. */
4425 hr = IDirect3DDevice9_StretchRect(device, surfaces[RT_64], &src_rect64,
4426 surfaces[RT_DST_64], &dst_rect64, D3DTEXF_NONE);
4427 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4429 /* Fill the surface of the smaller rendertarget texture with red. */
4430 fill_surface(surfaces[RT_32], 0xffff0000, 0);
4432 /* rendertarget surface ==> rendertarget texture, scaling. */
4433 hr = IDirect3DDevice9_StretchRect(device, surfaces[RT_32], NULL, surfaces[TEX_RT_DST_64], NULL, D3DTEXF_NONE);
4434 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4435 /* We can't lock rendertarget textures, so copy to our temp surface first. */
4436 hr = IDirect3DDevice9_GetRenderTargetData(device, surfaces[TEX_RT_DST_64], surf_temp64);
4437 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4438 color = getPixelColorFromSurface(surf_temp64, 48, 48);
4439 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
4441 /* rendertarget surface ==> rendertarget surface, scaling. */
4442 hr = IDirect3DDevice9_StretchRect(device, surfaces[RT_32], NULL, surfaces[RT_DST_64], NULL, D3DTEXF_NONE);
4443 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4444 color = getPixelColorFromSurface(surfaces[RT_DST_64], 48, 48);
4445 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
4447 /* backbuffer ==> surface tests (no scaling). */
4448 /* Blit with NULL rectangles. */
4449 hr = IDirect3DDevice9_StretchRect(device, surfaces[BACKBUFFER], NULL,
4450 surfaces[TEX_RT_DST_640_480], NULL, D3DTEXF_NONE);
4451 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4452 /* Blit without scaling. */
4453 hr = IDirect3DDevice9_StretchRect(device, surfaces[BACKBUFFER], &src_rect,
4454 surfaces[TEX_RT_DST_640_480], &dst_rect, D3DTEXF_NONE);
4455 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4457 /* Test error conditions. */
4458 for (i = 0; i < ARRAY_SIZE(error_condition_tests); ++i)
4460 const struct error_condition_test *test = &error_condition_tests[i];
4462 hr = IDirect3DDevice9_StretchRect(device, surfaces[test->src], test->src_rect,
4463 surfaces[test->dst], test->dst_rect, test->filter);
4464 todo_wine_if(test->todo)
4465 ok(hr == test->allowed ? D3D_OK : D3DERR_INVALIDCALL, "Test %u, got unexpected hr %#lx.\n", i, hr);
4468 /* TODO: Test format conversions. */
4470 for (i = 0; i < ARRAY_SIZE(surfaces); ++i)
4472 IDirect3DSurface9_Release(surfaces[i]);
4475 IDirect3DSurface9_Release(surf_temp32);
4476 IDirect3DSurface9_Release(surf_temp64);
4477 IDirect3DTexture9_Release(tex_rt32);
4478 IDirect3DTexture9_Release(tex_rt64);
4479 IDirect3DTexture9_Release(tex_rt_dest64);
4480 IDirect3DTexture9_Release(tex_rt_dest640_480);
4481 IDirect3DTexture9_Release(tex32);
4482 IDirect3DTexture9_Release(tex64);
4483 IDirect3DTexture9_Release(tex_dest64);
4484 refcount = IDirect3DDevice9_Release(device);
4485 ok(!refcount, "Device has %lu references left.\n", refcount);
4486 done:
4487 IDirect3D9_Release(d3d);
4488 DestroyWindow(window);
4491 static void test_multisample_stretch_rect(void)
4493 static const D3DTEXTUREFILTERTYPE filters[] =
4495 D3DTEXF_NONE,
4496 D3DTEXF_POINT,
4497 D3DTEXF_LINEAR,
4499 IDirect3DSurface9 *rt, *ms_rt, *ms_rt2, *rt_r5g6b5;
4500 struct surface_readback rb;
4501 IDirect3DDevice9 *device;
4502 unsigned int color, i;
4503 DWORD quality_levels;
4504 IDirect3D9 *d3d;
4505 ULONG refcount;
4506 HWND window;
4507 HRESULT hr;
4508 RECT rect;
4510 window = create_window();
4511 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4512 ok(!!d3d, "Failed to create a D3D object.\n");
4514 if (IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
4515 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, &quality_levels) == D3DERR_NOTAVAILABLE)
4517 skip("Multisampling not supported for D3DFMT_A8R8G8B8.\n");
4518 IDirect3D9_Release(d3d);
4519 DestroyWindow(window);
4520 return;
4523 if (!(device = create_device(d3d, window, window, TRUE)))
4525 skip("Failed to create a 3D device.\n");
4526 IDirect3D9_Release(d3d);
4527 DestroyWindow(window);
4528 return;
4531 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128,
4532 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
4533 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4534 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128,
4535 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_2_SAMPLES, quality_levels - 1, FALSE, &ms_rt, NULL);
4536 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4537 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128,
4538 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_2_SAMPLES, quality_levels - 1, FALSE, &ms_rt2, NULL);
4539 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4541 hr = IDirect3DDevice9_SetRenderTarget(device, 0, ms_rt);
4542 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4543 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff00ff, 0.0f, 0);
4544 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4546 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
4547 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4549 for (i = 0; i < ARRAY_SIZE(filters); ++i)
4551 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
4552 ok(hr == D3D_OK, "Test %u, got unexpected hr %#lx.\n", i, hr);
4553 hr = IDirect3DDevice9_StretchRect(device, ms_rt, NULL, rt, NULL, filters[i]);
4554 ok(hr == D3D_OK, "Test %u, got unexpected hr %#lx.\n", i, hr);
4555 color = getPixelColor(device, 64, 64);
4556 ok(color == 0x00ff00ff, "Test %u, got unexpected color 0x%08x.\n", i, color);
4559 /* Scaling */
4560 SetRect(&rect, 0, 0, 64, 64);
4561 for (i = 0; i < ARRAY_SIZE(filters); ++i)
4563 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
4564 ok(hr == D3D_OK, "Test %u, got unexpected hr %#lx.\n", i, hr);
4565 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, ms_rt2, NULL, D3DTEXF_NONE);
4566 ok(hr == D3D_OK, "Test %u, got unexpected hr %#lx.\n", i, hr);
4568 hr = IDirect3DDevice9_StretchRect(device, ms_rt, NULL, rt, &rect, filters[i]);
4569 ok(hr == D3D_OK, "Test %u, got unexpected hr %#lx.\n", i, hr);
4570 get_rt_readback(rt, &rb);
4571 color = get_readback_color(&rb, 32, 32);
4572 ok(color == 0x00ff00ff, "Test %u, got unexpected color 0x%08x.\n", i, color);
4573 color = get_readback_color(&rb, 64, 64);
4574 ok(color == 0xffffffff, "Test %u, got unexpected color 0x%08x.\n", i, color);
4575 color = get_readback_color(&rb, 96, 96);
4576 ok(color == 0xffffffff, "Test %u, got unexpected color 0x%08x.\n", i, color);
4577 release_surface_readback(&rb);
4579 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
4580 ok(hr == D3D_OK, "Test %u, got unexpected hr %#lx.\n", i, hr);
4581 hr = IDirect3DDevice9_StretchRect(device, ms_rt, &rect, rt, NULL, filters[i]);
4582 ok(hr == D3D_OK, "Test %u, got unexpected hr %#lx.\n", i, hr);
4583 get_rt_readback(rt, &rb);
4584 color = get_readback_color(&rb, 32, 32);
4585 ok(color == 0x00ff00ff, "Test %u, got unexpected color 0x%08x.\n", i, color);
4586 color = get_readback_color(&rb, 64, 64);
4587 ok(color == 0x00ff00ff, "Test %u, got unexpected color 0x%08x.\n", i, color);
4588 color = get_readback_color(&rb, 96, 96);
4589 ok(color == 0x00ff00ff, "Test %u, got unexpected color 0x%08x.\n", i, color);
4590 release_surface_readback(&rb);
4592 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0f, 0);
4593 ok(hr == D3D_OK, "Test %u, got unexpected hr %#lx.\n", i, hr);
4594 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, ms_rt, &rect, filters[i]);
4595 ok(hr == D3D_OK, "Test %u, got unexpected hr %#lx.\n", i, hr);
4596 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
4597 ok(hr == D3D_OK, "Test %u, got unexpected hr %#lx.\n", i, hr);
4598 hr = IDirect3DDevice9_StretchRect(device, ms_rt, &rect, rt, NULL, filters[i]);
4599 ok(hr == D3D_OK, "Test %u, got unexpected hr %#lx.\n", i, hr);
4600 get_rt_readback(rt, &rb);
4601 color = get_readback_color(&rb, 32, 32);
4602 ok(color == 0xffffff00, "Test %u, got unexpected color 0x%08x.\n", i, color);
4603 color = get_readback_color(&rb, 64, 64);
4604 ok(color == 0xffffff00, "Test %u, got unexpected color 0x%08x.\n", i, color);
4605 color = get_readback_color(&rb, 96, 96);
4606 ok(color == 0xffffff00, "Test %u, got unexpected color 0x%08x.\n", i, color);
4607 release_surface_readback(&rb);
4609 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff00ff, 0.0f, 0);
4610 ok(hr == D3D_OK, "Test %u, got unexpected hr %#lx.\n", i, hr);
4611 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, ms_rt, NULL, D3DTEXF_NONE);
4612 ok(hr == D3D_OK, "Test %u, got unexpected hr %#lx.\n", i, hr);
4614 hr = IDirect3DDevice9_StretchRect(device, ms_rt, &rect, ms_rt2, NULL, filters[i]);
4615 ok(hr == D3D_OK, "Test %u, got unexpected hr %#lx.\n", i, hr);
4616 hr = IDirect3DDevice9_StretchRect(device, ms_rt2, &rect, rt, NULL, filters[i]);
4617 ok(hr == D3D_OK, "Test %u, got unexpected hr %#lx.\n", i, hr);
4618 get_rt_readback(rt, &rb);
4619 color = get_readback_color(&rb, 32, 32);
4620 ok(color == 0x00ff00ff, "Test %u, got unexpected color 0x%08x.\n", i, color);
4621 color = get_readback_color(&rb, 64, 64);
4622 ok(color == 0x00ff00ff, "Test %u, got unexpected color 0x%08x.\n", i, color);
4623 color = get_readback_color(&rb, 96, 96);
4624 ok(color == 0x00ff00ff, "Test %u, got unexpected color 0x%08x.\n", i, color);
4625 release_surface_readback(&rb);
4628 /* Format conversion */
4629 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128,
4630 D3DFMT_R5G6B5, D3DMULTISAMPLE_NONE, 0, FALSE, &rt_r5g6b5, NULL);
4631 if (FAILED(hr))
4633 skip("Failed to create D3DFMT_R5G6B5 render target.\n");
4634 goto done;
4637 for (i = 0; i < ARRAY_SIZE(filters); ++i)
4639 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
4640 ok(hr == D3D_OK, "Test %u, got unexpected hr %#lx.\n", i, hr);
4641 hr = IDirect3DDevice9_StretchRect(device, ms_rt, NULL, rt_r5g6b5, NULL, filters[i]);
4642 ok(hr == D3D_OK, "Test %u, got unexpected hr %#lx.\n", i, hr);
4643 hr = IDirect3DDevice9_StretchRect(device, rt_r5g6b5, NULL, rt, NULL, filters[i]);
4644 ok(hr == D3D_OK, "Test %u, got unexpected hr %#lx.\n", i, hr);
4645 color = getPixelColor(device, 64, 64);
4646 ok(color == 0x00ff00ff, "Test %u, got unexpected color 0x%08x.\n", i, color);
4649 IDirect3DSurface9_Release(rt_r5g6b5);
4651 done:
4652 IDirect3DSurface9_Release(ms_rt2);
4653 IDirect3DSurface9_Release(ms_rt);
4654 IDirect3DSurface9_Release(rt);
4655 refcount = IDirect3DDevice9_Release(device);
4656 ok(!refcount, "Device has %lu references left.\n", refcount);
4657 IDirect3D9_Release(d3d);
4658 DestroyWindow(window);
4661 static void maxmip_test(void)
4663 IDirect3DTexture9 *texture;
4664 IDirect3DSurface9 *surface;
4665 IDirect3DDevice9 *device;
4666 unsigned int color;
4667 IDirect3D9 *d3d;
4668 ULONG refcount;
4669 D3DCAPS9 caps;
4670 HWND window;
4671 HRESULT hr;
4672 DWORD ret;
4674 static const struct
4676 struct
4678 float x, y, z;
4679 float s, t;
4681 v[4];
4683 quads[] =
4686 {-1.0, -1.0, 0.0, 0.0, 0.0},
4687 {-1.0, 0.0, 0.0, 0.0, 1.0},
4688 { 0.0, -1.0, 0.0, 1.0, 0.0},
4689 { 0.0, 0.0, 0.0, 1.0, 1.0},
4692 { 0.0, -1.0, 0.0, 0.0, 0.0},
4693 { 0.0, 0.0, 0.0, 0.0, 1.0},
4694 { 1.0, -1.0, 0.0, 1.0, 0.0},
4695 { 1.0, 0.0, 0.0, 1.0, 1.0},
4698 { 0.0, 0.0, 0.0, 0.0, 0.0},
4699 { 0.0, 1.0, 0.0, 0.0, 1.0},
4700 { 1.0, 0.0, 0.0, 1.0, 0.0},
4701 { 1.0, 1.0, 0.0, 1.0, 1.0},
4704 {-1.0, 0.0, 0.0, 0.0, 0.0},
4705 {-1.0, 1.0, 0.0, 0.0, 1.0},
4706 { 0.0, 0.0, 0.0, 1.0, 0.0},
4707 { 0.0, 1.0, 0.0, 1.0, 1.0},
4711 window = create_window();
4712 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4713 ok(!!d3d, "Failed to create a D3D object.\n");
4714 if (!(device = create_device(d3d, window, window, TRUE)))
4716 skip("Failed to create a D3D device, skipping tests.\n");
4717 goto done;
4720 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4721 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
4722 if (!(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP))
4724 skip("No mipmap support, skipping tests.\n");
4725 IDirect3DDevice9_Release(device);
4726 goto done;
4729 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0,
4730 D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
4731 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
4733 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4734 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4735 fill_surface(surface, 0xffff0000, 0);
4736 IDirect3DSurface9_Release(surface);
4737 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
4738 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4739 fill_surface(surface, 0xff00ff00, 0);
4740 IDirect3DSurface9_Release(surface);
4741 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
4742 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4743 fill_surface(surface, 0xff0000ff, 0);
4744 IDirect3DSurface9_Release(surface);
4746 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4747 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4748 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4749 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4751 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4752 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
4753 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4754 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4756 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
4757 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4759 hr = IDirect3DDevice9_BeginScene(device);
4760 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
4762 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
4763 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#lx.\n", hr);
4764 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
4765 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
4767 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
4768 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#lx.\n", hr);
4769 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
4770 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
4772 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
4773 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#lx.\n", hr);
4774 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
4775 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
4777 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
4778 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#lx.\n", hr);
4779 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
4780 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
4782 hr = IDirect3DDevice9_EndScene(device);
4783 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
4785 /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
4786 color = getPixelColor(device, 160, 360);
4787 ok(color == 0x00ff0000, "MaxMip 0, no mipfilter has color 0x%08x.\n", color);
4788 color = getPixelColor(device, 480, 360);
4789 ok(color == 0x00ff0000, "MaxMip 1, no mipfilter has color 0x%08x.\n", color);
4790 color = getPixelColor(device, 480, 120);
4791 ok(color == 0x00ff0000, "MaxMip 2, no mipfilter has color 0x%08x.\n", color);
4792 color = getPixelColor(device, 160, 120);
4793 ok(color == 0x00ff0000, "MaxMip 3, no mipfilter has color 0x%08x.\n", color);
4794 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4795 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4797 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4798 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4800 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
4801 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4803 hr = IDirect3DDevice9_BeginScene(device);
4804 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
4806 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
4807 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#lx.\n", hr);
4808 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
4809 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
4811 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
4812 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#lx.\n", hr);
4813 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
4814 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
4816 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
4817 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#lx.\n", hr);
4818 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
4819 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
4821 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
4822 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#lx.\n", hr);
4823 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
4824 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
4826 hr = IDirect3DDevice9_EndScene(device);
4827 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
4829 /* Max Mip level 0-2 sample from the specified texture level, Max Mip
4830 * level 3 (> levels in texture) samples from the highest level in the
4831 * texture (level 2). */
4832 color = getPixelColor(device, 160, 360);
4833 ok(color == 0x00ff0000, "MaxMip 0, point mipfilter has color 0x%08x.\n", color);
4834 color = getPixelColor(device, 480, 360);
4835 ok(color == 0x0000ff00, "MaxMip 1, point mipfilter has color 0x%08x.\n", color);
4836 color = getPixelColor(device, 480, 120);
4837 ok(color == 0x000000ff, "MaxMip 2, point mipfilter has color 0x%08x.\n", color);
4838 color = getPixelColor(device, 160, 120);
4839 ok(color == 0x000000ff, "MaxMip 3, point mipfilter has color 0x%08x.\n", color);
4840 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4841 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4843 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
4844 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4846 hr = IDirect3DDevice9_BeginScene(device);
4847 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
4849 /* Mipmapping OFF, LOD level smaller than MAXMIPLEVEL. LOD level limits */
4850 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4851 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#lx.\n", hr);
4852 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
4853 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#lx.\n", hr);
4854 ret = IDirect3DTexture9_SetLOD(texture, 1);
4855 ok(ret == 0, "Got unexpected LOD %lu.\n", ret);
4856 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
4857 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
4859 /* Mipmapping ON, LOD level smaller than max mip level. LOD level limits */
4860 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4861 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#lx.\n", hr);
4862 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
4863 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#lx.\n", hr);
4864 ret = IDirect3DTexture9_SetLOD(texture, 2);
4865 ok(ret == 1, "Got unexpected LOD %lu.\n", ret);
4866 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
4867 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
4869 /* Mipmapping ON, LOD level bigger than max mip level. MAXMIPLEVEL limits */
4870 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
4871 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#lx.\n", hr);
4872 ret = IDirect3DTexture9_SetLOD(texture, 1);
4873 ok(ret == 2, "Got unexpected LOD %lu.\n", ret);
4874 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
4875 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
4877 /* Mipmapping OFF, LOD level bigger than max mip level. LOD level limits */
4878 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4879 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#lx.\n", hr);
4880 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
4881 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#lx.\n", hr);
4882 ret = IDirect3DTexture9_SetLOD(texture, 1);
4883 ok(ret == 1, "Got unexpected LOD %lu.\n", ret);
4884 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
4885 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
4887 hr = IDirect3DDevice9_EndScene(device);
4888 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
4890 /* Max Mip level 0-2 sample from the specified texture level, Max Mip
4891 * level 3 (> levels in texture) samples from the highest level in the
4892 * texture (level 2). */
4893 color = getPixelColor(device, 160, 360);
4894 ok(color == 0x0000ff00, "MaxMip 0, LOD 1, none mipfilter has color 0x%08x.\n", color);
4895 color = getPixelColor(device, 480, 360);
4896 ok(color == 0x000000ff, "MaxMip 1, LOD 2, point mipfilter has color 0x%08x.\n", color);
4897 color = getPixelColor(device, 480, 120);
4898 ok(color == 0x000000ff, "MaxMip 2, LOD 1, point mipfilter has color 0x%08x.\n", color);
4899 color = getPixelColor(device, 160, 120);
4900 ok(color == 0x0000ff00, "MaxMip 2, LOD 1, none mipfilter has color 0x%08x.\n", color);
4902 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4903 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4905 IDirect3DTexture9_Release(texture);
4906 refcount = IDirect3DDevice9_Release(device);
4907 ok(!refcount, "Device has %lu references left.\n", refcount);
4908 done:
4909 IDirect3D9_Release(d3d);
4910 DestroyWindow(window);
4913 static void release_buffer_test(void)
4915 IDirect3DVertexBuffer9 *vb;
4916 IDirect3DIndexBuffer9 *ib;
4917 IDirect3DDevice9 *device;
4918 unsigned int color;
4919 IDirect3D9 *d3d;
4920 ULONG refcount;
4921 HWND window;
4922 HRESULT hr;
4923 BYTE *data;
4925 static const short indices[] = {3, 4, 5};
4926 static const struct
4928 struct vec3 position;
4929 DWORD diffuse;
4931 quad[] =
4933 {{-1.0f, -1.0f, 0.1f}, 0xffff0000},
4934 {{-1.0f, 1.0f, 0.1f}, 0xffff0000},
4935 {{ 1.0f, 1.0f, 0.1f}, 0xffff0000},
4937 {{-1.0f, -1.0f, 0.1f}, 0xff00ff00},
4938 {{-1.0f, 1.0f, 0.1f}, 0xff00ff00},
4939 {{ 1.0f, 1.0f, 0.1f}, 0xff00ff00},
4942 window = create_window();
4943 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4944 ok(!!d3d, "Failed to create a D3D object.\n");
4945 if (!(device = create_device(d3d, window, window, TRUE)))
4947 skip("Failed to create a D3D device, skipping tests.\n");
4948 goto done;
4951 /* Index and vertex buffers should always be creatable */
4952 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0,
4953 D3DFVF_XYZ | D3DFVF_DIFFUSE, D3DPOOL_MANAGED, &vb, NULL);
4954 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#lx.\n", hr);
4955 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
4956 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4957 memcpy(data, quad, sizeof(quad));
4958 hr = IDirect3DVertexBuffer9_Unlock(vb);
4959 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4961 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0,
4962 D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
4963 ok(SUCCEEDED(hr), "Failed to create index buffer, hr %#lx.\n", hr);
4964 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
4965 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4966 memcpy(data, indices, sizeof(indices));
4967 hr = IDirect3DIndexBuffer9_Unlock(ib);
4968 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4970 hr = IDirect3DDevice9_SetIndices(device, ib);
4971 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4972 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
4973 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4974 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
4975 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4976 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4977 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
4979 /* Now destroy the bound index buffer and draw again */
4980 refcount = IDirect3DIndexBuffer9_Release(ib);
4981 ok(!refcount, "Unexpected refcount %lu.\n", refcount);
4983 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
4984 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4986 hr = IDirect3DDevice9_BeginScene(device);
4987 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
4988 /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent
4989 * D3D from making assumptions about the indices or vertices. */
4990 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
4991 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
4992 hr = IDirect3DDevice9_EndScene(device);
4993 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
4995 color = getPixelColor(device, 160, 120);
4996 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1), "Got unexpected color 0x%08x.\n", color);
4997 color = getPixelColor(device, 480, 360);
4998 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1), "Got unexpected color 0x%08x.\n", color);
5000 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5001 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5003 /* Index buffer was already destroyed as part of the test */
5004 IDirect3DVertexBuffer9_Release(vb);
5005 refcount = IDirect3DDevice9_Release(device);
5006 ok(!refcount, "Device has %lu references left.\n", refcount);
5007 done:
5008 IDirect3D9_Release(d3d);
5009 DestroyWindow(window);
5012 static void float_texture_test(void)
5014 IDirect3DTexture9 *texture;
5015 IDirect3DDevice9 *device;
5016 unsigned int color;
5017 D3DLOCKED_RECT lr;
5018 IDirect3D9 *d3d;
5019 ULONG refcount;
5020 float *data;
5021 HWND window;
5022 HRESULT hr;
5024 static const float quad[] =
5026 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
5027 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
5028 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
5029 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
5032 window = create_window();
5033 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5034 ok(!!d3d, "Failed to create a D3D object.\n");
5035 if (!(device = create_device(d3d, window, window, TRUE)))
5037 skip("Failed to create a D3D device, skipping tests.\n");
5038 goto done;
5041 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
5042 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK)
5044 skip("D3DFMT_R32F textures not supported\n");
5045 IDirect3DDevice9_Release(device);
5046 goto done;
5049 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F, D3DPOOL_MANAGED, &texture, NULL);
5050 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
5052 memset(&lr, 0, sizeof(lr));
5053 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5054 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5055 data = lr.pBits;
5056 *data = 0.0;
5057 hr = IDirect3DTexture9_UnlockRect(texture, 0);
5058 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5060 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
5061 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
5062 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
5063 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5065 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
5066 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
5068 hr = IDirect3DDevice9_BeginScene(device);
5069 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
5070 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5071 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
5072 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
5073 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
5074 hr = IDirect3DDevice9_EndScene(device);
5075 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
5077 color = getPixelColor(device, 240, 320);
5078 ok(color == 0x0000ffff, "R32F with value 0.0 has color %08x, expected 0x0000ffff\n", color);
5080 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5081 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5083 IDirect3DTexture9_Release(texture);
5084 refcount = IDirect3DDevice9_Release(device);
5085 ok(!refcount, "Device has %lu references left.\n", refcount);
5086 done:
5087 IDirect3D9_Release(d3d);
5088 DestroyWindow(window);
5091 static void g16r16_texture_test(void)
5093 IDirect3DTexture9 *texture;
5094 IDirect3DDevice9 *device;
5095 unsigned int color;
5096 D3DLOCKED_RECT lr;
5097 IDirect3D9 *d3d;
5098 ULONG refcount;
5099 DWORD *data;
5100 HWND window;
5101 HRESULT hr;
5103 static const float quad[] =
5105 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
5106 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
5107 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
5108 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
5111 window = create_window();
5112 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5113 ok(!!d3d, "Failed to create a D3D object.\n");
5114 if (!(device = create_device(d3d, window, window, TRUE)))
5116 skip("Failed to create a D3D device, skipping tests.\n");
5117 goto done;
5120 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
5121 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK)
5123 skip("D3DFMT_G16R16 textures not supported\n");
5124 IDirect3DDevice9_Release(device);
5125 goto done;
5128 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16, D3DPOOL_MANAGED, &texture, NULL);
5129 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
5131 memset(&lr, 0, sizeof(lr));
5132 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5133 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5134 data = lr.pBits;
5135 *data = 0x0f00f000;
5136 hr = IDirect3DTexture9_UnlockRect(texture, 0);
5137 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5139 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
5140 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
5141 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
5142 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5144 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
5145 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
5147 hr = IDirect3DDevice9_BeginScene(device);
5148 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
5149 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5150 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
5151 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
5152 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
5153 hr = IDirect3DDevice9_EndScene(device);
5154 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
5156 color = getPixelColor(device, 240, 320);
5157 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
5158 "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
5160 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5161 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5163 IDirect3DTexture9_Release(texture);
5164 refcount = IDirect3DDevice9_Release(device);
5165 ok(!refcount, "Device has %lu references left.\n", refcount);
5166 done:
5167 IDirect3D9_Release(d3d);
5168 DestroyWindow(window);
5171 #define check_rect(a, b, c) check_rect_(__LINE__, a, b, c)
5172 static void check_rect_(unsigned int line, struct surface_readback *rb, RECT r, const char *message)
5174 LONG x_coords[2][2] =
5176 {r.left - 1, r.left + 1},
5177 {r.right + 1, r.right - 1},
5179 LONG y_coords[2][2] =
5181 {r.top - 1, r.top + 1},
5182 {r.bottom + 1, r.bottom - 1}
5184 unsigned int color, i, j, x_side, y_side;
5185 int x, y;
5187 if (r.left < 0 && r.top < 0 && r.right < 0 && r.bottom < 0)
5189 BOOL all_match = TRUE;
5191 for (y = 0; y < 480; ++y)
5193 for (x = 0; x < 640; ++x)
5195 color = get_readback_color(rb, x, y);
5196 if (color != 0xff000000)
5198 all_match = FALSE;
5199 break;
5202 if (!all_match)
5203 break;
5205 ok_(__FILE__, line)(all_match, "%s: pixel (%d, %d) has color %08x.\n", message, x, y, color);
5206 return;
5209 for (i = 0; i < 2; ++i)
5211 for (j = 0; j < 2; ++j)
5213 for (x_side = 0; x_side < 2; ++x_side)
5215 for (y_side = 0; y_side < 2; ++y_side)
5217 unsigned int expected = (x_side == 1 && y_side == 1) ? 0xffffffff : 0xff000000;
5219 x = x_coords[i][x_side];
5220 y = y_coords[j][y_side];
5221 if (x < 0 || x >= 640 || y < 0 || y >= 480)
5222 continue;
5223 color = get_readback_color(rb, x, y);
5224 ok_(__FILE__, line)(color == expected, "%s: pixel (%d, %d) has color %08x, expected %08x.\n",
5225 message, x, y, color, expected);
5232 struct projected_textures_test_run
5234 const char *message;
5235 DWORD flags;
5236 IDirect3DVertexDeclaration9 *decl;
5237 BOOL vs, ps;
5238 RECT rect;
5241 static void projected_textures_test(IDirect3DDevice9 *device,
5242 struct projected_textures_test_run tests[4])
5244 unsigned int i;
5246 static const DWORD vertex_shader[] =
5248 0xfffe0101, /* vs_1_1 */
5249 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5250 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
5251 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5252 0x00000001, 0xe00f0000, 0x90e40001, /* mov oT0, v1 */
5253 0x0000ffff /* end */
5255 static const DWORD pixel_shader[] =
5257 0xffff0103, /* ps_1_3 */
5258 0x00000042, 0xb00f0000, /* tex t0 */
5259 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5260 0x0000ffff /* end */
5262 IDirect3DVertexShader9 *vs = NULL;
5263 IDirect3DPixelShader9 *ps = NULL;
5264 IDirect3D9 *d3d;
5265 D3DCAPS9 caps;
5266 HRESULT hr;
5267 IDirect3DSurface9 *backbuffer;
5268 struct surface_readback rb;
5270 IDirect3DDevice9_GetDirect3D(device, &d3d);
5271 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5272 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5273 IDirect3D9_Release(d3d);
5275 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
5277 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader, &vs);
5278 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5280 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 3))
5282 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader, &ps);
5283 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5286 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
5287 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#lx.\n", hr);
5289 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0f, 0);
5290 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5292 hr = IDirect3DDevice9_BeginScene(device);
5293 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
5295 for (i = 0; i < 4; ++i)
5297 DWORD value = 0xdeadbeef;
5298 static const float proj_quads[] =
5300 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 4.0f, 6.0f,
5301 -1.0f, 0.0f, 0.1f, 0.0f, 4.0f, 4.0f, 6.0f,
5302 0.0f, -1.0f, 0.1f, 4.0f, 0.0f, 4.0f, 6.0f,
5303 0.0f, 0.0f, 0.1f, 4.0f, 4.0f, 4.0f, 6.0f,
5305 0.0f, -1.0f, 0.1f, 0.0f, 0.0f, 4.0f, 6.0f,
5306 0.0f, 0.0f, 0.1f, 0.0f, 4.0f, 4.0f, 6.0f,
5307 1.0f, -1.0f, 0.1f, 4.0f, 0.0f, 4.0f, 6.0f,
5308 1.0f, 0.0f, 0.1f, 4.0f, 4.0f, 4.0f, 6.0f,
5310 -1.0f, 0.0f, 0.1f, 0.0f, 0.0f, 4.0f, 6.0f,
5311 -1.0f, 1.0f, 0.1f, 0.0f, 4.0f, 4.0f, 6.0f,
5312 0.0f, 0.0f, 0.1f, 4.0f, 0.0f, 4.0f, 6.0f,
5313 0.0f, 1.0f, 0.1f, 4.0f, 4.0f, 4.0f, 6.0f,
5315 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, 4.0f, 6.0f,
5316 0.0f, 1.0f, 0.1f, 0.0f, 4.0f, 4.0f, 6.0f,
5317 1.0f, 0.0f, 0.1f, 4.0f, 0.0f, 4.0f, 6.0f,
5318 1.0f, 1.0f, 0.1f, 4.0f, 4.0f, 4.0f, 6.0f,
5321 if (tests[i].vs)
5323 if (!vs)
5325 skip("Vertex shaders not supported, skipping\n");
5326 continue;
5328 hr = IDirect3DDevice9_SetVertexShader(device, vs);
5330 else
5331 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5332 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5333 if (tests[i].ps)
5335 if (!ps)
5337 skip("Pixel shaders not supported, skipping\n");
5338 continue;
5340 hr = IDirect3DDevice9_SetPixelShader(device, ps);
5342 else
5343 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5344 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5346 hr = IDirect3DDevice9_SetVertexDeclaration(device, tests[i].decl);
5347 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5349 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, tests[i].flags);
5350 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5351 hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, &value);
5352 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5353 ok(value == tests[i].flags, "Got value %#lx.\n", value);
5355 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
5356 &proj_quads[i * 4 * 7], 7 * sizeof(float));
5357 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5360 hr = IDirect3DDevice9_EndScene(device);
5361 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5363 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5364 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5365 if (vs) IDirect3DVertexShader9_Release(vs);
5366 if (ps) IDirect3DPixelShader9_Release(ps);
5368 get_rt_readback(backbuffer, &rb);
5369 for (i = 0; i < 4; ++i)
5371 if ((!tests[i].vs || vs) && (!tests[i].ps || ps))
5372 check_rect(&rb, tests[i].rect, tests[i].message);
5374 release_surface_readback(&rb);
5375 IDirect3DSurface9_Release(backbuffer);
5378 static void texture_transform_flags_test(void)
5380 HRESULT hr;
5381 IDirect3D9 *d3d;
5382 D3DFORMAT fmt = D3DFMT_X8R8G8B8;
5383 D3DCAPS9 caps;
5384 IDirect3DTexture9 *texture = NULL;
5385 IDirect3DVolumeTexture9 *volume = NULL;
5386 unsigned int color, x, y, z, w, h;
5387 IDirect3DDevice9 *device;
5388 D3DLOCKED_RECT lr;
5389 D3DLOCKED_BOX lb;
5390 ULONG refcount;
5391 HWND window;
5392 IDirect3DVertexDeclaration9 *decl, *decl2, *decl3, *decl4;
5394 static const D3DVERTEXELEMENT9 decl_elements[] = {
5395 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5396 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5397 D3DDECL_END()
5399 static const D3DVERTEXELEMENT9 decl_elements2[] = {
5400 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5401 {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5402 D3DDECL_END()
5404 static const D3DVERTEXELEMENT9 decl_elements3[] = {
5405 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5406 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5407 D3DDECL_END()
5409 static const D3DVERTEXELEMENT9 decl_elements4[] = {
5410 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5411 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5412 D3DDECL_END()
5414 static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
5415 0x00, 0xff, 0x00, 0x00,
5416 0x00, 0x00, 0x00, 0x00,
5417 0x00, 0x00, 0x00, 0x00};
5418 static const D3DMATRIX identity =
5420 1.0f, 0.0f, 0.0f, 0.0f,
5421 0.0f, 1.0f, 0.0f, 0.0f,
5422 0.0f, 0.0f, 1.0f, 0.0f,
5423 0.0f, 0.0f, 0.0f, 1.0f,
5424 }}};
5426 window = create_window();
5427 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5428 ok(!!d3d, "Failed to create a D3D object.\n");
5429 if (!(device = create_device(d3d, window, window, TRUE)))
5431 skip("Failed to create a D3D device, skipping tests.\n");
5432 goto done;
5435 memset(&lr, 0, sizeof(lr));
5436 memset(&lb, 0, sizeof(lb));
5437 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
5438 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK)
5439 fmt = D3DFMT_A16B16G16R16;
5441 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5442 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5443 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
5444 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5445 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
5446 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5447 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements4, &decl4);
5448 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5449 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
5450 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5451 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
5452 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5453 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
5454 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5455 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
5456 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5457 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
5458 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5459 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
5460 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5461 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
5462 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5463 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
5464 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5465 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
5466 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5467 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
5468 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5469 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
5470 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5472 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5473 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5474 w = min(1024, caps.MaxTextureWidth);
5475 h = min(1024, caps.MaxTextureHeight);
5476 hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
5477 0, fmt, D3DPOOL_MANAGED, &texture, NULL);
5478 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5479 if (!texture)
5481 skip("Failed to create the test texture.\n");
5482 IDirect3DDevice9_Release(device);
5483 goto done;
5486 /* Unfortunately there is no easy way to set up a texture coordinate passthrough
5487 * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
5488 * 1.0 in red and green for the x and y coords
5490 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5491 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5492 for(y = 0; y < h; y++) {
5493 for(x = 0; x < w; x++) {
5494 double r_f = (double) y / (double) h;
5495 double g_f = (double) x / (double) w;
5496 if(fmt == D3DFMT_A16B16G16R16) {
5497 unsigned short r, g;
5498 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
5499 r = (unsigned short) (r_f * 65536.0);
5500 g = (unsigned short) (g_f * 65536.0);
5501 dst[0] = r;
5502 dst[1] = g;
5503 dst[2] = 0;
5504 dst[3] = 65535;
5505 } else {
5506 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
5507 unsigned char r = (unsigned char) (r_f * 255.0);
5508 unsigned char g = (unsigned char) (g_f * 255.0);
5509 dst[0] = 0;
5510 dst[1] = g;
5511 dst[2] = r;
5512 dst[3] = 255;
5516 hr = IDirect3DTexture9_UnlockRect(texture, 0);
5517 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5518 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5519 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5521 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5522 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5523 hr = IDirect3DDevice9_BeginScene(device);
5524 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5525 if(SUCCEEDED(hr))
5527 static const float quad1[] =
5529 -1.0f, -1.0f, 0.1f, 1.0f, 1.0f,
5530 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f,
5531 0.0f, -1.0f, 0.1f, 1.0f, 1.0f,
5532 0.0f, 0.0f, 0.1f, 1.0f, 1.0f,
5534 static const float quad2[] =
5536 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f,
5537 -1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
5538 0.0f, 0.0f, 0.1f, 1.0f, 1.0f,
5539 0.0f, 1.0f, 0.1f, 1.0f, 1.0f,
5541 static const float quad3[] =
5543 0.0f, 0.0f, 0.1f, 0.5f, 0.5f,
5544 0.0f, 1.0f, 0.1f, 0.5f, 0.5f,
5545 1.0f, 0.0f, 0.1f, 0.5f, 0.5f,
5546 1.0f, 1.0f, 0.1f, 0.5f, 0.5f,
5548 static const float quad4[] =
5550 320.0f, 480.0f, 0.1f, 1.0f, 0.0f, 1.0f,
5551 320.0f, 240.0f, 0.1f, 1.0f, 0.0f, 1.0f,
5552 640.0f, 480.0f, 0.1f, 1.0f, 0.0f, 1.0f,
5553 640.0f, 240.0f, 0.1f, 1.0f, 0.0f, 1.0f,
5555 D3DMATRIX mat =
5557 0.0f, 0.0f, 0.0f, 0.0f,
5558 0.0f, 0.0f, 0.0f, 0.0f,
5559 0.0f, 0.0f, 0.0f, 0.0f,
5560 0.0f, 0.0f, 0.0f, 0.0f,
5561 }}};
5563 /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
5564 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
5565 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5566 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
5567 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5569 /* What happens with transforms enabled? */
5570 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
5571 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5572 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
5573 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5575 /* What happens if 4 coords are used, but only 2 given ?*/
5576 mat.m[2][0] = 1.0f;
5577 mat.m[3][1] = 1.0f;
5578 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
5579 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5580 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
5581 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5582 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
5583 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5585 /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
5586 * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
5587 * due to the coords in the vertices. (turns out red, indeed)
5589 memset(&mat, 0, sizeof(mat));
5590 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
5591 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5592 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
5593 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5594 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
5595 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5596 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5597 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5599 hr = IDirect3DDevice9_EndScene(device);
5600 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5602 color = getPixelColor(device, 160, 360);
5603 ok(color_match(color, 0x00ffff00, 1), "quad 1 has color %08x, expected 0x00ffff00\n", color);
5604 color = getPixelColor(device, 160, 120);
5605 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
5606 color = getPixelColor(device, 480, 120);
5607 ok(color_match(color, 0x0000ff00, 1), "quad 3 has color %08x, expected 0x0000ff00\n", color);
5608 color = getPixelColor(device, 480, 360);
5609 ok(color_match(color, 0x00ff0000, 1), "quad 4 has color %08x, expected 0x00ff0000\n", color);
5610 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5611 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5613 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
5614 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5616 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5617 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5618 hr = IDirect3DDevice9_BeginScene(device);
5619 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5620 if(SUCCEEDED(hr))
5622 static const float quad1[] =
5624 -1.0f, -1.0f, 0.1f, 0.8f, 0.2f,
5625 -1.0f, 0.0f, 0.1f, 0.8f, 0.2f,
5626 0.0f, -1.0f, 0.1f, 0.8f, 0.2f,
5627 0.0f, 0.0f, 0.1f, 0.8f, 0.2f,
5629 static const float quad2[] =
5631 -1.0f, 0.0f, 0.1f, 0.5f, 1.0f,
5632 -1.0f, 1.0f, 0.1f, 0.5f, 1.0f,
5633 0.0f, 0.0f, 0.1f, 0.5f, 1.0f,
5634 0.0f, 1.0f, 0.1f, 0.5f, 1.0f,
5636 static const float quad3[] =
5638 0.0f, 0.0f, 0.1f, 0.5f, 1.0f,
5639 0.0f, 1.0f, 0.1f, 0.5f, 1.0f,
5640 1.0f, 0.0f, 0.1f, 0.5f, 1.0f,
5641 1.0f, 1.0f, 0.1f, 0.5f, 1.0f,
5643 static const float quad4[] =
5645 0.0f, -1.0f, 0.1f, 0.8f, 0.2f,
5646 0.0f, 0.0f, 0.1f, 0.8f, 0.2f,
5647 1.0f, -1.0f, 0.1f, 0.8f, 0.2f,
5648 1.0f, 0.0f, 0.1f, 0.8f, 0.2f,
5650 D3DMATRIX mat =
5652 0.0f, 0.0f, 0.0f, 0.0f,
5653 0.0f, 0.0f, 0.0f, 0.0f,
5654 0.0f, 1.0f, 0.0f, 0.0f,
5655 0.0f, 0.0f, 0.0f, 0.0f,
5656 }}};
5658 /* What happens to the default 1 in the 3rd coordinate if it is disabled? */
5659 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
5660 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5661 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
5662 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5664 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
5665 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5667 /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
5668 * it behaves like COUNT2 because normal textures require 2 coords. */
5669 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
5670 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5671 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
5672 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5674 /* Just to be sure, the same as quad2 above */
5675 memset(&mat, 0, sizeof(mat));
5676 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
5677 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5678 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
5679 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5680 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
5681 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5683 /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
5684 * used? And what happens to the first? */
5685 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
5686 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5687 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
5688 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5690 hr = IDirect3DDevice9_EndScene(device);
5691 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5693 color = getPixelColor(device, 160, 360);
5694 ok(color_match(color, 0x00ff0000, 1), "quad 1 has color %08x, expected 0x00ff0000\n", color);
5695 color = getPixelColor(device, 160, 120);
5696 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
5697 color = getPixelColor(device, 480, 120);
5698 ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
5699 "quad 3 has color %08x, expected 0x00ff8000\n", color);
5700 color = getPixelColor(device, 480, 360);
5701 ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00ff0000, 1),
5702 "quad 4 has color %08x, expected 0x0033cc00\n", color);
5703 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5704 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5706 IDirect3DTexture9_Release(texture);
5708 /* Test projected textures, without any fancy matrices */
5709 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
5710 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5711 if (SUCCEEDED(hr))
5713 struct projected_textures_test_run projected_tests_1[4] =
5716 "D3DTTFF_COUNT4 | D3DTTFF_PROJECTED - bottom left",
5717 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED,
5718 decl3,
5719 FALSE, TRUE,
5720 {120, 300, 240, 390},
5723 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED - bottom right",
5724 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
5725 decl3,
5726 FALSE, TRUE,
5727 {400, 360, 480, 420},
5729 /* Try with some invalid values */
5731 "0xffffffff (draws like COUNT4 | PROJECTED) - top left",
5732 0xffffffff,
5733 decl3,
5734 FALSE, TRUE,
5735 {120, 60, 240, 150}
5738 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (draws non-projected) - top right",
5739 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
5740 decl4,
5741 FALSE, TRUE,
5742 {340, 210, 360, 225},
5745 struct projected_textures_test_run projected_tests_2[4] =
5748 "D3DTTFF_PROJECTED (like COUNT4 | PROJECTED, texcoord has 4 components) - bottom left",
5749 D3DTTFF_PROJECTED,
5750 decl3,
5751 FALSE, TRUE,
5752 {120, 300, 240, 390},
5755 "D3DTTFF_PROJECTED (like COUNT3 | PROJECTED, texcoord has only 3 components) - bottom right",
5756 D3DTTFF_PROJECTED,
5757 decl,
5758 FALSE, TRUE,
5759 {400, 360, 480, 420},
5762 "0xffffffff (like COUNT3 | PROJECTED, texcoord has only 3 components) - top left",
5763 0xffffffff,
5764 decl,
5765 FALSE, TRUE,
5766 {80, 120, 160, 180},
5769 "D3DTTFF_COUNT1 (draws non-projected) - top right",
5770 D3DTTFF_COUNT1,
5771 decl4,
5772 FALSE, TRUE,
5773 {340, 210, 360, 225},
5776 struct projected_textures_test_run projected_tests_3[4] =
5779 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - bottom left",
5780 D3DTTFF_PROJECTED,
5781 decl3,
5782 TRUE, FALSE,
5783 {120, 300, 240, 390},
5786 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - bottom right",
5787 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
5788 decl3,
5789 TRUE, TRUE,
5790 {440, 300, 560, 390},
5793 "0xffffffff (like COUNT4 | PROJECTED) - top left",
5794 0xffffffff,
5795 decl3,
5796 TRUE, TRUE,
5797 {120, 60, 240, 150},
5800 "D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - top right",
5801 D3DTTFF_PROJECTED,
5802 decl3,
5803 FALSE, FALSE,
5804 {440, 60, 560, 150},
5808 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &identity);
5809 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5811 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5812 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5813 for(x = 0; x < 4; x++) {
5814 memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
5816 hr = IDirect3DTexture9_UnlockRect(texture, 0);
5817 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5818 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5819 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5821 projected_textures_test(device, projected_tests_1);
5822 projected_textures_test(device, projected_tests_2);
5823 projected_textures_test(device, projected_tests_3);
5825 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5826 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5827 IDirect3DTexture9_Release(texture);
5830 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
5831 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5832 /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
5833 * Thus watch out if sampling from texels between 0 and 1.
5835 hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
5836 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
5837 if(!volume) {
5838 skip("Failed to create a volume texture\n");
5839 goto out;
5842 hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
5843 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5844 for(z = 0; z < 32; z++) {
5845 for(y = 0; y < 32; y++) {
5846 for(x = 0; x < 32; x++) {
5847 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
5848 void *mem = ((char *) lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
5849 float r_f = (float) x / 31.0;
5850 float g_f = (float) y / 31.0;
5851 float b_f = (float) z / 31.0;
5853 if(fmt == D3DFMT_A16B16G16R16) {
5854 unsigned short *mem_s = mem;
5855 mem_s[0] = r_f * 65535.0;
5856 mem_s[1] = g_f * 65535.0;
5857 mem_s[2] = b_f * 65535.0;
5858 mem_s[3] = 65535;
5859 } else {
5860 unsigned char *mem_c = mem;
5861 mem_c[0] = b_f * 255.0;
5862 mem_c[1] = g_f * 255.0;
5863 mem_c[2] = r_f * 255.0;
5864 mem_c[3] = 255;
5869 hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
5870 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5872 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
5873 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5875 hr = IDirect3DDevice9_BeginScene(device);
5876 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5877 if(SUCCEEDED(hr))
5879 static const float quad1[] =
5881 -1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5882 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5883 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5884 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5886 static const float quad2[] =
5888 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5889 -1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5890 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5891 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5893 static const float quad3[] =
5895 0.0f, 0.0f, 0.1f, 0.0f, 0.0f,
5896 0.0f, 1.0f, 0.1f, 0.0f, 0.0f,
5897 1.0f, 0.0f, 0.1f, 0.0f, 0.0f,
5898 1.0f, 1.0f, 0.1f, 0.0f, 0.0f,
5900 static const float quad4[] =
5902 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5903 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5904 1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5905 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5907 D3DMATRIX mat =
5909 1.0f, 0.0f, 0.0f, 0.0f,
5910 0.0f, 0.0f, 1.0f, 0.0f,
5911 0.0f, 1.0f, 0.0f, 0.0f,
5912 0.0f, 0.0f, 0.0f, 1.0f,
5913 }}};
5914 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5915 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5917 /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
5918 * values
5920 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
5921 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5922 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
5923 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5924 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5925 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5927 /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
5928 * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
5929 * otherwise the w will be missing(blue).
5930 * turns out that on nvidia cards the blue color is missing, so it is an output modification.
5931 * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3. */
5932 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
5933 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5934 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5935 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5937 /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 3 */
5938 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &identity);
5939 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5940 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
5941 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5942 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5943 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5944 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
5945 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5947 /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
5948 * disable. ATI extends it up to the amount of values needed for the volume texture
5950 memset(&mat, 0, sizeof(mat));
5951 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
5952 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5953 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
5954 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5955 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5956 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5957 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5958 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5960 hr = IDirect3DDevice9_EndScene(device);
5961 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5964 color = getPixelColor(device, 160, 360);
5965 ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
5966 color = getPixelColor(device, 160, 120);
5967 ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
5968 "quad 2 has color %08x, expected 0x00ffff00\n", color);
5969 color = getPixelColor(device, 480, 120);
5970 ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
5971 color = getPixelColor(device, 480, 360);
5972 ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
5974 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5975 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5977 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
5978 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5979 hr = IDirect3DDevice9_BeginScene(device);
5980 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5981 if(SUCCEEDED(hr))
5983 static const float quad1[] =
5985 -1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5986 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5987 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5988 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5990 static const float quad2[] =
5992 -1.0f, 0.0f, 0.1f,
5993 -1.0f, 1.0f, 0.1f,
5994 0.0f, 0.0f, 0.1f,
5995 0.0f, 1.0f, 0.1f,
5997 static const float quad3[] =
5999 0.0f, 0.0f, 0.1f, 1.0f,
6000 0.0f, 1.0f, 0.1f, 1.0f,
6001 1.0f, 0.0f, 0.1f, 1.0f,
6002 1.0f, 1.0f, 0.1f, 1.0f,
6004 static const D3DMATRIX mat =
6006 0.0f, 0.0f, 0.0f, 0.0f,
6007 0.0f, 0.0f, 0.0f, 0.0f,
6008 0.0f, 0.0f, 0.0f, 0.0f,
6009 0.0f, 1.0f, 0.0f, 0.0f,
6010 }}};
6011 static const D3DMATRIX mat2 =
6013 0.0f, 0.0f, 0.0f, 1.0f,
6014 1.0f, 0.0f, 0.0f, 0.0f,
6015 0.0f, 1.0f, 0.0f, 0.0f,
6016 0.0f, 0.0f, 1.0f, 0.0f,
6017 }}};
6018 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
6019 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6021 /* Default values? 4 coords used, 3 passed. What happens to the 4th?
6022 * Use COUNT3 because newer Nvidia drivers return black when there are more (output) coords
6023 * than being used by the texture(volume tex -> 3). Again, as shown in earlier test the COUNTx
6024 * affects the post-transformation output, so COUNT3 plus the matrix above is OK for testing the
6025 * 4th *input* coordinate.
6027 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
6028 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6029 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
6030 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6031 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
6032 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6034 /* None passed */
6035 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &identity);
6036 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6037 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6038 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6039 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
6040 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6042 /* 4 used, 1 passed */
6043 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
6044 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6045 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat2);
6046 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6047 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
6048 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6050 hr = IDirect3DDevice9_EndScene(device);
6051 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6053 color = getPixelColor(device, 160, 360);
6054 ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
6055 color = getPixelColor(device, 160, 120);
6056 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
6057 color = getPixelColor(device, 480, 120);
6058 ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
6059 /* Quad4: unused */
6061 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6062 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6064 IDirect3DVolumeTexture9_Release(volume);
6066 out:
6067 IDirect3DVertexDeclaration9_Release(decl);
6068 IDirect3DVertexDeclaration9_Release(decl2);
6069 IDirect3DVertexDeclaration9_Release(decl3);
6070 IDirect3DVertexDeclaration9_Release(decl4);
6071 refcount = IDirect3DDevice9_Release(device);
6072 ok(!refcount, "Device has %lu references left.\n", refcount);
6073 done:
6074 IDirect3D9_Release(d3d);
6075 DestroyWindow(window);
6078 static void texdepth_test(void)
6080 IDirect3DPixelShader9 *shader;
6081 IDirect3DDevice9 *device;
6082 unsigned int color;
6083 IDirect3D9 *d3d;
6084 ULONG refcount;
6085 D3DCAPS9 caps;
6086 HWND window;
6087 HRESULT hr;
6089 static const float texdepth_test_data1[] = { 0.25f, 2.0f, 0.0f, 0.0f};
6090 static const float texdepth_test_data2[] = { 0.25f, 0.5f, 0.0f, 0.0f};
6091 static const float texdepth_test_data3[] = {-1.00f, 0.1f, 0.0f, 0.0f};
6092 static const float texdepth_test_data4[] = {-0.25f, -0.5f, 0.0f, 0.0f};
6093 static const float texdepth_test_data5[] = { 1.00f, -0.1f, 0.0f, 0.0f};
6094 static const float texdepth_test_data6[] = { 1.00f, 0.5f, 0.0f, 0.0f};
6095 static const float texdepth_test_data7[] = { 0.50f, 0.0f, 0.0f, 0.0f};
6096 static const DWORD shader_code[] =
6098 0xffff0104, /* ps_1_4 */
6099 0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c1, 0, 0, 1, 1 */
6100 0x00000001, 0x800f0005, 0xa0e40000, /* mov r5, c0 */
6101 0x0000fffd, /* phase */
6102 0x00000057, 0x800f0005, /* texdepth r5 */
6103 0x00000001, 0x800f0000, 0xa0e40001, /* mov r0, c1 */
6104 0x0000ffff /* end */
6106 static const float vertex[] =
6108 -1.0f, -1.0f, 0.0f,
6109 -1.0f, 1.0f, 0.0f,
6110 1.0f, -1.0f, 1.0f,
6111 1.0f, 1.0f, 1.0f,
6114 window = create_window();
6115 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6116 ok(!!d3d, "Failed to create a D3D object.\n");
6117 if (!(device = create_device(d3d, window, window, TRUE)))
6119 skip("Failed to create a D3D device, skipping tests.\n");
6120 goto done;
6123 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6124 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
6125 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 4))
6127 skip("No ps_1_4 support, skipping tests.\n");
6128 IDirect3DDevice9_Release(device);
6129 goto done;
6132 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
6133 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6135 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
6136 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6137 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6138 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
6139 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
6140 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6141 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
6142 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6143 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
6144 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6145 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6146 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6148 /* Fill the depth buffer with a gradient */
6149 hr = IDirect3DDevice9_BeginScene(device);
6150 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
6151 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
6152 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
6153 hr = IDirect3DDevice9_EndScene(device);
6154 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
6156 /* Now perform the actual tests. Same geometry, but with the shader */
6157 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
6158 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6159 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
6160 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6161 hr = IDirect3DDevice9_SetPixelShader(device, shader);
6162 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6164 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
6165 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6166 hr = IDirect3DDevice9_BeginScene(device);
6167 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
6168 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
6169 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
6170 hr = IDirect3DDevice9_EndScene(device);
6171 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
6173 color = getPixelColor(device, 158, 240);
6174 ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
6175 color = getPixelColor(device, 162, 240);
6176 ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
6178 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6179 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6181 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
6182 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6184 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
6185 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6186 hr = IDirect3DDevice9_BeginScene(device);
6187 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
6188 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
6189 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
6190 hr = IDirect3DDevice9_EndScene(device);
6191 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
6193 color = getPixelColor(device, 318, 240);
6194 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
6195 color = getPixelColor(device, 322, 240);
6196 ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
6198 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6199 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6201 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6202 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6204 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
6205 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6206 hr = IDirect3DDevice9_BeginScene(device);
6207 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
6208 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
6209 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
6210 hr = IDirect3DDevice9_EndScene(device);
6211 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
6213 color = getPixelColor(device, 1, 240);
6214 ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
6216 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6217 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6219 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
6220 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6222 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
6223 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6224 hr = IDirect3DDevice9_BeginScene(device);
6225 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
6226 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
6227 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
6228 hr = IDirect3DDevice9_EndScene(device);
6229 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
6231 color = getPixelColor(device, 318, 240);
6232 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
6233 color = getPixelColor(device, 322, 240);
6234 ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
6236 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6237 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6239 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
6240 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6242 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
6243 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6244 hr = IDirect3DDevice9_BeginScene(device);
6245 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
6246 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
6247 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
6248 hr = IDirect3DDevice9_EndScene(device);
6249 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
6251 color = getPixelColor(device, 1, 240);
6252 ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
6254 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6255 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6257 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
6258 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6260 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
6261 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6262 hr = IDirect3DDevice9_BeginScene(device);
6263 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
6264 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
6265 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
6266 hr = IDirect3DDevice9_EndScene(device);
6267 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
6269 color = getPixelColor(device, 638, 240);
6270 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
6272 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6273 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6275 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6276 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6278 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
6279 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6280 hr = IDirect3DDevice9_BeginScene(device);
6281 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
6282 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
6283 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
6284 hr = IDirect3DDevice9_EndScene(device);
6285 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
6287 color = getPixelColor(device, 638, 240);
6288 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
6290 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6291 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6293 IDirect3DPixelShader9_Release(shader);
6294 refcount = IDirect3DDevice9_Release(device);
6295 ok(!refcount, "Device has %lu references left.\n", refcount);
6296 done:
6297 IDirect3D9_Release(d3d);
6298 DestroyWindow(window);
6301 static void texkill_test(void)
6303 IDirect3DPixelShader9 *shader;
6304 IDirect3DDevice9 *device;
6305 unsigned int color;
6306 IDirect3D9 *d3d;
6307 ULONG refcount;
6308 D3DCAPS9 caps;
6309 HWND window;
6310 HRESULT hr;
6312 static const float vertex[] =
6314 /* bottom top right left */
6315 -1.0f, -1.0f, 1.0f, -0.1f, 0.9f, 0.9f, -0.1f,
6316 -1.0f, 1.0f, 1.0f, -0.1f, 0.9f, -0.1f, 0.9f,
6317 1.0f, -1.0f, 0.0f, 0.9f, -0.1f, 0.9f, -0.1f,
6318 1.0f, 1.0f, 0.0f, 0.9f, -0.1f, -0.1f, 0.9f,
6320 static const DWORD shader_code_11[] =
6322 0xffff0101, /* ps_1_1 */
6323 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
6324 0x00000041, 0xb00f0000, /* texkill t0 */
6325 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6326 0x0000ffff /* end */
6328 static const DWORD shader_code_20[] =
6330 0xffff0200, /* ps_2_0 */
6331 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
6332 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
6333 0x01000041, 0xb00f0000, /* texkill t0 */
6334 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
6335 0x0000ffff /* end */
6338 window = create_window();
6339 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6340 ok(!!d3d, "Failed to create a D3D object.\n");
6341 if (!(device = create_device(d3d, window, window, TRUE)))
6343 skip("Failed to create a D3D device, skipping tests.\n");
6344 goto done;
6347 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6348 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
6349 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
6351 skip("No ps_1_1 support, skipping tests.\n");
6352 IDirect3DDevice9_Release(device);
6353 goto done;
6356 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
6357 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6358 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
6359 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6361 hr = IDirect3DDevice9_SetPixelShader(device, shader);
6362 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6363 hr = IDirect3DDevice9_BeginScene(device);
6364 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
6365 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
6366 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
6367 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
6368 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
6369 hr = IDirect3DDevice9_EndScene(device);
6370 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
6372 color = getPixelColor(device, 63, 46);
6373 ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
6374 color = getPixelColor(device, 66, 46);
6375 ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
6376 color = getPixelColor(device, 63, 49);
6377 ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
6378 color = getPixelColor(device, 66, 49);
6379 ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
6381 color = getPixelColor(device, 578, 46);
6382 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
6383 color = getPixelColor(device, 575, 46);
6384 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
6385 color = getPixelColor(device, 578, 49);
6386 ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
6387 color = getPixelColor(device, 575, 49);
6388 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
6390 color = getPixelColor(device, 63, 430);
6391 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
6392 color = getPixelColor(device, 63, 433);
6393 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
6394 color = getPixelColor(device, 66, 433);
6395 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
6396 color = getPixelColor(device, 66, 430);
6397 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
6399 color = getPixelColor(device, 578, 430);
6400 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
6401 color = getPixelColor(device, 578, 433);
6402 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
6403 color = getPixelColor(device, 575, 433);
6404 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
6405 color = getPixelColor(device, 575, 430);
6406 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
6408 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6409 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6411 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6412 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6413 IDirect3DPixelShader9_Release(shader);
6415 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
6416 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6417 if (FAILED(IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader)))
6419 skip("Failed to create 2.0 test shader, most likely not supported.\n");
6420 IDirect3DDevice9_Release(device);
6421 goto done;
6424 hr = IDirect3DDevice9_SetPixelShader(device, shader);
6425 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6426 hr = IDirect3DDevice9_BeginScene(device);
6427 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
6428 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
6429 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
6430 hr = IDirect3DDevice9_EndScene(device);
6431 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
6433 color = getPixelColor(device, 63, 46);
6434 ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
6435 color = getPixelColor(device, 66, 46);
6436 ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
6437 color = getPixelColor(device, 63, 49);
6438 ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
6439 color = getPixelColor(device, 66, 49);
6440 ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
6442 color = getPixelColor(device, 578, 46);
6443 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
6444 color = getPixelColor(device, 575, 46);
6445 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
6446 color = getPixelColor(device, 578, 49);
6447 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
6448 color = getPixelColor(device, 575, 49);
6449 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
6451 color = getPixelColor(device, 63, 430);
6452 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
6453 color = getPixelColor(device, 63, 433);
6454 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
6455 color = getPixelColor(device, 66, 433);
6456 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
6457 color = getPixelColor(device, 66, 430);
6458 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
6460 color = getPixelColor(device, 578, 430);
6461 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
6462 color = getPixelColor(device, 578, 433);
6463 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
6464 color = getPixelColor(device, 575, 433);
6465 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
6466 color = getPixelColor(device, 575, 430);
6467 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
6469 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6470 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6472 IDirect3DPixelShader9_Release(shader);
6473 refcount = IDirect3DDevice9_Release(device);
6474 ok(!refcount, "Device has %lu references left.\n", refcount);
6475 done:
6476 IDirect3D9_Release(d3d);
6477 DestroyWindow(window);
6480 static void test_generate_mipmap(void)
6482 static const RECT r1 = {256, 256, 512, 512};
6483 static const RECT r2 = {512, 256, 768, 512};
6484 static const RECT r3 = {256, 512, 512, 768};
6485 static const RECT r4 = {512, 512, 768, 768};
6486 static const float quad[] =
6488 -0.5f, -0.5f, 0.1f, 0.0f, 0.0f,
6489 -0.5f, 0.5f, 0.1f, 0.0f, 1.0f,
6490 0.5f, -0.5f, 0.1f, 1.0f, 0.0f,
6491 0.5f, 0.5f, 0.1f, 1.0f, 1.0f,
6493 IDirect3DTexture9 *texture, *texture2;
6494 IDirect3DSurface9 *surface, *surface2;
6495 IDirect3DDevice9 *device;
6496 unsigned int color, x, y;
6497 D3DLOCKED_RECT lr;
6498 IDirect3D9 *d3d;
6499 ULONG refcount;
6500 HWND window;
6501 HRESULT hr;
6503 window = create_window();
6504 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6505 ok(!!d3d, "Failed to create a D3D object.\n");
6506 if (!(device = create_device(d3d, window, window, TRUE)))
6508 skip("Failed to create a D3D device, skipping tests.\n");
6509 goto done;
6512 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 1.0f, 0);
6513 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
6515 /* Make the texture big enough that a mipmap level > 0 is used. */
6516 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_RENDERTARGET,
6517 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, 0);
6518 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
6520 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, 0,
6521 D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &texture2, 0);
6522 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
6524 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6525 ok(SUCCEEDED(hr), "Failed to get surface, hr %#lx.\n", hr);
6526 hr = IDirect3DTexture9_GetSurfaceLevel(texture2, 0, &surface2);
6527 ok(SUCCEEDED(hr), "Failed to get surface, hr %#lx.\n", hr);
6528 hr = IDirect3DSurface9_LockRect(surface2, &lr, NULL, 0);
6529 ok(SUCCEEDED(hr), "Failed to map surface, hr %#lx.\n", hr);
6530 for (y = 0; y < 1024; ++y)
6532 for(x = 0; x < 1024; ++x)
6534 DWORD *dst = (DWORD *)((BYTE *)lr.pBits + y * lr.Pitch + x * 4);
6535 POINT pt;
6537 pt.x = x;
6538 pt.y = y;
6539 if (PtInRect(&r1, pt))
6540 *dst = 0xffff0000;
6541 else if (PtInRect(&r2, pt))
6542 *dst = 0xff00ff00;
6543 else if (PtInRect(&r3, pt))
6544 *dst = 0xff0000ff;
6545 else if (PtInRect(&r4, pt))
6546 *dst = 0xff000000;
6547 else
6548 *dst = 0xffffffff;
6551 hr = IDirect3DSurface9_UnlockRect(surface2);
6552 ok(SUCCEEDED(hr), "Failed to unmap surface, hr %#lx.\n", hr);
6554 hr = IDirect3DDevice9_UpdateSurface(device, surface2, NULL, surface, NULL);
6555 ok(SUCCEEDED(hr), "Failed to update surface, hr %#lx.\n", hr);
6557 IDirect3DSurface9_Release(surface2);
6558 IDirect3DSurface9_Release(surface);
6559 IDirect3DTexture9_Release(texture2);
6561 hr = IDirect3DTexture9_SetAutoGenFilterType(texture, D3DTEXF_LINEAR);
6562 ok(SUCCEEDED(hr), "Failed to set mipmap autogen filter type, hr %#lx.\n", hr);
6564 IDirect3DTexture9_GenerateMipSubLevels(texture);
6566 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
6567 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
6568 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
6569 ok(SUCCEEDED(hr), "Failed to set mipmap filtering, hr %#lx.\n", hr);
6570 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6571 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
6573 hr = IDirect3DDevice9_BeginScene(device);
6574 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
6575 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6576 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
6577 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6578 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
6579 hr = IDirect3DDevice9_EndScene(device);
6580 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
6581 IDirect3DTexture9_Release(texture);
6583 color = getPixelColor(device, 200, 200);
6584 ok(!color, "Unexpected color 0x%08x.\n", color);
6585 color = getPixelColor(device, 280, 200);
6586 ok(!color, "Unexpected color 0x%08x.\n", color);
6587 color = getPixelColor(device, 360, 200);
6588 ok(!color, "Unexpected color 0x%08x.\n", color);
6589 color = getPixelColor(device, 440, 200);
6590 ok(!color, "Unexpected color 0x%08x.\n", color);
6591 color = getPixelColor(device, 200, 270);
6592 ok(!color, "Unexpected color 0x%08x.\n", color);
6593 color = getPixelColor(device, 280, 270);
6594 ok(!color, "Unexpected color 0x%08x.\n", color);
6595 color = getPixelColor(device, 360, 270);
6596 ok(!color, "Unexpected color 0x%08x.\n", color);
6597 color = getPixelColor(device, 440, 270);
6598 ok(!color, "Unexpected color 0x%08x.\n", color);
6599 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6600 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
6602 refcount = IDirect3DDevice9_Release(device);
6603 ok(!refcount, "Device has %lu references left.\n", refcount);
6604 done:
6605 IDirect3D9_Release(d3d);
6606 DestroyWindow(window);
6609 static void test_mipmap_autogen(void)
6611 IDirect3DSurface9 *surface, *surface2, *surface3, *backbuffer;
6612 IDirect3DTexture9 *texture, *texture2, *texture3;
6613 IDirect3DCubeTexture9 *cube_texture;
6614 unsigned int color, i, x, y;
6615 IDirect3DDevice9 *device;
6616 D3DLOCKED_RECT lr;
6617 IDirect3D9 *d3d;
6618 ULONG refcount;
6619 D3DCAPS9 caps;
6620 HWND window;
6621 HRESULT hr;
6623 static const RECT r1 = {256, 256, 512, 512};
6624 static const RECT r2 = {512, 256, 768, 512};
6625 static const RECT r3 = {256, 512, 512, 768};
6626 static const RECT r4 = {512, 512, 768, 768};
6627 static const float quad[] =
6629 -0.5f, -0.5f, 0.1f, 0.0f, 0.0f,
6630 -0.5f, 0.5f, 0.1f, 0.0f, 1.0f,
6631 0.5f, -0.5f, 0.1f, 1.0f, 0.0f,
6632 0.5f, 0.5f, 0.1f, 1.0f, 1.0f,
6635 window = create_window();
6636 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6637 ok(!!d3d, "Failed to create a D3D object.\n");
6638 if (!(device = create_device(d3d, window, window, TRUE)))
6640 skip("Failed to create a D3D device, skipping tests.\n");
6641 goto done;
6644 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
6645 D3DFMT_X8R8G8B8, D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK)
6647 skip("No autogenmipmap support.\n");
6648 IDirect3DDevice9_Release(device);
6649 goto done;
6652 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6653 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#lx.\n", hr);
6655 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 1.0f, 0);
6656 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6658 /* Make the texture big enough that a mipmap level > 0 is used. */
6659 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
6660 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
6661 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6663 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6664 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6665 memset(&lr, 0, sizeof(lr));
6666 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
6667 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6668 for(y = 0; y < 1024; y++) {
6669 for(x = 0; x < 1024; x++) {
6670 DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
6671 POINT pt;
6673 pt.x = x;
6674 pt.y = y;
6675 if(PtInRect(&r1, pt)) {
6676 *dst = 0xffff0000;
6677 } else if(PtInRect(&r2, pt)) {
6678 *dst = 0xff00ff00;
6679 } else if(PtInRect(&r3, pt)) {
6680 *dst = 0xff0000ff;
6681 } else if(PtInRect(&r4, pt)) {
6682 *dst = 0xff000000;
6683 } else {
6684 *dst = 0xffffffff;
6688 hr = IDirect3DSurface9_UnlockRect(surface);
6689 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6690 IDirect3DSurface9_Release(surface);
6692 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6693 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6694 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
6695 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6696 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6697 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
6699 hr = IDirect3DDevice9_BeginScene(device);
6700 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
6701 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6702 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
6703 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6704 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
6705 hr = IDirect3DDevice9_EndScene(device);
6706 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
6707 IDirect3DTexture9_Release(texture);
6709 color = getPixelColor(device, 200, 200);
6710 ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
6711 color = getPixelColor(device, 280, 200);
6712 ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
6713 color = getPixelColor(device, 360, 200);
6714 ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
6715 color = getPixelColor(device, 440, 200);
6716 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
6717 color = getPixelColor(device, 200, 270);
6718 ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
6719 color = getPixelColor(device, 280, 270);
6720 ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
6721 color = getPixelColor(device, 360, 270);
6722 ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
6723 color = getPixelColor(device, 440, 270);
6724 ok(color == 0x00ffffff, "pixel 440/270 has color %08x, expected 0x00ffffff\n", color);
6725 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6726 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6728 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6729 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
6730 if (!(caps.DevCaps2 & D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES))
6732 skip("Blitting from textures is not supported.\n");
6733 IDirect3DSurface9_Release(backbuffer);
6734 IDirect3DDevice9_Release(device);
6735 goto done;
6737 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1, 0,
6738 D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &texture, 0);
6739 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
6740 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
6741 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture2, 0);
6742 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
6743 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP | D3DUSAGE_RENDERTARGET,
6744 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture3, 0);
6745 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
6747 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6748 ok(SUCCEEDED(hr), "Failed to get surface, hr %#lx.\n", hr);
6749 memset(&lr, 0, sizeof(lr));
6750 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
6751 ok(SUCCEEDED(hr), "Failed to map surface, hr %#lx.\n", hr);
6752 for (y = 0; y < 1024; ++y)
6754 for (x = 0; x < 1024; ++x)
6756 DWORD *dst = (DWORD *)((BYTE *)lr.pBits + y * lr.Pitch + x * 4);
6757 POINT pt;
6759 pt.x = x;
6760 pt.y = y;
6761 if (PtInRect(&r1, pt))
6762 *dst = 0xffff0000;
6763 else if (PtInRect(&r2, pt))
6764 *dst = 0xff00ff00;
6765 else if (PtInRect(&r3, pt))
6766 *dst = 0xff0000ff;
6767 else if (PtInRect(&r4, pt))
6768 *dst = 0xff000000;
6769 else
6770 *dst = 0xffffffff;
6773 hr = IDirect3DSurface9_UnlockRect(surface);
6774 ok(SUCCEEDED(hr), "Failed to unmap surface, hr %#lx.\n", hr);
6775 IDirect3DSurface9_Release(surface);
6777 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)texture,
6778 (IDirect3DBaseTexture9 *)texture2);
6779 ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx.\n", hr);
6781 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture2);
6782 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
6784 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 1.0f, 0);
6785 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
6787 hr = IDirect3DDevice9_BeginScene(device);
6788 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
6789 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6790 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
6791 hr = IDirect3DDevice9_EndScene(device);
6792 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
6794 color = getPixelColor(device, 200, 200);
6795 ok(color == 0x00ffffff, "Unexpected color 0x%08x.\n", color);
6796 color = getPixelColor(device, 280, 200);
6797 ok(color == 0x000000ff, "Unexpected color 0x%08x.\n", color);
6798 color = getPixelColor(device, 360, 200);
6799 ok(color == 0x00000000, "Unexpected color 0x%08x.\n", color);
6800 color = getPixelColor(device, 440, 200);
6801 ok(color == 0x00ffffff, "Unexpected color 0x%08x.\n", color);
6802 color = getPixelColor(device, 200, 270);
6803 ok(color == 0x00ffffff, "Unexpected color 0x%08x.\n", color);
6804 color = getPixelColor(device, 280, 270);
6805 ok(color == 0x00ff0000, "Unexpected color 0x%08x.\n", color);
6806 color = getPixelColor(device, 360, 270);
6807 ok(color == 0x0000ff00, "Unexpected color 0x%08x.\n", color);
6808 color = getPixelColor(device, 440, 270);
6809 ok(color == 0x00ffffff, "Unexpected color 0x%08x.\n", color);
6811 hr = IDirect3DTexture9_GetSurfaceLevel(texture2, 0, &surface2);
6812 ok(SUCCEEDED(hr), "Failed to get surface, hr %#lx.\n", hr);
6813 hr = IDirect3DTexture9_GetSurfaceLevel(texture3, 0, &surface3);
6814 ok(SUCCEEDED(hr), "Failed to get surface, hr %#lx.\n", hr);
6815 hr = IDirect3DDevice9_StretchRect(device, surface2, NULL, surface3, NULL, D3DTEXF_POINT);
6816 ok(SUCCEEDED(hr), "Failed to blit texture, hr %#lx.\n", hr);
6818 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture3);
6819 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
6821 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 1.0f, 0);
6822 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
6824 hr = IDirect3DDevice9_BeginScene(device);
6825 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
6826 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6827 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
6828 hr = IDirect3DDevice9_EndScene(device);
6829 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
6831 color = getPixelColor(device, 200, 200);
6832 ok(color == 0x00ffffff, "Unexpected color 0x%08x.\n", color);
6833 color = getPixelColor(device, 280, 200);
6834 ok(color == 0x000000ff, "Unexpected color 0x%08x.\n", color);
6835 color = getPixelColor(device, 360, 200);
6836 ok(color == 0x00000000, "Unexpected color 0x%08x.\n", color);
6837 color = getPixelColor(device, 440, 200);
6838 ok(color == 0x00ffffff, "Unexpected color 0x%08x.\n", color);
6839 color = getPixelColor(device, 200, 270);
6840 ok(color == 0x00ffffff, "Unexpected color 0x%08x.\n", color);
6841 color = getPixelColor(device, 280, 270);
6842 ok(color == 0x00ff0000, "Unexpected color 0x%08x.\n", color);
6843 color = getPixelColor(device, 360, 270);
6844 ok(color == 0x0000ff00, "Unexpected color 0x%08x.\n", color);
6845 color = getPixelColor(device, 440, 270);
6846 ok(color == 0x00ffffff, "Unexpected color 0x%08x.\n", color);
6848 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface3);
6849 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
6851 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 1.0f, 0);
6852 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
6854 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
6855 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
6857 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 1.0f, 0);
6858 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
6860 hr = IDirect3DDevice9_BeginScene(device);
6861 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
6862 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6863 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
6864 hr = IDirect3DDevice9_EndScene(device);
6865 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
6867 color = getPixelColor(device, 200, 200);
6868 ok(color == 0x0000ffff, "Unexpected color 0x%08x.\n", color);
6870 IDirect3DSurface9_Release(surface3);
6871 IDirect3DSurface9_Release(surface2);
6872 IDirect3DTexture9_Release(texture3);
6873 IDirect3DTexture9_Release(texture2);
6874 IDirect3DTexture9_Release(texture);
6876 if (!(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP))
6878 skip("No cube textures support.\n");
6879 IDirect3DSurface9_Release(backbuffer);
6880 IDirect3DDevice9_Release(device);
6881 goto done;
6883 hr = IDirect3DDevice9_CreateCubeTexture(device, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
6884 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &cube_texture, 0);
6885 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
6886 for (i = 0; i < 6; ++i)
6888 hr = IDirect3DCubeTexture9_LockRect(cube_texture, i, 0, &lr, NULL, 0);
6889 ok(SUCCEEDED(hr), "Failed to map texture, hr %#lx.\n", hr);
6891 for (y = 0; y < 1024; ++y)
6893 for (x = 0; x < 1024; ++x)
6895 DWORD *dst = (DWORD *)((BYTE *)lr.pBits + y * lr.Pitch + x * 4);
6896 POINT pt;
6898 pt.x = x;
6899 pt.y = y;
6900 if (PtInRect(&r1, pt))
6901 *dst = 0xffff0000;
6902 else if (PtInRect(&r2, pt))
6903 *dst = 0xff00ff00;
6904 else if (PtInRect(&r3, pt))
6905 *dst = 0xff0000ff;
6906 else if (PtInRect(&r4, pt))
6907 *dst = 0xff000000;
6908 else
6909 *dst = 0xffffffff;
6912 hr = IDirect3DCubeTexture9_UnlockRect(cube_texture, i, 0);
6913 ok(SUCCEEDED(hr), "Failed to unmap texture, hr %#lx.\n", hr);
6916 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)cube_texture);
6917 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
6919 hr = IDirect3DDevice9_BeginScene(device);
6920 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
6921 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6922 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
6923 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6924 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
6925 hr = IDirect3DDevice9_EndScene(device);
6926 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
6927 IDirect3DCubeTexture9_Release(cube_texture);
6929 color = getPixelColor(device, 200, 200);
6930 ok(color == 0x00000000, "Unexpected color 0x%08x.\n", color);
6931 color = getPixelColor(device, 280, 200);
6932 ok(color == 0x00ffffff, "Unexpected color 0x%08x.\n", color);
6933 color = getPixelColor(device, 360, 200);
6934 ok(color == 0x00ffffff, "Unexpected color 0x%08x.\n", color);
6935 color = getPixelColor(device, 440, 200);
6936 ok(color == 0x00ffffff, "Unexpected color 0x%08x.\n", color);
6937 color = getPixelColor(device, 200, 270);
6938 ok(color == 0x00000000, "Unexpected color 0x%08x.\n", color);
6939 color = getPixelColor(device, 280, 270);
6940 ok(color == 0x00ffffff, "Unexpected color 0x%08x.\n", color);
6941 color = getPixelColor(device, 360, 270);
6942 ok(color == 0x00ffffff, "Unexpected color 0x%08x.\n", color);
6943 color = getPixelColor(device, 440, 270);
6944 ok(color == 0x0000ff00, "Unexpected color 0x%08x.\n", color);
6946 /* Test format not supporting D3DUSAGE_AUTOGENMIPMAP. */
6947 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
6948 D3DFMT_X8R8G8B8, D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_A1R5G5B5);
6949 if (hr != D3DOK_NOAUTOGEN)
6951 skip("D3DFMT_A1R5G5B5 support is not D3DOK_NOAUTOGEN (hr %#lx).\n", hr);
6953 else
6955 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
6956 D3DFMT_A1R5G5B5, D3DPOOL_MANAGED, &texture, 0);
6957 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
6959 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
6960 ok(SUCCEEDED(hr), "Failed to map texture, hr %#lx.\n", hr);
6961 for (y = 0; y < 1024; ++y)
6963 for (x = 0; x < 1024; ++x)
6965 WORD *dst = (WORD *)(((BYTE *)lr.pBits) + y * lr.Pitch + x * 2);
6966 POINT pt;
6968 pt.x = x;
6969 pt.y = y;
6970 if (PtInRect(&r1, pt))
6971 *dst = 0xfc00;
6972 else if (PtInRect(&r2, pt))
6973 *dst = 0x83e0;
6974 else if (PtInRect(&r3, pt))
6975 *dst = 0x801f;
6976 else if (PtInRect(&r4, pt))
6977 *dst = 0x8000;
6978 else
6979 *dst = 0xffff;
6982 hr = IDirect3DTexture9_UnlockRect(texture, 0);
6983 ok(SUCCEEDED(hr), "Failed to unmap texture, hr %#lx.\n", hr);
6985 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
6986 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
6988 hr = IDirect3DDevice9_BeginScene(device);
6989 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
6990 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6991 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
6992 hr = IDirect3DDevice9_EndScene(device);
6993 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
6994 IDirect3DTexture9_Release(texture);
6996 color = getPixelColor(device, 200, 200);
6997 ok(color == 0x00ffffff, "Unexpected color 0x%08x.\n", color);
6998 color = getPixelColor(device, 280, 200);
6999 ok(color == 0x000000ff, "Unexpected color 0x%08x.\n", color);
7000 color = getPixelColor(device, 360, 200);
7001 ok(color == 0x00000000, "Unexpected color 0x%08x.\n", color);
7002 color = getPixelColor(device, 440, 200);
7003 ok(color == 0x00ffffff, "Unexpected color 0x%08x.\n", color);
7004 color = getPixelColor(device, 200, 270);
7005 ok(color == 0x00ffffff, "Unexpected color 0x%08x.\n", color);
7006 color = getPixelColor(device, 280, 270);
7007 ok(color == 0x00ff0000, "Unexpected color 0x%08x.\n", color);
7008 color = getPixelColor(device, 360, 270);
7009 ok(color == 0x0000ff00, "Unexpected color 0x%08x.\n", color);
7010 color = getPixelColor(device, 440, 270);
7011 ok(color == 0x00ffffff, "Unexpected color 0x%08x.\n", color);
7012 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7013 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
7016 IDirect3DSurface9_Release(backbuffer);
7018 refcount = IDirect3DDevice9_Release(device);
7019 ok(!refcount, "Device has %lu references left.\n", refcount);
7020 done:
7021 IDirect3D9_Release(d3d);
7022 DestroyWindow(window);
7025 static void test_constant_clamp_vs(void)
7027 IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
7028 IDirect3DVertexDeclaration9 *decl;
7029 IDirect3DDevice9 *device;
7030 unsigned int color;
7031 IDirect3D9 *d3d;
7032 ULONG refcount;
7033 D3DCAPS9 caps;
7034 HWND window;
7035 HRESULT hr;
7037 static const DWORD shader_code_11[] =
7039 0xfffe0101, /* vs_1_1 */
7040 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7041 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
7042 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
7043 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7044 0x0000ffff /* end */
7046 static const DWORD shader_code_11_2[] =
7048 0xfffe0101, /* vs_1_1 */
7049 0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
7050 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
7051 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7052 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
7053 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
7054 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7055 0x0000ffff /* end */
7057 static const DWORD shader_code_20[] =
7059 0xfffe0200, /* vs_2_0 */
7060 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7061 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
7062 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
7063 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7064 0x0000ffff /* end */
7066 static const DWORD shader_code_20_2[] =
7068 0xfffe0200, /* vs_2_0 */
7069 0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
7070 0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
7071 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7072 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
7073 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
7074 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7075 0x0000ffff /* end */
7077 static const D3DVERTEXELEMENT9 decl_elements[] =
7079 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7080 D3DDECL_END()
7082 static const float quad1[] =
7084 -1.0f, -1.0f, 0.1f,
7085 -1.0f, 0.0f, 0.1f,
7086 0.0f, -1.0f, 0.1f,
7087 0.0f, 0.0f, 0.1f,
7089 static const float quad2[] =
7091 0.0f, -1.0f, 0.1f,
7092 0.0f, 0.0f, 0.1f,
7093 1.0f, -1.0f, 0.1f,
7094 1.0f, 0.0f, 0.1f,
7096 static const float quad3[] =
7098 0.0f, 0.0f, 0.1f,
7099 0.0f, 1.0f, 0.1f,
7100 1.0f, 0.0f, 0.1f,
7101 1.0f, 1.0f, 0.1f,
7103 static const float quad4[] =
7105 -1.0f, 0.0f, 0.1f,
7106 -1.0f, 1.0f, 0.1f,
7107 0.0f, 0.0f, 0.1f,
7108 0.0f, 1.0f, 0.1f,
7110 static const float test_data_c1[4] = { 1.25f, -0.50f, -1.50f, 1.0f};
7111 static const float test_data_c2[4] = {-0.50f, 1.25f, 2.00f, 1.0f};
7113 window = create_window();
7114 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7115 ok(!!d3d, "Failed to create a D3D object.\n");
7116 if (!(device = create_device(d3d, window, window, TRUE)))
7118 skip("Failed to create a D3D device, skipping tests.\n");
7119 goto done;
7122 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7123 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
7124 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
7126 skip("No vs_1_1 support, skipping tests.\n");
7127 IDirect3DDevice9_Release(device);
7128 goto done;
7131 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
7132 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7134 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
7135 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7136 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
7137 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7138 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
7139 if(FAILED(hr)) shader_20 = NULL;
7140 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
7141 if(FAILED(hr)) shader_20_2 = NULL;
7142 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
7143 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7145 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
7146 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7147 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
7148 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7149 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
7150 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7152 hr = IDirect3DDevice9_BeginScene(device);
7153 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
7155 hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
7156 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
7157 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
7158 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
7160 hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
7161 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
7162 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
7163 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
7165 if (shader_20)
7167 hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
7168 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
7169 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
7170 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
7173 if (shader_20_2)
7175 hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
7176 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
7177 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
7178 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
7181 hr = IDirect3DDevice9_EndScene(device);
7182 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
7184 color = getPixelColor(device, 160, 360);
7185 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
7186 "quad 1 has color %08x, expected 0x00bfbf80\n", color);
7187 color = getPixelColor(device, 480, 360);
7188 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
7189 "quad 2 has color %08x, expected 0x00bfbf80\n", color);
7190 if(shader_20) {
7191 color = getPixelColor(device, 480, 120);
7192 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
7193 "quad 3 has color %08x, expected 0x00bfbf80\n", color);
7195 if(shader_20_2) {
7196 color = getPixelColor(device, 160, 120);
7197 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
7198 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
7200 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7201 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7203 IDirect3DVertexDeclaration9_Release(decl);
7204 if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
7205 if(shader_20) IDirect3DVertexShader9_Release(shader_20);
7206 IDirect3DVertexShader9_Release(shader_11_2);
7207 IDirect3DVertexShader9_Release(shader_11);
7208 refcount = IDirect3DDevice9_Release(device);
7209 ok(!refcount, "Device has %lu references left.\n", refcount);
7210 done:
7211 IDirect3D9_Release(d3d);
7212 DestroyWindow(window);
7215 static void constant_clamp_ps_test(void)
7217 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
7218 IDirect3DDevice9 *device;
7219 unsigned int color;
7220 IDirect3D9 *d3d;
7221 ULONG refcount;
7222 D3DCAPS9 caps;
7223 HWND window;
7224 HRESULT hr;
7226 static const DWORD shader_code_11[] =
7228 0xffff0101, /* ps_1_1 */
7229 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
7230 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
7231 0x0000ffff /* end */
7233 static const DWORD shader_code_12[] =
7235 0xffff0102, /* ps_1_2 */
7236 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
7237 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
7238 0x0000ffff /* end */
7240 /* Skip 1.3 shaders because we have only 4 quads (ok, could make them
7241 * smaller if needed). 1.2 and 1.4 shaders behave the same, so it's
7242 * unlikely that 1.3 shaders are different. During development of this
7243 * test, 1.3 shaders were verified too. */
7244 static const DWORD shader_code_14[] =
7246 0xffff0104, /* ps_1_4 */
7247 /* Try to make one constant local. It gets clamped too, although the
7248 * binary contains the bigger numbers. */
7249 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
7250 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
7251 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
7252 0x0000ffff /* end */
7254 static const DWORD shader_code_20[] =
7256 0xffff0200, /* ps_2_0 */
7257 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
7258 0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
7259 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
7260 0x0000ffff /* end */
7262 static const float quad1[] =
7264 -1.0f, -1.0f, 0.1f,
7265 -1.0f, 0.0f, 0.1f,
7266 0.0f, -1.0f, 0.1f,
7267 0.0f, 0.0f, 0.1f,
7269 static const float quad2[] =
7271 0.0f, -1.0f, 0.1f,
7272 0.0f, 0.0f, 0.1f,
7273 1.0f, -1.0f, 0.1f,
7274 1.0f, 0.0f, 0.1f,
7276 static const float quad3[] =
7278 0.0f, 0.0f, 0.1f,
7279 0.0f, 1.0f, 0.1f,
7280 1.0f, 0.0f, 0.1f,
7281 1.0f, 1.0f, 0.1f,
7283 static const float quad4[] =
7285 -1.0f, 0.0f, 0.1f,
7286 -1.0f, 1.0f, 0.1f,
7287 0.0f, 0.0f, 0.1f,
7288 0.0f, 1.0f, 0.1f,
7290 static const float test_data_c1[4] = { 1.25f, -0.50f, -1.50f, 1.0f};
7291 static const float test_data_c2[4] = {-0.50f, 1.25f, 2.00f, 1.0f};
7293 window = create_window();
7294 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7295 ok(!!d3d, "Failed to create a D3D object.\n");
7296 if (!(device = create_device(d3d, window, window, TRUE)))
7298 skip("Failed to create a D3D device, skipping tests.\n");
7299 goto done;
7302 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7303 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
7304 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 4))
7306 skip("No ps_1_4 support, skipping tests.\n");
7307 IDirect3DDevice9_Release(device);
7308 goto done;
7311 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
7312 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7314 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
7315 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7316 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
7317 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7318 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
7319 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7320 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
7321 if(FAILED(hr)) shader_20 = NULL;
7323 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
7324 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7325 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
7326 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7327 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7328 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7330 hr = IDirect3DDevice9_BeginScene(device);
7331 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
7333 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
7334 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
7335 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
7336 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
7338 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
7339 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
7340 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
7341 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
7343 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
7344 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
7345 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
7346 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
7348 if (shader_20)
7350 hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
7351 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
7352 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
7353 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
7356 hr = IDirect3DDevice9_EndScene(device);
7357 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
7359 color = getPixelColor(device, 160, 360);
7360 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
7361 "quad 1 has color %08x, expected 0x00808000\n", color);
7362 color = getPixelColor(device, 480, 360);
7363 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
7364 "quad 2 has color %08x, expected 0x00808000\n", color);
7365 color = getPixelColor(device, 480, 120);
7366 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
7367 "quad 3 has color %08x, expected 0x00808000\n", color);
7368 if(shader_20) {
7369 color = getPixelColor(device, 160, 120);
7370 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
7371 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
7373 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7374 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7376 if(shader_20) IDirect3DPixelShader9_Release(shader_20);
7377 IDirect3DPixelShader9_Release(shader_14);
7378 IDirect3DPixelShader9_Release(shader_12);
7379 IDirect3DPixelShader9_Release(shader_11);
7380 refcount = IDirect3DDevice9_Release(device);
7381 ok(!refcount, "Device has %lu references left.\n", refcount);
7382 done:
7383 IDirect3D9_Release(d3d);
7384 DestroyWindow(window);
7387 static void dp2add_ps_test(void)
7389 IDirect3DPixelShader9 *shader_dp2add_sat;
7390 IDirect3DPixelShader9 *shader_dp2add;
7391 IDirect3DDevice9 *device;
7392 unsigned int color;
7393 IDirect3D9 *d3d;
7394 ULONG refcount;
7395 D3DCAPS9 caps;
7396 HWND window;
7397 HRESULT hr;
7399 /* DP2ADD is defined as: (src0.r * src1.r) + (src0.g * src1.g) + src2.
7400 * One D3D restriction of all shader instructions except SINCOS is that no more than 2
7401 * source tokens can be constants. So, for this exercise, we move contents of c0 to
7402 * r0 first.
7403 * The result here for the r,g,b components should be roughly 0.5:
7404 * (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
7405 static const DWORD shader_code_dp2add[] = {
7406 0xffff0200, /* ps_2_0 */
7407 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0 */
7409 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
7410 0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add r0.rgb, r0, r0, r0.a */
7412 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
7413 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
7414 0x0000ffff /* end */
7417 /* Test the _sat modifier, too. Result here should be:
7418 * DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
7419 * _SAT: ==> 1.0
7420 * ADD: (1.0 + -0.5) = 0.5
7422 static const DWORD shader_code_dp2add_sat[] = {
7423 0xffff0200, /* ps_2_0 */
7424 0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0 */
7426 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
7427 0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add_sat r0.rgb, r0, r0, r0.a */
7428 0x03000002, 0x80070000, 0x80e40000, 0xa0000000, /* add r0.rgb, r0, c0.r */
7430 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
7431 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
7432 0x0000ffff /* end */
7434 static const float quad[] =
7436 -1.0f, -1.0f, 0.1f,
7437 -1.0f, 1.0f, 0.1f,
7438 1.0f, -1.0f, 0.1f,
7439 1.0f, 1.0f, 0.1f,
7442 window = create_window();
7443 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7444 ok(!!d3d, "Failed to create a D3D object.\n");
7445 if (!(device = create_device(d3d, window, window, TRUE)))
7447 skip("Failed to create a D3D device, skipping tests.\n");
7448 goto done;
7451 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7452 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
7453 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
7455 skip("No ps_2_0 support, skipping tests.\n");
7456 IDirect3DDevice9_Release(device);
7457 goto done;
7460 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
7461 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7463 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
7464 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7466 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
7467 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7469 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7470 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7472 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
7473 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#lx.\n", hr);
7474 hr = IDirect3DDevice9_BeginScene(device);
7475 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
7476 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
7477 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#lx.\n", hr);
7478 hr = IDirect3DDevice9_EndScene(device);
7479 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
7481 color = getPixelColor(device, 360, 240);
7482 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1), "Got unexpected color 0x%08x.\n", color);
7484 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7485 ok(SUCCEEDED(hr), "Failed to present frame, hr %#lx.\n", hr);
7486 IDirect3DPixelShader9_Release(shader_dp2add);
7488 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
7489 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#lx.\n", hr);
7490 hr = IDirect3DDevice9_BeginScene(device);
7491 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
7492 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
7493 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#lx.\n", hr);
7494 hr = IDirect3DDevice9_EndScene(device);
7495 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
7497 color = getPixelColor(device, 360, 240);
7498 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1), "Got unexpected color 0x%08x.\n", color);
7500 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7501 ok(SUCCEEDED(hr), "Failed to present frame, hr %#lx.\n", hr);
7502 IDirect3DPixelShader9_Release(shader_dp2add_sat);
7504 refcount = IDirect3DDevice9_Release(device);
7505 ok(!refcount, "Device has %lu references left.\n", refcount);
7506 done:
7507 IDirect3D9_Release(d3d);
7508 DestroyWindow(window);
7511 static void cnd_test(void)
7513 IDirect3DPixelShader9 *shader_11_coissue_2, *shader_12_coissue_2, *shader_13_coissue_2, *shader_14_coissue_2;
7514 IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
7515 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
7516 IDirect3DDevice9 *device;
7517 unsigned int color;
7518 IDirect3D9 *d3d;
7519 ULONG refcount;
7520 D3DCAPS9 caps;
7521 HWND window;
7522 HRESULT hr;
7524 /* ps 1.x shaders are rather picky with writemasks and source swizzles.
7525 * The dp3 is used to copy r0.r to all components of r1, then copy r1.a to
7526 * r0.a. Essentially it does a mov r0.a, r0.r, which isn't allowed as-is
7527 * in 1.x pixel shaders. */
7528 static const DWORD shader_code_11[] =
7530 0xffff0101, /* ps_1_1 */
7531 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
7532 0x00000040, 0xb00f0000, /* texcoord t0 */
7533 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, ???(t0) */
7534 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
7535 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
7536 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
7537 0x0000ffff /* end */
7539 static const DWORD shader_code_12[] =
7541 0xffff0102, /* ps_1_2 */
7542 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
7543 0x00000040, 0xb00f0000, /* texcoord t0 */
7544 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
7545 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
7546 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
7547 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
7548 0x0000ffff /* end */
7550 static const DWORD shader_code_13[] =
7552 0xffff0103, /* ps_1_3 */
7553 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
7554 0x00000040, 0xb00f0000, /* texcoord t0 */
7555 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
7556 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3, r1, r0, c0 */
7557 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
7558 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
7559 0x0000ffff /* end */
7561 static const DWORD shader_code_14[] =
7563 0xffff0104, /* ps_1_3 */
7564 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
7565 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
7566 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
7567 0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0, c1, c2 */
7568 0x0000ffff /* end */
7571 /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
7572 * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
7573 * set by the compiler, it was added manually after compilation. Note that the COISSUE
7574 * flag on a color(.xyz) operation is only allowed after an alpha operation. DirectX doesn't
7575 * have proper docs, but GL_ATI_fragment_shader explains the pairing of color and alpha ops
7576 * well enough.
7578 * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
7579 * The input from t0 is [0;1]. 0.5 is subtracted, then we have to multiply with 2. Since
7580 * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
7581 * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
7583 static const DWORD shader_code_11_coissue[] =
7585 0xffff0101, /* ps_1_1 */
7586 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
7587 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
7588 0x00000040, 0xb00f0000, /* texcoord t0 */
7589 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
7590 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
7591 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
7592 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
7593 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
7594 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
7595 0x0000ffff /* end */
7597 static const DWORD shader_code_11_coissue_2[] =
7599 0xffff0101, /* ps_1_1 */
7600 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
7601 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
7602 0x00000040, 0xb00f0000, /* texcoord t0 */
7603 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
7604 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
7605 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
7606 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
7607 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
7608 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
7609 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
7610 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
7611 0x0000ffff /* end */
7613 static const DWORD shader_code_12_coissue[] =
7615 0xffff0102, /* ps_1_2 */
7616 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
7617 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
7618 0x00000040, 0xb00f0000, /* texcoord t0 */
7619 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
7620 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
7621 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
7622 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
7623 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
7624 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
7625 0x0000ffff /* end */
7627 static const DWORD shader_code_12_coissue_2[] =
7629 0xffff0102, /* ps_1_2 */
7630 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
7631 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
7632 0x00000040, 0xb00f0000, /* texcoord t0 */
7633 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
7634 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
7635 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
7636 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
7637 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
7638 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
7639 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
7640 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
7641 0x0000ffff /* end */
7643 static const DWORD shader_code_13_coissue[] =
7645 0xffff0103, /* ps_1_3 */
7646 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
7647 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
7648 0x00000040, 0xb00f0000, /* texcoord t0 */
7649 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
7650 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
7651 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
7652 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
7653 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
7654 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
7655 0x0000ffff /* end */
7657 static const DWORD shader_code_13_coissue_2[] =
7659 0xffff0103, /* ps_1_3 */
7660 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
7661 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
7662 0x00000040, 0xb00f0000, /* texcoord t0 */
7663 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
7664 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
7665 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
7666 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
7667 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
7668 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
7669 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
7670 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
7671 0x0000ffff /* end */
7673 /* ps_1_4 does not have a different cnd behavior, just pass the [0;1]
7674 * texcrd result to cnd, it will compare against 0.5. */
7675 static const DWORD shader_code_14_coissue[] =
7677 0xffff0104, /* ps_1_4 */
7678 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
7679 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0.xyz, t0 */
7680 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
7681 0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0, c1, c2 */
7682 0x0000ffff /* end */
7684 static const DWORD shader_code_14_coissue_2[] =
7686 0xffff0104, /* ps_1_4 */
7687 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
7688 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0.xyz, t0 */
7689 0x00000001, 0x80080000, 0x80000000, /* mov r0.a, r0.x */
7690 0x00000001, 0x80070001, 0xa0ff0000, /* mov r1.xyz, c0.a */
7691 0x40000050, 0x80080001, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r1.a, r0.a, c1, c2 */
7692 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
7693 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
7694 0x0000ffff /* end */
7696 static const float quad1[] =
7698 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 1.0f,
7699 -1.0f, 0.0f, 0.1f, 0.0f, 1.0f, 0.0f,
7700 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f,
7701 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f,
7703 static const float quad2[] =
7705 0.0f, -1.0f, 0.1f, 0.0f, 0.0f, 1.0f,
7706 0.0f, 0.0f, 0.1f, 0.0f, 1.0f, 0.0f,
7707 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f,
7708 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f,
7710 static const float quad3[] =
7712 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, 1.0f,
7713 0.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f,
7714 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f,
7715 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f,
7717 static const float quad4[] =
7719 -1.0f, 0.0f, 0.1f, 0.0f, 0.0f, 1.0f,
7720 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f,
7721 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f,
7722 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f,
7724 static const float test_data_c1[4] = {0.0f, 0.0f, 0.0f, 0.0f};
7725 static const float test_data_c2[4] = {1.0f, 1.0f, 1.0f, 1.0f};
7726 static const float test_data_c1_coi[4] = {0.0f, 1.0f, 0.0f, 0.0f};
7727 static const float test_data_c2_coi[4] = {1.0f, 0.0f, 1.0f, 1.0f};
7729 window = create_window();
7730 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7731 ok(!!d3d, "Failed to create a D3D object.\n");
7732 if (!(device = create_device(d3d, window, window, TRUE)))
7734 skip("Failed to create a D3D device, skipping tests.\n");
7735 goto done;
7738 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7739 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
7740 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 4))
7742 skip("No ps_1_4 support, skipping tests.\n");
7743 IDirect3DDevice9_Release(device);
7744 goto done;
7747 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
7748 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7750 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
7751 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7752 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
7753 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7754 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
7755 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7756 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
7757 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7758 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
7759 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7760 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
7761 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7762 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
7763 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7764 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
7765 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7766 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue_2, &shader_11_coissue_2);
7767 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7768 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue_2, &shader_12_coissue_2);
7769 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7770 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue_2, &shader_13_coissue_2);
7771 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7772 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue_2, &shader_14_coissue_2);
7773 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7775 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
7776 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7777 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
7778 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7779 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7780 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7782 hr = IDirect3DDevice9_BeginScene(device);
7783 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
7785 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
7786 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
7787 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
7788 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
7790 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
7791 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
7792 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
7793 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
7795 hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
7796 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
7797 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
7798 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7800 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
7801 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
7802 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
7803 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
7805 hr = IDirect3DDevice9_EndScene(device);
7806 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
7808 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7809 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7811 /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
7812 color = getPixelColor(device, 158, 118);
7813 ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
7814 color = getPixelColor(device, 162, 118);
7815 ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
7816 color = getPixelColor(device, 158, 122);
7817 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
7818 color = getPixelColor(device, 162, 122);
7819 ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
7821 /* 1.1 shader. All 3 components get set, based on the .w comparison */
7822 color = getPixelColor(device, 158, 358);
7823 ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
7824 color = getPixelColor(device, 162, 358);
7825 ok(color_match(color, 0x00000000, 1), "pixel 162, 358 has color 0x%08x, expected 0x00000000.\n", color);
7826 color = getPixelColor(device, 158, 362);
7827 ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
7828 color = getPixelColor(device, 162, 362);
7829 ok(color_match(color, 0x00000000, 1), "pixel 162, 362 has color 0x%08x, expected 0x00000000.\n", color);
7831 /* 1.2 shader */
7832 color = getPixelColor(device, 478, 358);
7833 ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
7834 color = getPixelColor(device, 482, 358);
7835 ok(color_match(color, 0x00000000, 1), "pixel 482, 358 has color 0x%08x, expected 0x00000000.\n", color);
7836 color = getPixelColor(device, 478, 362);
7837 ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
7838 color = getPixelColor(device, 482, 362);
7839 ok(color_match(color, 0x00000000, 1), "pixel 482, 362 has color 0x%08x, expected 0x00000000.\n", color);
7841 /* 1.3 shader */
7842 color = getPixelColor(device, 478, 118);
7843 ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
7844 color = getPixelColor(device, 482, 118);
7845 ok(color_match(color, 0x00000000, 1), "pixel 482, 118 has color 0x%08x, expected 0x00000000.\n", color);
7846 color = getPixelColor(device, 478, 122);
7847 ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
7848 color = getPixelColor(device, 482, 122);
7849 ok(color_match(color, 0x00000000, 1), "pixel 482, 122 has color 0x%08x, expected 0x00000000.\n", color);
7851 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7852 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7854 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
7855 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7856 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
7857 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7858 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
7859 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7861 hr = IDirect3DDevice9_BeginScene(device);
7862 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
7864 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
7865 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
7866 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
7867 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
7869 hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
7870 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
7871 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
7872 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
7874 hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
7875 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
7876 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
7877 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
7879 hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
7880 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
7881 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
7882 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
7884 hr = IDirect3DDevice9_EndScene(device);
7885 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
7887 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7888 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7890 /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
7891 * that we swapped the values in c1 and c2 to make the other tests return some color
7893 color = getPixelColor(device, 158, 118);
7894 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
7895 color = getPixelColor(device, 162, 118);
7896 ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
7897 color = getPixelColor(device, 158, 122);
7898 ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
7899 color = getPixelColor(device, 162, 122);
7900 ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
7902 /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected
7903 * (The Win7 nvidia driver always selects c2)
7905 color = getPixelColor(device, 158, 358);
7906 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
7907 "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
7908 color = getPixelColor(device, 162, 358);
7909 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
7910 "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
7911 color = getPixelColor(device, 158, 362);
7912 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
7913 "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
7914 color = getPixelColor(device, 162, 362);
7915 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
7916 "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
7918 /* 1.2 shader */
7919 color = getPixelColor(device, 478, 358);
7920 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
7921 "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
7922 color = getPixelColor(device, 482, 358);
7923 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
7924 "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
7925 color = getPixelColor(device, 478, 362);
7926 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
7927 "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
7928 color = getPixelColor(device, 482, 362);
7929 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
7930 "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
7932 /* 1.3 shader */
7933 color = getPixelColor(device, 478, 118);
7934 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
7935 "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
7936 color = getPixelColor(device, 482, 118);
7937 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
7938 "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
7939 color = getPixelColor(device, 478, 122);
7940 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
7941 "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
7942 color = getPixelColor(device, 482, 122);
7943 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
7944 "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
7946 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7947 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7949 /* Retest with the coissue flag on the alpha instruction instead. This
7950 * works "as expected". The Windows 8 testbot (WARP) seems to handle this
7951 * the same as coissue on .rgb. */
7952 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
7953 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7955 hr = IDirect3DDevice9_BeginScene(device);
7956 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
7958 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue_2);
7959 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
7960 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
7961 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
7963 hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue_2);
7964 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
7965 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
7966 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
7968 hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue_2);
7969 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
7970 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
7971 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
7973 hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue_2);
7974 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
7975 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
7976 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
7978 hr = IDirect3DDevice9_EndScene(device);
7979 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
7981 /* 1.4 shader */
7982 color = getPixelColor(device, 158, 118);
7983 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
7984 color = getPixelColor(device, 162, 118);
7985 ok(color == 0x00000000, "pixel 162, 118 has color %08x, expected 0x00000000\n", color);
7986 color = getPixelColor(device, 158, 122);
7987 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
7988 color = getPixelColor(device, 162, 122);
7989 ok(color == 0x00000000, "pixel 162, 122 has color %08x, expected 0x00000000\n", color);
7991 /* 1.1 shader */
7992 color = getPixelColor(device, 238, 358);
7993 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
7994 "pixel 238, 358 has color %08x, expected 0x00ffffff\n", color);
7995 color = getPixelColor(device, 242, 358);
7996 ok(color_match(color, 0x00000000, 1),
7997 "pixel 242, 358 has color %08x, expected 0x00000000\n", color);
7998 color = getPixelColor(device, 238, 362);
7999 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
8000 "pixel 238, 362 has color %08x, expected 0x00ffffff\n", color);
8001 color = getPixelColor(device, 242, 362);
8002 ok(color_match(color, 0x00000000, 1),
8003 "pixel 242, 362 has color %08x, expected 0x00000000\n", color);
8005 /* 1.2 shader */
8006 color = getPixelColor(device, 558, 358);
8007 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
8008 "pixel 558, 358 has color %08x, expected 0x00ffffff\n", color);
8009 color = getPixelColor(device, 562, 358);
8010 ok(color_match(color, 0x00000000, 1),
8011 "pixel 562, 358 has color %08x, expected 0x00000000\n", color);
8012 color = getPixelColor(device, 558, 362);
8013 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
8014 "pixel 558, 362 has color %08x, expected 0x00ffffff\n", color);
8015 color = getPixelColor(device, 562, 362);
8016 ok(color_match(color, 0x00000000, 1),
8017 "pixel 562, 362 has color %08x, expected 0x00000000\n", color);
8019 /* 1.3 shader */
8020 color = getPixelColor(device, 558, 118);
8021 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
8022 "pixel 558, 118 has color %08x, expected 0x00ffffff\n", color);
8023 color = getPixelColor(device, 562, 118);
8024 ok(color_match(color, 0x00000000, 1),
8025 "pixel 562, 118 has color %08x, expected 0x00000000\n", color);
8026 color = getPixelColor(device, 558, 122);
8027 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
8028 "pixel 558, 122 has color %08x, expected 0x00ffffff\n", color);
8029 color = getPixelColor(device, 562, 122);
8030 ok(color_match(color, 0x00000000, 1),
8031 "pixel 562, 122 has color %08x, expected 0x00000000\n", color);
8033 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8034 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8036 IDirect3DPixelShader9_Release(shader_14_coissue_2);
8037 IDirect3DPixelShader9_Release(shader_13_coissue_2);
8038 IDirect3DPixelShader9_Release(shader_12_coissue_2);
8039 IDirect3DPixelShader9_Release(shader_11_coissue_2);
8040 IDirect3DPixelShader9_Release(shader_14_coissue);
8041 IDirect3DPixelShader9_Release(shader_13_coissue);
8042 IDirect3DPixelShader9_Release(shader_12_coissue);
8043 IDirect3DPixelShader9_Release(shader_11_coissue);
8044 IDirect3DPixelShader9_Release(shader_14);
8045 IDirect3DPixelShader9_Release(shader_13);
8046 IDirect3DPixelShader9_Release(shader_12);
8047 IDirect3DPixelShader9_Release(shader_11);
8048 refcount = IDirect3DDevice9_Release(device);
8049 ok(!refcount, "Device has %lu references left.\n", refcount);
8050 done:
8051 IDirect3D9_Release(d3d);
8052 DestroyWindow(window);
8055 static void nested_loop_test(void)
8057 IDirect3DVertexShader9 *vshader;
8058 IDirect3DPixelShader9 *shader;
8059 IDirect3DDevice9 *device;
8060 unsigned int color;
8061 IDirect3D9 *d3d;
8062 ULONG refcount;
8063 D3DCAPS9 caps;
8064 HWND window;
8065 HRESULT hr;
8067 static const DWORD shader_code[] =
8069 0xffff0300, /* ps_3_0 */
8070 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
8071 0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
8072 0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0 */
8073 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
8074 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
8075 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
8076 0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001, /* add r0, r0, c1 */
8077 0x0000001d, /* endloop */
8078 0x0000001d, /* endloop */
8079 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
8080 0x0000ffff /* end */
8082 static const DWORD vshader_code[] =
8084 0xfffe0300, /* vs_3_0 */
8085 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8086 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
8087 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
8088 0x0000ffff /* end */
8090 static const float quad[] =
8092 -1.0f, -1.0f, 0.1f,
8093 -1.0f, 1.0f, 0.1f,
8094 1.0f, -1.0f, 0.1f,
8095 1.0f, 1.0f, 0.1f,
8098 window = create_window();
8099 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8100 ok(!!d3d, "Failed to create a D3D object.\n");
8101 if (!(device = create_device(d3d, window, window, TRUE)))
8103 skip("Failed to create a D3D device, skipping tests.\n");
8104 goto done;
8107 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8108 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
8109 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
8111 skip("No shader model 3 support, skipping tests.\n");
8112 IDirect3DDevice9_Release(device);
8113 goto done;
8116 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8117 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8118 hr = IDirect3DDevice9_SetPixelShader(device, shader);
8119 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8120 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
8121 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8122 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
8123 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8124 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8125 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8126 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x0000ff00, 1.0f, 0);
8127 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8129 hr = IDirect3DDevice9_BeginScene(device);
8130 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
8131 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
8132 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
8133 hr = IDirect3DDevice9_EndScene(device);
8134 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
8136 color = getPixelColor(device, 360, 240);
8137 ok(color_match(color, 0x00800000, 1),
8138 "Nested loop test returned color 0x%08x, expected 0x00800000.\n", color);
8140 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8141 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8143 IDirect3DPixelShader9_Release(shader);
8144 IDirect3DVertexShader9_Release(vshader);
8145 refcount = IDirect3DDevice9_Release(device);
8146 ok(!refcount, "Device has %lu references left.\n", refcount);
8147 done:
8148 IDirect3D9_Release(d3d);
8149 DestroyWindow(window);
8152 static void pretransformed_varying_test(void)
8154 /* dcl_position: fails to compile */
8155 static const DWORD blendweight_code[] =
8157 0xffff0300, /* ps_3_0 */
8158 0x0200001f, 0x80000001, 0x900f0000, /* dcl_blendweight, v0 */
8159 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
8160 0x0000ffff /* end */
8162 static const DWORD blendindices_code[] =
8164 0xffff0300, /* ps_3_0 */
8165 0x0200001f, 0x80000002, 0x900f0000, /* dcl_blendindices, v0 */
8166 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
8167 0x0000ffff /* end */
8169 static const DWORD normal_code[] =
8171 0xffff0300, /* ps_3_0 */
8172 0x0200001f, 0x80000003, 0x900f0000, /* dcl_normal, v0 */
8173 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
8174 0x0000ffff /* end */
8176 /* psize: fails? */
8177 static const DWORD texcoord0_code[] =
8179 0xffff0300, /* ps_3_0 */
8180 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0, v0 */
8181 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
8182 0x0000ffff /* end */
8184 static const DWORD tangent_code[] =
8186 0xffff0300, /* ps_3_0 */
8187 0x0200001f, 0x80000006, 0x900f0000, /* dcl_tangent, v0 */
8188 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
8189 0x0000ffff /* end */
8191 static const DWORD binormal_code[] =
8193 0xffff0300, /* ps_3_0 */
8194 0x0200001f, 0x80000007, 0x900f0000, /* dcl_binormal, v0 */
8195 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
8196 0x0000ffff /* end */
8198 /* tessfactor: fails */
8199 /* positiont: fails */
8200 static const DWORD color_code[] =
8202 0xffff0300, /* ps_3_0 */
8203 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0, v0 */
8204 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
8205 0x0000ffff /* end */
8207 static const DWORD fog_code[] =
8209 0xffff0300, /* ps_3_0 */
8210 0x0200001f, 0x8000000b, 0x900f0000, /* dcl_fog, v0 */
8211 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
8212 0x0000ffff /* end */
8214 static const DWORD depth_code[] =
8216 0xffff0300, /* ps_3_0 */
8217 0x0200001f, 0x8000000c, 0x900f0000, /* dcl_depth, v0 */
8218 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
8219 0x0000ffff /* end */
8221 static const DWORD specular_code[] =
8223 0xffff0300, /* ps_3_0 */
8224 0x0200001f, 0x8001000a, 0x900f0000, /* dcl_color1, v0 */
8225 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
8226 0x0000ffff /* end */
8228 /* sample: fails */
8229 static const DWORD texcoord1_code[] =
8231 0xffff0300, /* ps_3_0 */
8232 0x0200001f, 0x80010005, 0x900f0000, /* dcl_texcoord1, v0 */
8233 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
8234 0x0000ffff /* end */
8236 static const DWORD texcoord1_alpha_code[] =
8238 0xffff0300, /* ps_3_0 */
8239 0x0200001f, 0x80010005, 0x900f0000, /* dcl_texcoord1, v0 */
8240 0x02000001, 0x800f0800, 0x90ff0000, /* mov oC0, v0.w */
8241 0x0000ffff /* end */
8244 static const struct
8246 const char *name;
8247 const DWORD *shader_code;
8248 unsigned int color;
8249 BOOL todo;
8250 BOOL broken;
8251 DWORD broken_color;
8253 tests[] =
8255 {"blendweight", blendweight_code, 0x00191919, TRUE },
8256 {"blendindices", blendindices_code, 0x00333333, TRUE },
8257 {"normal", normal_code, 0x004c4c4c, TRUE },
8258 {"texcoord0", texcoord0_code, 0x00808c8c, FALSE},
8259 {"tangent", tangent_code, 0x00999999, TRUE },
8260 {"binormal", binormal_code, 0x00b2b2b2, TRUE },
8261 {"color", color_code, 0x00e6e6e6, FALSE},
8262 {"fog", fog_code, 0x00666666, TRUE },
8263 {"depth", depth_code, 0x00cccccc, TRUE },
8264 {"specular", specular_code, 0x004488ff, FALSE},
8265 {"texcoord1", texcoord1_code, 0x00000000, FALSE},
8266 /* texcoord .w is 1.0 on r500 and WARP. See also test_uninitialized_varyings(). */
8267 {"texcoord1 alpha", texcoord1_alpha_code, 0x00000000, FALSE, TRUE, 0x00ffffff},
8269 /* Declare a monster vertex type :-) */
8270 static const D3DVERTEXELEMENT9 decl_elements[] = {
8271 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
8272 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
8273 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
8274 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
8275 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
8276 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
8277 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
8278 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
8279 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
8280 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8281 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
8282 D3DDECL_END()
8285 static const struct
8287 float pos_x, pos_y, pos_z, rhw;
8288 float weight_1, weight_2, weight_3, weight_4;
8289 float index_1, index_2, index_3, index_4;
8290 float normal_1, normal_2, normal_3, normal_4;
8291 float fog_1, fog_2, fog_3, fog_4;
8292 float texcoord_1, texcoord_2, texcoord_3, texcoord_4;
8293 float tangent_1, tangent_2, tangent_3, tangent_4;
8294 float binormal_1, binormal_2, binormal_3, binormal_4;
8295 float depth_1, depth_2, depth_3, depth_4;
8296 D3DCOLOR diffuse;
8297 D3DCOLOR specular;
8299 data[] =
8302 0.0f, 0.0f, 0.1f, 1.0f,
8303 0.1f, 0.1f, 0.1f, 0.1f,
8304 0.2f, 0.2f, 0.2f, 0.2f,
8305 0.3f, 0.3f, 0.3f, 0.3f,
8306 0.4f, 0.4f, 0.4f, 0.4f,
8307 0.5f, 0.55f, 0.55f, 0.55f,
8308 0.6f, 0.6f, 0.6f, 0.7f,
8309 0.7f, 0.7f, 0.7f, 0.6f,
8310 0.8f, 0.8f, 0.8f, 0.8f,
8311 0xe6e6e6e6, /* 0.9 * 256 */
8312 0x224488ff, /* Nothing special */
8315 640.0f, 0.0f, 0.1f, 1.0f,
8316 0.1f, 0.1f, 0.1f, 0.1f,
8317 0.2f, 0.2f, 0.2f, 0.2f,
8318 0.3f, 0.3f, 0.3f, 0.3f,
8319 0.4f, 0.4f, 0.4f, 0.4f,
8320 0.5f, 0.55f, 0.55f, 0.55f,
8321 0.6f, 0.6f, 0.6f, 0.7f,
8322 0.7f, 0.7f, 0.7f, 0.6f,
8323 0.8f, 0.8f, 0.8f, 0.8f,
8324 0xe6e6e6e6, /* 0.9 * 256 */
8325 0x224488ff, /* Nothing special */
8328 0.0f, 480.0f, 0.1f, 1.0f,
8329 0.1f, 0.1f, 0.1f, 0.1f,
8330 0.2f, 0.2f, 0.2f, 0.2f,
8331 0.3f, 0.3f, 0.3f, 0.3f,
8332 0.4f, 0.4f, 0.4f, 0.4f,
8333 0.5f, 0.55f, 0.55f, 0.55f,
8334 0.6f, 0.6f, 0.6f, 0.7f,
8335 0.7f, 0.7f, 0.7f, 0.6f,
8336 0.8f, 0.8f, 0.8f, 0.8f,
8337 0xe6e6e6e6, /* 0.9 * 256 */
8338 0x224488ff, /* Nothing special */
8341 640.0f, 480.0f, 0.1f, 1.0f,
8342 0.1f, 0.1f, 0.1f, 0.1f,
8343 0.2f, 0.2f, 0.2f, 0.2f,
8344 0.3f, 0.3f, 0.3f, 0.3f,
8345 0.4f, 0.4f, 0.4f, 0.4f,
8346 0.5f, 0.55f, 0.55f, 0.55f,
8347 0.6f, 0.6f, 0.6f, 0.7f,
8348 0.7f, 0.7f, 0.7f, 0.6f,
8349 0.8f, 0.8f, 0.8f, 0.8f,
8350 0xe6e6e6e6, /* 0.9 * 256 */
8351 0x224488ff, /* Nothing special */
8354 IDirect3DVertexDeclaration9 *decl;
8355 D3DADAPTER_IDENTIFIER9 identifier;
8356 IDirect3DDevice9 *device;
8357 unsigned int color, i;
8358 IDirect3D9 *d3d;
8359 ULONG refcount;
8360 D3DCAPS9 caps;
8361 HWND window;
8362 HRESULT hr;
8364 window = create_window();
8365 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8366 ok(!!d3d, "Failed to create a D3D object.\n");
8367 if (!(device = create_device(d3d, window, window, TRUE)))
8369 skip("Failed to create a D3D device, skipping tests.\n");
8370 goto done;
8373 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8374 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
8375 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
8377 skip("No shader model 3 support, skipping tests.\n");
8378 IDirect3DDevice9_Release(device);
8379 goto done;
8382 hr = IDirect3D9_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
8383 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#lx.\n", hr);
8384 if (adapter_is_warp(&identifier) && sizeof(UINT) == sizeof(UINT_PTR))
8386 /* Apparently the "monster" vertex declaration used in this test
8387 * overruns some stack buffer (DrawPrimitiveUP crashes with a
8388 * 0xc0000409 exception) on 32-bit WARP since Win 10 1809. */
8389 skip("Test crashes on recent 32-bit WARP.\n");
8390 IDirect3DDevice9_Release(device);
8391 goto done;
8394 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
8395 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8396 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
8397 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8399 for (i = 0; i < ARRAY_SIZE(tests); ++i)
8401 IDirect3DPixelShader9 *shader;
8403 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
8404 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8406 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &shader);
8407 ok(SUCCEEDED(hr), "Failed to create pixel shader for test %s, hr %#lx.\n", tests[i].name, hr);
8409 hr = IDirect3DDevice9_SetPixelShader(device, shader);
8410 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8412 hr = IDirect3DDevice9_BeginScene(device);
8413 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
8414 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(*data));
8415 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
8416 hr = IDirect3DDevice9_EndScene(device);
8417 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
8419 /* This isn't a weekend's job to fix, ignore the problem for now.
8420 * Needs a replacement pipeline. */
8421 color = getPixelColor(device, 360, 240);
8422 if (tests[i].todo)
8423 todo_wine ok(color_match(color, tests[i].color, 1)
8424 || broken(color_match(color, 0x00000000, 1)
8425 && tests[i].shader_code == blendindices_code),
8426 "Test %s returned color 0x%08x, expected 0x%08x (todo).\n",
8427 tests[i].name, color, tests[i].color);
8428 else
8429 ok(color_match(color, tests[i].color, 1)
8430 || broken(color_match(color, tests[i].broken_color, 1) && tests[i].broken),
8431 "Test %s returned color 0x%08x, expected 0x%08x.\n",
8432 tests[i].name, color, tests[i].color);
8434 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8435 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8437 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8438 ok(SUCCEEDED(hr), "Failed to set pixel shader for test %s, hr %#lx.\n", tests[i].name, hr);
8439 IDirect3DPixelShader9_Release(shader);
8442 IDirect3DVertexDeclaration9_Release(decl);
8443 refcount = IDirect3DDevice9_Release(device);
8444 ok(!refcount, "Device has %lu references left.\n", refcount);
8445 done:
8446 IDirect3D9_Release(d3d);
8447 DestroyWindow(window);
8450 static void test_compare_instructions(void)
8452 IDirect3DVertexShader9 *shader_slt_scalar;
8453 IDirect3DVertexShader9 *shader_sge_scalar;
8454 IDirect3DVertexShader9 *shader_slt_vec;
8455 IDirect3DVertexShader9 *shader_sge_vec;
8456 IDirect3DDevice9 *device;
8457 unsigned int color;
8458 IDirect3D9 *d3d;
8459 ULONG refcount;
8460 D3DCAPS9 caps;
8461 HWND window;
8462 HRESULT hr;
8464 static const DWORD shader_sge_vec_code[] =
8466 0xfffe0101, /* vs_1_1 */
8467 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8468 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8469 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
8470 0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001, /* sge oD0, r0, c1 */
8471 0x0000ffff /* end */
8473 static const DWORD shader_slt_vec_code[] =
8475 0xfffe0101, /* vs_1_1 */
8476 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8477 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8478 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
8479 0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001, /* slt oD0, r0, c1 */
8480 0x0000ffff /* end */
8482 static const DWORD shader_sge_scalar_code[] =
8484 0xfffe0101, /* vs_1_1 */
8485 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8486 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8487 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
8488 0x0000000d, 0xd0010000, 0x80000000, 0xa0550001, /* slt oD0.r, r0.r, c1.b */
8489 0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001, /* slt oD0.g, r0.g, c1.r */
8490 0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001, /* slt oD0.b, r0.b, c1.g */
8491 0x0000ffff /* end */
8493 static const DWORD shader_slt_scalar_code[] =
8495 0xfffe0101, /* vs_1_1 */
8496 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8497 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8498 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
8499 0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001, /* slt oD0.r, r0.r, c1.b */
8500 0x0000000c, 0xd0020000, 0x80550000, 0xa0000001, /* slt oD0.g, r0.g, c1.r */
8501 0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001, /* slt oD0.b, r0.b, c1.g */
8502 0x0000ffff /* end */
8504 static const float quad1[] =
8506 -1.0f, -1.0f, 0.1f,
8507 -1.0f, 0.0f, 0.1f,
8508 0.0f, -1.0f, 0.1f,
8509 0.0f, 0.0f, 0.1f,
8511 static const float quad2[] =
8513 0.0f, -1.0f, 0.1f,
8514 0.0f, 0.0f, 0.1f,
8515 1.0f, -1.0f, 0.1f,
8516 1.0f, 0.0f, 0.1f,
8518 static const float quad3[] =
8520 -1.0f, 0.0f, 0.1f,
8521 -1.0f, 1.0f, 0.1f,
8522 0.0f, 0.0f, 0.1f,
8523 0.0f, 1.0f, 0.1f,
8525 static const float quad4[] =
8527 0.0f, 0.0f, 0.1f,
8528 0.0f, 1.0f, 0.1f,
8529 1.0f, 0.0f, 0.1f,
8530 1.0f, 1.0f, 0.1f,
8532 static const float const0[4] = {0.8f, 0.2f, 0.2f, 0.2f};
8533 static const float const1[4] = {0.2f, 0.8f, 0.2f, 0.2f};
8535 window = create_window();
8536 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8537 ok(!!d3d, "Failed to create a D3D object.\n");
8538 if (!(device = create_device(d3d, window, window, TRUE)))
8540 skip("Failed to create a D3D device, skipping tests.\n");
8541 goto done;
8544 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8545 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
8546 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
8548 skip("No vs_1_1 support, skipping tests.\n");
8549 IDirect3DDevice9_Release(device);
8550 goto done;
8553 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
8554 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8556 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
8557 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8558 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
8559 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8560 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
8561 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8562 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
8563 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8564 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
8565 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8566 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
8567 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8568 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8569 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8571 hr = IDirect3DDevice9_BeginScene(device);
8572 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
8574 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
8575 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
8576 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
8577 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
8579 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
8580 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
8581 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
8582 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
8584 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
8585 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
8586 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
8587 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
8589 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
8590 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#lx.\n", hr);
8592 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
8593 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
8594 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
8595 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
8597 hr = IDirect3DDevice9_EndScene(device);
8598 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
8600 color = getPixelColor(device, 160, 360);
8601 ok(color == 0x00ff00ff, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00ff00ff\n", color);
8602 color = getPixelColor(device, 480, 360);
8603 ok(color == 0x0000ff00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000ff00\n", color);
8604 color = getPixelColor(device, 160, 120);
8605 ok(color == 0x00ffffff, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00ffffff\n", color);
8606 color = getPixelColor(device, 480, 160);
8607 ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
8609 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8610 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8612 IDirect3DVertexShader9_Release(shader_sge_vec);
8613 IDirect3DVertexShader9_Release(shader_slt_vec);
8614 IDirect3DVertexShader9_Release(shader_sge_scalar);
8615 IDirect3DVertexShader9_Release(shader_slt_scalar);
8616 refcount = IDirect3DDevice9_Release(device);
8617 ok(!refcount, "Device has %lu references left.\n", refcount);
8618 done:
8619 IDirect3D9_Release(d3d);
8620 DestroyWindow(window);
8623 static void test_vshader_input(void)
8625 IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
8626 IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
8627 IDirect3DVertexDeclaration9 *decl_nocolor;
8628 IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
8629 D3DADAPTER_IDENTIFIER9 identifier;
8630 IDirect3DPixelShader9 *ps;
8631 IDirect3DDevice9 *device;
8632 unsigned int color, i;
8633 IDirect3D9 *d3d;
8634 ULONG refcount;
8635 D3DCAPS9 caps;
8636 HWND window;
8637 HRESULT hr;
8638 BOOL warp;
8640 static const DWORD swapped_shader_code_3[] =
8642 0xfffe0300, /* vs_3_0 */
8643 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
8644 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
8645 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8646 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
8647 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
8648 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
8649 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
8650 0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
8651 0x0000ffff /* end */
8653 static const DWORD swapped_shader_code_1[] =
8655 0xfffe0101, /* vs_1_1 */
8656 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8657 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
8658 0x0000001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
8659 0x00000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
8660 0x00000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
8661 0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
8662 0x0000ffff /* end */
8664 static const DWORD swapped_shader_code_2[] =
8666 0xfffe0200, /* vs_2_0 */
8667 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8668 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
8669 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
8670 0x02000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
8671 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
8672 0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
8673 0x0000ffff /* end */
8675 static const DWORD texcoord_color_shader_code_3[] =
8677 0xfffe0300, /* vs_3_0 */
8678 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
8679 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
8680 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8681 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
8682 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
8683 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
8684 0x0000ffff /* end */
8686 static const DWORD texcoord_color_shader_code_2[] =
8688 0xfffe0200, /* vs_2_0 */
8689 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8690 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
8691 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8692 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
8693 0x0000ffff /* end */
8695 static const DWORD texcoord_color_shader_code_1[] =
8697 0xfffe0101, /* vs_1_1 */
8698 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8699 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
8700 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8701 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
8702 0x0000ffff /* end */
8704 static const DWORD color_color_shader_code_3[] =
8706 0xfffe0300, /* vs_3_0 */
8707 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
8708 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
8709 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8710 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
8711 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
8712 0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001, /* mul o1, c0, v1 */
8713 0x0000ffff /* end */
8715 static const DWORD color_color_shader_code_2[] =
8717 0xfffe0200, /* vs_2_0 */
8718 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8719 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
8720 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8721 0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
8722 0x0000ffff /* end */
8724 static const DWORD color_color_shader_code_1[] =
8726 0xfffe0101, /* vs_1_1 */
8727 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8728 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
8729 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8730 0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
8731 0x0000ffff /* end */
8733 static const DWORD ps3_code[] =
8735 0xffff0300, /* ps_3_0 */
8736 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
8737 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
8738 0x0000ffff /* end */
8740 static const float quad1[] =
8742 -1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
8743 -1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
8744 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
8745 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
8747 static const float quad2[] =
8749 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
8750 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
8751 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
8752 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
8754 static const float quad3[] =
8756 -1.0f, 0.0f, 0.1f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f,
8757 -1.0f, 1.0f, 0.1f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f,
8758 0.0f, 0.0f, 0.1f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
8759 0.0f, 1.0f, 0.1f, -1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
8761 static const float quad4[] =
8763 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
8764 0.0f, 1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
8765 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
8766 1.0f, 1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
8768 static const float quad1_modified[] =
8770 -1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
8771 -1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f,
8772 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
8773 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, -1.0f, -1.0f, -1.0f, 0.0f,
8775 static const float quad2_modified[] =
8777 0.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
8778 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
8779 1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
8780 1.0f, 0.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
8782 static const struct
8784 struct vec3 position;
8785 DWORD diffuse;
8787 quad1_color[] =
8789 {{-1.0f, -1.0f, 0.1f}, 0x00ff8040},
8790 {{-1.0f, 0.0f, 0.1f}, 0x00ff8040},
8791 {{ 0.0f, -1.0f, 0.1f}, 0x00ff8040},
8792 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
8794 quad2_color[] =
8796 {{ 0.0f, -1.0f, 0.1f}, 0x00ff8040},
8797 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
8798 {{ 1.0f, -1.0f, 0.1f}, 0x00ff8040},
8799 {{ 1.0f, 0.0f, 0.1f}, 0x00ff8040},
8801 quad3_color[] =
8803 {{-1.0f, 0.0f, 0.1f}, 0x00ff8040},
8804 {{-1.0f, 1.0f, 0.1f}, 0x00ff8040},
8805 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
8806 {{ 0.0f, 1.0f, 0.1f}, 0x00ff8040},
8808 static const float quad4_color[] =
8810 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f, 0.0f,
8811 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f, 0.0f,
8812 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f, 1.0f,
8813 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f, 1.0f,
8815 static const struct vec3 quad_nocolor[] =
8817 {-1.0f, -1.0f, 0.1f},
8818 {-1.0f, 1.0f, 0.1f},
8819 { 1.0f, -1.0f, 0.1f},
8820 { 1.0f, 1.0f, 0.1f},
8822 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] =
8824 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8825 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
8826 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
8827 D3DDECL_END()
8829 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] =
8831 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8832 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
8833 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
8834 D3DDECL_END()
8836 static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] =
8838 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8839 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
8840 D3DDECL_END()
8842 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] =
8844 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8845 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
8846 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
8847 D3DDECL_END()
8849 static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] =
8851 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8852 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
8853 D3DDECL_END()
8855 static const D3DVERTEXELEMENT9 decl_elements_color_color[] =
8857 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8858 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8859 D3DDECL_END()
8861 static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] =
8863 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8864 {0, 12, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8865 D3DDECL_END()
8867 static const D3DVERTEXELEMENT9 decl_elements_color_float[] =
8869 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8870 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8871 D3DDECL_END()
8873 static const D3DVERTEXELEMENT9 decl_elements_nocolor[] =
8875 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8876 D3DDECL_END()
8878 static const float normalize[4] = {1.0f / 256.0f, 1.0f / 256.0f, 1.0f / 256.0f, 1.0f / 256.0f};
8879 static const float no_normalize[4] = {1.0f, 1.0f, 1.0f, 1.0f};
8881 window = create_window();
8882 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8883 ok(!!d3d, "Failed to create a D3D object.\n");
8884 if (!(device = create_device(d3d, window, window, TRUE)))
8886 skip("Failed to create a D3D device, skipping tests.\n");
8887 goto done;
8890 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8891 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
8892 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
8894 skip("No vs_3_0 support, skipping tests.\n");
8895 IDirect3DDevice9_Release(device);
8896 goto done;
8898 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0))
8900 skip("No ps_3_0 support, skipping tests.\n");
8901 IDirect3DDevice9_Release(device);
8902 goto done;
8905 hr = IDirect3D9_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
8906 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#lx.\n", hr);
8907 warp = adapter_is_warp(&identifier);
8909 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
8910 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8911 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
8912 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8913 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
8914 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8915 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
8916 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8918 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
8919 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8920 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
8921 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8922 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
8923 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8924 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
8925 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8926 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_nocolor, &decl_nocolor);
8927 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8929 hr = IDirect3DDevice9_CreatePixelShader(device, ps3_code, &ps);
8930 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8932 for (i = 1; i <= 3; ++i)
8934 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
8935 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8936 if(i == 3) {
8937 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
8938 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8939 hr = IDirect3DDevice9_SetPixelShader(device, ps);
8940 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8941 } else if(i == 2){
8942 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
8943 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8944 } else if(i == 1) {
8945 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
8946 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8949 hr = IDirect3DDevice9_BeginScene(device);
8950 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
8952 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
8953 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
8955 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
8956 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
8957 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
8958 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
8960 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
8961 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
8962 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
8963 if (i == 3 || i == 2)
8964 ok(SUCCEEDED(hr), "Failed to draw, i %u, hr %#lx.\n", i, hr);
8965 else if (i == 1)
8966 /* Succeeds or fails, depending on SW or HW vertex processing. */
8967 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
8969 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
8970 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
8971 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
8972 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
8974 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
8975 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
8976 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
8977 if (i == 3 || i == 2)
8978 ok(SUCCEEDED(hr), "Failed to draw, i %u, hr %#lx.\n", i, hr);
8979 else if (i == 1)
8980 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
8982 hr = IDirect3DDevice9_EndScene(device);
8983 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
8985 if(i == 3 || i == 2) {
8986 color = getPixelColor(device, 160, 360);
8987 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
8988 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00ffff80\n", color);
8990 /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
8991 color = getPixelColor(device, 480, 360);
8992 /* On the Windows 8 testbot (WARP) the draw succeeds, but uses
8993 * mostly random data as input. */
8994 ok(color == 0x00ffff00 || color == 0x00ff0000 || broken(warp),
8995 "Got unexpected color 0x%08x for quad 2 (1crd).\n", color);
8996 color = getPixelColor(device, 160, 120);
8997 /* Same as above, accept both the last used value and 0.0 for the undefined streams */
8998 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
8999 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00ff0080\n", color);
9001 color = getPixelColor(device, 480, 160);
9002 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
9003 } else if(i == 1) {
9004 color = getPixelColor(device, 160, 360);
9005 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
9006 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00ffff80\n", color);
9007 color = getPixelColor(device, 480, 360);
9008 /* Accept the clear color as well in this case, since SW VP
9009 * returns an error. On the Windows 8 testbot (WARP) the draw
9010 * succeeds, but uses mostly random data as input. */
9011 ok(color == 0x00ffff00 || color == 0x00ff0000 || broken(warp),
9012 "Got unexpected color 0x%08x for quad 2 (1crd).\n", color);
9013 color = getPixelColor(device, 160, 120);
9014 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
9015 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00ff0080\n", color);
9016 color = getPixelColor(device, 480, 160);
9017 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
9020 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9021 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9023 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
9024 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9026 /* Now find out if the whole streams are re-read, or just the last
9027 * active value for the vertices is used. */
9028 hr = IDirect3DDevice9_BeginScene(device);
9029 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
9031 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
9032 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
9034 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
9035 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
9036 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
9037 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
9039 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
9040 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
9041 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
9042 if (i == 3 || i == 2)
9043 ok(SUCCEEDED(hr), "Failed to draw, i %u, hr %#lx.\n", i, hr);
9044 else if (i == 1)
9045 /* Succeeds or fails, depending on SW or HW vertex processing. */
9046 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9048 hr = IDirect3DDevice9_EndScene(device);
9049 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
9051 color = getPixelColor(device, 480, 350);
9052 /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
9053 * as well.
9055 * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
9056 * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
9057 * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
9058 * refrast's result.
9060 * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
9062 ok(color == 0x000000ff || color == 0x00808080 || color == 0x00000000 || broken(warp),
9063 "Got unexpected color 0x%08x for quad 2 (different colors).\n", color);
9065 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9066 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9068 IDirect3DDevice9_SetVertexShader(device, NULL);
9069 IDirect3DDevice9_SetPixelShader(device, NULL);
9070 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
9072 IDirect3DVertexShader9_Release(swapped_shader);
9075 for (i = 1; i <= 3; ++i)
9077 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
9078 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9079 if(i == 3) {
9080 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
9081 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9082 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
9083 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9084 hr = IDirect3DDevice9_SetPixelShader(device, ps);
9085 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9086 } else if(i == 2){
9087 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
9088 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9089 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
9090 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9091 } else if(i == 1) {
9092 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
9093 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9094 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
9095 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9098 hr = IDirect3DDevice9_BeginScene(device);
9099 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
9101 hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
9102 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
9103 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
9104 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
9105 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
9106 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
9108 hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
9109 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
9111 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
9112 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#lx.\n", hr);
9113 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
9114 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
9115 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
9116 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
9118 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
9119 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#lx.\n", hr);
9120 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
9121 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
9122 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
9123 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
9125 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
9126 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
9127 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
9128 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
9130 hr = IDirect3DDevice9_EndScene(device);
9131 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
9133 color = getPixelColor(device, 160, 360);
9134 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
9135 "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
9136 color = getPixelColor(device, 480, 360);
9137 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
9138 "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
9139 color = getPixelColor(device, 160, 120);
9140 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
9141 "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
9142 color = getPixelColor(device, 480, 160);
9143 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
9144 "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00ffff00\n", color);
9146 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9147 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9149 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_nocolor);
9150 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
9152 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
9153 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
9155 hr = IDirect3DDevice9_BeginScene(device);
9156 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
9157 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_nocolor, sizeof(quad_nocolor[0]));
9158 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
9159 hr = IDirect3DDevice9_EndScene(device);
9160 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
9162 /* WARP and r500 return a color from a previous draw. In case of WARP it is random, although most of the
9163 * time it is the color of the last draw, which happens to be the one with quad4_color above. AMD's r500
9164 * uses the last D3DCOLOR attribute, which is the one from quad3_color.
9166 * Newer AMD cards and Nvidia return zero. */
9167 color = getPixelColor(device, 160, 360);
9168 ok(color_match(color, 0x00000000, 1) || broken(color_match(color, 0x00ff8040, 1)) || broken(warp),
9169 "Got unexpected color 0x%08x for no color attribute test.\n", color);
9171 IDirect3DDevice9_SetVertexShader(device, NULL);
9172 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
9173 IDirect3DDevice9_SetPixelShader(device, NULL);
9175 IDirect3DVertexShader9_Release(texcoord_color_shader);
9176 IDirect3DVertexShader9_Release(color_color_shader);
9179 IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
9180 IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
9181 IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
9182 IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
9184 IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
9185 IDirect3DVertexDeclaration9_Release(decl_color_color);
9186 IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
9187 IDirect3DVertexDeclaration9_Release(decl_color_float);
9188 IDirect3DVertexDeclaration9_Release(decl_nocolor);
9190 IDirect3DPixelShader9_Release(ps);
9191 refcount = IDirect3DDevice9_Release(device);
9192 ok(!refcount, "Device has %lu references left.\n", refcount);
9193 done:
9194 IDirect3D9_Release(d3d);
9195 DestroyWindow(window);
9198 static void srgbtexture_test(void)
9200 /* The result of sRGB to linear conversion for value 0x7f (~ .5) used on
9201 * texture mip level 0 should be 0x36 (~ 0.21), per this formula:
9202 * linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
9203 * This is true where srgb_color > 0.04045.
9204 * For the value of 0x3f used on mip level 1 the result should be 0x0d (~0.05). */
9205 struct IDirect3DTexture9 *texture;
9206 struct IDirect3DSurface9 *surface;
9207 IDirect3DDevice9 *device;
9208 unsigned int colour, i;
9209 IDirect3D9 *d3d;
9210 ULONG refcount;
9211 HWND window;
9212 DWORD value;
9213 HRESULT hr;
9215 static const float quad[] =
9217 -1.0f, -1.0f, 0.0f, 0.0f, 1.0f,
9218 -1.0f, 1.0f, 0.0f, 0.0f, 0.0f,
9219 1.0f, -1.0f, 0.0f, 1.0f, 1.0f,
9220 1.0f, 1.0f, 0.0f, 1.0f, 0.0f,
9222 static const struct
9224 D3DFORMAT format;
9225 const char *format_name;
9226 DWORD fill_colour1, fill_colour2;
9227 DWORD fill_colour_rb1, fill_colour_rb2;
9228 DWORD conv_colour1, conv_colour2;
9230 tests[] =
9232 {D3DFMT_A8R8G8B8, "A8R8G8B8",
9233 0xff7f7f7f, 0xff3f3f3f, 0x007f7f7f, 0x003f3f3f, 0x00363636, 0x000d0d0d},
9234 {D3DFMT_R5G6B5, "R5G6R5",
9235 0x7bef, 0x39e7, 0x007b7d7b, 0x003a3d3a, 0x00333433, 0x000a0c0a},
9236 {D3DFMT_A1R5G5B5, "A1R5G5R5",
9237 0xbdef, 0x9ce7, 0x007b7b7b, 0x003a3a3a, 0x00333433, 0x000a0a0a},
9238 {D3DFMT_X1R5G5B5, "X1R5G5R5",
9239 0x3def, 0x1ce7, 0x007b7b7b, 0x003a3a3a, 0x00333433, 0x000a0a0a},
9242 window = create_window();
9243 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9244 ok(!!d3d, "Failed to create a D3D object.\n");
9245 if (!(device = create_device(d3d, window, window, TRUE)))
9247 skip("Failed to create a D3D device, skipping tests.\n");
9248 goto done;
9251 for (i = 0; i < ARRAY_SIZE(tests); ++i)
9253 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
9254 D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE, tests[i].format) != D3D_OK)
9256 skip("%s textures with SRGBREAD are not supported.\n", tests[i].format_name);
9257 continue;
9260 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 2, 0, tests[i].format, D3DPOOL_MANAGED, &texture, NULL);
9261 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9262 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
9263 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9264 fill_surface(surface, tests[i].fill_colour1, 0);
9265 IDirect3DSurface9_Release(surface);
9266 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
9267 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9268 fill_surface(surface, tests[i].fill_colour2, 0);
9269 IDirect3DSurface9_Release(surface);
9271 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9272 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9273 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9274 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9276 /* AMD uses the LSB of the D3DSAMP_SRGBTEXTURE value.
9277 * NVIDIA ignores any values other than 0 and 1, leaving the previous
9278 * D3DSAMP_SRGBTEXTURE state.
9279 * Intel, WARP treat the value as boolean. */
9280 hr = IDirect3DDevice9_BeginScene(device);
9281 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9282 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, 0x7e41882a);
9283 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9284 hr = IDirect3DDevice9_GetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, &value);
9285 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9286 ok(value == 0x7e41882a, "Got unexpected value %#lx.\n", value);
9287 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9288 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9289 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
9290 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9291 hr = IDirect3DDevice9_EndScene(device);
9292 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9293 colour = getPixelColor(device, 320, 240);
9294 ok(color_match(colour, tests[i].fill_colour_rb1, 2)
9295 || broken(color_match(colour, tests[i].conv_colour1, 1)),
9296 "Format %s, got unexpected colour 0x%08x.\n", tests[i].format_name, colour);
9297 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9298 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9300 hr = IDirect3DDevice9_BeginScene(device);
9301 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9302 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, 100);
9303 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9304 hr = IDirect3DDevice9_GetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, &value);
9305 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9306 ok(value == 100, "Got unexpected value %#lx.\n", value);
9307 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
9308 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9309 hr = IDirect3DDevice9_EndScene(device);
9310 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9311 colour = getPixelColor(device, 320, 240);
9312 ok(color_match(colour, tests[i].fill_colour_rb1, 2)
9313 || broken(color_match(colour, tests[i].conv_colour1, 1)),
9314 "Format %s, got unexpected colour 0x%08x.\n", tests[i].format_name, colour);
9315 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9316 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9318 hr = IDirect3DDevice9_BeginScene(device);
9319 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9320 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, 2);
9321 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9322 hr = IDirect3DDevice9_GetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, &value);
9323 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9324 ok(value == 2, "Got unexpected value %#lx.\n", value);
9325 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
9326 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9327 hr = IDirect3DDevice9_EndScene(device);
9328 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9329 colour = getPixelColor(device, 320, 240);
9330 ok(color_match(colour, tests[i].fill_colour_rb1, 2)
9331 || broken(color_match(colour, tests[i].conv_colour1, 1)),
9332 "Format %s, got unexpected colour 0x%08x.\n", tests[i].format_name, colour);
9333 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9334 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9336 hr = IDirect3DDevice9_BeginScene(device);
9337 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9338 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, 3);
9339 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9340 hr = IDirect3DDevice9_GetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, &value);
9341 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9342 ok(value == 3, "Got unexpected value %#lx.\n", value);
9343 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
9344 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9345 hr = IDirect3DDevice9_EndScene(device);
9346 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9347 colour = getPixelColor(device, 320, 240);
9348 ok(color_match(colour, tests[i].fill_colour_rb1, 2)
9349 || color_match(colour, tests[i].conv_colour1, 3),
9350 "Format %s, got unexpected colour 0x%08x.\n", tests[i].format_name, colour);
9351 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9352 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9354 hr = IDirect3DDevice9_BeginScene(device);
9355 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9356 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
9357 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9358 hr = IDirect3DDevice9_GetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, &value);
9359 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9360 ok(value == TRUE, "Got unexpected value %#lx.\n", value);
9361 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
9362 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9363 hr = IDirect3DDevice9_EndScene(device);
9364 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9365 colour = getPixelColor(device, 320, 240);
9366 ok(color_match(colour, tests[i].conv_colour1, 3), "Format %s, got unexpected colour 0x%08x.\n",
9367 tests[i].format_name, colour);
9368 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9369 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9371 hr = IDirect3DDevice9_BeginScene(device);
9372 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9373 /* Set the other state to verify that the sampler just inherits old
9374 * D3DSAMP_SRGBTEXTURE but the old sampler is not preserved entirely on
9375 * NVIDIA. */
9376 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, 0x7e41882a);
9377 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9378 hr = IDirect3DDevice9_GetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, &value);
9379 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9380 ok(value == 0x7e41882a, "Got unexpected value %#lx.\n", value);
9381 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
9382 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9383 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
9384 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9385 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
9386 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9387 hr = IDirect3DDevice9_EndScene(device);
9388 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9389 colour = getPixelColor(device, 320, 240);
9390 ok(color_match(colour, tests[i].conv_colour2, 1)
9391 || color_match(colour, tests[i].fill_colour_rb2, 2),
9392 "Format %s, got unexpected colour 0x%08x.\n", tests[i].format_name, colour);
9393 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9394 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9396 hr = IDirect3DDevice9_BeginScene(device);
9397 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9398 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, 0);
9399 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9400 hr = IDirect3DDevice9_GetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, &value);
9401 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9402 ok(value == 0, "Got unexpected value %#lx.\n", value);
9403 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
9404 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9405 hr = IDirect3DDevice9_EndScene(device);
9406 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9407 colour = getPixelColor(device, 320, 240);
9408 ok(color_match(colour, tests[i].fill_colour_rb2, 2),
9409 "Format %s, got unexpected colour 0x%08x.\n", tests[i].format_name, colour);
9410 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9411 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9413 hr = IDirect3DDevice9_BeginScene(device);
9414 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9415 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, 0x7e41882a);
9416 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9417 hr = IDirect3DDevice9_GetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, &value);
9418 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9419 ok(value == 0x7e41882a, "Got unexpected value %#lx.\n", value);
9420 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9421 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9422 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
9423 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9424 hr = IDirect3DDevice9_EndScene(device);
9425 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9426 colour = getPixelColor(device, 320, 240);
9427 ok(color_match(colour, tests[i].fill_colour_rb2, 2)
9428 || broken(color_match(colour, tests[i].conv_colour2, 1)),
9429 "Format %s, got unexpected colour 0x%08x.\n", tests[i].format_name, colour);
9430 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9431 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9432 IDirect3DTexture9_Release(texture);
9434 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, 0);
9435 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9436 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
9437 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9440 refcount = IDirect3DDevice9_Release(device);
9441 ok(!refcount, "Device has %lu references left.\n", refcount);
9442 done:
9443 IDirect3D9_Release(d3d);
9444 DestroyWindow(window);
9447 static void test_shademode(void)
9449 IDirect3DVertexBuffer9 *vb_strip;
9450 IDirect3DVertexBuffer9 *vb_list;
9451 unsigned int color0, color1, i;
9452 IDirect3DVertexShader9 *vs;
9453 IDirect3DPixelShader9 *ps;
9454 IDirect3DDevice9 *device;
9455 void *data = NULL;
9456 IDirect3D9 *d3d;
9457 ULONG refcount;
9458 D3DCAPS9 caps;
9459 HWND window;
9460 HRESULT hr;
9462 static const DWORD vs1_code[] =
9464 0xfffe0101, /* vs_1_1 */
9465 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
9466 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
9467 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
9468 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
9469 0x0000ffff
9471 static const DWORD vs2_code[] =
9473 0xfffe0200, /* vs_2_0 */
9474 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
9475 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
9476 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
9477 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
9478 0x0000ffff
9480 static const DWORD vs3_code[] =
9482 0xfffe0300, /* vs_3_0 */
9483 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
9484 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
9485 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
9486 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */
9487 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
9488 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
9489 0x0000ffff
9491 static const DWORD ps1_code[] =
9493 0xffff0101, /* ps_1_1 */
9494 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
9495 0x0000ffff
9497 static const DWORD ps2_code[] =
9499 0xffff0200, /* ps_2_0 */
9500 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
9501 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
9502 0x0000ffff
9504 static const DWORD ps3_code[] =
9506 0xffff0300, /* ps_3_0 */
9507 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
9508 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
9509 0x0000ffff
9511 static const struct
9513 struct vec3 position;
9514 DWORD diffuse;
9516 quad_strip[] =
9518 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
9519 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
9520 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
9521 {{ 1.0f, 1.0f, 0.0f}, 0xffffffff},
9523 quad_list[] =
9525 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
9526 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
9527 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
9529 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
9530 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
9531 {{ 1.0f, 1.0f, 0.0f}, 0xffffffff},
9533 static const struct test_shader
9535 DWORD version;
9536 const DWORD *code;
9538 novs = {0, NULL},
9539 vs_1 = {D3DVS_VERSION(1, 1), vs1_code},
9540 vs_2 = {D3DVS_VERSION(2, 0), vs2_code},
9541 vs_3 = {D3DVS_VERSION(3, 0), vs3_code},
9542 nops = {0, NULL},
9543 ps_1 = {D3DPS_VERSION(1, 1), ps1_code},
9544 ps_2 = {D3DPS_VERSION(2, 0), ps2_code},
9545 ps_3 = {D3DPS_VERSION(3, 0), ps3_code};
9546 static const struct
9548 const struct test_shader *vs, *ps;
9549 DWORD primtype;
9550 DWORD shademode;
9551 unsigned int color0, color1;
9552 BOOL todo;
9554 tests[] =
9556 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, FALSE},
9557 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_PHONG, 0x000dca28, 0x000d45c7, FALSE},
9558 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
9559 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_PHONG, 0x000dca28, 0x000d45c7, FALSE},
9560 {&novs, &nops, D3DPT_TRIANGLELIST, D3DSHADE_FLAT, 0x00ff0000, 0x000000ff, FALSE},
9561 {&novs, &nops, D3DPT_TRIANGLELIST, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
9562 {&vs_1, &ps_1, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, FALSE},
9563 {&vs_1, &ps_1, D3DPT_TRIANGLESTRIP, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
9564 {&vs_1, &ps_1, D3DPT_TRIANGLELIST, D3DSHADE_FLAT, 0x00ff0000, 0x000000ff, FALSE},
9565 {&vs_1, &ps_1, D3DPT_TRIANGLELIST, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
9566 {&novs, &ps_1, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, FALSE},
9567 {&vs_1, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, FALSE},
9568 {&vs_2, &ps_2, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, FALSE},
9569 {&vs_2, &ps_2, D3DPT_TRIANGLESTRIP, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
9570 {&vs_3, &ps_3, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, TRUE},
9571 {&vs_3, &ps_3, D3DPT_TRIANGLESTRIP, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
9574 window = create_window();
9575 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9576 ok(!!d3d, "Failed to create a D3D object.\n");
9577 if (!(device = create_device(d3d, window, window, TRUE)))
9579 skip("Failed to create a D3D device, skipping tests.\n");
9580 goto done;
9583 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9584 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9585 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
9586 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#lx.\n", hr);
9588 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9589 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9591 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip), 0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
9592 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9593 hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
9594 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9595 memcpy(data, quad_strip, sizeof(quad_strip));
9596 hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
9597 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9599 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list), 0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
9600 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9601 hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
9602 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9603 memcpy(data, quad_list, sizeof(quad_list));
9604 hr = IDirect3DVertexBuffer9_Unlock(vb_list);
9605 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9607 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9608 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
9610 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
9611 * the color fixups we have to do for FLAT shading will be dependent on that. */
9613 for (i = 0; i < ARRAY_SIZE(tests); ++i)
9615 if (tests[i].vs->version)
9617 if (caps.VertexShaderVersion >= tests[i].vs->version)
9619 hr = IDirect3DDevice9_CreateVertexShader(device, tests[i].vs->code, &vs);
9620 ok(hr == D3D_OK, "Failed to create vertex shader, hr %#lx.\n", hr);
9621 hr = IDirect3DDevice9_SetVertexShader(device, vs);
9622 ok(hr == D3D_OK, "Failed to set vertex shader, hr %#lx.\n", hr);
9624 else
9626 skip("Shader version unsupported, skipping some tests.\n");
9627 continue;
9630 else
9632 vs = NULL;
9634 if (tests[i].ps->version)
9636 if (caps.PixelShaderVersion >= tests[i].ps->version)
9638 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].ps->code, &ps);
9639 ok(hr == D3D_OK, "Failed to create pixel shader, hr %#lx.\n", hr);
9640 hr = IDirect3DDevice9_SetPixelShader(device, ps);
9641 ok(hr == D3D_OK, "Failed to set pixel shader, hr %#lx.\n", hr);
9643 else
9645 skip("Shader version unsupported, skipping some tests.\n");
9646 if (vs)
9648 IDirect3DDevice9_SetVertexShader(device, NULL);
9649 IDirect3DVertexShader9_Release(vs);
9651 continue;
9654 else
9656 ps = NULL;
9659 hr = IDirect3DDevice9_SetStreamSource(device, 0,
9660 tests[i].primtype == D3DPT_TRIANGLESTRIP ? vb_strip : vb_list, 0, sizeof(quad_strip[0]));
9661 ok(hr == D3D_OK, "Failed to set stream source, hr %#lx.\n", hr);
9663 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
9664 ok(hr == D3D_OK, "Failed to clear, hr %#lx.\n", hr);
9666 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, tests[i].shademode);
9667 ok(hr == D3D_OK, "Failed to set shade mode, hr %#lx.\n", hr);
9669 hr = IDirect3DDevice9_BeginScene(device);
9670 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
9671 hr = IDirect3DDevice9_DrawPrimitive(device, tests[i].primtype, 0, 2);
9672 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
9673 hr = IDirect3DDevice9_EndScene(device);
9674 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
9676 color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
9677 color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
9679 /* For D3DSHADE_FLAT it should take the color of the first vertex of
9680 * each triangle. This requires EXT_provoking_vertex or similar
9681 * functionality being available. */
9682 /* PHONG should be the same as GOURAUD, since no hardware implements
9683 * this. */
9684 todo_wine_if (tests[i].todo)
9686 ok(color_match(color0, tests[i].color0, 1), "Test %u shading has color0 %08x, expected %08x.\n",
9687 i, color0, tests[i].color0);
9688 ok(color_match(color1, tests[i].color1, 1), "Test %u shading has color1 %08x, expected %08x.\n",
9689 i, color1, tests[i].color1);
9691 IDirect3DDevice9_SetVertexShader(device, NULL);
9692 IDirect3DDevice9_SetPixelShader(device, NULL);
9694 if (ps)
9695 IDirect3DPixelShader9_Release(ps);
9696 if (vs)
9697 IDirect3DVertexShader9_Release(vs);
9700 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9701 ok(hr == D3D_OK, "Failed to present, hr %#lx.\n", hr);
9703 IDirect3DVertexBuffer9_Release(vb_strip);
9704 IDirect3DVertexBuffer9_Release(vb_list);
9705 refcount = IDirect3DDevice9_Release(device);
9706 ok(!refcount, "Device has %lu references left.\n", refcount);
9707 done:
9708 IDirect3D9_Release(d3d);
9709 DestroyWindow(window);
9712 static void test_blend(void)
9714 IDirect3DSurface9 *backbuffer, *offscreen;
9715 IDirect3DTexture9 *offscreenTexture;
9716 IDirect3DDevice9 *device;
9717 unsigned int color;
9718 IDirect3D9 *d3d;
9719 ULONG refcount;
9720 HWND window;
9721 HRESULT hr;
9723 static const struct
9725 struct vec3 position;
9726 DWORD diffuse;
9728 quad1[] =
9730 {{-1.0f, -1.0f, 0.1f}, 0x4000ff00},
9731 {{-1.0f, 0.0f, 0.1f}, 0x4000ff00},
9732 {{ 1.0f, -1.0f, 0.1f}, 0x4000ff00},
9733 {{ 1.0f, 0.0f, 0.1f}, 0x4000ff00},
9735 quad2[] =
9737 {{-1.0f, 0.0f, 0.1f}, 0xc00000ff},
9738 {{-1.0f, 1.0f, 0.1f}, 0xc00000ff},
9739 {{ 1.0f, 0.0f, 0.1f}, 0xc00000ff},
9740 {{ 1.0f, 1.0f, 0.1f}, 0xc00000ff},
9742 static const float composite_quad[][5] =
9744 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
9745 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
9746 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
9747 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
9750 window = create_window();
9751 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9752 ok(!!d3d, "Failed to create a D3D object.\n");
9753 if (!(device = create_device(d3d, window, window, TRUE)))
9755 skip("Failed to create a D3D device, skipping tests.\n");
9756 goto done;
9759 /* Clear the render target with alpha = 0.5 */
9760 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x80ff0000, 1.0f, 0);
9761 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9763 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
9764 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
9765 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
9767 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9768 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9770 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
9771 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9773 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9774 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9776 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9777 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9778 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9779 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9780 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
9781 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9782 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
9783 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9784 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9785 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9787 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
9788 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9789 hr = IDirect3DDevice9_BeginScene(device);
9790 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
9792 /* Draw two quads, one with src alpha blending, one with dest alpha
9793 * blending. */
9794 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
9795 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
9796 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
9797 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
9798 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
9799 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
9801 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
9802 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
9803 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
9804 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
9805 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
9806 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
9808 /* Switch to the offscreen buffer, and redo the testing. The offscreen
9809 * render target doesn't have an alpha channel. DESTALPHA and INVDESTALPHA
9810 * "don't work" on render targets without alpha channel, they give
9811 * essentially ZERO and ONE blend factors. */
9812 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
9813 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
9814 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x80ff0000, 1.0f, 0);
9815 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
9817 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
9818 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
9819 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
9820 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
9821 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
9822 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
9824 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
9825 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
9826 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
9827 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
9828 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
9829 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
9831 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9832 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
9834 /* Render the offscreen texture onto the frame buffer to be able to
9835 * compare it regularly. Disable alpha blending for the final
9836 * composition. */
9837 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
9838 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
9839 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9840 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
9842 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
9843 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
9844 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
9845 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
9847 hr = IDirect3DDevice9_EndScene(device);
9848 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
9850 color = getPixelColor(device, 160, 360);
9851 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
9852 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
9854 color = getPixelColor(device, 160, 120);
9855 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
9856 "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
9858 color = getPixelColor(device, 480, 360);
9859 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
9860 "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
9862 color = getPixelColor(device, 480, 120);
9863 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
9864 "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
9866 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9868 IDirect3DSurface9_Release(backbuffer);
9869 IDirect3DTexture9_Release(offscreenTexture);
9870 IDirect3DSurface9_Release(offscreen);
9871 refcount = IDirect3DDevice9_Release(device);
9872 ok(!refcount, "Device has %lu references left.\n", refcount);
9873 done:
9874 IDirect3D9_Release(d3d);
9875 DestroyWindow(window);
9878 static void fixed_function_decl_test(void)
9880 IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
9881 IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_nocolor, *dcl_positiont;
9882 IDirect3DVertexBuffer9 *vb, *vb2;
9883 unsigned int color, size, i;
9884 IDirect3DDevice9 *device;
9885 BOOL s_ok, ub_ok, f_ok;
9886 IDirect3D9 *d3d;
9887 ULONG refcount;
9888 D3DCAPS9 caps;
9889 HWND window;
9890 void *data;
9891 HRESULT hr;
9893 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
9894 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9895 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9896 D3DDECL_END()
9898 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
9899 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9900 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9901 D3DDECL_END()
9903 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
9904 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9905 {0, 12, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9906 D3DDECL_END()
9908 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
9909 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9910 {1, 0, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9911 D3DDECL_END()
9913 static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
9914 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9915 {0, 12, D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9916 D3DDECL_END()
9918 static const D3DVERTEXELEMENT9 decl_elements_float[] = {
9919 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9920 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9921 D3DDECL_END()
9923 static const D3DVERTEXELEMENT9 decl_elements_nocolor[] = {
9924 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9925 D3DDECL_END()
9927 static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
9928 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
9929 {0, 16, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9930 D3DDECL_END()
9932 static const struct
9934 struct vec3 position;
9935 DWORD diffuse;
9937 quad1[] = /* D3DCOLOR */
9939 {{-1.0f, -1.0f, 0.1f}, 0x00ffff00},
9940 {{-1.0f, 0.0f, 0.1f}, 0x00ffff00},
9941 {{ 0.0f, -1.0f, 0.1f}, 0x00ffff00},
9942 {{ 0.0f, 0.0f, 0.1f}, 0x00ffff00},
9944 quad2[] = /* UBYTE4N */
9946 {{-1.0f, 0.0f, 0.1f}, 0x00ffff00},
9947 {{-1.0f, 1.0f, 0.1f}, 0x00ffff00},
9948 {{ 0.0f, 0.0f, 0.1f}, 0x00ffff00},
9949 {{ 0.0f, 1.0f, 0.1f}, 0x00ffff00},
9951 static const struct
9953 struct vec3 position;
9954 struct { unsigned short x, y, z, w; } color;
9956 quad3[] = /* USHORT4N */
9958 {{0.0f, -1.0f, 0.1f}, {0x0000, 0x0000, 0xffff, 0xffff}},
9959 {{0.0f, 0.0f, 0.1f}, {0x0000, 0x0000, 0xffff, 0xffff}},
9960 {{1.0f, -1.0f, 0.1f}, {0x0000, 0x0000, 0xffff, 0xffff}},
9961 {{1.0f, 0.0f, 0.1f}, {0x0000, 0x0000, 0xffff, 0xffff}},
9963 static const struct
9965 struct vec3 position;
9966 struct vec4 color;
9968 quad4[] =
9970 {{0.0f, 0.0f, 0.1f}, {1.0f, 0.0f, 0.0f, 0.0f}},
9971 {{0.0f, 1.0f, 0.1f}, {1.0f, 0.0f, 0.0f, 0.0f}},
9972 {{1.0f, 0.0f, 0.1f}, {1.0f, 0.0f, 0.0f, 0.0f}},
9973 {{1.0f, 1.0f, 0.1f}, {1.0f, 0.0f, 0.0f, 0.0f}},
9975 static const DWORD colors[] =
9977 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
9978 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
9979 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
9980 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
9981 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
9982 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
9983 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
9984 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
9985 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
9986 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
9987 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
9988 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
9989 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
9990 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
9991 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
9992 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
9994 static const float quads[] =
9996 -1.0f, -1.0f, 0.1f,
9997 -1.0f, 0.0f, 0.1f,
9998 0.0f, -1.0f, 0.1f,
9999 0.0f, 0.0f, 0.1f,
10001 0.0f, -1.0f, 0.1f,
10002 0.0f, 0.0f, 0.1f,
10003 1.0f, -1.0f, 0.1f,
10004 1.0f, 0.0f, 0.1f,
10006 0.0f, 0.0f, 0.1f,
10007 0.0f, 1.0f, 0.1f,
10008 1.0f, 0.0f, 0.1f,
10009 1.0f, 1.0f, 0.1f,
10011 -1.0f, 0.0f, 0.1f,
10012 -1.0f, 1.0f, 0.1f,
10013 0.0f, 0.0f, 0.1f,
10014 0.0f, 1.0f, 0.1f,
10016 static const struct
10018 struct vec4 position;
10019 DWORD diffuse;
10021 quad_transformed[] =
10023 {{ 90.0f, 110.0f, 0.1f, 2.0f}, 0x00ffff00},
10024 {{570.0f, 110.0f, 0.1f, 2.0f}, 0x00ffff00},
10025 {{ 90.0f, 300.0f, 0.1f, 2.0f}, 0x00ffff00},
10026 {{570.0f, 300.0f, 0.1f, 2.0f}, 0x00ffff00},
10029 window = create_window();
10030 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10031 ok(!!d3d, "Failed to create a D3D object.\n");
10032 if (!(device = create_device(d3d, window, window, TRUE)))
10034 skip("Failed to create a D3D device, skipping tests.\n");
10035 goto done;
10038 memset(&caps, 0, sizeof(caps));
10039 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10040 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10042 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
10043 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10045 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
10046 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10047 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
10048 ok(SUCCEEDED(hr) || hr == E_FAIL, "Got hr %#lx.\n", hr);
10049 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
10050 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10051 if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
10052 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
10053 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10054 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
10055 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10056 } else {
10057 trace("D3DDTCAPS_UBYTE4N not supported\n");
10058 dcl_ubyte_2 = NULL;
10059 dcl_ubyte = NULL;
10061 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
10062 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10063 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_nocolor, &dcl_nocolor);
10064 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10065 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
10066 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10068 size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
10069 hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
10070 0, 0, D3DPOOL_MANAGED, &vb, NULL);
10071 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10073 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10074 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
10076 hr = IDirect3DDevice9_BeginScene(device);
10077 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
10079 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
10080 if (dcl_color)
10082 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
10083 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
10084 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
10085 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
10088 /* Tests with non-standard fixed function types fail on the refrast. The
10089 * ATI driver partially accepts them, the NVIDIA driver accepts them all.
10090 * All those differences even though we're using software vertex
10091 * processing. Doh! */
10092 if (dcl_ubyte)
10094 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
10095 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
10096 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
10097 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
10098 ub_ok = SUCCEEDED(hr);
10101 if (dcl_short)
10103 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
10104 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
10105 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
10106 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
10107 s_ok = SUCCEEDED(hr);
10110 if (dcl_float)
10112 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
10113 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
10114 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
10115 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
10116 f_ok = SUCCEEDED(hr);
10119 hr = IDirect3DDevice9_EndScene(device);
10120 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
10122 if(dcl_short) {
10123 color = getPixelColor(device, 480, 360);
10124 ok(color == 0x000000ff || !s_ok,
10125 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
10127 if(dcl_ubyte) {
10128 color = getPixelColor(device, 160, 120);
10129 ok(color == 0x0000ffff || !ub_ok,
10130 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
10132 if(dcl_color) {
10133 color = getPixelColor(device, 160, 360);
10134 ok(color == 0x00ffff00,
10135 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
10137 if(dcl_float) {
10138 color = getPixelColor(device, 480, 120);
10139 ok(color == 0x00ff0000 || !f_ok,
10140 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
10142 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10144 /* The following test with vertex buffers doesn't serve to find out new
10145 * information from windows. It is a plain regression test because wined3d
10146 * uses different codepaths for attribute conversion with vertex buffers.
10147 * It makes sure that the vertex buffer one works, while the above tests
10148 * whether the immediate mode code works. */
10149 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
10150 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
10151 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
10152 hr = IDirect3DDevice9_BeginScene(device);
10153 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
10155 if (dcl_color)
10157 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
10158 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#lx.\n", hr);
10159 memcpy(data, quad1, sizeof(quad1));
10160 hr = IDirect3DVertexBuffer9_Unlock(vb);
10161 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#lx.\n", hr);
10162 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
10163 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
10164 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
10165 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#lx.\n", hr);
10166 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
10167 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
10170 if (dcl_ubyte)
10172 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
10173 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#lx.\n", hr);
10174 memcpy(data, quad2, sizeof(quad2));
10175 hr = IDirect3DVertexBuffer9_Unlock(vb);
10176 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#lx.\n", hr);
10177 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
10178 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
10179 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
10180 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#lx.\n", hr);
10181 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
10182 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
10183 ub_ok = SUCCEEDED(hr);
10186 if (dcl_short)
10188 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
10189 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#lx.\n", hr);
10190 memcpy(data, quad3, sizeof(quad3));
10191 hr = IDirect3DVertexBuffer9_Unlock(vb);
10192 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#lx.\n", hr);
10193 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
10194 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
10195 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
10196 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#lx.\n", hr);
10197 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
10198 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
10199 s_ok = SUCCEEDED(hr);
10202 if (dcl_float)
10204 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
10205 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#lx.\n", hr);
10206 memcpy(data, quad4, sizeof(quad4));
10207 hr = IDirect3DVertexBuffer9_Unlock(vb);
10208 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#lx.\n", hr);
10209 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
10210 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
10211 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
10212 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#lx.\n", hr);
10213 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
10214 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
10215 f_ok = SUCCEEDED(hr);
10218 hr = IDirect3DDevice9_EndScene(device);
10219 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
10221 if(dcl_short) {
10222 color = getPixelColor(device, 480, 360);
10223 ok(color == 0x000000ff || !s_ok,
10224 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
10226 if(dcl_ubyte) {
10227 color = getPixelColor(device, 160, 120);
10228 ok(color == 0x0000ffff || !ub_ok,
10229 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
10231 if(dcl_color) {
10232 color = getPixelColor(device, 160, 360);
10233 ok(color == 0x00ffff00,
10234 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
10236 if(dcl_float) {
10237 color = getPixelColor(device, 480, 120);
10238 ok(color == 0x00ff0000 || !f_ok,
10239 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
10241 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10243 /* Test with no diffuse color attribute. */
10244 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
10245 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
10247 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_nocolor);
10248 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
10249 hr = IDirect3DDevice9_BeginScene(device);
10250 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
10251 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quads, sizeof(float) * 3);
10252 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
10253 hr = IDirect3DDevice9_EndScene(device);
10254 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
10256 color = getPixelColor(device, 160, 360);
10257 ok(color == 0x00ffffff, "Got unexpected color 0x%08x in the no color attribute test.\n", color);
10259 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10261 /* Test what happens with specular lighting enabled and no specular color attribute. */
10262 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
10263 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
10264 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
10265 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARENABLE, TRUE);
10266 ok(SUCCEEDED(hr), "Failed to enable specular lighting, hr %#lx.\n", hr);
10267 hr = IDirect3DDevice9_BeginScene(device);
10268 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
10270 if (dcl_color)
10272 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
10273 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
10274 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
10275 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
10277 if (dcl_ubyte)
10279 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
10280 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
10281 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
10282 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
10283 ub_ok = SUCCEEDED(hr);
10285 if (dcl_short)
10287 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
10288 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
10289 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
10290 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
10291 s_ok = SUCCEEDED(hr);
10293 if (dcl_float)
10295 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
10296 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
10297 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
10298 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
10299 f_ok = SUCCEEDED(hr);
10302 hr = IDirect3DDevice9_EndScene(device);
10303 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
10304 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARENABLE, FALSE);
10305 ok(SUCCEEDED(hr), "Failed to disable specular lighting, hr %#lx.\n", hr);
10307 if (dcl_short)
10309 color = getPixelColor(device, 480, 360);
10310 ok(color == 0x000000ff || !s_ok,
10311 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff.\n", color);
10313 if (dcl_ubyte)
10315 color = getPixelColor(device, 160, 120);
10316 ok(color == 0x0000ffff || !ub_ok,
10317 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff.\n", color);
10319 if (dcl_color)
10321 color = getPixelColor(device, 160, 360);
10322 ok(color == 0x00ffff00,
10323 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00.\n", color);
10325 if (dcl_float)
10327 color = getPixelColor(device, 480, 120);
10328 ok(color == 0x00ff0000 || !f_ok,
10329 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000.\n", color);
10331 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10333 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
10334 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10335 memcpy(data, quad_transformed, sizeof(quad_transformed));
10336 hr = IDirect3DVertexBuffer9_Unlock(vb);
10337 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10339 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
10340 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10342 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
10343 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10345 hr = IDirect3DDevice9_BeginScene(device);
10346 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
10347 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
10348 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#lx.\n", hr);
10349 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
10350 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
10351 hr = IDirect3DDevice9_EndScene(device);
10352 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
10354 color = getPixelColor(device, 88, 108);
10355 ok(color == 0x000000ff,
10356 "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
10357 color = getPixelColor(device, 92, 108);
10358 ok(color == 0x000000ff,
10359 "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
10360 color = getPixelColor(device, 88, 112);
10361 ok(color == 0x000000ff,
10362 "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
10363 color = getPixelColor(device, 92, 112);
10364 ok(color == 0x00ffff00,
10365 "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
10367 color = getPixelColor(device, 568, 108);
10368 ok(color == 0x000000ff,
10369 "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
10370 color = getPixelColor(device, 572, 108);
10371 ok(color == 0x000000ff,
10372 "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
10373 color = getPixelColor(device, 568, 112);
10374 ok(color == 0x00ffff00,
10375 "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
10376 color = getPixelColor(device, 572, 112);
10377 ok(color == 0x000000ff,
10378 "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
10380 color = getPixelColor(device, 88, 298);
10381 ok(color == 0x000000ff,
10382 "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
10383 color = getPixelColor(device, 92, 298);
10384 ok(color == 0x00ffff00,
10385 "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
10386 color = getPixelColor(device, 88, 302);
10387 ok(color == 0x000000ff,
10388 "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
10389 color = getPixelColor(device, 92, 302);
10390 ok(color == 0x000000ff,
10391 "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
10393 color = getPixelColor(device, 568, 298);
10394 ok(color == 0x00ffff00,
10395 "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
10396 color = getPixelColor(device, 572, 298);
10397 ok(color == 0x000000ff,
10398 "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
10399 color = getPixelColor(device, 568, 302);
10400 ok(color == 0x000000ff,
10401 "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
10402 color = getPixelColor(device, 572, 302);
10403 ok(color == 0x000000ff,
10404 "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
10406 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10408 /* This test is pointless without those two declarations: */
10409 if((!dcl_color_2) || (!dcl_ubyte_2)) {
10410 skip("color-ubyte switching test declarations aren't supported\n");
10411 goto out;
10414 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
10415 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10416 memcpy(data, quads, sizeof(quads));
10417 hr = IDirect3DVertexBuffer9_Unlock(vb);
10418 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10419 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
10420 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
10421 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10422 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
10423 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10424 memcpy(data, colors, sizeof(colors));
10425 hr = IDirect3DVertexBuffer9_Unlock(vb2);
10426 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10428 for(i = 0; i < 2; i++) {
10429 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
10430 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10432 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
10433 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10434 if(i == 0) {
10435 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
10436 } else {
10437 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
10439 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10441 hr = IDirect3DDevice9_BeginScene(device);
10442 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
10444 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
10445 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
10446 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
10447 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
10448 ub_ok = SUCCEEDED(hr);
10450 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
10451 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
10452 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
10453 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
10455 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
10456 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
10457 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
10458 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
10459 ub_ok = (SUCCEEDED(hr) && ub_ok);
10461 hr = IDirect3DDevice9_EndScene(device);
10462 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
10464 if(i == 0) {
10465 color = getPixelColor(device, 480, 360);
10466 ok(color == 0x00ff0000,
10467 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
10468 color = getPixelColor(device, 160, 120);
10469 ok(color == 0x00ffffff,
10470 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
10471 color = getPixelColor(device, 160, 360);
10472 ok(color == 0x000000ff || !ub_ok,
10473 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
10474 color = getPixelColor(device, 480, 120);
10475 ok(color == 0x000000ff || !ub_ok,
10476 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
10477 } else {
10478 color = getPixelColor(device, 480, 360);
10479 ok(color == 0x000000ff,
10480 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
10481 color = getPixelColor(device, 160, 120);
10482 ok(color == 0x00ffffff,
10483 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
10484 color = getPixelColor(device, 160, 360);
10485 ok(color == 0x00ff0000 || !ub_ok,
10486 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
10487 color = getPixelColor(device, 480, 120);
10488 ok(color == 0x00ff0000 || !ub_ok,
10489 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
10491 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10494 IDirect3DVertexBuffer9_Release(vb2);
10495 out:
10496 IDirect3DVertexBuffer9_Release(vb);
10497 if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
10498 if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
10499 if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
10500 if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
10501 if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
10502 if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
10503 IDirect3DVertexDeclaration9_Release(dcl_nocolor);
10504 IDirect3DVertexDeclaration9_Release(dcl_positiont);
10505 refcount = IDirect3DDevice9_Release(device);
10506 ok(!refcount, "Device has %lu references left.\n", refcount);
10507 done:
10508 IDirect3D9_Release(d3d);
10509 DestroyWindow(window);
10512 static void test_vshader_float16(void)
10514 IDirect3DVertexDeclaration9 *vdecl = NULL;
10515 IDirect3DVertexBuffer9 *buffer = NULL;
10516 IDirect3DVertexShader9 *shader;
10517 IDirect3DDevice9 *device;
10518 unsigned int color;
10519 IDirect3D9 *d3d;
10520 ULONG refcount;
10521 D3DCAPS9 caps;
10522 HWND window;
10523 void *data;
10524 HRESULT hr;
10526 static const D3DVERTEXELEMENT9 decl_elements[] =
10528 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
10529 {0, 12, D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
10530 D3DDECL_END()
10532 static const DWORD shader_code[] =
10534 0xfffe0101, /* vs_1_1 */
10535 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10536 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
10537 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
10538 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
10539 0x0000ffff,
10541 static const struct vertex_float16color
10543 float x, y, z;
10544 DWORD c1, c2;
10546 quad[] =
10548 { -1.0, -1.0, 0.1, 0x3c000000, 0x00000000 }, /* green */
10549 { -1.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
10550 { 0.0, -1.0, 0.1, 0x3c000000, 0x00000000 },
10551 { 0.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
10553 { 0.0, -1.0, 0.1, 0x00003c00, 0x00000000 }, /* red */
10554 { 0.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
10555 { 1.0, -1.0, 0.1, 0x00003c00, 0x00000000 },
10556 { 1.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
10558 { 0.0, 0.0, 0.1, 0x00000000, 0x00003c00 }, /* blue */
10559 { 0.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
10560 { 1.0, 0.0, 0.1, 0x00000000, 0x00003c00 },
10561 { 1.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
10563 { -1.0, 0.0, 0.1, 0x00000000, 0x3c000000 }, /* alpha */
10564 { -1.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
10565 { 0.0, 0.0, 0.1, 0x00000000, 0x3c000000 },
10566 { 0.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
10569 window = create_window();
10570 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10571 ok(!!d3d, "Failed to create a D3D object.\n");
10572 if (!(device = create_device(d3d, window, window, TRUE)))
10574 skip("Failed to create a D3D device, skipping tests.\n");
10575 goto done;
10578 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10579 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
10580 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
10582 skip("No vs_3_0 support, skipping tests.\n");
10583 IDirect3DDevice9_Release(device);
10584 goto done;
10587 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff102030, 1.0f, 0);
10588 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10590 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
10591 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10592 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10593 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10594 hr = IDirect3DDevice9_SetVertexShader(device, shader);
10595 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10597 hr = IDirect3DDevice9_BeginScene(device);
10598 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
10599 hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
10600 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
10601 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 0, sizeof(quad[0]));
10602 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
10603 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 4, sizeof(quad[0]));
10604 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
10605 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 8, sizeof(quad[0]));
10606 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
10607 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
10608 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
10609 hr = IDirect3DDevice9_EndScene(device);
10610 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
10612 color = getPixelColor(device, 480, 360);
10613 ok(color == 0x00ff0000,
10614 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
10615 color = getPixelColor(device, 160, 120);
10616 ok(color == 0x00000000,
10617 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
10618 color = getPixelColor(device, 160, 360);
10619 ok(color == 0x0000ff00,
10620 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
10621 color = getPixelColor(device, 480, 120);
10622 ok(color == 0x000000ff,
10623 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
10624 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10626 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
10627 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10629 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
10630 D3DPOOL_MANAGED, &buffer, NULL);
10631 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10632 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
10633 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10634 memcpy(data, quad, sizeof(quad));
10635 hr = IDirect3DVertexBuffer9_Unlock(buffer);
10636 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10637 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
10638 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10640 hr = IDirect3DDevice9_BeginScene(device);
10641 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
10642 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
10643 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
10644 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
10645 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
10646 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
10647 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
10648 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
10649 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
10650 hr = IDirect3DDevice9_EndScene(device);
10651 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
10653 color = getPixelColor(device, 480, 360);
10654 ok(color == 0x00ff0000,
10655 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
10656 color = getPixelColor(device, 160, 120);
10657 ok(color == 0x00000000,
10658 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
10659 color = getPixelColor(device, 160, 360);
10660 ok(color == 0x0000ff00,
10661 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
10662 color = getPixelColor(device, 480, 120);
10663 ok(color == 0x000000ff,
10664 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
10665 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10667 IDirect3DVertexDeclaration9_Release(vdecl);
10668 IDirect3DVertexShader9_Release(shader);
10669 IDirect3DVertexBuffer9_Release(buffer);
10670 refcount = IDirect3DDevice9_Release(device);
10671 ok(!refcount, "Device has %lu references left.\n", refcount);
10672 done:
10673 IDirect3D9_Release(d3d);
10674 DestroyWindow(window);
10677 static void conditional_np2_repeat_test(void)
10679 IDirect3DTexture9 *texture;
10680 IDirect3DDevice9 *device;
10681 unsigned int color, x, y;
10682 D3DLOCKED_RECT rect;
10683 IDirect3D9 *d3d;
10684 ULONG refcount;
10685 D3DCAPS9 caps;
10686 HWND window;
10687 HRESULT hr;
10688 DWORD *dst;
10690 static const float quad[] =
10692 -1.0f, -1.0f, 0.1f, -0.2f, -0.2f,
10693 -1.0f, 1.0f, 0.1f, -0.2f, 1.2f,
10694 1.0f, -1.0f, 0.1f, 1.2f, -0.2f,
10695 1.0f, 1.0f, 0.1f, 1.2f, 1.2f,
10698 window = create_window();
10699 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10700 ok(!!d3d, "Failed to create a D3D object.\n");
10701 if (!(device = create_device(d3d, window, window, TRUE)))
10703 skip("Failed to create a D3D device, skipping tests.\n");
10704 goto done;
10707 memset(&caps, 0, sizeof(caps));
10708 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10709 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10710 if (caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL)
10712 /* NP2 conditional requires the POW2 flag. Check that while we're at it */
10713 ok(caps.TextureCaps & D3DPTEXTURECAPS_POW2,
10714 "Card has conditional NP2 support without power of two restriction set\n");
10716 else if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
10718 skip("No conditional NP2 support, skipping conditional NP2 tests\n");
10719 IDirect3DDevice9_Release(device);
10720 goto done;
10722 else
10724 skip("Card has unconditional NP2 support, skipping conditional NP2 tests\n");
10725 IDirect3DDevice9_Release(device);
10726 goto done;
10729 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
10730 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
10732 hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
10733 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
10735 memset(&rect, 0, sizeof(rect));
10736 hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
10737 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
10738 for(y = 0; y < 10; y++) {
10739 for(x = 0; x < 10; x++) {
10740 dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
10741 if(x == 0 || x == 9 || y == 0 || y == 9) {
10742 *dst = 0x00ff0000;
10743 } else {
10744 *dst = 0x000000ff;
10748 hr = IDirect3DTexture9_UnlockRect(texture, 0);
10749 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
10751 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
10752 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
10753 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10754 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
10755 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
10756 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
10757 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
10758 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
10759 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
10760 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
10762 hr = IDirect3DDevice9_BeginScene(device);
10763 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
10764 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
10765 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
10766 hr = IDirect3DDevice9_EndScene(device);
10767 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
10769 color = getPixelColor(device, 1, 1);
10770 ok(color == 0x00ff0000, "NP2: Pixel 1, 1 has color %08x, expected 0x00ff0000\n", color);
10771 color = getPixelColor(device, 639, 479);
10772 ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
10774 color = getPixelColor(device, 135, 101);
10775 ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
10776 color = getPixelColor(device, 140, 101);
10777 ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
10778 color = getPixelColor(device, 135, 105);
10779 ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
10780 color = getPixelColor(device, 140, 105);
10781 ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
10783 color = getPixelColor(device, 135, 376);
10784 ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
10785 color = getPixelColor(device, 140, 376);
10786 ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
10787 color = getPixelColor(device, 135, 379);
10788 ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
10789 color = getPixelColor(device, 140, 379);
10790 ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
10792 color = getPixelColor(device, 500, 101);
10793 ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
10794 color = getPixelColor(device, 504, 101);
10795 ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
10796 color = getPixelColor(device, 500, 105);
10797 ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
10798 color = getPixelColor(device, 504, 105);
10799 ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
10801 color = getPixelColor(device, 500, 376);
10802 ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
10803 color = getPixelColor(device, 504, 376);
10804 ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
10805 color = getPixelColor(device, 500, 380);
10806 ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
10807 color = getPixelColor(device, 504, 380);
10808 ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
10810 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10812 IDirect3DTexture9_Release(texture);
10813 refcount = IDirect3DDevice9_Release(device);
10814 ok(!refcount, "Device has %lu references left.\n", refcount);
10815 done:
10816 IDirect3D9_Release(d3d);
10817 DestroyWindow(window);
10820 static void vface_register_test(void)
10822 IDirect3DSurface9 *surface, *backbuffer;
10823 IDirect3DVertexShader9 *vshader;
10824 IDirect3DPixelShader9 *shader;
10825 IDirect3DTexture9 *texture;
10826 IDirect3DDevice9 *device;
10827 unsigned int color;
10828 IDirect3D9 *d3d;
10829 ULONG refcount;
10830 D3DCAPS9 caps;
10831 HWND window;
10832 HRESULT hr;
10834 static const DWORD shader_code[] =
10836 0xffff0300, /* ps_3_0 */
10837 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
10838 0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
10839 0x0200001f, 0x80000000, 0x900f1001, /* dcl vFace */
10840 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
10841 0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001, /* cmp r0, vFace, c0, r1 */
10842 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
10843 0x0000ffff /* END */
10845 static const DWORD vshader_code[] =
10847 0xfffe0300, /* vs_3_0 */
10848 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10849 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
10850 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
10851 0x0000ffff /* end */
10853 static const float quad[] =
10855 -1.0f, -1.0f, 0.1f,
10856 1.0f, -1.0f, 0.1f,
10857 -1.0f, 0.0f, 0.1f,
10859 1.0f, -1.0f, 0.1f,
10860 1.0f, 0.0f, 0.1f,
10861 -1.0f, 0.0f, 0.1f,
10863 -1.0f, 0.0f, 0.1f,
10864 -1.0f, 1.0f, 0.1f,
10865 1.0f, 0.0f, 0.1f,
10867 1.0f, 0.0f, 0.1f,
10868 -1.0f, 1.0f, 0.1f,
10869 1.0f, 1.0f, 0.1f,
10871 static const float blit[] =
10873 0.0f, -1.0f, 0.1f, 0.0f, 0.0f,
10874 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
10875 0.0f, 1.0f, 0.1f, 0.0f, 1.0f,
10876 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
10879 window = create_window();
10880 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10881 ok(!!d3d, "Failed to create a D3D object.\n");
10882 if (!(device = create_device(d3d, window, window, TRUE)))
10884 skip("Failed to create a D3D device, skipping tests.\n");
10885 goto done;
10888 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10889 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
10890 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
10892 skip("No shader model 3 support, skipping tests.\n");
10893 IDirect3DDevice9_Release(device);
10894 goto done;
10897 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
10898 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10899 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
10900 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10901 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
10902 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10903 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
10904 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10905 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
10906 ok(SUCCEEDED(hr), "Failed to set cull mode, hr %#lx.\n", hr);
10907 hr = IDirect3DDevice9_SetPixelShader(device, shader);
10908 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10909 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
10910 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10911 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10912 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10913 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
10914 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10916 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
10917 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10919 hr = IDirect3DDevice9_BeginScene(device);
10920 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
10922 /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
10923 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
10924 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
10925 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
10926 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
10927 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
10928 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
10929 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10930 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
10931 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
10932 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
10934 /* Blit the texture onto the back buffer to make it visible */
10935 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10936 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
10937 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
10938 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
10939 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
10940 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
10941 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10942 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#lx.\n", hr);
10943 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10944 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#lx.\n", hr);
10945 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
10946 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
10947 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
10948 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
10950 hr = IDirect3DDevice9_EndScene(device);
10951 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
10953 color = getPixelColor(device, 160, 360);
10954 ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
10955 color = getPixelColor(device, 160, 120);
10956 ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
10957 color = getPixelColor(device, 480, 360);
10958 ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
10959 color = getPixelColor(device, 480, 120);
10960 ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
10961 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10962 ok(SUCCEEDED(hr), "Present failed, hr %#lx.\n", hr);
10964 IDirect3DPixelShader9_Release(shader);
10965 IDirect3DVertexShader9_Release(vshader);
10966 IDirect3DSurface9_Release(surface);
10967 IDirect3DSurface9_Release(backbuffer);
10968 IDirect3DTexture9_Release(texture);
10969 refcount = IDirect3DDevice9_Release(device);
10970 ok(!refcount, "Device has %lu references left.\n", refcount);
10971 done:
10972 IDirect3D9_Release(d3d);
10973 DestroyWindow(window);
10976 static void fixed_function_bumpmap_test(void)
10978 IDirect3DVertexDeclaration9 *vertex_declaration;
10979 IDirect3DTexture9 *texture, *tex1, *tex2;
10980 D3DLOCKED_RECT locked_rect;
10981 IDirect3DDevice9 *device;
10982 unsigned int color, i;
10983 BOOL L6V5U5_supported;
10984 float scale, offset;
10985 IDirect3D9 *d3d;
10986 ULONG refcount;
10987 D3DCAPS9 caps;
10988 HWND window;
10989 HRESULT hr;
10991 static const float quad[][7] =
10993 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
10994 {-1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
10995 { 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
10996 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
10998 static const D3DVERTEXELEMENT9 decl_elements[] =
11000 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
11001 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
11002 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
11003 D3DDECL_END()
11005 /* use asymmetric matrix to test loading */
11006 static const float bumpenvmat[4] = {0.0f, 0.5f, -0.5f, 0.0f};
11008 window = create_window();
11009 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11010 ok(!!d3d, "Failed to create a D3D object.\n");
11011 if (!(device = create_device(d3d, window, window, TRUE)))
11013 skip("Failed to create a D3D device, skipping tests.\n");
11014 goto done;
11017 memset(&caps, 0, sizeof(caps));
11018 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11019 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11020 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP))
11022 skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
11023 IDirect3DDevice9_Release(device);
11024 goto done;
11027 /* This check is disabled, some Windows drivers do not handle
11028 * D3DUSAGE_QUERY_LEGACYBUMPMAP properly. They report that it is not
11029 * supported, but after that bump mapping works properly. So just test if
11030 * the format is generally supported, and check the BUMPENVMAP flag. */
11031 L6V5U5_supported = SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
11032 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_L6V5U5));
11033 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
11034 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_V8U8)))
11036 skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
11037 IDirect3DDevice9_Release(device);
11038 return;
11041 /* Generate the textures */
11042 generate_bumpmap_textures(device);
11044 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, float_to_int(bumpenvmat[0]));
11045 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11046 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, float_to_int(bumpenvmat[1]));
11047 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11048 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, float_to_int(bumpenvmat[2]));
11049 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11050 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, float_to_int(bumpenvmat[3]));
11051 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11053 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
11054 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11055 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
11056 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11057 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
11058 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11060 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
11061 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11062 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
11063 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11064 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
11065 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11067 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
11068 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11070 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
11071 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11073 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff00ff, 1.0f, 0);
11074 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11076 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
11077 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11078 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
11079 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11081 hr = IDirect3DDevice9_BeginScene(device);
11082 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11084 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
11085 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11087 hr = IDirect3DDevice9_EndScene(device);
11088 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11090 color = getPixelColor(device, 240, 60);
11091 ok(color_match(color, 0x005ea000, 4), "Got unexpected color 0x%08x.\n", color);
11092 color = getPixelColor(device, 400, 60);
11093 ok(color_match(color, 0x009ea000, 4), "Got unexpected color 0x%08x.\n", color);
11094 color = getPixelColor(device, 80, 180);
11095 ok(color_match(color, 0x005ea000, 4), "Got unexpected color 0x%08x.\n", color);
11096 color = getPixelColor(device, 560, 180);
11097 ok(color_match(color, 0x009ea000, 4), "Got unexpected color 0x%08x.\n", color);
11098 color = getPixelColor(device, 80, 300);
11099 ok(color_match(color, 0x005e6000, 4), "Got unexpected color 0x%08x.\n", color);
11100 color = getPixelColor(device, 560, 300);
11101 ok(color_match(color, 0x009e6000, 4), "Got unexpected color 0x%08x.\n", color);
11102 color = getPixelColor(device, 240, 420);
11103 ok(color_match(color, 0x005e6000, 4), "Got unexpected color 0x%08x.\n", color);
11104 color = getPixelColor(device, 400, 420);
11105 ok(color_match(color, 0x009e6000, 4), "Got unexpected color 0x%08x.\n", color);
11106 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11107 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11109 for(i = 0; i < 2; i++) {
11110 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
11111 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11112 IDirect3DTexture9_Release(texture); /* For the GetTexture */
11113 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
11114 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11115 IDirect3DTexture9_Release(texture); /* To destroy it */
11118 if (!L6V5U5_supported || !(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE))
11120 skip("L6V5U5 / D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping tests.\n");
11121 IDirect3DVertexDeclaration9_Release(vertex_declaration);
11122 IDirect3DDevice9_Release(device);
11123 goto done;
11126 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
11127 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11128 /* This test only tests the luminance part. The bumpmapping part was already tested above and
11129 * would only make this test more complicated
11131 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
11132 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11133 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
11134 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11136 memset(&locked_rect, 0, sizeof(locked_rect));
11137 hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
11138 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11139 *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
11140 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
11141 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11143 memset(&locked_rect, 0, sizeof(locked_rect));
11144 hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
11145 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11146 *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
11147 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
11148 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11150 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
11151 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11152 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
11153 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11155 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
11156 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11157 scale = 2.0;
11158 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
11159 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11160 offset = 0.1;
11161 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
11162 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11164 hr = IDirect3DDevice9_BeginScene(device);
11165 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
11166 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
11167 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
11168 hr = IDirect3DDevice9_EndScene(device);
11169 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
11171 color = getPixelColor(device, 320, 240);
11172 /* red: 1.0 * (0.25 * 2.0 + 0.1) = 1.0 * 0.6 = 0.6 = 0x99
11173 * green: 0.5 * (0.25 * 2.0 + 0.1) = 0.5 * 0.6 = 0.3 = 0x4c
11174 * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
11176 ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
11177 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11178 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11180 /* Check a result scale factor > 1.0 */
11181 scale = 10;
11182 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
11183 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11184 offset = 10;
11185 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
11186 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11188 hr = IDirect3DDevice9_BeginScene(device);
11189 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
11190 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
11191 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
11192 hr = IDirect3DDevice9_EndScene(device);
11193 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
11195 color = getPixelColor(device, 320, 240);
11196 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
11197 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11198 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11200 /* Check clamping in the scale factor calculation */
11201 scale = 1000;
11202 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
11203 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11204 offset = -1;
11205 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
11206 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11208 hr = IDirect3DDevice9_BeginScene(device);
11209 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
11210 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
11211 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
11212 hr = IDirect3DDevice9_EndScene(device);
11213 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
11215 color = getPixelColor(device, 320, 240);
11216 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
11217 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11218 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11220 IDirect3DTexture9_Release(tex1);
11221 IDirect3DTexture9_Release(tex2);
11222 IDirect3DVertexDeclaration9_Release(vertex_declaration);
11223 refcount = IDirect3DDevice9_Release(device);
11224 ok(!refcount, "Device has %lu references left.\n", refcount);
11225 done:
11226 IDirect3D9_Release(d3d);
11227 DestroyWindow(window);
11230 static void stencil_cull_test(void)
11232 IDirect3DDevice9 *device;
11233 IDirect3D9 *d3d;
11234 ULONG refcount;
11235 D3DCAPS9 caps;
11236 HWND window;
11237 HRESULT hr;
11238 static const struct
11240 struct vec3 position;
11242 quad1[] =
11244 {{-1.0f, -1.0f, 0.1f}},
11245 {{ 0.0f, -1.0f, 0.1f}},
11246 {{-1.0f, 0.0f, 0.1f}},
11247 {{ 0.0f, 0.0f, 0.1f}},
11249 quad2[] =
11251 {{ 0.0f, -1.0f, 0.1f}},
11252 {{ 1.0f, -1.0f, 0.1f}},
11253 {{ 0.0f, 0.0f, 0.1f}},
11254 {{ 1.0f, 0.0f, 0.1f}},
11256 quad3[] =
11258 {{ 0.0f, 0.0f, 0.1f}},
11259 {{ 1.0f, 0.0f, 0.1f}},
11260 {{ 0.0f, 1.0f, 0.1f}},
11261 {{ 1.0f, 1.0f, 0.1f}},
11263 quad4[] =
11265 {{-1.0f, 0.0f, 0.1f}},
11266 {{ 0.0f, 0.0f, 0.1f}},
11267 {{-1.0f, 1.0f, 0.1f}},
11268 {{ 0.0f, 1.0f, 0.1f}},
11270 struct
11272 struct vec3 position;
11273 DWORD diffuse;
11275 painter[] =
11277 {{-1.0f, -1.0f, 0.0f}, 0x00000000},
11278 {{ 1.0f, -1.0f, 0.0f}, 0x00000000},
11279 {{-1.0f, 1.0f, 0.0f}, 0x00000000},
11280 {{ 1.0f, 1.0f, 0.0f}, 0x00000000},
11282 static const WORD indices_cw[] = {0, 1, 3};
11283 static const WORD indices_ccw[] = {0, 2, 3};
11284 unsigned int color, i;
11286 window = create_window();
11287 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11288 ok(!!d3d, "Failed to create a D3D object.\n");
11289 if (!(device = create_device(d3d, window, window, TRUE)))
11291 skip("Cannot create a device with a D24S8 stencil buffer.\n");
11292 DestroyWindow(window);
11293 IDirect3D9_Release(d3d);
11294 return;
11296 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11297 ok(SUCCEEDED(hr), "Failed to get caps, hr %#lx.\n", hr);
11298 if (!(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED))
11300 skip("No two sided stencil support\n");
11301 goto cleanup;
11304 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
11305 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11306 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
11307 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11309 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
11310 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11311 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11312 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11313 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
11314 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11315 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
11316 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11317 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
11318 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11319 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
11320 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11322 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
11323 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11324 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
11325 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11326 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
11327 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11329 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
11330 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11331 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
11332 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11334 /* First pass: Fill the stencil buffer with some values... */
11335 hr = IDirect3DDevice9_BeginScene(device);
11336 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11338 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
11339 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11340 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST,
11341 0, 4, 1, indices_cw, D3DFMT_INDEX16, quad1, sizeof(*quad1));
11342 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11343 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST,
11344 0, 4, 1, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(*quad1));
11345 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11347 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
11348 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11349 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
11350 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11351 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST,
11352 0, 4, 1, indices_cw, D3DFMT_INDEX16, quad2, sizeof(*quad2));
11353 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11354 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST,
11355 0, 4, 1, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(*quad2));
11356 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11358 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
11359 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11360 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST,
11361 0, 4, 1, indices_cw, D3DFMT_INDEX16, quad3, sizeof(*quad3));
11362 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11363 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST,
11364 0, 4, 1, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(*quad3));
11365 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11367 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
11368 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11369 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST,
11370 0, 4, 1, indices_cw, D3DFMT_INDEX16, quad4, sizeof(*quad4));
11371 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11372 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST,
11373 0, 4, 1, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(*quad4));
11374 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11376 hr = IDirect3DDevice9_EndScene(device);
11377 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11379 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
11380 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11381 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
11382 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11383 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
11384 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11385 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
11386 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11387 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
11388 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11389 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
11390 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11392 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILMASK, 0x000000ff);
11393 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11395 /* 2nd pass: Make the stencil values visible */
11396 hr = IDirect3DDevice9_BeginScene(device);
11397 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11398 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11399 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11400 for (i = 0; i < 16; ++i)
11402 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x0000ff00 | i);
11403 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
11405 painter[0].diffuse = (i * 16); /* Creates shades of blue */
11406 painter[1].diffuse = (i * 16);
11407 painter[2].diffuse = (i * 16);
11408 painter[3].diffuse = (i * 16);
11409 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
11410 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11412 hr = IDirect3DDevice9_EndScene(device);
11413 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11415 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
11416 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11418 color = getPixelColor(device, 160, 420);
11419 ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
11420 color = getPixelColor(device, 160, 300);
11421 ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
11423 color = getPixelColor(device, 480, 420);
11424 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
11425 color = getPixelColor(device, 480, 300);
11426 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
11428 color = getPixelColor(device, 160, 180);
11429 ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
11430 color = getPixelColor(device, 160, 60);
11431 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
11433 color = getPixelColor(device, 480, 180);
11434 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
11435 color = getPixelColor(device, 480, 60);
11436 ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
11438 /* Test for reference truncation. */
11439 /* 1st pass: set stencil. */
11440 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0f, 0);
11441 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11442 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_REPLACE);
11443 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11444 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_REPLACE);
11445 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11446 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
11447 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11448 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x1cc);
11449 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11450 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILMASK, 0);
11451 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11452 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_ALWAYS);
11453 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11454 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
11455 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11456 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
11457 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11459 hr = IDirect3DDevice9_BeginScene(device);
11460 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11461 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
11462 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11463 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST,
11464 0, 4, 1, indices_cw, D3DFMT_INDEX16, quad1, sizeof(*quad1));
11465 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11466 hr = IDirect3DDevice9_EndScene(device);
11467 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11469 /* 2nd pass: draw image. */
11470 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
11471 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11473 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0xdb);
11474 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11475 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILMASK, 0x0f);
11476 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11477 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_LESS);
11478 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11480 hr = IDirect3DDevice9_BeginScene(device);
11481 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11482 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11483 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11484 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
11485 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11486 hr = IDirect3DDevice9_EndScene(device);
11487 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11489 color = getPixelColor(device, 280, 360);
11490 ok(color == 0x000000f0, "Got unexpected colour 0x%08x.\n", color);
11492 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11493 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11495 cleanup:
11496 refcount = IDirect3DDevice9_Release(device);
11497 ok(!refcount, "Device has %lu references left.\n", refcount);
11498 IDirect3D9_Release(d3d);
11499 DestroyWindow(window);
11502 static void test_fragment_coords(void)
11504 IDirect3DSurface9 *surface = NULL, *backbuffer;
11505 IDirect3DPixelShader9 *shader, *shader_frac;
11506 IDirect3DVertexShader9 *vshader;
11507 IDirect3DDevice9 *device;
11508 unsigned int color;
11509 D3DLOCKED_RECT lr;
11510 IDirect3D9 *d3d;
11511 ULONG refcount;
11512 D3DCAPS9 caps;
11513 HWND window;
11514 HRESULT hr;
11515 DWORD *pos;
11517 static const DWORD shader_code[] =
11519 0xffff0300, /* ps_3_0 */
11520 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
11521 0x03000002, 0x80030000, 0x90541000, 0xa1fe0000, /* sub r0.xy, vPos.xy, c0.zw */
11522 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
11523 0x02000001, 0x80080002, 0xa0550000, /* mov r2.a, c0.y */
11524 0x02000001, 0x80010002, 0xa0550000, /* mov r2.r, c0.y */
11525 0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001, /* cmp r2.g, r0.x, r1.x, r1.y */
11526 0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001, /* cmp r2.b, r0.y, r1.x, r1.y */
11527 0x02000001, 0x800f0800, 0x80e40002, /* mov oC0, r2 */
11528 0x0000ffff /* end */
11530 static const DWORD shader_frac_code[] =
11532 0xffff0300, /* ps_3_0 */
11533 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
11534 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
11535 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
11536 0x02000013, 0x80030000, 0x90541000, /* frc r0.xy, vPos.xy */
11537 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
11538 0x0000ffff /* end */
11540 static const DWORD vshader_code[] =
11542 0xfffe0300, /* vs_3_0 */
11543 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
11544 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
11545 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
11546 0x0000ffff /* end */
11548 static const float quad[] =
11550 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
11551 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
11552 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
11553 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
11555 float constant[4] = {1.0, 0.0, 320, 240};
11557 window = create_window();
11558 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11559 ok(!!d3d, "Failed to create a D3D object.\n");
11560 if (!(device = create_device(d3d, window, window, TRUE)))
11562 skip("Failed to create a D3D device, skipping tests.\n");
11563 goto done;
11566 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11567 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
11568 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
11570 skip("No shader model 3 support, skipping tests.\n");
11571 IDirect3DDevice9_Release(device);
11572 goto done;
11575 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
11576 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11577 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
11578 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11579 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
11580 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11581 hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
11582 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11583 hr = IDirect3DDevice9_SetPixelShader(device, shader);
11584 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11585 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
11586 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11587 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
11588 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11589 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
11590 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11592 hr = IDirect3DDevice9_BeginScene(device);
11593 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
11594 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
11595 ok(SUCCEEDED(hr), "Failed to set pixel shader constant, hr %#lx.\n", hr);
11596 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
11597 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
11598 hr = IDirect3DDevice9_EndScene(device);
11599 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
11601 /* This has to be pixel exact */
11602 color = getPixelColor(device, 319, 239);
11603 ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
11604 color = getPixelColor(device, 320, 239);
11605 ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
11606 color = getPixelColor(device, 319, 240);
11607 ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
11608 color = getPixelColor(device, 320, 240);
11609 ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
11610 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11612 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
11613 &surface, NULL);
11614 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11615 hr = IDirect3DDevice9_BeginScene(device);
11616 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
11617 constant[2] = 16; constant[3] = 16;
11618 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
11619 ok(SUCCEEDED(hr), "Failed to set pixel shader constant, hr %#lx.\n", hr);
11620 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
11621 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
11622 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
11623 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
11624 hr = IDirect3DDevice9_EndScene(device);
11625 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
11627 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
11628 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11630 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
11631 color = *pos & 0x00ffffff;
11632 ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
11633 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
11634 color = *pos & 0x00ffffff;
11635 ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
11636 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
11637 color = *pos & 0x00ffffff;
11638 ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
11639 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
11640 color = *pos & 0x00ffffff;
11641 ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
11643 hr = IDirect3DSurface9_UnlockRect(surface);
11644 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11646 /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
11647 * have full control over the multisampling setting inside this test
11649 hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
11650 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11651 hr = IDirect3DDevice9_BeginScene(device);
11652 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
11653 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
11654 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
11655 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
11656 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
11657 hr = IDirect3DDevice9_EndScene(device);
11658 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
11660 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11661 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11663 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
11664 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11666 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
11667 color = *pos & 0x00ffffff;
11668 ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
11670 hr = IDirect3DSurface9_UnlockRect(surface);
11671 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11673 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11674 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11675 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
11676 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11677 IDirect3DPixelShader9_Release(shader);
11678 IDirect3DPixelShader9_Release(shader_frac);
11679 IDirect3DVertexShader9_Release(vshader);
11680 if(surface) IDirect3DSurface9_Release(surface);
11681 IDirect3DSurface9_Release(backbuffer);
11682 refcount = IDirect3DDevice9_Release(device);
11683 ok(!refcount, "Device has %lu references left.\n", refcount);
11684 done:
11685 IDirect3D9_Release(d3d);
11686 DestroyWindow(window);
11689 static BOOL point_match(IDirect3DDevice9 *device, UINT x, UINT y, UINT r)
11691 D3DCOLOR color;
11693 color = D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
11694 if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
11695 if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
11696 if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
11697 if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
11699 ++r;
11700 color = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff);
11701 if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
11702 if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
11703 if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
11704 if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
11706 return TRUE;
11709 static void test_pointsize(void)
11711 static const float a = 1.0f, b = 1.0f, c = 1.0f;
11712 float ptsize, ptsizemax_orig, ptsizemin_orig;
11713 IDirect3DSurface9 *rt, *backbuffer;
11714 D3DADAPTER_IDENTIFIER9 identifier;
11715 IDirect3DTexture9 *tex1, *tex2;
11716 IDirect3DDevice9 *device;
11717 IDirect3DVertexShader9 *vs;
11718 IDirect3DPixelShader9 *ps;
11719 unsigned int color, i, j;
11720 D3DLOCKED_RECT lr;
11721 IDirect3D9 *d3d;
11722 ULONG refcount;
11723 D3DCAPS9 caps;
11724 HWND window;
11725 HRESULT hr;
11727 static const RECT rect = {0, 0, 128, 128};
11728 static const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000, 0x00000000, 0x00000000};
11729 static const DWORD tex2_data[4] = {0x00000000, 0x0000ff00, 0x00000000, 0x0000ff00};
11730 static const float vertices[] =
11732 64.0f, 64.0f, 0.1f,
11733 128.0f, 64.0f, 0.1f,
11734 192.0f, 64.0f, 0.1f,
11735 256.0f, 64.0f, 0.1f,
11736 320.0f, 64.0f, 0.1f,
11737 384.0f, 64.0f, 0.1f,
11738 448.0f, 64.0f, 0.1f,
11739 512.0f, 64.0f, 0.1f,
11741 static const struct
11743 float x, y, z;
11744 float point_size;
11746 vertex_pointsize = {64.0f, 64.0f, 0.1f, 48.0f},
11747 vertex_pointsize_scaled = {64.0f, 64.0f, 0.1f, 24.0f},
11748 vertex_pointsize_zero = {64.0f, 64.0f, 0.1f, 0.0f};
11749 /* Writing a texture coordinate from the shader is technically unnecessary, but is required
11750 * to make Windows AMD r500 drivers work. Without it, texture coordinates in the pixel
11751 * shaders are 0. */
11752 static const DWORD vshader_code[] =
11754 0xfffe0101, /* vs_1_1 */
11755 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
11756 0x00000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
11757 0x00000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
11758 0x00000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
11759 0x00000004, 0xc00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad oPos, v0.w, c3, r0 */
11760 0x00000001, 0xe00f0000, 0x90e40000, /* mov oT0, v0 */
11761 0x00000001, 0xe00f0001, 0x90e40000, /* mov oT1, v0 */
11762 0x0000ffff
11764 static const DWORD vshader_psize_code[] =
11766 0xfffe0101, /* vs_1_1 */
11767 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
11768 0x0000001f, 0x80000004, 0x900f0001, /* dcl_psize v1 */
11769 0x00000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
11770 0x00000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
11771 0x00000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
11772 0x00000004, 0xc00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad oPos, v0.w, c3, r0 */
11773 0x00000001, 0xc00f0002, 0x90000001, /* mov oPts, v1.x */
11774 0x00000001, 0xe00f0000, 0x90e40000, /* mov oT0, v0 */
11775 0x00000001, 0xe00f0001, 0x90e40000, /* mov oT1, v0 */
11776 0x0000ffff
11778 static const DWORD pshader_code[] =
11780 0xffff0101, /* ps_1_1 */
11781 0x00000042, 0xb00f0000, /* tex t0 */
11782 0x00000042, 0xb00f0001, /* tex t1 */
11783 0x00000002, 0x800f0000, 0xb0e40000, 0xb0e40001, /* add r0, t0, t1 */
11784 0x0000ffff
11786 static const DWORD pshader2_code[] =
11788 0xffff0200, /* ps_2_0 */
11789 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
11790 0x0200001f, 0x80000000, 0xb00f0001, /* dcl t1 */
11791 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
11792 0x0200001f, 0x90000000, 0xa00f0801, /* dcl_2d s1 */
11793 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
11794 0x03000042, 0x800f0001, 0xb0e40001, 0xa0e40801, /* texld r1, t1, s1 */
11795 0x03000002, 0x800f0000, 0x80e40000, 0x80e40001, /* add r0, r0, r1 */
11796 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
11797 0x0000ffff
11799 static const DWORD pshader2_zw_code[] =
11801 0xffff0200, /* ps_2_0 */
11802 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
11803 0x0200001f, 0x80000000, 0xb00f0001, /* dcl t1 */
11804 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
11805 0x0200001f, 0x90000000, 0xa00f0801, /* dcl_2d s1 */
11806 0x02000001, 0x80030000, 0xb01b0000, /* mov r0.xy, t0.wzyx */
11807 0x02000001, 0x80030001, 0xb01b0001, /* mov r1.xy, t1.wzyx */
11808 0x03000042, 0x800f0000, 0x80e40000, 0xa0e40800, /* texld r0, r0, s0 */
11809 0x03000042, 0x800f0001, 0x80e40001, 0xa0e40801, /* texld r1, r1, s1 */
11810 0x03000002, 0x800f0000, 0x80e40000, 0x80e40001, /* add r0, r0, r1 */
11811 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
11812 0x0000ffff
11814 static const DWORD vshader3_code[] =
11816 0xfffe0300, /* vs_3_0 */
11817 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
11818 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
11819 0x0200001f, 0x80000005, 0xe00f0001, /* dcl_texcoord0 o1 */
11820 0x0200001f, 0x80010005, 0xe00f0002, /* dcl_texcoord1 o2 */
11821 0x03000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
11822 0x04000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
11823 0x04000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
11824 0x04000004, 0xe00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad o0, v0.w, c3, r0 */
11825 0x02000001, 0xe00f0001, 0x90000000, /* mov o1, v0.x */
11826 0x02000001, 0xe00f0002, 0x90000000, /* mov o2, v0.x */
11827 0x0000ffff
11829 static const DWORD vshader3_psize_code[] =
11831 0xfffe0300, /* vs_3_0 */
11832 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
11833 0x0200001f, 0x80000004, 0x90010001, /* dcl_psize v1.x */
11834 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
11835 0x0200001f, 0x80000004, 0xe00f0001, /* dcl_psize o1 */
11836 0x0200001f, 0x80000005, 0xe00f0002, /* dcl_texcoord0 o2 */
11837 0x0200001f, 0x80010005, 0xe00f0003, /* dcl_texcoord1 o3 */
11838 0x03000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
11839 0x04000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
11840 0x04000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
11841 0x04000004, 0xe00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad o0, v0.w, c3, r0 */
11842 0x02000001, 0xe00f0001, 0x90000001, /* mov o1, v1.x */
11843 0x02000001, 0xe00f0002, 0x90000000, /* mov o2, v0.x */
11844 0x02000001, 0xe00f0003, 0x90000000, /* mov o3, v0.x */
11845 0x0000ffff
11847 static const DWORD pshader3_code[] =
11849 0xffff0300, /* ps_3_0 */
11850 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
11851 0x0200001f, 0x80010005, 0x900f0001, /* dcl_texcoord1 v1 */
11852 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
11853 0x0200001f, 0x90000000, 0xa00f0801, /* dcl_2d s1 */
11854 0x03000042, 0x800f0000, 0x90e40000, 0xa0e40800, /* texld r0, v0, s0 */
11855 0x03000042, 0x800f0001, 0x90e40001, 0xa0e40801, /* texld r1, v1, s1 */
11856 0x03000002, 0x800f0800, 0x80e40000, 0x80e40001, /* add oC0, r0, r1 */
11857 0x0000ffff
11859 static const DWORD pshader3_zw_code[] =
11861 0xffff0300, /* ps_3_0 */
11862 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
11863 0x0200001f, 0x80010005, 0x900f0001, /* dcl_texcoord1 v1 */
11864 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
11865 0x0200001f, 0x90000000, 0xa00f0801, /* dcl_2d s1 */
11866 0x03000042, 0x800f0000, 0x90fe0000, 0xa0e40800, /* texld r0, v0.zw, s0 */
11867 0x03000042, 0x800f0001, 0x90fe0001, 0xa0e40801, /* texld r1, v1.zw, s1 */
11868 0x03000002, 0x800f0800, 0x80e40000, 0x80e40001, /* add oC0, r0, r1 */
11869 0x0000ffff
11871 static const struct test_shader
11873 DWORD version;
11874 const DWORD *code;
11876 novs = {0, NULL},
11877 vs1 = {D3DVS_VERSION(1, 1), vshader_code},
11878 vs1_psize = {D3DVS_VERSION(1, 1), vshader_psize_code},
11879 vs3 = {D3DVS_VERSION(3, 0), vshader3_code},
11880 vs3_psize = {D3DVS_VERSION(3, 0), vshader3_psize_code},
11881 nops = {0, NULL},
11882 ps1 = {D3DPS_VERSION(1, 1), pshader_code},
11883 ps2 = {D3DPS_VERSION(2, 0), pshader2_code},
11884 ps2_zw = {D3DPS_VERSION(2, 0), pshader2_zw_code},
11885 ps3 = {D3DPS_VERSION(3, 0), pshader3_code},
11886 ps3_zw = {D3DPS_VERSION(3, 0), pshader3_zw_code};
11888 static const D3DVERTEXELEMENT9 decl_elements_psize[] =
11890 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
11891 {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_PSIZE, 0},
11892 D3DDECL_END()
11895 static const D3DVERTEXELEMENT9 decl_elements_no_psize[] =
11897 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
11898 D3DDECL_END()
11901 static const D3DVERTEXELEMENT9 decl_elements_missing_psize[] =
11903 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
11904 {1, 0, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_PSIZE, 0},
11905 D3DDECL_END()
11908 static const struct
11910 const struct test_shader *vs;
11911 const struct test_shader *ps;
11912 DWORD accepted_fvf;
11913 unsigned int nonscaled_size, scaled_size;
11914 BOOL gives_0_0_texcoord;
11915 BOOL broken_texcoord_u;
11917 test_setups[] =
11919 {&novs, &nops, D3DFVF_XYZ, 32, 45, FALSE, FALSE},
11920 {&vs1, &ps1, D3DFVF_XYZ, 32, 32, FALSE, FALSE},
11921 {&novs, &ps1, D3DFVF_XYZ, 32, 45, FALSE, FALSE},
11922 {&vs1, &nops, D3DFVF_XYZ, 32, 32, FALSE, FALSE},
11923 {&novs, &ps2, D3DFVF_XYZ, 32, 45, FALSE, TRUE},
11924 {&novs, &ps2_zw, D3DFVF_XYZ, 32, 45, TRUE, FALSE},
11925 {&vs1, &ps2, D3DFVF_XYZ, 32, 32, FALSE, TRUE},
11926 {&vs1, &ps2_zw, D3DFVF_XYZ, 32, 32, TRUE, FALSE},
11927 {&vs3, &ps3, D3DFVF_XYZ, 32, 32, FALSE, TRUE},
11928 {&vs3, &ps3_zw, D3DFVF_XYZ, 32, 32, TRUE, FALSE},
11929 {&novs, &nops, D3DFVF_XYZ | D3DFVF_PSIZE, 48, 33, FALSE, FALSE},
11930 {&vs1_psize, &ps1, D3DFVF_XYZ | D3DFVF_PSIZE, 48, 24, FALSE, FALSE},
11931 {&vs3_psize, &ps3, D3DFVF_XYZ | D3DFVF_PSIZE, 48, 24, FALSE, TRUE},
11934 static const struct
11936 BOOL zero_size;
11937 BOOL scale;
11938 BOOL override_min;
11939 const D3DVERTEXELEMENT9 *decl_elements;
11940 DWORD fvf;
11941 const void *vertex_data;
11942 unsigned int vertex_size;
11944 tests[] =
11946 {FALSE, FALSE, FALSE, NULL, D3DFVF_XYZ, vertices, sizeof(float) * 3},
11947 {FALSE, TRUE, FALSE, NULL, D3DFVF_XYZ, vertices, sizeof(float) * 3},
11948 {FALSE, FALSE, TRUE, NULL, D3DFVF_XYZ, vertices, sizeof(float) * 3},
11949 {TRUE, FALSE, FALSE, NULL, D3DFVF_XYZ, vertices, sizeof(float) * 3},
11950 {FALSE, FALSE, FALSE, NULL, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize, sizeof(vertex_pointsize)},
11951 {FALSE, TRUE, FALSE, NULL, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize_scaled, sizeof(vertex_pointsize_scaled)},
11952 {FALSE, FALSE, TRUE, NULL, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize, sizeof(vertex_pointsize)},
11953 {TRUE, FALSE, FALSE, NULL, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize_zero, sizeof(vertex_pointsize_zero)},
11954 {FALSE, FALSE, FALSE, decl_elements_no_psize, D3DFVF_XYZ, vertices, sizeof(float) * 3},
11955 {FALSE, FALSE, FALSE, decl_elements_psize, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize, sizeof(vertex_pointsize)},
11956 {FALSE, FALSE, FALSE, decl_elements_missing_psize, D3DFVF_XYZ, vertices, sizeof(float) * 3},
11957 {FALSE, FALSE, FALSE, decl_elements_missing_psize, D3DFVF_XYZ | D3DFVF_PSIZE, vertices, sizeof(float) * 3},
11960 /* Transforms the coordinate system [-1.0;1.0]x[1.0;-1.0] to
11961 * [0.0;0.0]x[640.0;480.0]. Z is untouched. */
11962 D3DMATRIX matrix =
11964 2.0f / 640.0f, 0.0f, 0.0f, 0.0f,
11965 0.0f, -2.0f / 480.0f, 0.0f, 0.0f,
11966 0.0f, 0.0f, 1.0f, 0.0f,
11967 -1.0f, 1.0f, 0.0f, 1.0f,
11968 }}};
11970 window = create_window();
11971 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11972 ok(!!d3d, "Failed to create a D3D object.\n");
11973 if (!(device = create_device(d3d, window, window, TRUE)))
11975 skip("Failed to create a D3D device, skipping tests.\n");
11976 goto done;
11979 hr = IDirect3D9_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
11980 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11982 memset(&caps, 0, sizeof(caps));
11983 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11984 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11985 if(caps.MaxPointSize < 32.0) {
11986 skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
11987 IDirect3DDevice9_Release(device);
11988 goto done;
11991 /* The r500 Windows driver needs a draw with regular texture coordinates at least once during the
11992 * device's lifetime, otherwise texture coordinate generation only works for texture 0. */
11993 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
11994 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11995 hr = IDirect3DDevice9_BeginScene(device);
11996 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
11997 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, vertices, sizeof(float) * 5);
11998 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
11999 hr = IDirect3DDevice9_EndScene(device);
12000 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
12002 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
12003 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12004 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12005 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
12006 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
12007 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12008 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
12009 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12011 hr = IDirect3DDevice9_BeginScene(device);
12012 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
12014 ptsize = 15.0f;
12015 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
12016 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
12017 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
12018 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
12020 ptsize = 31.0f;
12021 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
12022 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
12023 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
12024 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
12026 ptsize = 30.75f;
12027 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
12028 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
12029 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
12030 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
12032 if (caps.MaxPointSize >= 63.0f)
12034 ptsize = 63.0f;
12035 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
12036 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
12037 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
12038 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
12040 ptsize = 62.75f;
12041 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
12042 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
12043 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
12044 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
12047 ptsize = 1.0f;
12048 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
12049 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
12050 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
12051 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
12053 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *)&ptsizemax_orig);
12054 ok(SUCCEEDED(hr), "Failed to get render state, hr %#lx.\n", hr);
12055 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *)&ptsizemin_orig);
12056 ok(SUCCEEDED(hr), "Failed to get render state, hr %#lx.\n", hr);
12058 /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
12059 ptsize = 15.0f;
12060 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
12061 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
12062 ptsize = 1.0f;
12063 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *(DWORD *)&ptsize);
12064 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
12065 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
12066 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
12068 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *(DWORD *)&ptsizemax_orig);
12069 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
12071 /* pointsize < pointsize_min < pointsize_max?
12072 * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
12073 ptsize = 1.0f;
12074 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
12075 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
12076 ptsize = 15.0f;
12077 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsize);
12078 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
12079 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
12080 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
12082 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsizemin_orig);
12083 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
12085 hr = IDirect3DDevice9_EndScene(device);
12086 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
12088 ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
12089 ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
12090 ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
12092 if (caps.MaxPointSize >= 63.0)
12094 ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
12095 ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
12098 ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
12099 /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
12100 ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
12101 /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
12102 ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
12104 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12106 /* The following code tests point sprites with two textures, to see if each texture coordinate unit
12107 * generates texture coordinates for the point(result: Yes, it does)
12109 * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
12110 * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
12111 * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
12113 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
12114 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12116 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
12117 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12118 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
12119 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12120 memset(&lr, 0, sizeof(lr));
12121 hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
12122 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12123 memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
12124 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
12125 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12126 memset(&lr, 0, sizeof(lr));
12127 hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
12128 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12129 memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
12130 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
12131 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12132 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
12133 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12134 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
12135 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12136 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12137 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12138 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12139 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12140 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
12141 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12142 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12143 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12144 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
12145 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12147 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
12148 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12149 ptsize = 32.0;
12150 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
12151 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12153 hr = IDirect3DDevice9_BeginScene(device);
12154 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
12155 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
12156 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
12157 hr = IDirect3DDevice9_EndScene(device);
12158 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
12160 color = getPixelColor(device, 64-4, 64-4);
12161 ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
12162 color = getPixelColor(device, 64-4, 64+4);
12163 ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
12164 color = getPixelColor(device, 64+4, 64+4);
12165 ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
12166 color = getPixelColor(device, 64+4, 64-4);
12167 ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
12168 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12170 matrix.m[0][0] = 1.0f / 64.0f;
12171 matrix.m[1][1] = -1.0f / 64.0f;
12172 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
12173 ok(SUCCEEDED(hr), "SetTransform failed, hr %#lx.\n", hr);
12175 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
12176 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#lx.\n", hr);
12178 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
12179 D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL );
12180 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#lx.\n", hr);
12182 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSCALE_A, *(DWORD *)&a);
12183 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#lx.\n", hr);
12184 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSCALE_B, *(DWORD *)&b);
12185 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#lx.\n", hr);
12186 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSCALE_C, *(DWORD *)&c);
12187 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#lx.\n", hr);
12188 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
12190 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, &matrix._11, 4);
12191 ok(SUCCEEDED(hr), "Failed to set vertex shader constants, hr %#lx.\n", hr);
12194 if (caps.MaxPointSize < 63.0f)
12196 skip("MaxPointSize %f < 63.0, skipping some tests.\n", caps.MaxPointSize);
12197 goto cleanup;
12200 for (i = 0; i < ARRAY_SIZE(test_setups); ++i)
12202 winetest_push_context("Setup %u", i);
12204 if (caps.VertexShaderVersion < test_setups[i].vs->version
12205 || caps.PixelShaderVersion < test_setups[i].ps->version)
12207 skip("Vertex / pixel shader version not supported, skipping test.\n");
12208 winetest_pop_context();
12209 continue;
12211 if (test_setups[i].vs->code)
12213 hr = IDirect3DDevice9_CreateVertexShader(device, test_setups[i].vs->code, &vs);
12214 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#lx (case %u).\n", hr, i);
12216 else
12218 vs = NULL;
12220 if (test_setups[i].ps->code)
12222 hr = IDirect3DDevice9_CreatePixelShader(device, test_setups[i].ps->code, &ps);
12223 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#lx (case %u).\n", hr, i);
12225 else
12227 ps = NULL;
12230 hr = IDirect3DDevice9_SetVertexShader(device, vs);
12231 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
12232 hr = IDirect3DDevice9_SetPixelShader(device, ps);
12233 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
12235 for (j = 0; j < ARRAY_SIZE(tests); ++j)
12237 bool broken_texcoord_u = test_setups[i].broken_texcoord_u;
12238 unsigned int size = tests[j].override_min ? 63 : tests[j].zero_size ? 0 : tests[j].scale
12239 ? test_setups[i].scaled_size : test_setups[i].nonscaled_size;
12240 struct surface_readback rb;
12242 if (test_setups[i].accepted_fvf != tests[j].fvf)
12243 continue;
12245 if (tests[j].decl_elements == decl_elements_missing_psize)
12247 /* If PSIZE is referenced in the vertex declaration but the
12248 * corresponding buffer is not bound, the point size is
12249 * effectively either zero (NVidia) or one (AMD, WARP). */
12250 if (!vs || (test_setups[i].accepted_fvf & D3DFVF_PSIZE))
12251 size = 1;
12252 else
12253 size = 32;
12256 winetest_push_context("test %u (expected size %u)", j, size);
12258 ptsize = tests[j].zero_size ? 0.0f : 32.0f;
12259 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
12260 ok(SUCCEEDED(hr), "Failed to set pointsize, hr %#lx.\n", hr);
12262 ptsize = tests[j].override_min ? 63.0f : tests[j].zero_size ? 0.0f : ptsizemin_orig;
12263 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsize);
12264 ok(SUCCEEDED(hr), "Failed to set minimum pointsize, hr %#lx.\n", hr);
12266 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSCALEENABLE, tests[j].scale);
12267 ok(SUCCEEDED(hr), "Failed setting point scale state, hr %#lx.\n", hr);
12269 if (tests[j].decl_elements)
12271 IDirect3DVertexDeclaration9 *vertex_declaration;
12273 hr = IDirect3DDevice9_CreateVertexDeclaration(device, tests[j].decl_elements, &vertex_declaration);
12274 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12275 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
12276 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12277 IDirect3DVertexDeclaration9_Release(vertex_declaration);
12279 else
12281 hr = IDirect3DDevice9_SetFVF(device, tests[j].fvf);
12282 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12285 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12286 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
12287 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
12288 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
12290 hr = IDirect3DDevice9_BeginScene(device);
12291 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
12292 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1,
12293 tests[j].vertex_data, tests[j].vertex_size);
12294 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
12295 hr = IDirect3DDevice9_EndScene(device);
12296 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
12298 hr = IDirect3DDevice9_StretchRect(device, rt, &rect, backbuffer, &rect, D3DTEXF_NONE);
12299 ok(SUCCEEDED(hr), "Failed to blit, hr %#lx.\n", hr);
12300 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
12301 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
12303 get_rt_readback(backbuffer, &rb);
12305 if (size <= 1)
12307 unsigned int warp_colour = 0x0000ff00;
12309 if (test_setups[i].broken_texcoord_u)
12310 warp_colour = 0x00000000;
12311 else if (test_setups[i].gives_0_0_texcoord)
12312 warp_colour = 0x00ff0000;
12314 color = get_readback_color(&rb, 64, 64);
12315 if (size == 0)
12317 /* Windows on real hardware draws nothing. WARP draws one
12318 * pixel as if the point size was 1.
12320 * Technically 0 pointsize is undefined in OpenGL but in
12321 * practice it seems like it does the "useful" thing on all
12322 * the drivers I tried. */
12323 todo_wine_if(!color_match(color, 0xff00ffff, 0))
12324 ok(color == 0xff00ffff
12325 || broken(adapter_is_warp(&identifier) && color == warp_colour),
12326 "Got unexpected color 0x%08x at (64, 64).\n", color);
12328 else
12330 /* Exact colour varies based on texcoord, but we should get
12331 * a pixel drawn here. */
12332 ok(color != 0xff00ffff, "Got unexpected color 0x%08x at (64, 64).\n", color);
12335 color = get_readback_color(&rb, 63, 64);
12336 ok(color == 0xff00ffff, "Got unexpected color 0x%08x at (63, 64).\n", color);
12337 color = get_readback_color(&rb, 65, 64);
12338 ok(color == 0xff00ffff, "Got unexpected color 0x%08x at (65, 64).\n", color);
12339 color = get_readback_color(&rb, 64, 63);
12340 ok(color == 0xff00ffff, "Got unexpected color 0x%08x at (64, 63).\n", color);
12341 color = get_readback_color(&rb, 64, 65);
12342 ok(color == 0xff00ffff, "Got unexpected color 0x%08x at (64, 65).\n", color);
12344 else
12346 /* On AMD and WARP, apparently only the first texcoord is
12347 * modified by the point coordinates when using SM2/3 pixel
12348 * shaders. */
12350 for (unsigned int y = 0; y < 128; ++y)
12352 /* Skip the edges; coordinates are not pixel-exact. */
12353 if (y == 64 - size / 2 || y == 64 + size / 2 || y == 64)
12354 continue;
12356 for (unsigned int x = 0; x < 128; ++x)
12358 unsigned int expect = 0xff00ffff, broken_u = 0xff00ffff;
12360 /* Skip the edges; coordinates are not pixel-exact. */
12361 if (x == 64 - size / 2 || x == 64 + size / 2 || x == 64)
12362 continue;
12364 color = get_readback_color(&rb, x, y);
12366 if (x > 64 - size / 2 && x < 64 + size / 2
12367 && y > 64 - size / 2 && y < 64 + size / 2)
12370 if (test_setups[i].gives_0_0_texcoord)
12371 expect = broken_u = 0x00ff0000;
12372 else if (y < 64 && x < 64)
12373 expect = broken_u = 0x00ff0000;
12374 else if (y >= 64 && x < 64)
12375 expect = broken_u = 0x00000000;
12376 else if (y < 64 && x >= 64)
12378 expect = 0x00ffff00;
12379 broken_u = 0x00ff0000;
12381 else if (y >= 64 && x >= 64)
12383 expect = 0x0000ff00;
12384 broken_u = 0x00000000;
12388 if (!(color == expect || broken(test_setups[i].broken_texcoord_u && color == broken_u)))
12390 ok(0, "Expected 0x%08x, got 0x%08x at (%u, %u).\n", expect, color, x, y);
12391 goto stop;
12395 stop:
12397 color = get_readback_color(&rb, 64 - size / 2 + 1, 64 - size / 2 + 1);
12398 ok(color_match(color, 0x00ff0000, 0),
12399 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
12400 color = get_readback_color(&rb, 64 + size / 2 - 1, 64 - size / 2 + 1);
12401 ok(color_match(color, test_setups[i].gives_0_0_texcoord ? 0x00ff0000 : 0x00ffff00, 0)
12402 || (broken_texcoord_u && broken(color_match(color, 0x00ff0000, 0))),
12403 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
12404 color = get_readback_color(&rb, 64 - size / 2 + 1, 64 + size / 2 - 1);
12405 ok(color_match(color, test_setups[i].gives_0_0_texcoord ? 0x00ff0000 : 0x00000000, 0),
12406 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
12407 color = get_readback_color(&rb, 64 + size / 2 - 1, 64 + size / 2 - 1);
12408 ok(color_match(color, test_setups[i].gives_0_0_texcoord ? 0x00ff0000 : 0x0000ff00, 0)
12409 || (broken_texcoord_u && broken(color_match(color, 0x00000000, 0))),
12410 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
12412 color = get_readback_color(&rb, 64 - size / 2 - 1, 64 - size / 2 - 1);
12413 ok(color_match(color, 0xff00ffff, 0),
12414 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
12415 color = get_readback_color(&rb, 64 + size / 2 + 1, 64 - size / 2 - 1);
12416 ok(color_match(color, 0xff00ffff, 0),
12417 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
12418 color = get_readback_color(&rb, 64 - size / 2 - 1, 64 + size / 2 + 1);
12419 ok(color_match(color, 0xff00ffff, 0),
12420 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
12421 color = get_readback_color(&rb, 64 + size / 2 + 1, 64 + size / 2 + 1);
12422 ok(color_match(color, 0xff00ffff, 0),
12423 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
12426 release_surface_readback(&rb);
12428 winetest_pop_context();
12430 IDirect3DDevice9_SetVertexShader(device, NULL);
12431 IDirect3DDevice9_SetPixelShader(device, NULL);
12432 if (vs)
12433 IDirect3DVertexShader9_Release(vs);
12434 if (ps)
12435 IDirect3DVertexShader9_Release(ps);
12437 winetest_pop_context();
12440 cleanup:
12441 IDirect3DSurface9_Release(backbuffer);
12442 IDirect3DSurface9_Release(rt);
12444 IDirect3DTexture9_Release(tex1);
12445 IDirect3DTexture9_Release(tex2);
12446 refcount = IDirect3DDevice9_Release(device);
12447 ok(!refcount, "Device has %lu references left.\n", refcount);
12448 done:
12449 IDirect3D9_Release(d3d);
12450 DestroyWindow(window);
12453 static void multiple_rendertargets_test(void)
12455 IDirect3DSurface9 *surf1, *surf2, *backbuf, *readback;
12456 IDirect3DPixelShader9 *ps1, *ps2;
12457 IDirect3DTexture9 *tex1, *tex2;
12458 IDirect3DVertexShader9 *vs;
12459 IDirect3DDevice9 *device;
12460 unsigned int color, i, j;
12461 IDirect3D9 *d3d;
12462 ULONG refcount;
12463 D3DCAPS9 caps;
12464 HWND window;
12465 HRESULT hr;
12467 static const DWORD vshader_code[] =
12469 0xfffe0300, /* vs_3_0 */
12470 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
12471 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
12472 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
12473 0x0000ffff /* end */
12475 static const DWORD pshader_code1[] =
12477 0xffff0300, /* ps_3_0 */
12478 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
12479 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
12480 0x0000ffff /* end */
12482 static const DWORD pshader_code2[] =
12484 0xffff0300, /* ps_3_0 */
12485 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
12486 0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0.0, 0.0, 1.0, 0.0 */
12487 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
12488 0x02000001, 0x800f0801, 0xa0e40001, /* mov oC1, c1 */
12489 0x0000ffff /* end */
12491 static const float quad[] =
12493 -1.0f, -1.0f, 0.1f,
12494 -1.0f, 1.0f, 0.1f,
12495 1.0f, -1.0f, 0.1f,
12496 1.0f, 1.0f, 0.1f,
12498 static const float texquad[] =
12500 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
12501 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
12502 0.0f, -1.0f, 0.1f, 1.0f, 0.0f,
12503 0.0f, 1.0f, 0.1f, 1.0f, 1.0f,
12505 0.0f, -1.0f, 0.1f, 0.0f, 0.0f,
12506 0.0f, 1.0f, 0.1f, 0.0f, 1.0f,
12507 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
12508 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
12511 window = create_window();
12512 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12513 ok(!!d3d, "Failed to create a D3D object.\n");
12514 if (!(device = create_device(d3d, window, window, TRUE)))
12516 skip("Failed to create a D3D device, skipping tests.\n");
12517 goto done;
12520 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12521 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
12522 if (caps.NumSimultaneousRTs < 2)
12524 skip("Only 1 simultaneous render target supported, skipping MRT test.\n");
12525 IDirect3DDevice9_Release(device);
12526 goto done;
12528 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
12530 skip("No shader model 3 support, skipping tests.\n");
12531 IDirect3DDevice9_Release(device);
12532 goto done;
12535 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
12536 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12538 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 16, 16,
12539 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
12540 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed, hr %#lx.\n", hr);
12542 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
12543 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
12544 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12545 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
12546 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
12547 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12548 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vs);
12549 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#lx.\n", hr);
12550 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code1, &ps1);
12551 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#lx.\n", hr);
12552 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code2, &ps2);
12553 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#lx.\n", hr);
12555 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
12556 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12557 hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
12558 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12559 hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
12560 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12562 hr = IDirect3DDevice9_SetVertexShader(device, vs);
12563 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#lx.\n", hr);
12564 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
12565 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12566 hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
12567 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12568 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
12569 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12571 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
12572 ok(SUCCEEDED(hr), "Clear failed, hr %#lx,\n", hr);
12573 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
12574 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#lx.\n", hr);
12575 color = getPixelColorFromSurface(readback, 8, 8);
12576 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
12577 "Expected color 0x000000ff, got 0x%08x.\n", color);
12578 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
12579 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#lx.\n", hr);
12580 color = getPixelColorFromSurface(readback, 8, 8);
12581 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
12582 "Expected color 0x000000ff, got 0x%08x.\n", color);
12584 /* Render targets not written by the pixel shader should be unmodified. */
12585 hr = IDirect3DDevice9_SetPixelShader(device, ps1);
12586 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
12587 hr = IDirect3DDevice9_BeginScene(device);
12588 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
12589 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
12590 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
12591 hr = IDirect3DDevice9_EndScene(device);
12592 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
12593 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
12594 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#lx.\n", hr);
12595 color = getPixelColorFromSurface(readback, 8, 8);
12596 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
12597 "Expected color 0xff00ff00, got 0x%08x.\n", color);
12598 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
12599 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#lx.\n", hr);
12600 for (i = 6; i < 10; ++i)
12602 for (j = 6; j < 10; ++j)
12604 color = getPixelColorFromSurface(readback, j, i);
12605 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
12606 "Expected color 0xff0000ff, got 0x%08x at %u, %u.\n", color, j, i);
12610 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
12611 ok(SUCCEEDED(hr), "Clear failed, hr %#lx,\n", hr);
12612 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
12613 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#lx.\n", hr);
12614 color = getPixelColorFromSurface(readback, 8, 8);
12615 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
12616 "Expected color 0x0000ff00, got 0x%08x.\n", color);
12617 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
12618 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#lx.\n", hr);
12619 color = getPixelColorFromSurface(readback, 8, 8);
12620 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
12621 "Expected color 0x0000ff00, got 0x%08x.\n", color);
12623 hr = IDirect3DDevice9_SetPixelShader(device, ps2);
12624 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
12626 hr = IDirect3DDevice9_BeginScene(device);
12627 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
12629 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
12630 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
12632 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12633 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
12634 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
12635 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
12636 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12637 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
12638 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
12639 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
12640 hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
12641 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
12642 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
12643 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
12645 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
12646 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
12647 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
12648 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
12650 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
12651 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
12652 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
12653 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
12655 hr = IDirect3DDevice9_EndScene(device);
12656 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
12658 color = getPixelColor(device, 160, 240);
12659 ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
12660 color = getPixelColor(device, 480, 240);
12661 ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
12662 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12664 IDirect3DPixelShader9_Release(ps2);
12665 IDirect3DPixelShader9_Release(ps1);
12666 IDirect3DVertexShader9_Release(vs);
12667 IDirect3DTexture9_Release(tex1);
12668 IDirect3DTexture9_Release(tex2);
12669 IDirect3DSurface9_Release(surf1);
12670 IDirect3DSurface9_Release(surf2);
12671 IDirect3DSurface9_Release(backbuf);
12672 IDirect3DSurface9_Release(readback);
12673 refcount = IDirect3DDevice9_Release(device);
12674 ok(!refcount, "Device has %lu references left.\n", refcount);
12675 done:
12676 IDirect3D9_Release(d3d);
12677 DestroyWindow(window);
12680 static void pixelshader_blending_test(void)
12682 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
12683 IDirect3DTexture9 *offscreenTexture = NULL;
12684 unsigned int fmt_index, color;
12685 IDirect3DDevice9 *device;
12686 IDirect3D9 *d3d;
12687 ULONG refcount;
12688 HWND window;
12689 HRESULT hr;
12691 static const struct
12693 const char *fmtName;
12694 D3DFORMAT textureFormat;
12695 unsigned int resultColorBlending, resultColorNoBlending;
12697 test_formats[] =
12699 {"D3DFMT_G16R16", D3DFMT_G16R16, 0x001820ff, 0x002010ff},
12700 {"D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff},
12701 {"D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001820ff, 0x002010ff},
12702 {"D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00182000, 0x00201000},
12703 {"D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff},
12704 {"D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001820ff, 0x002010ff},
12705 {"D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00182000, 0x00201000},
12706 {"D3DFMT_L8", D3DFMT_L8, 0x00181818, 0x00202020},
12708 static const float quad[][5] =
12710 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
12711 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
12712 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
12713 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
12715 static const struct
12717 struct vec3 position;
12718 DWORD diffuse;
12720 quad1[] =
12722 {{-1.0f, -1.0f, 0.1f}, 0x80103000},
12723 {{-1.0f, 1.0f, 0.1f}, 0x80103000},
12724 {{ 1.0f, -1.0f, 0.1f}, 0x80103000},
12725 {{ 1.0f, 1.0f, 0.1f}, 0x80103000},
12727 quad2[] =
12729 {{-1.0f, -1.0f, 0.1f}, 0x80201000},
12730 {{-1.0f, 1.0f, 0.1f}, 0x80201000},
12731 {{ 1.0f, -1.0f, 0.1f}, 0x80201000},
12732 {{ 1.0f, 1.0f, 0.1f}, 0x80201000},
12735 window = create_window();
12736 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12737 ok(!!d3d, "Failed to create a D3D object.\n");
12738 if (!(device = create_device(d3d, window, window, TRUE)))
12740 skip("Failed to create a D3D device, skipping tests.\n");
12741 goto done;
12744 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
12745 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12747 for (fmt_index = 0; fmt_index < ARRAY_SIZE(test_formats); ++fmt_index)
12749 D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
12751 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
12752 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, fmt) != D3D_OK)
12754 skip("%s textures not supported as render targets.\n", test_formats[fmt_index].fmtName);
12755 continue;
12758 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
12759 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12761 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
12762 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
12763 if(!offscreenTexture) {
12764 continue;
12767 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
12768 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12769 if(!offscreen) {
12770 continue;
12773 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12774 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12776 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12777 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12778 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12779 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12780 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
12781 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12782 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
12783 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12784 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12785 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12787 /* Below we will draw two quads with different colors and try to blend
12788 * them together. The result color is compared with the expected
12789 * outcome. */
12790 hr = IDirect3DDevice9_BeginScene(device);
12791 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
12793 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
12794 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
12795 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 1.0f, 0);
12796 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
12798 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
12799 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
12801 /* Draw a quad using color 0x0010200. */
12802 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
12803 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
12804 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
12805 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
12806 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
12807 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
12809 /* Draw a quad using color 0x0020100. */
12810 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
12811 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
12812 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
12813 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
12814 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
12815 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
12817 /* We don't want to blend the result on the backbuffer. */
12818 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
12819 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
12821 /* Prepare rendering the 'blended' texture quad to the backbuffer. */
12822 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
12823 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
12824 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)offscreenTexture);
12825 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
12827 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
12828 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
12830 /* This time with the texture. */
12831 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
12832 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
12834 hr = IDirect3DDevice9_EndScene(device);
12835 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
12837 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
12838 D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK)
12840 /* Compare the color of the center quad with our expectation. */
12841 color = getPixelColor(device, 320, 240);
12842 ok(color_match(color, test_formats[fmt_index].resultColorBlending, 1),
12843 "Offscreen failed for %s: Got color 0x%08x, expected 0x%08x.\n",
12844 test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
12846 else
12848 /* No pixel shader blending is supported so expect garbage. The
12849 * type of 'garbage' depends on the driver version and OS. E.g. on
12850 * G16R16 ATI reports (on old r9600 drivers) 0x00ffffff and on
12851 * modern ones 0x002010ff which is also what NVIDIA reports. On
12852 * Vista NVIDIA seems to report 0x00ffffff on Geforce7 cards. */
12853 color = getPixelColor(device, 320, 240);
12854 ok((color == 0x00ffffff) || (color == test_formats[fmt_index].resultColorNoBlending),
12855 "Offscreen failed for %s: Got unexpected color 0x%08x, expected no color blending.\n",
12856 test_formats[fmt_index].fmtName, color);
12858 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12860 IDirect3DDevice9_SetTexture(device, 0, NULL);
12861 if(offscreenTexture) {
12862 IDirect3DTexture9_Release(offscreenTexture);
12864 if(offscreen) {
12865 IDirect3DSurface9_Release(offscreen);
12869 IDirect3DSurface9_Release(backbuffer);
12870 refcount = IDirect3DDevice9_Release(device);
12871 ok(!refcount, "Device has %lu references left.\n", refcount);
12872 done:
12873 IDirect3D9_Release(d3d);
12874 DestroyWindow(window);
12877 static void tssargtemp_test(void)
12879 IDirect3DDevice9 *device;
12880 unsigned int color;
12881 IDirect3D9 *d3d;
12882 ULONG refcount;
12883 D3DCAPS9 caps;
12884 HWND window;
12885 HRESULT hr;
12887 static const struct
12889 struct vec3 position;
12890 DWORD diffuse;
12892 quad[] =
12894 {{-1.0f, -1.0f, 0.1f}, 0x00ff0000},
12895 {{-1.0f, 1.0f, 0.1f}, 0x00ff0000},
12896 {{ 1.0f, -1.0f, 0.1f}, 0x00ff0000},
12897 {{ 1.0f, 1.0f, 0.1f}, 0x00ff0000},
12900 window = create_window();
12901 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12902 ok(!!d3d, "Failed to create a D3D object.\n");
12903 if (!(device = create_device(d3d, window, window, TRUE)))
12905 skip("Failed to create a D3D device, skipping tests.\n");
12906 goto done;
12909 memset(&caps, 0, sizeof(caps));
12910 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12911 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12912 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
12913 skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
12914 IDirect3DDevice9_Release(device);
12915 goto done;
12918 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
12919 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12921 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12922 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12923 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
12924 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12926 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12927 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12928 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
12929 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12930 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
12931 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12933 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
12934 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12935 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
12936 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12937 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
12938 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12940 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
12941 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12943 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
12944 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12945 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12946 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
12947 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12948 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12950 hr = IDirect3DDevice9_BeginScene(device);
12951 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
12952 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
12953 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
12954 hr = IDirect3DDevice9_EndScene(device);
12955 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
12957 color = getPixelColor(device, 320, 240);
12958 ok(color == 0x00ffff00, "TSSARGTEMP test returned color 0x%08x, expected 0x00ffff00\n", color);
12959 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12961 refcount = IDirect3DDevice9_Release(device);
12962 ok(!refcount, "Device has %lu references left.\n", refcount);
12963 done:
12964 IDirect3D9_Release(d3d);
12965 DestroyWindow(window);
12968 /* Drawing Indexed Geometry with instances*/
12969 static void stream_test(void)
12971 IDirect3DVertexDeclaration9 *pDecl = NULL;
12972 IDirect3DVertexShader9 *shader = NULL;
12973 IDirect3DVertexBuffer9 *vb3 = NULL;
12974 IDirect3DVertexBuffer9 *vb2 = NULL;
12975 IDirect3DVertexBuffer9 *vb = NULL;
12976 IDirect3DIndexBuffer9 *ib = NULL;
12977 unsigned int color, ind, i;
12978 IDirect3DDevice9 *device;
12979 IDirect3D9 *d3d;
12980 ULONG refcount;
12981 D3DCAPS9 caps;
12982 HWND window;
12983 HRESULT hr;
12984 BYTE *data;
12986 static const struct testdata
12988 DWORD idxVertex; /* number of instances in the first stream */
12989 DWORD idxColor; /* number of instances in the second stream */
12990 DWORD idxInstance; /* should be 1 ?? */
12991 unsigned int color1, color2, color3, color4;
12992 WORD strVertex; /* specify which stream to use 0-2*/
12993 WORD strColor;
12994 WORD strInstance;
12995 DWORD explicit_zero_freq;
12997 testcases[]=
12999 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 0 */
13000 {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 1 */
13001 {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 2 */
13002 {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 3 */
13003 {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 4 */
13004 {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 5 */
13005 {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 6 */
13006 {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 7 */
13007 {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 8 */
13008 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 9 */
13009 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 10 */
13010 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 11 */
13012 /* The number of instances is read from stream zero, even if stream zero is not
13013 * in use. Exact behavior of this corner case depends on the presence or absence
13014 * of D3DSTREAMSOURCE_INDEXEDDATA. r500 GPUs need D3DSTREAMSOURCE_INDEXEDDATA
13015 * to be present, otherwise they disable instancing and behave like in a non-
13016 * instanced draw. Nvidia drivers do not show different behavior with or without
13017 * D3DSTREAMSOURCE_INDEXEDDATA. Note however that setting the value to 0 is not
13018 * allowed by the d3d runtime.
13020 * The meaning of (D3DSTREAMSOURCE_INDEXEDDATA | 0) is driver dependent. r500
13021 * will fall back to non-instanced drawing. Geforce 7 will draw 1 instance.
13022 * Geforce 8+ will draw nothing. */
13023 {3, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1, 1}, /* 12 */
13024 {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 2, 3, 1, 2}, /* 13 */
13025 {1, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 2, 3, 1, 3}, /* 14 */
13026 {0, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 3, 1, 4}, /* 15 */
13028 static const DWORD shader_code[] =
13030 0xfffe0101, /* vs_1_1 */
13031 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
13032 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
13033 0x0000001f, 0x80000005, 0x900f0002, /* dcl_texcoord v2 */
13034 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
13035 0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
13036 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
13037 0x0000ffff
13039 /* Note that this set of coordinates and instancepos[] have an implicit
13040 * w = 1.0, which is added to w = 2.0, so the perspective divide divides
13041 * x, y and z by 2. */
13042 static const float quad[][3] =
13044 {-0.5f, -0.5f, 1.1f}, /*0 */
13045 {-0.5f, 0.5f, 1.1f}, /*1 */
13046 { 0.5f, -0.5f, 1.1f}, /*2 */
13047 { 0.5f, 0.5f, 1.1f}, /*3 */
13049 static const float vertcolor[][4] =
13051 {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
13052 {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
13053 {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
13054 {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
13056 /* 4 position for 4 instances */
13057 static const float instancepos[][3] =
13059 {-0.6f,-0.6f, 0.0f},
13060 { 0.6f,-0.6f, 0.0f},
13061 { 0.6f, 0.6f, 0.0f},
13062 {-0.6f, 0.6f, 0.0f},
13064 static const short indices[] = {0, 1, 2, 2, 1, 3};
13065 D3DVERTEXELEMENT9 decl[] =
13067 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
13068 {1, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
13069 {2, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
13070 D3DDECL_END()
13073 window = create_window();
13074 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13075 ok(!!d3d, "Failed to create a D3D object.\n");
13076 if (!(device = create_device(d3d, window, window, TRUE)))
13078 skip("Failed to create a D3D device, skipping tests.\n");
13079 goto done;
13082 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13083 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
13084 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
13086 skip("No vs_3_0 support, skipping tests.\n");
13087 IDirect3DDevice9_Release(device);
13088 goto done;
13091 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 0, &ind);
13092 ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq unexpected result, "
13093 "hr %#lx, ind %#x.\n", hr, ind);
13094 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
13095 ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq unexpected result, "
13096 "hr %#lx, ind %#x.\n", hr, ind);
13098 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
13099 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed, hr %#lx.\n", hr);
13101 /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
13102 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
13103 ok(hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
13105 /* check wrong cases */
13106 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
13107 ok(hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
13108 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
13109 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
13110 ok(ind == 1, "Got frequency %#x.\n", ind);
13111 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
13112 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13113 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
13114 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
13115 ok(ind == 2, "Got frequency %#x.\n", ind);
13116 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
13117 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13118 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
13119 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
13120 ok(ind == D3DSTREAMSOURCE_INDEXEDDATA, "Got frequency %#x.\n", ind);
13121 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
13122 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13123 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
13124 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
13125 ok(ind == D3DSTREAMSOURCE_INSTANCEDATA, "Got frequency %#x.\n", ind);
13126 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
13127 ok(hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
13128 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
13129 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
13130 ok(ind == D3DSTREAMSOURCE_INSTANCEDATA, "Got frequency %#x.\n", ind);
13132 /* set the default value back */
13133 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
13134 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13136 /* create all VertexBuffers*/
13137 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
13138 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13139 if(!vb) {
13140 skip("Failed to create a vertex buffer\n");
13141 IDirect3DDevice9_Release(device);
13142 goto done;
13144 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
13145 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13146 if(!vb2) {
13147 skip("Failed to create a vertex buffer\n");
13148 goto out;
13150 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
13151 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13152 if(!vb3) {
13153 skip("Failed to create a vertex buffer\n");
13154 goto out;
13157 /* create IndexBuffer*/
13158 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
13159 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13160 if(!ib) {
13161 skip("Failed to create an index buffer\n");
13162 goto out;
13165 /* copy all Buffers (Vertex + Index)*/
13166 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
13167 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13168 memcpy(data, quad, sizeof(quad));
13169 hr = IDirect3DVertexBuffer9_Unlock(vb);
13170 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13171 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
13172 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13173 memcpy(data, vertcolor, sizeof(vertcolor));
13174 hr = IDirect3DVertexBuffer9_Unlock(vb2);
13175 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13176 hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
13177 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13178 memcpy(data, instancepos, sizeof(instancepos));
13179 hr = IDirect3DVertexBuffer9_Unlock(vb3);
13180 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13181 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
13182 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13183 memcpy(data, indices, sizeof(indices));
13184 hr = IDirect3DIndexBuffer9_Unlock(ib);
13185 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13187 /* create VertexShader */
13188 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
13189 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13190 if(!shader) {
13191 skip("Failed to create a vertex shader.\n");
13192 goto out;
13195 hr = IDirect3DDevice9_SetVertexShader(device, shader);
13196 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13198 hr = IDirect3DDevice9_SetIndices(device, ib);
13199 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13201 /* run all tests */
13202 for( i = 0; i < ARRAY_SIZE(testcases); ++i)
13204 struct testdata act = testcases[i];
13205 decl[0].Stream = act.strVertex;
13206 decl[1].Stream = act.strColor;
13207 decl[2].Stream = act.strInstance;
13208 /* create VertexDeclarations */
13209 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
13210 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13212 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
13213 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13215 hr = IDirect3DDevice9_BeginScene(device);
13216 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
13218 hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
13219 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
13221 /* If stream 0 is unused, set the stream frequency regardless to show
13222 * that the number if instances is read from it. */
13223 if (act.strVertex && act.strColor && act.strInstance)
13225 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0,
13226 D3DSTREAMSOURCE_INDEXEDDATA | act.explicit_zero_freq);
13227 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#lx.\n", hr);
13230 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex,
13231 (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
13232 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#lx.\n", hr);
13233 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
13234 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#lx.\n", hr);
13236 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor,
13237 (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
13238 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#lx.\n", hr);
13239 hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
13240 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#lx.\n", hr);
13242 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance,
13243 (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
13244 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#lx.\n", hr);
13245 hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
13246 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#lx.\n", hr);
13248 /* Non-indexed draw test. Only a single instance should be drawn. */
13249 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLELIST, 0, 1);
13250 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
13252 hr = IDirect3DDevice9_EndScene(device);
13253 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
13255 /* Check that only single triangle instance has beed drawn with non-indexed draw. */
13256 color = getPixelColor(device, 200, 340);
13257 ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
13258 color = getPixelColor(device, 400, 340);
13259 ok(color == 0x00ffffff, "has color 0x%08x, expected 0x%08x (case %i)\n", color, 0x00ffffff, i);
13260 color = getPixelColor(device, 400, 180);
13261 ok(color == 0x00ffffff, "has color 0x%08x, expected 0x%08x (case %i)\n", color, 0x00ffffff, i);
13262 color = getPixelColor(device, 200, 180);
13263 ok(color == 0x00ffffff, "has color 0x%08x, expected 0x%08x (case %i)\n", color, 0x00ffffff, i);
13265 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13266 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13268 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
13269 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13271 hr = IDirect3DDevice9_BeginScene(device);
13272 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
13274 /* Indexed draw test. */
13275 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
13276 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
13277 hr = IDirect3DDevice9_EndScene(device);
13278 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
13280 /* set all StreamSource && StreamSourceFreq back to default */
13281 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
13282 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#lx.\n", hr);
13283 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
13284 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#lx.\n", hr);
13285 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
13286 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#lx.\n", hr);
13287 hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
13288 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#lx.\n", hr);
13289 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
13290 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#lx.\n", hr);
13291 hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
13292 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#lx.\n", hr);
13294 hr = IDirect3DVertexDeclaration9_Release(pDecl);
13295 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13297 color = getPixelColor(device, 160, 360);
13298 ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
13299 color = getPixelColor(device, 480, 360);
13300 ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
13301 color = getPixelColor(device, 480, 120);
13302 ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
13303 color = getPixelColor(device, 160, 120);
13304 ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
13306 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13307 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13310 out:
13311 if(vb) IDirect3DVertexBuffer9_Release(vb);
13312 if(vb2)IDirect3DVertexBuffer9_Release(vb2);
13313 if(vb3)IDirect3DVertexBuffer9_Release(vb3);
13314 if(ib)IDirect3DIndexBuffer9_Release(ib);
13315 if(shader)IDirect3DVertexShader9_Release(shader);
13316 refcount = IDirect3DDevice9_Release(device);
13317 ok(!refcount, "Device has %lu references left.\n", refcount);
13318 done:
13319 IDirect3D9_Release(d3d);
13320 DestroyWindow(window);
13323 static void np2_stretch_rect_test(void)
13325 IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
13326 IDirect3DTexture9 *dsttex = NULL;
13327 IDirect3DDevice9 *device;
13328 unsigned int color;
13329 IDirect3D9 *d3d;
13330 ULONG refcount;
13331 HWND window;
13332 HRESULT hr;
13334 static const D3DRECT r1 = {0, 0, 50, 50 };
13335 static const D3DRECT r2 = {50, 0, 100, 50 };
13336 static const D3DRECT r3 = {50, 50, 100, 100};
13337 static const D3DRECT r4 = {0, 50, 50, 100};
13338 static const float quad[] =
13340 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
13341 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
13342 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
13343 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
13346 window = create_window();
13347 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13348 ok(!!d3d, "Failed to create a D3D object.\n");
13349 if (!(device = create_device(d3d, window, window, TRUE)))
13351 skip("Failed to create a D3D device, skipping tests.\n");
13352 goto done;
13355 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
13356 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13358 hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
13359 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
13360 hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
13361 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
13363 if(!src || !dsttex) {
13364 skip("One or more test resources could not be created\n");
13365 goto cleanup;
13368 hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
13369 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13371 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
13372 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13374 /* Clear the StretchRect destination for debugging */
13375 hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
13376 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13377 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
13378 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13380 hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
13381 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13383 hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
13384 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13385 hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
13386 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13387 hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
13388 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13389 hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
13390 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13392 /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
13393 * the target -> texture GL blit path
13395 hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
13396 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13397 IDirect3DSurface9_Release(dst);
13399 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
13400 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13402 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
13403 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13404 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
13405 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13406 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
13407 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13408 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
13409 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13411 hr = IDirect3DDevice9_BeginScene(device);
13412 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
13413 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
13414 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
13415 hr = IDirect3DDevice9_EndScene(device);
13416 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
13418 color = getPixelColor(device, 160, 360);
13419 ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
13420 color = getPixelColor(device, 480, 360);
13421 ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
13422 color = getPixelColor(device, 480, 120);
13423 ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
13424 color = getPixelColor(device, 160, 120);
13425 ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
13426 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13427 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13429 cleanup:
13430 if(src) IDirect3DSurface9_Release(src);
13431 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
13432 if(dsttex) IDirect3DTexture9_Release(dsttex);
13433 refcount = IDirect3DDevice9_Release(device);
13434 ok(!refcount, "Device has %lu references left.\n", refcount);
13435 done:
13436 IDirect3D9_Release(d3d);
13437 DestroyWindow(window);
13440 static void texop_test(void)
13442 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
13443 IDirect3DTexture9 *texture = NULL;
13444 D3DLOCKED_RECT locked_rect;
13445 IDirect3DDevice9 *device;
13446 unsigned int color, i;
13447 IDirect3D9 *d3d;
13448 ULONG refcount;
13449 D3DCAPS9 caps;
13450 HWND window;
13451 HRESULT hr;
13453 static const struct {
13454 float x, y, z;
13455 float s, t;
13456 D3DCOLOR diffuse;
13457 } quad[] = {
13458 {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
13459 {-1.0f, 1.0f, 0.1f, -1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
13460 { 1.0f, -1.0f, 0.1f, 1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
13461 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
13464 static const D3DVERTEXELEMENT9 decl_elements[] = {
13465 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
13466 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
13467 {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
13468 D3DDECL_END()
13471 static const struct {
13472 D3DTEXTUREOP op;
13473 const char *name;
13474 DWORD caps_flag;
13475 unsigned int result;
13476 } test_data[] = {
13477 {D3DTOP_SELECTARG1, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
13478 {D3DTOP_SELECTARG2, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
13479 {D3DTOP_MODULATE, "MODULATE", D3DTEXOPCAPS_MODULATE, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
13480 {D3DTOP_MODULATE2X, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
13481 {D3DTOP_MODULATE4X, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
13482 {D3DTOP_ADD, "ADD", D3DTEXOPCAPS_ADD, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
13483 {D3DTOP_ADDSIGNED, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
13484 {D3DTOP_ADDSIGNED2X, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
13485 {D3DTOP_SUBTRACT, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
13486 {D3DTOP_ADDSMOOTH, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
13487 {D3DTOP_BLENDDIFFUSEALPHA, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
13488 {D3DTOP_BLENDTEXTUREALPHA, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
13489 {D3DTOP_BLENDFACTORALPHA, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
13490 {D3DTOP_BLENDTEXTUREALPHAPM, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
13491 {D3DTOP_BLENDCURRENTALPHA, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
13492 {D3DTOP_MODULATEALPHA_ADDCOLOR, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
13493 {D3DTOP_MODULATECOLOR_ADDALPHA, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
13494 {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
13495 {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
13496 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
13497 {D3DTOP_DOTPRODUCT3, "DOTPRODUCT3", D3DTEXOPCAPS_DOTPRODUCT3, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
13498 {D3DTOP_MULTIPLYADD, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
13499 {D3DTOP_LERP, "LERP", D3DTEXOPCAPS_LERP, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
13502 window = create_window();
13503 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13504 ok(!!d3d, "Failed to create a D3D object.\n");
13505 if (!(device = create_device(d3d, window, window, TRUE)))
13507 skip("Failed to create a D3D device, skipping tests.\n");
13508 goto done;
13511 memset(&caps, 0, sizeof(caps));
13512 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13513 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13515 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
13516 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13517 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
13518 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13520 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
13521 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13522 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
13523 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13524 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
13525 hr = IDirect3DTexture9_UnlockRect(texture, 0);
13526 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13527 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
13528 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13530 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
13531 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13532 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
13533 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13534 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
13535 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13537 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
13538 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13540 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13541 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13542 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
13543 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13544 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
13545 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13547 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
13548 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13550 for (i = 0; i < ARRAY_SIZE(test_data); ++i)
13552 if (!(caps.TextureOpCaps & test_data[i].caps_flag))
13554 skip("tex operation %s not supported\n", test_data[i].name);
13555 continue;
13558 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
13559 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13561 hr = IDirect3DDevice9_BeginScene(device);
13562 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13564 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13565 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13567 hr = IDirect3DDevice9_EndScene(device);
13568 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13570 color = getPixelColor(device, 320, 240);
13571 ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
13572 test_data[i].name, color, test_data[i].result);
13574 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13575 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13578 IDirect3DTexture9_Release(texture);
13579 IDirect3DVertexDeclaration9_Release(vertex_declaration);
13580 refcount = IDirect3DDevice9_Release(device);
13581 ok(!refcount, "Device has %lu references left.\n", refcount);
13582 done:
13583 IDirect3D9_Release(d3d);
13584 DestroyWindow(window);
13587 static void yuv_color_test(void)
13589 HRESULT hr;
13590 IDirect3DSurface9 *surface, *target;
13591 D3DLOCKED_RECT lr;
13592 IDirect3D9 *d3d;
13593 D3DFORMAT skip_once = D3DFMT_UNKNOWN;
13594 IDirect3DDevice9 *device;
13595 unsigned int color, i;
13596 D3DSURFACE_DESC desc;
13597 ULONG refcount;
13598 HWND window;
13600 static const struct
13602 unsigned int in;
13603 D3DFORMAT format;
13604 const char *fmt_string;
13605 unsigned int left, right;
13607 test_data[] =
13609 {0x00000000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00008700, 0x00008700},
13610 {0xff000000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00008700, 0x004bff1c},
13611 {0x00ff0000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b30000, 0x00b30000},
13612 {0x0000ff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x004bff1c, 0x00008700},
13613 {0x000000ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x000030e1, 0x000030e1},
13614 {0xffff0000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b30000, 0x00ffd01c},
13615 {0xff00ff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x004bff1c, 0x004bff1c},
13616 {0xff0000ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x000030e1, 0x004bffff},
13617 {0x00ffff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ffd01c, 0x00b30000},
13618 {0x00ff00ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b300e1, 0x00b300e1},
13619 {0x0000ffff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x004bffff, 0x001030e1},
13620 {0xffffff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ffd01c, 0x00ffd01c},
13621 {0xffff00ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b300e1, 0x00ff79ff},
13622 {0xffffffff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ff79ff, 0x00ff79ff},
13623 {0x4cff4c54, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ff0000, 0x00ff0000},
13624 {0x00800080, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00000000, 0x00000000},
13625 {0xff80ff80, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ffffff, 0x00ffffff},
13626 {0x1c6b1cff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x000000fd, 0x000000fd},
13628 {0x00000000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00008700, 0x00008700},
13629 {0xff000000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b30000, 0x00b30000},
13630 {0x00ff0000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00008700, 0x004bff1c},
13631 {0x0000ff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x000030e1, 0x000030e1},
13632 {0x000000ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x004bff1c, 0x00008700},
13633 {0xffff0000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b30000, 0x00ffd01c},
13634 {0xff00ff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b300e1, 0x00b300e1},
13635 {0xff0000ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ffd01c, 0x00b30000},
13636 {0x00ffff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x000030e1, 0x004bffff},
13637 {0x00ff00ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x004bff1c, 0x004bff1c},
13638 {0x0000ffff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x004bffff, 0x000030e1},
13639 {0xffffff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b300e1, 0x00ff79ff},
13640 {0xffff00ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ffd01c, 0x00ffd01c},
13641 {0xffffffff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ff79ff, 0x00ff79ff},
13642 {0x4cff4c54, D3DFMT_YUY2, "D3DFMT_YUY2", 0x000b8b00, 0x00b6ffa3},
13643 {0x00800080, D3DFMT_YUY2, "D3DFMT_YUY2", 0x0000ff00, 0x0000ff00},
13644 {0xff80ff80, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ff00ff, 0x00ff00ff},
13645 {0x1c6b1cff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x006dff45, 0x0000d500},
13648 window = create_window();
13649 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13650 ok(!!d3d, "Failed to create a D3D object.\n");
13651 if (!(device = create_device(d3d, window, window, TRUE)))
13653 skip("Failed to create a D3D device, skipping tests.\n");
13654 goto done;
13657 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
13658 ok(SUCCEEDED(hr), "Failed to get render target, hr %#lx.\n", hr);
13659 hr = IDirect3DSurface9_GetDesc(target, &desc);
13660 ok(SUCCEEDED(hr), "Failed to get surface description, hr %#lx.\n", hr);
13662 for (i = 0; i < ARRAY_SIZE(test_data); i++)
13664 /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect.
13665 * Thus use StretchRect to draw the YUV surface onto the screen instead of drawPrimitive. */
13666 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
13667 D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, test_data[i].format)))
13669 if (skip_once != test_data[i].format)
13671 skip("%s is not supported.\n", test_data[i].fmt_string);
13672 skip_once = test_data[i].format;
13674 continue;
13676 if (FAILED(IDirect3D9_CheckDeviceFormatConversion(d3d, 0,
13677 D3DDEVTYPE_HAL, test_data[i].format, desc.Format)))
13679 if (skip_once != test_data[i].format)
13681 skip("Driver cannot blit %s surfaces.\n", test_data[i].fmt_string);
13682 skip_once = test_data[i].format;
13684 continue;
13687 /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1.
13688 * However, Nvidia Windows drivers have problems with 2x1 YUY2/UYVY surfaces, so use a 4x1 surface and
13689 * fill the second block with dummy data. If the surface has a size of 2x1, those drivers ignore the
13690 * second luminance value, resulting in an incorrect color in the right pixel. */
13691 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 4, 1, test_data[i].format,
13692 D3DPOOL_DEFAULT, &surface, NULL);
13693 ok(SUCCEEDED(hr), "Failed to create surface, hr %#lx.\n", hr);
13696 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
13697 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#lx.\n", hr);
13698 ((DWORD *)lr.pBits)[0] = test_data[i].in;
13699 ((DWORD *)lr.pBits)[1] = 0x00800080;
13700 hr = IDirect3DSurface9_UnlockRect(surface);
13701 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#lx.\n", hr);
13703 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 1.0f, 0);
13704 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
13705 hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
13706 ok(SUCCEEDED(hr), "Failed to draw surface onto backbuffer, hr %#lx.\n", hr);
13708 /* Some Windows drivers (mostly Nvidia, but also some VM drivers) insist on doing linear filtering
13709 * although we asked for point filtering. Be careful when reading the results and use the pixel
13710 * centers. In the future we may want to add tests for the filtered pixels as well.
13712 * Unfortunately different implementations(Windows-Nvidia and Mac-AMD tested) interpret some colors
13713 * vastly differently, so we need a max diff of 18. */
13714 color = getPixelColor(device, 1, 240);
13715 ok(color_match(color, test_data[i].left, 18),
13716 "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s.\n",
13717 test_data[i].in, color, test_data[i].left, test_data[i].fmt_string);
13718 color = getPixelColor(device, 318, 240);
13719 ok(color_match(color, test_data[i].right, 18),
13720 "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s.\n",
13721 test_data[i].in, color, test_data[i].right, test_data[i].fmt_string);
13722 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13723 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
13724 IDirect3DSurface9_Release(surface);
13727 IDirect3DSurface9_Release(target);
13728 refcount = IDirect3DDevice9_Release(device);
13729 ok(!refcount, "Device has %lu references left.\n", refcount);
13730 done:
13731 IDirect3D9_Release(d3d);
13732 DestroyWindow(window);
13735 static void yuv_layout_test(void)
13737 unsigned int color, ref_color, fmt, i, x, y;
13738 HRESULT hr;
13739 IDirect3DSurface9 *surface, *target;
13740 D3DFORMAT format;
13741 const char *fmt_string;
13742 D3DLOCKED_RECT lr;
13743 IDirect3D9 *d3d;
13744 BYTE *buf, *chroma_buf, *u_buf, *v_buf;
13745 UINT width = 20, height = 16;
13746 IDirect3DDevice9 *device;
13747 ULONG refcount;
13748 D3DCAPS9 caps;
13749 D3DSURFACE_DESC desc;
13750 HWND window;
13752 static const struct
13754 DWORD color1, color2;
13755 DWORD rgb1, rgb2;
13757 test_data[] =
13759 { 0x000000, 0xffffff, 0x00008800, 0x00ff7dff },
13760 { 0xff0000, 0x00ffff, 0x004aff14, 0x00b800ee },
13761 { 0x00ff00, 0xff00ff, 0x000024ee, 0x00ffe114 },
13762 { 0x0000ff, 0xffff00, 0x00b80000, 0x004affff },
13763 { 0xffff00, 0x0000ff, 0x004affff, 0x00b80000 },
13764 { 0xff00ff, 0x00ff00, 0x00ffe114, 0x000024ee },
13765 { 0x00ffff, 0xff0000, 0x00b800ee, 0x004aff14 },
13766 { 0xffffff, 0x000000, 0x00ff7dff, 0x00008800 },
13769 static const struct
13771 D3DFORMAT format;
13772 const char *str;
13774 formats[] =
13776 { D3DFMT_UYVY, "D3DFMT_UYVY", },
13777 { D3DFMT_YUY2, "D3DFMT_YUY2", },
13778 { MAKEFOURCC('Y','V','1','2'), "D3DFMT_YV12", },
13779 { MAKEFOURCC('N','V','1','2'), "D3DFMT_NV12", },
13782 window = create_window();
13783 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13784 ok(!!d3d, "Failed to create a D3D object.\n");
13785 if (!(device = create_device(d3d, window, window, TRUE)))
13787 skip("Failed to create a D3D device, skipping tests.\n");
13788 goto done;
13791 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13792 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#lx.\n", hr);
13793 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2
13794 && !(caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL))
13796 skip("No NP2 texture support, skipping YUV texture layout test.\n");
13797 IDirect3DDevice9_Release(device);
13798 goto done;
13801 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
13802 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
13803 hr = IDirect3DSurface9_GetDesc(target, &desc);
13804 ok(SUCCEEDED(hr), "Failed to get surface description, hr %#lx.\n", hr);
13806 for (fmt = 0; fmt < ARRAY_SIZE(formats); fmt++)
13808 format = formats[fmt].format;
13809 fmt_string = formats[fmt].str;
13811 /* Some (all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in
13812 * StretchRect. Thus use StretchRect to draw the YUV surface onto the screen instead
13813 * of drawPrimitive. */
13814 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
13815 D3DRTYPE_SURFACE, format) != D3D_OK)
13817 skip("%s is not supported.\n", fmt_string);
13818 continue;
13820 if (FAILED(IDirect3D9_CheckDeviceFormatConversion(d3d, 0,
13821 D3DDEVTYPE_HAL, format, desc.Format)))
13823 skip("Driver cannot blit %s surfaces.\n", fmt_string);
13824 continue;
13827 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, width, height, format, D3DPOOL_DEFAULT, &surface, NULL);
13828 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
13830 for (i = 0; i < ARRAY_SIZE(test_data); i++)
13832 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
13833 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
13834 buf = lr.pBits;
13835 chroma_buf = buf + lr.Pitch * height;
13836 if (format == MAKEFOURCC('Y','V','1','2'))
13838 v_buf = chroma_buf;
13839 u_buf = chroma_buf + height / 2 * lr.Pitch/2;
13841 /* Draw the top left quarter of the screen with color1, the rest with color2 */
13842 for (y = 0; y < height; y++)
13844 for (x = 0; x < width; x += 2)
13846 DWORD color = (x < width / 2 && y < height / 2) ? test_data[i].color1 : test_data[i].color2;
13847 BYTE Y = (color >> 16) & 0xff;
13848 BYTE U = (color >> 8) & 0xff;
13849 BYTE V = (color >> 0) & 0xff;
13850 if (format == D3DFMT_UYVY)
13852 buf[y * lr.Pitch + 2 * x + 0] = U;
13853 buf[y * lr.Pitch + 2 * x + 1] = Y;
13854 buf[y * lr.Pitch + 2 * x + 2] = V;
13855 buf[y * lr.Pitch + 2 * x + 3] = Y;
13857 else if (format == D3DFMT_YUY2)
13859 buf[y * lr.Pitch + 2 * x + 0] = Y;
13860 buf[y * lr.Pitch + 2 * x + 1] = U;
13861 buf[y * lr.Pitch + 2 * x + 2] = Y;
13862 buf[y * lr.Pitch + 2 * x + 3] = V;
13864 else if (format == MAKEFOURCC('Y','V','1','2'))
13866 buf[y * lr.Pitch + x + 0] = Y;
13867 buf[y * lr.Pitch + x + 1] = Y;
13868 u_buf[(y / 2) * (lr.Pitch / 2) + (x / 2)] = U;
13869 v_buf[(y / 2) * (lr.Pitch / 2) + (x / 2)] = V;
13871 else if (format == MAKEFOURCC('N','V','1','2'))
13873 buf[y * lr.Pitch + x + 0] = Y;
13874 buf[y * lr.Pitch + x + 1] = Y;
13875 chroma_buf[(y / 2) * lr.Pitch + 2 * (x / 2) + 0] = U;
13876 chroma_buf[(y / 2) * lr.Pitch + 2 * (x / 2) + 1] = V;
13880 hr = IDirect3DSurface9_UnlockRect(surface);
13881 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
13883 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 1.0f, 0);
13884 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
13885 hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
13886 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
13888 /* Some Windows drivers (mostly Nvidia, but also some VM drivers) insist on doing linear filtering
13889 * although we asked for point filtering. To prevent running into precision problems, read at points
13890 * with some margin within each quadrant.
13892 * Unfortunately different implementations(Windows-Nvidia and Mac-AMD tested) interpret some colors
13893 * vastly differently, so we need a max diff of 18. */
13894 for (y = 0; y < 4; y++)
13896 for (x = 0; x < 4; x++)
13898 UINT xcoord = (1 + 2 * x) * 640 / 8;
13899 UINT ycoord = (1 + 2 * y) * 480 / 8;
13900 ref_color = (y < 2 && x < 2) ? test_data[i].rgb1 : test_data[i].rgb2;
13901 color = getPixelColor(device, xcoord, ycoord);
13902 ok(color_match(color, ref_color, 18),
13903 "Format %s: Got color %#x for pixel (%d/%d)/(%d/%d), pixel %d %d, expected %#x.\n",
13904 fmt_string, color, x, 4, y, 4, xcoord, ycoord, ref_color);
13907 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13908 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13910 IDirect3DSurface9_Release(surface);
13913 IDirect3DSurface9_Release(target);
13914 refcount = IDirect3DDevice9_Release(device);
13915 ok(!refcount, "Device has %lu references left.\n", refcount);
13916 done:
13917 IDirect3D9_Release(d3d);
13918 DestroyWindow(window);
13921 static void texop_range_test(void)
13923 IDirect3DTexture9 *texture;
13924 D3DLOCKED_RECT locked_rect;
13925 IDirect3DDevice9 *device;
13926 unsigned int color;
13927 IDirect3D9 *d3d;
13928 ULONG refcount;
13929 D3DCAPS9 caps;
13930 HWND window;
13931 HRESULT hr;
13933 static const struct
13935 float x, y, z;
13936 D3DCOLOR diffuse;
13938 quad[] =
13940 {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
13941 {-1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
13942 { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
13943 { 1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
13946 window = create_window();
13947 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13948 ok(!!d3d, "Failed to create a D3D object.\n");
13949 if (!(device = create_device(d3d, window, window, TRUE)))
13951 skip("Failed to create a D3D device, skipping tests.\n");
13952 goto done;
13955 /* We need ADD and SUBTRACT operations */
13956 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13957 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13958 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD))
13960 skip("D3DTOP_ADD is not supported, skipping value range test.\n");
13961 IDirect3DDevice9_Release(device);
13962 goto done;
13964 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT))
13966 skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test.\n");
13967 IDirect3DDevice9_Release(device);
13968 goto done;
13971 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13972 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13973 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13974 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
13975 /* Stage 1: result = diffuse(=1.0) + diffuse
13976 * stage 2: result = result - tfactor(= 0.5)
13978 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
13979 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13980 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
13981 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13982 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
13983 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13984 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
13985 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13986 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
13987 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13988 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
13989 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13990 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
13991 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13993 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
13994 ok(SUCCEEDED(hr), "Failed to clear device, hr %#lx.\n\n", hr);
13995 hr = IDirect3DDevice9_BeginScene(device);
13996 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13997 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13998 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13999 hr = IDirect3DDevice9_EndScene(device);
14000 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14002 color = getPixelColor(device, 320, 240);
14003 ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
14004 color);
14005 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14006 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14008 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
14009 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14010 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
14011 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14012 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
14013 hr = IDirect3DTexture9_UnlockRect(texture, 0);
14014 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14015 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
14016 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14018 /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
14019 * stage 2: result = result + diffuse(1.0)
14021 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
14022 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14023 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
14024 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14025 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
14026 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14027 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
14028 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14029 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
14030 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14031 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
14032 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14033 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
14034 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14036 hr = IDirect3DDevice9_BeginScene(device);
14037 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14038 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14039 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14040 hr = IDirect3DDevice9_EndScene(device);
14041 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14043 color = getPixelColor(device, 320, 240);
14044 ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
14045 color);
14046 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14047 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14049 IDirect3DTexture9_Release(texture);
14050 refcount = IDirect3DDevice9_Release(device);
14051 ok(!refcount, "Device has %lu references left.\n", refcount);
14052 done:
14053 IDirect3D9_Release(d3d);
14054 DestroyWindow(window);
14057 static void alphareplicate_test(void)
14059 IDirect3DDevice9 *device;
14060 unsigned int color;
14061 IDirect3D9 *d3d;
14062 ULONG refcount;
14063 HWND window;
14064 HRESULT hr;
14066 static const struct
14068 struct vec3 position;
14069 DWORD diffuse;
14071 quad[] =
14073 {{-1.0f, -1.0f, 0.1f}, 0x80ff00ff},
14074 {{-1.0f, 1.0f, 0.1f}, 0x80ff00ff},
14075 {{ 1.0f, -1.0f, 0.1f}, 0x80ff00ff},
14076 {{ 1.0f, 1.0f, 0.1f}, 0x80ff00ff},
14079 window = create_window();
14080 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14081 ok(!!d3d, "Failed to create a D3D object.\n");
14082 if (!(device = create_device(d3d, window, window, TRUE)))
14084 skip("Failed to create a D3D device, skipping tests.\n");
14085 goto done;
14088 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
14089 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14091 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
14092 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14094 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
14095 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14096 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
14097 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14099 hr = IDirect3DDevice9_BeginScene(device);
14100 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
14101 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14102 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
14103 hr = IDirect3DDevice9_EndScene(device);
14104 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
14106 color = getPixelColor(device, 320, 240);
14107 ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
14108 color);
14109 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14110 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14112 refcount = IDirect3DDevice9_Release(device);
14113 ok(!refcount, "Device has %lu references left.\n", refcount);
14114 done:
14115 IDirect3D9_Release(d3d);
14116 DestroyWindow(window);
14119 static void dp3_alpha_test(void)
14121 IDirect3DDevice9 *device;
14122 unsigned int color;
14123 IDirect3D9 *d3d;
14124 ULONG refcount;
14125 D3DCAPS9 caps;
14126 HWND window;
14127 HRESULT hr;
14129 static const struct
14131 struct vec3 position;
14132 DWORD diffuse;
14134 quad[] =
14136 {{-1.0f, -1.0f, 0.1f}, 0x408080c0},
14137 {{-1.0f, 1.0f, 0.1f}, 0x408080c0},
14138 {{ 1.0f, -1.0f, 0.1f}, 0x408080c0},
14139 {{ 1.0f, 1.0f, 0.1f}, 0x408080c0},
14142 window = create_window();
14143 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14144 ok(!!d3d, "Failed to create a D3D object.\n");
14145 if (!(device = create_device(d3d, window, window, TRUE)))
14147 skip("Failed to create a D3D device, skipping tests.\n");
14148 goto done;
14151 memset(&caps, 0, sizeof(caps));
14152 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
14153 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
14154 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3))
14156 skip("D3DTOP_DOTPRODUCT3 not supported\n");
14157 IDirect3DDevice9_Release(device);
14158 goto done;
14161 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
14162 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14164 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
14165 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14167 /* dp3_x4 r0, diffuse_bias, tfactor_bias
14168 * mov r0.a, diffuse.a
14169 * mov r0, r0.a
14171 * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
14172 * thus with input vec4(0.5, 0.5, 0.75, 0.25) and vec4(1.0, 1.0, 1.0, 1.0) the result is
14173 * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
14175 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
14176 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14177 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
14178 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14179 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
14180 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14181 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
14182 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14183 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
14184 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14185 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
14186 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14187 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
14188 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14189 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
14190 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14191 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
14192 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14193 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
14194 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
14196 hr = IDirect3DDevice9_BeginScene(device);
14197 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
14198 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14199 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
14200 hr = IDirect3DDevice9_EndScene(device);
14201 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
14203 color = getPixelColor(device, 320, 240);
14204 ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
14205 color);
14206 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14207 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14209 refcount = IDirect3DDevice9_Release(device);
14210 ok(!refcount, "Device has %lu references left.\n", refcount);
14211 done:
14212 IDirect3D9_Release(d3d);
14213 DestroyWindow(window);
14216 static void zwriteenable_test(void)
14218 IDirect3DDevice9 *device;
14219 unsigned int color;
14220 IDirect3D9 *d3d;
14221 ULONG refcount;
14222 HWND window;
14223 HRESULT hr;
14225 static const struct
14227 struct vec3 position;
14228 DWORD diffuse;
14230 quad1[] =
14232 {{-1.0f, -1.0f, 0.1f}, 0x00ff0000},
14233 {{-1.0f, 1.0f, 0.1f}, 0x00ff0000},
14234 {{ 1.0f, -1.0f, 0.1f}, 0x00ff0000},
14235 {{ 1.0f, 1.0f, 0.1f}, 0x00ff0000},
14237 quad2[] =
14239 {{-1.0f, -1.0f, 0.9f}, 0x0000ff00},
14240 {{-1.0f, 1.0f, 0.9f}, 0x0000ff00},
14241 {{ 1.0f, -1.0f, 0.9f}, 0x0000ff00},
14242 {{ 1.0f, 1.0f, 0.9f}, 0x0000ff00},
14245 window = create_window();
14246 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14247 ok(!!d3d, "Failed to create a D3D object.\n");
14248 if (!(device = create_device(d3d, window, window, TRUE)))
14250 skip("Failed to create a D3D device, skipping tests.\n");
14251 goto done;
14254 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
14255 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14257 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
14258 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14259 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
14260 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14261 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
14262 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14263 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
14264 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14265 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
14266 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
14268 hr = IDirect3DDevice9_BeginScene(device);
14269 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
14270 /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1,
14271 * zenable = D3DZB_FALSE, zwriteenable = TRUE. The red color is written
14272 * because the z test is disabled. The question is whether the z = 0.1
14273 * values are written into the Z buffer. After the draw, set
14274 * zenable = TRUE and draw a green quad at z = 0.9. If the values are
14275 * written, the z test will fail(0.9 > 0.1) and the red color remains. If
14276 * the values are not written, the z test succeeds(0.9 < 1.0) and the
14277 * green color is written. It turns out that the screen is green, so
14278 * zenable = D3DZB_FALSE and zwriteenable = TRUE does NOT write to the z
14279 * buffer. */
14280 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
14281 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
14282 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
14283 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
14284 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
14285 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
14286 hr = IDirect3DDevice9_EndScene(device);
14287 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
14289 color = getPixelColor(device, 320, 240);
14290 ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
14291 color);
14292 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14293 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14295 refcount = IDirect3DDevice9_Release(device);
14296 ok(!refcount, "Device has %lu references left.\n", refcount);
14297 done:
14298 IDirect3D9_Release(d3d);
14299 DestroyWindow(window);
14302 static void alphatest_test(void)
14304 #define ALPHATEST_PASSED 0x0000ff00
14305 #define ALPHATEST_FAILED 0x00ff0000
14306 IDirect3DDevice9 *device;
14307 unsigned int color, i, j;
14308 IDirect3D9 *d3d;
14309 ULONG refcount;
14310 D3DCAPS9 caps;
14311 DWORD value;
14312 HWND window;
14313 HRESULT hr;
14315 static const struct
14317 D3DCMPFUNC func;
14318 unsigned int color_less;
14319 unsigned int color_equal;
14320 unsigned int color_greater;
14322 testdata[] =
14324 {D3DCMP_NEVER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED},
14325 {D3DCMP_LESS, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED},
14326 {D3DCMP_EQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED},
14327 {D3DCMP_LESSEQUAL, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED},
14328 {D3DCMP_GREATER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED},
14329 {D3DCMP_NOTEQUAL, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED},
14330 {D3DCMP_GREATEREQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED},
14331 {D3DCMP_ALWAYS, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED},
14333 static const struct
14335 struct vec3 position;
14336 DWORD diffuse;
14338 quad[] =
14340 {{-1.0f, -1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
14341 {{-1.0f, 1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
14342 {{ 1.0f, -1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
14343 {{ 1.0f, 1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
14346 window = create_window();
14347 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14348 ok(!!d3d, "Failed to create a D3D object.\n");
14349 if (!(device = create_device(d3d, window, window, TRUE)))
14351 skip("Failed to create a D3D device, skipping tests.\n");
14352 goto done;
14355 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
14356 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
14358 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
14359 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
14360 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
14361 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14362 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
14363 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14365 for (j = 0; j < 2; ++j)
14367 if (j == 1)
14369 /* Try a pixel shader instead of fixed function. The wined3d code
14370 * may emulate the alpha test either for performance reasons
14371 * (floating point RTs) or to work around driver bugs (GeForce
14372 * 7x00 cards on MacOS). There may be a different codepath for ffp
14373 * and shader in this case, and the test should cover both. */
14374 IDirect3DPixelShader9 *ps;
14375 static const DWORD shader_code[] =
14377 0xffff0101, /* ps_1_1 */
14378 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
14379 0x0000ffff /* end */
14381 memset(&caps, 0, sizeof(caps));
14382 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
14383 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14384 if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
14385 break;
14388 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
14389 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14390 hr = IDirect3DDevice9_SetPixelShader(device, ps);
14391 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14392 IDirect3DPixelShader9_Release(ps);
14395 for(i = 0; i < ARRAY_SIZE(testdata); i++)
14397 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
14398 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14400 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
14401 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14402 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
14403 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14404 hr = IDirect3DDevice9_BeginScene(device);
14405 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
14406 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14407 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
14408 hr = IDirect3DDevice9_EndScene(device);
14409 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
14410 color = getPixelColor(device, 320, 240);
14411 ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
14412 color, testdata[i].color_less, testdata[i].func);
14413 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14414 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14416 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
14417 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14418 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
14419 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14420 hr = IDirect3DDevice9_BeginScene(device);
14421 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
14422 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14423 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
14424 hr = IDirect3DDevice9_EndScene(device);
14425 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
14426 color = getPixelColor(device, 320, 240);
14427 ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
14428 color, testdata[i].color_equal, testdata[i].func);
14429 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14430 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14432 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
14433 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14434 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
14435 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14436 hr = IDirect3DDevice9_BeginScene(device);
14437 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
14438 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14439 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
14440 hr = IDirect3DDevice9_EndScene(device);
14441 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
14442 color = getPixelColor(device, 320, 240);
14443 ok(color_match(color, testdata[i].color_greater, 1),
14444 "Alphatest failed, color 0x%08x, expected 0x%08x, alpha > ref, func %u.\n",
14445 color, testdata[i].color_greater, testdata[i].func);
14446 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14447 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed, hr %#lx.\n", hr);
14449 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0f, 0);
14450 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr %#lx.\n", hr);
14451 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0xff70);
14452 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr %#lx.\n", hr);
14453 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_ALPHAREF, &value);
14454 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr %#lx.\n", hr);
14455 ok(value == 0xff70, "Unexpected D3DRS_ALPHAREF value %#lx.\n", value);
14456 hr = IDirect3DDevice9_BeginScene(device);
14457 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr %#lx.\n", hr);
14458 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14459 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#lx.\n", hr);
14460 hr = IDirect3DDevice9_EndScene(device);
14461 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr %#lx.\n", hr);
14462 color = getPixelColor(device, 320, 240);
14463 ok(color_match(color, testdata[i].color_greater, 1),
14464 "Alphatest failed, color 0x%08x, expected 0x%08x, alpha > ref, func %u.\n",
14465 color, testdata[i].color_greater, testdata[i].func);
14466 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14467 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed, hr %#lx.\n", hr);
14472 refcount = IDirect3DDevice9_Release(device);
14473 ok(!refcount, "Device has %lu references left.\n", refcount);
14474 done:
14475 IDirect3D9_Release(d3d);
14476 DestroyWindow(window);
14479 static void sincos_test(void)
14481 IDirect3DVertexShader9 *sin_shader, *cos_shader;
14482 IDirect3DDevice9 *device;
14483 struct vec3 data[1280];
14484 IDirect3D9 *d3d;
14485 unsigned int i;
14486 ULONG refcount;
14487 D3DCAPS9 caps;
14488 HWND window;
14489 HRESULT hr;
14491 static const DWORD sin_shader_code[] =
14493 0xfffe0200, /* vs_2_0 */
14494 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
14495 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
14496 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
14497 0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.y, r1.x, c0, c1 */
14498 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
14499 0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002, /* mul oPos.y, r0.y, c2.w */
14500 0x02000001, 0xd00f0000, 0xa0a60002, /* mov oD0, c2.zyzz */
14501 0x0000ffff /* end */
14503 static const DWORD cos_shader_code[] =
14505 0xfffe0200, /* vs_2_0 */
14506 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
14507 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
14508 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
14509 0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.x, r1.x, c0, c1 */
14510 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
14511 0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002, /* mul oPos.y, r0.x, c2.w */
14512 0x02000001, 0xd00f0000, 0xa0a90002, /* mov oD0, c2.yzzz */
14513 0x0000ffff /* end */
14515 static const float sincosc1[4] = {D3DSINCOSCONST1};
14516 static const float sincosc2[4] = {D3DSINCOSCONST2};
14518 window = create_window();
14519 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14520 ok(!!d3d, "Failed to create a D3D object.\n");
14521 if (!(device = create_device(d3d, window, window, TRUE)))
14523 skip("Failed to create a D3D device, skipping tests.\n");
14524 goto done;
14527 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
14528 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
14529 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
14531 skip("No vs_2_0 support, skipping tests.\n");
14532 IDirect3DDevice9_Release(device);
14533 goto done;
14536 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
14537 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14539 hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
14540 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14541 hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
14542 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14543 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
14544 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14545 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
14546 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14547 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
14548 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14550 /* Generate a point from -1 to 1 every 0.5 pixels */
14551 for(i = 0; i < 1280; i++) {
14552 data[i].x = (-640.0 + i) / 640.0;
14553 data[i].y = 0.0;
14554 data[i].z = 0.1;
14557 hr = IDirect3DDevice9_BeginScene(device);
14558 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
14560 hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
14561 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
14562 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
14563 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
14565 hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
14566 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
14567 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
14568 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
14570 hr = IDirect3DDevice9_EndScene(device);
14571 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
14573 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14574 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14575 /* TODO: Find a way to properly validate the lines. Precision issues make this a kinda nasty task */
14577 IDirect3DVertexShader9_Release(sin_shader);
14578 IDirect3DVertexShader9_Release(cos_shader);
14579 refcount = IDirect3DDevice9_Release(device);
14580 ok(!refcount, "Device has %lu references left.\n", refcount);
14581 done:
14582 IDirect3D9_Release(d3d);
14583 DestroyWindow(window);
14586 static void loop_index_test(void)
14588 IDirect3DVertexShader9 *shader;
14589 IDirect3DDevice9 *device;
14590 unsigned int color;
14591 IDirect3D9 *d3d;
14592 float values[4];
14593 ULONG refcount;
14594 D3DCAPS9 caps;
14595 HWND window;
14596 HRESULT hr;
14598 static const DWORD shader_code[] =
14600 0xfffe0200, /* vs_2_0 */
14601 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
14602 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
14603 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
14604 0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1] */
14605 0x0000001d, /* endloop */
14606 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
14607 0x02000001, 0xd00f0000, 0x80e40000, /* mov oD0, r0 */
14608 0x0000ffff /* END */
14610 static const float quad[] =
14612 -1.0f, -1.0f, 0.1f,
14613 -1.0f, 1.0f, 0.1f,
14614 1.0f, -1.0f, 0.1f,
14615 1.0f, 1.0f, 0.1f,
14617 static const float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
14618 static const float one[4] = {1.0f, 1.0f, 1.0f, 1.0f};
14619 static const int i0[4] = {2, 10, -3, 0};
14621 window = create_window();
14622 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14623 ok(!!d3d, "Failed to create a D3D object.\n");
14624 if (!(device = create_device(d3d, window, window, TRUE)))
14626 skip("Failed to create a D3D device, skipping tests.\n");
14627 goto done;
14630 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
14631 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
14632 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
14634 skip("No vs_2_0 support, skipping tests.\n");
14635 IDirect3DDevice9_Release(device);
14636 goto done;
14639 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
14640 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14641 hr = IDirect3DDevice9_SetVertexShader(device, shader);
14642 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14643 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
14644 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14645 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
14646 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14648 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
14649 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14650 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
14651 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14652 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
14653 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14654 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
14655 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14656 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
14657 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14658 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
14659 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14660 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
14661 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14662 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
14663 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14664 values[0] = 1.0;
14665 values[1] = 1.0;
14666 values[2] = 0.0;
14667 values[3] = 0.0;
14668 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
14669 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14670 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
14671 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14672 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
14673 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14674 values[0] = -1.0;
14675 values[1] = 0.0;
14676 values[2] = 0.0;
14677 values[3] = 0.0;
14678 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
14679 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14680 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
14681 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14682 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
14683 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14684 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
14685 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14686 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
14687 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14689 hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
14690 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14692 hr = IDirect3DDevice9_BeginScene(device);
14693 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
14694 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
14695 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
14696 hr = IDirect3DDevice9_EndScene(device);
14697 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
14698 color = getPixelColor(device, 320, 240);
14699 ok(color_match(color, 0x0000ff00, 1),
14700 "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
14701 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14702 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14704 IDirect3DVertexShader9_Release(shader);
14705 refcount = IDirect3DDevice9_Release(device);
14706 ok(!refcount, "Device has %lu references left.\n", refcount);
14707 done:
14708 IDirect3D9_Release(d3d);
14709 DestroyWindow(window);
14712 static void sgn_test(void)
14714 IDirect3DVertexShader9 *shader;
14715 IDirect3DDevice9 *device;
14716 unsigned int color;
14717 IDirect3D9 *d3d;
14718 ULONG refcount;
14719 D3DCAPS9 caps;
14720 HWND window;
14721 HRESULT hr;
14723 static const DWORD shader_code[] =
14725 0xfffe0200, /* vs_2_0 */
14726 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position o0 */
14727 0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
14728 0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0 */
14729 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
14730 0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002, /* sgn r0, c0, r1, r2 */
14731 0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001, /* add oD0, r0, c1 */
14732 0x0000ffff /* end */
14734 static const float quad[] =
14736 -1.0f, -1.0f, 0.1f,
14737 -1.0f, 1.0f, 0.1f,
14738 1.0f, -1.0f, 0.1f,
14739 1.0f, 1.0f, 0.1f,
14742 window = create_window();
14743 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14744 ok(!!d3d, "Failed to create a D3D object.\n");
14745 if (!(device = create_device(d3d, window, window, TRUE)))
14747 skip("Failed to create a D3D device, skipping tests.\n");
14748 goto done;
14751 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
14752 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
14753 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
14755 skip("No vs_2_0 support, skipping tests.\n");
14756 IDirect3DDevice9_Release(device);
14757 goto done;
14760 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
14761 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14762 hr = IDirect3DDevice9_SetVertexShader(device, shader);
14763 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14764 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
14765 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14766 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
14767 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14769 hr = IDirect3DDevice9_BeginScene(device);
14770 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
14771 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
14772 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
14773 hr = IDirect3DDevice9_EndScene(device);
14774 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
14775 color = getPixelColor(device, 320, 240);
14776 ok(color_match(color, 0x008000ff, 1),
14777 "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
14778 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14779 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14781 IDirect3DVertexShader9_Release(shader);
14782 refcount = IDirect3DDevice9_Release(device);
14783 ok(!refcount, "Device has %lu references left.\n", refcount);
14784 done:
14785 IDirect3D9_Release(d3d);
14786 DestroyWindow(window);
14789 static void test_viewport(void)
14791 static const struct
14793 D3DVIEWPORT9 vp;
14794 float expected_z;
14795 RECT expected_rect;
14796 const char *message;
14798 tests[] =
14800 {{ 0, 0, 640, 480}, 0.001f, { 0, 120, 479, 359}, "Viewport (0, 0) - (640, 480)"},
14801 {{ 0, 0, 640, 480, 0.5f, 0.0f}, 0.501f,
14802 { 0, 120, 479, 359}, "Viewport (0, 0, 0.5) - (640, 480, 0.0)"},
14803 {{ 0, 0, 320, 240}, 0.001f, { 0, 60, 239, 179}, "Viewport (0, 0) - (320, 240)"},
14804 {{ 0, 0, 1280, 960}, 0.001f, { 0, 240, 639, 479}, "Viewport (0, 0) - (1280, 960)"},
14805 {{ 0, 0, 2000, 1600}, 0.001f, { 0, 400, 639, 479}, "Viewport (0, 0) - (2000, 1600)"},
14806 {{100, 100, 640, 480}, 0.001f, {100, 220, 579, 459}, "Viewport (100, 100) - (640, 480)"},
14807 {{ 0, 0, 8192, 8192}, 0.001f, {-10, -10, -10, -10}, "Viewport (0, 0) - (8192, 8192)"},
14808 /* AMD HD 2600 on XP draws nothing visible for this one. */
14809 /* {{ 0, 0, 8192, 480}, {-10, -10, -1, -1}, "(0, 0) - (8192, 480) viewport"}, */
14811 static const struct vec3 quad[] =
14813 {-1.5f, -0.5f, 1.0f},
14814 {-1.5f, 0.5f, 1.0f},
14815 { 0.5f, -0.5f, 1.0f},
14816 { 0.5f, 0.5f, 1.0f},
14818 IDirect3DSurface9 *backbuffer;
14819 const float z_eps = 0.0001;
14820 struct surface_readback rb;
14821 IDirect3DDevice9 *device;
14822 BOOL draw_succeeded;
14823 IDirect3D9 *d3d;
14824 unsigned int i;
14825 ULONG refcount;
14826 HWND window;
14827 HRESULT hr;
14829 window = create_window();
14830 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14831 ok(!!d3d, "Failed to create a D3D object.\n");
14832 if (!(device = create_device(d3d, window, window, TRUE)))
14834 skip("Failed to create a D3D device, skipping tests.\n");
14835 goto done;
14838 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
14839 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14841 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
14842 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14843 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
14844 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14846 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
14847 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14849 /* This crashes on Windows. */
14850 if (0)
14851 hr = IDirect3DDevice9_SetViewport(device, NULL);
14853 for (i = 0; i < ARRAY_SIZE(tests); ++i)
14855 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000,
14856 tests[i].expected_z - z_eps, 0);
14857 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14859 hr = IDirect3DDevice9_SetViewport(device, &tests[i].vp);
14860 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14862 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
14863 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14865 hr = IDirect3DDevice9_BeginScene(device);
14866 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14867 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
14868 ok(hr == D3D_OK || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#lx.\n", hr);
14869 draw_succeeded = hr == D3D_OK;
14870 hr = IDirect3DDevice9_EndScene(device);
14871 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14873 if (!draw_succeeded)
14874 continue;
14876 get_rt_readback(backbuffer, &rb);
14877 check_rect(&rb, tests[i].expected_rect, tests[i].message);
14878 release_surface_readback(&rb);
14880 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000,
14881 tests[i].expected_z + z_eps, 0);
14882 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14883 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
14884 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14886 hr = IDirect3DDevice9_BeginScene(device);
14887 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14888 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
14889 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14890 hr = IDirect3DDevice9_EndScene(device);
14891 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14893 get_rt_readback(backbuffer, &rb);
14894 check_rect(&rb, tests[i].expected_rect, tests[i].message);
14895 release_surface_readback(&rb);
14898 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14899 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
14901 IDirect3DSurface9_Release(backbuffer);
14902 refcount = IDirect3DDevice9_Release(device);
14903 ok(!refcount, "Device has %lu references left.\n", refcount);
14904 done:
14905 IDirect3D9_Release(d3d);
14906 DestroyWindow(window);
14909 /* This test tests depth clamping / clipping behaviour:
14910 * - With software vertex processing, depth values are clamped to the
14911 * minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
14912 * when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
14913 * same as regular vertices here.
14914 * - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
14915 * Normal vertices are always clipped. Pretransformed vertices are
14916 * clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
14917 * - The viewport's MinZ/MaxZ is irrelevant for this.
14919 static void depth_clamp_test(void)
14921 IDirect3DDevice9 *device;
14922 unsigned int color;
14923 D3DVIEWPORT9 vp;
14924 IDirect3D9 *d3d;
14925 ULONG refcount;
14926 D3DCAPS9 caps;
14927 HWND window;
14928 HRESULT hr;
14930 static const struct
14932 struct vec4 position;
14933 DWORD diffuse;
14935 quad1[] =
14937 {{ 0.0f, 0.0f, 5.0f, 1.0f}, 0xff002b7f},
14938 {{640.0f, 0.0f, 5.0f, 1.0f}, 0xff002b7f},
14939 {{ 0.0f, 480.0f, 5.0f, 1.0f}, 0xff002b7f},
14940 {{640.0f, 480.0f, 5.0f, 1.0f}, 0xff002b7f},
14942 quad2[] =
14944 {{ 0.0f, 300.0f, 10.0f, 1.0f}, 0xfff9e814},
14945 {{640.0f, 300.0f, 10.0f, 1.0f}, 0xfff9e814},
14946 {{ 0.0f, 360.0f, 10.0f, 1.0f}, 0xfff9e814},
14947 {{640.0f, 360.0f, 10.0f, 1.0f}, 0xfff9e814},
14949 quad3[] =
14951 {{112.0f, 108.0f, 5.0f, 1.0f}, 0xffffffff},
14952 {{208.0f, 108.0f, 5.0f, 1.0f}, 0xffffffff},
14953 {{112.0f, 204.0f, 5.0f, 1.0f}, 0xffffffff},
14954 {{208.0f, 204.0f, 5.0f, 1.0f}, 0xffffffff},
14956 quad4[] =
14958 {{ 42.0f, 41.0f, 10.0f, 1.0f}, 0xffffffff},
14959 {{112.0f, 41.0f, 10.0f, 1.0f}, 0xffffffff},
14960 {{ 42.0f, 108.0f, 10.0f, 1.0f}, 0xffffffff},
14961 {{112.0f, 108.0f, 10.0f, 1.0f}, 0xffffffff},
14963 static const struct
14965 struct vec3 position;
14966 DWORD diffuse;
14968 quad5[] =
14970 {{-0.5f, 0.5f, 10.0f}, 0xff14f914},
14971 {{ 0.5f, 0.5f, 10.0f}, 0xff14f914},
14972 {{-0.5f, -0.5f, 10.0f}, 0xff14f914},
14973 {{ 0.5f, -0.5f, 10.0f}, 0xff14f914},
14975 quad6[] =
14977 {{-1.0f, 0.5f, 10.0f}, 0xfff91414},
14978 {{ 1.0f, 0.5f, 10.0f}, 0xfff91414},
14979 {{-1.0f, 0.25f, 10.0f}, 0xfff91414},
14980 {{ 1.0f, 0.25f, 10.0f}, 0xfff91414},
14983 window = create_window();
14984 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14985 ok(!!d3d, "Failed to create a D3D object.\n");
14986 if (!(device = create_device(d3d, window, window, TRUE)))
14988 skip("Failed to create a D3D device, skipping tests.\n");
14989 goto done;
14992 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
14993 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
14995 vp.X = 0;
14996 vp.Y = 0;
14997 vp.Width = 640;
14998 vp.Height = 480;
14999 vp.MinZ = 0.0;
15000 vp.MaxZ = 7.5;
15002 hr = IDirect3DDevice9_SetViewport(device, &vp);
15003 if(FAILED(hr))
15005 /* Windows 7 rejects MaxZ > 1.0, Windows XP allows it. This doesn't break
15006 * the tests because the 7.5 is just intended to show that it doesn't have
15007 * any influence on the drawing or D3DRS_CLIPPING = FALSE. Set an accepted
15008 * viewport and continue.
15010 ok(broken(hr == D3DERR_INVALIDCALL), "D3D rejected maxZ > 1.0\n");
15011 vp.MaxZ = 1.0;
15012 hr = IDirect3DDevice9_SetViewport(device, &vp);
15014 ok(SUCCEEDED(hr), "SetViewport failed, hr %#lx.\n", hr);
15016 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0, 0);
15017 ok(SUCCEEDED(hr), "Clear failed, hr %#lx.\n", hr);
15019 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
15020 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15021 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
15022 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15023 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
15024 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15025 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
15026 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15028 hr = IDirect3DDevice9_BeginScene(device);
15029 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
15031 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
15032 ok(SUCCEEDED(hr), "SetFVF failed, hr %#lx.\n", hr);
15034 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
15035 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
15036 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
15037 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
15039 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
15040 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15042 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
15043 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
15044 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
15045 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
15047 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
15048 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15050 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
15051 ok(SUCCEEDED(hr), "SetFVF failed, hr %#lx.\n", hr);
15053 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
15054 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
15056 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
15057 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15059 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
15060 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
15062 hr = IDirect3DDevice9_EndScene(device);
15063 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
15065 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
15067 color = getPixelColor(device, 75, 75);
15068 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
15069 color = getPixelColor(device, 150, 150);
15070 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
15071 color = getPixelColor(device, 320, 240);
15072 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
15073 color = getPixelColor(device, 320, 330);
15074 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
15075 color = getPixelColor(device, 320, 330);
15076 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
15078 else
15080 color = getPixelColor(device, 75, 75);
15081 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
15082 color = getPixelColor(device, 150, 150);
15083 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
15084 color = getPixelColor(device, 320, 240);
15085 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
15086 color = getPixelColor(device, 320, 330);
15087 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
15088 color = getPixelColor(device, 320, 330);
15089 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
15092 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15093 ok(hr == S_OK, "Got hr %#lx.\n", hr);
15095 refcount = IDirect3DDevice9_Release(device);
15096 ok(!refcount, "Device has %lu references left.\n", refcount);
15097 done:
15098 IDirect3D9_Release(d3d);
15099 DestroyWindow(window);
15102 static void depth_bounds_test(void)
15104 static const struct
15106 struct vec4 position;
15107 DWORD diffuse;
15109 quad1[] =
15111 {{ 0.0f, 0.0f, 0.0f, 1.0f}, 0xfff9e814},
15112 {{640.0f, 0.0f, 0.0f, 1.0f}, 0xfff9e814},
15113 {{ 0.0f, 480.0f, 1.0f, 1.0f}, 0xfff9e814},
15114 {{640.0f, 480.0f, 1.0f, 1.0f}, 0xfff9e814},
15116 quad2[] =
15118 {{ 0.0f, 0.0f, 0.6f, 1.0f}, 0xff002b7f},
15119 {{640.0f, 0.0f, 0.6f, 1.0f}, 0xff002b7f},
15120 {{ 0.0f, 480.0f, 0.6f, 1.0f}, 0xff002b7f},
15121 {{640.0f, 480.0f, 0.6f, 1.0f}, 0xff002b7f},
15123 quad3[] =
15125 {{ 0.0f, 100.0f, 0.6f, 1.0f}, 0xfff91414},
15126 {{640.0f, 100.0f, 0.6f, 1.0f}, 0xfff91414},
15127 {{ 0.0f, 160.0f, 0.6f, 1.0f}, 0xfff91414},
15128 {{640.0f, 160.0f, 0.6f, 1.0f}, 0xfff91414},
15131 union {
15132 DWORD d;
15133 float f;
15134 } tmpvalue;
15136 IDirect3DSurface9 *offscreen_surface = NULL;
15137 IDirect3DDevice9 *device;
15138 unsigned int color;
15139 IDirect3D9 *d3d;
15140 ULONG refcount;
15141 HWND window;
15142 HRESULT hr;
15144 window = create_window();
15145 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15146 ok(!!d3d, "Failed to create a D3D object.\n");
15147 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
15148 D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, MAKEFOURCC('N','V','D','B')) != D3D_OK)
15150 skip("No NVDB (depth bounds test) support, skipping tests.\n");
15151 goto done;
15153 if (!(device = create_device(d3d, window, window, TRUE)))
15155 skip("Failed to create a D3D device, skipping tests.\n");
15156 goto done;
15159 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
15160 MAKEFOURCC('N','V','D','B'), D3DPOOL_DEFAULT, &offscreen_surface, NULL);
15161 ok(FAILED(hr), "Able to create surface, hr %#lx.\n", hr);
15162 if (offscreen_surface) IDirect3DSurface9_Release(offscreen_surface);
15164 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
15165 ok(SUCCEEDED(hr), "Clear failed, hr %#lx.\n", hr);
15167 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
15168 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15169 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
15170 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15171 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
15172 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15173 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
15174 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15177 hr = IDirect3DDevice9_BeginScene(device);
15178 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
15180 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
15181 ok(SUCCEEDED(hr), "SetFVF failed, hr %#lx.\n", hr);
15183 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
15184 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
15186 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, MAKEFOURCC('N','V','D','B'));
15187 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15189 tmpvalue.f = 0.625;
15190 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
15191 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15193 tmpvalue.f = 0.75;
15194 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_W, tmpvalue.d);
15195 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15197 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
15198 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
15200 tmpvalue.f = 0.75;
15201 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
15202 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15204 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
15205 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
15207 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, 0);
15208 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15210 hr = IDirect3DDevice9_EndScene(device);
15211 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
15213 color = getPixelColor(device, 150, 130);
15214 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
15215 color = getPixelColor(device, 150, 200);
15216 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
15217 color = getPixelColor(device, 150, 300-5);
15218 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
15219 color = getPixelColor(device, 150, 300+5);
15220 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
15221 color = getPixelColor(device, 150, 330);
15222 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
15223 color = getPixelColor(device, 150, 360-5);
15224 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
15225 color = getPixelColor(device, 150, 360+5);
15226 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
15228 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15229 ok(hr == S_OK, "Got hr %#lx.\n", hr);
15230 refcount = IDirect3DDevice9_Release(device);
15231 ok(!refcount, "Device has %lu references left.\n", refcount);
15232 done:
15233 IDirect3D9_Release(d3d);
15234 DestroyWindow(window);
15237 static void depth_buffer_test(void)
15239 static const struct
15241 struct vec3 position;
15242 DWORD diffuse;
15244 quad1[] =
15246 {{-1.0, 1.0, 0.33f}, 0xff00ff00},
15247 {{ 1.0, 1.0, 0.33f}, 0xff00ff00},
15248 {{-1.0, -1.0, 0.33f}, 0xff00ff00},
15249 {{ 1.0, -1.0, 0.33f}, 0xff00ff00},
15251 quad2[] =
15253 {{-1.0, 1.0, 0.50f}, 0xffff00ff},
15254 {{ 1.0, 1.0, 0.50f}, 0xffff00ff},
15255 {{-1.0, -1.0, 0.50f}, 0xffff00ff},
15256 {{ 1.0, -1.0, 0.50f}, 0xffff00ff},
15258 quad3[] =
15260 {{-1.0, 1.0, 0.66f}, 0xffff0000},
15261 {{ 1.0, 1.0, 0.66f}, 0xffff0000},
15262 {{-1.0, -1.0, 0.66f}, 0xffff0000},
15263 {{ 1.0, -1.0, 0.66f}, 0xffff0000},
15265 static const unsigned int expected_colors[4][4] =
15267 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
15268 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
15269 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
15270 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
15273 IDirect3DSurface9 *backbuffer, *rt1, *rt2, *rt3;
15274 IDirect3DDevice9 *device;
15275 unsigned int color, i, j;
15276 D3DVIEWPORT9 vp;
15277 IDirect3D9 *d3d;
15278 ULONG refcount;
15279 HWND window;
15280 HRESULT hr;
15282 window = create_window();
15283 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15284 ok(!!d3d, "Failed to create a D3D object.\n");
15285 if (!(device = create_device(d3d, window, window, TRUE)))
15287 skip("Failed to create a D3D device, skipping tests.\n");
15288 goto done;
15291 vp.X = 0;
15292 vp.Y = 0;
15293 vp.Width = 640;
15294 vp.Height = 480;
15295 vp.MinZ = 0.0;
15296 vp.MaxZ = 1.0;
15298 hr = IDirect3DDevice9_SetViewport(device, &vp);
15299 ok(SUCCEEDED(hr), "SetViewport failed, hr %#lx.\n", hr);
15301 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
15302 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15303 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
15304 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15305 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
15306 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15307 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
15308 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15309 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
15310 ok(SUCCEEDED(hr), "SetFVF failed, hr %#lx.\n", hr);
15312 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
15313 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#lx.\n", hr);
15314 hr = IDirect3DDevice9_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
15315 D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
15316 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#lx.\n", hr);
15317 hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
15318 D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
15319 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#lx.\n", hr);
15320 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
15321 D3DMULTISAMPLE_NONE, 0, FALSE, &rt3, NULL);
15322 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#lx.\n", hr);
15324 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt3);
15325 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#lx.\n", hr);
15326 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
15327 ok(SUCCEEDED(hr), "Clear failed, hr %#lx.\n", hr);
15329 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
15330 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#lx.\n", hr);
15331 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
15332 ok(SUCCEEDED(hr), "Clear failed, hr %#lx.\n", hr);
15334 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
15335 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#lx.\n", hr);
15336 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
15337 ok(SUCCEEDED(hr), "Clear failed, hr %#lx.\n", hr);
15339 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
15340 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#lx.\n", hr);
15341 hr = IDirect3DDevice9_BeginScene(device);
15342 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
15343 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
15344 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
15345 hr = IDirect3DDevice9_EndScene(device);
15346 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
15348 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
15349 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#lx.\n", hr);
15351 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
15352 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15354 hr = IDirect3DDevice9_BeginScene(device);
15355 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
15356 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
15357 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
15358 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
15359 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
15360 hr = IDirect3DDevice9_EndScene(device);
15361 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
15363 for (i = 0; i < 4; ++i)
15365 for (j = 0; j < 4; ++j)
15367 unsigned int x = 80 * ((2 * j) + 1);
15368 unsigned int y = 60 * ((2 * i) + 1);
15369 color = getPixelColor(device, x, y);
15370 ok(color_match(color, expected_colors[i][j], 0),
15371 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
15375 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15376 ok(hr == S_OK, "Got hr %#lx.\n", hr);
15378 IDirect3DSurface9_Release(backbuffer);
15379 IDirect3DSurface9_Release(rt3);
15380 IDirect3DSurface9_Release(rt2);
15381 IDirect3DSurface9_Release(rt1);
15382 refcount = IDirect3DDevice9_Release(device);
15383 ok(!refcount, "Device has %lu references left.\n", refcount);
15384 done:
15385 IDirect3D9_Release(d3d);
15386 DestroyWindow(window);
15389 /* Test that partial depth copies work the way they're supposed to. The clear
15390 * on rt2 only needs a partial copy of the onscreen depth/stencil buffer, and
15391 * the following draw should only copy back the part that was modified. */
15392 static void depth_buffer2_test(void)
15394 static const struct
15396 struct vec3 position;
15397 DWORD diffuse;
15399 quad[] =
15401 {{-1.0f, 1.0f, 0.66f}, 0xffff0000},
15402 {{ 1.0f, 1.0f, 0.66f}, 0xffff0000},
15403 {{-1.0f, -1.0f, 0.66f}, 0xffff0000},
15404 {{ 1.0f, -1.0f, 0.66f}, 0xffff0000},
15407 IDirect3DSurface9 *backbuffer, *rt1, *rt2;
15408 IDirect3DDevice9 *device;
15409 unsigned int color, i, j;
15410 D3DVIEWPORT9 vp;
15411 IDirect3D9 *d3d;
15412 ULONG refcount;
15413 HWND window;
15414 HRESULT hr;
15416 window = create_window();
15417 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15418 ok(!!d3d, "Failed to create a D3D object.\n");
15419 if (!(device = create_device(d3d, window, window, TRUE)))
15421 skip("Failed to create a D3D device, skipping tests.\n");
15422 goto done;
15425 vp.X = 0;
15426 vp.Y = 0;
15427 vp.Width = 640;
15428 vp.Height = 480;
15429 vp.MinZ = 0.0;
15430 vp.MaxZ = 1.0;
15432 hr = IDirect3DDevice9_SetViewport(device, &vp);
15433 ok(SUCCEEDED(hr), "SetViewport failed, hr %#lx.\n", hr);
15435 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
15436 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15437 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
15438 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15439 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
15440 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15441 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
15442 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15443 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
15444 ok(SUCCEEDED(hr), "SetFVF failed, hr %#lx.\n", hr);
15446 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
15447 D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
15448 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#lx.\n", hr);
15449 hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
15450 D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
15451 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#lx.\n", hr);
15452 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
15453 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#lx.\n", hr);
15455 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
15456 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#lx.\n", hr);
15457 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
15458 ok(SUCCEEDED(hr), "Clear failed, hr %#lx.\n", hr);
15460 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
15461 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#lx.\n", hr);
15462 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 0.5f, 0);
15463 ok(SUCCEEDED(hr), "Clear failed, hr %#lx.\n", hr);
15465 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
15466 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#lx.\n", hr);
15467 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
15468 ok(SUCCEEDED(hr), "Clear failed, hr %#lx.\n", hr);
15470 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
15471 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#lx.\n", hr);
15473 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
15474 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15476 hr = IDirect3DDevice9_BeginScene(device);
15477 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
15478 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15479 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
15480 hr = IDirect3DDevice9_EndScene(device);
15481 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
15483 for (i = 0; i < 4; ++i)
15485 for (j = 0; j < 4; ++j)
15487 unsigned int x = 80 * ((2 * j) + 1);
15488 unsigned int y = 60 * ((2 * i) + 1);
15489 color = getPixelColor(device, x, y);
15490 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
15491 "Expected color 0x0000ff00 at %u,%u, got 0x%08x.\n", x, y, color);
15495 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15496 ok(hr == S_OK, "Got hr %#lx.\n", hr);
15498 IDirect3DSurface9_Release(backbuffer);
15499 IDirect3DSurface9_Release(rt2);
15500 IDirect3DSurface9_Release(rt1);
15501 refcount = IDirect3DDevice9_Release(device);
15502 ok(!refcount, "Device has %lu references left.\n", refcount);
15503 done:
15504 IDirect3D9_Release(d3d);
15505 DestroyWindow(window);
15508 static void depth_blit_test(void)
15510 static const struct
15512 struct vec3 position;
15513 DWORD diffuse;
15515 quad1[] =
15517 {{-1.0f, 1.0f, 0.33f}, 0xff00ff00},
15518 {{ 1.0f, 1.0f, 0.33f}, 0xff00ff00},
15519 {{-1.0f, -1.0f, 0.33f}, 0xff00ff00},
15520 {{ 1.0f, -1.0f, 0.33f}, 0xff00ff00},
15522 quad2[] =
15524 {{-1.0f, 1.0f, 0.66f}, 0xff0000ff},
15525 {{ 1.0f, 1.0f, 0.66f}, 0xff0000ff},
15526 {{-1.0f, -1.0f, 0.66f}, 0xff0000ff},
15527 {{ 1.0f, -1.0f, 0.66f}, 0xff0000ff},
15529 static const unsigned int expected_colors[4][4] =
15531 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
15532 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
15533 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
15534 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
15537 IDirect3DSurface9 *backbuffer, *ds1, *ds2, *ds3;
15538 IDirect3DDevice9 *device;
15539 unsigned int color, i, j;
15540 RECT src_rect, dst_rect;
15541 D3DVIEWPORT9 vp;
15542 IDirect3D9 *d3d;
15543 ULONG refcount;
15544 HWND window;
15545 HRESULT hr;
15547 window = create_window();
15548 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15549 ok(!!d3d, "Failed to create a D3D object.\n");
15550 if (!(device = create_device(d3d, window, window, TRUE)))
15552 skip("Failed to create a D3D device, skipping tests.\n");
15553 goto done;
15556 vp.X = 0;
15557 vp.Y = 0;
15558 vp.Width = 640;
15559 vp.Height = 480;
15560 vp.MinZ = 0.0;
15561 vp.MaxZ = 1.0;
15563 hr = IDirect3DDevice9_SetViewport(device, &vp);
15564 ok(SUCCEEDED(hr), "SetViewport failed, hr %#lx.\n", hr);
15566 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
15567 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#lx.\n", hr);
15568 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds1);
15569 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#lx.\n", hr);
15570 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8, 0, 0, FALSE, &ds2, NULL);
15571 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#lx.\n", hr);
15572 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds2);
15573 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#lx.\n", hr);
15574 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 320, 240, D3DFMT_D24S8, 0, 0, FALSE, &ds3, NULL);
15575 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#lx.\n", hr);
15577 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
15578 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15579 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
15580 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15581 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
15582 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15583 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
15584 ok(SUCCEEDED(hr), "SetFVF failed, hr %#lx.\n", hr);
15586 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
15587 ok(SUCCEEDED(hr), "Clear failed, hr %#lx.\n", hr);
15588 SetRect(&dst_rect, 0, 0, 480, 360);
15589 hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 0.5f, 0);
15590 ok(SUCCEEDED(hr), "Clear failed, hr %#lx.\n", hr);
15591 SetRect(&dst_rect, 0, 0, 320, 240);
15592 hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
15593 ok(SUCCEEDED(hr), "Clear failed, hr %#lx.\n", hr);
15595 /* Partial blit. */
15596 SetRect(&src_rect, 0, 0, 320, 240);
15597 SetRect(&dst_rect, 0, 0, 320, 240);
15598 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
15599 ok(hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
15600 /* Flipped. */
15601 SetRect(&src_rect, 0, 0, 640, 480);
15602 SetRect(&dst_rect, 0, 480, 640, 0);
15603 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
15604 ok(hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
15605 /* Full, explicit. */
15606 SetRect(&src_rect, 0, 0, 640, 480);
15607 SetRect(&dst_rect, 0, 0, 640, 480);
15608 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
15609 ok(SUCCEEDED(hr), "StretchRect failed, hr %#lx.\n", hr);
15610 /* Filtered blit. */
15611 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_LINEAR);
15612 ok(SUCCEEDED(hr), "StretchRect failed, hr %#lx.\n", hr);
15613 /* Depth -> color blit.*/
15614 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, backbuffer, NULL, D3DTEXF_POINT);
15615 ok(hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
15616 IDirect3DSurface9_Release(backbuffer);
15617 /* Full surface, different sizes */
15618 hr = IDirect3DDevice9_StretchRect(device, ds3, NULL, ds1, NULL, D3DTEXF_POINT);
15619 ok(hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
15620 hr = IDirect3DDevice9_StretchRect(device, ds1, NULL, ds3, NULL, D3DTEXF_POINT);
15621 ok(hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
15623 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds1);
15624 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#lx.\n", hr);
15625 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
15626 ok(SUCCEEDED(hr), "Clear failed, hr %#lx.\n", hr);
15627 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_POINT);
15628 ok(SUCCEEDED(hr), "StretchRect failed, hr %#lx.\n", hr);
15630 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
15631 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15632 hr = IDirect3DDevice9_BeginScene(device);
15633 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
15634 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
15635 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
15636 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
15637 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
15638 hr = IDirect3DDevice9_EndScene(device);
15639 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
15641 for (i = 0; i < 4; ++i)
15643 for (j = 0; j < 4; ++j)
15645 unsigned int x = 80 * ((2 * j) + 1);
15646 unsigned int y = 60 * ((2 * i) + 1);
15647 color = getPixelColor(device, x, y);
15648 ok(color_match(color, expected_colors[i][j], 0),
15649 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
15653 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15654 ok(hr == S_OK, "Got hr %#lx.\n", hr);
15656 IDirect3DSurface9_Release(ds3);
15657 IDirect3DSurface9_Release(ds2);
15658 IDirect3DSurface9_Release(ds1);
15659 refcount = IDirect3DDevice9_Release(device);
15660 ok(!refcount, "Device has %lu references left.\n", refcount);
15661 done:
15662 IDirect3D9_Release(d3d);
15663 DestroyWindow(window);
15666 static void intz_test(void)
15668 static const DWORD ps_code[] =
15670 0xffff0200, /* ps_2_0 */
15671 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
15672 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
15673 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
15674 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
15675 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
15676 0x03010042, 0x800f0001, 0xb0e40000, 0xa0e40800, /* texldp r1, t0, s0 */
15677 0x02000001, 0x80020000, 0x80000001, /* mov r0.y, r1.x */
15678 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
15679 0x0000ffff, /* end */
15681 struct
15683 float x, y, z;
15684 float s, t, p, q;
15686 quad[] =
15688 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
15689 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
15690 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
15691 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
15693 half_quad_1[] =
15695 { -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
15696 { 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
15697 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
15698 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
15700 half_quad_2[] =
15702 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
15703 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
15704 { -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
15705 { 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
15707 struct
15709 unsigned int x, y, color;
15711 expected_colors[] =
15713 { 80, 100, 0x20204020},
15714 {240, 100, 0x6060bf60},
15715 {400, 100, 0x9f9f409f},
15716 {560, 100, 0xdfdfbfdf},
15717 { 80, 450, 0x20204020},
15718 {240, 450, 0x6060bf60},
15719 {400, 450, 0x9f9f409f},
15720 {560, 450, 0xdfdfbfdf},
15723 IDirect3DSurface9 *original_rt, *rt;
15724 struct surface_readback rb;
15725 IDirect3DTexture9 *texture;
15726 IDirect3DPixelShader9 *ps;
15727 IDirect3DDevice9 *device;
15728 IDirect3DSurface9 *ds;
15729 IDirect3D9 *d3d;
15730 ULONG refcount;
15731 D3DCAPS9 caps;
15732 HWND window;
15733 HRESULT hr;
15734 UINT i;
15736 window = create_window();
15737 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15738 ok(!!d3d, "Failed to create a D3D object.\n");
15739 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
15740 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'))))
15742 skip("No INTZ support, skipping INTZ test.\n");
15743 goto done;
15745 if (!(device = create_device(d3d, window, window, TRUE)))
15747 skip("Failed to create a D3D device, skipping tests.\n");
15748 goto done;
15751 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
15752 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#lx.\n", hr);
15753 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
15755 skip("No pixel shader 2.0 support, skipping INTZ test.\n");
15756 IDirect3DDevice9_Release(device);
15757 goto done;
15759 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
15761 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
15762 IDirect3DDevice9_Release(device);
15763 goto done;
15766 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
15767 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#lx.\n", hr);
15769 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
15770 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
15771 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#lx.\n", hr);
15772 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
15773 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
15774 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#lx.\n", hr);
15775 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
15776 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#lx.\n", hr);
15778 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
15779 ok(SUCCEEDED(hr), "SetFVF failed, hr %#lx.\n", hr);
15780 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
15781 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15782 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
15783 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15784 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
15785 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15786 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
15787 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15789 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
15790 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#lx.\n", hr);
15791 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
15792 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#lx.\n", hr);
15793 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
15794 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#lx.\n", hr);
15795 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
15796 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#lx.\n", hr);
15797 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
15798 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#lx.\n", hr);
15800 /* Render offscreen, using the INTZ texture as depth buffer */
15801 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
15802 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#lx.\n", hr);
15803 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
15804 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#lx.\n", hr);
15805 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15806 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#lx.\n", hr);
15807 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
15808 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#lx.\n", hr);
15810 /* Setup the depth/stencil surface. */
15811 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
15812 ok(SUCCEEDED(hr), "Clear failed, hr %#lx.\n", hr);
15814 hr = IDirect3DDevice9_BeginScene(device);
15815 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
15816 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15817 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
15818 hr = IDirect3DDevice9_EndScene(device);
15819 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
15821 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
15822 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#lx.\n", hr);
15823 IDirect3DSurface9_Release(ds);
15824 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
15825 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#lx.\n", hr);
15826 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
15827 ok(SUCCEEDED(hr), "SetTexture failed, hr %#lx.\n", hr);
15828 hr = IDirect3DDevice9_SetPixelShader(device, ps);
15829 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#lx.\n", hr);
15831 /* Read the depth values back. */
15832 hr = IDirect3DDevice9_BeginScene(device);
15833 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
15834 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15835 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
15836 hr = IDirect3DDevice9_EndScene(device);
15837 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
15839 get_rt_readback(original_rt, &rb);
15840 for (i = 0; i < ARRAY_SIZE(expected_colors); ++i)
15842 unsigned int color = get_readback_color(&rb, expected_colors[i].x, expected_colors[i].y);
15843 ok(color_match(color, expected_colors[i].color, 1),
15844 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
15845 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
15847 release_surface_readback(&rb);
15849 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15850 ok(SUCCEEDED(hr), "Present failed, hr %#lx.\n", hr);
15852 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
15853 ok(SUCCEEDED(hr), "SetTexture failed, hr %#lx.\n", hr);
15854 IDirect3DTexture9_Release(texture);
15856 /* Render onscreen while using the INTZ texture as depth buffer */
15857 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
15858 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
15859 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
15860 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#lx.\n", hr);
15861 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
15862 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#lx.\n", hr);
15863 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
15864 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#lx.\n", hr);
15866 /* Setup the depth/stencil surface. */
15867 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
15868 ok(SUCCEEDED(hr), "Clear failed, hr %#lx.\n", hr);
15870 hr = IDirect3DDevice9_BeginScene(device);
15871 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
15872 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15873 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
15874 hr = IDirect3DDevice9_EndScene(device);
15875 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
15877 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
15878 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#lx.\n", hr);
15879 IDirect3DSurface9_Release(ds);
15880 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
15881 ok(SUCCEEDED(hr), "SetTexture failed, hr %#lx.\n", hr);
15882 hr = IDirect3DDevice9_SetPixelShader(device, ps);
15883 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#lx.\n", hr);
15885 /* Read the depth values back. */
15886 hr = IDirect3DDevice9_BeginScene(device);
15887 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
15888 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15889 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
15890 hr = IDirect3DDevice9_EndScene(device);
15891 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
15893 get_rt_readback(original_rt, &rb);
15894 for (i = 0; i < ARRAY_SIZE(expected_colors); ++i)
15896 unsigned int color = get_readback_color(&rb, expected_colors[i].x, expected_colors[i].y);
15897 ok(color_match(color, expected_colors[i].color, 1),
15898 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
15899 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
15901 release_surface_readback(&rb);
15903 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15904 ok(SUCCEEDED(hr), "Present failed, hr %#lx.\n", hr);
15906 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
15907 ok(SUCCEEDED(hr), "SetTexture failed, hr %#lx.\n", hr);
15908 IDirect3DTexture9_Release(texture);
15910 /* Render offscreen, then onscreen, and finally check the INTZ texture in both areas */
15911 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
15912 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
15913 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
15914 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#lx.\n", hr);
15916 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
15917 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#lx.\n", hr);
15918 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15919 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#lx.\n", hr);
15920 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
15921 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#lx.\n", hr);
15923 /* Setup the depth/stencil surface. */
15924 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
15925 ok(SUCCEEDED(hr), "Clear failed, hr %#lx.\n", hr);
15927 hr = IDirect3DDevice9_BeginScene(device);
15928 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
15929 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_1, sizeof(*half_quad_1));
15930 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
15931 hr = IDirect3DDevice9_EndScene(device);
15932 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
15934 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
15935 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#lx.\n", hr);
15937 hr = IDirect3DDevice9_BeginScene(device);
15938 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
15939 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_2, sizeof(*half_quad_2));
15940 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
15941 hr = IDirect3DDevice9_EndScene(device);
15942 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
15944 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
15945 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#lx.\n", hr);
15946 IDirect3DSurface9_Release(ds);
15947 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
15948 ok(SUCCEEDED(hr), "SetTexture failed, hr %#lx.\n", hr);
15949 hr = IDirect3DDevice9_SetPixelShader(device, ps);
15950 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#lx.\n", hr);
15952 /* Read the depth values back. */
15953 hr = IDirect3DDevice9_BeginScene(device);
15954 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
15955 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15956 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
15957 hr = IDirect3DDevice9_EndScene(device);
15958 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
15960 get_rt_readback(original_rt, &rb);
15961 for (i = 0; i < ARRAY_SIZE(expected_colors); ++i)
15963 unsigned int color = get_readback_color(&rb, expected_colors[i].x, expected_colors[i].y);
15964 ok(color_match(color, expected_colors[i].color, 1),
15965 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
15966 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
15968 release_surface_readback(&rb);
15970 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15971 ok(SUCCEEDED(hr), "Present failed, hr %#lx.\n", hr);
15973 IDirect3DTexture9_Release(texture);
15974 IDirect3DPixelShader9_Release(ps);
15975 IDirect3DSurface9_Release(original_rt);
15976 IDirect3DSurface9_Release(rt);
15977 refcount = IDirect3DDevice9_Release(device);
15978 ok(!refcount, "Device has %lu references left.\n", refcount);
15979 done:
15980 IDirect3D9_Release(d3d);
15981 DestroyWindow(window);
15984 static void test_fetch4(void)
15986 static const DWORD vs_code[] =
15988 0xfffe0300, /* vs_3_0 */
15989 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
15990 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
15991 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
15992 0x0200001f, 0x80000005, 0xe00f0001, /* dcl_texcoord o1 */
15993 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
15994 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
15995 0x0000ffff,
15997 static const DWORD ps_code_texld[] =
15999 0xffff0300, /* ps_3_0 */
16000 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord v0 */
16001 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
16002 0x03000042, 0x800f0000, 0x90e40000, 0xa0e40800, /* texld r0, v0, s0 */
16003 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
16004 0x0000ffff, /* end */
16006 /* AMD and Wine use the projection on Fetch4, Intel UHD ignores it. */
16007 static const DWORD ps_code_texldp[] =
16009 0xffff0300, /* ps_3_0 */
16010 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord v0 */
16011 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
16012 /* The idea here is that if we project from .z, we get a 4x zoom. From
16013 * .w a 2x zoom. */
16014 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x40800000, 0x40000000, /* def c0, 0.0, 0.0, 4.0, 2.0 */
16015 0x02000001, 0x80030000, 0x90f40000, /* mov r0.xy, v0.xyww */
16016 0x02000001, 0x800c0000, 0xa0e00000, /* mov r0.zw, c0.xxzw */
16017 0x03010042, 0x800f0000, 0x80e40000, 0xa0e40800, /* texldp r0, r0, s0 */
16018 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
16019 0x0000ffff, /* end */
16021 static const DWORD ps_code_swizzle[] =
16023 /* Test texld when sampling with a .yzwx swizzle. */
16024 0xffff0300, /* ps_3_0 */
16025 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord v0 */
16026 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
16027 0x03000042, 0x800f0000, 0x90e40000, 0xa0390800, /* texld r0, v0, s0.yzwx */
16028 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
16029 0x0000ffff, /* end */
16031 /* Fetch4 uses the same D3D state as LOD bias, and therefore disables LOD
16032 * handling. Texldd/texldb/texldl give the same result as plain texld. */
16033 /* NOTE: The Radeon HD 5700 driver 8.17.10.1404 disables Fetch4 on these
16034 * instructions. */
16035 static const DWORD ps_code_texldd[] =
16037 0xffff0300, /* ps_3_0 */
16038 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord v0 */
16039 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
16040 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
16041 0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0 */
16042 0x02000001, 0x800f0002, 0xa0e40000, /* mov r2, c0 */
16043 0x0500005d, 0x800f0000, 0x90e40000, 0xa0e40800, 0xa0e40000, 0x80e40002, /* texldd r0, v0, s0, c0, r2 */
16044 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
16045 0x0000ffff, /* end */
16047 static const DWORD ps_code_texldb[] =
16049 0xffff0300, /* ps_3_0 */
16050 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord v0 */
16051 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
16052 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x40a00000, 0x40a00000, /* def c0, 0.0, 0.0, 5.0, 5.0 */
16053 0x03000002, 0x800f0000, 0x90e40000, 0xa0e40000, /* add r0, v0, c0 */
16054 0x03020042, 0x800f0000, 0x80e40000, 0xa0e40800, /* texldb r0, r0, s0 */
16055 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
16056 0x0000ffff, /* end */
16058 static const DWORD ps_code_texldl[] =
16060 0xffff0300, /* ps_3_0 */
16061 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord v0 */
16062 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
16063 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f000000, 0x3f000000, /* def c0, 0.0, 0.0, 0.5, 0.5 */
16064 0x03000002, 0x800f0000, 0x90e40000, 0xa0e40000, /* add r0, v0, c0 */
16065 0x0300005f, 0x800f0000, 0x80e40000, 0xa0e40800, /* texldl r0, r0, s0 */
16066 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
16067 0x0000ffff, /* end */
16069 static const DWORD ps_code_3d[] =
16071 0xffff0300, /* ps_3_0 */
16072 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord v0 */
16073 0x0200001f, 0xa0000000, 0xa00f0800, /* dcl_volume s0 */
16074 0x03000042, 0x800f0000, 0x90e40000, 0xa0e40800, /* texld r0, v0, s0 */
16075 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
16076 0x0000ffff, /* end */
16079 static const struct
16081 struct vec3 position;
16082 struct vec4 texcoord;
16084 quad[] =
16086 {{-1.0f, 1.0f, 1.0f}, {0.0f, 0.0f, 4.0f, 2.0f}},
16087 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.0f, 4.0f, 2.0f}},
16088 {{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f, 4.0f, 2.0f}},
16089 {{ 1.0f, -1.0f, 0.0f}, {1.0f, 1.0f, 4.0f, 2.0f}},
16091 quad2[] =
16093 /* Tilted on the z-axis to get a depth gradient in the depth test. */
16094 /* Note: Using 0.55f-0.6f to avoid rounding errors on depth tests. */
16095 {{-1.0f, 1.0f, 1.0f}, {0.0f, 0.0f, 0.6f, 0.0f}},
16096 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.0f, 0.6f, 0.0f}},
16097 {{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f, 0.6f, 0.0f}},
16098 {{ 1.0f, -1.0f, 0.0f}, {1.0f, 1.0f, 0.6f, 0.0f}},
16101 static const struct
16103 unsigned int x[4], y[4];
16104 D3DCOLOR colour_amd[16];
16105 D3DCOLOR colour_intel[16];
16106 D3DCOLOR colour_fetch4_off[16];
16107 D3DCOLOR colour_3d_fetch4_off[16];
16108 D3DCOLOR colour_3d_amd_zround[16];
16110 expected_colours =
16112 /* Sample positions. */
16113 {40, 200, 360, 520},
16114 {30, 150, 270, 390},
16115 /* AMD implementation (-0.5 texel offsets). */
16116 {0x131202f2, 0x1211f2f1, 0x1110f101, 0x10100101,
16117 0x02f204f4, 0xf2f1f4f3, 0xf101f303, 0x01010303,
16118 0x04f42322, 0xf4f32221, 0xf3032120, 0x03032020,
16119 0x23222322, 0x22212221, 0x21202120, 0x20202020},
16120 /* Intel UHD 620 implementation (no texel offsets).
16121 * We treat the Intel results as broken. */
16122 {0x13131313, 0x12131312, 0x11121211, 0x10111110,
16123 0x13021302, 0x120213f2, 0x11f212f1, 0x10f11101,
16124 0x02040204, 0xf20402f4, 0xf1f4f2f3, 0x01f3f103,
16125 0x04230423, 0xf4230422, 0xf322f421, 0x0321f320},
16126 /* Fetch4 off on 2D textures. */
16127 {0x13131313, 0x12121212, 0x11111111, 0x10101010,
16128 0x02020202, 0xf2f2f2f2, 0xf1f1f1f1, 0x01010101,
16129 0x04040404, 0xf4f4f4f4, 0xf3f3f3f3, 0x03030303,
16130 0x23232323, 0x22222222, 0x21212121, 0x20202020},
16131 /* Fetch4 off on 3D textures. */
16132 {0xff020202, 0xfff2f2f2, 0xfff1f1f1, 0xff010101,
16133 0xff050505, 0xfff4f4f4, 0xfff3f3f3, 0xff030303,
16134 0xff232323, 0xff222222, 0xff212121, 0xff202020,
16135 0xff131313, 0xff121212, 0xff111111, 0xff101010},
16136 /* Fetch4 on, 3D texture without nearest z rounding. */
16137 {0x02f204f4, 0xf2f1f4f3, 0xf101f303, 0x01010303,
16138 0x04f42322, 0xf4f32221, 0xf3032120, 0x03032020,
16139 0x23221312, 0x22211211, 0x21201110, 0x20201010,
16140 0x13121312, 0x12111211, 0x11101110, 0x10101010},
16143 static const DWORD fetch4_data[] = {0x10111213, 0x01f1f202, 0x03f3f404, 0x20212223};
16145 static const struct
16147 const char *name;
16148 const DWORD *ps_code;
16149 unsigned int projection;
16150 BOOL swizzled;
16151 DWORD ttff_flags;
16153 shaders[] =
16155 {"FFP", NULL, 0, FALSE, 0},
16156 {"texld", ps_code_texld, 0, FALSE, 0},
16157 {"texldp", ps_code_texldp, 2, FALSE, 0},
16158 {"texld_yzwx", ps_code_swizzle, 0, TRUE , 0},
16159 {"texldd", ps_code_texldd, 0, FALSE, 0},
16160 {"texldb", ps_code_texldb, 0, FALSE, 0},
16161 {"texldl", ps_code_texldl, 0, FALSE, 0},
16162 {"FFP_proj", NULL, 2, FALSE, D3DTTFF_PROJECTED},
16163 {"FFP_proj3", NULL, 4, FALSE, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED},
16166 static const struct
16168 const char *name;
16169 D3DFORMAT format;
16170 DWORD data;
16171 unsigned int x, y;
16172 unsigned int w, h;
16173 D3DCOLOR colour_amd[3];
16174 D3DCOLOR colour_intel[3];
16175 BOOL todo;
16177 format_tests[] =
16179 /* Enabled formats */
16181 "L8", D3DFMT_L8,
16182 0xff804010, 360, 30, 2, 2,
16183 {0x40400000, 0x40400000, 0x10400000},
16184 {0x40101040, 0x40101040, 0x40101040},
16187 "L16", D3DFMT_L16,
16188 0xff804010, 360, 30, 2, 2,
16189 {0xffff0000, 0xffff0000, 0x40ff0000},
16190 {0xff4040ff, 0xff4040ff, 0xff4040ff},
16193 "R16F", D3DFMT_R16F,
16194 0x38003c00, 360, 30, 2, 2,
16195 {0x80800000, 0x80800000, 0xff800000},
16196 {0x80ffff80, 0x80ffff80, 0x80ffff80},
16199 "R32F", D3DFMT_R32F,
16200 0x3f000000, 360, 30, 2, 2,
16201 {0x00000000, 0x00000000, 0x80000000},
16202 {0x00808000, 0x00808000, 0x00808000},
16205 "ATI1", MAKEFOURCC('A','T','I','1'),
16206 0xb97700ff, 360, 30, 4, 4,
16207 {0x6d6d6d6d, 0x6d6d6d6d, 0x49494949},
16208 {0xff6d00ff, 0xff6d00ff, 0xff4900ff},
16210 /* Unsupported on Intel, broken in Wine. */
16212 "A8", D3DFMT_A8,
16213 0xff804010, 360, 30, 2, 2,
16214 {0x40400000, 0x40400000, 0x10400000},
16215 {0x00000000, 0x00000000, 0x00000000},
16216 TRUE,
16218 /* Unsupported format. */
16220 "A8R8G8B8", D3DFMT_A8R8G8B8,
16221 0xff804010, 360, 270, 2, 2,
16222 {0x00000000, 0x00000000, 0xff804010},
16223 {0x00000000, 0x00000000, 0xff804010},
16227 static const struct
16229 D3DCOLOR colour_off, colour_amd, colour_intel;
16230 unsigned int x, y;
16232 expected_depth[][4] =
16235 /* Shadow samplers. */
16236 {0xffffffff, 0xffffffff, 0xffffffff, 20, 15},
16237 {0xffffffff, 0xffffffff, 0xffffffff, 260, 15},
16238 {0x00000000, 0x00000000, 0x00000000, 20, 255},
16239 {0x00000000, 0x00000000, 0x00000000, 260, 135},
16242 /* DF16. */
16243 {0xfffe0000, 0xfedfdfbf, 0xffffffff, 20, 15},
16244 {0xff9f0000, 0x9f7f7f5f, 0x9fbfbf9f, 260, 15},
16245 {0xff800000, 0x7f5f5f3f, 0x9f809f80, 20, 255},
16246 {0xff600000, 0x5f3f3f1f, 0x80809f60, 260, 135},
16249 /* DF24. */
16250 {0xffff0000, 0xffdfdfbf, 0xffffffff, 20, 15},
16251 {0xff9f0000, 0x9f7f7f5f, 0x9fbfbf9f, 260, 15},
16252 {0xff800000, 0x7f5f5f3f, 0x9f809f80, 20, 255},
16253 {0xff600000, 0x5f3f3f1f, 0x80809f60, 260, 135},
16256 /* INTZ. */
16257 {0xffffffff, 0xffdfdfbf, 0xffffffff, 20, 15},
16258 {0x9f9f9f9f, 0x9f7f7f5f, 0x9fbfbf9f, 260, 15},
16259 {0x7f7f7f7f, 0x7f5f5f3f, 0x9f809f80, 20, 255},
16260 {0x5f5f5f5f, 0x5f3f3f1f, 0x80809f60, 260, 135},
16264 static const struct
16266 const char *name;
16267 D3DFORMAT format;
16268 unsigned int index;
16270 depth_tests[] =
16272 {"D16_LOCKABLE", D3DFMT_D16_LOCKABLE, 0},
16273 {"D32", D3DFMT_D32, 0},
16274 {"D15S1", D3DFMT_D15S1, 0},
16275 {"D24S8", D3DFMT_D24S8, 0},
16276 {"D24X8", D3DFMT_D24X8, 0},
16277 {"D24X4S4", D3DFMT_D24X4S4, 0},
16278 {"D16", D3DFMT_D16, 0},
16279 {"D32F_LOCKABLE", D3DFMT_D32F_LOCKABLE, 0},
16280 {"D24FS8", D3DFMT_D24FS8, 0},
16281 {"DF16", MAKEFOURCC('D','F','1','6'), 1},
16282 {"DF24", MAKEFOURCC('D','F','2','4'), 2},
16283 {"INTZ", MAKEFOURCC('I','N','T','Z'), 3},
16286 unsigned int colour, colour_amd, colour_intel, colour_off, colour_zround, i, j, k, x, y;
16287 IDirect3DPixelShader9 *ps[ARRAY_SIZE(shaders)];
16288 IDirect3DVolumeTexture9 *texture_3d;
16289 IDirect3DSurface9 *original_rt, *rt;
16290 IDirect3DPixelShader9 *ps_3d;
16291 struct surface_readback rb;
16292 IDirect3DVertexShader9 *vs;
16293 IDirect3DTexture9 *texture;
16294 IDirect3DDevice9 *device;
16295 D3DLOCKED_RECT lr;
16296 D3DLOCKED_BOX lb;
16297 IDirect3D9 *d3d;
16298 ULONG refcount;
16299 D3DCAPS9 caps;
16300 HWND window;
16301 HRESULT hr;
16303 window = create_window();
16304 d3d = Direct3DCreate9(D3D_SDK_VERSION);
16305 ok(!!d3d, "Failed to create a D3D object.\n");
16306 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
16307 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('D','F','2','4'))))
16309 skip("No DF24 support, skipping Fetch4 test.\n");
16310 goto done;
16312 if (!(device = create_device(d3d, window, window, TRUE)))
16314 skip("Failed to create a D3D device, skipping tests.\n");
16315 goto done;
16318 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
16319 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16320 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0))
16322 skip("No pixel shader 3.0 support, skipping FETCH4 test.\n");
16323 IDirect3DDevice9_Release(device);
16324 goto done;
16326 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
16327 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16328 hr = IDirect3DDevice9_CreateRenderTarget(device, 8, 8, D3DFMT_A8R8G8B8,
16329 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
16330 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16332 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
16333 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16334 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
16335 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16336 for (i = 0; i < ARRAY_SIZE(fetch4_data); ++i)
16337 memcpy((BYTE *)lr.pBits + i * lr.Pitch, &fetch4_data[i], sizeof(fetch4_data[i]));
16338 hr = IDirect3DTexture9_UnlockRect(texture, 0);
16339 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16341 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
16342 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16343 for (i = 0; i < ARRAY_SIZE(shaders); ++i)
16345 if (!shaders[i].ps_code)
16347 ps[i] = NULL;
16348 continue;
16351 hr = IDirect3DDevice9_CreatePixelShader(device, shaders[i].ps_code, &ps[i]);
16352 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16354 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_3d, &ps_3d);
16355 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16357 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
16358 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16359 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
16360 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16361 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
16362 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16363 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
16364 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16365 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
16366 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16367 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
16368 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16370 /* According to the documentation, Fetch4 is enabled when
16371 * D3DSAMP_MIPMAPLODBIAS == GET4 and D3DSAMP_MAGFILTER == D3DTEXF_POINT.
16372 * In practice, it seems that only GET4 is required.
16374 * AMD r500 hardware always uses POINT filtering with Fetch4. The driver
16375 * later on corrected this by adding a -0.5 texel offset. */
16376 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPMAPLODBIAS, MAKEFOURCC('G','E','T','4'));
16377 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16378 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
16379 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16380 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
16381 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16382 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
16383 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16384 /* Fetch4 should work with any texture wrapping mode, and does in Wine.
16385 * However, AMD RX 580 devices force clamping when fetch4 is on.
16386 * No other driver/hardware does this, but to avoid problems, we test with
16387 * CLAMP on. */
16388 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
16389 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16390 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
16391 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16392 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
16393 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16395 /* Test basic Fetch4 sampling. */
16396 for (i = 0; i < ARRAY_SIZE(shaders); ++i)
16398 hr = IDirect3DDevice9_SetVertexShader(device, ps[i] ? vs : NULL);
16399 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16400 hr = IDirect3DDevice9_SetPixelShader(device, ps[i]);
16401 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16402 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, shaders[i].ttff_flags);
16403 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16405 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
16406 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16407 hr = IDirect3DDevice9_BeginScene(device);
16408 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16409 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16410 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16411 hr = IDirect3DDevice9_EndScene(device);
16412 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16414 get_rt_readback(original_rt, &rb);
16415 for (j = 0; j < ARRAY_SIZE(expected_colours.colour_amd); ++j)
16417 unsigned int projection = shaders[i].projection;
16419 x = expected_colours.x[j % 4];
16420 y = expected_colours.y[j / 4];
16421 colour_amd = expected_colours.colour_amd[j];
16422 if (projection)
16423 colour_amd = expected_colours.colour_amd[j / 4 / projection * 4 + (j % 4) / projection];
16424 if (shaders[i].swizzled)
16425 colour_amd = (colour_amd << 8) | (colour_amd >> 24);
16426 colour_intel = expected_colours.colour_intel[j];
16427 colour_off = expected_colours.colour_fetch4_off[j];
16428 colour = get_readback_color(&rb, x, y);
16430 ok(color_match(colour, colour_amd, 1) || broken(color_match(colour, colour_intel, 1))
16431 || broken(color_match(colour, colour_off, 1)),
16432 "Test %s: Got unexpected colour 0x%08x at (%u, %u).\n",
16433 shaders[i].name, colour, x, y);
16435 release_surface_readback(&rb);
16437 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16438 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16440 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, 0);
16441 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16443 /* Test Fetch4 format support. */
16444 for (i = 0; i < ARRAY_SIZE(format_tests); ++i)
16446 IDirect3DTexture9 *tex;
16448 hr = IDirect3DDevice9_CreateTexture(device, format_tests[i].w, format_tests[i].h,
16449 1, 0, format_tests[i].format, D3DPOOL_MANAGED, &tex, NULL);
16450 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16451 hr = IDirect3DTexture9_LockRect(tex, 0, &lr, NULL, 0);
16452 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16453 memcpy(lr.pBits, &format_tests[i].data, 4);
16454 hr = IDirect3DTexture9_UnlockRect(tex, 0);
16455 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16456 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex);
16457 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16459 for (j = 0; j < ARRAY_SIZE(format_tests[i].colour_amd); ++j)
16461 hr = IDirect3DDevice9_SetVertexShader(device, ps[j] ? vs : NULL);
16462 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16463 hr = IDirect3DDevice9_SetPixelShader(device, ps[j]);
16464 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16466 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
16467 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16468 hr = IDirect3DDevice9_BeginScene(device);
16469 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16470 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
16471 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16472 hr = IDirect3DDevice9_EndScene(device);
16473 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16475 get_rt_readback(original_rt, &rb);
16476 colour_amd = format_tests[i].colour_amd[j];
16477 colour_intel = format_tests[i].colour_intel[j];
16478 colour = get_readback_color(&rb, format_tests[i].x, format_tests[i].y);
16479 /* On windows just test the R channel, since G/B might be 0xff or 0x00. */
16480 todo_wine_if(format_tests[i].todo)
16481 ok(color_match(colour, colour_amd, 2) || broken(color_match(colour, colour_intel, 2))
16482 || broken(color_match(colour & 0x00ff0000, colour_amd & 0x00ff0000, 2)),
16483 "Test %s on %s: Got unexpected colour 0x%08x at (%u, %u).\n",
16484 shaders[j].name, format_tests[i].name, colour, format_tests[i].x, format_tests[i].y);
16485 release_surface_readback(&rb);
16487 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16488 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16490 IDirect3DTexture9_Release(tex);
16493 hr = IDirect3DDevice9_CreateVolumeTexture(device, 4, 4, 2, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture_3d, NULL);
16494 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16495 hr = IDirect3DVolumeTexture9_LockBox(texture_3d, 0, &lb, NULL, 0);
16496 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16497 for (i = 0; i < ARRAY_SIZE(fetch4_data); ++i)
16499 memcpy((BYTE *)lb.pBits + i * lb.RowPitch, &fetch4_data[i], sizeof(fetch4_data[i]));
16500 /* Shift the lower level, to keep it different. */
16501 memcpy((BYTE *)lb.pBits + i * lb.RowPitch + lb.SlicePitch, &fetch4_data[(i + 1) % 4], sizeof(fetch4_data[i]));
16503 hr = IDirect3DVolumeTexture9_UnlockBox(texture_3d, 0);
16504 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16505 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture_3d);
16506 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16508 /* Test Fetch4 with 3D textures. */
16509 for (i = 0; i < 2; ++i)
16511 hr = IDirect3DDevice9_SetVertexShader(device, i ? vs : NULL);
16512 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16513 hr = IDirect3DDevice9_SetPixelShader(device, i ? ps_3d : NULL);
16514 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16516 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
16517 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16518 hr = IDirect3DDevice9_BeginScene(device);
16519 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16520 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
16521 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16522 hr = IDirect3DDevice9_EndScene(device);
16523 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16524 get_rt_readback(original_rt, &rb);
16525 for (j = 0; j < ARRAY_SIZE(expected_colours.colour_amd); ++j)
16527 x = expected_colours.x[j % 4];
16528 y = expected_colours.y[j / 4];
16529 colour_amd = expected_colours.colour_amd[j];
16530 colour_intel = expected_colours.colour_intel[j];
16531 colour_off = expected_colours.colour_3d_fetch4_off[j];
16532 colour_zround = expected_colours.colour_3d_amd_zround[j];
16533 colour = get_readback_color(&rb, x, y);
16535 /* Note: Fetch4 on 3D textures have different results based on the vendor/driver
16536 * - AMD "HD 5700" rounds to nearest "z" texel, and does fetch4 normally on .xy
16537 * - AMD "R500" has fetch4 disabled
16538 * - AMD "R580" has fetch4 enabled sampling at .xy0
16539 * - Intel UHD 620 sample with fetch4 at .xy0 */
16540 ok(color_match(colour, colour_off, 2) || broken(color_match(colour, colour_zround, 2)
16541 || color_match(colour, colour_intel, 2) || color_match(colour, colour_amd, 2)),
16542 "Test 3D %s: Got unexpected colour 0x%08x at (%u, %u).\n", shaders[i].name, colour, x, y);
16544 release_surface_readback(&rb);
16545 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16546 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16549 /* Test Fetch4 with depth textures. */
16550 for (i = 0; i < ARRAY_SIZE(depth_tests); ++i)
16552 D3DFORMAT format = depth_tests[i].format;
16553 IDirect3DTexture9 *depth_texture;
16554 IDirect3DSurface9 *ds;
16556 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
16557 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format)))
16559 skip("Skipping %s depth test, unsupported format.\n", depth_tests[i].name);
16560 continue;
16563 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1,
16564 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &depth_texture, NULL);
16565 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16566 hr = IDirect3DTexture9_GetSurfaceLevel(depth_texture, 0, &ds);
16567 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16568 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16569 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16570 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
16571 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16572 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
16573 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16574 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
16575 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16576 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
16577 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16578 hr = IDirect3DDevice9_SetSamplerState(device, 0,
16579 D3DSAMP_MIPMAPLODBIAS, MAKEFOURCC('G','E','T','1'));
16580 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16582 /* Setup the depth/stencil surface. */
16583 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
16584 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16586 /* Render to the depth surface. */
16587 hr = IDirect3DDevice9_BeginScene(device);
16588 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16589 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
16590 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16591 hr = IDirect3DDevice9_EndScene(device);
16592 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16594 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16595 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16596 IDirect3DSurface9_Release(ds);
16597 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
16598 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16599 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)depth_texture);
16600 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16602 /* Set a shader for depth sampling, otherwise Windows does not show
16603 * anything. */
16604 hr = IDirect3DDevice9_SetVertexShader(device, vs);
16605 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16606 hr = IDirect3DDevice9_SetPixelShader(device, ps[1]); /* texld */
16607 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16609 for (j = 0; j < 2; ++j)
16611 hr = IDirect3DDevice9_SetSamplerState(device, 0,
16612 D3DSAMP_MIPMAPLODBIAS, MAKEFOURCC('G','E','T', j ? '4' : '1' ));
16613 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16615 /* Do the actual shadow mapping. */
16616 hr = IDirect3DDevice9_BeginScene(device);
16617 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16618 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
16619 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16620 hr = IDirect3DDevice9_EndScene(device);
16621 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16623 get_rt_readback(original_rt, &rb);
16624 for (k = 0; k < ARRAY_SIZE(expected_depth[depth_tests[i].index]); ++k)
16626 x = expected_depth[depth_tests[i].index][k].x;
16627 y = expected_depth[depth_tests[i].index][k].y;
16628 colour_amd = expected_depth[depth_tests[i].index][k].colour_amd;
16629 colour_intel = expected_depth[depth_tests[i].index][k].colour_intel;
16630 colour_off = expected_depth[depth_tests[i].index][k].colour_off;
16631 colour = get_readback_color(&rb, x, y);
16633 /* When Fetch4 is off, ignore the .g and .b channels on
16634 * windows. Some implementations will replicate the .r channel
16635 * to .g and .b, others will return 0 for .g and .b. */
16636 if (!j)
16637 ok(color_match(colour, colour_off, 2)
16638 || broken(color_match(colour & 0x00ff0000, colour_off & 0x00ff0000, 2)),
16639 "Test off: Got unexpected colour 0x%08x for format %s at (%u, %u).\n",
16640 colour, depth_tests[i].name, x, y);
16641 else
16642 ok(color_match(colour, colour_amd, 2) || broken(color_match(colour, colour_intel, 2)),
16643 "Test on: Got unexpected colour 0x%08x for format %s at (%u, %u).\n",
16644 colour, depth_tests[i].name, x, y);
16646 release_surface_readback(&rb);
16648 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16649 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16652 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
16653 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16654 IDirect3DTexture9_Release(depth_texture);
16657 IDirect3DVolumeTexture9_Release(texture_3d);
16658 IDirect3DTexture9_Release(texture);
16659 for (i = 0; i < ARRAY_SIZE(ps); ++i)
16661 if (ps[i])
16662 IDirect3DPixelShader9_Release(ps[i]);
16664 IDirect3DPixelShader9_Release(ps_3d);
16665 IDirect3DVertexShader9_Release(vs);
16666 IDirect3DSurface9_Release(rt);
16667 IDirect3DSurface9_Release(original_rt);
16668 refcount = IDirect3DDevice9_Release(device);
16669 ok(!refcount, "Device has %lu references left.\n", refcount);
16670 done:
16671 IDirect3D9_Release(d3d);
16672 DestroyWindow(window);
16675 static void shadow_test(void)
16677 static const DWORD ps_code[] =
16679 0xffff0200, /* ps_2_0 */
16680 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
16681 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
16682 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
16683 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
16684 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
16685 0x03010042, 0x800f0001, 0xb0e40000, 0xa0e40800, /* texldp r1, t0, s0 */
16686 0x02000001, 0x80020000, 0x80000001, /* mov r0.y, r1.x */
16687 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
16688 0x0000ffff, /* end */
16690 struct
16692 D3DFORMAT format;
16693 const char *name;
16695 formats[] =
16697 {D3DFMT_D16_LOCKABLE, "D3DFMT_D16_LOCKABLE"},
16698 {D3DFMT_D32, "D3DFMT_D32"},
16699 {D3DFMT_D15S1, "D3DFMT_D15S1"},
16700 {D3DFMT_D24S8, "D3DFMT_D24S8"},
16701 {D3DFMT_D24X8, "D3DFMT_D24X8"},
16702 {D3DFMT_D24X4S4, "D3DFMT_D24X4S4"},
16703 {D3DFMT_D16, "D3DFMT_D16"},
16704 {D3DFMT_D32F_LOCKABLE, "D3DFMT_D32F_LOCKABLE"},
16705 {D3DFMT_D24FS8, "D3DFMT_D24FS8"},
16707 struct
16709 float x, y, z;
16710 float s, t, p, q;
16712 quad[] =
16714 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
16715 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
16716 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
16717 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
16719 struct
16721 unsigned int x, y, color;
16723 expected_colors[] =
16725 {400, 60, 0x00000000},
16726 {560, 180, 0xffff00ff},
16727 {560, 300, 0xffff00ff},
16728 {400, 420, 0xffffffff},
16729 {240, 420, 0xffffffff},
16730 { 80, 300, 0x00000000},
16731 { 80, 180, 0x00000000},
16732 {240, 60, 0x00000000},
16735 IDirect3DSurface9 *original_ds, *original_rt, *rt;
16736 struct surface_readback rb;
16737 IDirect3DPixelShader9 *ps;
16738 IDirect3DDevice9 *device;
16739 IDirect3D9 *d3d;
16740 ULONG refcount;
16741 D3DCAPS9 caps;
16742 HWND window;
16743 HRESULT hr;
16744 UINT i;
16746 window = create_window();
16747 d3d = Direct3DCreate9(D3D_SDK_VERSION);
16748 ok(!!d3d, "Failed to create a D3D object.\n");
16749 if (!(device = create_device(d3d, window, window, TRUE)))
16751 skip("Failed to create a D3D device, skipping tests.\n");
16752 goto done;
16755 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
16756 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#lx.\n", hr);
16757 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
16759 skip("No pixel shader 2.0 support, skipping shadow test.\n");
16760 IDirect3DDevice9_Release(device);
16761 goto done;
16764 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
16765 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#lx.\n", hr);
16766 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
16767 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#lx.\n", hr);
16769 hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
16770 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
16771 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#lx.\n", hr);
16772 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
16773 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#lx.\n", hr);
16775 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
16776 ok(SUCCEEDED(hr), "SetFVF failed, hr %#lx.\n", hr);
16777 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
16778 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
16779 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
16780 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
16781 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
16782 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
16783 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
16784 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
16786 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
16787 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#lx.\n", hr);
16788 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
16789 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#lx.\n", hr);
16790 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
16791 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#lx.\n", hr);
16792 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
16793 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#lx.\n", hr);
16794 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
16795 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#lx.\n", hr);
16797 for (i = 0; i < ARRAY_SIZE(formats); ++i)
16799 D3DFORMAT format = formats[i].format;
16800 IDirect3DTexture9 *texture;
16801 IDirect3DSurface9 *ds;
16802 unsigned int j;
16804 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
16805 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format)))
16806 continue;
16808 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
16809 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture, NULL);
16810 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#lx.\n", hr);
16812 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
16813 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#lx.\n", hr);
16815 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16816 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#lx.\n", hr);
16818 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
16819 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#lx.\n", hr);
16821 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
16822 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#lx.\n", hr);
16824 /* Setup the depth/stencil surface. */
16825 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
16826 ok(SUCCEEDED(hr), "Clear failed, hr %#lx.\n", hr);
16828 hr = IDirect3DDevice9_BeginScene(device);
16829 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
16830 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16831 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
16832 hr = IDirect3DDevice9_EndScene(device);
16833 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
16835 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16836 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#lx.\n", hr);
16837 IDirect3DSurface9_Release(ds);
16839 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
16840 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#lx.\n", hr);
16842 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
16843 ok(SUCCEEDED(hr), "SetTexture failed, hr %#lx.\n", hr);
16845 hr = IDirect3DDevice9_SetPixelShader(device, ps);
16846 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#lx.\n", hr);
16848 /* Do the actual shadow mapping. */
16849 hr = IDirect3DDevice9_BeginScene(device);
16850 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
16851 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16852 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
16853 hr = IDirect3DDevice9_EndScene(device);
16854 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
16856 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
16857 ok(SUCCEEDED(hr), "SetTexture failed, hr %#lx.\n", hr);
16858 IDirect3DTexture9_Release(texture);
16860 get_rt_readback(original_rt, &rb);
16861 for (j = 0; j < ARRAY_SIZE(expected_colors); ++j)
16863 unsigned int color = get_readback_color(&rb, expected_colors[j].x, expected_colors[j].y);
16864 /* Geforce 7 on Windows returns 1.0 in alpha when the depth format is D24S8 or D24X8,
16865 * whereas other GPUs (all AMD, newer Nvidia) return the same value they return in .rgb.
16866 * Accept alpha mismatches as broken but make sure to check the color channels. */
16867 ok(color_match(color, expected_colors[j].color, 0)
16868 || broken(color_match(color & 0x00ffffff, expected_colors[j].color & 0x00ffffff, 0)),
16869 "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
16870 expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
16871 formats[i].name, color);
16873 release_surface_readback(&rb);
16875 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16876 ok(SUCCEEDED(hr), "Present failed, hr %#lx.\n", hr);
16879 IDirect3DPixelShader9_Release(ps);
16880 IDirect3DSurface9_Release(original_ds);
16881 IDirect3DSurface9_Release(original_rt);
16882 IDirect3DSurface9_Release(rt);
16883 refcount = IDirect3DDevice9_Release(device);
16884 ok(!refcount, "Device has %lu references left.\n", refcount);
16885 done:
16886 IDirect3D9_Release(d3d);
16887 DestroyWindow(window);
16890 static void clip_planes(IDirect3DDevice9 *device, const char *test_name)
16892 static const struct
16894 struct vec3 position;
16895 DWORD diffuse;
16897 quad1[] =
16899 {{-1.0f, -1.0f, 0.0f}, 0xfff9e814},
16900 {{-1.0f, 1.0f, 0.0f}, 0xfff9e814},
16901 {{ 1.0f, -1.0f, 0.0f}, 0xfff9e814},
16902 {{ 1.0f, 1.0f, 0.0f}, 0xfff9e814},
16904 quad2[] =
16906 {{-1.0f, -1.0f, 0.0f}, 0xff002b7f},
16907 {{-1.0f, 1.0f, 0.0f}, 0xff002b7f},
16908 {{ 1.0f, -1.0f, 0.0f}, 0xff002b7f},
16909 {{ 1.0f, 1.0f, 0.0f}, 0xff002b7f},
16911 unsigned int color;
16912 HRESULT hr;
16914 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 1.0, 0);
16915 ok(SUCCEEDED(hr), "Clear failed, hr %#lx.\n", hr);
16917 hr = IDirect3DDevice9_BeginScene(device);
16918 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
16920 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
16921 ok(SUCCEEDED(hr), "SetFVF failed, hr %#lx.\n", hr);
16923 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
16924 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
16925 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
16926 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
16928 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0x1);
16929 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
16930 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
16931 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
16933 hr = IDirect3DDevice9_EndScene(device);
16934 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
16936 color = getPixelColor(device, 1, 240);
16937 ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
16938 color = getPixelColor(device, 638, 240);
16939 ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
16941 color = getPixelColor(device, 1, 241);
16942 ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
16943 color = getPixelColor(device, 638, 241);
16944 ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
16947 static void clip_planes_test(void)
16949 IDirect3DSurface9 *offscreen_surface, *original_rt;
16950 IDirect3DTexture9 *offscreen = NULL;
16951 IDirect3DVertexShader9 *shader;
16952 IDirect3DDevice9 *device;
16953 IDirect3D9 *d3d;
16954 ULONG refcount;
16955 D3DCAPS9 caps;
16956 HWND window;
16957 HRESULT hr;
16959 static const float plane0[4] = {0.0f, 1.0f, 0.0f, 0.5f / 480.0f}; /* a quarter-pixel offset */
16960 static const DWORD shader_code[] =
16962 0xfffe0200, /* vs_2_0 */
16963 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
16964 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
16965 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
16966 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
16967 0x0000ffff /* end */
16970 window = create_window();
16971 d3d = Direct3DCreate9(D3D_SDK_VERSION);
16972 ok(!!d3d, "Failed to create a D3D object.\n");
16973 if (!(device = create_device(d3d, window, window, TRUE)))
16975 skip("Failed to create a D3D device, skipping tests.\n");
16976 goto done;
16979 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
16980 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
16981 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
16983 skip("No vs_2_0 support, skipping tests.\n");
16984 IDirect3DDevice9_Release(device);
16985 goto done;
16988 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
16989 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#lx.\n", hr);
16991 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
16992 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
16993 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
16994 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
16995 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
16996 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
16997 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
16998 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
17000 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
17001 ok(hr == S_OK, "Got hr %#lx.\n", hr);
17002 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
17003 ok(hr == S_OK, "Got hr %#lx.\n", hr);
17005 IDirect3DDevice9_SetClipPlane(device, 0, plane0);
17007 clip_planes(device, "Onscreen FFP");
17009 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen, NULL);
17010 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#lx.\n", hr);
17011 hr = IDirect3DTexture9_GetSurfaceLevel(offscreen, 0, &offscreen_surface);
17012 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#lx.\n", hr);
17013 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
17014 ok(hr == S_OK, "Got hr %#lx.\n", hr);
17016 clip_planes(device, "Offscreen FFP");
17018 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17019 ok(hr == S_OK, "Got hr %#lx.\n", hr);
17021 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
17022 ok(hr == S_OK, "Got hr %#lx.\n", hr);
17023 hr = IDirect3DDevice9_SetVertexShader(device, shader);
17024 ok(hr == S_OK, "Got hr %#lx.\n", hr);
17026 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
17027 ok(hr == S_OK, "Got hr %#lx.\n", hr);
17029 clip_planes(device, "Onscreen vertex shader");
17031 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
17032 ok(hr == S_OK, "Got hr %#lx.\n", hr);
17034 clip_planes(device, "Offscreen vertex shader");
17036 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17037 ok(hr == S_OK, "Got hr %#lx.\n", hr);
17039 IDirect3DVertexShader9_Release(shader);
17040 IDirect3DSurface9_Release(original_rt);
17041 IDirect3DSurface9_Release(offscreen_surface);
17042 IDirect3DTexture9_Release(offscreen);
17043 refcount = IDirect3DDevice9_Release(device);
17044 ok(!refcount, "Device has %lu references left.\n", refcount);
17045 done:
17046 IDirect3D9_Release(d3d);
17047 DestroyWindow(window);
17050 static void fp_special_test(void)
17052 /* Microsoft's assembler generates nan and inf with "1.#QNAN" and "1.#INF." respectively */
17053 static const DWORD vs_header[] =
17055 0xfffe0200, /* vs_2_0 */
17056 0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0 */
17057 0x05000051, 0xa00f0001, 0x7fc00000, 0xff800000, 0x7f800000, 0x00000000, /* def c1, nan, -inf, inf, 0 */
17058 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
17059 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
17062 static const DWORD vs_log[] = {0x0200000f, 0x80010000, 0x90000001}; /* log r0.x, v1.x */
17063 static const DWORD vs_pow[] =
17064 {0x03000020, 0x80010000, 0x90000001, 0x90000001}; /* pow r0.x, v1.x, v1.x */
17065 static const DWORD vs_nrm[] = {0x02000024, 0x80070000, 0x90000001}; /* nrm r0.xyz, v1.x */
17066 static const DWORD vs_rcp1[] = {0x02000006, 0x80010000, 0x90000001}; /* rcp r0.x, v1.x */
17067 static const DWORD vs_rcp2[] = {0x02000006, 0x80010000, 0x91000001}; /* rcp r0.x, -v1.x */
17068 static const DWORD vs_rsq1[] = {0x02000007, 0x80010000, 0x90000001}; /* rsq r0.x, v1.x */
17069 static const DWORD vs_rsq2[] = {0x02000007, 0x80010000, 0x91000001}; /* rsq r0.x, -v1.x */
17070 static const DWORD vs_lit[] = {0x02000010, 0x800f0000, 0x90000001, /* lit r0, v1.xxxx */
17071 0x02000001, 0x80010000, 0x80aa0000}; /* mov r0.x, v0.z */
17072 static const DWORD vs_def1[] = {0x02000001, 0x80010000, 0xa0000001}; /* mov r0.x, c1.x */
17073 static const DWORD vs_def2[] = {0x02000001, 0x80010000, 0xa0550001}; /* mov r0.x, c1.y */
17074 static const DWORD vs_def3[] = {0x02000001, 0x80010000, 0xa0aa0001}; /* mov r0.x, c1.z */
17076 static const DWORD vs_footer[] =
17078 0x03000005, 0x80020000, 0x80000000, 0xa0ff0000, /* mul r0.y, r0.x, c0.w */
17079 0x0300000d, 0x80040000, 0x80000000, 0x80550000, /* sge r0.z, r0.x, r0.y */
17080 0x0300000d, 0x80020000, 0x80e40000, 0x80000000, /* sge r0.y, r0, r0.x */
17081 0x03000005, 0x80040000, 0x80550000, 0x80e40000, /* mul r0.z, r0.y, r0 */
17082 0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000, /* max r0.w, -r0.z, r0.z */
17083 0x0300000c, 0x80020000, 0x80000000, 0x80000000, /* slt r0.y, r0.x, r0.x */
17084 0x03000002, 0x80040000, 0x80550000, 0x80550000, /* add r0.z, r0.y, r0.y */
17085 0x0300000c, 0x80020000, 0xa0000000, 0x80ff0000, /* slt r0.y, c0.x, r0.w */
17086 0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000, /* max r0.w, -r0.z, r0.z */
17087 0x03000002, 0x80040000, 0x81550000, 0xa0e40000, /* add r0.z, -r0.y, c0 */
17088 0x0300000c, 0x80080000, 0xa0000000, 0x80e40000, /* slt r0.w, c0.x, r0 */
17089 0x03000005, 0x80040000, 0x80ff0000, 0x80e40000, /* mul r0.z, r0.w, r0 */
17090 0x04000004, 0x80020000, 0x80aa0000, 0xa0e40000, 0x80e40000, /* mad r0.y, r0.z, c0, r0 */
17091 0x02000001, 0xe0030000, 0x80e40000, /* mov oT0.xy, r0 */
17092 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
17093 0x0000ffff, /* end */
17096 static const struct
17098 const char *name;
17099 const DWORD *ops;
17100 DWORD size;
17101 unsigned int r500, r600, nv40, nv50, warp;
17103 vs_body[] =
17105 /* The basic ideas here are:
17106 * 2.0 * +/-INF == +/-INF
17107 * NAN != NAN
17109 * The vertex shader value is written to the red component, with 0.0
17110 * and +/-INF mapping to 0xff, and NAN to 0x7f. Anything else should
17111 * result in 0x00. The pixel shader value is written to the green
17112 * component, but here 0.0 also results in 0x00. The actual value is
17113 * written to the blue component.
17115 * There are considerable differences between graphics cards in how
17116 * these are handled, but pow and nrm never generate INF or NAN on
17117 * real hardware. */
17118 {"log", vs_log, sizeof(vs_log), 0x00000000, 0x00000000, 0x00ff0000, 0x00ff7f00, 0x00ff8000},
17119 {"pow", vs_pow, sizeof(vs_pow), 0x000000ff, 0x000000ff, 0x0000ff00, 0x000000ff, 0x00008000},
17120 {"nrm", vs_nrm, sizeof(vs_nrm), 0x00ff0000, 0x00ff0000, 0x0000ff00, 0x00ff0000, 0x00008000},
17121 {"rcp1", vs_rcp1, sizeof(vs_rcp1), 0x000000ff, 0x000000ff, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
17122 {"rcp2", vs_rcp2, sizeof(vs_rcp2), 0x000000ff, 0x00000000, 0x00ff0000, 0x00ff7f00, 0x00ff8000},
17123 {"rsq1", vs_rsq1, sizeof(vs_rsq1), 0x000000ff, 0x000000ff, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
17124 {"rsq2", vs_rsq2, sizeof(vs_rsq2), 0x000000ff, 0x000000ff, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
17125 {"lit", vs_lit, sizeof(vs_lit), 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
17126 {"def1", vs_def1, sizeof(vs_def1), 0x000000ff, 0x00007f00, 0x0000ff00, 0x00007f00, 0x00008000},
17127 {"def2", vs_def2, sizeof(vs_def2), 0x00ff0000, 0x00ff7f00, 0x00ff0000, 0x00ff7f00, 0x00ff8000},
17128 {"def3", vs_def3, sizeof(vs_def3), 0x00ff00ff, 0x00ff7f00, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
17131 static const DWORD ps_code[] =
17133 0xffff0200, /* ps_2_0 */
17134 0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0 */
17135 0x0200001f, 0x80000000, 0xb0030000, /* dcl t0.xy */
17136 0x0300000b, 0x80010001, 0xb0e40000, 0xa0e40000, /* max r1.x, t0, c0 */
17137 0x0300000a, 0x80010000, 0xb0e40000, 0xa0e40000, /* min r0.x, t0, c0 */
17138 0x03000002, 0x80010000, 0x80e40000, 0x81e40001, /* add r0.x, r0, -r1 */
17139 0x04000004, 0x80010001, 0xb0e40000, 0xa0ff0000, 0xb1e40000, /* mad r1.x, t0, c0.w. -t0 */
17140 0x02000023, 0x80010002, 0x80e40001, /* abs r2.x, r1 */
17141 0x02000023, 0x80010000, 0x80e40000, /* abs r0.x, r0 */
17142 0x02000023, 0x80010001, 0xb0e40000, /* abs r1.x, t0 */
17143 0x04000058, 0x80010002, 0x81e40002, 0xa0aa0000, 0xa0e40000, /* cmp r2.x, -r2, c0.z, c0 */
17144 0x02000023, 0x80010002, 0x80e40002, /* abs r2.x, r2 */
17145 0x04000058, 0x80010001, 0x81e40001, 0xa0aa0000, 0xa0e40000, /* cmp r1.x, -r1, c0.z, c0 */
17146 0x02000023, 0x80010001, 0x80e40001, /* abs r1.x, r1 */
17147 0x04000058, 0x80010003, 0x81e40002, 0xa0aa0000, 0xa0e40000, /* cmp r3.x, -r2, c0.z, c0 */
17148 0x04000058, 0x80010002, 0x81e40001, 0xa0aa0000, 0xa0e40000, /* cmp r2.x, -r1, c0.z, c0 */
17149 0x04000058, 0x80010000, 0x81e40000, 0xa0550000, 0xa0e40000, /* cmp r0.x, -r0, c0.y, c0 */
17150 0x03000005, 0x80010002, 0x80e40002, 0x80e40003, /* mul r2.x, r2, r3 */
17151 0x04000058, 0x80010000, 0x81e40002, 0xa0aa0000, 0x80e40000, /* cmp r0.x, -r2, c0.z, r0 */
17152 0x04000058, 0x80020000, 0x81000001, 0x80000000, 0xa0000000, /* cmp r0.y, -r1.x, r0.x, c0.x */
17153 0x02000001, 0x80050000, 0xb0c90000, /* mov r0.xz, t0.yzxw */
17154 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.w, c0.z */
17155 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
17156 0x0000ffff, /* end */
17159 static const struct
17161 float x, y, z;
17162 float s;
17164 quad[] =
17166 { -1.0f, 1.0f, 0.0f, 0.0f},
17167 { 1.0f, 1.0f, 1.0f, 0.0f},
17168 { -1.0f, -1.0f, 0.0f, 0.0f},
17169 { 1.0f, -1.0f, 1.0f, 0.0f},
17172 IDirect3DPixelShader9 *ps;
17173 IDirect3DDevice9 *device;
17174 UINT body_size = 0;
17175 IDirect3D9 *d3d;
17176 DWORD *vs_code;
17177 ULONG refcount;
17178 D3DCAPS9 caps;
17179 HWND window;
17180 HRESULT hr;
17181 UINT i;
17183 window = create_window();
17184 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17185 ok(!!d3d, "Failed to create a D3D object.\n");
17186 if (!(device = create_device(d3d, window, window, TRUE)))
17188 skip("Failed to create a D3D device, skipping tests.\n");
17189 goto done;
17192 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
17193 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#lx.\n", hr);
17194 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0) || caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
17196 skip("No shader model 2.0 support, skipping floating point specials test.\n");
17197 IDirect3DDevice9_Release(device);
17198 goto done;
17201 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE1(0));
17202 ok(SUCCEEDED(hr), "SetFVF failed, hr %#lx.\n", hr);
17204 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
17205 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#lx.\n", hr);
17206 hr = IDirect3DDevice9_SetPixelShader(device, ps);
17207 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#lx.\n", hr);
17209 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
17210 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
17212 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
17213 ok(SUCCEEDED(hr), "Clear failed, hr %#lx.\n", hr);
17215 for (i = 0; i < ARRAY_SIZE(vs_body); ++i)
17217 if (vs_body[i].size > body_size) body_size = vs_body[i].size;
17220 vs_code = malloc(sizeof(vs_header) + body_size + sizeof(vs_footer));
17221 memcpy(vs_code, vs_header, sizeof(vs_header));
17223 for (i = 0; i < ARRAY_SIZE(vs_body); ++i)
17225 DWORD offset = ARRAY_SIZE(vs_header);
17226 IDirect3DVertexShader9 *vs;
17227 unsigned int color;
17229 memcpy(vs_code + offset, vs_body[i].ops, vs_body[i].size);
17230 offset += vs_body[i].size / sizeof(*vs_body[i].ops);
17231 memcpy(vs_code + offset, vs_footer, sizeof(vs_footer));
17233 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
17234 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#lx.\n", hr);
17235 hr = IDirect3DDevice9_SetVertexShader(device, vs);
17236 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#lx.\n", hr);
17238 hr = IDirect3DDevice9_BeginScene(device);
17239 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
17240 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17241 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
17242 hr = IDirect3DDevice9_EndScene(device);
17243 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
17245 color = getPixelColor(device, 320, 240);
17246 ok(color_match(color, vs_body[i].r500, 1)
17247 || color_match(color, vs_body[i].r600, 1)
17248 || color_match(color, vs_body[i].nv40, 1)
17249 || color_match(color, vs_body[i].nv50, 1)
17250 || broken(color_match(color, vs_body[i].warp, 1)),
17251 "Expected color 0x%08x, 0x%08x, 0x%08x or 0x%08x for instruction \"%s\", got 0x%08x.\n",
17252 vs_body[i].r500, vs_body[i].r600, vs_body[i].nv40, vs_body[i].nv50, vs_body[i].name, color);
17254 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17255 ok(SUCCEEDED(hr), "Present failed, hr %#lx.\n", hr);
17257 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
17258 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#lx.\n", hr);
17259 IDirect3DVertexShader9_Release(vs);
17262 free(vs_code);
17264 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
17265 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#lx.\n", hr);
17266 IDirect3DPixelShader9_Release(ps);
17267 refcount = IDirect3DDevice9_Release(device);
17268 ok(!refcount, "Device has %lu references left.\n", refcount);
17269 done:
17270 IDirect3D9_Release(d3d);
17271 DestroyWindow(window);
17274 static void srgbwrite_format_test(void)
17276 IDirect3D9 *d3d;
17277 IDirect3DSurface9 *rt, *backbuffer;
17278 IDirect3DTexture9 *texture;
17279 IDirect3DDevice9 *device;
17280 unsigned int color, i;
17281 ULONG refcount;
17282 HWND window;
17283 HRESULT hr;
17285 static const unsigned int color_rgb = 0x00808080, color_srgb = 0x00bcbcbc;
17286 static const struct
17288 D3DFORMAT fmt;
17289 const char *name;
17291 formats[] =
17293 { D3DFMT_R5G6B5, "D3DFMT_R5G6B5" },
17294 { D3DFMT_X8R8G8B8, "D3DFMT_X8R8G8B8" },
17295 { D3DFMT_A8R8G8B8, "D3DFMT_A8R8G8B8" },
17296 { D3DFMT_A16B16G16R16F, "D3DFMT_A16B16G16R16F" },
17297 { D3DFMT_A32B32G32R32F, "D3DFMT_A32B32G32R32F" },
17299 static const struct
17301 float x, y, z;
17302 float u, v;
17304 quad[] =
17306 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f},
17307 {-1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
17308 { 1.0f, -1.0f, 0.1f, 0.0f, 1.0f},
17309 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f}
17312 window = create_window();
17313 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17314 ok(!!d3d, "Failed to create a D3D object.\n");
17315 if (!(device = create_device(d3d, window, window, TRUE)))
17317 skip("Failed to create a D3D device, skipping tests.\n");
17318 goto done;
17321 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
17322 ok(SUCCEEDED(hr), "SetFVF failed, hr %#lx.\n", hr);
17323 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
17324 ok(SUCCEEDED(hr), "GetBackBuffer failed, hr %#lx.\n", hr);
17325 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
17326 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#lx.\n", hr);
17327 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
17328 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
17330 for(i = 0; i < ARRAY_SIZE(formats); i++)
17332 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
17333 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, formats[i].fmt)))
17335 skip("Format %s not supported as render target, skipping test.\n",
17336 formats[i].name);
17337 continue;
17340 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, D3DUSAGE_RENDERTARGET,
17341 formats[i].fmt, D3DPOOL_DEFAULT, &texture, NULL);
17342 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#lx.\n", hr);
17343 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
17344 ok(SUCCEEDED(hr), "Clear failed, hr %#lx.\n", hr);
17346 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &rt);
17347 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#lx.\n", hr);
17348 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
17349 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#lx.\n", hr);
17350 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
17351 ok(SUCCEEDED(hr), "Clear failed, hr %#lx.\n", hr);
17353 hr = IDirect3DDevice9_BeginScene(device);
17354 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
17356 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
17357 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
17358 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
17359 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#lx.\n", hr);
17360 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17361 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
17363 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
17364 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
17365 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
17366 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
17367 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
17368 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
17369 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
17370 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#lx.\n", hr);
17371 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17372 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
17373 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
17374 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
17376 hr = IDirect3DDevice9_EndScene(device);
17377 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
17379 IDirect3DSurface9_Release(rt);
17380 IDirect3DTexture9_Release(texture);
17382 color = getPixelColor(device, 360, 240);
17383 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
17384 D3DUSAGE_QUERY_SRGBWRITE,
17385 D3DRTYPE_TEXTURE, formats[i].fmt) == D3D_OK)
17387 /* Big slop for R5G6B5 */
17388 ok(color_match(color, color_srgb, 5), "Format %s supports srgb, expected color 0x%08x, got 0x%08x\n",
17389 formats[i].name, color_srgb, color);
17391 else
17393 /* Big slop for R5G6B5 */
17394 ok(color_match(color, color_rgb, 5), "Format %s does not support srgb, expected color 0x%08x, got 0x%08x\n",
17395 formats[i].name, color_rgb, color);
17398 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17399 ok(SUCCEEDED(hr), "Present failed, hr %#lx.\n", hr);
17402 IDirect3DSurface9_Release(backbuffer);
17403 refcount = IDirect3DDevice9_Release(device);
17404 ok(!refcount, "Device has %lu references left.\n", refcount);
17405 done:
17406 IDirect3D9_Release(d3d);
17407 DestroyWindow(window);
17410 static void ds_size_test(void)
17412 IDirect3DSurface9 *ds, *rt, *old_rt, *old_ds, *readback;
17413 IDirect3DDevice9 *device;
17414 DWORD num_passes;
17415 IDirect3D9 *d3d;
17416 ULONG refcount;
17417 HWND window;
17418 HRESULT hr;
17420 static const struct
17422 float x, y, z;
17424 quad[] =
17426 {-1.0f, -1.0f, 0.0f},
17427 {-1.0f, 1.0f, 0.0f},
17428 { 1.0f, -1.0f, 0.0f},
17429 { 1.0f, 1.0f, 0.0f},
17432 window = create_window();
17433 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17434 ok(!!d3d, "Failed to create a D3D object.\n");
17435 if (!(device = create_device(d3d, window, window, TRUE)))
17437 skip("Failed to create a D3D device, skipping tests.\n");
17438 goto done;
17441 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
17442 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#lx.\n", hr);
17443 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 32, 32, D3DFMT_D24X8, D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
17444 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateDepthStencilSurface failed, hr %#lx.\n", hr);
17445 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
17446 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr %#lx.\n", hr);
17448 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
17449 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
17451 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
17452 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#lx.\n", hr);
17453 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
17454 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#lx.\n", hr);
17455 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
17456 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#lx.\n", hr);
17457 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
17458 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#lx.\n", hr);
17459 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
17460 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#lx.\n", hr);
17461 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &old_ds);
17462 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetDepthStencilSurface failed, hr %#lx.\n", hr);
17463 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
17464 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#lx.\n", hr);
17465 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
17466 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#lx.\n", hr);
17467 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
17468 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#lx.\n", hr);
17470 /* The D3DCLEAR_TARGET clear works. D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER returns OK,
17471 * but does not change the surface's contents. */
17472 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000FF, 0.0f, 0);
17473 ok(SUCCEEDED(hr), "Target clear failed, hr %#lx.\n", hr);
17474 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.2f, 0);
17475 ok(SUCCEEDED(hr), "Z Buffer clear failed, hr %#lx.\n", hr);
17476 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 0.5f, 0);
17477 ok(SUCCEEDED(hr), "Target and Z Buffer clear failed, hr %#lx.\n", hr);
17479 /* Nvidia does not clear the surface(The color is still 0x000000ff), AMD does(the color is 0x00ff0000) */
17481 /* Turning on any depth-related state results in a ValidateDevice failure */
17482 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
17483 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#lx.\n", hr);
17484 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
17485 ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "Got hr %#lx.\n", hr);
17486 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
17487 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#lx.\n", hr);
17488 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
17489 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#lx.\n", hr);
17490 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
17491 ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "Got hr %#lx.\n", hr);
17493 /* Try to draw with the device in an invalid state. */
17494 hr = IDirect3DDevice9_BeginScene(device);
17495 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
17496 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17497 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
17498 hr = IDirect3DDevice9_EndScene(device);
17499 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
17501 /* Don't check the resulting draw unless we find an app that needs it. On
17502 * NVIDIA ValidateDevice() returns CONFLICTINGRENDERSTATE, so the result
17503 * is undefined. On AMD D3D seems to assume the stored Z buffer value is
17504 * 0.0 for all pixels, even those that are covered by the depth buffer. */
17506 hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
17507 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#lx.\n", hr);
17508 hr = IDirect3DDevice9_SetDepthStencilSurface(device, old_ds);
17509 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#lx.\n", hr);
17510 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
17511 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#lx.\n", hr);
17513 IDirect3DSurface9_Release(readback);
17514 IDirect3DSurface9_Release(ds);
17515 IDirect3DSurface9_Release(rt);
17516 IDirect3DSurface9_Release(old_rt);
17517 IDirect3DSurface9_Release(old_ds);
17518 refcount = IDirect3DDevice9_Release(device);
17519 ok(!refcount, "Device has %lu references left.\n", refcount);
17520 done:
17521 IDirect3D9_Release(d3d);
17522 DestroyWindow(window);
17525 static void unbound_sampler_test(void)
17527 IDirect3DPixelShader9 *ps, *ps_cube, *ps_volume;
17528 IDirect3DSurface9 *rt, *old_rt;
17529 IDirect3DDevice9 *device;
17530 unsigned int color;
17531 IDirect3D9 *d3d;
17532 ULONG refcount;
17533 D3DCAPS9 caps;
17534 HWND window;
17535 HRESULT hr;
17537 static const DWORD ps_code[] =
17539 0xffff0200, /* ps_2_0 */
17540 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
17541 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
17542 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
17543 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
17544 0x0000ffff, /* end */
17546 static const DWORD ps_code_cube[] =
17548 0xffff0200, /* ps_2_0 */
17549 0x0200001f, 0x98000000, 0xa00f0800, /* dcl_cube s0 */
17550 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
17551 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
17552 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
17553 0x0000ffff, /* end */
17555 static const DWORD ps_code_volume[] =
17557 0xffff0200, /* ps_2_0 */
17558 0x0200001f, 0xa0000000, 0xa00f0800, /* dcl_volume s0 */
17559 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
17560 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
17561 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
17562 0x0000ffff, /* end */
17565 static const struct
17567 float x, y, z;
17568 float u, v;
17570 quad[] =
17572 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f},
17573 {-1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
17574 { 1.0f, -1.0f, 0.1f, 0.0f, 1.0f},
17575 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f}
17578 window = create_window();
17579 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17580 ok(!!d3d, "Failed to create a D3D object.\n");
17581 if (!(device = create_device(d3d, window, window, TRUE)))
17583 skip("Failed to create a D3D device, skipping tests.\n");
17584 goto done;
17587 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
17588 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
17589 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
17591 skip("No ps_2_0 support, skipping tests.\n");
17592 IDirect3DDevice9_Release(device);
17593 goto done;
17595 if (!(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP) || !(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP))
17597 skip("No cube / volume texture support, skipping tests.\n");
17598 IDirect3DDevice9_Release(device);
17599 goto done;
17602 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
17603 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStage failed, hr %#lx.\n", hr);
17605 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
17606 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#lx.\n", hr);
17607 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_cube, &ps_cube);
17608 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#lx.\n", hr);
17609 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_volume, &ps_volume);
17610 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#lx.\n", hr);
17612 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL);
17613 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#lx.\n", hr);
17615 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
17616 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#lx.\n", hr);
17618 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
17619 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#lx.\n", hr);
17621 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 );
17622 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#lx.\n", hr);
17624 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x56ffffff, 1.0f, 0);
17625 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#lx.\n", hr);
17627 hr = IDirect3DDevice9_SetPixelShader(device, ps);
17628 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#lx.\n", hr);
17630 hr = IDirect3DDevice9_BeginScene(device);
17631 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
17632 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17633 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
17634 hr = IDirect3DDevice9_EndScene(device);
17635 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
17637 color = getPixelColorFromSurface(rt, 32, 32);
17638 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
17640 /* Now try with a cube texture */
17641 hr = IDirect3DDevice9_SetPixelShader(device, ps_cube);
17642 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#lx.\n", hr);
17644 hr = IDirect3DDevice9_BeginScene(device);
17645 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
17646 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17647 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
17648 hr = IDirect3DDevice9_EndScene(device);
17649 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
17651 color = getPixelColorFromSurface(rt, 32, 32);
17652 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
17654 /* And then with a volume texture */
17655 hr = IDirect3DDevice9_SetPixelShader(device, ps_volume);
17656 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#lx.\n", hr);
17658 hr = IDirect3DDevice9_BeginScene(device);
17659 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
17660 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17661 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
17662 hr = IDirect3DDevice9_EndScene(device);
17663 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
17665 color = getPixelColorFromSurface(rt, 32, 32);
17666 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
17668 IDirect3DSurface9_Release(rt);
17669 IDirect3DSurface9_Release(old_rt);
17670 IDirect3DPixelShader9_Release(ps);
17671 IDirect3DPixelShader9_Release(ps_cube);
17672 IDirect3DPixelShader9_Release(ps_volume);
17673 refcount = IDirect3DDevice9_Release(device);
17674 ok(!refcount, "Device has %lu references left.\n", refcount);
17675 done:
17676 IDirect3D9_Release(d3d);
17677 DestroyWindow(window);
17680 static void update_surface_test(void)
17682 static const BYTE blocks[][8] =
17684 {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00}, /* White */
17685 {0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Red */
17686 {0xe0, 0xff, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00}, /* Yellow */
17687 {0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Green */
17688 {0xff, 0x07, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Cyan */
17689 {0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00}, /* Blue */
17690 {0x1f, 0xf8, 0x1f, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Magenta */
17692 static const struct
17694 unsigned int x, y, color;
17696 expected_colors[] =
17698 { 18, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0xff)},
17699 { 57, 240, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff)},
17700 {109, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0xff)},
17701 {184, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
17702 {290, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
17703 {440, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
17704 {584, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
17706 static const struct
17708 float x, y, z, w;
17709 float u, v;
17711 tri[] =
17713 { 0.0f, 480.0f, 0.0f, 1.0f, 0.0f, 0.0f},
17714 { 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
17715 {640.0f, 240.0f, 0.0f, 10.0f, 100.0f, 0.5f},
17717 static const RECT rect_2x2 = {0, 0, 2, 2};
17718 static const struct
17720 UINT src_level;
17721 UINT dst_level;
17722 const RECT *r;
17723 HRESULT hr;
17725 block_size_tests[] =
17727 {1, 0, NULL, D3D_OK},
17728 {0, 1, NULL, D3DERR_INVALIDCALL},
17729 {5, 4, NULL, D3DERR_INVALIDCALL},
17730 {4, 5, NULL, D3DERR_INVALIDCALL},
17731 {4, 5, &rect_2x2, D3DERR_INVALIDCALL},
17732 {5, 5, &rect_2x2, D3D_OK},
17735 IDirect3DSurface9 *src_surface, *dst_surface;
17736 IDirect3DTexture9 *src_tex, *dst_tex;
17737 IDirect3DDevice9 *device;
17738 IDirect3D9 *d3d;
17739 ULONG refcount;
17740 UINT count, i;
17741 HWND window;
17742 HRESULT hr;
17744 window = create_window();
17745 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17746 ok(!!d3d, "Failed to create a D3D object.\n");
17747 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
17748 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1)))
17750 skip("DXT1 not supported, skipping tests.\n");
17751 goto done;
17753 if (!(device = create_device(d3d, window, window, TRUE)))
17755 skip("Failed to create a D3D device, skipping tests.\n");
17756 goto done;
17759 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_SYSTEMMEM, &src_tex, NULL);
17760 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
17761 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_DEFAULT, &dst_tex, NULL);
17762 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
17764 count = IDirect3DTexture9_GetLevelCount(src_tex);
17765 ok(count == 7, "Got level count %u, expected 7.\n", count);
17767 for (i = 0; i < count; ++i)
17769 UINT row_count, block_count, x, y;
17770 D3DSURFACE_DESC desc;
17771 BYTE *row, *block;
17772 D3DLOCKED_RECT r;
17774 hr = IDirect3DTexture9_GetLevelDesc(src_tex, i, &desc);
17775 ok(SUCCEEDED(hr), "Failed to get level desc, hr %#lx.\n", hr);
17777 hr = IDirect3DTexture9_LockRect(src_tex, i, &r, NULL, 0);
17778 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#lx.\n", hr);
17780 row_count = ((desc.Height + 3) & ~3) / 4;
17781 block_count = ((desc.Width + 3) & ~3) / 4;
17782 row = r.pBits;
17784 for (y = 0; y < row_count; ++y)
17786 block = row;
17787 for (x = 0; x < block_count; ++x)
17789 memcpy(block, blocks[i], sizeof(blocks[i]));
17790 block += sizeof(blocks[i]);
17792 row += r.Pitch;
17795 hr = IDirect3DTexture9_UnlockRect(src_tex, i);
17796 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#lx.\n", hr);
17799 for (i = 0; i < ARRAY_SIZE(block_size_tests); ++i)
17801 hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, block_size_tests[i].src_level, &src_surface);
17802 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#lx.\n", hr);
17803 hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, block_size_tests[i].dst_level, &dst_surface);
17804 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#lx.\n", hr);
17806 hr = IDirect3DDevice9_UpdateSurface(device, src_surface, block_size_tests[i].r, dst_surface, NULL);
17807 ok(hr == block_size_tests[i].hr, "Update surface returned %#lx for test %u, expected %#lx.\n",
17808 hr, i, block_size_tests[i].hr);
17810 IDirect3DSurface9_Release(dst_surface);
17811 IDirect3DSurface9_Release(src_surface);
17814 for (i = 0; i < count; ++i)
17816 hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, i, &src_surface);
17817 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#lx.\n", hr);
17818 hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, i, &dst_surface);
17819 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#lx.\n", hr);
17821 hr = IDirect3DDevice9_UpdateSurface(device, src_surface, NULL, dst_surface, NULL);
17822 ok(SUCCEEDED(hr), "Failed to update surface at level %u, hr %#lx.\n", i, hr);
17824 IDirect3DSurface9_Release(dst_surface);
17825 IDirect3DSurface9_Release(src_surface);
17828 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
17829 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
17830 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
17831 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#lx.\n", hr);
17832 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
17833 ok(SUCCEEDED(hr), "SetFVF failed, hr %#lx.\n", hr);
17834 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)dst_tex);
17835 ok(SUCCEEDED(hr), "SetTexture failed, hr %#lx.\n", hr);
17836 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
17837 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#lx.\n", hr);
17838 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
17839 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#lx.\n", hr);
17841 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0f, 0);
17842 ok(SUCCEEDED(hr), "Clear failed, hr %#lx.\n", hr);
17844 hr = IDirect3DDevice9_BeginScene(device);
17845 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
17846 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 1, tri, sizeof(*tri));
17847 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
17848 hr = IDirect3DDevice9_EndScene(device);
17849 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
17851 for (i = 0; i < ARRAY_SIZE(expected_colors); ++i)
17853 unsigned int color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
17854 ok(color_match(color, expected_colors[i].color, 0),
17855 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
17856 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
17859 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17860 ok(SUCCEEDED(hr), "Present failed, hr %#lx.\n", hr);
17862 IDirect3DTexture9_Release(dst_tex);
17863 IDirect3DTexture9_Release(src_tex);
17864 refcount = IDirect3DDevice9_Release(device);
17865 ok(!refcount, "Device has %lu references left.\n", refcount);
17866 done:
17867 IDirect3D9_Release(d3d);
17868 DestroyWindow(window);
17871 static void multisample_get_rtdata_test(void)
17873 IDirect3DSurface9 *original_ds, *original_rt, *rt, *readback;
17874 IDirect3DDevice9 *device;
17875 IDirect3D9 *d3d;
17876 ULONG refcount;
17877 HWND window;
17878 HRESULT hr;
17880 window = create_window();
17881 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17882 ok(!!d3d, "Failed to create a D3D object.\n");
17883 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
17884 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
17886 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping tests.\n");
17887 goto done;
17889 if (!(device = create_device(d3d, window, window, TRUE)))
17891 skip("Failed to create a D3D device, skipping tests.\n");
17892 goto done;
17895 hr = IDirect3DDevice9_CreateRenderTarget(device, 256, 256, D3DFMT_A8R8G8B8,
17896 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
17897 ok(SUCCEEDED(hr), "Failed to create render target, hr %#lx.\n", hr);
17898 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 256, 256, D3DFMT_A8R8G8B8,
17899 D3DPOOL_SYSTEMMEM, &readback, NULL);
17900 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#lx.\n", hr);
17902 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
17903 ok(SUCCEEDED(hr), "Failed to get render target, hr %#lx.\n", hr);
17904 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
17905 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#lx.\n", hr);
17907 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
17908 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
17909 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
17910 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#lx.\n", hr);
17912 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
17913 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#lx.\n", hr);
17914 hr = IDirect3DDevice9_GetRenderTargetData(device, rt, readback);
17915 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
17917 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
17918 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#lx.\n", hr);
17919 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
17920 ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#lx.\n", hr);
17922 IDirect3DSurface9_Release(original_ds);
17923 IDirect3DSurface9_Release(original_rt);
17924 IDirect3DSurface9_Release(readback);
17925 IDirect3DSurface9_Release(rt);
17926 refcount = IDirect3DDevice9_Release(device);
17927 ok(!refcount, "Device has %lu references left.\n", refcount);
17928 done:
17929 IDirect3D9_Release(d3d);
17930 DestroyWindow(window);
17933 static void test_multisample_get_front_buffer_data(void)
17935 IDirect3DSwapChain9 *swapchain;
17936 D3DPRESENT_PARAMETERS d3dpp;
17937 IDirect3DSurface9 *readback;
17938 IDirect3DTexture9 *texture;
17939 IDirect3DDevice9 *device;
17940 unsigned int color;
17941 IDirect3D9 *d3d;
17942 ULONG refcount;
17943 HWND window;
17944 HRESULT hr;
17946 window = create_window();
17947 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17948 ok(!!d3d, "Failed to create D3D object.\n");
17949 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
17950 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
17952 skip("Multisampling not supported for D3DFMT_A8R8G8B8.\n");
17953 goto done;
17955 if (!(device = create_device(d3d, window, window, FALSE)))
17957 skip("Failed to create D3D device.\n");
17958 goto done;
17961 hr = IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
17962 ok(hr == D3D_OK, "Failed to get the implicit swapchain, hr %#lx.\n", hr);
17963 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &d3dpp);
17964 ok(hr == D3D_OK, "Failed to get present parameters, hr %#lx.\n", hr);
17965 IDirect3DSwapChain9_Release(swapchain);
17966 d3dpp.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
17967 d3dpp.MultiSampleQuality = 0;
17968 hr = IDirect3DDevice9_Reset(device, &d3dpp);
17969 ok(hr == D3D_OK, "Failed to reset device, hr %#lx.\n", hr);
17971 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00f0ff0f, 0.0, 0);
17972 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#lx.\n", hr);
17973 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17974 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
17976 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 640, 480, D3DFMT_A8R8G8B8,
17977 D3DPOOL_SYSTEMMEM, &readback, NULL);
17978 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#lx.\n", hr);
17979 hr = IDirect3DDevice9_GetFrontBufferData(device, 0, readback);
17980 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
17981 color = getPixelColorFromSurface(readback, 320, 240);
17982 ok((color & 0x00ffffff) == 0x00f0ff0f, "Got unexpected color 0x%08x.\n", color);
17983 IDirect3DSurface9_Release(readback);
17985 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
17986 0, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &texture, NULL);
17987 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
17989 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &readback);
17990 ok(SUCCEEDED(hr), "Failed to create surface, hr %#lx.\n", hr);
17991 hr = IDirect3DDevice9_GetFrontBufferData(device, 0, readback);
17992 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
17993 color = getPixelColorFromSurface(readback, 320, 240);
17994 ok((color & 0x00ffffff) == 0x00f0ff0f, "Got unexpected color 0x%08x.\n", color);
17995 IDirect3DSurface9_Release(readback);
17996 IDirect3DTexture9_Release(texture);
17998 refcount = IDirect3DDevice9_Release(device);
17999 ok(!refcount, "Device has %lu references left.\n", refcount);
18000 done:
18001 IDirect3D9_Release(d3d);
18002 DestroyWindow(window);
18005 static void multisampled_depth_buffer_test(void)
18007 IDirect3DDevice9 *device = 0;
18008 IDirect3DSurface9 *original_rt, *rt, *readback, *ds, *original_ds;
18009 IDirect3D9 *d3d;
18010 D3DCAPS9 caps;
18011 HRESULT hr;
18012 D3DPRESENT_PARAMETERS present_parameters;
18013 unsigned int i;
18014 static const struct
18016 float x, y, z;
18017 D3DCOLOR color;
18019 quad_1[] =
18021 { -1.0f, 1.0f, 0.0f, 0xffff0000},
18022 { 1.0f, 1.0f, 1.0f, 0xffff0000},
18023 { -1.0f, -1.0f, 0.0f, 0xffff0000},
18024 { 1.0f, -1.0f, 1.0f, 0xffff0000},
18026 quad_2[] =
18028 { -1.0f, 1.0f, 1.0f, 0xff0000ff},
18029 { 1.0f, 1.0f, 0.0f, 0xff0000ff},
18030 { -1.0f, -1.0f, 1.0f, 0xff0000ff},
18031 { 1.0f, -1.0f, 0.0f, 0xff0000ff},
18033 static const struct
18035 unsigned int x, y, color;
18037 expected_colors[] =
18039 { 80, 100, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
18040 {240, 100, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
18041 {400, 100, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
18042 {560, 100, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
18043 { 80, 450, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
18044 {240, 450, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
18045 {400, 450, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
18046 {560, 450, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
18049 d3d = Direct3DCreate9(D3D_SDK_VERSION);
18050 ok(!!d3d, "Failed to create a D3D object.\n");
18052 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
18053 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
18055 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled depth buffer test.\n");
18056 IDirect3D9_Release(d3d);
18057 return;
18059 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
18060 D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
18062 skip("Multisampling not supported for D3DFMT_D24S8, skipping multisampled depth buffer test.\n");
18063 IDirect3D9_Release(d3d);
18064 return;
18067 ZeroMemory(&present_parameters, sizeof(present_parameters));
18068 present_parameters.Windowed = TRUE;
18069 present_parameters.hDeviceWindow = create_window();
18070 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
18071 present_parameters.BackBufferWidth = 640;
18072 present_parameters.BackBufferHeight = 480;
18073 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
18074 present_parameters.EnableAutoDepthStencil = TRUE;
18075 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
18076 present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
18078 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
18079 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,
18080 &present_parameters, &device);
18081 ok(hr == D3D_OK, "Failed to create a device, hr %#lx.\n", hr);
18083 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
18084 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#lx.\n", hr);
18085 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
18087 skip("No unconditional NP2 texture support, skipping multisampled depth buffer test.\n");
18088 goto cleanup;
18091 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
18092 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
18093 ok(SUCCEEDED(hr), "Failed to create render target, hr %#lx.\n", hr);
18094 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
18095 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
18096 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#lx.\n", hr);
18098 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
18099 ok(SUCCEEDED(hr), "Failed to get render target, hr %#lx.\n", hr);
18100 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
18101 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#lx.\n", hr);
18103 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
18104 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18105 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
18106 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18107 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
18108 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18109 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
18110 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18111 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
18112 ok(SUCCEEDED(hr), "SetFVF failed, hr %#lx.\n", hr);
18114 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
18115 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#lx.\n", hr);
18117 /* Render onscreen and then offscreen */
18118 hr = IDirect3DDevice9_BeginScene(device);
18119 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
18120 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
18121 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
18122 hr = IDirect3DDevice9_EndScene(device);
18123 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
18125 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, rt, NULL, D3DTEXF_POINT);
18126 ok(SUCCEEDED(hr), "StretchRect failed, hr %#lx.\n", hr);
18127 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
18128 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
18130 hr = IDirect3DDevice9_BeginScene(device);
18131 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
18132 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
18133 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
18134 hr = IDirect3DDevice9_EndScene(device);
18135 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
18137 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, readback, NULL, D3DTEXF_POINT);
18138 ok(SUCCEEDED(hr), "StretchRect failed, hr %#lx.\n", hr);
18140 for (i = 0; i < ARRAY_SIZE(expected_colors); ++i)
18142 unsigned int color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
18143 ok(color_match(color, expected_colors[i].color, 1),
18144 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
18145 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
18148 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
18149 ok(SUCCEEDED(hr), "StretchRect failed, hr %#lx.\n", hr);
18150 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18151 ok(hr == S_OK, "Got hr %#lx.\n", hr);
18153 /* Render offscreen and then onscreen */
18154 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
18155 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#lx.\n", hr);
18156 IDirect3DSurface9_Release(ds);
18157 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
18158 D3DMULTISAMPLE_2_SAMPLES, 0, TRUE, &ds, NULL);
18159 ok(SUCCEEDED(hr), "Failed to create depth/stencil, hr %#lx.\n", hr);
18160 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
18161 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#lx.\n", hr);
18163 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
18164 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#lx.\n", hr);
18166 hr = IDirect3DDevice9_BeginScene(device);
18167 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
18168 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
18169 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
18170 hr = IDirect3DDevice9_EndScene(device);
18171 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
18173 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
18174 ok(SUCCEEDED(hr), "StretchRect failed, hr %#lx.\n", hr);
18175 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
18176 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
18178 hr = IDirect3DDevice9_BeginScene(device);
18179 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
18180 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
18181 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
18182 hr = IDirect3DDevice9_EndScene(device);
18183 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
18185 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, readback, NULL, D3DTEXF_POINT);
18186 ok(SUCCEEDED(hr), "StretchRect failed, hr %#lx.\n", hr);
18188 for (i = 0; i < ARRAY_SIZE(expected_colors); ++i)
18190 unsigned int color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
18191 ok(color_match(color, expected_colors[i].color, 1),
18192 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
18193 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
18196 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18197 ok(hr == S_OK, "Got hr %#lx.\n", hr);
18199 IDirect3DSurface9_Release(ds);
18200 IDirect3DSurface9_Release(readback);
18201 IDirect3DSurface9_Release(rt);
18202 IDirect3DSurface9_Release(original_rt);
18203 cleanup_device(device);
18205 ZeroMemory(&present_parameters, sizeof(present_parameters));
18206 present_parameters.Windowed = TRUE;
18207 present_parameters.hDeviceWindow = create_window();
18208 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
18209 present_parameters.BackBufferWidth = 640;
18210 present_parameters.BackBufferHeight = 480;
18211 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
18212 present_parameters.EnableAutoDepthStencil = TRUE;
18213 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
18214 present_parameters.MultiSampleType = D3DMULTISAMPLE_NONE;
18216 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
18217 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,
18218 &present_parameters, &device);
18219 ok(hr == D3D_OK, "Failed to create a device, hr %#lx.\n", hr);
18221 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
18222 ok(SUCCEEDED(hr), "Failed to clear depth buffer, hr %#lx.\n", hr);
18224 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
18225 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
18226 ok(SUCCEEDED(hr), "Failed to create render target, hr %#lx.\n", hr);
18227 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
18228 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
18229 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#lx.\n", hr);
18230 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
18231 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &ds, NULL);
18232 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#lx.\n", hr);
18234 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
18235 ok(SUCCEEDED(hr), "Failed to get render target, hr %#lx.\n", hr);
18236 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
18237 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#lx.\n", hr);
18238 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
18239 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
18240 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
18241 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#lx.\n", hr);
18243 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
18244 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18245 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
18246 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18247 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
18248 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18249 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
18250 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18251 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
18252 ok(SUCCEEDED(hr), "SetFVF failed, hr %#lx.\n", hr);
18254 /* Render to a multisampled offscreen frame buffer and then blit to
18255 * the onscreen (not multisampled) frame buffer. */
18256 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
18257 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#lx.\n", hr);
18259 hr = IDirect3DDevice9_BeginScene(device);
18260 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
18261 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
18262 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
18263 hr = IDirect3DDevice9_EndScene(device);
18264 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
18266 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
18267 ok(SUCCEEDED(hr), "StretchRect failed, hr %#lx.\n", hr);
18268 hr = IDirect3DDevice9_StretchRect(device, ds, NULL, original_ds, NULL, D3DTEXF_POINT);
18269 ok(SUCCEEDED(hr), "StretchRect failed, hr %#lx.\n", hr);
18271 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
18272 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
18273 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
18274 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#lx.\n", hr);
18276 hr = IDirect3DDevice9_BeginScene(device);
18277 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
18278 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
18279 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
18280 hr = IDirect3DDevice9_EndScene(device);
18281 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
18283 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, readback, NULL, D3DTEXF_POINT);
18284 ok(SUCCEEDED(hr), "StretchRect failed, hr %#lx.\n", hr);
18286 for (i = 0; i < ARRAY_SIZE(expected_colors); ++i)
18288 unsigned int color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
18289 ok(color_match(color, expected_colors[i].color, 1),
18290 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
18291 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
18294 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18295 ok(hr == S_OK, "Got hr %#lx.\n", hr);
18297 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
18298 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#lx.\n", hr);
18299 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
18300 ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#lx.\n", hr);
18302 IDirect3DSurface9_Release(original_ds);
18303 IDirect3DSurface9_Release(original_rt);
18304 IDirect3DSurface9_Release(ds);
18305 IDirect3DSurface9_Release(readback);
18306 IDirect3DSurface9_Release(rt);
18307 cleanup:
18308 cleanup_device(device);
18309 IDirect3D9_Release(d3d);
18312 static void resz_test(void)
18314 IDirect3DDevice9 *device = 0;
18315 IDirect3DSurface9 *rt, *original_rt, *ds, *readback, *intz_ds;
18316 D3DCAPS9 caps;
18317 HRESULT hr;
18318 D3DPRESENT_PARAMETERS present_parameters;
18319 unsigned int i;
18320 static const DWORD ps_code[] =
18322 0xffff0200, /* ps_2_0 */
18323 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
18324 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
18325 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
18326 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
18327 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
18328 0x02000001, 0x80010001, 0x80e40000, /* mov r1.x, r0 */
18329 0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texldp r0, t0, s0 */
18330 0x02000001, 0x80020001, 0x80000000, /* mov r1.y, r0.x */
18331 0x02000001, 0x800f0800, 0x80e40001, /* mov oC0, r1 */
18332 0x0000ffff, /* end */
18334 static const struct
18336 float x, y, z;
18337 float s, t, p, q;
18339 quad[] =
18341 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
18342 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
18343 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
18344 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
18346 static const struct
18348 unsigned int x, y, color;
18350 expected_colors[] =
18352 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
18353 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
18354 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
18355 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
18356 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
18357 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
18358 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
18359 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
18361 IDirect3DTexture9 *texture;
18362 IDirect3DPixelShader9 *ps;
18363 IDirect3D9 *d3d;
18364 DWORD value;
18366 d3d = Direct3DCreate9(D3D_SDK_VERSION);
18367 ok(!!d3d, "Failed to create a D3D object.\n");
18369 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
18370 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
18372 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping RESZ test.\n");
18373 IDirect3D9_Release(d3d);
18374 return;
18376 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
18377 D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
18379 skip("Multisampling not supported for D3DFMT_D24S8, skipping RESZ test.\n");
18380 IDirect3D9_Release(d3d);
18381 return;
18384 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
18385 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'))))
18387 skip("No INTZ support, skipping RESZ test.\n");
18388 IDirect3D9_Release(d3d);
18389 return;
18392 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
18393 D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, MAKEFOURCC('R','E','S','Z'))))
18395 skip("No RESZ support, skipping RESZ test.\n");
18396 IDirect3D9_Release(d3d);
18397 return;
18400 ZeroMemory(&present_parameters, sizeof(present_parameters));
18401 present_parameters.Windowed = TRUE;
18402 present_parameters.hDeviceWindow = create_window();
18403 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
18404 present_parameters.BackBufferWidth = 640;
18405 present_parameters.BackBufferHeight = 480;
18406 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
18407 present_parameters.EnableAutoDepthStencil = FALSE;
18408 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
18409 present_parameters.MultiSampleType = D3DMULTISAMPLE_NONE;
18411 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
18412 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
18413 ok(hr == D3D_OK, "Failed to create a device, hr %#lx.\n", hr);
18415 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
18416 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#lx.\n", hr);
18417 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
18419 skip("No pixel shader 2.0 support, skipping INTZ test.\n");
18420 cleanup_device(device);
18421 IDirect3D9_Release(d3d);
18422 return;
18424 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
18426 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
18427 cleanup_device(device);
18428 IDirect3D9_Release(d3d);
18429 return;
18432 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
18433 ok(SUCCEEDED(hr), "Failed to get render target, hr %#lx.\n", hr);
18435 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
18436 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
18437 ok(SUCCEEDED(hr), "Failed to create render target, hr %#lx.\n", hr);
18438 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
18439 D3DMULTISAMPLE_2_SAMPLES, 0, TRUE, &ds, NULL);
18440 ok(SUCCEEDED(hr), "Failed to create depth/stencil, hr %#lx.\n", hr);
18441 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
18442 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
18443 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#lx.\n", hr);
18445 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
18446 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
18447 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#lx.\n", hr);
18448 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &intz_ds);
18449 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#lx.\n", hr);
18450 hr = IDirect3DDevice9_SetDepthStencilSurface(device, intz_ds);
18451 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#lx.\n", hr);
18452 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
18453 ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#lx.\n", hr);
18454 IDirect3DSurface9_Release(intz_ds);
18455 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
18456 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#lx.\n", hr);
18458 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
18459 ok(SUCCEEDED(hr), "SetFVF failed, hr %#lx.\n", hr);
18460 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
18461 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18462 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
18463 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18464 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
18465 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18466 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
18467 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18469 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
18470 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#lx.\n", hr);
18471 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
18472 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#lx.\n", hr);
18473 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
18474 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#lx.\n", hr);
18475 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
18476 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#lx.\n", hr);
18477 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
18478 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#lx.\n", hr);
18480 /* Render offscreen (multisampled), blit the depth buffer
18481 * into the INTZ texture and then check its contents */
18482 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
18483 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
18484 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
18485 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#lx.\n", hr);
18486 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
18487 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#lx.\n", hr);
18489 hr = IDirect3DDevice9_BeginScene(device);
18490 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
18491 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18492 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
18494 /* The destination depth texture has to be bound to sampler 0 */
18495 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
18496 ok(SUCCEEDED(hr), "SetTexture failed, hr %#lx.\n", hr);
18498 /* the ATI "spec" says you have to do a dummy draw to ensure correct commands ordering */
18499 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
18500 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18501 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
18502 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18503 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
18504 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18505 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18506 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
18507 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
18508 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18509 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
18510 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18511 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
18512 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18514 /* The actual multisampled depth buffer resolve happens here */
18515 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
18516 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#lx.\n", hr);
18517 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, &value);
18518 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
18519 ok(value == 0x7fa05000, "Got value %#lx.\n", value);
18521 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
18522 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
18523 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
18524 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#lx.\n", hr);
18525 hr = IDirect3DDevice9_SetPixelShader(device, ps);
18526 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#lx.\n", hr);
18528 /* Read the depth values back */
18529 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18530 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
18531 hr = IDirect3DDevice9_EndScene(device);
18532 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
18534 for (i = 0; i < ARRAY_SIZE(expected_colors); ++i)
18536 unsigned int color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
18537 ok(color_match(color, expected_colors[i].color, 1),
18538 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
18539 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
18542 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18543 ok(hr == S_OK, "Got hr %#lx.\n", hr);
18545 IDirect3DSurface9_Release(ds);
18546 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
18547 ok(SUCCEEDED(hr), "SetTexture failed, hr %#lx.\n", hr);
18548 IDirect3DTexture9_Release(texture);
18549 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
18550 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#lx.\n", hr);
18551 IDirect3DPixelShader9_Release(ps);
18552 IDirect3DSurface9_Release(readback);
18553 IDirect3DSurface9_Release(original_rt);
18554 IDirect3DSurface9_Release(rt);
18555 cleanup_device(device);
18557 ZeroMemory(&present_parameters, sizeof(present_parameters));
18558 present_parameters.Windowed = TRUE;
18559 present_parameters.hDeviceWindow = create_window();
18560 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
18561 present_parameters.BackBufferWidth = 640;
18562 present_parameters.BackBufferHeight = 480;
18563 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
18564 present_parameters.EnableAutoDepthStencil = TRUE;
18565 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
18566 present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
18568 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
18569 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
18570 ok(hr == D3D_OK, "Failed to create a device, hr %#lx.\n", hr);
18572 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
18573 ok(SUCCEEDED(hr), "Failed to get render target, hr %#lx.\n", hr);
18574 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
18575 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#lx.\n", hr);
18576 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
18577 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
18578 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#lx.\n", hr);
18579 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
18580 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
18581 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#lx.\n", hr);
18582 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &intz_ds);
18583 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#lx.\n", hr);
18584 hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
18585 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
18586 hr = IDirect3DDevice9_SetDepthStencilSurface(device, intz_ds);
18587 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#lx.\n", hr);
18588 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
18589 ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#lx.\n", hr);
18590 IDirect3DSurface9_Release(intz_ds);
18591 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
18592 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#lx.\n", hr);
18594 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
18595 ok(SUCCEEDED(hr), "SetFVF failed, hr %#lx.\n", hr);
18596 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
18597 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18598 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
18599 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18600 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
18601 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18602 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
18603 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18605 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
18606 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#lx.\n", hr);
18607 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
18608 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#lx.\n", hr);
18609 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
18610 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#lx.\n", hr);
18611 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
18612 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#lx.\n", hr);
18613 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
18614 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#lx.\n", hr);
18616 /* Render onscreen, blit the depth buffer into the INTZ texture
18617 * and then check its contents */
18618 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
18619 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
18620 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
18621 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#lx.\n", hr);
18622 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
18623 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#lx.\n", hr);
18625 hr = IDirect3DDevice9_BeginScene(device);
18626 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
18627 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18628 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
18629 hr = IDirect3DDevice9_EndScene(device);
18630 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
18632 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
18633 ok(SUCCEEDED(hr), "SetTexture failed, hr %#lx.\n", hr);
18635 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
18636 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18637 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
18638 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18639 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
18640 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18641 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18642 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
18643 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
18644 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18645 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
18646 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18647 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
18648 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18650 /* The actual multisampled depth buffer resolve happens here */
18651 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
18652 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#lx.\n", hr);
18653 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, &value);
18654 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
18655 ok(value == 0x7fa05000, "Got value %#lx.\n", value);
18657 hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
18658 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
18659 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
18660 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#lx.\n", hr);
18661 hr = IDirect3DDevice9_SetPixelShader(device, ps);
18662 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#lx.\n", hr);
18664 /* Read the depth values back */
18665 hr = IDirect3DDevice9_BeginScene(device);
18666 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
18667 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18668 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
18669 hr = IDirect3DDevice9_EndScene(device);
18670 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
18672 for (i = 0; i < ARRAY_SIZE(expected_colors); ++i)
18674 unsigned int color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
18675 ok(color_match(color, expected_colors[i].color, 1),
18676 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
18677 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
18680 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18681 ok(hr == S_OK, "Got hr %#lx.\n", hr);
18684 /* Test edge cases - try with no texture at all */
18685 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
18686 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#lx.\n", hr);
18687 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
18688 ok(SUCCEEDED(hr), "SetTexture failed, hr %#lx.\n", hr);
18689 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
18690 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#lx.\n", hr);
18691 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
18692 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#lx.\n", hr);
18694 hr = IDirect3DDevice9_BeginScene(device);
18695 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
18696 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18697 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
18698 hr = IDirect3DDevice9_EndScene(device);
18699 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
18701 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
18702 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#lx.\n", hr);
18704 /* With a non-multisampled depth buffer */
18705 IDirect3DSurface9_Release(ds);
18706 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
18707 D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
18708 ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr %#lx.\n", hr);
18710 hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
18711 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
18712 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
18713 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#lx.\n", hr);
18714 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
18715 ok(SUCCEEDED(hr), "SetTexture failed, hr %#lx.\n", hr);
18717 hr = IDirect3DDevice9_BeginScene(device);
18718 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
18719 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18720 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
18722 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
18723 ok(SUCCEEDED(hr), "SetTexture failed, hr %#lx.\n", hr);
18725 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
18726 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18727 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
18728 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18729 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
18730 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18731 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18732 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
18733 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
18734 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18735 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
18736 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18737 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
18738 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18739 hr = IDirect3DDevice9_EndScene(device);
18740 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
18742 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
18743 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#lx.\n", hr);
18745 hr = IDirect3DDevice9_SetPixelShader(device, ps);
18746 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#lx.\n", hr);
18748 /* Read the depth values back. */
18749 hr = IDirect3DDevice9_BeginScene(device);
18750 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
18751 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18752 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
18753 hr = IDirect3DDevice9_EndScene(device);
18754 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
18756 for (i = 0; i < ARRAY_SIZE(expected_colors); ++i)
18758 unsigned int color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
18759 ok(color_match(color, expected_colors[i].color, 1),
18760 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
18761 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
18764 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18765 ok(hr == S_OK, "Got hr %#lx.\n", hr);
18767 /* Without a current depth-stencil buffer set */
18768 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
18769 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#lx.\n", hr);
18770 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
18771 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#lx.\n", hr);
18773 hr = IDirect3DDevice9_BeginScene(device);
18774 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
18775 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18776 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
18777 hr = IDirect3DDevice9_EndScene(device);
18778 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
18780 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
18781 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#lx.\n", hr);
18783 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
18784 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#lx.\n", hr);
18785 IDirect3DSurface9_Release(ds);
18786 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
18787 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
18788 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
18789 ok(SUCCEEDED(hr), "SetTexture failed, hr %#lx.\n", hr);
18790 IDirect3DTexture9_Release(texture);
18791 IDirect3DPixelShader9_Release(ps);
18792 IDirect3DSurface9_Release(readback);
18793 IDirect3DSurface9_Release(original_rt);
18794 cleanup_device(device);
18795 IDirect3D9_Release(d3d);
18798 static void zenable_test(void)
18800 static const struct
18802 struct vec4 position;
18803 D3DCOLOR diffuse;
18805 tquad[] =
18807 {{ 0.0f, 480.0f, -0.5f, 1.0f}, 0xff00ff00},
18808 {{ 0.0f, 0.0f, -0.5f, 1.0f}, 0xff00ff00},
18809 {{640.0f, 480.0f, 1.5f, 1.0f}, 0xff00ff00},
18810 {{640.0f, 0.0f, 1.5f, 1.0f}, 0xff00ff00},
18812 unsigned int color, x, y, i, j, test;
18813 IDirect3DDevice9 *device;
18814 IDirect3D9 *d3d;
18815 ULONG refcount;
18816 D3DCAPS9 caps;
18817 HWND window;
18818 HRESULT hr;
18819 IDirect3DSurface9 *ds;
18821 window = create_window();
18822 d3d = Direct3DCreate9(D3D_SDK_VERSION);
18823 ok(!!d3d, "Failed to create a D3D object.\n");
18824 if (!(device = create_device(d3d, window, window, TRUE)))
18826 skip("Failed to create a D3D device, skipping tests.\n");
18827 goto done;
18830 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
18831 ok(SUCCEEDED(hr), "Failed to get depth stencil surface, hr %#lx.\n", hr);
18833 for (test = 0; test < 2; ++test)
18835 /* The Windows 8 testbot (WARP) appears to clip with
18836 * ZENABLE = D3DZB_TRUE and no depth buffer set. */
18837 static const D3DCOLOR expected_broken[] =
18839 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
18840 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
18841 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
18842 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
18845 if (!test)
18847 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
18848 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#lx.\n", hr);
18850 else
18852 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
18853 ok(SUCCEEDED(hr), "Failed to disable z-buffering, hr %#lx.\n", hr);
18854 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
18855 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#lx.\n", hr);
18856 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.0f, 0);
18857 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#lx.\n", hr);
18859 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
18860 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
18862 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0f, 0);
18863 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#lx.\n", hr);
18864 hr = IDirect3DDevice9_BeginScene(device);
18865 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
18866 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tquad, sizeof(*tquad));
18867 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
18868 hr = IDirect3DDevice9_EndScene(device);
18869 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
18871 for (i = 0; i < 4; ++i)
18873 for (j = 0; j < 4; ++j)
18875 x = 80 * ((2 * j) + 1);
18876 y = 60 * ((2 * i) + 1);
18877 color = getPixelColor(device, x, y);
18878 ok(color_match(color, 0x0000ff00, 1)
18879 || broken(color_match(color, expected_broken[i * 4 + j], 1) && !test),
18880 "Expected color 0x0000ff00 at %u, %u, got 0x%08x, test %u.\n",
18881 x, y, color, test);
18885 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18886 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#lx.\n", hr);
18889 IDirect3DSurface9_Release(ds);
18891 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
18892 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
18894 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1)
18895 && caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
18897 static const DWORD vs_code[] =
18899 0xfffe0101, /* vs_1_1 */
18900 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
18901 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
18902 0x00000001, 0xd00f0000, 0x90e40000, /* mov oD0, v0 */
18903 0x0000ffff
18905 static const DWORD ps_code[] =
18907 0xffff0101, /* ps_1_1 */
18908 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
18909 0x0000ffff /* end */
18911 static const struct vec3 quad[] =
18913 {-1.0f, -1.0f, -0.5f},
18914 {-1.0f, 1.0f, -0.5f},
18915 { 1.0f, -1.0f, 1.5f},
18916 { 1.0f, 1.0f, 1.5f},
18918 static const unsigned int expected[] =
18920 0x00ff0000, 0x0060df60, 0x009fdf9f, 0x00ff0000,
18921 0x00ff0000, 0x00609f60, 0x009f9f9f, 0x00ff0000,
18922 0x00ff0000, 0x00606060, 0x009f609f, 0x00ff0000,
18923 0x00ff0000, 0x00602060, 0x009f209f, 0x00ff0000,
18925 /* The Windows 8 testbot (WARP) appears to not clip z for regular
18926 * vertices either. */
18927 static const unsigned int expected_broken[] =
18929 0x0020df20, 0x0060df60, 0x009fdf9f, 0x00dfdfdf,
18930 0x00209f20, 0x00609f60, 0x009f9f9f, 0x00df9fdf,
18931 0x00206020, 0x00606060, 0x009f609f, 0x00df60df,
18932 0x00202020, 0x00602060, 0x009f209f, 0x00df20df,
18935 IDirect3DVertexShader9 *vs;
18936 IDirect3DPixelShader9 *ps;
18938 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
18939 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
18940 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
18941 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#lx.\n", hr);
18942 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
18943 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#lx.\n", hr);
18944 hr = IDirect3DDevice9_SetVertexShader(device, vs);
18945 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
18946 hr = IDirect3DDevice9_SetPixelShader(device, ps);
18947 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
18949 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
18950 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#lx.\n", hr);
18951 hr = IDirect3DDevice9_BeginScene(device);
18952 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
18953 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18954 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
18955 hr = IDirect3DDevice9_EndScene(device);
18956 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
18958 for (i = 0; i < 4; ++i)
18960 for (j = 0; j < 4; ++j)
18962 x = 80 * ((2 * j) + 1);
18963 y = 60 * ((2 * i) + 1);
18964 color = getPixelColor(device, x, y);
18965 ok(color_match(color, expected[i * 4 + j], 1)
18966 || broken(color_match(color, expected_broken[i * 4 + j], 1)),
18967 "Expected color 0x%08x at %u, %u, got 0x%08x.\n", expected[i * 4 + j], x, y, color);
18971 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18972 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#lx.\n", hr);
18974 IDirect3DPixelShader9_Release(ps);
18975 IDirect3DVertexShader9_Release(vs);
18978 refcount = IDirect3DDevice9_Release(device);
18979 ok(!refcount, "Device has %lu references left.\n", refcount);
18980 done:
18981 IDirect3D9_Release(d3d);
18982 DestroyWindow(window);
18985 static void fog_special_test(void)
18987 static const struct
18989 struct vec3 position;
18990 D3DCOLOR diffuse;
18992 quad[] =
18994 {{ -1.0f, -1.0f, 0.0f}, 0xff00ff00},
18995 {{ -1.0f, 1.0f, 0.0f}, 0xff00ff00},
18996 {{ 1.0f, -1.0f, 1.0f}, 0xff00ff00},
18997 {{ 1.0f, 1.0f, 1.0f}, 0xff00ff00}
18999 static const struct
19001 DWORD vertexmode, tablemode;
19002 BOOL vs, ps;
19003 unsigned int color_left, color_right;
19005 tests[] =
19007 {D3DFOG_LINEAR, D3DFOG_NONE, FALSE, FALSE, 0x00ff0000, 0x00ff0000},
19008 {D3DFOG_LINEAR, D3DFOG_NONE, FALSE, TRUE, 0x00ff0000, 0x00ff0000},
19009 {D3DFOG_LINEAR, D3DFOG_NONE, TRUE, FALSE, 0x00ff0000, 0x00ff0000},
19010 {D3DFOG_LINEAR, D3DFOG_NONE, TRUE, TRUE, 0x00ff0000, 0x00ff0000},
19012 {D3DFOG_NONE, D3DFOG_LINEAR, FALSE, FALSE, 0x0000ff00, 0x00ff0000},
19013 {D3DFOG_NONE, D3DFOG_LINEAR, FALSE, TRUE, 0x0000ff00, 0x00ff0000},
19014 {D3DFOG_NONE, D3DFOG_LINEAR, TRUE, FALSE, 0x0000ff00, 0x00ff0000},
19015 {D3DFOG_NONE, D3DFOG_LINEAR, TRUE, TRUE, 0x0000ff00, 0x00ff0000},
19017 static const DWORD pixel_shader_code[] =
19019 0xffff0101, /* ps_1_1 */
19020 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
19021 0x0000ffff
19023 static const DWORD vertex_shader_code[] =
19025 0xfffe0101, /* vs_1_1 */
19026 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
19027 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
19028 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
19029 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
19030 0x0000ffff
19032 static const D3DMATRIX identity =
19034 1.0f, 0.0f, 0.0f, 0.0f,
19035 0.0f, 1.0f, 0.0f, 0.0f,
19036 0.0f, 0.0f, 1.0f, 0.0f,
19037 0.0f, 0.0f, 0.0f, 1.0f,
19038 }}};
19039 union
19041 float f;
19042 DWORD d;
19043 } conv;
19044 HRESULT hr;
19045 IDirect3DPixelShader9 *ps;
19046 IDirect3DVertexShader9 *vs;
19047 IDirect3DDevice9 *device;
19048 unsigned int color, i;
19049 IDirect3D9 *d3d;
19050 ULONG refcount;
19051 D3DCAPS9 caps;
19052 HWND window;
19054 window = create_window();
19055 d3d = Direct3DCreate9(D3D_SDK_VERSION);
19056 ok(!!d3d, "Failed to create a D3D object.\n");
19057 if (!(device = create_device(d3d, window, window, TRUE)))
19059 skip("Failed to create a D3D device, skipping tests.\n");
19060 goto done;
19063 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
19064 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
19065 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
19067 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code, &vs);
19068 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#lx.\n", hr);
19070 else
19072 skip("Vertex Shaders not supported, skipping some fog tests.\n");
19073 vs = NULL;
19075 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
19077 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &ps);
19078 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#lx.\n", hr);
19080 else
19082 skip("Pixel Shaders not supported, skipping some fog tests.\n");
19083 ps = NULL;
19086 /* The table fog tests seem to depend on the projection matrix explicitly
19087 * being set to an identity matrix, even though that's the default.
19088 * (AMD Radeon HD 6310, Windows 7) */
19089 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
19090 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#lx.\n", hr);
19092 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
19093 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
19094 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
19095 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
19096 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
19097 ok(SUCCEEDED(hr), "Failed to enable fog, hr %#lx.\n", hr);
19098 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffff0000);
19099 ok(SUCCEEDED(hr), "Failed to set fog color, hr %#lx.\n", hr);
19101 conv.f = 0.5f;
19102 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, conv.d);
19103 ok(SUCCEEDED(hr), "Failed to set fog start, hr %#lx.\n", hr);
19104 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, conv.d);
19105 ok(SUCCEEDED(hr), "Failed to set fog end, hr %#lx.\n", hr);
19107 for (i = 0; i < ARRAY_SIZE(tests); i++)
19109 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
19110 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#lx.\n", hr);
19112 if (!tests[i].vs)
19114 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
19115 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
19117 else if (vs)
19119 hr = IDirect3DDevice9_SetVertexShader(device, vs);
19120 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
19122 else
19124 continue;
19127 if (!tests[i].ps)
19129 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
19130 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
19132 else if (ps)
19134 hr = IDirect3DDevice9_SetPixelShader(device, ps);
19135 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
19137 else
19139 continue;
19142 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vertexmode);
19143 ok(SUCCEEDED(hr), "Failed to set fogvertexmode, hr %#lx.\n", hr);
19144 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tablemode);
19145 ok(SUCCEEDED(hr), "Failed to set fogtablemode, hr %#lx.\n", hr);
19147 hr = IDirect3DDevice9_BeginScene(device);
19148 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
19149 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19150 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
19151 hr = IDirect3DDevice9_EndScene(device);
19152 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
19154 color = getPixelColor(device, 310, 240);
19155 ok(color_match(color, tests[i].color_left, 1),
19156 "Expected left color 0x%08x, got 0x%08x, case %u.\n", tests[i].color_left, color, i);
19157 color = getPixelColor(device, 330, 240);
19158 ok(color_match(color, tests[i].color_right, 1),
19159 "Expected right color 0x%08x, got 0x%08x, case %u.\n", tests[i].color_right, color, i);
19161 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19162 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#lx.\n", hr);
19165 if (vs)
19166 IDirect3DVertexShader9_Release(vs);
19167 if (ps)
19168 IDirect3DPixelShader9_Release(ps);
19169 refcount = IDirect3DDevice9_Release(device);
19170 ok(!refcount, "Device has %lu references left.\n", refcount);
19171 done:
19172 IDirect3D9_Release(d3d);
19173 DestroyWindow(window);
19176 static void volume_srgb_test(void)
19178 HRESULT hr;
19179 IDirect3DVolumeTexture9 *tex1, *tex2;
19180 D3DPOOL pool;
19181 D3DLOCKED_BOX locked_box;
19182 IDirect3DDevice9 *device;
19183 unsigned int color, i, j;
19184 IDirect3D9 *d3d;
19185 ULONG refcount;
19186 HWND window;
19188 static const struct
19190 BOOL srgb;
19191 unsigned int color;
19193 tests[] =
19195 /* Try toggling on and off */
19196 { FALSE, 0x007f7f7f },
19197 { TRUE, 0x00363636 },
19198 { FALSE, 0x007f7f7f },
19200 static const struct
19202 struct vec3 pos;
19203 struct vec3 texcrd;
19205 quad[] =
19207 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
19208 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
19209 {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
19210 {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
19213 window = create_window();
19214 d3d = Direct3DCreate9(D3D_SDK_VERSION);
19215 ok(!!d3d, "Failed to create a D3D object.\n");
19216 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
19217 D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_VOLUMETEXTURE, D3DFMT_A8R8G8B8) != D3D_OK)
19219 skip("D3DFMT_A8R8G8B8 volume textures with SRGBREAD not supported.\n");
19220 goto done;
19222 if (!(device = create_device(d3d, window, window, TRUE)))
19224 skip("Failed to create a D3D device, skipping tests.\n");
19225 goto done;
19228 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
19229 ok(SUCCEEDED(hr), "Failed to set color op 0, hr %#lx.\n", hr);
19230 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
19231 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#lx.\n", hr);
19232 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
19233 ok(SUCCEEDED(hr), "Failed to set color op 0, hr %#lx.\n", hr);
19234 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
19235 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#lx.\n", hr);
19237 for (i = 0; i < 2; i++)
19239 if (!i)
19240 pool = D3DPOOL_SYSTEMMEM;
19241 else
19242 pool = D3DPOOL_MANAGED;
19244 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 1, 1, 1, 0, D3DFMT_A8R8G8B8, pool, &tex1, NULL);
19245 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#lx.\n", hr);
19246 hr = IDirect3DVolumeTexture9_LockBox(tex1, 0, &locked_box, NULL, 0);
19247 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#lx.\n", hr);
19248 *((DWORD *)locked_box.pBits) = 0x7f7f7f7f;
19249 hr = IDirect3DVolumeTexture9_UnlockBox(tex1, 0);
19250 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#lx.\n", hr);
19252 if (!i)
19254 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 1, 1, 1, 0,
19255 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
19256 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#lx.\n", hr);
19257 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex1, (IDirect3DBaseTexture9 *)tex2);
19258 ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx.\n", hr);
19259 IDirect3DVolumeTexture9_Release(tex1);
19261 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex2);
19262 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
19263 IDirect3DVolumeTexture9_Release(tex2);
19265 else
19267 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex1);
19268 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
19269 IDirect3DVolumeTexture9_Release(tex1);
19272 for (j = 0; j < ARRAY_SIZE(tests); j++)
19274 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, tests[j].srgb);
19275 ok(SUCCEEDED(hr), "Failed to set srgb state, hr %#lx.\n", hr);
19277 hr = IDirect3DDevice9_BeginScene(device);
19278 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
19279 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19280 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
19281 hr = IDirect3DDevice9_EndScene(device);
19282 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
19284 color = getPixelColor(device, 320, 240);
19285 ok(color_match(color, tests[j].color, 2),
19286 "Expected color 0x%08x, got 0x%08x, i = %u, j = %u.\n", tests[j].color, color, i, j);
19288 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19289 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#lx.\n", hr);
19293 refcount = IDirect3DDevice9_Release(device);
19294 ok(!refcount, "Device has %lu references left.\n", refcount);
19295 done:
19296 IDirect3D9_Release(d3d);
19297 DestroyWindow(window);
19300 static void volume_dxtn_test(void)
19302 IDirect3DVolumeTexture9 *texture;
19303 struct surface_readback rb;
19304 unsigned int colour, i, j;
19305 IDirect3DDevice9 *device;
19306 IDirect3DSurface9 *rt;
19307 D3DLOCKED_BOX box;
19308 IDirect3D9 *d3d;
19309 ULONG refcount;
19310 HWND window;
19311 HRESULT hr;
19313 static const BYTE dxt1_data[] =
19315 0x00, 0xf8, 0x00, 0xf8, 0xf0, 0xf0, 0xf0, 0xf0,
19316 0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00,
19317 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
19318 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
19320 static const BYTE dxt3_data[] =
19322 0xff, 0xee, 0xff, 0xee, 0xff, 0xee, 0xff, 0xee, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
19323 0xff, 0xdd, 0xff, 0xdd, 0xff, 0xdd, 0xff, 0xdd, 0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00,
19324 0xff, 0xcc, 0xff, 0xcc, 0xff, 0xcc, 0xff, 0xcc, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
19325 0xff, 0xbb, 0xff, 0xbb, 0xff, 0xbb, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
19327 static const BYTE dxt5_data[] =
19329 /* A 8x4x2 texture consisting of 4 4x4 blocks. The colours of the
19330 * blocks are red, green, blue and white. */
19331 0xff, 0xff, 0x80, 0x0d, 0xd8, 0x80, 0x0d, 0xd8, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
19332 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00,
19333 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
19334 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
19336 static const unsigned int dxt1_expected_colours[] =
19338 0xffff0000, 0x00000000, 0xff00ff00, 0xff00ff00,
19339 0xff0000ff, 0xff0000ff, 0xffffffff, 0xffffffff,
19341 static const unsigned int dxt3_expected_colours[] =
19343 0xffff0000, 0xeeff0000, 0xff00ff00, 0xdd00ff00,
19344 0xff0000ff, 0xcc0000ff, 0xffffffff, 0xbbffffff,
19346 static const unsigned int dxt5_expected_colours[] =
19348 0xffff0000, 0x00ff0000, 0xff00ff00, 0xff00ff00,
19349 0xff0000ff, 0xff0000ff, 0xffffffff, 0xffffffff
19352 static const struct
19354 const char *name;
19355 D3DFORMAT format;
19356 const BYTE *data;
19357 DWORD data_size;
19358 const unsigned int *expected_colours;
19360 tests[] =
19362 {"DXT1", D3DFMT_DXT1, dxt1_data, sizeof(dxt1_data), dxt1_expected_colours},
19363 {"DXT3", D3DFMT_DXT3, dxt3_data, sizeof(dxt3_data), dxt3_expected_colours},
19364 {"DXT5", D3DFMT_DXT5, dxt5_data, sizeof(dxt5_data), dxt5_expected_colours},
19367 static const struct
19369 struct vec3 position;
19370 struct vec3 texcrd;
19372 quads[] =
19374 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.25f}},
19375 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.25f}},
19376 {{ 0.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.25f}},
19377 {{ 0.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.25f}},
19379 {{ 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.75f}},
19380 {{ 0.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.75f}},
19381 {{ 1.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.75f}},
19382 {{ 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.75f}},
19385 window = create_window();
19386 d3d = Direct3DCreate9(D3D_SDK_VERSION);
19387 ok(!!d3d, "Failed to create a D3D object.\n");
19389 if (!(device = create_device(d3d, window, window, TRUE)))
19391 skip("Failed to create a D3D device, skipping tests.\n");
19392 goto done;
19395 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &rt);
19396 ok(SUCCEEDED(hr), "Failed to get render target, hr %#lx.\n", hr);
19398 for (i = 0; i < ARRAY_SIZE(tests); ++i)
19400 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
19401 D3DFMT_X8R8G8B8, 0, D3DRTYPE_VOLUMETEXTURE, tests[i].format)))
19403 skip("%s volume textures are not supported, skipping test.\n", tests[i].name);
19404 continue;
19406 hr = IDirect3DDevice9_CreateVolumeTexture(device, 8, 4, 2, 1, 0,
19407 tests[i].format, D3DPOOL_MANAGED, &texture, NULL);
19408 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#lx.\n", hr);
19410 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &box, NULL, 0);
19411 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#lx.\n", hr);
19412 memcpy(box.pBits, tests[i].data, tests[i].data_size);
19413 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
19414 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#lx.\n", hr);
19416 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
19417 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
19418 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
19419 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
19420 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
19421 ok(SUCCEEDED(hr), "Failed to set colour op, hr %#lx.\n", hr);
19422 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
19423 ok(SUCCEEDED(hr), "Failed to set colour arg, hr %#lx.\n", hr);
19424 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
19425 ok(SUCCEEDED(hr), "Failed to set colour op, hr %#lx.\n", hr);
19426 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
19427 ok(SUCCEEDED(hr), "Failed to set mag filter, hr %#lx.\n", hr);
19429 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
19430 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
19431 hr = IDirect3DDevice9_BeginScene(device);
19432 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
19433 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
19434 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
19435 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
19436 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
19437 hr = IDirect3DDevice9_EndScene(device);
19438 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
19440 get_rt_readback(rt, &rb);
19441 for (j = 0; j < ARRAY_SIZE(dxt1_expected_colours); ++j)
19443 colour = get_readback_color(&rb, 40 + 80 * j, 240);
19444 ok(color_match(colour, tests[i].expected_colours[j], 1),
19445 "Expected colour 0x%08x, got 0x%08x, case %u.\n", tests[i].expected_colours[j], colour, j);
19447 release_surface_readback(&rb);
19449 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19450 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
19451 IDirect3DVolumeTexture9_Release(texture);
19454 IDirect3DSurface9_Release(rt);
19455 refcount = IDirect3DDevice9_Release(device);
19456 ok(!refcount, "Device has %lu references left.\n", refcount);
19457 done:
19458 IDirect3D9_Release(d3d);
19459 DestroyWindow(window);
19462 static void volume_v16u16_test(void)
19464 IDirect3DVolumeTexture9 *texture;
19465 IDirect3DPixelShader9 *shader;
19466 IDirect3DDevice9 *device;
19467 unsigned int color, i;
19468 D3DLOCKED_BOX box;
19469 IDirect3D9 *d3d;
19470 ULONG refcount;
19471 D3DCAPS9 caps;
19472 SHORT *texel;
19473 HWND window;
19474 HRESULT hr;
19476 static const struct
19478 struct vec3 position;
19479 struct vec3 texcrd;
19481 quads[] =
19483 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.25f}},
19484 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.25f}},
19485 {{ 0.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.25f}},
19486 {{ 0.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.25f}},
19488 {{ 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.75f}},
19489 {{ 0.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.75f}},
19490 {{ 1.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.75f}},
19491 {{ 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.75f}},
19493 static const DWORD shader_code[] =
19495 0xffff0101, /* ps_1_1 */
19496 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, */
19497 0x3f000000, 0x3f000000, /* 0.5, 0.5 */
19498 0x00000042, 0xb00f0000, /* tex t0 */
19499 0x00000004, 0x800f0000, 0xb0e40000, 0xa0e40000, 0xa0e40000, /* mad r0, t0, c0, c0 */
19500 0x0000ffff /* end */
19503 window = create_window();
19504 d3d = Direct3DCreate9(D3D_SDK_VERSION);
19505 ok(!!d3d, "Failed to create a D3D object.\n");
19506 if (!(device = create_device(d3d, window, window, TRUE)))
19508 skip("Failed to create a D3D device, skipping tests.\n");
19509 goto done;
19512 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
19513 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
19514 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
19516 skip("No ps_1_1 support, skipping tests.\n");
19517 IDirect3DDevice9_Release(device);
19518 goto done;
19520 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
19521 D3DFMT_X8R8G8B8, 0, D3DRTYPE_VOLUMETEXTURE, D3DFMT_V16U16)))
19523 skip("Volume V16U16 textures are not supported, skipping test.\n");
19524 IDirect3DDevice9_Release(device);
19525 goto done;
19528 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
19529 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
19530 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
19531 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#lx.\n", hr);
19532 hr = IDirect3DDevice9_SetPixelShader(device, shader);
19533 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
19534 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
19535 ok(SUCCEEDED(hr), "Failed to set filter, hr %#lx.\n", hr);
19537 for (i = 0; i < 2; i++)
19539 D3DPOOL pool;
19541 if (i)
19542 pool = D3DPOOL_SYSTEMMEM;
19543 else
19544 pool = D3DPOOL_MANAGED;
19546 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 2, 2, 1, 0, D3DFMT_V16U16,
19547 pool, &texture, NULL);
19548 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#lx.\n", hr);
19550 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &box, NULL, 0);
19551 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#lx.\n", hr);
19553 texel = (SHORT *)((BYTE *)box.pBits + 0 * box.RowPitch + 0 * box.SlicePitch);
19554 texel[0] = 32767;
19555 texel[1] = 32767;
19556 texel = (SHORT *)((BYTE *)box.pBits + 1 * box.RowPitch + 0 * box.SlicePitch);
19557 texel[0] = -32768;
19558 texel[1] = 0;
19559 texel = (SHORT *)((BYTE *)box.pBits + 0 * box.RowPitch + 1 * box.SlicePitch);
19560 texel[0] = -16384;
19561 texel[1] = 16384;
19562 texel = (SHORT *)((BYTE *)box.pBits + 1 * box.RowPitch + 1 * box.SlicePitch);
19563 texel[0] = 0;
19564 texel[1] = 0;
19566 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
19567 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#lx.\n", hr);
19569 if (i)
19571 IDirect3DVolumeTexture9 *texture2;
19573 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 2, 2, 1, 0, D3DFMT_V16U16,
19574 D3DPOOL_DEFAULT, &texture2, NULL);
19575 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#lx.\n", hr);
19577 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)texture,
19578 (IDirect3DBaseTexture9 *)texture2);
19579 ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx.\n", hr);
19581 IDirect3DVolumeTexture9_Release(texture);
19582 texture = texture2;
19585 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
19586 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
19588 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
19589 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
19590 hr = IDirect3DDevice9_BeginScene(device);
19591 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
19592 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
19593 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
19594 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
19595 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
19596 hr = IDirect3DDevice9_EndScene(device);
19597 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
19599 color = getPixelColor(device, 120, 160);
19600 ok (color_match(color, 0x000080ff, 2),
19601 "Expected color 0x000080ff, got 0x%08x, V16U16 input -32768, 0.\n", color);
19602 color = getPixelColor(device, 120, 400);
19603 ok (color_match(color, 0x00ffffff, 2),
19604 "Expected color 0x00ffffff, got 0x%08x, V16U16 input 32767, 32767.\n", color);
19605 color = getPixelColor(device, 360, 160);
19606 ok (color_match(color, 0x007f7fff, 2),
19607 "Expected color 0x007f7fff, got 0x%08x, V16U16 input 0, 0.\n", color);
19608 color = getPixelColor(device, 360, 400);
19609 ok (color_match(color, 0x0040c0ff, 2),
19610 "Expected color 0x0040c0ff, got 0x%08x, V16U16 input -16384, 16384.\n", color);
19612 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19613 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
19615 IDirect3DVolumeTexture9_Release(texture);
19618 IDirect3DPixelShader9_Release(shader);
19619 refcount = IDirect3DDevice9_Release(device);
19620 ok(!refcount, "Device has %lu references left.\n", refcount);
19621 done:
19622 IDirect3D9_Release(d3d);
19623 DestroyWindow(window);
19626 static void add_dirty_rect_test_draw(IDirect3DDevice9 *device)
19628 HRESULT hr;
19629 static const struct
19631 struct vec3 position;
19632 struct vec2 texcoord;
19634 quad[] =
19636 {{-1.0, -1.0, 0.0}, {0.0, 0.0}},
19637 {{-1.0, 1.0, 0.0}, {0.0, 1.0}},
19638 {{ 1.0, -1.0, 0.0}, {1.0, 0.0}},
19639 {{ 1.0, 1.0, 0.0}, {1.0, 1.0}},
19642 hr = IDirect3DDevice9_BeginScene(device);
19643 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
19644 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad, sizeof(*quad));
19645 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
19646 hr = IDirect3DDevice9_EndScene(device);
19647 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
19650 static void add_dirty_rect_test(void)
19652 HRESULT hr;
19653 IDirect3DTexture9 *tex_dst1, *tex_dst2, *tex_src_red, *tex_src_green,
19654 *tex_managed, *tex_dynamic;
19655 IDirect3DSurface9 *surface_dst2, *surface_src_green, *surface_src_red,
19656 *surface_managed0, *surface_managed1, *surface_dynamic;
19657 IDirect3DDevice9 *device;
19658 unsigned int color, i;
19659 IDirect3D9 *d3d;
19660 ULONG refcount;
19661 DWORD *texel;
19662 HWND window;
19663 HDC dc;
19664 D3DLOCKED_RECT locked_rect;
19665 static const RECT part_rect = {96, 96, 160, 160};
19666 static const RECT oob_rect[] =
19668 { 0, 0, 200, 300},
19669 { 0, 0, 300, 200},
19670 {100, 100, 10, 10},
19671 {200, 300, 10, 10},
19672 {300, 200, 310, 210},
19673 { 0, 0, 0, 0},
19676 window = create_window();
19677 d3d = Direct3DCreate9(D3D_SDK_VERSION);
19678 ok(!!d3d, "Failed to create a D3D object.\n");
19679 if (!(device = create_device(d3d, window, window, TRUE)))
19681 skip("Failed to create a D3D device, skipping tests.\n");
19682 IDirect3D9_Release(d3d);
19683 DestroyWindow(window);
19684 return;
19687 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
19688 D3DPOOL_DEFAULT, &tex_dst1, NULL);
19689 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
19690 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
19691 D3DPOOL_DEFAULT, &tex_dst2, NULL);
19692 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
19693 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
19694 D3DPOOL_SYSTEMMEM, &tex_src_red, NULL);
19695 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
19696 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
19697 D3DPOOL_SYSTEMMEM, &tex_src_green, NULL);
19698 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
19699 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 2, 0, D3DFMT_X8R8G8B8,
19700 D3DPOOL_MANAGED, &tex_managed, NULL);
19701 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
19702 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, D3DUSAGE_DYNAMIC,
19703 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex_dynamic, NULL);
19704 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
19706 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dst2, 0, &surface_dst2);
19707 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#lx.\n", hr);
19708 hr = IDirect3DTexture9_GetSurfaceLevel(tex_src_green, 0, &surface_src_green);
19709 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#lx.\n", hr);
19710 hr = IDirect3DTexture9_GetSurfaceLevel(tex_src_red, 0, &surface_src_red);
19711 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#lx.\n", hr);
19712 hr = IDirect3DTexture9_GetSurfaceLevel(tex_managed, 0, &surface_managed0);
19713 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#lx.\n", hr);
19714 hr = IDirect3DTexture9_GetSurfaceLevel(tex_managed, 1, &surface_managed1);
19715 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#lx.\n", hr);
19716 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dynamic, 0, &surface_dynamic);
19717 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#lx.\n", hr);
19719 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
19720 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#lx.\n", hr);
19721 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
19722 ok(SUCCEEDED(hr), "Failed to set color op, hr %#lx.\n", hr);
19723 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
19724 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#lx.\n", hr);
19725 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
19726 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#lx.\n", hr);
19728 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst2);
19729 ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr);
19730 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_red,
19731 (IDirect3DBaseTexture9 *)tex_dst2);
19732 fill_surface(surface_src_green, 0x00000080, D3DLOCK_NO_DIRTY_UPDATE);
19733 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
19734 (IDirect3DBaseTexture9 *)tex_dst2);
19735 ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr);
19736 add_dirty_rect_test_draw(device);
19737 color = getPixelColor(device, 320, 240);
19738 ok(color_match(color, 0x00000080, 1), "Unexpected colour 0x%08x.\n", color);
19739 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19740 ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr);
19742 fill_surface(surface_src_red, 0x00ff0000, 0);
19743 fill_surface(surface_src_green, 0x0000ff00, 0);
19745 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
19746 (IDirect3DBaseTexture9 *)tex_dst1);
19747 ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx.\n", hr);
19749 /* The second UpdateTexture call writing to tex_dst2 is ignored because tex_src_green is not dirty. */
19750 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_red,
19751 (IDirect3DBaseTexture9 *)tex_dst2);
19752 ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx.\n", hr);
19753 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
19754 (IDirect3DBaseTexture9 *)tex_dst2);
19755 ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx.\n", hr);
19757 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst1);
19758 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
19759 add_dirty_rect_test_draw(device);
19760 color = getPixelColor(device, 320, 240);
19761 ok(color_match(color, 0x0000ff00, 1),
19762 "Expected color 0x0000ff00, got 0x%08x.\n", color);
19763 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19764 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
19766 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst2);
19767 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
19768 add_dirty_rect_test_draw(device);
19769 color = getPixelColor(device, 320, 240);
19770 ok(color_match(color, 0x00ff0000, 1),
19771 "Expected color 0x00ff0000, got 0x%08x.\n", color);
19772 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19773 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
19775 /* AddDirtyRect on the destination is ignored. */
19776 hr = IDirect3DTexture9_AddDirtyRect(tex_dst2, &part_rect);
19777 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#lx.\n", hr);
19778 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
19779 (IDirect3DBaseTexture9 *)tex_dst2);
19780 ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx.\n", hr);
19781 add_dirty_rect_test_draw(device);
19782 color = getPixelColor(device, 320, 240);
19783 ok(color_match(color, 0x00ff0000, 1),
19784 "Expected color 0x00ff0000, got 0x%08x.\n", color);
19785 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19786 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
19788 hr = IDirect3DTexture9_AddDirtyRect(tex_dst2, NULL);
19789 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#lx.\n", hr);
19790 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
19791 (IDirect3DBaseTexture9 *)tex_dst2);
19792 ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx.\n", hr);
19793 add_dirty_rect_test_draw(device);
19794 color = getPixelColor(device, 320, 240);
19795 ok(color_match(color, 0x00ff0000, 1),
19796 "Expected color 0x00ff0000, got 0x%08x.\n", color);
19797 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19798 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
19800 /* AddDirtyRect on the source makes UpdateTexture work. Partial rectangle
19801 * tracking is supported. */
19802 hr = IDirect3DTexture9_AddDirtyRect(tex_src_green, &part_rect);
19803 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#lx.\n", hr);
19804 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
19805 (IDirect3DBaseTexture9 *)tex_dst2);
19806 ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx.\n", hr);
19807 add_dirty_rect_test_draw(device);
19808 color = getPixelColor(device, 320, 240);
19809 ok(color_match(color, 0x0000ff00, 1),
19810 "Expected color 0x0000ff00, got 0x%08x.\n", color);
19811 color = getPixelColor(device, 1, 1);
19812 ok(color_match(color, 0x00ff0000, 1),
19813 "Expected color 0x00ff0000, got 0x%08x.\n", color);
19814 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19815 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
19817 hr = IDirect3DTexture9_AddDirtyRect(tex_src_green, NULL);
19818 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#lx.\n", hr);
19819 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
19820 (IDirect3DBaseTexture9 *)tex_dst2);
19821 ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx.\n", hr);
19822 add_dirty_rect_test_draw(device);
19823 color = getPixelColor(device, 1, 1);
19824 ok(color_match(color, 0x0000ff00, 1),
19825 "Expected color 0x0000ff00, got 0x%08x.\n", color);
19827 /* UpdateTexture() ignores locks made with D3DLOCK_NO_DIRTY_UPDATE. */
19828 fill_surface(surface_src_green, 0x00000080, D3DLOCK_NO_DIRTY_UPDATE);
19829 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
19830 (IDirect3DBaseTexture9 *)tex_dst2);
19831 ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx.\n", hr);
19832 add_dirty_rect_test_draw(device);
19833 color = getPixelColor(device, 320, 240);
19834 ok(color_match(color, 0x0000ff00, 1),
19835 "Expected color 0x0000ff00, got 0x%08x.\n", color);
19836 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19837 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
19839 /* Manually copying the surface works, though. */
19840 hr = IDirect3DDevice9_UpdateSurface(device, surface_src_green, NULL, surface_dst2, NULL);
19841 ok(hr == D3D_OK, "Failed to copy surface, hr %#lx.\n", hr);
19842 add_dirty_rect_test_draw(device);
19843 color = getPixelColor(device, 320, 240);
19844 ok(color_match(color, 0x00000080, 1), "Got unexpected colour 0x%08x.\n", color);
19845 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19846 ok(hr == D3D_OK, "Failed to present, hr %#lx.\n", hr);
19848 /* Readonly maps write to D3DPOOL_SYSTEMMEM, but don't record a dirty rectangle. */
19849 fill_surface(surface_src_green, 0x000000ff, D3DLOCK_READONLY);
19850 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
19851 (IDirect3DBaseTexture9 *)tex_dst2);
19852 ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx.\n", hr);
19853 add_dirty_rect_test_draw(device);
19854 color = getPixelColor(device, 320, 240);
19855 ok(color_match(color, 0x00000080, 1), "Got unexpected colour 0x%08x.\n", color);
19856 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19857 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
19859 hr = IDirect3DTexture9_AddDirtyRect(tex_src_green, NULL);
19860 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
19861 (IDirect3DBaseTexture9 *)tex_dst2);
19862 ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx.\n", hr);
19863 add_dirty_rect_test_draw(device);
19864 color = getPixelColor(device, 320, 240);
19865 ok(color_match(color, 0x000000ff, 1),
19866 "Expected color 0x000000ff, got 0x%08x.\n", color);
19867 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19868 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
19870 /* Maps without either of these flags record a dirty rectangle. */
19871 fill_surface(surface_src_green, 0x00ffffff, 0);
19872 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
19873 (IDirect3DBaseTexture9 *)tex_dst2);
19874 ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx.\n", hr);
19875 add_dirty_rect_test_draw(device);
19876 color = getPixelColor(device, 320, 240);
19877 ok(color_match(color, 0x00ffffff, 1),
19878 "Expected color 0x00ffffff, got 0x%08x.\n", color);
19879 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19880 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
19882 /* Partial LockRect works just like a partial AddDirtyRect call. */
19883 hr = IDirect3DTexture9_LockRect(tex_src_green, 0, &locked_rect, &part_rect, 0);
19884 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#lx.\n", hr);
19885 texel = locked_rect.pBits;
19886 for (i = 0; i < 64; i++)
19887 texel[i] = 0x00ff00ff;
19888 for (i = 1; i < 64; i++)
19889 memcpy((BYTE *)locked_rect.pBits + i * locked_rect.Pitch, locked_rect.pBits, locked_rect.Pitch);
19890 hr = IDirect3DTexture9_UnlockRect(tex_src_green, 0);
19891 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#lx.\n", hr);
19892 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
19893 (IDirect3DBaseTexture9 *)tex_dst2);
19894 ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx.\n", hr);
19895 add_dirty_rect_test_draw(device);
19896 color = getPixelColor(device, 320, 240);
19897 ok(color_match(color, 0x00ff00ff, 1),
19898 "Expected color 0x00ff00ff, got 0x%08x.\n", color);
19899 color = getPixelColor(device, 1, 1);
19900 ok(color_match(color, 0x00ffffff, 1),
19901 "Expected color 0x00ffffff, got 0x%08x.\n", color);
19902 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19903 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
19905 /* GetDC() records a dirty rect. */
19906 fill_surface(surface_src_green, 0x00000080, D3DLOCK_NO_DIRTY_UPDATE);
19907 hr = IDirect3DSurface9_GetDC(surface_src_green, &dc);
19908 ok(hr == S_OK, "Got hr %#lx.\n", hr);
19909 hr = IDirect3DSurface9_ReleaseDC(surface_src_green, dc);
19910 ok(hr == S_OK, "Got hr %#lx.\n", hr);
19911 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
19912 (IDirect3DBaseTexture9 *)tex_dst2);
19913 ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx.\n", hr);
19914 add_dirty_rect_test_draw(device);
19915 color = getPixelColor(device, 320, 240);
19916 ok(color_match(color, 0x00000080, 1), "Got unexpected color 0x%08x.\n", color);
19917 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19918 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
19920 fill_surface(surface_src_red, 0x00ff0000, 0);
19921 fill_surface(surface_src_green, 0x0000ff00, 0);
19923 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
19924 (IDirect3DBaseTexture9 *)tex_dst1);
19925 ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx.\n", hr);
19926 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst1);
19927 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
19928 add_dirty_rect_test_draw(device);
19929 color = getPixelColor(device, 320, 240);
19930 ok(color_match(color, 0x0000ff00, 1),
19931 "Expected color 0x0000ff00, got 0x%08x.\n", color);
19932 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19933 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
19935 /* UpdateSurface ignores the missing dirty marker. */
19936 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_red,
19937 (IDirect3DBaseTexture9 *)tex_dst2);
19938 hr = IDirect3DDevice9_UpdateSurface(device, surface_src_green, NULL, surface_dst2, NULL);
19939 ok(SUCCEEDED(hr), "Failed to update surface, hr %#lx.\n", hr);
19940 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst2);
19941 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
19942 add_dirty_rect_test_draw(device);
19943 color = getPixelColor(device, 320, 240);
19944 ok(color_match(color, 0x0000ff00, 1),
19945 "Expected color 0x0000ff00, got 0x%08x.\n", color);
19946 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19947 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
19949 fill_surface(surface_src_green, 0x000000ff, D3DLOCK_NO_DIRTY_UPDATE);
19951 /* So does drawing directly from the sysmem texture. */
19952 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_src_green);
19953 ok(hr == S_OK, "Failed to set texture, hr %#lx.\n", hr);
19954 add_dirty_rect_test_draw(device);
19955 color = getPixelColor(device, 320, 240);
19956 /* Radeon GPUs read zero from sysmem textures. */
19957 ok(color_match(color, 0x000000ff, 1) || broken(color_match(color, 0x00000000, 1)),
19958 "Got unexpected color 0x%08x.\n", color);
19960 /* Tests with managed textures. */
19961 fill_surface(surface_managed0, 0x00ff0000, 0);
19962 fill_surface(surface_managed1, 0x00ff0000, 0);
19963 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_managed);
19964 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
19965 add_dirty_rect_test_draw(device);
19966 color = getPixelColor(device, 320, 240);
19967 ok(color_match(color, 0x00ff0000, 1),
19968 "Expected color 0x00ff0000, got 0x%08x.\n", color);
19969 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19970 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
19971 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
19972 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#lx.\n", hr);
19973 add_dirty_rect_test_draw(device);
19974 color = getPixelColor(device, 320, 240);
19975 ok(color_match(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
19976 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19977 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
19979 /* Managed textures also honor D3DLOCK_NO_DIRTY_UPDATE. */
19980 fill_surface(surface_managed0, 0x0000ff00, D3DLOCK_NO_DIRTY_UPDATE);
19981 fill_surface(surface_managed1, 0x000000ff, D3DLOCK_NO_DIRTY_UPDATE);
19982 add_dirty_rect_test_draw(device);
19983 color = getPixelColor(device, 320, 240);
19984 ok(color_match(color, 0x00ff0000, 1),
19985 "Expected color 0x00ff0000, got 0x%08x.\n", color);
19986 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19987 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
19988 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
19989 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#lx.\n", hr);
19990 add_dirty_rect_test_draw(device);
19991 color = getPixelColor(device, 320, 240);
19992 ok(color_match(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
19993 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19994 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
19996 /* AddDirtyRect uploads the new contents.
19997 * Partial surface updates work, and two separate dirty rectangles are
19998 * tracked individually. Tested on Nvidia Kepler, other drivers untested. */
19999 hr = IDirect3DTexture9_AddDirtyRect(tex_managed, &part_rect);
20000 ok(hr == S_OK, "Failed to add dirty rect, hr %#lx.\n", hr);
20001 add_dirty_rect_test_draw(device);
20002 color = getPixelColor(device, 320, 240);
20003 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
20004 color = getPixelColor(device, 1, 1);
20005 ok(color_match(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
20006 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20007 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
20009 hr = IDirect3DTexture9_AddDirtyRect(tex_managed, NULL);
20010 ok(hr == S_OK, "Failed to add dirty rect, hr %#lx.\n", hr);
20011 add_dirty_rect_test_draw(device);
20012 color = getPixelColor(device, 320, 240);
20013 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
20014 color = getPixelColor(device, 1, 1);
20015 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
20016 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20017 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
20019 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
20020 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#lx.\n", hr);
20021 add_dirty_rect_test_draw(device);
20022 color = getPixelColor(device, 320, 240);
20023 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
20024 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20025 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
20027 /* So does EvictManagedResources. */
20028 fill_surface(surface_managed0, 0x00ffff00, D3DLOCK_NO_DIRTY_UPDATE);
20029 fill_surface(surface_managed1, 0x00ff00ff, D3DLOCK_NO_DIRTY_UPDATE);
20030 hr = IDirect3DDevice9_EvictManagedResources(device);
20031 ok(SUCCEEDED(hr), "Failed to evict managed resources, hr %#lx.\n", hr);
20032 add_dirty_rect_test_draw(device);
20033 color = getPixelColor(device, 320, 240);
20034 ok(color_match(color, 0x00ff00ff, 1), "Got unexpected color 0x%08x.\n", color);
20035 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20036 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
20037 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
20038 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#lx.\n", hr);
20039 add_dirty_rect_test_draw(device);
20040 color = getPixelColor(device, 320, 240);
20041 ok(color_match(color, 0x00ffff00, 1), "Got unexpected color 0x%08x.\n", color);
20042 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20043 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
20045 /* So does GetDC(). */
20046 fill_surface(surface_managed0, 0x00000080, D3DLOCK_NO_DIRTY_UPDATE);
20047 hr = IDirect3DSurface9_GetDC(surface_managed0, &dc);
20048 ok(hr == S_OK, "Got hr %#lx.\n", hr);
20049 hr = IDirect3DSurface9_ReleaseDC(surface_managed0, dc);
20050 ok(hr == S_OK, "Got hr %#lx.\n", hr);
20051 add_dirty_rect_test_draw(device);
20052 color = getPixelColor(device, 320, 240);
20053 ok(color_match(color, 0x00000080, 1), "Got unexpected color 0x%08x.\n", color);
20054 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20055 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
20057 /* Tests with dynamic textures */
20058 fill_surface(surface_dynamic, 0x0000ffff, 0);
20059 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dynamic);
20060 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
20061 add_dirty_rect_test_draw(device);
20062 color = getPixelColor(device, 320, 240);
20063 ok(color_match(color, 0x0000ffff, 1),
20064 "Expected color 0x0000ffff, got 0x%08x.\n", color);
20065 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20066 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
20068 /* Dynamic textures don't honor D3DLOCK_NO_DIRTY_UPDATE. */
20069 fill_surface(surface_dynamic, 0x00ffff00, D3DLOCK_NO_DIRTY_UPDATE);
20070 add_dirty_rect_test_draw(device);
20071 color = getPixelColor(device, 320, 240);
20072 ok(color_match(color, 0x00ffff00, 1),
20073 "Expected color 0x00ffff00, got 0x%08x.\n", color);
20074 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20075 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
20077 /* AddDirtyRect on a locked texture is allowed. */
20078 hr = IDirect3DTexture9_LockRect(tex_src_red, 0, &locked_rect, NULL, 0);
20079 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#lx.\n", hr);
20080 hr = IDirect3DTexture9_AddDirtyRect(tex_src_red, NULL);
20081 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#lx.\n", hr);
20082 hr = IDirect3DTexture9_UnlockRect(tex_src_red, 0);
20083 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#lx.\n", hr);
20085 /* Redundant AddDirtyRect calls are ok. */
20086 hr = IDirect3DTexture9_AddDirtyRect(tex_managed, NULL);
20087 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#lx.\n", hr);
20088 hr = IDirect3DTexture9_AddDirtyRect(tex_managed, NULL);
20089 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#lx.\n", hr);
20091 /* Test out-of-bounds regions. */
20092 for (i = 0; i < ARRAY_SIZE(oob_rect); ++i)
20094 hr = IDirect3DTexture9_AddDirtyRect(tex_src_red, &oob_rect[i]);
20095 ok(hr == D3DERR_INVALIDCALL, "[%u] Got unexpected hr %#lx.\n", i, hr);
20096 hr = IDirect3DTexture9_LockRect(tex_src_red, 0, &locked_rect, &oob_rect[i], 0);
20097 ok(SUCCEEDED(hr), "[%u] Got unexpected hr %#lx.\n", i, hr);
20098 hr = IDirect3DTexture9_UnlockRect(tex_src_red, 0);
20099 ok(SUCCEEDED(hr), "[%u] Got unexpected hr %#lx.\n", i, hr);
20102 IDirect3DSurface9_Release(surface_dst2);
20103 IDirect3DSurface9_Release(surface_managed1);
20104 IDirect3DSurface9_Release(surface_managed0);
20105 IDirect3DSurface9_Release(surface_src_red);
20106 IDirect3DSurface9_Release(surface_src_green);
20107 IDirect3DSurface9_Release(surface_dynamic);
20108 IDirect3DTexture9_Release(tex_src_red);
20109 IDirect3DTexture9_Release(tex_src_green);
20110 IDirect3DTexture9_Release(tex_dst1);
20111 IDirect3DTexture9_Release(tex_dst2);
20112 IDirect3DTexture9_Release(tex_managed);
20113 IDirect3DTexture9_Release(tex_dynamic);
20115 /* As above, test UpdateSurface() after locking the source with
20116 * D3DLOCK_NO_DIRTY_UPDATE, but this time do it immediately after creating
20117 * the destination texture. This is a regression test for a previously
20118 * broken code path. */
20120 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
20121 D3DPOOL_DEFAULT, &tex_dst2, NULL);
20122 ok(hr == D3D_OK, "Failed to create texture, hr %#lx.\n", hr);
20123 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
20124 D3DPOOL_SYSTEMMEM, &tex_src_green, NULL);
20125 ok(hr == D3D_OK, "Failed to create texture, hr %#lx.\n", hr);
20127 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dst2, 0, &surface_dst2);
20128 ok(hr == D3D_OK, "Failed to get surface level, hr %#lx.\n", hr);
20129 hr = IDirect3DTexture9_GetSurfaceLevel(tex_src_green, 0, &surface_src_green);
20130 ok(hr == D3D_OK, "Failed to get surface level, hr %#lx.\n", hr);
20132 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst2);
20133 ok(hr == D3D_OK, "Failed to set texture, hr %#lx.\n", hr);
20134 fill_surface(surface_src_green, 0x00ff0000, D3DLOCK_NO_DIRTY_UPDATE);
20135 hr = IDirect3DDevice9_UpdateSurface(device, surface_src_green, NULL, surface_dst2, NULL);
20136 ok(hr == D3D_OK, "Failed to copy rects, hr %#lx.\n", hr);
20137 add_dirty_rect_test_draw(device);
20138 color = getPixelColor(device, 320, 240);
20139 ok(color_match(color, 0x00ff0000, 1), "Got unexpected colour 0x%08x.\n", color);
20140 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20141 ok(hr == D3D_OK, "Failed to present, hr %#lx.\n", hr);
20143 IDirect3DSurface9_Release(surface_dst2);
20144 IDirect3DSurface9_Release(surface_src_green);
20145 IDirect3DTexture9_Release(tex_dst2);
20146 IDirect3DTexture9_Release(tex_src_green);
20148 refcount = IDirect3DDevice9_Release(device);
20149 ok(!refcount, "Device has %lu references left.\n", refcount);
20150 IDirect3D9_Release(d3d);
20151 DestroyWindow(window);
20154 static void test_buffer_no_dirty_update(void)
20156 unsigned int refcount, colour;
20157 IDirect3DVertexBuffer9 *vb;
20158 IDirect3DDevice9 *device;
20159 IDirect3D9 *d3d;
20160 HWND window;
20161 HRESULT hr;
20162 void *data;
20164 static const struct
20166 struct vec3 position;
20167 DWORD diffuse;
20169 green_quad[] =
20171 {{-1.0f, -1.0f, 0.1f}, 0xff00ff00},
20172 {{-1.0f, 1.0f, 0.1f}, 0xff00ff00},
20173 {{ 1.0f, -1.0f, 0.1f}, 0xff00ff00},
20175 {{ 1.0f, -1.0f, 0.1f}, 0xff00ff00},
20176 {{-1.0f, 1.0f, 0.1f}, 0xff00ff00},
20177 {{ 1.0f, 1.0f, 0.1f}, 0xff00ff00},
20179 red_quad[] =
20181 {{-1.0f, -1.0f, 0.1f}, 0xffff0000},
20182 {{-1.0f, 1.0f, 0.1f}, 0xffff0000},
20183 {{ 1.0f, -1.0f, 0.1f}, 0xffff0000},
20185 {{ 1.0f, -1.0f, 0.1f}, 0xffff0000},
20186 {{-1.0f, 1.0f, 0.1f}, 0xffff0000},
20187 {{ 1.0f, 1.0f, 0.1f}, 0xffff0000},
20190 window = create_window();
20191 d3d = Direct3DCreate9(D3D_SDK_VERSION);
20192 ok(!!d3d, "Failed to create a D3D object.\n");
20193 if (!(device = create_device(d3d, window, window, TRUE)))
20195 skip("Failed to create a D3D device.\n");
20196 goto done;
20199 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(green_quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
20200 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
20202 hr = IDirect3DVertexBuffer9_Lock(vb, 0, 0, &data, 0);
20203 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
20204 memcpy(data, red_quad, sizeof(red_quad));
20205 hr = IDirect3DVertexBuffer9_Unlock(vb);
20206 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
20208 hr = IDirect3DVertexBuffer9_Lock(vb, 0, 0, &data, D3DLOCK_NO_DIRTY_UPDATE);
20209 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
20210 memcpy(data, green_quad, sizeof(green_quad));
20211 hr = IDirect3DVertexBuffer9_Unlock(vb);
20212 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
20214 hr = IDirect3DDevice9_BeginScene(device);
20215 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
20216 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
20217 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
20218 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
20219 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
20220 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
20221 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
20222 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
20223 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
20224 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(*green_quad));
20225 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
20226 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLELIST, 0, 2);
20227 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
20228 hr = IDirect3DDevice9_EndScene(device);
20229 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
20230 colour = getPixelColor(device, 320, 240);
20231 ok(color_match(colour, 0x0000ff00, 1), "Got unexpected colour 0x%09x.\n", colour);
20233 IDirect3DVertexBuffer9_Release(vb);
20234 refcount = IDirect3DDevice9_Release(device);
20235 ok(!refcount, "Device has %u references left.\n", refcount);
20236 done:
20237 IDirect3D9_Release(d3d);
20238 DestroyWindow(window);
20241 static void test_per_stage_constant(void)
20243 IDirect3DDevice9 *device;
20244 unsigned int color;
20245 IDirect3D9 *d3d;
20246 ULONG refcount;
20247 D3DCAPS9 caps;
20248 HWND window;
20249 HRESULT hr;
20251 static const struct
20253 struct vec3 position;
20254 D3DCOLOR diffuse;
20256 quad[] =
20258 {{-1.0f, -1.0f, 0.1f}, 0xffff0000},
20259 {{-1.0f, 1.0f, 0.1f}, 0xffff0000},
20260 {{ 1.0f, -1.0f, 0.1f}, 0xffff0000},
20261 {{ 1.0f, 1.0f, 0.1f}, 0xffff0000},
20264 window = create_window();
20265 d3d = Direct3DCreate9(D3D_SDK_VERSION);
20266 ok(!!d3d, "Failed to create a D3D object.\n");
20267 if (!(device = create_device(d3d, window, window, TRUE)))
20269 skip("Failed to create a D3D device, skipping tests.\n");
20270 goto done;
20273 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
20274 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
20275 if (!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_PERSTAGECONSTANT))
20277 skip("Per-stage constants not supported, skipping tests.\n");
20278 IDirect3DDevice9_Release(device);
20279 goto done;
20282 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
20283 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
20284 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
20285 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
20286 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
20287 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
20288 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
20289 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
20290 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
20291 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
20293 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_CONSTANT, 0x80a1b2c3);
20294 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#lx.\n", hr);
20295 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_CONSTANT);
20296 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#lx.\n", hr);
20297 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
20298 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#lx.\n", hr);
20300 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
20301 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
20303 hr = IDirect3DDevice9_BeginScene(device);
20304 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
20305 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
20306 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
20307 hr = IDirect3DDevice9_EndScene(device);
20308 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
20310 color = getPixelColor(device, 320, 240);
20311 ok(color_match(color, 0x00a1b2c3, 1), "Got unexpected color 0x%08x.\n", color);
20312 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20313 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
20315 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_CONSTANT | D3DTA_COMPLEMENT);
20316 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#lx.\n", hr);
20318 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
20319 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
20321 hr = IDirect3DDevice9_BeginScene(device);
20322 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
20323 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
20324 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
20325 hr = IDirect3DDevice9_EndScene(device);
20326 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
20328 color = getPixelColor(device, 320, 240);
20329 ok(color_match(color, 0x005e4d3c, 1), "Got unexpected color 0x%08x.\n", color);
20330 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20331 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
20333 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_CONSTANT | D3DTA_ALPHAREPLICATE);
20334 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#lx.\n", hr);
20336 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
20337 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
20339 hr = IDirect3DDevice9_BeginScene(device);
20340 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
20341 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
20342 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
20343 hr = IDirect3DDevice9_EndScene(device);
20344 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
20346 color = getPixelColor(device, 320, 240);
20347 ok(color_match(color, 0x00808080, 1), "Got unexpected color 0x%08x.\n", color);
20348 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20349 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
20351 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_CONSTANT);
20352 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#lx.\n", hr);
20353 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
20354 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#lx.\n", hr);
20355 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_CURRENT);
20356 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#lx.\n", hr);
20358 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
20359 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
20361 hr = IDirect3DDevice9_BeginScene(device);
20362 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
20363 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
20364 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
20365 hr = IDirect3DDevice9_EndScene(device);
20366 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
20368 color = getPixelColor(device, 320, 240);
20369 ok(color_match(color, 0x0080007f, 1), "Got unexpected color 0x%08x.\n", color);
20370 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20371 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
20373 refcount = IDirect3DDevice9_Release(device);
20374 ok(!refcount, "Device has %lu references left.\n", refcount);
20375 done:
20376 IDirect3D9_Release(d3d);
20377 DestroyWindow(window);
20380 static void test_3dc_formats(void)
20382 static const char ati1n_data[] =
20384 /* A 4x4 texture with the color component at 50%. */
20385 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
20387 static const char ati2n_data[] =
20389 /* A 8x4 texture consisting of 2 4x4 blocks. The first block has 50% first color component,
20390 * 0% second component. Second block is the opposite. */
20391 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
20392 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
20394 static const struct
20396 struct vec3 position;
20397 struct vec2 texcoord;
20399 quads[] =
20401 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f}},
20402 {{-1.0f, 1.0f, 0.0f}, {0.0f, 1.0f}},
20403 {{ 0.0f, -1.0f, 1.0f}, {1.0f, 0.0f}},
20404 {{ 0.0f, 1.0f, 1.0f}, {1.0f, 1.0f}},
20406 {{ 0.0f, -1.0f, 0.0f}, {0.0f, 0.0f}},
20407 {{ 0.0f, 1.0f, 0.0f}, {0.0f, 1.0f}},
20408 {{ 1.0f, -1.0f, 1.0f}, {1.0f, 0.0f}},
20409 {{ 1.0f, 1.0f, 1.0f}, {1.0f, 1.0f}},
20411 static const DWORD ati1n_fourcc = MAKEFOURCC('A','T','I','1');
20412 static const DWORD ati2n_fourcc = MAKEFOURCC('A','T','I','2');
20413 static const struct
20415 struct vec2 position;
20416 D3DCOLOR amd_r500;
20417 D3DCOLOR amd_r600;
20418 D3DCOLOR nvidia_old;
20419 D3DCOLOR nvidia_new;
20421 expected_colors[] =
20423 {{ 80, 240}, 0x007fffff, 0x003f3f3f, 0x007f7f7f, 0x007f0000},
20424 {{240, 240}, 0x007fffff, 0x003f3f3f, 0x007f7f7f, 0x007f0000},
20425 {{400, 240}, 0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff},
20426 {{560, 240}, 0x007f00ff, 0x007f00ff, 0x007f00ff, 0x007f00ff},
20428 IDirect3D9 *d3d;
20429 IDirect3DDevice9 *device;
20430 unsigned int color, i;
20431 IDirect3DTexture9 *ati1n_texture, *ati2n_texture;
20432 D3DCAPS9 caps;
20433 D3DLOCKED_RECT rect;
20434 ULONG refcount;
20435 HWND window;
20436 HRESULT hr;
20438 window = create_window();
20439 d3d = Direct3DCreate9(D3D_SDK_VERSION);
20440 ok(!!d3d, "Failed to create a D3D object.\n");
20441 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
20442 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, ati1n_fourcc)))
20444 skip("ATI1N textures are not supported, skipping test.\n");
20445 goto done;
20447 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
20448 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, ati2n_fourcc)))
20450 skip("ATI2N textures are not supported, skipping test.\n");
20451 goto done;
20453 if (!(device = create_device(d3d, window, window, TRUE)))
20455 skip("Failed to create a D3D device, skipping tests.\n");
20456 goto done;
20458 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
20459 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
20460 if (!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP))
20462 skip("D3DTA_TEMP not supported, skipping tests.\n");
20463 IDirect3DDevice9_Release(device);
20464 goto done;
20467 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, ati1n_fourcc,
20468 D3DPOOL_MANAGED, &ati1n_texture, NULL);
20469 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
20471 hr = IDirect3DTexture9_LockRect(ati1n_texture, 0, &rect, NULL, 0);
20472 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#lx.\n", hr);
20473 memcpy(rect.pBits, ati1n_data, sizeof(ati1n_data));
20474 hr = IDirect3DTexture9_UnlockRect(ati1n_texture, 0);
20475 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#lx.\n", hr);
20477 hr = IDirect3DDevice9_CreateTexture(device, 8, 4, 1, 0, ati2n_fourcc,
20478 D3DPOOL_MANAGED, &ati2n_texture, NULL);
20479 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
20481 hr = IDirect3DTexture9_LockRect(ati2n_texture, 0, &rect, NULL, 0);
20482 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#lx.\n", hr);
20483 memcpy(rect.pBits, ati2n_data, sizeof(ati2n_data));
20484 hr = IDirect3DTexture9_UnlockRect(ati2n_texture, 0);
20485 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#lx.\n", hr);
20487 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0));
20488 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
20489 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BLENDTEXTUREALPHA);
20490 ok(SUCCEEDED(hr), "Failed to set color op, hr %#lx.\n", hr);
20491 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
20492 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#lx.\n", hr);
20493 /* The temporary register is initialized to 0. */
20494 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TEMP);
20495 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#lx.\n", hr);
20496 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
20497 ok(SUCCEEDED(hr), "Failed to set alpha op, hr %#lx.\n", hr);
20498 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
20499 ok(SUCCEEDED(hr), "Failed to set alpha arg, hr %#lx.\n", hr);
20500 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
20501 ok(SUCCEEDED(hr), "Failed to set color op, hr %#lx.\n", hr);
20502 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
20503 ok(SUCCEEDED(hr), "Failed to set mag filter, hr %#lx.\n", hr);
20505 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
20506 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
20507 hr = IDirect3DDevice9_BeginScene(device);
20508 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
20509 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)ati1n_texture);
20510 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
20511 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
20512 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
20513 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)ati2n_texture);
20514 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
20515 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
20516 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
20517 hr = IDirect3DDevice9_EndScene(device);
20518 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
20520 for (i = 0; i < 4; ++i)
20522 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
20523 ok (color_match(color, expected_colors[i].amd_r500, 1)
20524 || color_match(color, expected_colors[i].amd_r600, 1)
20525 || color_match(color, expected_colors[i].nvidia_old, 1)
20526 || color_match(color, expected_colors[i].nvidia_new, 1),
20527 "Got unexpected color 0x%08x, case %u.\n", color, i);
20530 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20531 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
20532 IDirect3DTexture9_Release(ati2n_texture);
20533 IDirect3DTexture9_Release(ati1n_texture);
20534 refcount = IDirect3DDevice9_Release(device);
20535 ok(!refcount, "Device has %lu references left.\n", refcount);
20537 done:
20538 IDirect3D9_Release(d3d);
20539 DestroyWindow(window);
20542 static void test_fog_interpolation(void)
20544 HRESULT hr;
20545 IDirect3DDevice9 *device;
20546 unsigned int color, i;
20547 IDirect3D9 *d3d;
20548 ULONG refcount;
20549 HWND window;
20551 static const struct
20553 struct vec3 position;
20554 D3DCOLOR diffuse;
20555 D3DCOLOR specular;
20557 quad[] =
20559 {{-1.0f, -1.0f, 0.0f}, 0xffff0000, 0xff000000},
20560 {{-1.0f, 1.0f, 0.0f}, 0xffff0000, 0xff000000},
20561 {{ 1.0f, -1.0f, 1.0f}, 0xffff0000, 0x00000000},
20562 {{ 1.0f, 1.0f, 1.0f}, 0xffff0000, 0x00000000},
20564 union
20566 DWORD d;
20567 float f;
20568 } conv;
20569 static const struct
20571 D3DFOGMODE vfog, tfog;
20572 D3DSHADEMODE shade;
20573 D3DCOLOR middle_color;
20574 BOOL todo;
20576 tests[] =
20578 {D3DFOG_NONE, D3DFOG_NONE, D3DSHADE_FLAT, 0x00007f80, FALSE},
20579 {D3DFOG_NONE, D3DFOG_NONE, D3DSHADE_GOURAUD, 0x00007f80, FALSE},
20580 {D3DFOG_EXP, D3DFOG_NONE, D3DSHADE_FLAT, 0x00007f80, TRUE},
20581 {D3DFOG_EXP, D3DFOG_NONE, D3DSHADE_GOURAUD, 0x00007f80, TRUE},
20582 {D3DFOG_NONE, D3DFOG_EXP, D3DSHADE_FLAT, 0x0000ea15, FALSE},
20583 {D3DFOG_NONE, D3DFOG_EXP, D3DSHADE_GOURAUD, 0x0000ea15, FALSE},
20584 {D3DFOG_EXP, D3DFOG_EXP, D3DSHADE_FLAT, 0x0000ea15, FALSE},
20585 {D3DFOG_EXP, D3DFOG_EXP, D3DSHADE_GOURAUD, 0x0000ea15, FALSE},
20587 static const D3DMATRIX ident_mat =
20589 1.0f, 0.0f, 0.0f, 0.0f,
20590 0.0f, 1.0f, 0.0f, 0.0f,
20591 0.0f, 0.0f, 1.0f, 0.0f,
20592 0.0f, 0.0f, 0.0f, 1.0f
20593 }}};
20594 D3DCAPS9 caps;
20596 window = create_window();
20597 d3d = Direct3DCreate9(D3D_SDK_VERSION);
20598 ok(!!d3d, "Failed to create a D3D object.\n");
20600 if (!(device = create_device(d3d, window, window, TRUE)))
20602 skip("Failed to create a D3D device, skipping tests.\n");
20603 IDirect3D9_Release(d3d);
20604 DestroyWindow(window);
20605 return;
20608 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
20609 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
20610 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
20611 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
20613 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
20614 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#lx.\n", hr);
20615 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
20616 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
20617 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
20618 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
20619 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
20620 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
20621 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
20622 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
20623 conv.f = 5.0;
20624 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGDENSITY, conv.d);
20625 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
20627 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
20628 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#lx.\n", hr);
20629 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
20630 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#lx.\n", hr);
20631 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x000000ff);
20632 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
20634 /* Some of the tests seem to depend on the projection matrix explicitly
20635 * being set to an identity matrix, even though that's the default.
20636 * (AMD Radeon X1600, AMD Radeon HD 6310, Windows 7). Without this,
20637 * the drivers seem to use a static z = 1.0 input for the fog equation.
20638 * The input value is independent of the actual z and w component of
20639 * the vertex position. */
20640 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &ident_mat);
20641 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#lx.\n", hr);
20643 for (i = 0; i < ARRAY_SIZE(tests); i++)
20645 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE) && tests[i].tfog)
20646 continue;
20648 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00808080, 0.0f, 0);
20649 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
20651 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, tests[i].shade);
20652 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
20653 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vfog);
20654 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
20655 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tfog);
20656 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
20657 hr = IDirect3DDevice9_BeginScene(device);
20658 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
20659 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
20660 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
20661 hr = IDirect3DDevice9_EndScene(device);
20662 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
20664 color = getPixelColor(device, 0, 240);
20665 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x, case %u.\n", color, i);
20666 color = getPixelColor(device, 320, 240);
20667 todo_wine_if (tests[i].todo)
20668 ok(color_match(color, tests[i].middle_color, 2),
20669 "Got unexpected color 0x%08x, case %u.\n", color, i);
20670 color = getPixelColor(device, 639, 240);
20671 ok(color_match(color, 0x0000fd02, 2), "Got unexpected color 0x%08x, case %u.\n", color, i);
20672 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20673 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
20676 refcount = IDirect3DDevice9_Release(device);
20677 ok(!refcount, "Device has %lu references left.\n", refcount);
20678 IDirect3D9_Release(d3d);
20679 DestroyWindow(window);
20682 static void test_negative_fixedfunction_fog(void)
20684 HRESULT hr;
20685 IDirect3DDevice9 *device;
20686 unsigned int color, i;
20687 IDirect3D9 *d3d;
20688 ULONG refcount;
20689 HWND window;
20691 static const struct
20693 struct vec3 position;
20694 D3DCOLOR diffuse;
20696 quad[] =
20698 {{-1.0f, -1.0f, -0.5f}, 0xffff0000},
20699 {{-1.0f, 1.0f, -0.5f}, 0xffff0000},
20700 {{ 1.0f, -1.0f, -0.5f}, 0xffff0000},
20701 {{ 1.0f, 1.0f, -0.5f}, 0xffff0000},
20703 static const struct
20705 struct vec4 position;
20706 D3DCOLOR diffuse;
20708 tquad[] =
20710 {{ 0.0f, 0.0f, -0.5f, 1.0f}, 0xffff0000},
20711 {{640.0f, 0.0f, -0.5f, 1.0f}, 0xffff0000},
20712 {{ 0.0f, 480.0f, -0.5f, 1.0f}, 0xffff0000},
20713 {{640.0f, 480.0f, -0.5f, 1.0f}, 0xffff0000},
20715 static const D3DMATRIX zero =
20717 1.0f, 0.0f, 0.0f, 0.0f,
20718 0.0f, 1.0f, 0.0f, 0.0f,
20719 0.0f, 0.0f, 0.0f, 0.0f,
20720 0.0f, 0.0f, 0.0f, 1.0f
20721 }}};
20722 /* Needed to make AMD drivers happy. Yeah, it is not supposed to
20723 * have an effect on RHW draws. */
20724 static const D3DMATRIX identity =
20726 1.0f, 0.0f, 0.0f, 0.0f,
20727 0.0f, 1.0f, 0.0f, 0.0f,
20728 0.0f, 0.0f, 1.0f, 0.0f,
20729 0.0f, 0.0f, 0.0f, 1.0f
20730 }}};
20731 static const struct
20733 DWORD pos_type;
20734 const void *quad;
20735 size_t stride;
20736 const D3DMATRIX *matrix;
20737 union
20739 float f;
20740 DWORD d;
20741 } start, end;
20742 D3DFOGMODE vfog, tfog;
20743 DWORD color, color_broken, color_broken2;
20745 tests[] =
20747 /* Run the XYZRHW tests first. Depth clamping is broken after RHW draws on the testbot.
20749 * Geforce8+ GPUs on Windows abs() table fog, everything else does not. */
20750 {D3DFVF_XYZRHW, tquad, sizeof(*tquad), &identity, { 0.0f}, {1.0f},
20751 D3DFOG_NONE, D3DFOG_LINEAR, 0x00ff0000, 0x00808000, 0x00808000},
20752 /* r200 GPUs and presumably all d3d8 and older HW clamp the fog
20753 * parameters to 0.0 and 1.0 in the table fog case. */
20754 {D3DFVF_XYZRHW, tquad, sizeof(*tquad), &identity, {-1.0f}, {0.0f},
20755 D3DFOG_NONE, D3DFOG_LINEAR, 0x00808000, 0x00ff0000, 0x0000ff00},
20756 /* test_fog_interpolation shows that vertex fog evaluates the fog
20757 * equation in the vertex pipeline. Start = -1.0 && end = 0.0 shows
20758 * that the abs happens before the fog equation is evaluated.
20760 * Vertex fog abs() behavior is the same on all GPUs. */
20761 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, { 0.0f}, {1.0f},
20762 D3DFOG_LINEAR, D3DFOG_NONE, 0x00808000, 0x00808000, 0x00808000},
20763 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, {-1.0f}, {0.0f},
20764 D3DFOG_LINEAR, D3DFOG_NONE, 0x0000ff00, 0x0000ff00, 0x0000ff00},
20765 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, { 0.0f}, {1.0f},
20766 D3DFOG_EXP, D3DFOG_NONE, 0x009b6400, 0x009b6400, 0x009b6400},
20768 D3DCAPS9 caps;
20770 window = create_window();
20771 d3d = Direct3DCreate9(D3D_SDK_VERSION);
20772 ok(!!d3d, "Failed to create a D3D object.\n");
20774 if (!(device = create_device(d3d, window, window, TRUE)))
20776 skip("Failed to create a D3D device, skipping tests.\n");
20777 IDirect3D9_Release(d3d);
20778 DestroyWindow(window);
20779 return;
20782 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
20783 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
20784 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
20785 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests.\n");
20787 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
20788 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
20789 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
20790 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
20791 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
20792 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
20793 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
20794 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
20795 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
20796 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
20798 for (i = 0; i < ARRAY_SIZE(tests); i++)
20800 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE) && tests[i].tfog)
20801 continue;
20803 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
20804 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
20806 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, tests[i].matrix);
20807 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#lx.\n", hr);
20808 hr = IDirect3DDevice9_SetFVF(device, tests[i].pos_type | D3DFVF_DIFFUSE);
20809 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#lx.\n", hr);
20810 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, tests[i].start.d);
20811 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
20812 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, tests[i].end.d);
20813 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
20814 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vfog);
20815 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
20816 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tfog);
20817 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
20819 hr = IDirect3DDevice9_BeginScene(device);
20820 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
20821 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tests[i].quad, tests[i].stride);
20822 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
20823 hr = IDirect3DDevice9_EndScene(device);
20824 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
20826 color = getPixelColor(device, 320, 240);
20827 ok(color_match(color, tests[i].color, 2) || broken(color_match(color, tests[i].color_broken, 2))
20828 || broken(color_match(color, tests[i].color_broken2, 2)),
20829 "Got unexpected color 0x%08x, case %u.\n", color, i);
20830 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20831 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
20834 refcount = IDirect3DDevice9_Release(device);
20835 ok(!refcount, "Device has %lu references left.\n", refcount);
20836 IDirect3D9_Release(d3d);
20837 DestroyWindow(window);
20840 static void test_position_index(void)
20842 static const D3DVERTEXELEMENT9 decl_elements[] =
20844 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
20845 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 1},
20846 D3DDECL_END()
20848 /* Declaring (and using) a position1 output semantic in a VS fails at draw time on AMD
20849 * but works on Nvidia.
20850 * MSDN is not consistent on this point. */
20851 static const DWORD vs_code[] =
20853 0xfffe0300, /* vs_3_0 */
20854 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
20855 0x0200001f, 0x80010000, 0x900f0001, /* dcl_position1 v1 */
20856 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position0 o0 */
20857 0x0200001f, 0x80010000, 0xe00f0001, /* dcl_position1 o1 */
20858 0x0200001f, 0x80000005, 0xe00f0002, /* dcl_texcoord0 o2 */
20859 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
20860 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
20861 0x02000001, 0xe00f0002, 0x90e40001, /* mov o2, v1 */
20862 0x0000ffff /* end */
20864 static const DWORD vs_code_2[] =
20866 0xfffe0300, /* vs_3_0 */
20867 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
20868 0x0200001f, 0x80010000, 0x900f0001, /* dcl_position1 v1 */
20869 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position0 o0 */
20870 0x0200001f, 0x80000005, 0xe00f0002, /* dcl_texcoord0 o2 */
20871 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
20872 0x02000001, 0xe00f0002, 0x90e40001, /* mov o2, v1 */
20873 0x0000ffff /* end */
20875 static const DWORD ps_code[] =
20877 0xffff0300, /* ps_3_0 */
20878 0x0200001f, 0x80010000, 0x900f0000, /* dcl_position1 v0 */
20879 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
20880 0x0000ffff /* end */
20882 static const DWORD ps_code_2[] =
20884 0xffff0300, /* ps_3_0 */
20885 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
20886 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
20887 0x0000ffff /* end */
20889 /* This one is considered invalid by the native shader assembler. */
20890 static const DWORD ps_code_bad[] =
20892 0xffff0300, /* ps_3_0 */
20893 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
20894 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
20895 0x0000ffff /* end */
20897 static const struct
20899 struct vec3 position;
20900 struct vec3 position1;
20902 quad[] =
20904 {{-1.0f, -1.0f, 0.5f}, {1.0f, 0.0f, 0.0f}},
20905 {{-1.0f, 1.0f, 0.5f}, {1.0f, 0.0f, 0.0f}},
20906 {{ 1.0f, -1.0f, 0.5f}, {0.0f, 1.0f, 0.0f}},
20907 {{ 1.0f, 1.0f, 0.5f}, {0.0f, 1.0f, 0.0f}},
20909 static const struct
20911 struct vec2 position;
20912 D3DCOLOR expected_color;
20913 D3DCOLOR broken_color;
20915 expected_colors[] =
20917 {{ 80, 240}, 0x00df2000, 0x00ff00ff},
20918 {{240, 240}, 0x009f6000, 0x00ff00ff},
20919 {{400, 240}, 0x00609f00, 0x00ff00ff},
20920 {{560, 240}, 0x0020df00, 0x00ff00ff},
20922 IDirect3D9 *d3d;
20923 IDirect3DDevice9 *device;
20924 IDirect3DVertexDeclaration9 *vertex_declaration;
20925 IDirect3DVertexShader9 *vs, *vs2;
20926 IDirect3DPixelShader9 *ps, *ps2;
20927 unsigned int color, i;
20928 D3DCAPS9 caps;
20929 ULONG refcount;
20930 HWND window;
20931 HRESULT hr;
20933 window = create_window();
20934 d3d = Direct3DCreate9(D3D_SDK_VERSION);
20935 ok(!!d3d, "Failed to create a D3D object.\n");
20936 if (!(device = create_device(d3d, window, window, TRUE)))
20938 skip("Failed to create a D3D device, skipping tests.\n");
20939 goto done;
20942 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
20943 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
20944 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0)
20945 || caps.PixelShaderVersion < D3DPS_VERSION(3, 0))
20947 skip("Shader model 3.0 unsupported, skipping tests.\n");
20948 IDirect3DDevice9_Release(device);
20949 goto done;
20952 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
20953 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed, hr %#lx\n", hr);
20955 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
20956 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#lx\n", hr);
20958 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
20959 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#lx.\n", hr);
20960 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code_2, &vs2);
20961 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#lx.\n", hr);
20963 hr = IDirect3DDevice9_SetVertexShader(device, vs);
20964 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
20966 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_bad, &ps);
20967 ok(hr == D3DERR_INVALIDCALL, "CreatePixelShader returned hr %#lx.\n", hr);
20969 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
20970 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#lx.\n", hr);
20971 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_2, &ps2);
20972 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#lx.\n", hr);
20974 hr = IDirect3DDevice9_SetPixelShader(device, ps);
20975 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
20977 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
20978 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
20979 hr = IDirect3DDevice9_BeginScene(device);
20980 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
20981 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
20982 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
20983 hr = IDirect3DDevice9_EndScene(device);
20984 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
20986 for (i = 0; i < ARRAY_SIZE(expected_colors); ++i)
20988 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
20989 ok (color_match(color, expected_colors[i].expected_color, 1)
20990 || broken(color_match(color, expected_colors[i].broken_color, 1)),
20991 "Got unexpected color 0x%08x, case %u.\n", color, i);
20994 hr = IDirect3DDevice9_SetPixelShader(device, ps2);
20995 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
20997 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
20998 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
20999 hr = IDirect3DDevice9_BeginScene(device);
21000 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
21001 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
21002 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
21003 hr = IDirect3DDevice9_EndScene(device);
21004 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
21006 for (i = 0; i < ARRAY_SIZE(expected_colors); ++i)
21008 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
21009 ok (color_match(color, expected_colors[i].expected_color, 1)
21010 || broken(color_match(color, expected_colors[i].broken_color, 1)),
21011 "Got unexpected color 0x%08x, case %u.\n", color, i);
21014 hr = IDirect3DDevice9_SetVertexShader(device, vs2);
21015 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
21017 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
21018 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
21019 hr = IDirect3DDevice9_BeginScene(device);
21020 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
21021 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
21022 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
21023 hr = IDirect3DDevice9_EndScene(device);
21024 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
21026 for (i = 0; i < ARRAY_SIZE(expected_colors); ++i)
21028 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
21029 ok (color_match(color, expected_colors[i].expected_color, 1),
21030 "Got unexpected color 0x%08x, case %u.\n", color, i);
21033 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
21034 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
21036 IDirect3DPixelShader9_Release(ps2);
21037 IDirect3DPixelShader9_Release(ps);
21038 IDirect3DVertexShader9_Release(vs2);
21039 IDirect3DVertexShader9_Release(vs);
21040 IDirect3DVertexDeclaration9_Release(vertex_declaration);
21041 refcount = IDirect3DDevice9_Release(device);
21042 ok(!refcount, "Device has %lu references left.\n", refcount);
21044 done:
21045 IDirect3D9_Release(d3d);
21046 DestroyWindow(window);
21049 static void test_table_fog_zw(void)
21051 HRESULT hr;
21052 IDirect3DDevice9 *device;
21053 unsigned int color;
21054 IDirect3D9 *d3d;
21055 ULONG refcount;
21056 HWND window;
21057 D3DCAPS9 caps;
21058 static struct
21060 struct vec4 position;
21061 D3DCOLOR diffuse;
21063 quad[] =
21065 {{ 0.0f, 0.0f, 0.0f, 0.0f}, 0xffff0000},
21066 {{640.0f, 0.0f, 0.0f, 0.0f}, 0xffff0000},
21067 {{ 0.0f, 480.0f, 0.0f, 0.0f}, 0xffff0000},
21068 {{640.0f, 480.0f, 0.0f, 0.0f}, 0xffff0000},
21070 static const D3DMATRIX identity =
21072 1.0f, 0.0f, 0.0f, 0.0f,
21073 0.0f, 1.0f, 0.0f, 0.0f,
21074 0.0f, 0.0f, 1.0f, 0.0f,
21075 0.0f, 0.0f, 0.0f, 1.0f
21076 }}};
21077 static const struct
21079 float z, w;
21080 D3DZBUFFERTYPE z_test;
21081 unsigned int color;
21083 tests[] =
21085 {0.7f, 0.0f, D3DZB_TRUE, 0x004cb200},
21086 {0.7f, 0.0f, D3DZB_FALSE, 0x004cb200},
21087 {0.7f, 0.3f, D3DZB_TRUE, 0x004cb200},
21088 {0.7f, 0.3f, D3DZB_FALSE, 0x004cb200},
21089 {0.7f, 3.0f, D3DZB_TRUE, 0x004cb200},
21090 {0.7f, 3.0f, D3DZB_FALSE, 0x004cb200},
21091 {0.3f, 0.0f, D3DZB_TRUE, 0x00b24c00},
21092 {0.3f, 0.0f, D3DZB_FALSE, 0x00b24c00},
21094 unsigned int i;
21096 window = create_window();
21097 d3d = Direct3DCreate9(D3D_SDK_VERSION);
21098 ok(!!d3d, "Failed to create a D3D object.\n");
21100 if (!(device = create_device(d3d, window, window, TRUE)))
21102 skip("Failed to create a D3D device, skipping tests.\n");
21103 IDirect3D9_Release(d3d);
21104 DestroyWindow(window);
21105 return;
21108 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
21109 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
21110 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
21112 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping POSITIONT table fog test.\n");
21113 goto done;
21116 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
21117 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
21118 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
21119 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
21120 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
21121 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
21122 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
21123 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
21124 /* Work around an AMD Windows driver bug. Needs a proj matrix applied redundantly. */
21125 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
21126 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#lx.\n", hr);
21127 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
21128 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
21129 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
21130 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#lx.\n", hr);
21132 for (i = 0; i < ARRAY_SIZE(tests); ++i)
21134 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
21135 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
21137 quad[0].position.z = tests[i].z;
21138 quad[1].position.z = tests[i].z;
21139 quad[2].position.z = tests[i].z;
21140 quad[3].position.z = tests[i].z;
21141 quad[0].position.w = tests[i].w;
21142 quad[1].position.w = tests[i].w;
21143 quad[2].position.w = tests[i].w;
21144 quad[3].position.w = tests[i].w;
21145 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, tests[i].z_test);
21146 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
21148 hr = IDirect3DDevice9_BeginScene(device);
21149 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
21150 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
21151 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
21152 hr = IDirect3DDevice9_EndScene(device);
21153 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
21155 color = getPixelColor(device, 320, 240);
21156 ok(color_match(color, tests[i].color, 2),
21157 "Got unexpected color 0x%08x, expected 0x%08x, case %u.\n", color, tests[i].color, i);
21158 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
21159 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
21162 done:
21163 refcount = IDirect3DDevice9_Release(device);
21164 ok(!refcount, "Device has %lu references left.\n", refcount);
21165 IDirect3D9_Release(d3d);
21166 DestroyWindow(window);
21169 static void test_signed_formats(void)
21171 unsigned int expected_color, color, i, j, x, y;
21172 IDirect3DDevice9 *device;
21173 HWND window;
21174 HRESULT hr;
21175 IDirect3DTexture9 *texture, *texture_sysmem;
21176 IDirect3DSurface9 *src_surface, *dst_surface;
21177 D3DLOCKED_RECT locked_rect;
21178 IDirect3DPixelShader9 *shader, *shader_alpha;
21179 IDirect3D9 *d3d;
21180 D3DCAPS9 caps;
21181 ULONG refcount;
21183 /* The input data was designed for D3DFMT_L6V5U5 and then transferred
21184 * to the other formats because L6V5U5 is the lowest precision format.
21185 * It tests the extreme values -1.0 (-16) and 1.0 (15) for U/V and
21186 * 0.0 (0) and 1.0 (63) for L, the neutral point 0 as well as -1 and 1.
21187 * Some other intermediate values are tested too. The input value -15
21188 * (min + 1) is tested as well. Unlike what OpenGL 4.4 says in section
21189 * 2.3.4.1, this value does not represent -1.0. In the interest of re-
21190 * using the expected output data the 8 bit and 16 bit values in V8U8
21191 * and V16U16 match (post-normalization) the 5 bit input values. Thus
21192 * -1, 1 and -127 are not tested in V8U8.
21194 * 8 bit specific values like -127 are tested in the Q channel of
21195 * D3DFMT_Q8W8V8U8. Here d3d seems to follow the rules from the GL
21196 * spec. AMD's r200 is broken though and returns a value < -1.0 for
21197 * -128. The difference between using -127 or -128 as the lowest
21198 * possible value gets lost in the slop of 1 though. */
21199 static const USHORT content_v8u8[4][4] =
21201 {0x0000, 0x7f7f, 0x8880, 0x0000},
21202 {0x0080, 0x8000, 0x7f00, 0x007f},
21203 {0x193b, 0xe8c8, 0x0808, 0xf8f8},
21204 {0x4444, 0xc0c0, 0xa066, 0x22e0},
21206 static const DWORD content_v16u16[4][4] =
21208 {0x00000000, 0x7fff7fff, 0x88008000, 0x00000000},
21209 {0x00008000, 0x80000000, 0x7fff0000, 0x00007fff},
21210 {0x19993bbb, 0xe800c800, 0x08880888, 0xf800f800},
21211 {0x44444444, 0xc000c000, 0xa0006666, 0x2222e000},
21213 static const DWORD content_q8w8v8u8[4][4] =
21215 {0x00000000, 0xff7f7f7f, 0x7f008880, 0x817f0000},
21216 {0x10000080, 0x20008000, 0x30007f00, 0x4000007f},
21217 {0x5020193b, 0x6028e8c8, 0x70020808, 0x807ff8f8},
21218 {0x90414444, 0xa000c0c0, 0x8261a066, 0x834922e0},
21220 static const DWORD content_x8l8v8u8[4][4] =
21222 {0x00000000, 0x00ff7f7f, 0x00008880, 0x00ff0000},
21223 {0x00000080, 0x00008000, 0x00007f00, 0x0000007f},
21224 {0x0041193b, 0x0051e8c8, 0x00040808, 0x00fff8f8},
21225 {0x00824444, 0x0000c0c0, 0x00c2a066, 0x009222e0},
21227 /* D3DFMT_L6V5U5 has poor precision on some GPUs. On a GeForce 7 the highest V and U value (15)
21228 * results in the output color 0xfb, which is 4 steps away from the correct value 0xff. It is
21229 * not the ~0xf0 you'd get if you blindly left-shifted the 5 bit value to form an 8 bit value
21230 * though.
21232 * There may also be an off-by-one bug involved: The value -7 should result in the output 0x47,
21233 * but ends up as 0x4d. Likewise, -3 becomes 0x6e instead of 0x67. Those values are close to
21234 * the proper results of -6 and -2.
21236 * On Wine the emulation with unsigned R5G6B5 has poor precision, e.g. the signed 0 becomes 16,
21237 * and ((16 / 31) - 0.5) * 2.0 is 0.032 instead of 0.000. The final output result we read back
21238 * is 0x84 instead of 0x80. */
21239 static const USHORT content_l6v5u5[4][4] =
21241 {0x0000, 0xfdef, 0x0230, 0xfc00},
21242 {0x0010, 0x0200, 0x01e0, 0x000f},
21243 {0x4067, 0x53b9, 0x0421, 0xffff},
21244 {0x8108, 0x0318, 0xc28c, 0x909c},
21246 static const struct
21248 D3DFORMAT format;
21249 const char *name;
21250 const void *content;
21251 SIZE_T pixel_size;
21252 BOOL blue, alpha;
21253 unsigned int slop, slop_broken, alpha_broken;
21255 formats[] =
21257 {D3DFMT_V8U8, "D3DFMT_V8U8", content_v8u8, sizeof(WORD), FALSE, FALSE, 1, 0, FALSE},
21258 {D3DFMT_V16U16, "D3DFMT_V16U16", content_v16u16, sizeof(DWORD), FALSE, FALSE, 1, 0, FALSE},
21259 {D3DFMT_Q8W8V8U8, "D3DFMT_Q8W8V8U8", content_q8w8v8u8, sizeof(DWORD), TRUE, TRUE, 1, 0, TRUE },
21260 {D3DFMT_X8L8V8U8, "D3DFMT_X8L8V8U8", content_x8l8v8u8, sizeof(DWORD), TRUE, FALSE, 1, 0, FALSE},
21261 {D3DFMT_L6V5U5, "D3DFMT_L6V5U5", content_l6v5u5, sizeof(WORD), TRUE, FALSE, 4, 7, FALSE},
21263 static const struct
21265 D3DPOOL pool;
21266 UINT width;
21267 RECT src_rect;
21268 POINT dst_point;
21270 tests[] =
21272 {D3DPOOL_SYSTEMMEM, 4, {1, 1, 2, 3}, {2, 0}},
21273 {D3DPOOL_SYSTEMMEM, 1, {0, 1, 1, 3}, {0, 0}},
21274 {D3DPOOL_MANAGED, 4, {1, 1, 2, 3}, {2, 0}},
21275 {D3DPOOL_MANAGED, 1, {0, 1, 1, 3}, {0, 0}},
21277 static const DWORD shader_code[] =
21279 0xffff0101, /* ps_1_1 */
21280 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0,5, 0,5 */
21281 0x00000042, 0xb00f0000, /* tex t0 */
21282 0x00000004, 0x800f0000, 0xb0e40000, 0xa0e40000, 0xa0e40000, /* mad r0, t0, c0, c0 */
21283 0x0000ffff /* end */
21285 static const DWORD shader_code_alpha[] =
21287 /* The idea of this shader is to replicate the alpha value in .rg, and set
21288 * blue to 1.0 iff the alpha value is < -1.0 and 0.0 otherwise. */
21289 0xffff0101, /* ps_1_1 */
21290 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
21291 0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
21292 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
21293 0x00000042, 0xb00f0000, /* tex t0 */
21294 0x00000004, 0x80070000, 0xb0ff0000, 0xa0e40000, 0xa0e40000, /* mad r0.rgb, t0.a, c0, c0 */
21295 0x00000003, 0x80080000, 0xb1ff0000, 0xa0e40000, /* sub r0.a, -t0.a, c0 */
21296 0x00000050, 0x80080000, 0x80ff0000, 0xa0ff0001, 0xa0ff0002, /* cnd r0.a, r0.a, c1.a, c2.a */
21297 0x00000005, 0x80070001, 0xa0e40001, 0x80e40000, /* mul r1.rgb, c1, r0 */
21298 0x00000004, 0x80070000, 0x80ff0000, 0xa0e40002, 0x80e40001, /* mad r0.rgb, r0.a, c2, r1 */
21299 0x0000ffff /* end */
21301 static const struct
21303 struct vec3 position;
21304 struct vec2 texcrd;
21306 quad[] =
21308 /* Flip the y coordinate to make the input and
21309 * output arrays easier to compare. */
21310 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 1.0f}},
21311 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 0.0f}},
21312 {{ 1.0f, -1.0f, 0.0f}, { 1.0f, 1.0f}},
21313 {{ 1.0f, 1.0f, 0.0f}, { 1.0f, 0.0f}},
21315 static const D3DCOLOR expected_alpha[4][4] =
21317 {0x00808000, 0x007f7f00, 0x00ffff00, 0x00000000},
21318 {0x00909000, 0x00a0a000, 0x00b0b000, 0x00c0c000},
21319 {0x00d0d000, 0x00e0e000, 0x00f0f000, 0x00000000},
21320 {0x00101000, 0x00202000, 0x00010100, 0x00020200},
21322 static const BOOL alpha_broken[4][4] =
21324 {FALSE, FALSE, FALSE, FALSE},
21325 {FALSE, FALSE, FALSE, FALSE},
21326 {FALSE, FALSE, FALSE, TRUE },
21327 {FALSE, FALSE, FALSE, FALSE},
21329 static const D3DCOLOR expected_colors[4][4] =
21331 {0x00808080, 0x00fefeff, 0x00010780, 0x008080ff},
21332 {0x00018080, 0x00800180, 0x0080fe80, 0x00fe8080},
21333 {0x00ba98a0, 0x004767a8, 0x00888881, 0x007878ff},
21334 {0x00c3c3c0, 0x003f3f80, 0x00e51fe1, 0x005fa2c8},
21336 static const D3DCOLOR expected_colors2[4][4] =
21338 {0x00808080, 0x00fefeff, 0x00800180, 0x008080ff},
21339 {0x00018080, 0x00800180, 0x004767a8, 0x00fe8080},
21340 {0x00ba98a0, 0x004767a8, 0x00888881, 0x007878ff},
21341 {0x00c3c3c0, 0x003f3f80, 0x00e51fe1, 0x005fa2c8},
21343 static const D3DCOLOR expected_colors3[4] =
21345 0x00018080,
21346 0x00ba98a0,
21347 0x00ba98a0,
21348 0x00c3c3c0,
21351 window = create_window();
21352 d3d = Direct3DCreate9(D3D_SDK_VERSION);
21353 ok(!!d3d, "Failed to create a D3D object.\n");
21355 if (!(device = create_device(d3d, window, window, TRUE)))
21357 skip("Failed to create a D3D device, skipping tests.\n");
21358 IDirect3D9_Release(d3d);
21359 DestroyWindow(window);
21360 return;
21363 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
21364 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
21366 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
21368 skip("Pixel shaders not supported, skipping converted format test.\n");
21369 goto done;
21372 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
21373 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
21374 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
21375 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
21376 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
21377 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#lx.\n", hr);
21378 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_alpha, &shader_alpha);
21379 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#lx.\n", hr);
21381 for (i = 0; i < ARRAY_SIZE(formats); i++)
21383 hr = IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
21384 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, formats[i].format);
21385 if (FAILED(hr))
21387 skip("Format %s not supported, skipping.\n", formats[i].name);
21388 continue;
21391 for (j = 0; j < ARRAY_SIZE(tests); j++)
21393 texture_sysmem = NULL;
21394 hr = IDirect3DDevice9_CreateTexture(device, tests[j].width, 4, 1, 0,
21395 formats[i].format, tests[j].pool, &texture, NULL);
21396 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
21398 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
21399 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#lx.\n", hr);
21400 for (y = 0; y < 4; y++)
21402 memcpy((char *)locked_rect.pBits + y * locked_rect.Pitch,
21403 (char *)formats[i].content + y * 4 * formats[i].pixel_size,
21404 tests[j].width * formats[i].pixel_size);
21406 hr = IDirect3DTexture9_UnlockRect(texture, 0);
21407 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#lx.\n", hr);
21409 if (tests[j].pool == D3DPOOL_SYSTEMMEM)
21411 texture_sysmem = texture;
21412 hr = IDirect3DDevice9_CreateTexture(device, tests[j].width, 4, 1, 0,
21413 formats[i].format, D3DPOOL_DEFAULT, &texture, NULL);
21414 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
21416 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)texture_sysmem,
21417 (IDirect3DBaseTexture9 *)texture);
21418 ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx.\n", hr);
21421 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
21422 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
21423 hr = IDirect3DDevice9_SetPixelShader(device, shader_alpha);
21424 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
21426 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00330033, 0.0f, 0);
21427 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
21428 hr = IDirect3DDevice9_BeginScene(device);
21429 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
21430 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(*quad));
21431 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
21432 hr = IDirect3DDevice9_EndScene(device);
21433 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
21435 for (y = 0; y < 4; y++)
21437 for (x = 0; x < tests[j].width; x++)
21439 BOOL r200_broken = formats[i].alpha_broken && alpha_broken[y][x];
21440 if (formats[i].alpha)
21441 expected_color = expected_alpha[y][x];
21442 else
21443 expected_color = 0x00ffff00;
21445 color = getPixelColor(device, 80 + 160 * x, 60 + 120 * y);
21446 ok(color_match(color, expected_color, 1) || broken(r200_broken),
21447 "Expected color 0x%08x, got 0x%08x, format %s, test %u, location %ux%u.\n",
21448 expected_color, color, formats[i].name, j, x, y);
21451 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
21452 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
21454 hr = IDirect3DDevice9_SetPixelShader(device, shader);
21455 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
21457 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00330033, 0.0f, 0);
21458 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
21459 hr = IDirect3DDevice9_BeginScene(device);
21460 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
21461 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(*quad));
21462 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
21463 hr = IDirect3DDevice9_EndScene(device);
21464 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
21466 for (y = 0; y < 4; y++)
21468 for (x = 0; x < tests[j].width; x++)
21470 expected_color = expected_colors[y][x];
21471 if (!formats[i].blue)
21472 expected_color |= 0x000000ff;
21474 color = getPixelColor(device, 80 + 160 * x, 60 + 120 * y);
21475 ok(color_match(color, expected_color, formats[i].slop)
21476 || broken(color_match(color, expected_color, formats[i].slop_broken)),
21477 "Expected color 0x%08x, got 0x%08x, format %s, test %u, location %ux%u.\n",
21478 expected_color, color, formats[i].name, j, x, y);
21481 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
21482 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
21484 if (tests[j].pool != D3DPOOL_SYSTEMMEM)
21486 IDirect3DTexture9_Release(texture);
21487 continue;
21490 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &dst_surface);
21491 ok(SUCCEEDED(hr), "Failed to get surface, hr %#lx.\n", hr);
21492 IDirect3DTexture9_GetSurfaceLevel(texture_sysmem, 0, &src_surface);
21493 ok(SUCCEEDED(hr), "Failed to get surface, hr %#lx.\n", hr);
21495 hr = IDirect3DDevice9_UpdateSurface(device, src_surface,
21496 &tests[j].src_rect, dst_surface, &tests[j].dst_point);
21497 ok(SUCCEEDED(hr), "Failed to update surface, hr %#lx.\n", hr);
21499 IDirect3DSurface9_Release(dst_surface);
21500 IDirect3DSurface9_Release(src_surface);
21502 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00003300, 0.0f, 0);
21503 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
21504 hr = IDirect3DDevice9_BeginScene(device);
21505 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
21506 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(*quad));
21507 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
21508 hr = IDirect3DDevice9_EndScene(device);
21509 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
21511 for (y = 0; y < 4; y++)
21513 for (x = 0; x < tests[j].width; x++)
21515 if (tests[j].width == 4)
21516 expected_color = expected_colors2[y][x];
21517 else
21518 expected_color = expected_colors3[y];
21520 if (!formats[i].blue)
21521 expected_color |= 0x000000ff;
21523 color = getPixelColor(device, 80 + 160 * x, 60 + 120 * y);
21524 ok(color_match(color, expected_color, formats[i].slop)
21525 || broken(color_match(color, expected_color, formats[i].slop_broken)),
21526 "Expected color 0x%08x, got 0x%08x, format %s, test %u, location %ux%u.\n",
21527 expected_color, color, formats[i].name, j, x, y);
21530 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
21531 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
21533 IDirect3DTexture9_Release(texture_sysmem);
21534 IDirect3DTexture9_Release(texture);
21538 IDirect3DPixelShader9_Release(shader);
21539 IDirect3DPixelShader9_Release(shader_alpha);
21541 done:
21542 refcount = IDirect3DDevice9_Release(device);
21543 ok(!refcount, "Device has %lu references left.\n", refcount);
21544 IDirect3D9_Release(d3d);
21545 DestroyWindow(window);
21548 static void test_multisample_mismatch(void)
21550 IDirect3DDevice9 *device;
21551 unsigned int color;
21552 IDirect3D9 *d3d;
21553 HWND window;
21554 HRESULT hr;
21555 ULONG refcount;
21556 IDirect3DSurface9 *rt, *rt_multi, *ds;
21557 static const struct
21559 struct vec3 position;
21560 DWORD color;
21562 quad[] =
21564 {{ -1.0f, -1.0f, 0.0f}, 0x000000ff},
21565 {{ -1.0f, 1.0f, 0.0f}, 0x000000ff},
21566 {{ 1.0f, -1.0f, 1.0f}, 0x000000ff},
21567 {{ 1.0f, 1.0f, 1.0f}, 0x000000ff},
21570 window = create_window();
21571 d3d = Direct3DCreate9(D3D_SDK_VERSION);
21572 ok(!!d3d, "Failed to create a D3D object.\n");
21573 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
21574 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
21576 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisample mismatch test.\n");
21577 IDirect3D9_Release(d3d);
21578 return;
21580 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
21581 D3DFMT_D24X8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
21583 skip("Multisampling not supported for D3DFMT_D24X8, skipping multisample mismatch test.\n");
21584 IDirect3D9_Release(d3d);
21585 return;
21588 if (!(device = create_device(d3d, window, window, TRUE)))
21590 skip("Failed to create a D3D device, skipping tests.\n");
21591 IDirect3D9_Release(d3d);
21592 DestroyWindow(window);
21593 return;
21596 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
21597 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt_multi, NULL);
21598 ok(SUCCEEDED(hr), "Failed to create render target, hr %#lx.\n", hr);
21600 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.1f, 0);
21601 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
21603 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
21604 ok(SUCCEEDED(hr), "Failed to set depth stencil, hr %#lx.\n", hr);
21605 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &rt);
21606 ok(SUCCEEDED(hr), "Failed to get render target, hr %#lx.\n", hr);
21607 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt_multi);
21608 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
21610 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
21611 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
21612 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
21613 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
21615 /* Clear with incompatible buffers. Partial and combined clears. */
21616 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
21617 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
21618 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.3f, 0);
21619 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
21620 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x0000ff00, 0.5f, 0);
21621 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
21623 /* The color buffer is reliably cleared on AMD and Nvidia GPUs. */
21624 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
21625 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
21626 hr = IDirect3DDevice9_StretchRect(device, rt_multi, NULL, rt, NULL, D3DTEXF_POINT);
21627 ok(SUCCEEDED(hr), "StretchRect failed, hr %#lx.\n", hr);
21628 color = getPixelColor(device, 320, 240);
21629 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
21630 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
21631 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
21633 /* Check depth buffer values. AMD GPUs (r500 and evergreen tested) clear
21634 * the depth buffer like you'd expect in a correct framebuffer
21635 * setup. Nvidia doesn't clear it, neither in the Z only clear case nor in
21636 * the combined clear case.
21637 * In Wine we currently happen to allow the depth only clear case but
21638 * disallow the combined one. */
21639 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
21640 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
21641 hr = IDirect3DDevice9_BeginScene(device);
21642 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
21643 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
21644 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
21645 hr = IDirect3DDevice9_EndScene(device);
21646 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
21647 color = getPixelColor(device, 62, 240);
21648 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
21649 color = getPixelColor(device, 64, 240);
21650 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x000000ff, 1),
21651 "Got unexpected color 0x%08x.\n", color);
21652 color = getPixelColor(device, 318, 240);
21653 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x000000ff, 1)),
21654 "Got unexpected color 0x%08x.\n", color);
21655 color = getPixelColor(device, 322, 240);
21656 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
21657 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
21658 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
21660 /* Draw with incompatible buffers. AMD even performs Z testing, and the Z test
21661 * results appear to be correct for this simple draw. Nvidia doesn't draw unless
21662 * the depth test is disabled. Setting ZFUNC = ALWAYS doesn't make the geometry
21663 * show up either. Only test the ZENABLE = FALSE case for now. */
21664 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
21665 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
21666 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt_multi);
21667 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
21668 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
21669 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
21670 hr = IDirect3DDevice9_BeginScene(device);
21671 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
21672 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
21673 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
21674 hr = IDirect3DDevice9_EndScene(device);
21675 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
21677 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
21678 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
21679 hr = IDirect3DDevice9_StretchRect(device, rt_multi, NULL, rt, NULL, D3DTEXF_POINT);
21680 ok(SUCCEEDED(hr), "StretchRect failed, hr %#lx.\n", hr);
21681 color = getPixelColor(device, 320, 240);
21682 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
21683 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
21684 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
21686 IDirect3DSurface9_Release(ds);
21688 /* Test the reverse situation: Multisampled depth buffer, single sampled color buffer.
21689 * Color clears work as expected, AMD also clears the depth buffer, Nvidia does not. */
21690 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24X8,
21691 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &ds, NULL);
21692 ok(SUCCEEDED(hr), "Failed to create depth/stencil, hr %#lx.\n", hr);
21693 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
21694 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#lx.\n", hr);
21695 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt_multi);
21696 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
21697 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ffff00, 0.1f, 0);
21698 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
21700 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
21701 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
21702 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
21703 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
21704 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.3f, 0);
21705 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
21706 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x0000ff00, 0.5f, 0);
21707 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
21709 color = getPixelColor(device, 320, 240);
21710 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
21711 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
21712 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
21714 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt_multi);
21715 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
21716 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
21717 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
21718 hr = IDirect3DDevice9_BeginScene(device);
21719 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
21720 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
21721 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
21722 hr = IDirect3DDevice9_EndScene(device);
21723 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
21725 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
21726 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
21727 hr = IDirect3DDevice9_StretchRect(device, rt_multi, NULL, rt, NULL, D3DTEXF_POINT);
21728 ok(SUCCEEDED(hr), "StretchRect failed, hr %#lx.\n", hr);
21729 color = getPixelColor(device, 62, 240);
21730 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
21731 color = getPixelColor(device, 318, 240);
21732 ok(color_match(color, 0x00ffff00, 1) || broken(color_match(color, 0x000000ff, 1)),
21733 "Got unexpected color 0x%08x.\n", color);
21734 color = getPixelColor(device, 322, 240);
21735 ok(color_match(color, 0x00ffff00, 1), "Got unexpected color 0x%08x.\n", color);
21736 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
21737 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
21739 /* Draw with a single sampled color buffer and a multisampled depth buffer. Again
21740 * AMD seems to perform correct Z testing, Nvidia doesn't draw unless the Z test
21741 * is disabled. Again only test the ZENABLE = FALSE case. */
21742 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
21743 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
21744 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
21745 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
21746 hr = IDirect3DDevice9_BeginScene(device);
21747 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
21748 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
21749 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
21750 hr = IDirect3DDevice9_EndScene(device);
21751 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
21752 color = getPixelColor(device, 320, 240);
21753 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
21754 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
21755 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
21757 /* Draw with both buffers single sampled but multisample quality set to 1 for depth buffer.
21758 * The difference in multisample quality parameter is ignored. */
21759 IDirect3DSurface9_Release(ds);
21760 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24X8,
21761 D3DMULTISAMPLE_NONE, 1, FALSE, &ds, NULL);
21762 ok(SUCCEEDED(hr), "Failed to create depth/stencil, hr %#lx.\n", hr);
21763 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
21764 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
21765 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
21766 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#lx.\n", hr);
21767 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x0000ff00, 0.5f, 0);
21768 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
21769 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
21770 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
21771 hr = IDirect3DDevice9_BeginScene(device);
21772 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
21773 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
21774 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
21775 hr = IDirect3DDevice9_EndScene(device);
21776 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
21777 color = getPixelColor(device, 62, 240);
21778 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
21779 color = getPixelColor(device, 322, 240);
21780 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
21781 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
21782 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
21784 IDirect3DSurface9_Release(rt);
21785 IDirect3DSurface9_Release(ds);
21786 IDirect3DSurface9_Release(rt_multi);
21788 refcount = IDirect3DDevice9_Release(device);
21789 ok(!refcount, "Device has %lu references left.\n", refcount);
21790 IDirect3D9_Release(d3d);
21791 DestroyWindow(window);
21794 static void test_texcoordindex(void)
21796 static const D3DMATRIX mat =
21798 1.0f, 0.0f, 0.0f, 0.0f,
21799 0.0f, 0.0f, 0.0f, 0.0f,
21800 0.0f, 0.0f, 0.0f, 0.0f,
21801 0.0f, 0.0f, 0.0f, 0.0f,
21802 }}};
21803 static const struct
21805 struct vec3 pos;
21806 struct vec2 texcoord1;
21807 struct vec2 texcoord2;
21808 struct vec2 texcoord3;
21810 quad[] =
21812 {{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f}, {0.0f, 0.0f}, {1.0f, 1.0f}},
21813 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 0.0f}},
21814 {{ 1.0f, -1.0f, 0.0f}, {1.0f, 1.0f}, {1.0f, 0.0f}, {0.0f, 1.0f}},
21815 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 0.0f}},
21817 IDirect3DDevice9 *device;
21818 unsigned int color;
21819 IDirect3D9 *d3d9;
21820 HWND window;
21821 HRESULT hr;
21822 IDirect3DTexture9 *texture1, *texture2;
21823 D3DLOCKED_RECT locked_rect;
21824 ULONG refcount;
21825 DWORD *ptr;
21827 window = create_window();
21828 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
21829 ok(!!d3d9, "Failed to create a D3D object.\n");
21830 if (!(device = create_device(d3d9, window, window, TRUE)))
21832 skip("Failed to create a D3D device, skipping tests.\n");
21833 IDirect3D9_Release(d3d9);
21834 DestroyWindow(window);
21835 return;
21838 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture1, NULL);
21839 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
21840 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
21841 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
21843 hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, D3DLOCK_DISCARD);
21844 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#lx.\n", hr);
21845 ptr = locked_rect.pBits;
21846 ptr[0] = 0xff000000;
21847 ptr[1] = 0xff00ff00;
21848 ptr[2] = 0xff0000ff;
21849 ptr[3] = 0xff00ffff;
21850 hr = IDirect3DTexture9_UnlockRect(texture1, 0);
21851 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#lx.\n", hr);
21853 hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, D3DLOCK_DISCARD);
21854 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#lx.\n", hr);
21855 ptr = locked_rect.pBits;
21856 ptr[0] = 0xff000000;
21857 ptr[1] = 0xff0000ff;
21858 ptr[2] = 0xffff0000;
21859 ptr[3] = 0xffff00ff;
21860 hr = IDirect3DTexture9_UnlockRect(texture2, 0);
21861 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#lx.\n", hr);
21863 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture1);
21864 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
21865 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *)texture2);
21866 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
21867 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX3);
21868 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
21869 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
21870 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
21871 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
21872 ok(SUCCEEDED(hr), "Failed to set color op, hr %#lx.\n", hr);
21873 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
21874 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#lx.\n", hr);
21875 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
21876 ok(SUCCEEDED(hr), "Failed to set color op, hr %#lx.\n", hr);
21877 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
21878 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#lx.\n", hr);
21879 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
21880 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#lx.\n", hr);
21881 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
21882 ok(SUCCEEDED(hr), "Failed to set color op, hr %#lx.\n", hr);
21884 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXCOORDINDEX, 1);
21885 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#lx.\n", hr);
21886 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXCOORDINDEX, 0);
21887 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#lx.\n", hr);
21889 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
21890 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
21892 hr = IDirect3DDevice9_BeginScene(device);
21893 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
21894 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
21895 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
21896 hr = IDirect3DDevice9_EndScene(device);
21897 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
21899 color = getPixelColor(device, 160, 120);
21900 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
21901 color = getPixelColor(device, 480, 120);
21902 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
21903 color = getPixelColor(device, 160, 360);
21904 ok(color_match(color, 0x00ff0000, 2), "Got unexpected color 0x%08x.\n", color);
21905 color = getPixelColor(device, 480, 360);
21906 ok(color_match(color, 0x00ffffff, 2), "Got unexpected color 0x%08x.\n", color);
21908 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
21909 ok(SUCCEEDED(hr), "Failed to set texture transform flags, hr %#lx.\n", hr);
21910 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE1, &mat);
21911 ok(SUCCEEDED(hr), "Failed to set transformation matrix, hr %#lx.\n", hr);
21913 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
21914 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
21916 hr = IDirect3DDevice9_BeginScene(device);
21917 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
21918 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
21919 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
21920 hr = IDirect3DDevice9_EndScene(device);
21921 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
21923 color = getPixelColor(device, 160, 120);
21924 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
21925 color = getPixelColor(device, 480, 120);
21926 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
21927 color = getPixelColor(device, 160, 360);
21928 ok(color_match(color, 0x00000000, 2), "Got unexpected color 0x%08x.\n", color);
21929 color = getPixelColor(device, 480, 360);
21930 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
21932 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
21933 ok(SUCCEEDED(hr), "Failed to set texture transform flags, hr %#lx.\n", hr);
21934 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXCOORDINDEX, 2);
21935 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#lx.\n", hr);
21937 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
21938 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
21940 hr = IDirect3DDevice9_BeginScene(device);
21941 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
21942 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
21943 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
21944 hr = IDirect3DDevice9_EndScene(device);
21945 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
21947 color = getPixelColor(device, 160, 120);
21948 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
21949 color = getPixelColor(device, 480, 120);
21950 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
21951 color = getPixelColor(device, 160, 360);
21952 ok(color_match(color, 0x00ff00ff, 2), "Got unexpected color 0x%08x.\n", color);
21953 color = getPixelColor(device, 480, 360);
21954 ok(color_match(color, 0x00ffff00, 2), "Got unexpected color 0x%08x.\n", color);
21956 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
21957 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
21959 IDirect3DTexture9_Release(texture1);
21960 IDirect3DTexture9_Release(texture2);
21962 refcount = IDirect3DDevice9_Release(device);
21963 ok(!refcount, "Device has %lu references left.\n", refcount);
21964 IDirect3D9_Release(d3d9);
21965 DestroyWindow(window);
21968 static void test_vertex_blending(void)
21970 IDirect3DVertexDeclaration9 *vertex_declaration;
21971 IDirect3DDevice9 *device;
21972 unsigned int color, i;
21973 IDirect3D9 *d3d;
21974 D3DCAPS9 caps;
21975 ULONG refcount;
21976 HWND window;
21977 HRESULT hr;
21979 static const D3DMATRIX view_mat =
21981 2.0f / 10.0f, 0.0f, 0.0f, 0.0f,
21982 0.0f, 2.0f / 10.0f, 0.0f, 0.0f,
21983 0.0f, 0.0f, 1.0f, 0.0f,
21984 0.0f, 0.0f, 0.0f, 1.0f
21985 }}},
21986 upper_left =
21988 1.0f, 0.0f, 0.0f, 0.0f,
21989 0.0f, 1.0f, 0.0f, 0.0f,
21990 0.0f, 0.0f, 1.0f, 0.0f,
21991 -4.0f, 4.0f, 0.0f, 1.0f
21992 }}},
21993 lower_left =
21995 1.0f, 0.0f, 0.0f, 0.0f,
21996 0.0f, 1.0f, 0.0f, 0.0f,
21997 0.0f, 0.0f, 1.0f, 0.0f,
21998 -4.0f, -4.0f, 0.0f, 1.0f
21999 }}},
22000 upper_right =
22002 1.0f, 0.0f, 0.0f, 0.0f,
22003 0.0f, 1.0f, 0.0f, 0.0f,
22004 0.0f, 0.0f, 1.0f, 0.0f,
22005 4.0f, 4.0f, 0.0f, 1.0f
22006 }}},
22007 lower_right =
22009 1.0f, 0.0f, 0.0f, 0.0f,
22010 0.0f, 1.0f, 0.0f, 0.0f,
22011 0.0f, 0.0f, 1.0f, 0.0f,
22012 4.0f, -4.0f, 0.0f, 1.0f
22013 }}};
22015 static const POINT quad_upper_right_points[] =
22017 {576, 48}, {-1, -1},
22019 quad_upper_right_empty_points[] =
22021 {64, 48}, {64, 432}, {576, 432}, {320, 240}, {-1, -1}
22023 quad_center_points[] =
22025 {320, 240}, {-1, -1}
22027 quad_center_empty_points[] =
22029 {64, 48}, {576, 48}, {64, 432}, {576, 432}, {-1, -1}
22031 quad_upper_center_points[] =
22033 {320, 48}, {-1, -1}
22035 quad_upper_center_empty_points[] =
22037 {320, 240}, {64, 48}, {576, 48}, {-1, -1}
22039 quad_fullscreen_points[] =
22041 {320, 48}, {320, 240}, {64, 48}, {576, 48}, {64, 432}, {576, 432}, {-1, -1}
22043 quad_fullscreen_empty_points[] =
22045 {-1, -1}
22048 static const struct
22050 DWORD fvf;
22051 D3DVERTEXELEMENT9 decl_elements[3];
22052 struct
22054 struct
22056 struct vec3 position;
22057 struct vec3 blendweights;
22059 vertex_data_float[4];
22060 struct
22062 struct vec3 position;
22063 D3DCOLOR blendweights;
22065 vertex_data_d3dcolor[4];
22066 } s;
22067 const POINT *quad_points;
22068 const POINT *empty_points;
22070 tests[] =
22072 /* upper right */
22074 D3DFVF_XYZB3,
22075 {{0}},
22076 {{{{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
22077 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
22078 {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
22079 {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}}}},
22080 quad_upper_right_points, quad_upper_right_empty_points
22082 /* center */
22084 D3DFVF_XYZB3,
22085 {{0}},
22086 {{{{-1.0f, -1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}},
22087 {{-1.0f, 1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}},
22088 {{ 1.0f, -1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}},
22089 {{ 1.0f, 1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}}}},
22090 quad_center_points, quad_center_empty_points
22092 /* upper center */
22094 D3DFVF_XYZB3,
22095 {{0}},
22096 {{{{-1.0f, -1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}},
22097 {{-1.0f, 1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}},
22098 {{ 1.0f, -1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}},
22099 {{ 1.0f, 1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}}}},
22100 quad_upper_center_points, quad_upper_center_empty_points
22102 /* full screen */
22104 D3DFVF_XYZB3,
22105 {{0}},
22106 {{{{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f, 0.0f}},
22107 {{-1.0f, 1.0f, 0.0f}, {1.0f, 0.0f, 0.0f}},
22108 {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}},
22109 {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}}}},
22110 quad_fullscreen_points, quad_fullscreen_empty_points
22112 /* D3DCOLOR, full screen */
22116 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
22117 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
22118 D3DDECL_END()
22120 {{{{0}}},
22121 {{{-1.0f, -1.0f, 0.0f}, 0x0000ff00},
22122 {{-1.0f, 1.0f, 0.0f}, 0x00ff0000},
22123 {{ 1.0f, -1.0f, 0.0f}, 0x000000ff},
22124 {{ 1.0f, 1.0f, 0.0f}, 0x00000000}}},
22125 quad_fullscreen_points, quad_fullscreen_empty_points
22129 window = create_window();
22130 d3d = Direct3DCreate9(D3D_SDK_VERSION);
22131 ok(!!d3d, "Failed to create a D3D object.\n");
22132 if (!(device = create_device(d3d, window, window, TRUE)))
22134 skip("Failed to create a D3D device, skipping tests.\n");
22135 goto done;
22138 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
22139 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
22140 if (caps.MaxVertexBlendMatrices < 4)
22142 skip("Only %lu vertex blend matrices supported, skipping tests.\n", caps.MaxVertexBlendMatrices);
22143 IDirect3DDevice9_Release(device);
22144 goto done;
22147 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
22148 ok(hr == S_OK, "Got hr %#lx.\n", hr);
22150 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &view_mat);
22151 ok(hr == S_OK, "Got hr %#lx.\n", hr);
22153 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), &upper_left);
22154 ok(hr == S_OK, "Got hr %#lx.\n", hr);
22155 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(1), &lower_left);
22156 ok(hr == S_OK, "Got hr %#lx.\n", hr);
22157 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(2), &lower_right);
22158 ok(hr == S_OK, "Got hr %#lx.\n", hr);
22159 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(3), &upper_right);
22160 ok(hr == S_OK, "Got hr %#lx.\n", hr);
22162 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_VERTEXBLEND, D3DVBF_3WEIGHTS);
22163 ok(hr == S_OK, "Got hr %#lx.\n", hr);
22165 for (i = 0; i < ARRAY_SIZE(tests); ++i)
22167 const POINT *point;
22169 if (tests[i].fvf)
22171 hr = IDirect3DDevice9_SetFVF(device, tests[i].fvf);
22172 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
22173 vertex_declaration = NULL;
22175 else
22177 hr = IDirect3DDevice9_CreateVertexDeclaration(device, tests[i].decl_elements, &vertex_declaration);
22178 ok(SUCCEEDED(hr), "Failed to create vertex declaration, hr %#lx.\n", hr);
22179 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
22180 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
22183 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
22184 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
22186 hr = IDirect3DDevice9_BeginScene(device);
22187 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
22189 if (tests[i].fvf)
22190 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
22191 tests[i].s.vertex_data_float, sizeof(*tests[i].s.vertex_data_float));
22192 else
22193 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
22194 tests[i].s.vertex_data_d3dcolor, sizeof(*tests[i].s.vertex_data_d3dcolor));
22195 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
22197 hr = IDirect3DDevice9_EndScene(device);
22198 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
22200 point = tests[i].quad_points;
22201 while (point->x != -1 && point->y != -1)
22203 color = getPixelColor(device, point->x, point->y);
22204 ok(color_match(color, 0x00ffffff, 1), "Expected quad at (%ld,%ld).\n", point->x, point->y);
22205 ++point;
22208 point = tests[i].empty_points;
22209 while (point->x != -1 && point->y != -1)
22211 color = getPixelColor(device, point->x, point->y);
22212 ok(color_match(color, 0x00000000, 1), "Unexpected quad at (%ld,%ld).\n", point->x, point->y);
22213 ++point;
22216 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
22217 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
22219 if (vertex_declaration)
22220 IDirect3DVertexDeclaration9_Release(vertex_declaration);
22223 refcount = IDirect3DDevice9_Release(device);
22224 ok(!refcount, "Device has %lu references left.\n", refcount);
22226 done:
22227 IDirect3D9_Release(d3d);
22228 DestroyWindow(window);
22231 static void test_updatetexture(void)
22233 BOOL r32f_supported, ati2n_supported, do_visual_test;
22234 unsigned int color, t, i, f, l, x, y, z;
22235 IDirect3DBaseTexture9 *src, *dst;
22236 D3DLOCKED_RECT locked_rect;
22237 D3DLOCKED_BOX locked_box;
22238 IDirect3DDevice9 *device;
22239 IDirect3D9 *d3d9;
22240 ULONG refcount;
22241 D3DCAPS9 caps;
22242 HWND window;
22243 HRESULT hr;
22244 static const struct
22246 struct vec3 pos;
22247 struct vec2 texcoord;
22249 quad[] =
22251 {{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f}},
22252 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f}},
22253 {{ 1.0f, -1.0f, 0.0f}, {1.0f, 1.0f}},
22254 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.0f}},
22256 static const struct
22258 struct vec3 pos;
22259 struct vec3 texcoord;
22261 quad_cube_tex[] =
22263 {{-1.0f, -1.0f, 0.0f}, {1.0f, -0.5f, 0.5f}},
22264 {{-1.0f, 1.0f, 0.0f}, {1.0f, 0.5f, 0.5f}},
22265 {{ 1.0f, -1.0f, 0.0f}, {1.0f, -0.5f, -0.5f}},
22266 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.5f, -0.5f}},
22268 static const struct
22270 UINT src_width, src_height;
22271 UINT dst_width, dst_height;
22272 UINT src_levels, dst_levels;
22273 D3DFORMAT src_format, dst_format;
22274 BOOL broken_result, broken_updatetex;
22276 tests[] =
22278 {8, 8, 8, 8, 0, 0, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 0 */
22279 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 1 */
22280 {8, 8, 8, 8, 2, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 2 */
22281 {8, 8, 8, 8, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 3 */
22282 {8, 8, 8, 8, 4, 0, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 4 */
22283 {8, 8, 2, 2, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 5 */
22284 /* The WARP renderer doesn't handle these cases correctly. */
22285 {8, 8, 8, 8, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, TRUE}, /* 6 */
22286 {8, 8, 4, 4, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, TRUE}, /* 7 */
22287 /* Not clear what happens here on Windows, it doesn't make much sense
22288 * though (on Nvidia it seems to upload the 4x4 surface into the 7x7
22289 * one or something like that). */
22290 /* {8, 8, 7, 7, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, */
22291 {8, 8, 8, 8, 1, 4, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 8 */
22292 /* For this one UpdateTexture() returns failure on WARP on > Win 10 1709. */
22293 {4, 4, 8, 8, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE, TRUE}, /* 9 */
22294 /* This one causes weird behavior on Windows (it probably writes out
22295 * of the texture memory). */
22296 /* {8, 8, 4, 4, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, */
22297 {8, 4, 4, 2, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 10 */
22298 {8, 4, 2, 4, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 11 */
22299 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_X8R8G8B8, FALSE}, /* 12 */
22300 {8, 8, 8, 8, 4, 4, D3DFMT_X8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 13 */
22301 /* The data is converted correctly on AMD, on Nvidia nothing happens
22302 * (it draws a black quad). */
22303 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_R5G6B5, TRUE}, /* 14 */
22304 /* Here the data is converted on AMD, just copied and "reinterpreted" as
22305 * a 32 bit float on Nvidia (specifically the tested value becomes a
22306 * very small float number which we get as 0 in the test). */
22307 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_R32F, TRUE}, /* 15 */
22308 /* This one doesn't seem to give the expected results on AMD. */
22309 /* {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_Q8W8V8U8, FALSE}, */
22310 {8, 8, 8, 8, 4, 4, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE}, /* 16 */
22311 {8, 8, 8, 8, 4, 2, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE}, /* 17 */
22312 {8, 8, 2, 2, 4, 2, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE}, /* 18 */
22314 static const struct
22316 D3DRESOURCETYPE type;
22317 DWORD fvf;
22318 const void *quad;
22319 unsigned int vertex_size;
22320 DWORD cap;
22321 const char *name;
22323 texture_types[] =
22325 {D3DRTYPE_TEXTURE, D3DFVF_XYZ | D3DFVF_TEX1,
22326 quad, sizeof(*quad), D3DPTEXTURECAPS_MIPMAP, "2D mipmapped"},
22328 {D3DRTYPE_CUBETEXTURE, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0),
22329 quad_cube_tex, sizeof(*quad_cube_tex), D3DPTEXTURECAPS_CUBEMAP, "Cube"},
22331 {D3DRTYPE_VOLUMETEXTURE, D3DFVF_XYZ | D3DFVF_TEX1,
22332 quad, sizeof(*quad), D3DPTEXTURECAPS_VOLUMEMAP, "Volume"}
22335 window = create_window();
22336 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
22337 ok(!!d3d9, "Failed to create a D3D object.\n");
22338 if (!(device = create_device(d3d9, window, window, TRUE)))
22340 skip("Failed to create a D3D device, skipping tests.\n");
22341 IDirect3D9_Release(d3d9);
22342 DestroyWindow(window);
22343 return;
22346 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
22347 ok(SUCCEEDED(hr), "Failed to get caps, hr %#lx.\n", hr);
22349 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
22350 ok(SUCCEEDED(hr), "Failed to set texture filtering state, hr %#lx.\n", hr);
22351 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
22352 ok(SUCCEEDED(hr), "Failed to set texture clamping state, hr %#lx.\n", hr);
22353 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
22354 ok(SUCCEEDED(hr), "Failed to set texture clamping state, hr %#lx.\n", hr);
22355 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
22356 ok(SUCCEEDED(hr), "Failed to set texture clamping state, hr %#lx.\n", hr);
22357 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
22358 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
22359 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
22360 ok(hr == D3D_OK, "Failed to set texture stage state, hr %#lx.\n", hr);
22361 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
22362 ok(hr == D3D_OK, "Failed to set texture stage state, hr %#lx.\n", hr);
22364 for (t = 0; t < ARRAY_SIZE(texture_types); ++t)
22366 if (!(caps.TextureCaps & texture_types[t].cap))
22368 skip("%s textures not supported, skipping some tests.\n", texture_types[t].name);
22369 continue;
22371 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
22372 D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_FILTER, texture_types[t].type, D3DFMT_A8R8G8B8)))
22374 skip("%s D3DFMT_A8R8G8B8 texture filtering is not supported, skipping some tests.\n",
22375 texture_types[t].name);
22376 continue;
22378 r32f_supported = TRUE;
22379 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
22380 D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_FILTER, texture_types[t].type, D3DFMT_R32F)))
22382 skip("%s R32F textures are not supported, skipping some tests.\n", texture_types[t].name);
22383 r32f_supported = FALSE;
22385 ati2n_supported = TRUE;
22386 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
22387 D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_FILTER, texture_types[t].type, MAKEFOURCC('A','T','I','2'))))
22389 skip("%s ATI2N textures are not supported, skipping some tests.\n", texture_types[t].name);
22390 ati2n_supported = FALSE;
22393 hr = IDirect3DDevice9_SetFVF(device, texture_types[t].fvf);
22394 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
22396 for (i = 0; i < ARRAY_SIZE(tests); ++i)
22398 if (tests[i].dst_format == D3DFMT_R32F && !r32f_supported)
22399 continue;
22400 if (tests[i].dst_format == MAKEFOURCC('A','T','I','2') && !ati2n_supported)
22401 continue;
22403 switch (texture_types[t].type)
22405 case D3DRTYPE_TEXTURE:
22406 hr = IDirect3DDevice9_CreateTexture(device,
22407 tests[i].src_width, tests[i].src_height,
22408 tests[i].src_levels, 0, tests[i].src_format, D3DPOOL_SYSTEMMEM,
22409 (IDirect3DTexture9 **)&src, NULL);
22410 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx, case %u, %u.\n", hr, t, i);
22411 hr = IDirect3DDevice9_CreateTexture(device,
22412 tests[i].dst_width, tests[i].dst_height,
22413 tests[i].dst_levels, 0, tests[i].dst_format, D3DPOOL_DEFAULT,
22414 (IDirect3DTexture9 **)&dst, NULL);
22415 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx, case %u, %u.\n", hr, t, i);
22416 break;
22417 case D3DRTYPE_CUBETEXTURE:
22418 hr = IDirect3DDevice9_CreateCubeTexture(device,
22419 tests[i].src_width,
22420 tests[i].src_levels, 0, tests[i].src_format, D3DPOOL_SYSTEMMEM,
22421 (IDirect3DCubeTexture9 **)&src, NULL);
22422 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx, case %u, %u.\n", hr, t, i);
22423 hr = IDirect3DDevice9_CreateCubeTexture(device,
22424 tests[i].dst_width,
22425 tests[i].dst_levels, 0, tests[i].dst_format, D3DPOOL_DEFAULT,
22426 (IDirect3DCubeTexture9 **)&dst, NULL);
22427 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx, case %u, %u.\n", hr, t, i);
22428 break;
22429 case D3DRTYPE_VOLUMETEXTURE:
22430 hr = IDirect3DDevice9_CreateVolumeTexture(device,
22431 tests[i].src_width, tests[i].src_height, tests[i].src_width,
22432 tests[i].src_levels, 0, tests[i].src_format, D3DPOOL_SYSTEMMEM,
22433 (IDirect3DVolumeTexture9 **)&src, NULL);
22434 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx, case %u, %u.\n", hr, t, i);
22435 hr = IDirect3DDevice9_CreateVolumeTexture(device,
22436 tests[i].dst_width, tests[i].dst_height, tests[i].dst_width,
22437 tests[i].dst_levels, 0, tests[i].dst_format, D3DPOOL_DEFAULT,
22438 (IDirect3DVolumeTexture9 **)&dst, NULL);
22439 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx, case %u, %u.\n", hr, t, i);
22440 break;
22441 default:
22442 trace("Unexpected resource type.\n");
22445 /* Skip the visual part of the test for ATI2N (laziness) and cases that
22446 * give a different (and unlikely to be useful) result. */
22447 do_visual_test = (tests[i].src_format == D3DFMT_A8R8G8B8 || tests[i].src_format == D3DFMT_X8R8G8B8)
22448 && tests[i].src_levels != 0
22449 && tests[i].src_width >= tests[i].dst_width && tests[i].src_height >= tests[i].dst_height
22450 && !(tests[i].src_width > tests[i].src_height && tests[i].dst_width < tests[i].dst_height);
22452 if (do_visual_test)
22454 DWORD *ptr = NULL;
22455 unsigned int width, height, depth, row_pitch = 0, slice_pitch = 0;
22457 for (f = 0; f < (texture_types[t].type == D3DRTYPE_CUBETEXTURE ? 6 : 1); ++f)
22459 width = tests[i].src_width;
22460 height = texture_types[t].type != D3DRTYPE_CUBETEXTURE ? tests[i].src_height : tests[i].src_width;
22461 depth = texture_types[t].type == D3DRTYPE_VOLUMETEXTURE ? width : 1;
22463 for (l = 0; l < tests[i].src_levels; ++l)
22465 switch (texture_types[t].type)
22467 case D3DRTYPE_TEXTURE:
22468 hr = IDirect3DTexture9_LockRect((IDirect3DTexture9 *)src,
22469 l, &locked_rect, NULL, 0);
22470 ptr = locked_rect.pBits;
22471 row_pitch = locked_rect.Pitch / sizeof(*ptr);
22472 break;
22473 case D3DRTYPE_CUBETEXTURE:
22474 hr = IDirect3DCubeTexture9_LockRect((IDirect3DCubeTexture9 *)src,
22475 f, l, &locked_rect, NULL, 0);
22476 ptr = locked_rect.pBits;
22477 row_pitch = locked_rect.Pitch / sizeof(*ptr);
22478 break;
22479 case D3DRTYPE_VOLUMETEXTURE:
22480 hr = IDirect3DVolumeTexture9_LockBox((IDirect3DVolumeTexture9 *)src,
22481 l, &locked_box, NULL, 0);
22482 ptr = locked_box.pBits;
22483 row_pitch = locked_box.RowPitch / sizeof(*ptr);
22484 slice_pitch = locked_box.SlicePitch / sizeof(*ptr);
22485 break;
22486 default:
22487 trace("Unexpected resource type.\n");
22489 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#lx.\n", hr);
22491 for (z = 0; z < depth; ++z)
22493 for (y = 0; y < height; ++y)
22495 for (x = 0; x < width; ++x)
22497 ptr[z * slice_pitch + y * row_pitch + x] = 0xff000000
22498 | (DWORD)(x / (width - 1.0f) * 255.0f) << 16
22499 | (DWORD)(y / (height - 1.0f) * 255.0f) << 8;
22504 switch (texture_types[t].type)
22506 case D3DRTYPE_TEXTURE:
22507 hr = IDirect3DTexture9_UnlockRect((IDirect3DTexture9 *)src, l);
22508 break;
22509 case D3DRTYPE_CUBETEXTURE:
22510 hr = IDirect3DCubeTexture9_UnlockRect((IDirect3DCubeTexture9 *)src, f, l);
22511 break;
22512 case D3DRTYPE_VOLUMETEXTURE:
22513 hr = IDirect3DVolumeTexture9_UnlockBox((IDirect3DVolumeTexture9 *)src, l);
22514 break;
22515 default:
22516 trace("Unexpected resource type.\n");
22518 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#lx.\n", hr);
22520 width >>= 1;
22521 if (!width)
22522 width = 1;
22523 height >>= 1;
22524 if (!height)
22525 height = 1;
22526 depth >>= 1;
22527 if (!depth)
22528 depth = 1;
22533 hr = IDirect3DDevice9_UpdateTexture(device, src, dst);
22534 if (FAILED(hr))
22536 todo_wine ok(SUCCEEDED(hr) || broken(tests[i].broken_updatetex),
22537 "Failed to update texture, hr %#lx, case %u, %u.\n", hr, t, i);
22538 IDirect3DBaseTexture9_Release(src);
22539 IDirect3DBaseTexture9_Release(dst);
22540 continue;
22542 ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx, case %u, %u.\n", hr, t, i);
22544 if (do_visual_test)
22546 hr = IDirect3DDevice9_SetTexture(device, 0, dst);
22547 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
22549 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 1.0f, 0);
22550 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
22552 hr = IDirect3DDevice9_BeginScene(device);
22553 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
22554 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
22555 texture_types[t].quad, texture_types[t].vertex_size);
22556 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
22557 hr = IDirect3DDevice9_EndScene(device);
22558 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
22560 color = getPixelColor(device, 320, 240);
22561 ok (color_match(color, 0x007f7f00, 3) || broken(tests[i].broken_result)
22562 || broken(color == 0x00adbeef), /* WARP device often just breaks down. */
22563 "Got unexpected color 0x%08x, case %u, %u.\n", color, t, i);
22566 IDirect3DBaseTexture9_Release(src);
22567 IDirect3DBaseTexture9_Release(dst);
22570 refcount = IDirect3DDevice9_Release(device);
22571 ok(!refcount, "Device has %lu references left.\n", refcount);
22572 IDirect3D9_Release(d3d9);
22573 DestroyWindow(window);
22576 static void test_depthbias(void)
22578 IDirect3DDevice9 *device;
22579 unsigned int color, i;
22580 IDirect3D9 *d3d;
22581 IDirect3DSurface9 *ds;
22582 D3DCAPS9 caps;
22583 ULONG refcount;
22584 HWND window;
22585 HRESULT hr;
22586 static const D3DFORMAT formats[] =
22588 D3DFMT_D16, D3DFMT_D24X8, D3DFMT_D32, D3DFMT_D24S8, MAKEFOURCC('I','N','T','Z'),
22590 /* The scaling factor detection function detects the wrong factor for
22591 * float formats on Nvidia, therefore the following tests are disabled.
22592 * The wined3d function detects 2^23 like for fixed point formats but
22593 * the test needs 2^22 to pass.
22595 * AMD GPUs need a different scaling factor for float depth buffers
22596 * (2^24) than fixed point (2^23), but the wined3d detection function
22597 * works there, producing the right result in the test.
22599 * D3DFMT_D32F_LOCKABLE, D3DFMT_D24FS8,
22603 static const struct
22605 struct vec3 position;
22607 quad[] =
22609 {{-1.0f, -1.0f, 0.0f}},
22610 {{-1.0f, 1.0f, 0.0f}},
22611 {{ 1.0f, -1.0f, 1.0f}},
22612 {{ 1.0f, 1.0f, 1.0f}},
22614 union
22616 float f;
22617 DWORD d;
22618 } conv;
22620 window = create_window();
22621 d3d = Direct3DCreate9(D3D_SDK_VERSION);
22622 ok(!!d3d, "Failed to create a D3D object.\n");
22623 if (!(device = create_device(d3d, window, window, TRUE)))
22625 skip("Failed to create a D3D device, skipping tests.\n");
22626 goto done;
22629 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
22630 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
22631 if (!(caps.RasterCaps & D3DPRASTERCAPS_DEPTHBIAS))
22633 IDirect3DDevice9_Release(device);
22634 skip("D3DPRASTERCAPS_DEPTHBIAS not supported.\n");
22635 goto done;
22638 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
22639 ok(hr == S_OK, "Got hr %#lx.\n", hr);
22640 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
22641 ok(hr == S_OK, "Got hr %#lx.\n", hr);
22642 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
22643 ok(SUCCEEDED(hr), "Failed to set color op, hr %#lx.\n", hr);
22644 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
22645 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#lx.\n", hr);
22646 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
22647 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
22649 for (i = 0; i < ARRAY_SIZE(formats); ++i)
22651 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
22652 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, formats[i])))
22654 skip("Depth format %u not supported, skipping.\n", formats[i]);
22655 continue;
22658 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, formats[i],
22659 D3DMULTISAMPLE_NONE, 0, FALSE, &ds, NULL);
22660 ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr %#lx.\n", hr);
22661 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
22662 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#lx.\n", hr);
22663 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 0.5f, 0);
22664 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
22666 hr = IDirect3DDevice9_BeginScene(device);
22667 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
22669 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x00ff0000);
22670 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
22671 conv.f = -0.2f;
22672 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DEPTHBIAS, conv.d);
22673 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
22674 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
22675 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
22677 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
22678 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
22679 conv.f = 0.0f;
22680 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DEPTHBIAS, conv.d);
22681 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
22682 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
22683 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
22685 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x000000ff);
22686 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
22687 conv.f = 0.2f;
22688 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DEPTHBIAS, conv.d);
22689 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
22690 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
22691 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
22693 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x00ffffff);
22694 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
22695 conv.f = 0.4f;
22696 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DEPTHBIAS, conv.d);
22697 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
22698 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
22699 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
22701 color = getPixelColor(device, 61, 240);
22702 ok(color_match(color, 0x00ffffff, 1), "Got unexpected color %08x at x=62, format %u.\n", color, formats[i]);
22703 color = getPixelColor(device, 65, 240);
22705 /* The broken results are for the WARP driver on the testbot. It seems to initialize
22706 * a scaling factor based on the first depth format that is used. Other formats with
22707 * a different depth size then render incorrectly. */
22708 todo_wine_if(!color_match(color, 0x000000ff, 1))
22709 ok(color_match(color, 0x000000ff, 1) || broken(color_match(color, 0x00ffffff, 1)),
22710 "Got unexpected color %08x at x=64, format %u.\n", color, formats[i]);
22711 color = getPixelColor(device, 190, 240);
22712 todo_wine_if(!color_match(color, 0x000000ff, 1))
22713 ok(color_match(color, 0x000000ff, 1) || broken(color_match(color, 0x00ffffff, 1)),
22714 "Got unexpected color %08x at x=190, format %u.\n", color, formats[i]);
22716 color = getPixelColor(device, 194, 240);
22717 todo_wine_if(!color_match(color, 0x0000ff00, 1))
22718 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ffffff, 1)),
22719 "Got unexpected color %08x at x=194, format %u.\n", color, formats[i]);
22720 color = getPixelColor(device, 318, 240);
22721 todo_wine_if(!color_match(color, 0x0000ff00, 1))
22722 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ffffff, 1)),
22723 "Got unexpected color %08x at x=318, format %u.\n", color, formats[i]);
22725 color = getPixelColor(device, 322, 240);
22726 todo_wine_if(!color_match(color, 0x00ff0000, 1))
22727 ok(color_match(color, 0x00ff0000, 1) || broken(color_match(color, 0x00000000, 1)),
22728 "Got unexpected color %08x at x=322, format %u.\n", color, formats[i]);
22729 color = getPixelColor(device, 446, 240);
22730 todo_wine_if(!color_match(color, 0x00ff0000, 1))
22731 ok(color_match(color, 0x00ff0000, 1) || broken(color_match(color, 0x00000000, 1)),
22732 "Got unexpected color %08x at x=446, format %u.\n", color, formats[i]);
22734 color = getPixelColor(device, 450, 240);
22735 ok(color_match(color, 0x00000000, 1), "Got unexpected color %08x at x=446, format %u.\n", color, formats[i]);
22737 hr = IDirect3DDevice9_EndScene(device);
22738 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
22740 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
22741 ok(hr == S_OK, "Got hr %#lx.\n", hr);
22742 IDirect3DSurface9_Release(ds);
22745 refcount = IDirect3DDevice9_Release(device);
22746 ok(!refcount, "Device has %lu references left.\n", refcount);
22748 done:
22749 IDirect3D9_Release(d3d);
22750 DestroyWindow(window);
22753 static void test_flip(void)
22755 IDirect3DDevice9 *device;
22756 unsigned int color, i;
22757 IDirect3D9 *d3d;
22758 ULONG refcount;
22759 HWND window;
22760 HRESULT hr;
22761 IDirect3DSurface9 *back_buffers[3], *test_surface;
22762 D3DPRESENT_PARAMETERS present_parameters = {0};
22764 window = create_window();
22765 d3d = Direct3DCreate9(D3D_SDK_VERSION);
22766 ok(!!d3d, "Failed to create a D3D object.\n");
22768 present_parameters.BackBufferWidth = 640;
22769 present_parameters.BackBufferHeight = 480;
22770 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
22771 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
22772 present_parameters.hDeviceWindow = window;
22773 present_parameters.Windowed = TRUE;
22774 present_parameters.BackBufferCount = 3;
22775 present_parameters.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
22776 if (FAILED(hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
22777 window, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device)))
22779 skip("Failed to create a D3D device, skipping tests.\n");
22780 IDirect3D9_Release(d3d);
22781 DestroyWindow(window);
22782 return;
22785 for (i = 0; i < ARRAY_SIZE(back_buffers); ++i)
22787 hr = IDirect3DDevice9_GetBackBuffer(device, 0, i, D3DBACKBUFFER_TYPE_MONO, &back_buffers[i]);
22788 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#lx.\n", hr);
22790 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &test_surface);
22791 ok(SUCCEEDED(hr), "Failed to get render target, hr %#lx.\n", hr);
22792 ok(test_surface == back_buffers[0], "Expected render target %p, got %p.\n", back_buffers[0], test_surface);
22793 IDirect3DSurface9_Release(test_surface);
22795 hr = IDirect3DDevice9_SetRenderTarget(device, 0, back_buffers[2]);
22796 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
22798 hr = IDirect3DDevice9_ColorFill(device, back_buffers[0], NULL, 0xffff0000);
22799 ok(SUCCEEDED(hr), "Failed to color fill, hr %#lx.\n", hr);
22800 hr = IDirect3DDevice9_ColorFill(device, back_buffers[1], NULL, 0xff00ff00);
22801 ok(SUCCEEDED(hr), "Failed to color fill, hr %#lx.\n", hr);
22802 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
22803 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx\n", hr);
22805 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
22806 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
22808 /* Render target is unmodified. */
22809 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &test_surface);
22810 ok(SUCCEEDED(hr), "Failed to get render target, hr %#lx.\n", hr);
22811 ok(test_surface == back_buffers[2], "Expected render target %p, got %p.\n", back_buffers[2], test_surface);
22812 IDirect3DSurface9_Release(test_surface);
22814 /* Backbuffer surface pointers are unmodified */
22815 for (i = 0; i < ARRAY_SIZE(back_buffers); ++i)
22817 hr = IDirect3DDevice9_GetBackBuffer(device, 0, i, D3DBACKBUFFER_TYPE_MONO, &test_surface);
22818 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#lx.\n", hr);
22819 ok(test_surface == back_buffers[i], "Expected back buffer %u = %p, got %p.\n",
22820 i, back_buffers[i], test_surface);
22821 IDirect3DSurface9_Release(test_surface);
22824 /* Contents were changed. */
22825 color = getPixelColorFromSurface(back_buffers[0], 1, 1);
22826 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
22827 color = getPixelColorFromSurface(back_buffers[1], 1, 1);
22828 ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
22830 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0f, 0);
22831 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx\n", hr);
22833 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
22834 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
22836 color = getPixelColorFromSurface(back_buffers[0], 1, 1);
22837 ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
22838 color = getPixelColorFromSurface(back_buffers[1], 1, 1);
22839 ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
22841 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
22842 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
22844 color = getPixelColorFromSurface(back_buffers[0], 1, 1);
22845 ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
22847 for (i = 0; i < ARRAY_SIZE(back_buffers); ++i)
22848 IDirect3DSurface9_Release(back_buffers[i]);
22850 refcount = IDirect3DDevice9_Release(device);
22851 ok(!refcount, "Device has %lu references left.\n", refcount);
22853 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
22854 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
22856 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisample flip test.\n");
22857 goto done;
22860 present_parameters.BackBufferCount = 2;
22861 present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
22862 present_parameters.Flags = 0;
22863 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
22864 window, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device);
22866 for (i = 0; i < present_parameters.BackBufferCount; ++i)
22868 hr = IDirect3DDevice9_GetBackBuffer(device, 0, i, D3DBACKBUFFER_TYPE_MONO, &back_buffers[i]);
22869 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#lx.\n", hr);
22872 hr = IDirect3DDevice9_SetRenderTarget(device, 0, back_buffers[1]);
22873 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
22874 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0f, 0);
22875 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
22877 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
22878 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
22880 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
22881 D3DMULTISAMPLE_NONE, 0, TRUE, &test_surface, NULL);
22882 ok(SUCCEEDED(hr), "Failed to create surface, hr %#lx.\n", hr);
22883 hr = IDirect3DDevice9_StretchRect(device, back_buffers[0], NULL, test_surface, NULL, D3DTEXF_POINT);
22884 ok(SUCCEEDED(hr), "StretchRect failed, hr %#lx.\n", hr);
22886 color = getPixelColorFromSurface(test_surface, 1, 1);
22887 ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
22889 IDirect3DSurface9_Release(test_surface);
22890 for (i = 0; i < present_parameters.BackBufferCount; ++i)
22891 IDirect3DSurface9_Release(back_buffers[i]);
22893 refcount = IDirect3DDevice9_Release(device);
22894 ok(!refcount, "Device has %lu references left.\n", refcount);
22896 done:
22897 IDirect3D9_Release(d3d);
22898 DestroyWindow(window);
22901 static void test_uninitialized_varyings(void)
22903 static const D3DMATRIX mat =
22905 1.0f, 0.0f, 0.0f, 0.0f,
22906 0.0f, 1.0f, 0.0f, 0.0f,
22907 0.0f, 0.0f, 1.0f, 0.0f,
22908 0.0f, 0.0f, 0.0f, 1.0f,
22909 }}};
22910 static const struct vec3 quad[] =
22912 {-1.0f, -1.0f, 0.1f},
22913 {-1.0f, 1.0f, 0.1f},
22914 { 1.0f, -1.0f, 0.1f},
22915 { 1.0f, 1.0f, 0.1f},
22917 static const DWORD vs1_code[] =
22919 0xfffe0101, /* vs_1_1 */
22920 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
22921 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
22922 0x0000ffff
22924 static const DWORD vs1_partial_code[] =
22926 0xfffe0101, /* vs_1_1 */
22927 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
22928 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
22929 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
22930 0x00000001, 0xd0010000, 0xa0e40000, /* mov oD0.x, c0 */
22931 0x00000001, 0xd0010001, 0xa0e40000, /* mov oD1.x, c0 */
22932 0x00000001, 0xe0010000, 0xa0e40000, /* mov oT0.x, c0 */
22933 0x0000ffff
22935 static const DWORD vs2_code[] =
22937 0xfffe0200, /* vs_2_0 */
22938 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
22939 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
22940 0x0000ffff
22942 static const DWORD vs2_partial_code[] =
22944 0xfffe0200, /* vs_2_0 */
22945 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
22946 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
22947 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
22948 0x02000001, 0xd0010000, 0xa0e40000, /* mov oD0.x, c0 */
22949 0x02000001, 0xd0010001, 0xa0e40000, /* mov oD1.x, c0 */
22950 0x02000001, 0xe0010000, 0xa0e40000, /* mov oT0.x, c0 */
22951 0x0000ffff
22953 static const DWORD vs3_code[] =
22955 0xfffe0300, /* vs_3_0 */
22956 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
22957 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
22958 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
22959 0x0000ffff
22961 static const DWORD vs3_partial_code[] =
22963 0xfffe0300, /* vs_3_0 */
22964 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
22965 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
22966 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */
22967 0x0200001f, 0x8001000a, 0xe00f0002, /* dcl_color1 o2 */
22968 0x0200001f, 0x80000005, 0xe00f0003, /* dcl_texcoord0 o3 */
22969 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
22970 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
22971 0x02000001, 0xe0010001, 0xa0e40000, /* mov o1.x, c0 */
22972 0x02000001, 0xe0010002, 0xa0e40000, /* mov o2.x, c0 */
22973 0x02000001, 0xe0010003, 0xa0e40000, /* mov o3.x, c0 */
22974 0x0000ffff
22976 static const DWORD ps1_diffuse_code[] =
22978 0xffff0101, /* ps_1_1 */
22979 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
22980 0x0000ffff
22982 static const DWORD ps1_specular_code[] =
22984 0xffff0101, /* ps_1_1 */
22985 0x00000001, 0x800f0000, 0x90e40001, /* mov r0, v1 */
22986 0x0000ffff
22988 static const DWORD ps1_texcoord_code[] =
22990 0xffff0101, /* ps_1_1 */
22991 0x00000040, 0xb00f0000, /* texcoord t0 */
22992 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
22993 0x0000ffff
22995 static const DWORD ps2_diffuse_code[] =
22997 0xffff0200, /* ps_2_0 */
22998 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
22999 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
23000 0x0000ffff
23002 static const DWORD ps2_specular_code[] =
23004 0xffff0200, /* ps_2_0 */
23005 0x0200001f, 0x80000000, 0x900f0001, /* dcl v1 */
23006 0x02000001, 0x800f0800, 0x90e40001, /* mov oC0, v1 */
23007 0x0000ffff
23009 static const DWORD ps2_texcoord_code[] =
23011 0xffff0200, /* ps_2_0 */
23012 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
23013 0x02000001, 0x800f0800, 0xb0e40000, /* mov oC0, t0 */
23014 0x0000ffff
23016 #if 0
23017 /* This has been left here for documentation purposes. It is referenced in disabled tests in the table below. */
23018 static const DWORD ps3_diffuse_code[] =
23020 0xffff0300, /* ps_3_0 */
23021 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
23022 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
23023 0x0000ffff
23025 #endif
23026 static const DWORD ps3_specular_code[] =
23028 0xffff0300, /* ps_3_0 */
23029 0x0200001f, 0x8001000a, 0x900f0001, /* dcl_color1 v1 */
23030 0x02000001, 0x800f0800, 0x90e40001, /* mov oC0, v1 */
23031 0x0000ffff
23033 static const DWORD ps3_texcoord_code[] =
23035 0xffff0300, /* ps_3_0 */
23036 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
23037 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
23038 0x0000ffff
23040 static const struct
23042 DWORD vs_version;
23043 const DWORD *vs;
23044 DWORD ps_version;
23045 const DWORD *ps;
23046 D3DCOLOR expected;
23047 BOOL allow_zero_alpha;
23048 BOOL partial;
23049 BOOL broken_warp;
23051 /* On AMD specular color is generally initialized to 0x00000000 and texcoords to 0xff000000
23052 * while on Nvidia it's the opposite. Just allow both.
23054 * Partially initialized varyings reliably handle the component that has been initialized.
23055 * The uninitialized components generally follow the rule above, with some exceptions on
23056 * radeon cards. r500 and r600 GPUs have been found to set uninitialized components to 0.0,
23057 * 0.5 and 1.0 without a sensible pattern. */
23058 tests[] =
23060 {D3DVS_VERSION(1, 1), vs1_code, 0, NULL, 0xffffffff},
23061 { 0, NULL, D3DPS_VERSION(1, 1), ps1_texcoord_code, 0xff000000, TRUE},
23062 { 0, NULL, D3DPS_VERSION(2, 0), ps2_texcoord_code, 0xff000000, TRUE},
23063 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_diffuse_code, 0xffffffff},
23064 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_specular_code, 0xff000000, TRUE, FALSE, TRUE},
23065 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_texcoord_code, 0xff000000, TRUE},
23066 {D3DVS_VERSION(2, 0), vs2_code, D3DPS_VERSION(2, 0), ps2_diffuse_code, 0xffffffff},
23067 {D3DVS_VERSION(2, 0), vs2_code, D3DPS_VERSION(2, 0), ps2_specular_code, 0xff000000, TRUE, FALSE, TRUE},
23068 {D3DVS_VERSION(2, 0), vs2_code, D3DPS_VERSION(2, 0), ps2_texcoord_code, 0xff000000, TRUE},
23069 /* This test shows a lot of combinations of alpha and color that involve 1.0 and 0.0. Disable it.
23071 * AMD r500 sets alpha = 1.0, color = 0.0. Nvidia sets alpha = 1.0, color = 1.0. r600 Sets Alpha = 0.0,
23072 * color = 0.0. So far no combination with Alpha = 0.0, color = 1.0 has been found though.
23073 * {D3DVS_VERSION(3, 0), vs3_code, D3DPS_VERSION(3, 0), ps3_diffuse_code, 0xffffffff, FALSE, FALSE},
23075 * The same issues apply to the partially initialized COLOR0 varying, in addition to unreliable results
23076 * with partially initialized varyings in general.
23077 * {D3DVS_VERSION(3, 0), vs3_partial_code, D3DPS_VERSION(3, 0), ps3_diffuse_code, 0xff7fffff, TRUE, TRUE}, */
23078 {D3DVS_VERSION(3, 0), vs3_code, D3DPS_VERSION(3, 0), ps3_specular_code, 0xff000000, TRUE, FALSE, TRUE},
23079 {D3DVS_VERSION(3, 0), vs3_code, D3DPS_VERSION(3, 0), ps3_texcoord_code, 0xff000000, TRUE, FALSE, TRUE},
23080 {D3DVS_VERSION(1, 1), vs1_partial_code, 0, NULL, 0xff7fffff, FALSE, TRUE},
23081 {D3DVS_VERSION(1, 1), vs1_partial_code, D3DPS_VERSION(1, 1), ps1_diffuse_code, 0xff7fffff, FALSE, TRUE},
23082 {D3DVS_VERSION(1, 1), vs1_partial_code, D3DPS_VERSION(1, 1), ps1_specular_code, 0xff7f0000, TRUE, TRUE},
23083 {D3DVS_VERSION(1, 1), vs1_partial_code, D3DPS_VERSION(1, 1), ps1_texcoord_code, 0xff7f0000, TRUE, TRUE},
23084 {D3DVS_VERSION(2, 0), vs2_partial_code, D3DPS_VERSION(2, 0), ps2_diffuse_code, 0xff7fffff, FALSE, TRUE},
23085 {D3DVS_VERSION(2, 0), vs2_partial_code, D3DPS_VERSION(2, 0), ps2_specular_code, 0xff7f0000, TRUE, TRUE},
23086 {D3DVS_VERSION(2, 0), vs2_partial_code, D3DPS_VERSION(2, 0), ps2_texcoord_code, 0xff7f0000, TRUE, TRUE},
23087 {D3DVS_VERSION(3, 0), vs3_partial_code, D3DPS_VERSION(3, 0), ps3_specular_code, 0x007f0000, FALSE, TRUE},
23088 {D3DVS_VERSION(3, 0), vs3_partial_code, D3DPS_VERSION(3, 0), ps3_texcoord_code, 0xff7f0000, TRUE, TRUE},
23090 IDirect3DDevice9 *device;
23091 IDirect3D9 *d3d;
23092 HWND window;
23093 HRESULT hr;
23094 D3DADAPTER_IDENTIFIER9 identifier;
23095 IDirect3DSurface9 *backbuffer;
23096 struct surface_readback rb;
23097 IDirect3DVertexShader9 *vs;
23098 IDirect3DPixelShader9 *ps;
23099 unsigned int color, i;
23100 ULONG refcount;
23101 D3DCAPS9 caps;
23102 BOOL warp;
23104 window = create_window();
23105 d3d = Direct3DCreate9(D3D_SDK_VERSION);
23106 ok(!!d3d, "Failed to create a D3D object.\n");
23107 if (!(device = create_device(d3d, window, window, TRUE)))
23109 skip("Failed to create a D3D device, skipping tests.\n");
23110 IDirect3D9_Release(d3d);
23111 DestroyWindow(window);
23112 return;
23115 hr = IDirect3D9_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
23116 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#lx.\n", hr);
23117 warp = adapter_is_warp(&identifier);
23119 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
23120 ok(SUCCEEDED(hr), "Failed to get caps, hr %#lx.\n", hr);
23122 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
23123 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#lx.\n", hr);
23125 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &mat);
23126 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#lx.\n", hr);
23127 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &mat);
23128 ok(SUCCEEDED(hr), "Failed to set view transform, hr %#lx.\n", hr);
23129 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &mat);
23130 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#lx.\n", hr);
23131 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
23132 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#lx.\n", hr);
23133 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
23134 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#lx.\n", hr);
23135 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
23136 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#lx.\n", hr);
23137 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
23138 ok(SUCCEEDED(hr), "Failed to disable stencil test, hr %#lx.\n", hr);
23139 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
23140 ok(SUCCEEDED(hr), "Failed to disable culling, hr %#lx.\n", hr);
23142 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
23143 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
23145 for (i = 0; i < ARRAY_SIZE(tests); ++i)
23147 if (caps.VertexShaderVersion < tests[i].vs_version
23148 || caps.PixelShaderVersion < tests[i].ps_version)
23150 skip("Vertex / pixel shader version not supported, skipping test %u.\n", i);
23151 continue;
23153 if (tests[i].vs)
23155 hr = IDirect3DDevice9_CreateVertexShader(device, tests[i].vs, &vs);
23156 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#lx (case %u).\n", hr, i);
23158 else
23160 vs = NULL;
23162 if (tests[i].ps)
23164 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].ps, &ps);
23165 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#lx (case %u).\n", hr, i);
23167 else
23169 ps = NULL;
23172 hr = IDirect3DDevice9_SetVertexShader(device, vs);
23173 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
23174 hr = IDirect3DDevice9_SetPixelShader(device, ps);
23175 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
23177 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
23178 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
23180 hr = IDirect3DDevice9_BeginScene(device);
23181 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
23183 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
23184 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
23186 hr = IDirect3DDevice9_EndScene(device);
23187 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
23189 get_rt_readback(backbuffer, &rb);
23190 color = get_readback_color(&rb, 320, 240);
23191 ok(color_match(color, tests[i].expected, 1)
23192 || (tests[i].allow_zero_alpha && color_match(color, tests[i].expected & 0x00ffffff, 1))
23193 || (broken(warp && tests[i].broken_warp))
23194 || broken(tests[i].partial && color_match(color & 0x00ff0000, tests[i].expected & 0x00ff0000, 1)),
23195 "Got unexpected color 0x%08x, case %u.\n", color, i);
23196 release_surface_readback(&rb);
23198 if (vs)
23199 IDirect3DVertexShader9_Release(vs);
23200 if (ps)
23201 IDirect3DVertexShader9_Release(ps);
23204 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
23205 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
23207 IDirect3DSurface9_Release(backbuffer);
23208 refcount = IDirect3DDevice9_Release(device);
23209 ok(!refcount, "Device has %lu references left.\n", refcount);
23210 IDirect3D9_Release(d3d);
23211 DestroyWindow(window);
23214 static void test_multisample_init(void)
23216 IDirect3DDevice9 *device;
23217 unsigned int color, x, y;
23218 IDirect3D9 *d3d;
23219 IDirect3DSurface9 *back, *multi;
23220 ULONG refcount;
23221 HWND window;
23222 HRESULT hr;
23223 struct surface_readback rb;
23224 BOOL all_zero = TRUE;
23226 window = create_window();
23227 d3d = Direct3DCreate9(D3D_SDK_VERSION);
23228 ok(!!d3d, "Failed to create a D3D object.\n");
23230 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
23231 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
23233 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisample init test.\n");
23234 goto done;
23237 if (!(device = create_device(d3d, window, window, TRUE)))
23239 skip("Failed to create a D3D device, skipping tests.\n");
23240 goto done;
23243 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &back);
23244 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#lx.\n", hr);
23245 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
23246 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &multi, NULL);
23247 ok(SUCCEEDED(hr), "Failed to create multisampled render target, hr %#lx.\n", hr);
23249 hr = IDirect3DDevice9_StretchRect(device, multi, NULL, back, NULL, D3DTEXF_POINT);
23250 ok(SUCCEEDED(hr), "StretchRect failed, hr %#lx.\n", hr);
23252 get_rt_readback(back, &rb);
23253 for (y = 0; y < 480; ++y)
23255 for (x = 0; x < 640; x++)
23257 color = get_readback_color(&rb, x, y);
23258 if (!color_match(color, 0x00000000, 0))
23260 all_zero = FALSE;
23261 break;
23264 if (!all_zero)
23265 break;
23267 release_surface_readback(&rb);
23268 ok(all_zero, "Got unexpected color 0x%08x, position %ux%u.\n", color, x, y);
23270 IDirect3DSurface9_Release(multi);
23271 IDirect3DSurface9_Release(back);
23273 refcount = IDirect3DDevice9_Release(device);
23274 ok(!refcount, "Device has %lu references left.\n", refcount);
23276 done:
23277 IDirect3D9_Release(d3d);
23278 DestroyWindow(window);
23281 static void test_depth_stencil_init(void)
23283 IDirect3DDevice9 *device;
23284 IDirect3DSurface9 *ds[2];
23285 IDirect3DSurface9 *rt;
23286 IDirect3D9 *d3d;
23287 ULONG refcount;
23288 unsigned int i;
23289 HWND window;
23290 HRESULT hr;
23292 static const struct
23294 struct vec3 position;
23296 quad[] =
23298 {{-1.0f, -1.0f, 0.0f}},
23299 {{-1.0f, 1.0f, 0.0f}},
23300 {{ 1.0f, -1.0f, 0.0f}},
23301 {{ 1.0f, 1.0f, 0.0f}},
23304 window = create_window();
23305 d3d = Direct3DCreate9(D3D_SDK_VERSION);
23306 ok(!!d3d, "Failed to create D3D object.\n");
23307 if (!(device = create_device(d3d, window, window, TRUE)))
23309 skip("Failed to create D3D device.\n");
23310 goto done;
23313 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
23314 ok(hr == S_OK, "Failed to set render state, hr %#lx.\n", hr);
23315 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
23316 ok(hr == S_OK, "Failed to set render state, hr %#lx.\n", hr);
23317 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
23318 ok(hr == S_OK, "Failed to set render state, hr %#lx.\n", hr);
23319 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
23320 ok(hr == S_OK, "Failed to set color op, hr %#lx.\n", hr);
23321 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
23322 ok(hr == S_OK, "Failed to set color arg, hr %#lx.\n", hr);
23323 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
23324 ok(hr == S_OK, "Failed to set FVF, hr %#lx.\n", hr);
23326 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8, 0, 0, FALSE, &ds[0], NULL);
23327 ok(hr == S_OK, "Failed to create depth stencil surface, hr %#lx.\n", hr);
23328 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds[1]);
23329 ok(hr == S_OK, "Failed to get depth stencil surface, hr %#lx.\n", hr);
23331 for (i = 0; i < ARRAY_SIZE(ds); ++i)
23333 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds[i]);
23334 ok(hr == S_OK, "Failed to set depth stencil surface, hr %#lx.\n", hr);
23336 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
23337 ok(hr == S_OK, "Failed to clear, hr %#lx.\n", hr);
23339 hr = IDirect3DDevice9_BeginScene(device);
23340 ok(hr == S_OK, "Failed to begin scene, hr %#lx.\n", hr);
23341 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x000000ff);
23342 ok(hr == S_OK, "Failed to set render state, hr %#lx.\n", hr);
23343 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
23344 ok(hr == S_OK, "Failed to draw, hr %#lx.\n", hr);
23345 hr = IDirect3DDevice9_EndScene(device);
23346 ok(hr == S_OK, "Failed to end scene, hr %#lx.\n", hr);
23348 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &rt);
23349 ok(hr == S_OK, "Failed to get render target, hr %#lx.\n", hr);
23350 check_rt_color(rt, 0x000000ff);
23351 IDirect3DSurface9_Release(rt);
23353 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
23354 ok(hr == D3D_OK, "Failed to present, hr %#lx.\n", hr);
23356 IDirect3DSurface9_Release(ds[i]);
23359 refcount = IDirect3DDevice9_Release(device);
23360 ok(!refcount, "Device has %lu references left.\n", refcount);
23362 done:
23363 IDirect3D9_Release(d3d);
23364 DestroyWindow(window);
23367 static void test_texture_blending(void)
23369 #define STATE_END() {0xffffffff, 0xffffffff}
23370 #define IS_STATE_END(s) (s.name == 0xffffffff && s.value == 0xffffffff)
23372 IDirect3DTexture9 *texture_bumpmap, *texture_red;
23373 IDirect3DSurface9 *backbuffer;
23374 unsigned int color, i, j, k;
23375 struct surface_readback rb;
23376 D3DLOCKED_RECT locked_rect;
23377 IDirect3DDevice9 *device;
23378 IDirect3D9 *d3d;
23379 ULONG refcount;
23380 D3DCAPS9 caps;
23381 HWND window;
23382 HRESULT hr;
23384 static const struct
23386 struct vec3 position;
23387 DWORD diffuse;
23389 quad[] =
23391 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
23392 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
23393 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
23394 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
23397 static const float bumpenvmat[4] = {1.0f, 1.0f, 0.0f, 0.0f};
23399 struct texture_stage_state
23401 D3DTEXTURESTAGESTATETYPE name;
23402 DWORD value;
23405 enum texture_stage_texture
23407 TEXTURE_INVALID,
23408 TEXTURE_NONE,
23409 TEXTURE_BUMPMAP,
23410 TEXTURE_RED,
23413 struct texture_stage
23415 enum texture_stage_texture texture;
23416 struct texture_stage_state state[20];
23419 static const struct texture_stage default_stage_state =
23421 TEXTURE_NONE,
23423 {D3DTSS_COLOROP, D3DTOP_DISABLE},
23424 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
23425 {D3DTSS_COLORARG2, D3DTA_CURRENT},
23426 {D3DTSS_ALPHAOP, D3DTOP_DISABLE},
23427 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
23428 {D3DTSS_ALPHAARG2, D3DTA_CURRENT},
23429 {D3DTSS_BUMPENVMAT00, 0},
23430 {D3DTSS_BUMPENVMAT01, 0},
23431 {D3DTSS_BUMPENVMAT10, 0},
23432 {D3DTSS_BUMPENVMAT11, 0},
23433 {D3DTSS_BUMPENVLSCALE, 0},
23434 {D3DTSS_BUMPENVLOFFSET, 0},
23435 {D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE},
23436 {D3DTSS_COLORARG0, D3DTA_CURRENT},
23437 {D3DTSS_ALPHAARG0, D3DTA_CURRENT},
23438 {D3DTSS_RESULTARG, D3DTA_CURRENT},
23439 {D3DTSS_CONSTANT, 0},
23440 STATE_END(),
23444 const struct test
23446 DWORD tex_op_caps;
23447 unsigned int expected_color;
23448 struct texture_stage stage[8];
23450 tests[] =
23453 D3DTEXOPCAPS_DISABLE,
23454 0x80ffff02,
23457 TEXTURE_NONE,
23459 STATE_END(),
23465 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
23466 0x80ffff02,
23469 TEXTURE_NONE,
23471 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
23472 {D3DTSS_COLORARG1, D3DTA_CURRENT},
23473 STATE_END(),
23476 {TEXTURE_INVALID}
23480 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
23481 0x80ffff02,
23484 TEXTURE_NONE,
23486 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
23487 {D3DTSS_COLORARG1, D3DTA_CURRENT},
23488 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
23489 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
23490 STATE_END(),
23496 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
23497 0x80ffff02,
23500 TEXTURE_NONE,
23502 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
23503 {D3DTSS_COLORARG1, D3DTA_DIFFUSE},
23504 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
23505 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
23506 STATE_END(),
23512 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
23513 0x00000000,
23516 TEXTURE_NONE,
23518 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
23519 {D3DTSS_COLORARG1, D3DTA_TEMP},
23520 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
23521 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
23522 STATE_END(),
23528 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_SUBTRACT,
23529 0x80f0f000,
23532 TEXTURE_NONE,
23534 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
23535 {D3DTSS_COLORARG1, D3DTA_CURRENT},
23536 STATE_END(),
23540 TEXTURE_NONE,
23542 {D3DTSS_COLOROP, D3DTOP_SUBTRACT},
23543 {D3DTSS_COLORARG1, D3DTA_CURRENT},
23544 {D3DTSS_COLORARG2, D3DTA_CONSTANT},
23545 {D3DTSS_CONSTANT, 0x0f0f0f0f},
23546 STATE_END(),
23549 {TEXTURE_INVALID}
23553 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_SUBTRACT,
23554 0x71f0f000,
23557 TEXTURE_NONE,
23559 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
23560 {D3DTSS_COLORARG1, D3DTA_CURRENT},
23561 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
23562 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
23563 STATE_END(),
23567 TEXTURE_NONE,
23569 {D3DTSS_COLOROP, D3DTOP_SUBTRACT},
23570 {D3DTSS_COLORARG1, D3DTA_CURRENT},
23571 {D3DTSS_COLORARG2, D3DTA_CONSTANT},
23572 {D3DTSS_ALPHAOP, D3DTOP_SUBTRACT},
23573 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
23574 {D3DTSS_ALPHAARG2, D3DTA_CONSTANT},
23575 {D3DTSS_CONSTANT, 0x0f0f0f0f},
23576 STATE_END(),
23579 {TEXTURE_INVALID}
23584 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
23585 0x80ff0000,
23588 TEXTURE_BUMPMAP,
23590 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
23591 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
23592 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
23593 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
23594 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
23595 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
23596 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
23597 STATE_END(),
23602 TEXTURE_RED,
23604 {D3DTSS_COLOROP, D3DTOP_MODULATE},
23605 STATE_END(),
23608 {TEXTURE_INVALID}
23612 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
23613 0x80ff0000,
23616 TEXTURE_BUMPMAP,
23618 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
23619 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
23620 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
23621 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
23622 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
23623 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
23624 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
23625 STATE_END(),
23629 TEXTURE_RED,
23631 {D3DTSS_COLOROP, D3DTOP_MODULATE},
23632 STATE_END(),
23635 {TEXTURE_INVALID}
23639 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
23640 0x80ff0000,
23643 TEXTURE_BUMPMAP,
23645 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
23646 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
23647 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
23648 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
23649 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
23650 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
23651 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
23652 STATE_END(),
23656 TEXTURE_RED,
23658 {D3DTSS_COLOROP, D3DTOP_MODULATE},
23659 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
23660 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
23661 STATE_END(),
23664 {TEXTURE_INVALID}
23668 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
23669 0x00ff0000,
23672 TEXTURE_BUMPMAP,
23674 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
23675 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
23676 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
23677 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
23678 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
23679 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
23680 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
23681 STATE_END(),
23685 TEXTURE_RED,
23687 {D3DTSS_COLOROP, D3DTOP_MODULATE},
23688 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
23689 {D3DTSS_COLORARG2, D3DTA_CURRENT},
23690 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
23691 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
23692 STATE_END(),
23695 {TEXTURE_INVALID}
23699 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
23700 0x80ff0000,
23703 TEXTURE_BUMPMAP,
23705 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
23706 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
23707 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
23708 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
23709 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
23710 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
23711 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
23712 STATE_END(),
23716 TEXTURE_RED,
23718 {D3DTSS_COLOROP, D3DTOP_MODULATE},
23719 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
23720 {D3DTSS_COLORARG2, D3DTA_CURRENT},
23721 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
23722 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
23723 STATE_END(),
23726 {TEXTURE_INVALID}
23731 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE
23732 | D3DTEXOPCAPS_ADD,
23733 0x80ff0000,
23736 TEXTURE_BUMPMAP,
23738 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
23739 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
23740 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
23741 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
23742 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
23743 {D3DTSS_ALPHAOP, D3DTOP_ADD},
23744 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
23745 {D3DTSS_ALPHAARG2, D3DTA_CONSTANT},
23746 {D3DTSS_CONSTANT, 0x0fffffff},
23747 STATE_END(),
23751 TEXTURE_RED,
23753 {D3DTSS_COLOROP, D3DTOP_MODULATE},
23754 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
23755 {D3DTSS_COLORARG2, D3DTA_CURRENT},
23756 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
23757 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
23758 STATE_END(),
23761 {TEXTURE_INVALID}
23765 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE
23766 | D3DTEXOPCAPS_MODULATE2X,
23767 0x80ff0000,
23770 TEXTURE_BUMPMAP,
23772 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
23773 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
23774 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
23775 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
23776 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
23777 {D3DTSS_ALPHAOP, D3DTOP_MODULATE2X},
23778 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
23779 {D3DTSS_ALPHAARG2, D3DTA_CONSTANT},
23780 {D3DTSS_CONSTANT, 0x01ffffff},
23781 STATE_END(),
23785 TEXTURE_RED,
23787 {D3DTSS_COLOROP, D3DTOP_MODULATE},
23788 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
23789 {D3DTSS_COLORARG2, D3DTA_CURRENT},
23790 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
23791 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
23792 STATE_END(),
23795 {TEXTURE_INVALID}
23799 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE
23800 | D3DTEXOPCAPS_MODULATE2X,
23801 0x80ffff00,
23804 TEXTURE_BUMPMAP,
23806 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
23807 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
23808 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
23809 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
23810 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
23811 {D3DTSS_ALPHAOP, D3DTOP_MODULATE2X},
23812 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
23813 {D3DTSS_ALPHAARG2, D3DTA_CONSTANT},
23814 {D3DTSS_CONSTANT, 0x01ffffff},
23815 STATE_END(),
23819 TEXTURE_RED,
23821 {D3DTSS_COLOROP, D3DTOP_MODULATE},
23822 {D3DTSS_COLORARG1, D3DTA_CURRENT},
23823 {D3DTSS_COLORARG2, D3DTA_CURRENT},
23824 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
23825 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
23826 {D3DTSS_ALPHAARG2, D3DTA_CONSTANT},
23827 {D3DTSS_ALPHAARG0, D3DTA_CONSTANT},
23828 STATE_END(),
23831 {TEXTURE_INVALID}
23835 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP,
23836 0x01234567,
23839 TEXTURE_NONE,
23841 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
23842 {D3DTSS_COLORARG1, D3DTA_CONSTANT},
23843 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
23844 {D3DTSS_ALPHAARG1, D3DTA_CONSTANT},
23845 {D3DTSS_RESULTARG, D3DTA_TEMP},
23846 {D3DTSS_CONSTANT, 0x01234567},
23847 STATE_END(),
23851 TEXTURE_BUMPMAP,
23853 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
23854 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
23855 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
23856 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
23857 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
23858 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
23859 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
23860 {D3DTSS_RESULTARG, D3DTA_TEMP},
23861 STATE_END(),
23865 TEXTURE_RED,
23867 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
23868 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
23869 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
23870 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
23871 STATE_END(),
23875 TEXTURE_NONE,
23877 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
23878 {D3DTSS_COLORARG1, D3DTA_TEMP},
23879 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
23880 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
23881 STATE_END(),
23884 {TEXTURE_INVALID}
23888 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP,
23889 0x00234567,
23892 TEXTURE_NONE,
23894 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
23895 {D3DTSS_COLORARG1, D3DTA_CONSTANT},
23896 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
23897 {D3DTSS_ALPHAARG1, D3DTA_CONSTANT},
23898 {D3DTSS_RESULTARG, D3DTA_TEMP},
23899 {D3DTSS_CONSTANT, 0x01234567},
23900 STATE_END(),
23904 TEXTURE_BUMPMAP,
23906 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
23907 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
23908 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
23909 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
23910 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
23911 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
23912 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
23913 STATE_END(),
23917 TEXTURE_RED,
23919 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
23920 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
23921 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
23922 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
23923 STATE_END(),
23927 TEXTURE_NONE,
23929 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
23930 {D3DTSS_COLORARG1, D3DTA_TEMP},
23931 STATE_END(),
23934 {TEXTURE_INVALID}
23938 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP,
23939 0x01234567,
23942 TEXTURE_NONE,
23944 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
23945 {D3DTSS_COLORARG1, D3DTA_CONSTANT},
23946 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
23947 {D3DTSS_ALPHAARG1, D3DTA_CONSTANT},
23948 {D3DTSS_RESULTARG, D3DTA_TEMP},
23949 {D3DTSS_CONSTANT, 0x01234567},
23950 STATE_END(),
23954 TEXTURE_BUMPMAP,
23956 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
23957 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
23958 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
23959 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
23960 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
23961 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
23962 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
23963 {D3DTSS_RESULTARG, D3DTA_TEMP},
23964 STATE_END(),
23968 TEXTURE_RED,
23970 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
23971 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
23972 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
23973 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
23974 STATE_END(),
23978 TEXTURE_NONE,
23980 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
23981 {D3DTSS_COLORARG1, D3DTA_TEMP},
23982 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
23983 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
23984 STATE_END(),
23987 {TEXTURE_INVALID}
23991 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP,
23992 0x01234567,
23995 TEXTURE_NONE,
23997 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
23998 {D3DTSS_COLORARG1, D3DTA_CONSTANT},
23999 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
24000 {D3DTSS_ALPHAARG1, D3DTA_CONSTANT},
24001 {D3DTSS_RESULTARG, D3DTA_CURRENT},
24002 {D3DTSS_CONSTANT, 0x01234567},
24003 STATE_END(),
24007 TEXTURE_BUMPMAP,
24009 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
24010 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
24011 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
24012 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
24013 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
24014 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
24015 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
24016 {D3DTSS_RESULTARG, D3DTA_TEMP},
24017 STATE_END(),
24021 TEXTURE_RED,
24023 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
24024 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
24025 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
24026 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
24027 {D3DTSS_RESULTARG, D3DTA_TEMP},
24028 STATE_END(),
24032 TEXTURE_NONE,
24034 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
24035 {D3DTSS_COLORARG1, D3DTA_CURRENT},
24036 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
24037 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
24038 {D3DTSS_RESULTARG, D3DTA_CURRENT},
24039 STATE_END(),
24042 {TEXTURE_INVALID}
24047 window = create_window();
24048 d3d = Direct3DCreate9(D3D_SDK_VERSION);
24049 ok(!!d3d, "Failed to create a D3D object.\n");
24050 if (!(device = create_device(d3d, window, window, TRUE)))
24052 skip("Failed to create a D3D device.\n");
24053 goto done;
24056 memset(&caps, 0, sizeof(caps));
24057 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
24058 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr %#lx.\n", hr);
24060 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP))
24062 skip("D3DPMISCCAPS_TSSARGTEMP not supported.\n");
24063 IDirect3DDevice9_Release(device);
24064 goto done;
24067 if (!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_PERSTAGECONSTANT))
24069 skip("D3DPMISCCAPS_PERSTAGECONSTANT not supported.\n");
24070 IDirect3DDevice9_Release(device);
24071 goto done;
24074 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
24075 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_V8U8)))
24077 skip("D3DFMT_V8U8 not supported for legacy bump mapping.\n");
24078 IDirect3DDevice9_Release(device);
24079 goto done;
24082 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
24083 ok(hr == D3D_OK, "Can't get back buffer, hr %#lx.\n", hr);
24085 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture_bumpmap, NULL);
24086 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr %#lx.\n", hr);
24087 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture_red, NULL);
24088 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr %#lx.\n", hr);
24090 memset(&locked_rect, 0, sizeof(locked_rect));
24091 hr = IDirect3DTexture9_LockRect(texture_bumpmap, 0, &locked_rect, NULL, 0);
24092 ok(SUCCEEDED(hr), "LockRect failed, hr %#lx.\n", hr);
24093 *((WORD *)locked_rect.pBits) = 0xff00;
24094 hr = IDirect3DTexture9_UnlockRect(texture_bumpmap, 0);
24095 ok(SUCCEEDED(hr), "UnlockRect failed, hr %#lx.\n", hr);
24097 memset(&locked_rect, 0, sizeof(locked_rect));
24098 hr = IDirect3DTexture9_LockRect(texture_red, 0, &locked_rect, NULL, 0);
24099 ok(SUCCEEDED(hr), "LockRect failed, hr %#lx.\n", hr);
24100 *((DWORD *)locked_rect.pBits) = 0x00ff0000;
24101 hr = IDirect3DTexture9_UnlockRect(texture_red, 0);
24102 ok(SUCCEEDED(hr), "UnlockRect failed, hr %#lx.\n", hr);
24104 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
24105 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
24106 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
24107 ok(hr == D3D_OK, "Failed to disable lighting, hr %#lx.\n", hr);
24109 for (i = 0; i < ARRAY_SIZE(tests); ++i)
24111 const struct test *current_test = &tests[i];
24113 if ((caps.TextureOpCaps & current_test->tex_op_caps) != current_test->tex_op_caps)
24115 skip("Texture operations %#lx not supported.\n", current_test->tex_op_caps);
24116 continue;
24119 for (j = 0; j < caps.MaxTextureBlendStages; ++j)
24121 IDirect3DTexture9 *current_texture = NULL;
24123 for (k = 0; !IS_STATE_END(default_stage_state.state[k]); ++k)
24125 hr = IDirect3DDevice9_SetTextureStageState(device, j,
24126 default_stage_state.state[k].name, default_stage_state.state[k].value);
24127 ok(SUCCEEDED(hr), "Test %u: SetTextureStageState failed, hr %#lx.\n", i, hr);
24130 if (current_test->stage[j].texture != TEXTURE_INVALID)
24132 const struct texture_stage_state *current_state = current_test->stage[j].state;
24134 switch (current_test->stage[j].texture)
24136 case TEXTURE_RED:
24137 current_texture = texture_red;
24138 break;
24139 case TEXTURE_BUMPMAP:
24140 current_texture = texture_bumpmap;
24141 break;
24142 default:
24143 current_texture = NULL;
24144 break;
24147 for (k = 0; !IS_STATE_END(current_state[k]); ++k)
24149 hr = IDirect3DDevice9_SetTextureStageState(device, j,
24150 current_state[k].name, current_state[k].value);
24151 ok(SUCCEEDED(hr), "Test %u: SetTextureStageState failed, hr %#lx.\n", i, hr);
24155 hr = IDirect3DDevice9_SetTexture(device, j, (IDirect3DBaseTexture9 *)current_texture);
24156 ok(SUCCEEDED(hr), "Test %u: SetTexture failed, hr %#lx.\n", i, hr);
24159 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
24160 ok(hr == D3D_OK, "Test %u: IDirect3DDevice9_Clear failed, hr %#lx.\n", i, hr);
24162 hr = IDirect3DDevice9_BeginScene(device);
24163 ok(SUCCEEDED(hr), "Test %u: BeginScene failed, hr %#lx.\n", i, hr);
24164 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
24165 ok(SUCCEEDED(hr), "Test %u: DrawPrimitiveUP failed, hr %#lx.\n", i, hr);
24166 hr = IDirect3DDevice9_EndScene(device);
24167 ok(SUCCEEDED(hr), "Test %u: EndScene failed, hr %#lx.\n", i, hr);
24169 get_rt_readback(backbuffer, &rb);
24170 color = get_readback_color(&rb, 320, 240);
24171 ok(color_match(color, current_test->expected_color, 1),
24172 "Test %u: Got color 0x%08x, expected 0x%08x.\n", i, color, current_test->expected_color);
24173 release_surface_readback(&rb);
24174 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
24175 ok(SUCCEEDED(hr), "Test %u: Present failed, hr %#lx.\n", i, hr);
24178 IDirect3DTexture9_Release(texture_bumpmap);
24179 IDirect3DTexture9_Release(texture_red);
24180 IDirect3DSurface9_Release(backbuffer);
24181 refcount = IDirect3DDevice9_Release(device);
24182 ok(!refcount, "Device has %lu references left.\n", refcount);
24183 done:
24184 IDirect3D9_Release(d3d);
24185 DestroyWindow(window);
24188 static void test_color_clamping(void)
24190 static const D3DMATRIX mat =
24192 1.0f, 0.0f, 0.0f, 0.0f,
24193 0.0f, 1.0f, 0.0f, 0.0f,
24194 0.0f, 0.0f, 1.0f, 0.0f,
24195 0.0f, 0.0f, 0.0f, 1.0f,
24196 }}};
24197 static const struct vec3 quad[] =
24199 {-1.0f, -1.0f, 0.1f},
24200 {-1.0f, 1.0f, 0.1f},
24201 { 1.0f, -1.0f, 0.1f},
24202 { 1.0f, 1.0f, 0.1f},
24204 static const DWORD vs1_code[] =
24206 0xfffe0101, /* vs_1_1 */
24207 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
24208 0x00000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0 */
24209 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
24210 0x00000002, 0xd00f0000, 0xa0e40000, 0xa0e40000, /* add oD0, c0, c0 */
24211 0x00000002, 0xd00f0001, 0xa0e40000, 0xa0e40000, /* add oD1, c0, c0 */
24212 0x0000ffff
24214 static const DWORD vs2_code[] =
24216 0xfffe0200, /* vs_2_0 */
24217 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
24218 0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0 */
24219 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
24220 0x03000002, 0xd00f0000, 0xa0e40000, 0xa0e40000, /* add oD0, c0, c0 */
24221 0x03000002, 0xd00f0001, 0xa0e40000, 0xa0e40000, /* add oD1, c0, c0 */
24222 0x0000ffff
24224 static const DWORD vs3_code[] =
24226 0xfffe0300, /* vs_3_0 */
24227 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
24228 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
24229 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */
24230 0x0200001f, 0x8001000a, 0xe00f0002, /* dcl_color1 o2 */
24231 0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0 */
24232 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
24233 0x03000002, 0xe00f0001, 0xa0e40000, 0xa0e40000, /* add o1, c0, c0 */
24234 0x03000002, 0xe00f0002, 0xa0e40000, 0xa0e40000, /* add o2, c0, c0 */
24235 0x0000ffff
24237 static const DWORD ps1_code[] =
24239 0xffff0101, /* ps_1_1 */
24240 0x00000051, 0xa00f0000, 0x3e800000, 0x3e800000, 0x3e800000, 0x3e800000, /* def c0, 0.25, 0.25, 0.25, 0.25 */
24241 0x00000002, 0x800f0000, 0x90e40000, 0x90e40001, /* add r0, v0, v1 */
24242 0x00000005, 0x800f0000, 0x80e40000, 0xa0e40000, /* mul r0, r0, c0 */
24243 0x0000ffff
24245 static const DWORD ps2_code[] =
24247 0xffff0200, /* ps_2_0 */
24248 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
24249 0x0200001f, 0x80000000, 0x900f0001, /* dcl v1 */
24250 0x05000051, 0xa00f0000, 0x3e800000, 0x3e800000, 0x3e800000, 0x3e800000, /* def c0, 0.25, 0.25, 0.25, 0.25 */
24251 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
24252 0x03000002, 0x800f0000, 0x80e40000, 0x90e40001, /* add r0, r0, v1 */
24253 0x03000005, 0x800f0000, 0x80e40000, 0xa0e40000, /* mul r0, r0, c0 */
24254 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
24255 0x0000ffff
24257 static const DWORD ps3_code[] =
24259 0xffff0300, /* ps_3_0 */
24260 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
24261 0x0200001f, 0x8001000a, 0x900f0001, /* dcl_color1 v1 */
24262 0x05000051, 0xa00f0000, 0x3e800000, 0x3e800000, 0x3e800000, 0x3e800000, /* def c0, 0.25, 0.25, 0.25, 0.25 */
24263 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
24264 0x03000002, 0x800f0000, 0x80e40000, 0x90e40001, /* add r0, r0, v1 */
24265 0x03000005, 0x800f0800, 0x80e40000, 0xa0e40000, /* mul oC0, r0, c0 */
24266 0x0000ffff
24268 static const struct
24270 DWORD vs_version;
24271 const DWORD *vs;
24272 DWORD ps_version;
24273 const DWORD *ps;
24274 D3DCOLOR expected, broken;
24276 tests[] =
24278 {0, NULL, 0, NULL, 0x00404040},
24279 {0, NULL, D3DPS_VERSION(1, 1), ps1_code, 0x00404040, 0x00808080},
24280 {D3DVS_VERSION(1, 1), vs1_code, 0, NULL, 0x00404040},
24281 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_code, 0x007f7f7f},
24282 {D3DVS_VERSION(2, 0), vs2_code, D3DPS_VERSION(2, 0), ps2_code, 0x007f7f7f},
24283 {D3DVS_VERSION(3, 0), vs3_code, D3DPS_VERSION(3, 0), ps3_code, 0x00ffffff},
24285 IDirect3DVertexShader9 *vs;
24286 IDirect3DPixelShader9 *ps;
24287 IDirect3DDevice9 *device;
24288 unsigned int color, i;
24289 IDirect3D9 *d3d9;
24290 ULONG refcount;
24291 D3DCAPS9 caps;
24292 HWND window;
24293 HRESULT hr;
24295 window = create_window();
24296 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
24297 ok(!!d3d9, "Failed to create a D3D object.\n");
24298 if (!(device = create_device(d3d9, window, window, TRUE)))
24300 skip("Failed to create a D3D device, skipping tests.\n");
24301 IDirect3D9_Release(d3d9);
24302 DestroyWindow(window);
24303 return;
24306 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
24307 ok(SUCCEEDED(hr), "Failed to get caps, hr %#lx.\n", hr);
24309 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &mat);
24310 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#lx.\n", hr);
24311 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &mat);
24312 ok(SUCCEEDED(hr), "Failed to set view transform, hr %#lx.\n", hr);
24313 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &mat);
24314 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#lx.\n", hr);
24315 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
24316 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#lx.\n", hr);
24317 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
24318 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#lx.\n", hr);
24319 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
24320 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#lx.\n", hr);
24321 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
24322 ok(SUCCEEDED(hr), "Failed to disable stencil test, hr %#lx.\n", hr);
24323 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
24324 ok(SUCCEEDED(hr), "Failed to disable culling, hr %#lx.\n", hr);
24325 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
24326 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
24328 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xff404040);
24329 ok(SUCCEEDED(hr), "Failed to set texture factor, hr %#lx.\n", hr);
24330 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
24331 ok(SUCCEEDED(hr), "Failed to set color op, hr %#lx.\n", hr);
24332 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
24333 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#lx.\n", hr);
24334 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_SPECULAR);
24335 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#lx.\n", hr);
24336 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_MODULATE);
24337 ok(SUCCEEDED(hr), "Failed to set color op, hr %#lx.\n", hr);
24338 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
24339 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#lx.\n", hr);
24340 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
24341 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#lx.\n", hr);
24343 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
24344 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
24346 for (i = 0; i < ARRAY_SIZE(tests); ++i)
24348 if (caps.VertexShaderVersion < tests[i].vs_version
24349 || caps.PixelShaderVersion < tests[i].ps_version)
24351 skip("Vertex / pixel shader version not supported, skipping test %u.\n", i);
24352 continue;
24354 if (tests[i].vs)
24356 hr = IDirect3DDevice9_CreateVertexShader(device, tests[i].vs, &vs);
24357 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#lx (case %u).\n", hr, i);
24359 else
24361 vs = NULL;
24363 if (tests[i].ps)
24365 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].ps, &ps);
24366 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#lx (case %u).\n", hr, i);
24368 else
24370 ps = NULL;
24373 hr = IDirect3DDevice9_SetVertexShader(device, vs);
24374 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
24375 hr = IDirect3DDevice9_SetPixelShader(device, ps);
24376 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
24378 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
24379 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
24381 hr = IDirect3DDevice9_BeginScene(device);
24382 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
24384 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
24385 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
24387 hr = IDirect3DDevice9_EndScene(device);
24388 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
24390 color = getPixelColor(device, 320, 240);
24391 ok(color_match(color, tests[i].expected, 1) || broken(color_match(color, tests[i].broken, 1)),
24392 "Got unexpected color 0x%08x, case %u.\n", color, i);
24394 if (vs)
24395 IDirect3DVertexShader9_Release(vs);
24396 if (ps)
24397 IDirect3DVertexShader9_Release(ps);
24400 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
24401 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
24403 refcount = IDirect3DDevice9_Release(device);
24404 ok(!refcount, "Device has %lu references left.\n", refcount);
24405 IDirect3D9_Release(d3d9);
24406 DestroyWindow(window);
24409 static void test_line_antialiasing_blending(void)
24411 IDirect3DDevice9 *device;
24412 unsigned int color;
24413 IDirect3D9 *d3d9;
24414 ULONG refcount;
24415 D3DCAPS9 caps;
24416 HWND window;
24417 HRESULT hr;
24419 static const struct
24421 struct vec3 position;
24422 DWORD diffuse;
24424 green_quad[] =
24426 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
24427 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
24428 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
24429 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
24431 static const struct
24433 struct vec3 position;
24434 DWORD diffuse;
24436 red_quad[] =
24438 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
24439 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
24440 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
24441 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
24444 window = create_window();
24445 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
24446 ok(!!d3d9, "Failed to create a D3D object.\n");
24447 if (!(device = create_device(d3d9, window, window, TRUE)))
24449 skip("Failed to create a D3D device.\n");
24450 IDirect3D9_Release(d3d9);
24451 DestroyWindow(window);
24452 return;
24455 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
24456 ok(SUCCEEDED(hr), "Failed to get caps, hr %#lx.\n", hr);
24457 trace("Line antialiasing support: %#lx.\n", caps.LineCaps & D3DLINECAPS_ANTIALIAS);
24459 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
24460 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#lx.\n", hr);
24461 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
24462 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#lx.\n", hr);
24463 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
24464 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
24466 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
24467 ok(SUCCEEDED(hr), "Failed to enable blending, hr %#lx.\n", hr);
24468 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_BLENDOP, D3DBLENDOP_ADD);
24469 ok(SUCCEEDED(hr), "Failed to set blend op, hr %#lx.\n", hr);
24470 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
24471 ok(SUCCEEDED(hr), "Failed to set src blend, hr %#lx.\n", hr);
24472 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_DESTALPHA);
24473 ok(SUCCEEDED(hr), "Failed to set dest blend, hr %#lx.\n", hr);
24475 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
24476 ok(SUCCEEDED(hr), "Failed to set color op, hr %#lx.\n", hr);
24477 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
24478 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#lx.\n", hr);
24479 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
24480 ok(SUCCEEDED(hr), "Failed to set alpha op, hr %#lx.\n", hr);
24481 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
24482 ok(SUCCEEDED(hr), "Failed to set alpha arg, hr %#lx.\n", hr);
24484 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
24485 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
24487 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xccff0000, 0.0f, 0);
24488 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
24489 hr = IDirect3DDevice9_BeginScene(device);
24490 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
24491 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, green_quad, sizeof(*green_quad));
24492 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
24493 hr = IDirect3DDevice9_EndScene(device);
24494 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
24495 color = getPixelColor(device, 320, 240);
24496 ok(color_match(color, 0x00cc7f00, 1), "Got unexpected color 0x%08x.\n", color);
24498 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f00ff00, 0.0f, 0);
24499 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
24500 hr = IDirect3DDevice9_BeginScene(device);
24501 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
24502 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, red_quad, sizeof(*red_quad));
24503 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
24504 hr = IDirect3DDevice9_EndScene(device);
24505 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
24506 color = getPixelColor(device, 320, 240);
24507 ok(color_match(color, 0x00cc7f00, 1), "Got unexpected color 0x%08x.\n", color);
24509 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
24510 ok(SUCCEEDED(hr), "Failed to disable blending, hr %#lx.\n", hr);
24512 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xccff0000, 0.0f, 0);
24513 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
24514 hr = IDirect3DDevice9_BeginScene(device);
24515 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
24516 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, green_quad, sizeof(*green_quad));
24517 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
24518 hr = IDirect3DDevice9_EndScene(device);
24519 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
24520 color = getPixelColor(device, 320, 240);
24521 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
24523 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f00ff00, 0.0f, 0);
24524 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
24525 hr = IDirect3DDevice9_BeginScene(device);
24526 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
24527 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, red_quad, sizeof(*red_quad));
24528 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
24529 hr = IDirect3DDevice9_EndScene(device);
24530 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
24531 color = getPixelColor(device, 320, 240);
24532 ok(color_match(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
24534 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ANTIALIASEDLINEENABLE, TRUE);
24535 ok(SUCCEEDED(hr), "Failed to enable line antialiasing, hr %#lx.\n", hr);
24537 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xccff0000, 0.0f, 0);
24538 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
24539 hr = IDirect3DDevice9_BeginScene(device);
24540 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
24541 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, green_quad, sizeof(*green_quad));
24542 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
24543 hr = IDirect3DDevice9_EndScene(device);
24544 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
24545 color = getPixelColor(device, 320, 240);
24546 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
24548 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f00ff00, 0.0f, 0);
24549 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
24550 hr = IDirect3DDevice9_BeginScene(device);
24551 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
24552 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, red_quad, sizeof(*red_quad));
24553 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
24554 hr = IDirect3DDevice9_EndScene(device);
24555 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
24556 color = getPixelColor(device, 320, 240);
24557 ok(color_match(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
24559 refcount = IDirect3DDevice9_Release(device);
24560 ok(!refcount, "Device has %lu references left.\n", refcount);
24561 IDirect3D9_Release(d3d9);
24562 DestroyWindow(window);
24565 static void test_dsy(void)
24567 static const DWORD vs_code[] =
24569 0xfffe0300, /* vs_3_0 */
24570 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
24571 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
24572 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
24573 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */
24574 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
24575 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
24576 0x0000ffff
24578 static const DWORD ps_code[] =
24580 0xffff0300, /* ps_3_0 */
24581 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
24582 0x05000051, 0xa00f0000, 0x43700000, 0x3f000000, 0x00000000, 0x00000000, /* def c0, 240.0, 0.5, 0.0, 0.0 */
24583 0x0200005c, 0x800f0000, 0x90e40000, /* dsy r0, v0 */
24584 0x03000005, 0x800f0000, 0x80e40000, 0xa0000000, /* mul r0, r0, c0.x */
24585 0x03000002, 0x800f0800, 0x80e40000, 0xa0550000, /* add oC0, r0, c0.y */
24586 0x0000ffff
24588 static const struct
24590 struct vec3 pos;
24591 D3DCOLOR color;
24593 quad[] =
24595 {{-1.0f, -1.0f, 0.1f}, 0x00ff0000},
24596 {{-1.0f, 1.0f, 0.1f}, 0x0000ff00},
24597 {{ 1.0f, -1.0f, 0.1f}, 0x00ff0000},
24598 {{ 1.0f, 1.0f, 0.1f}, 0x0000ff00},
24600 IDirect3DSurface9 *backbuffer, *rt;
24601 IDirect3DVertexShader9 *vs;
24602 IDirect3DPixelShader9 *ps;
24603 IDirect3DDevice9 *device;
24604 unsigned int color;
24605 IDirect3D9 *d3d;
24606 ULONG refcount;
24607 D3DCAPS9 caps;
24608 HWND window;
24609 HRESULT hr;
24611 window = create_window();
24612 d3d = Direct3DCreate9(D3D_SDK_VERSION);
24613 ok(!!d3d, "Failed to create a D3D object.\n");
24614 if (!(device = create_device(d3d, window, window, TRUE)))
24616 skip("Failed to create a D3D device, skipping tests.\n");
24617 goto done;
24620 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
24621 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
24622 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0))
24624 skip("No ps_3_0 support, skipping dsy tests.\n");
24625 IDirect3DDevice9_Release(device);
24626 goto done;
24629 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
24630 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#lx.\n", hr);
24632 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
24633 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
24634 ok(SUCCEEDED(hr), "Failed to create offscreen render target, hr %#lx.\n", hr);
24635 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
24636 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
24638 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
24639 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#lx.\n", hr);
24640 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
24641 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#lx.\n", hr);
24643 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
24644 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
24645 hr = IDirect3DDevice9_SetVertexShader(device, vs);
24646 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
24647 hr = IDirect3DDevice9_SetPixelShader(device, ps);
24648 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
24650 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
24651 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
24652 hr = IDirect3DDevice9_BeginScene(device);
24653 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
24654 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
24655 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#lx.\n", hr);
24656 hr = IDirect3DDevice9_EndScene(device);
24657 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
24659 color = getPixelColor(device, 360, 240);
24660 ok(color_match(color, 0x00ff007f, 1), "Got unexpected color 0x%08x.\n", color);
24662 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
24663 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
24665 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
24666 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
24667 hr = IDirect3DDevice9_BeginScene(device);
24668 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
24669 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
24670 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#lx.\n", hr);
24671 hr = IDirect3DDevice9_EndScene(device);
24672 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
24674 color = getPixelColor(device, 360, 240);
24675 ok(color_match(color, 0x00ff007f, 1), "Got unexpected color 0x%08x.\n", color);
24677 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
24678 ok(SUCCEEDED(hr), "Failed to present frame, hr %#lx.\n", hr);
24680 IDirect3DSurface9_Release(rt);
24681 IDirect3DSurface9_Release(backbuffer);
24682 IDirect3DVertexShader9_Release(vs);
24683 IDirect3DPixelShader9_Release(ps);
24685 refcount = IDirect3DDevice9_Release(device);
24686 ok(!refcount, "Device has %lu references left.\n", refcount);
24687 done:
24688 IDirect3D9_Release(d3d);
24689 DestroyWindow(window);
24692 static void test_evict_bound_resources(void)
24694 IDirect3DVertexBuffer9 *vb;
24695 IDirect3DIndexBuffer9 *ib;
24696 IDirect3DDevice9 *device;
24697 unsigned int color;
24698 IDirect3D9 *d3d9;
24699 ULONG refcount;
24700 HWND window;
24701 void *data;
24702 HRESULT hr;
24704 static const struct
24706 struct vec3 position;
24707 DWORD diffuse;
24709 green_quad[] =
24711 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
24712 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
24713 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
24714 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
24716 static const unsigned short indices[] = {0, 1, 2, 3, 2, 1};
24718 window = create_window();
24719 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
24720 ok(!!d3d9, "Failed to create a D3D object.\n");
24722 if (!(device = create_device(d3d9, window, window, TRUE)))
24724 skip("Failed to create a D3D device.\n");
24725 IDirect3D9_Release(d3d9);
24726 DestroyWindow(window);
24727 return;
24730 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0,
24731 D3DFMT_INDEX16, D3DPOOL_MANAGED, &ib, NULL);
24732 ok(SUCCEEDED(hr), "Failed to create index buffer, hr %#lx.\n", hr);
24734 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(green_quad), 0,
24735 D3DFVF_XYZ | D3DFVF_DIFFUSE, D3DPOOL_MANAGED, &vb, NULL);
24736 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#lx.\n", hr);
24738 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
24739 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#lx.\n", hr);
24740 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
24741 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#lx.\n", hr);
24742 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
24743 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
24745 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
24746 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
24748 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(green_quad), &data, 0);
24749 ok(hr == D3D_OK, "Failed to lock vertex buffer, hr %#lx.\n", hr);
24750 memcpy(data, green_quad, sizeof(green_quad));
24751 hr = IDirect3DVertexBuffer9_Unlock(vb);
24752 ok(hr == D3D_OK, "Failed to unlock vertex buffer, hr %#lx.\n", hr);
24754 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), &data, 0);
24755 ok(hr == D3D_OK, "Failed to lock index buffer, hr %#lx.\n", hr);
24756 memcpy(data, indices, sizeof(indices));
24757 hr = IDirect3DIndexBuffer9_Unlock(ib);
24758 ok(hr == D3D_OK, "Failed to unlock index buffer, hr %#lx.\n", hr);
24760 hr = IDirect3DDevice9_SetIndices(device, ib);
24761 ok(hr == D3D_OK, "Failed to set index buffer, hr %#lx.\n", hr);
24762 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(*green_quad));
24763 ok(hr == D3D_OK, "Failed to set stream source, hr %#lx.\n", hr);
24765 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
24766 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
24767 hr = IDirect3DDevice9_BeginScene(device);
24768 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
24769 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
24770 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
24771 hr = IDirect3DDevice9_EndScene(device);
24772 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
24773 color = getPixelColor(device, 320, 240);
24774 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
24776 hr = IDirect3DDevice9_EvictManagedResources(device);
24777 ok(hr == D3D_OK, "Failed to evict managed resources, hr %#lx.\n", hr);
24779 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
24780 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
24781 hr = IDirect3DDevice9_BeginScene(device);
24782 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
24783 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
24784 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
24785 hr = IDirect3DDevice9_EndScene(device);
24786 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
24787 color = getPixelColor(device, 320, 240);
24788 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
24790 IDirect3DIndexBuffer9_Release(ib);
24791 IDirect3DVertexBuffer9_Release(vb);
24792 refcount = IDirect3DDevice9_Release(device);
24793 ok(!refcount, "Device has %lu references left.\n", refcount);
24794 IDirect3D9_Release(d3d9);
24795 DestroyWindow(window);
24798 /* This test shows that 0xffff is valid index in D3D9. */
24799 static void test_max_index16(void)
24801 static const struct vertex
24803 struct vec3 position;
24804 DWORD diffuse;
24806 green_quad[] =
24808 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
24809 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
24810 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
24811 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
24813 static const unsigned short indices[] = {0, 1, 2, 0xffff};
24814 static const unsigned int vertex_count = 0xffff + 1;
24816 D3DADAPTER_IDENTIFIER9 identifier;
24817 IDirect3DVertexBuffer9 *vb;
24818 IDirect3DIndexBuffer9 *ib;
24819 IDirect3DDevice9 *device;
24820 struct vertex *vb_data;
24821 unsigned int color;
24822 IDirect3D9 *d3d9;
24823 ULONG refcount;
24824 D3DCAPS9 caps;
24825 HWND window;
24826 void *data;
24827 HRESULT hr;
24828 BOOL warp;
24830 window = create_window();
24831 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
24832 ok(!!d3d9, "Failed to create a D3D object.\n");
24834 hr = IDirect3D9_GetAdapterIdentifier(d3d9, D3DADAPTER_DEFAULT, 0, &identifier);
24835 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#lx.\n", hr);
24836 warp = adapter_is_warp(&identifier);
24838 if (!(device = create_device(d3d9, window, window, TRUE)))
24840 skip("Failed to create a D3D device.\n");
24841 IDirect3D9_Release(d3d9);
24842 DestroyWindow(window);
24843 return;
24846 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
24847 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
24848 if (caps.MaxVertexIndex < 0xffff)
24850 skip("Max vertex index is lower than 0xffff (%#lx).\n", caps.MaxVertexIndex);
24851 IDirect3DDevice9_Release(device);
24852 IDirect3D9_Release(d3d9);
24853 DestroyWindow(window);
24854 return;
24857 hr = IDirect3DDevice9_CreateVertexBuffer(device, vertex_count * sizeof(*green_quad), 0,
24858 D3DFVF_XYZ | D3DFVF_DIFFUSE, D3DPOOL_MANAGED, &vb, NULL);
24859 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#lx.\n", hr);
24861 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0,
24862 D3DFMT_INDEX16, D3DPOOL_MANAGED, &ib, NULL);
24863 ok(SUCCEEDED(hr), "Failed to create index buffer, hr %#lx.\n", hr);
24865 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
24866 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#lx.\n", hr);
24867 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
24868 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#lx.\n", hr);
24869 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
24870 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
24872 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
24873 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
24875 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(green_quad), (void **)&vb_data, 0);
24876 ok(hr == D3D_OK, "Failed to lock vertex buffer, hr %#lx.\n", hr);
24877 vb_data[0] = green_quad[0];
24878 vb_data[1] = green_quad[1];
24879 vb_data[2] = green_quad[2];
24880 vb_data[0xffff] = green_quad[3];
24881 hr = IDirect3DVertexBuffer9_Unlock(vb);
24882 ok(hr == D3D_OK, "Failed to unlock vertex buffer, hr %#lx.\n", hr);
24884 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), &data, 0);
24885 ok(hr == D3D_OK, "Failed to lock index buffer, hr %#lx.\n", hr);
24886 memcpy(data, indices, sizeof(indices));
24887 hr = IDirect3DIndexBuffer9_Unlock(ib);
24888 ok(hr == D3D_OK, "Failed to unlock index buffer, hr %#lx.\n", hr);
24890 hr = IDirect3DDevice9_SetIndices(device, ib);
24891 ok(hr == D3D_OK, "Failed to set index buffer, hr %#lx.\n", hr);
24892 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(struct vertex));
24893 ok(hr == D3D_OK, "Failed to set stream source, hr %#lx.\n", hr);
24895 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
24896 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
24897 hr = IDirect3DDevice9_BeginScene(device);
24898 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
24899 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 0, vertex_count, 0, 2);
24900 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
24901 hr = IDirect3DDevice9_EndScene(device);
24902 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
24903 color = getPixelColor(device, 20, 20);
24904 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
24905 color = getPixelColor(device, 320, 240);
24906 ok(color_match(color, 0x0000ff00, 1) || broken(warp), "Got unexpected color 0x%08x.\n", color);
24907 color = getPixelColor(device, 620, 460);
24908 ok(color_match(color, 0x0000ff00, 1) || broken(warp), "Got unexpected color 0x%08x.\n", color);
24910 IDirect3DIndexBuffer9_Release(ib);
24911 IDirect3DVertexBuffer9_Release(vb);
24912 refcount = IDirect3DDevice9_Release(device);
24913 ok(!refcount, "Device has %lu references left.\n", refcount);
24914 IDirect3D9_Release(d3d9);
24915 DestroyWindow(window);
24918 static void test_backbuffer_resize(void)
24920 D3DPRESENT_PARAMETERS present_parameters = {0};
24921 IDirect3DSurface9 *backbuffer;
24922 IDirect3DDevice9 *device;
24923 unsigned int color;
24924 IDirect3D9 *d3d;
24925 ULONG refcount;
24926 HWND window;
24927 HRESULT hr;
24929 static const struct
24931 struct vec3 position;
24932 DWORD diffuse;
24934 quad[] =
24936 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
24937 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
24938 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
24939 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
24942 window = create_window();
24943 d3d = Direct3DCreate9(D3D_SDK_VERSION);
24944 ok(!!d3d, "Failed to create a D3D object.\n");
24945 if (!(device = create_device(d3d, window, window, TRUE)))
24947 skip("Failed to create a D3D device.\n");
24948 goto done;
24951 /* Wine d3d9 implementation had a bug which was triggered by a
24952 * SetRenderTarget() call with an unreferenced surface. */
24953 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
24954 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#lx.\n", hr);
24955 refcount = IDirect3DSurface9_Release(backbuffer);
24956 ok(!refcount, "Surface has %lu references left.\n", refcount);
24957 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
24958 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
24959 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
24960 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
24962 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
24963 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
24964 color = getPixelColor(device, 1, 1);
24965 ok(color == 0x00ff0000, "Got unexpected color 0x%08x.\n", color);
24967 present_parameters.BackBufferWidth = 800;
24968 present_parameters.BackBufferHeight = 600;
24969 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
24970 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
24971 present_parameters.hDeviceWindow = NULL;
24972 present_parameters.Windowed = TRUE;
24973 present_parameters.EnableAutoDepthStencil = TRUE;
24974 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
24975 hr = IDirect3DDevice9_Reset(device, &present_parameters);
24976 ok(SUCCEEDED(hr), "Failed to reset, hr %#lx.\n", hr);
24978 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
24979 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#lx.\n", hr);
24980 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
24981 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#lx.\n", hr);
24982 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
24983 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
24984 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
24985 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
24987 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
24988 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#lx.\n", hr);
24989 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
24990 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
24991 IDirect3DSurface9_Release(backbuffer);
24993 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
24994 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
24995 color = getPixelColor(device, 1, 1);
24996 ok(color == 0x00ffff00, "Got unexpected color 0x%08x.\n", color);
24997 color = getPixelColor(device, 700, 500);
24998 ok(color == 0x00ffff00, "Got unexpected color 0x%08x.\n", color);
25000 hr = IDirect3DDevice9_BeginScene(device);
25001 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
25002 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
25003 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
25004 hr = IDirect3DDevice9_EndScene(device);
25005 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
25006 color = getPixelColor(device, 1, 1);
25007 ok(color == 0x0000ff00, "Got unexpected color 0x%08x.\n", color);
25008 color = getPixelColor(device, 700, 500);
25009 ok(color == 0x0000ff00, "Got unexpected color 0x%08x.\n", color);
25011 refcount = IDirect3DDevice9_Release(device);
25012 ok(!refcount, "Device has %lu references left.\n", refcount);
25013 done:
25014 IDirect3D9_Release(d3d);
25015 DestroyWindow(window);
25018 static void test_drawindexedprimitiveup(void)
25020 static const struct vertex
25022 struct vec3 position;
25023 DWORD diffuse;
25025 quad[] =
25027 {{-1.0f, -1.0f, 0.1f}, 0xff00ff00},
25028 {{-1.0f, 1.0f, 0.1f}, 0xff0000ff},
25029 {{ 1.0f, -1.0f, 0.1f}, 0xffff0000},
25030 {{ 1.0f, 1.0f, 0.1f}, 0xff0000ff},
25032 {{-1.0f, -1.0f, 0.1f}, 0xff0000ff},
25033 {{-1.0f, 1.0f, 0.1f}, 0xff00ff00},
25034 {{ 1.0f, -1.0f, 0.1f}, 0xffff0000},
25035 {{ 1.0f, 1.0f, 0.1f}, 0xff00ff00},
25037 static const unsigned short indices[] = {0, 1, 2, 3, 4, 5, 6, 7};
25038 IDirect3DVertexBuffer9 *vb;
25039 IDirect3DDevice9 *device;
25040 UINT offset, stride;
25041 unsigned int color;
25042 IDirect3D9 *d3d;
25043 ULONG refcount;
25044 HWND window;
25045 HRESULT hr;
25047 window = create_window();
25048 d3d = Direct3DCreate9(D3D_SDK_VERSION);
25049 ok(!!d3d, "Failed to create a D3D object.\n");
25051 if (!(device = create_device(d3d, window, window, TRUE)))
25053 skip("Failed to create a D3D device.\n");
25054 IDirect3D9_Release(d3d);
25055 DestroyWindow(window);
25056 return;
25059 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
25060 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#lx.\n", hr);
25061 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
25062 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#lx.\n", hr);
25063 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
25064 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
25066 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
25067 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
25069 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
25070 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
25072 hr = IDirect3DDevice9_BeginScene(device);
25073 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
25074 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 4, 4, 2, indices + 4, D3DFMT_INDEX16, quad, sizeof(*quad));
25075 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
25076 hr = IDirect3DDevice9_EndScene(device);
25077 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
25079 color = getPixelColor(device, 160, 120);
25080 ok(color_match(color, 0x0040bf00, 1), "Got unexpected color 0x%08x.\n", color);
25081 color = getPixelColor(device, 480, 120);
25082 ok(color_match(color, 0x0040bf00, 1), "Got unexpected color 0x%08x.\n", color);
25083 color = getPixelColor(device, 160, 360);
25084 ok(color_match(color, 0x00404080, 1), "Got unexpected color 0x%08x.\n", color);
25085 color = getPixelColor(device, 480, 360);
25086 ok(color_match(color, 0x00bf4000, 1), "Got unexpected color 0x%08x.\n", color);
25088 hr = IDirect3DDevice9_GetStreamSource(device, 0, &vb, &offset, &stride);
25089 ok(SUCCEEDED(hr), "GetStreamSource failed, hr %#lx.\n", hr);
25090 ok(!vb, "Unexpected vb %p.\n", vb);
25091 ok(!offset, "Unexpected offset %u.\n", offset);
25092 ok(!stride, "Unexpected stride %u.\n", stride);
25094 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
25095 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
25097 hr = IDirect3DDevice9_BeginScene(device);
25098 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
25099 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 0, 4, 2, indices, D3DFMT_INDEX16, quad, sizeof(*quad));
25100 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
25101 hr = IDirect3DDevice9_EndScene(device);
25102 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
25104 color = getPixelColor(device, 160, 120);
25105 ok(color_match(color, 0x004000bf, 1), "Got unexpected color 0x%08x.\n", color);
25106 color = getPixelColor(device, 480, 120);
25107 ok(color_match(color, 0x004000bf, 1), "Got unexpected color 0x%08x.\n", color);
25108 color = getPixelColor(device, 160, 360);
25109 ok(color_match(color, 0x00408040, 1), "Got unexpected color 0x%08x.\n", color);
25110 color = getPixelColor(device, 480, 360);
25111 ok(color_match(color, 0x00bf0040, 1), "Got unexpected color 0x%08x.\n", color);
25113 refcount = IDirect3DDevice9_Release(device);
25114 ok(!refcount, "Device has %lu references left.\n", refcount);
25115 IDirect3D9_Release(d3d);
25116 DestroyWindow(window);
25119 static void test_vertex_texture(void)
25121 static const D3DVERTEXELEMENT9 decl_elements[] =
25123 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
25124 D3DDECL_END()
25126 static const struct vec3 quad[] =
25128 {-1.0f, -1.0f, 0.0f},
25129 {-1.0f, 1.0f, 0.0f},
25130 { 1.0f, -1.0f, 0.0f},
25131 { 1.0f, 1.0f, 0.0f},
25133 static const DWORD vs_code[] =
25135 0xfffe0300, /* vs_3_0 */
25136 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0, 0, 0, 0 */
25137 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
25138 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
25139 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
25140 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
25141 0x0300005f, 0xe00f0001, 0xa0000000, 0xa0e40800, /* texldl o1, c0.x, s0 */
25142 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
25143 0x0000ffff, /* end */
25145 static const DWORD ps_code[] =
25147 0xffff0300, /* ps_3_0 */
25148 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color v0 */
25149 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
25150 0x0000ffff, /* end */
25152 static const DWORD texture_data[4] = {0x00ffff00, 0x00ffff00, 0x00ffff00, 0x00ffff00};
25153 IDirect3DVertexDeclaration9 *declaration;
25154 IDirect3DTexture9 *texture;
25155 IDirect3DVertexShader9 *vs;
25156 IDirect3DPixelShader9 *ps;
25157 IDirect3DDevice9 *device;
25158 unsigned int color;
25159 D3DLOCKED_RECT lr;
25160 IDirect3D9 *d3d;
25161 ULONG refcount;
25162 D3DCAPS9 caps;
25163 HWND window;
25164 HRESULT hr;
25166 window = create_window();
25167 d3d = Direct3DCreate9(D3D_SDK_VERSION);
25168 ok(!!d3d, "Failed to create D3D object.\n");
25170 if (!(device = create_device(d3d, window, window, TRUE)))
25172 skip("Failed to create D3D device.\n");
25173 IDirect3D9_Release(d3d);
25174 DestroyWindow(window);
25175 return;
25178 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
25179 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
25180 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0) || caps.PixelShaderVersion < D3DPS_VERSION(3, 0))
25182 skip("SM3 is not supported.\n");
25183 goto done;
25185 if (!(caps.VertexTextureFilterCaps & D3DPTFILTERCAPS_MAGFPOINT)
25186 || !(caps.VertexTextureFilterCaps & D3DPTFILTERCAPS_MINFPOINT))
25188 skip("Vertex texture point filtering is not supported, caps %#lx.\n", caps.VertexTextureFilterCaps);
25189 goto done;
25191 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
25192 D3DUSAGE_QUERY_VERTEXTEXTURE, D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8);
25193 if (hr != D3D_OK)
25195 skip("No vertex texture fetch support for D3DFMT_A8R8G8B8, hr %#lx.\n", hr);
25196 goto done;
25199 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
25200 ok(hr == D3D_OK, "Failed to create texture, hr %#lx.\n", hr);
25201 memset(&lr, 0, sizeof(lr));
25202 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
25203 ok(hr == D3D_OK, "Failed to lock texture, hr %#lx.\n", hr);
25204 memcpy(lr.pBits, texture_data, sizeof(texture_data));
25205 hr = IDirect3DTexture9_UnlockRect(texture, 0);
25206 ok(hr == D3D_OK, "Failed to unlock texture, hr %#lx.\n", hr);
25208 hr = IDirect3DDevice9_SetTexture(device, D3DVERTEXTEXTURESAMPLER0, (IDirect3DBaseTexture9 *)texture);
25209 ok(hr == D3D_OK, "Failed to set texture, hr %#lx.\n", hr);
25211 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &declaration);
25212 ok(SUCCEEDED(hr), "Failed to create vertex declaration, hr %#lx.\n", hr);
25213 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
25214 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#lx.\n", hr);
25215 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
25216 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#lx.\n", hr);
25218 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration);
25219 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
25220 hr = IDirect3DDevice9_SetVertexShader(device, vs);
25221 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
25222 hr = IDirect3DDevice9_SetPixelShader(device, ps);
25223 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
25225 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
25226 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
25227 hr = IDirect3DDevice9_BeginScene(device);
25228 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
25229 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
25230 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
25231 hr = IDirect3DDevice9_EndScene(device);
25232 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
25233 color = getPixelColor(device, 160, 360);
25234 ok(color == texture_data[0], "Got unexpected color 0x%08x.\n", color);
25236 IDirect3DPixelShader9_Release(ps);
25237 IDirect3DVertexShader9_Release(vs);
25238 IDirect3DTexture9_Release(texture);
25239 IDirect3DVertexDeclaration9_Release(declaration);
25240 done:
25241 refcount = IDirect3DDevice9_Release(device);
25242 ok(!refcount, "Device has %lu references left.\n", refcount);
25243 IDirect3D9_Release(d3d);
25244 DestroyWindow(window);
25247 static void test_mvp_software_vertex_shaders(void)
25249 IDirect3DVertexDeclaration9 *vertex_declaration;
25250 D3DPRESENT_PARAMETERS present_parameters = {0};
25251 IDirect3DVertexShader9 *pure_sw_shader = NULL;
25252 IDirect3DVertexShader9 *reladdr_shader = NULL;
25253 unsigned int color, expected_color;
25254 IDirect3DDevice9 *device;
25255 IDirect3D9 *d3d;
25256 ULONG refcount;
25257 D3DCAPS9 caps;
25258 HWND window;
25259 HRESULT hr;
25261 static const float c_index[4] = {256.0f, 0.0f, 0.0f, 0.0f};
25262 static const float c_color[4] = {0.0f, 1.0f, 0.0f, 1.0f};
25263 static const DWORD reladdr_shader_code[] =
25265 0xfffe0200, /* vs_2_0 */
25266 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
25267 0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c1, 1.0, 1.0, 1.0, 1.0 */
25268 0x0200002e, 0xb0010000, 0xa0000000, /* mova a0.x, c0.x */
25269 0x03000001, 0xd00f0000, 0xa0e42000, 0xb0000000, /* mov oD0, c[a0.x] */
25270 0x02000001, 0xd0040000, 0xa0e40001, /* mov oD0.z, c1 */
25271 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
25272 0x0000ffff /* END */
25274 static const DWORD pure_sw_shader_code[] =
25276 0xfffe0200, /* vs_2_0 */
25277 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
25278 0x05000051, 0xa00f0100, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c256, 1.0, 1.0, 1.0, 1.0 */
25279 0x02000001, 0xd00f0000, 0xa0e40100, /* mov oD0, c256 */
25280 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
25281 0x0000ffff /* END */
25284 static const struct
25286 float position[3];
25287 DWORD color;
25289 quad[] =
25291 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
25292 {{-1.0f, 1.0f, 0.0f}, 0xffff0000},
25293 {{ 1.0f, 1.0f, 0.0f}, 0xffff0000},
25294 {{ 1.0f, -1.0f, 0.0f}, 0xffff0000},
25296 static const D3DVERTEXELEMENT9 decl_elements[] =
25298 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
25299 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
25300 D3DDECL_END()
25303 window = create_window();
25304 d3d = Direct3DCreate9(D3D_SDK_VERSION);
25305 ok(!!d3d, "Failed to create a D3D object.\n");
25307 present_parameters.Windowed = TRUE;
25308 present_parameters.hDeviceWindow = window;
25309 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
25310 present_parameters.BackBufferWidth = 640;
25311 present_parameters.BackBufferHeight = 480;
25312 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
25313 present_parameters.EnableAutoDepthStencil = TRUE;
25314 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
25316 if (FAILED(IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
25317 D3DCREATE_MIXED_VERTEXPROCESSING, &present_parameters, &device)))
25319 skip("Failed to create a D3D device, skipping tests.\n");
25320 goto done;
25323 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
25324 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
25325 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
25327 skip("No vs_2_0 support, skipping tests.\n");
25328 IDirect3DDevice9_Release(device);
25329 goto done;
25332 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
25333 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
25335 hr = IDirect3DDevice9_SetSoftwareVertexProcessing(device, 0);
25336 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25338 hr = IDirect3DDevice9_CreateVertexShader(device, reladdr_shader_code, &reladdr_shader);
25339 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25340 hr = IDirect3DDevice9_CreateVertexShader(device, pure_sw_shader_code, &pure_sw_shader);
25341 todo_wine
25342 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25343 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
25344 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25345 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
25346 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25348 hr = IDirect3DDevice9_SetVertexShader(device, pure_sw_shader);
25349 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25351 hr = IDirect3DDevice9_BeginScene(device);
25352 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25353 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
25354 todo_wine
25355 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
25356 hr = IDirect3DDevice9_EndScene(device);
25357 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25359 expected_color = 0; /* Nothing rendered. */
25360 color = getPixelColor(device, 5, 5);
25361 todo_wine
25362 ok(color == expected_color, "Expected color 0x%08x, got 0x%08x (sw shader in hw mode).\n",
25363 expected_color, color);
25365 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
25366 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25367 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
25368 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25370 hr = IDirect3DDevice9_BeginScene(device);
25371 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25372 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
25373 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25374 hr = IDirect3DDevice9_EndScene(device);
25375 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25377 expected_color = 0x00ff0000; /* Color from vertex data and not from the shader. */
25378 color = getPixelColor(device, 5, 5);
25379 ok(color == expected_color, "Expected color 0x%08x, got 0x%08x (sw shader in hw mode, second attempt).\n",
25380 expected_color, color);
25382 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
25383 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25384 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
25385 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25387 hr = IDirect3DDevice9_BeginScene(device);
25388 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25389 hr = IDirect3DDevice9_SetSoftwareVertexProcessing(device, 1);
25390 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25391 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
25392 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25393 hr = IDirect3DDevice9_EndScene(device);
25394 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25396 expected_color = 0x00ffffff;
25397 color = getPixelColor(device, 5, 5);
25398 todo_wine
25399 ok(color == expected_color, "Expected color 0x%08x, got 0x%08x (sw shader in sw mode).\n",
25400 expected_color, color);
25402 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
25403 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25404 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
25405 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25407 hr = IDirect3DDevice9_SetSoftwareVertexProcessing(device, 0);
25408 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25409 hr = IDirect3DDevice9_SetVertexShader(device, reladdr_shader);
25410 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25412 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, c_index, 1);
25413 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25414 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, (unsigned int)c_index[0], c_color, 1);
25415 todo_wine
25416 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25418 hr = IDirect3DDevice9_BeginScene(device);
25419 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25420 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
25421 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25422 hr = IDirect3DDevice9_EndScene(device);
25423 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25425 /* Index 256 is out of bounds for selected shader in HW mode. c[256] is 0 most of the time. It
25426 is not guaranteed across all the adapters though, so disabling test. */
25427 #if 0
25428 expected_color = 0x000000ff;
25429 color = getPixelColor(device, 5, 5);
25430 ok(color == expected_color, "Expected color 0x%08x, got 0x%08x (shader in hw mode).\n",
25431 expected_color, color);
25432 #endif
25434 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
25435 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25436 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
25437 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25439 hr = IDirect3DDevice9_BeginScene(device);
25440 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25441 hr = IDirect3DDevice9_SetSoftwareVertexProcessing(device, 1);
25442 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
25443 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25444 hr = IDirect3DDevice9_EndScene(device);
25445 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25447 expected_color = 0x0000ffff; /* c[256] is c_color for SW shader. */
25448 color = getPixelColor(device, 5, 5);
25449 todo_wine
25450 ok(color == expected_color, "Expected color 0x%08x, got 0x%08x (shader in sw mode).\n",
25451 expected_color, color);
25453 IDirect3DVertexDeclaration9_Release(vertex_declaration);
25454 IDirect3DVertexShader9_Release(reladdr_shader);
25455 if (pure_sw_shader)
25456 IDirect3DVertexShader9_Release(pure_sw_shader);
25457 refcount = IDirect3DDevice9_Release(device);
25458 ok(!refcount, "Device has %lu references left.\n", refcount);
25459 done:
25460 IDirect3D9_Release(d3d);
25461 DestroyWindow(window);
25464 static void test_null_format(void)
25466 static const D3DVIEWPORT9 vp_part_400 = {0, 100, 400, 200, 0.0f, 1.0f};
25467 static const D3DVIEWPORT9 vp_lower = {0, 60, 640, 420, 0.0f, 1.0f};
25468 static const D3DVIEWPORT9 vp_560 = {0, 180, 560, 300, 0.0f, 1.0f};
25469 static const D3DVIEWPORT9 vp_full = {0, 0, 640, 480, 0.0f, 1.0f};
25470 static const DWORD null_fourcc = MAKEFOURCC('N','U','L','L');
25471 static const struct
25473 struct vec3 pos;
25474 DWORD diffuse;
25476 quad_partial[] =
25478 {{-1.0f, 0.5f, 0.1f}, 0x000000ff},
25479 {{ 0.5f, 0.5f, 0.1f}, 0x000000ff},
25480 {{-1.0f, -1.0f, 0.1f}, 0x000000ff},
25481 {{ 0.5f, -1.0f, 0.1f}, 0x000000ff},
25483 quad[] =
25485 {{-1.0f, 1.0f, 0.5f}, 0x00ff0000},
25486 {{ 1.0f, 1.0f, 0.5f}, 0x00ff0000},
25487 {{-1.0f, -1.0f, 0.5f}, 0x00ff0000},
25488 {{ 1.0f, -1.0f, 0.5f}, 0x00ff0000},
25490 quad_far[] =
25492 {{-1.0f, 1.0f, 1.0f}, 0x0000ff00},
25493 {{ 1.0f, 1.0f, 1.0f}, 0x0000ff00},
25494 {{-1.0f, -1.0f, 1.0f}, 0x0000ff00},
25495 {{ 1.0f, -1.0f, 1.0f}, 0x0000ff00},
25497 static const struct
25499 unsigned int x, y, color;
25501 expected_colors[] =
25503 {200, 30, 0x0000ff00},
25504 {440, 30, 0x0000ff00},
25505 {520, 30, 0x0000ff00},
25506 {600, 30, 0x0000ff00},
25507 {200, 90, 0x00000000},
25508 {440, 90, 0x0000ff00},
25509 {520, 90, 0x0000ff00},
25510 {600, 90, 0x0000ff00},
25511 {200, 150, 0x000000ff},
25512 {440, 150, 0x000000ff},
25513 {520, 150, 0x0000ff00},
25514 {600, 150, 0x0000ff00},
25515 {200, 320, 0x000000ff},
25516 {440, 320, 0x000000ff},
25517 {520, 320, 0x00000000},
25518 {600, 320, 0x0000ff00},
25520 expected_small[] =
25522 {100, 100, 0x00ff0000},
25523 {200, 100, 0x00ff0000},
25524 {300, 100, 0x00ff0000},
25525 {100, 150, 0x00000000},
25526 {200, 150, 0x00000000},
25527 {300, 150, 0x00ff0000},
25528 {100, 200, 0x00000000},
25529 {200, 200, 0x00000000},
25530 {300, 200, 0x00ff0000},
25532 IDirect3DSurface9 *original_rt, *small_rt, *null_rt, *small_null_rt;
25533 IDirect3DSurface9 *original_ds, *small_ds;
25534 struct surface_readback rb;
25535 IDirect3DDevice9 *device;
25536 unsigned int color, i;
25537 IDirect3D9 *d3d;
25538 HWND window;
25539 HRESULT hr;
25541 d3d = Direct3DCreate9(D3D_SDK_VERSION);
25542 ok(!!d3d, "Failed to create a D3D object.\n");
25544 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
25545 D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, null_fourcc)))
25547 skip("No NULL format support, skipping NULL test.\n");
25548 IDirect3D9_Release(d3d);
25549 return;
25552 window = create_window();
25553 if (!(device = create_device(d3d, window, window, TRUE)))
25555 skip("Failed to create a D3D device.\n");
25556 IDirect3D9_Release(d3d);
25557 DestroyWindow(window);
25558 return;
25561 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
25562 ok(SUCCEEDED(hr), "Failed to get render target, hr %#lx.\n", hr);
25564 hr = IDirect3DDevice9_CreateRenderTarget(device, 400, 300, D3DFMT_A8R8G8B8,
25565 D3DMULTISAMPLE_NONE, 0, FALSE, &small_rt, NULL);
25566 ok(SUCCEEDED(hr), "Failed to create render target, hr %#lx.\n", hr);
25567 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, null_fourcc,
25568 D3DMULTISAMPLE_NONE, 0, FALSE, &null_rt, NULL);
25569 ok(SUCCEEDED(hr), "Failed to create render target, hr %#lx.\n", hr);
25570 hr = IDirect3DDevice9_CreateRenderTarget(device, 400, 300, null_fourcc,
25571 D3DMULTISAMPLE_NONE, 0, FALSE, &small_null_rt, NULL);
25572 ok(SUCCEEDED(hr), "Failed to create render target, hr %#lx.\n", hr);
25574 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
25575 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
25576 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 400, 300, D3DFMT_D24S8, 0, 0, FALSE,
25577 &small_ds, NULL);
25578 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
25580 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
25581 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
25582 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
25583 ok(SUCCEEDED(hr), "Failed to enable depth test, hr %#lx.\n", hr);
25584 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
25585 ok(SUCCEEDED(hr), "Failed to set depth function, hr %#lx.\n", hr);
25586 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
25587 ok(SUCCEEDED(hr), "Failed to enable depth write, hr %#lx.\n", hr);
25588 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
25589 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
25591 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
25592 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
25594 /* Clear extends to viewport size > RT size even if format is not
25595 * "NULL". */
25596 hr = IDirect3DDevice9_SetRenderTarget(device, 0, small_rt);
25597 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
25599 hr = IDirect3DDevice9_SetViewport(device, &vp_full);
25600 ok(hr == D3D_OK, "Failed to set viewport, hr %#lx.\n", hr);
25602 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.2f, 0);
25603 ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#lx.\n", hr);
25605 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
25606 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
25608 hr = IDirect3DDevice9_BeginScene(device);
25609 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
25610 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
25611 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
25612 hr = IDirect3DDevice9_EndScene(device);
25613 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
25615 hr = IDirect3DDevice9_SetRenderTarget(device, 0, null_rt);
25616 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
25617 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
25618 ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#lx.\n", hr);
25620 /* Draw only extends to viewport size > RT size if format is "NULL". */
25621 hr = IDirect3DDevice9_SetRenderTarget(device, 0, small_rt);
25622 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
25623 hr = IDirect3DDevice9_SetViewport(device, &vp_lower);
25624 ok(hr == D3D_OK, "Failed to set viewport, hr %#lx.\n", hr);
25625 hr = IDirect3DDevice9_BeginScene(device);
25626 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
25627 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
25628 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
25629 hr = IDirect3DDevice9_EndScene(device);
25630 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
25632 hr = IDirect3DDevice9_SetRenderTarget(device, 0, small_null_rt);
25633 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
25634 hr = IDirect3DDevice9_SetViewport(device, &vp_560);
25635 ok(hr == D3D_OK, "Failed to set viewport, hr %#lx.\n", hr);
25636 hr = IDirect3DDevice9_BeginScene(device);
25637 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
25638 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
25639 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
25640 hr = IDirect3DDevice9_EndScene(device);
25641 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
25643 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
25644 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
25646 hr = IDirect3DDevice9_BeginScene(device);
25647 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
25648 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_partial, sizeof(*quad_partial));
25649 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
25650 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_far, sizeof(*quad_far));
25651 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
25652 hr = IDirect3DDevice9_EndScene(device);
25653 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
25655 get_rt_readback(original_rt, &rb);
25656 for (i = 0; i < ARRAY_SIZE(expected_colors); ++i)
25658 color = get_readback_color(&rb, expected_colors[i].x, expected_colors[i].y);
25659 ok(color_match(color, expected_colors[i].color, 1),
25660 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
25661 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
25663 release_surface_readback(&rb);
25665 /* Clears and draws on a depth buffer smaller than the "NULL" RT work just
25666 * fine. */
25667 hr = IDirect3DDevice9_SetRenderTarget(device, 0, null_rt);
25668 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
25669 hr = IDirect3DDevice9_SetDepthStencilSurface(device, small_ds);
25670 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
25671 hr = IDirect3DDevice9_SetViewport(device, &vp_full);
25672 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
25674 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.6f, 0);
25675 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
25677 hr = IDirect3DDevice9_SetViewport(device, &vp_part_400);
25678 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
25680 hr = IDirect3DDevice9_BeginScene(device);
25681 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
25682 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_partial, sizeof(*quad_partial));
25683 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
25685 hr = IDirect3DDevice9_SetRenderTarget(device, 0, small_rt);
25686 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
25688 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
25689 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
25691 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
25692 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
25693 hr = IDirect3DDevice9_EndScene(device);
25694 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
25696 get_rt_readback(small_rt, &rb);
25697 for (i = 0; i < ARRAY_SIZE(expected_small); ++i)
25699 color = get_readback_color(&rb, expected_small[i].x, expected_small[i].y);
25700 ok(color_match(color, expected_small[i].color, 1),
25701 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
25702 expected_small[i].color, expected_small[i].x, expected_small[i].y, color);
25704 release_surface_readback(&rb);
25706 hr = IDirect3DDevice9_StretchRect(device, small_rt, NULL, original_rt, NULL, D3DTEXF_POINT);
25707 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
25708 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
25709 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
25711 IDirect3DSurface9_Release(small_ds);
25712 IDirect3DSurface9_Release(original_ds);
25713 IDirect3DSurface9_Release(small_null_rt);
25714 IDirect3DSurface9_Release(null_rt);
25715 IDirect3DSurface9_Release(small_rt);
25716 IDirect3DSurface9_Release(original_rt);
25717 cleanup_device(device);
25718 IDirect3D9_Release(d3d);
25721 static void test_map_synchronisation(void)
25723 unsigned int colour, i, j, tri_count, size;
25724 LARGE_INTEGER frequency, diff, ts[3];
25725 D3DADAPTER_IDENTIFIER9 identifier;
25726 IDirect3DVertexBuffer9 *buffer;
25727 IDirect3DDevice9 *device;
25728 BOOL unsynchronised, ret;
25729 IDirect3D9 *d3d;
25730 ULONG refcount;
25731 D3DCAPS9 caps;
25732 HWND window;
25733 HRESULT hr;
25735 static const struct
25737 unsigned int flags;
25738 BOOL unsynchronised;
25740 tests[] =
25742 {0, FALSE},
25743 {D3DLOCK_NOOVERWRITE, TRUE},
25744 {D3DLOCK_DISCARD, FALSE},
25745 {D3DLOCK_NOOVERWRITE | D3DLOCK_DISCARD, TRUE},
25748 static const struct quad
25750 struct
25752 struct vec3 position;
25753 DWORD diffuse;
25754 } strip[4];
25756 quad1 =
25759 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
25760 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
25761 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
25762 {{ 1.0f, 1.0f, 0.0f}, 0xffffffff},
25765 quad2 =
25768 {{-1.0f, -1.0f, 0.0f}, 0xffffff00},
25769 {{-1.0f, 1.0f, 0.0f}, 0xffffff00},
25770 {{ 1.0f, -1.0f, 0.0f}, 0xffffff00},
25771 {{ 1.0f, 1.0f, 0.0f}, 0xffffff00},
25774 struct quad *quads;
25776 window = create_window();
25777 ok(!!window, "Failed to create a window.\n");
25779 d3d = Direct3DCreate9(D3D_SDK_VERSION);
25780 ok(!!d3d, "Failed to create a D3D object.\n");
25781 if (!(device = create_device(d3d, window, window, TRUE)))
25783 skip("Failed to create a D3D device, skipping tests.\n");
25784 IDirect3D9_Release(d3d);
25785 DestroyWindow(window);
25786 return;
25789 hr = IDirect3D9_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
25790 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#lx.\n", hr);
25791 /* Maps are always synchronised on WARP. */
25792 if (adapter_is_warp(&identifier))
25794 skip("Running on WARP, skipping test.\n");
25795 goto done;
25798 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
25799 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
25801 tri_count = 0x1000;
25802 if (tri_count > caps.MaxPrimitiveCount)
25804 skip("Device supports only %lu primitives, skipping test.\n", caps.MaxPrimitiveCount);
25805 goto done;
25807 size = (tri_count + 2) * sizeof(*quad1.strip);
25809 ret = QueryPerformanceFrequency(&frequency);
25810 ok(ret, "Failed to get performance counter frequency.\n");
25812 hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
25813 D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &buffer, NULL);
25814 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#lx.\n", hr);
25815 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, size, (void **)&quads, D3DLOCK_DISCARD);
25816 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#lx.\n", hr);
25817 for (j = 0; j < size / sizeof(*quads); ++j)
25819 quads[j] = quad1;
25821 hr = IDirect3DVertexBuffer9_Unlock(buffer);
25822 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#lx.\n", hr);
25824 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
25825 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
25826 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
25827 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
25828 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(*quads->strip));
25829 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#lx.\n", hr);
25831 /* Initial draw to initialise states, compile shaders, etc. */
25832 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
25833 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
25834 hr = IDirect3DDevice9_BeginScene(device);
25835 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
25836 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, tri_count);
25837 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
25838 hr = IDirect3DDevice9_EndScene(device);
25839 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
25840 /* Read the result to ensure the GPU has finished drawing. */
25841 colour = getPixelColor(device, 320, 240);
25843 /* Time drawing tri_count triangles. */
25844 ret = QueryPerformanceCounter(&ts[0]);
25845 ok(ret, "Failed to read performance counter.\n");
25846 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
25847 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
25848 hr = IDirect3DDevice9_BeginScene(device);
25849 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
25850 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, tri_count);
25851 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
25852 hr = IDirect3DDevice9_EndScene(device);
25853 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
25854 colour = getPixelColor(device, 320, 240);
25855 /* Time drawing a single triangle. */
25856 ret = QueryPerformanceCounter(&ts[1]);
25857 ok(ret, "Failed to read performance counter.\n");
25858 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
25859 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
25860 hr = IDirect3DDevice9_BeginScene(device);
25861 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
25862 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 1);
25863 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
25864 hr = IDirect3DDevice9_EndScene(device);
25865 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
25866 colour = getPixelColor(device, 320, 240);
25867 ret = QueryPerformanceCounter(&ts[2]);
25868 ok(ret, "Failed to read performance counter.\n");
25870 IDirect3DVertexBuffer9_Release(buffer);
25872 /* Estimate the number of triangles we can draw in 100ms. */
25873 diff.QuadPart = ts[1].QuadPart - ts[0].QuadPart + ts[1].QuadPart - ts[2].QuadPart;
25874 tri_count = (tri_count * frequency.QuadPart) / (diff.QuadPart * 10);
25875 tri_count = ((tri_count + 2 + 3) & ~3) - 2;
25876 if (tri_count > caps.MaxPrimitiveCount)
25878 skip("Would need to draw %u triangles, but the device only supports %lu primitives.\n",
25879 tri_count, caps.MaxPrimitiveCount);
25880 goto done;
25882 size = (tri_count + 2) * sizeof(*quad1.strip);
25884 for (i = 0; i < ARRAY_SIZE(tests); ++i)
25886 hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
25887 D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &buffer, NULL);
25888 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#lx.\n", hr);
25889 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, size, (void **)&quads, D3DLOCK_DISCARD);
25890 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#lx.\n", hr);
25891 for (j = 0; j < size / sizeof(*quads); ++j)
25893 quads[j] = quad1;
25895 hr = IDirect3DVertexBuffer9_Unlock(buffer);
25896 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#lx.\n", hr);
25898 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(*quads->strip));
25899 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#lx.\n", hr);
25901 /* Start a draw operation. */
25902 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
25903 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
25904 hr = IDirect3DDevice9_BeginScene(device);
25905 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
25906 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, tri_count);
25907 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
25908 hr = IDirect3DDevice9_EndScene(device);
25909 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
25911 /* Map the last quad while the draw is in progress. */
25912 hr = IDirect3DVertexBuffer9_Lock(buffer, size - sizeof(quad2),
25913 sizeof(quad2), (void **)&quads, tests[i].flags);
25914 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#lx.\n", hr);
25915 *quads = quad2;
25916 hr = IDirect3DVertexBuffer9_Unlock(buffer);
25917 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#lx.\n", hr);
25919 colour = getPixelColor(device, 320, 240);
25920 unsynchronised = color_match(colour, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1);
25921 ok(tests[i].unsynchronised == unsynchronised, "Expected %s map for flags %#x.\n",
25922 tests[i].unsynchronised ? "unsynchronised" : "synchronised", tests[i].flags);
25924 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
25925 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
25927 IDirect3DVertexBuffer9_Release(buffer);
25930 done:
25931 refcount = IDirect3DDevice9_Release(device);
25932 ok(!refcount, "Device has %lu references left.\n", refcount);
25933 IDirect3D9_Release(d3d);
25934 DestroyWindow(window);
25937 static void test_color_vertex(void)
25939 IDirect3DDevice9 *device;
25940 unsigned int colour, i;
25941 D3DMATERIAL9 material;
25942 IDirect3D9 *d3d;
25943 ULONG refcount;
25944 HWND window;
25945 HRESULT hr;
25947 static const D3DVERTEXELEMENT9 decl_elements_missing_diffuse[] =
25949 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
25950 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
25951 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
25952 D3DDECL_END()
25955 static const D3DVERTEXELEMENT9 decl_elements_missing_specular[] =
25957 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
25958 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
25959 {2, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
25960 D3DDECL_END()
25963 static const D3DVERTEXELEMENT9 decl_elements_missing_both[] =
25965 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
25966 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
25967 {2, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
25968 D3DDECL_END()
25971 /* The idea here is to set up ambient light parameters in a way that the
25972 * ambient colour from the material is just passed through. The emissive
25973 * colour is just passed through anyway. The sum of ambient + emissive
25974 * should allow deduction of where the material colour came from.
25976 * Note that in cases without a D3DFVF_DIFFUSE flag the first colour value
25977 * in the struct will be fed into the specular vertex colour slot. */
25978 static const struct
25980 const D3DVERTEXELEMENT9 *decl_elements;
25981 DWORD fvf, color_vertex, ambient, emissive;
25982 unsigned int result;
25984 tests[] =
25986 {NULL, D3DFVF_DIFFUSE | D3DFVF_SPECULAR, FALSE, D3DMCS_COLOR1, D3DMCS_COLOR2, 0x000000c0},
25988 {NULL, D3DFVF_DIFFUSE | D3DFVF_SPECULAR, TRUE, D3DMCS_COLOR1, D3DMCS_COLOR2, 0x00ffff00},
25989 {NULL, D3DFVF_DIFFUSE | D3DFVF_SPECULAR, TRUE, D3DMCS_MATERIAL, D3DMCS_COLOR2, 0x0000ff80},
25990 {NULL, D3DFVF_DIFFUSE | D3DFVF_SPECULAR, TRUE, D3DMCS_COLOR1, D3DMCS_MATERIAL, 0x00ff0040},
25991 {NULL, D3DFVF_DIFFUSE | D3DFVF_SPECULAR, TRUE, D3DMCS_COLOR1, D3DMCS_COLOR1, 0x00ff0000},
25992 {NULL, D3DFVF_DIFFUSE | D3DFVF_SPECULAR, TRUE, D3DMCS_COLOR2, D3DMCS_COLOR2, 0x0000ff00},
25994 {NULL, D3DFVF_SPECULAR, TRUE, D3DMCS_COLOR1, D3DMCS_COLOR2, 0x00ff0080},
25995 {NULL, D3DFVF_SPECULAR, TRUE, D3DMCS_COLOR1, D3DMCS_MATERIAL, 0x000000c0},
25996 {NULL, D3DFVF_SPECULAR, TRUE, D3DMCS_MATERIAL, D3DMCS_COLOR2, 0x00ff0080},
25997 {NULL, D3DFVF_DIFFUSE, TRUE, D3DMCS_COLOR1, D3DMCS_COLOR2, 0x00ff0040},
25998 {NULL, D3DFVF_DIFFUSE, TRUE, D3DMCS_COLOR1, D3DMCS_MATERIAL, 0x00ff0040},
25999 {NULL, D3DFVF_DIFFUSE, TRUE, D3DMCS_COLOR2, D3DMCS_MATERIAL, 0x000000c0},
26001 {NULL, 0, TRUE, D3DMCS_COLOR1, D3DMCS_COLOR2, 0x000000c0},
26003 {decl_elements_missing_diffuse, 0, TRUE, D3DMCS_COLOR1, D3DMCS_COLOR2, 0x00ff0000},
26004 {decl_elements_missing_diffuse, 0, TRUE, D3DMCS_COLOR1, D3DMCS_MATERIAL, 0x00000040},
26005 {decl_elements_missing_diffuse, 0, TRUE, D3DMCS_MATERIAL, D3DMCS_COLOR2, 0x00ff0080},
26006 {decl_elements_missing_specular, 0, TRUE, D3DMCS_COLOR1, D3DMCS_COLOR2, 0x00ff0000},
26007 {decl_elements_missing_specular, 0, TRUE, D3DMCS_COLOR1, D3DMCS_MATERIAL, 0x00ff0040},
26008 {decl_elements_missing_specular, 0, TRUE, D3DMCS_MATERIAL, D3DMCS_COLOR2, 0x00000080},
26009 {decl_elements_missing_both, 0, TRUE, D3DMCS_COLOR1, D3DMCS_COLOR2, 0x00000000},
26012 static const struct
26014 struct vec3 position;
26015 DWORD diffuse;
26016 DWORD specular;
26018 quad[] =
26020 {{-1.0f, -1.0f, 0.0f}, 0xffff0000, 0xff00ff00},
26021 {{-1.0f, 1.0f, 0.0f}, 0xffff0000, 0xff00ff00},
26022 {{ 1.0f, -1.0f, 0.0f}, 0xffff0000, 0xff00ff00},
26023 {{ 1.0f, 1.0f, 0.0f}, 0xffff0000, 0xff00ff00},
26026 window = create_window();
26027 ok(!!window, "Failed to create a window.\n");
26029 d3d = Direct3DCreate9(D3D_SDK_VERSION);
26030 ok(!!d3d, "Failed to create a D3D object.\n");
26031 if (!(device = create_device(d3d, window, window, TRUE)))
26033 skip("Failed to create a D3D device, skipping tests.\n");
26034 IDirect3D9_Release(d3d);
26035 DestroyWindow(window);
26036 return;
26039 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
26040 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
26041 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_AMBIENT, 0xffffffff);
26042 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
26044 memset(&material, 0, sizeof(material));
26045 material.Ambient.b = 0.5f;
26046 material.Emissive.b = 0.25f;
26047 hr = IDirect3DDevice9_SetMaterial(device, &material);
26048 ok(SUCCEEDED(hr), "Failed to set material, hr %#lx\n", hr);
26050 for (i = 0; i < ARRAY_SIZE(tests); ++i)
26052 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORVERTEX, tests[i].color_vertex);
26053 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
26054 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_AMBIENTMATERIALSOURCE, tests[i].ambient);
26055 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
26056 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_EMISSIVEMATERIALSOURCE, tests[i].emissive);
26057 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
26059 if (tests[i].decl_elements)
26061 IDirect3DVertexDeclaration9 *vertex_declaration;
26063 hr = IDirect3DDevice9_CreateVertexDeclaration(device, tests[i].decl_elements, &vertex_declaration);
26064 ok(hr == S_OK, "Got hr %#lx.\n", hr);
26065 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
26066 ok(hr == S_OK, "Got hr %#lx.\n", hr);
26067 IDirect3DVertexDeclaration9_Release(vertex_declaration);
26069 else
26071 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | tests[i].fvf);
26072 ok(hr == S_OK, "Got hr %#lx.\n", hr);
26075 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x77777777, 0.0f, 0);
26076 ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#lx.\n", hr);
26078 hr = IDirect3DDevice9_BeginScene(device);
26079 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
26080 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
26081 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
26082 hr = IDirect3DDevice9_EndScene(device);
26083 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
26085 colour = getPixelColor(device, 320, 240);
26086 ok(color_match(colour, tests[i].result, 1),
26087 "Expected colour 0x%08x for test %u, got 0x%08x.\n",
26088 tests[i].result, i, colour);
26091 refcount = IDirect3DDevice9_Release(device);
26092 ok(!refcount, "Device has %lu references left.\n", refcount);
26093 IDirect3D9_Release(d3d);
26094 DestroyWindow(window);
26097 static void test_sysmem_draw(void)
26099 IDirect3DVertexBuffer9 *vb, *vb_s0, *vb_s1, *dst_vb, *get_vb;
26100 IDirect3DVertexDeclaration9 *vertex_declaration;
26101 unsigned int colour, i, offset, stride;
26102 IDirect3DTexture9 *texture;
26103 IDirect3DIndexBuffer9 *ib;
26104 IDirect3DDevice9 *device;
26105 struct vec4 *dst_data;
26106 D3DLOCKED_RECT lr;
26107 IDirect3D9 *d3d;
26108 ULONG refcount;
26109 HWND window;
26110 HRESULT hr;
26111 BYTE *data;
26113 static const DWORD texture_data[4] = {0xffff0000, 0xff00ff00, 0xff0000ff, 0xffffffff};
26114 static const D3DVERTEXELEMENT9 decl_elements[] =
26116 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
26117 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
26118 D3DDECL_END()
26120 static const struct
26122 struct vec3 position;
26123 DWORD diffuse;
26125 quad[] =
26127 {{-0.5f, -0.5f, 0.0f}, 0xffff0000},
26128 {{-0.5f, 0.5f, 0.0f}, 0xff00ff00},
26129 {{ 0.5f, -0.5f, 0.0f}, 0xff0000ff},
26130 {{ 0.5f, 0.5f, 0.0f}, 0xffffffff},
26132 static const struct vec3 quad_s0[] =
26134 {-1.0f, -1.0f, 0.0f},
26135 {-1.0f, 1.0f, 0.0f},
26136 { 1.0f, -1.0f, 0.0f},
26137 { 1.0f, 1.0f, 0.0f},
26139 {-1.0f, -1.0f, 0.0f},
26140 {-1.0f, 1.0f, 0.0f},
26141 { 1.0f, -1.0f, 0.0f},
26142 { 1.0f, 1.0f, 0.0f},
26144 static const DWORD quad_s1[] =
26146 0xffff0000,
26147 0xff00ff00,
26148 0xff0000ff,
26149 0xffffffff,
26151 0xff443322,
26152 0xff443322,
26153 0xff443322,
26154 0xff443322,
26156 static const short indices[] = {5, 6, 7, 8, 0, 1, 2, 3};
26158 window = create_window();
26159 ok(!!window, "Failed to create a window.\n");
26161 d3d = Direct3DCreate9(D3D_SDK_VERSION);
26162 ok(!!d3d, "Failed to create a D3D object.\n");
26163 if (!(device = create_device(d3d, window, window, TRUE)))
26165 skip("Failed to create a D3D device, skipping tests.\n");
26166 IDirect3D9_Release(d3d);
26167 DestroyWindow(window);
26168 return;
26171 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
26172 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26174 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_SYSTEMMEM, &vb, NULL);
26175 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26176 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **)&data, 0);
26177 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26178 memcpy(data, quad, sizeof(quad));
26179 hr = IDirect3DVertexBuffer9_Unlock(vb);
26180 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26182 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x77777777, 0.0f, 0);
26183 ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#lx.\n", hr);
26185 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
26186 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26187 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(*quad));
26188 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26190 hr = IDirect3DDevice9_BeginScene(device);
26191 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26192 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
26193 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26194 hr = IDirect3DDevice9_EndScene(device);
26195 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26197 colour = getPixelColor(device, 320, 240);
26198 ok(color_match(colour, 0x00007f7f, 1), "Got unexpected colour 0x%08x.\n", colour);
26200 hr = IDirect3DDevice9_CreateVertexBuffer(device, ARRAY_SIZE(quad) * sizeof(*dst_data),
26201 0, D3DFVF_XYZRHW, D3DPOOL_SYSTEMMEM, &dst_vb, NULL);
26202 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26203 hr = IDirect3DDevice9_ProcessVertices(device, 0, 0, ARRAY_SIZE(quad), dst_vb, NULL, 0);
26204 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26205 hr = IDirect3DVertexBuffer9_Lock(dst_vb, 0, 0, (void **)&dst_data, 0);
26206 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26207 for (i = 0; i < ARRAY_SIZE(quad); ++i)
26209 ok(compare_vec4(&dst_data[i], quad[i].position.x * 320.0f + 320.0f,
26210 -quad[i].position.y * 240.0f + 240.0f, 0.0f, 1.0f, 1),
26211 "Got unexpected vertex %u {%.8e, %.8e, %.8e, %.8e}.\n",
26212 i, dst_data[i].x, dst_data[i].y, dst_data[i].z, dst_data[i].w);
26214 hr = IDirect3DVertexBuffer9_Unlock(dst_vb);
26215 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26217 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0,
26218 D3DFMT_INDEX16, D3DPOOL_SYSTEMMEM, &ib, NULL);
26219 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26220 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **)&data, 0);
26221 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26222 memcpy(data, indices, sizeof(indices));
26223 hr = IDirect3DIndexBuffer9_Unlock(ib);
26224 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26226 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x77777777, 0.0f, 0);
26227 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26229 hr = IDirect3DDevice9_SetIndices(device, ib);
26230 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26232 hr = IDirect3DDevice9_BeginScene(device);
26233 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26234 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 0, 4, 4, 2);
26235 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26236 hr = IDirect3DDevice9_EndScene(device);
26237 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26239 colour = getPixelColor(device, 320, 240);
26240 ok(color_match(colour, 0x00007f7f, 1), "Got unexpected colour 0x%08x.\n", colour);
26242 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
26243 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26244 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
26245 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26247 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_s0), 0, 0, D3DPOOL_SYSTEMMEM, &vb_s0, NULL);
26248 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26249 hr = IDirect3DVertexBuffer9_Lock(vb_s0, 0, sizeof(quad_s0), (void **)&data, 0);
26250 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26251 memcpy(data, quad_s0, sizeof(quad_s0));
26252 hr = IDirect3DVertexBuffer9_Unlock(vb_s0);
26253 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26254 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_s1), 0, 0, D3DPOOL_SYSTEMMEM, &vb_s1, NULL);
26255 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26256 hr = IDirect3DVertexBuffer9_Lock(vb_s1, 0, sizeof(quad_s1), (void **)&data, 0);
26257 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26258 memcpy(data, quad_s1, sizeof(quad_s1));
26259 hr = IDirect3DVertexBuffer9_Unlock(vb_s1);
26260 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26262 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_s0, 0, sizeof(*quad_s0));
26263 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26264 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb_s1, 0, sizeof(*quad_s1));
26265 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26267 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x77777777, 0.0f, 0);
26268 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26270 hr = IDirect3DDevice9_BeginScene(device);
26271 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26272 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 0, 4, 4, 2);
26273 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26274 hr = IDirect3DDevice9_EndScene(device);
26275 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26277 colour = getPixelColor(device, 320, 240);
26278 ok(color_match(colour, 0x00007f7f, 1), "Got unexpected colour 0x%08x.\n", colour);
26280 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x77777777, 0.0f, 0);
26281 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26283 hr = IDirect3DDevice9_BeginScene(device);
26284 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26285 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 0, 5, 4, 2);
26286 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26287 hr = IDirect3DDevice9_EndScene(device);
26288 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26290 colour = getPixelColor(device, 320, 240);
26291 ok(color_match(colour, 0x00443322, 1), "Got unexpected colour 0x%08x.\n", colour);
26293 /* Test that releasing but not unbinding a vertex buffer doesn't break. */
26294 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
26295 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26296 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(*quad));
26297 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26298 hr = IDirect3DDevice9_SetIndices(device, ib);
26299 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26301 refcount = IDirect3DVertexBuffer9_Release(vb_s1);
26302 ok(!refcount, "Unexpected refcount %lu.\n", refcount);
26303 hr = IDirect3DDevice9_GetStreamSource(device, 1, &get_vb, &offset, &stride);
26304 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
26305 ok(get_vb == vb_s1, "Got unexpected vertex buffer %p.\n", get_vb);
26306 refcount = IDirect3DVertexBuffer9_Release(get_vb);
26307 ok(!refcount, "Unexpected refcount %lu.\n", refcount);
26309 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x77777777, 0.0f, 0);
26310 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26312 hr = IDirect3DDevice9_BeginScene(device);
26313 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26314 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 0, 4, 4, 2);
26315 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26316 hr = IDirect3DDevice9_EndScene(device);
26317 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26319 colour = getPixelColor(device, 320, 240);
26320 ok(color_match(colour, 0x00007f7f, 1), "Got unexpected colour 0x%08x.\n", colour);
26322 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
26323 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26324 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_s0, 0, sizeof(*quad_s0));
26325 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26327 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x77777777, 0.0f, 0);
26328 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26330 hr = IDirect3DDevice9_BeginScene(device);
26331 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26332 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 0, 4, 4, 2);
26333 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26334 hr = IDirect3DDevice9_EndScene(device);
26335 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26337 colour = getPixelColor(device, 320, 240);
26338 ok(color_match(colour, 0x00007f7f, 1), "Got unexpected colour 0x%08x.\n", colour);
26340 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &texture, NULL);
26341 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26342 memset(&lr, 0, sizeof(lr));
26343 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
26344 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26345 memcpy(lr.pBits, texture_data, sizeof(texture_data));
26346 hr = IDirect3DTexture9_UnlockRect(texture, 0);
26347 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26349 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
26350 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26352 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x77777777, 0.0f, 0);
26353 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26355 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
26356 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26358 hr = IDirect3DDevice9_BeginScene(device);
26359 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26360 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
26361 ok(hr == D3D_OK || hr == E_FAIL, "Got unexpected hr %#lx.\n", hr);
26362 hr = IDirect3DDevice9_EndScene(device);
26363 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26365 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
26366 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26368 IDirect3DTexture9_Release(texture);
26369 IDirect3DVertexBuffer9_Release(vb_s0);
26370 IDirect3DVertexDeclaration9_Release(vertex_declaration);
26371 IDirect3DIndexBuffer9_Release(ib);
26372 IDirect3DVertexBuffer9_Release(dst_vb);
26373 IDirect3DVertexBuffer9_Release(vb);
26374 refcount = IDirect3DDevice9_Release(device);
26375 ok(!refcount, "Device has %lu references left.\n", refcount);
26376 IDirect3D9_Release(d3d);
26377 DestroyWindow(window);
26380 static void test_nrm_instruction(void)
26382 IDirect3DVertexDeclaration9 *vertex_declaration;
26383 IDirect3DVertexShader9 *vertex_shader;
26384 IDirect3DPixelShader9 *pixel_shader;
26385 unsigned int body_size, colour, i;
26386 IDirect3DDevice9 *device;
26387 IDirect3D9 *d3d;
26388 DWORD *ps_code;
26389 ULONG refcount;
26390 D3DCAPS9 caps;
26391 HWND window;
26392 HRESULT hr;
26394 static const D3DVERTEXELEMENT9 decl_elements[] =
26396 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
26397 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
26398 {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
26399 D3DDECL_END()
26401 static const struct
26403 struct vec3 position;
26404 struct vec2 t0;
26405 struct vec4 t1;
26407 quad[] =
26409 {{-1.0f, -1.0f, 0.1f}, {1.0f, 1.0f}, {0.0f, 1.0f, 0.3f, 0.5f}},
26410 {{ 1.0f, -1.0f, 0.1f}, {1.0f, 1.0f}, {0.0f, 1.0f, 0.3f, 0.5f}},
26411 {{-1.0f, 1.0f, 0.1f}, {1.0f, 1.0f}, {0.0f, 1.0f, 0.3f, 0.5f}},
26412 {{ 1.0f, 1.0f, 0.1f}, {1.0f, 1.0f}, {0.0f, 1.0f, 0.3f, 0.5f}},
26415 static const DWORD vs_code[] =
26417 0xfffe0300, /* vs_3_0 */
26418 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
26419 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
26420 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
26421 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
26422 0x0200001f, 0x80000005, 0xe00f0001, /* dcl_texcoord0 o1 */
26423 0x0200001f, 0x80010005, 0xe00f0002, /* dcl_texcoord1 o2 */
26424 0x0200001f, 0x80020005, 0xe00f0003, /* dcl_texcoord2 o3 */
26425 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
26426 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
26427 0x02000001, 0xe00f0002, 0x90e40002, /* mov o2, v2 */
26428 0x02000024, 0x800f0000, 0x90e40002, /* nrm r0, v2 */
26429 0x02000001, 0xe00f0003, 0x80e40000, /* mov o3, r0 */
26430 0x0000ffff,
26432 static const DWORD ps_header[] =
26434 0xffff0300, /* ps_3_0 */
26436 static const DWORD ps_footer[] =
26438 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
26439 0x0000ffff, /* end */
26441 static const DWORD nrm_t0[] =
26443 0x0200001f, 0x80000005, 0x90070001, /* dcl_texcoord0 v0.xyz */
26444 0x02000024, 0x800f0000, 0x90e40001, /* nrm r0, v0 */
26446 static const DWORD nrm_xyz_t0[] =
26448 0x0200001f, 0x80000005, 0x90070000, /* dcl_texcoord0 v0.xyz */
26449 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
26450 0x02000024, 0x80070000, 0x90e40000, /* nrm r0.xyz, v0 */
26451 0x02000001, 0x80040000, 0x80ff0000, /* mov r0.z, r0.w */
26453 static const DWORD nrm_t1[] =
26455 0x0200001f, 0x80010005, 0x900f0000, /* dcl_texcoord1 v0.xyzw */
26456 0x02000024, 0x800f0000, 0x90e40000, /* nrm r0, v0 */
26458 static const DWORD nrm_vs_t1[] =
26460 0x0200001f, 0x80020005, 0x900f0000, /* dcl_texcoord2 v0.xyzw */
26461 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
26463 static const DWORD nrm_t1_xyz[] =
26465 0x0200001f, 0x80010005, 0x900f0000, /* dcl_texcoord1 v0.xyzw */
26466 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
26467 0x02000024, 0x80070000, 0x90e40000, /* nrm r0.xyz, t1 */
26468 0x02000001, 0x80040000, 0x80ff0000, /* mov r0.z, r0.w */
26470 static const DWORD nrm_t1_xy[] =
26472 0x0200001f, 0x80010005, 0x900f0000, /* dcl_texcoord1 v0.xyzw */
26473 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
26474 0x02000024, 0x800f0000, 0x90540000, /* nrm r0, v0.xy */
26476 static const DWORD nrm_xyz_t1_yw[] =
26478 0x0200001f, 0x80010005, 0x900f0000, /* dcl_texcoord1 v0.xyzw */
26479 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
26480 0x02000024, 0x80070000, 0x90fd0000, /* nrm r0.xyz, v0.yw */
26482 static const DWORD nrm_t1_dcl_xy[] =
26484 0x0200001f, 0x80010005, 0x90030000, /* dcl_texcoord1 v0.xy */
26485 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
26486 0x02000024, 0x800f0000, 0x90540000, /* nrm r0, v0 */
26488 static const DWORD nrm_c0[] =
26490 0x02000024, 0x800f0000, 0xa0e40000, /* nrm r0, c0 */
26491 0x02000001, 0x80040000, 0x80ff0000, /* mov r0.z, r0.w */
26493 static const DWORD nrm_c0_swizzle[] =
26495 0x02000024, 0x800f0000, 0xa0390000, /* nrm r0, c0.yzwx */
26498 static const struct
26500 const char *name;
26501 const DWORD *ops;
26502 DWORD body_size;
26503 struct vec4 c0;
26504 unsigned int expected_colour;
26506 tests[] =
26508 {"nrm_t0", nrm_t0, ARRAY_SIZE(nrm_t0), {0.0f}, 0x00b4b400},
26509 {"nrm_xyz_t0", nrm_xyz_t0, ARRAY_SIZE(nrm_xyz_t0), {0.1f, 0.1f, 0.1f, 0.1f}, 0x00b4b419},
26510 {"nrm_t1", nrm_t1, ARRAY_SIZE(nrm_t1), {0.0f}, 0x0000f449},
26511 {"nrm_vs_t1", nrm_vs_t1, ARRAY_SIZE(nrm_vs_t1), {0.0f}, 0x0000f449},
26512 {"nrm_t1_xyz", nrm_t1_xyz, ARRAY_SIZE(nrm_t1_xyz), {0.1f, 0.1f, 0.1f, 0.1f}, 0x0000f419},
26513 {"nrm_t1_xy", nrm_t1_xy, ARRAY_SIZE(nrm_t1_xy), {0.1f, 0.1f, 0.1f, 0.1f}, 0x0000b4b4},
26514 {"nrm_xyz_t1_yw", nrm_xyz_t1_yw, ARRAY_SIZE(nrm_xyz_t1_yw), {0.1f, 0.1f, 0.1f, 0.1f}, 0x00d06868},
26515 {"nrm_t1_dcl_xy", nrm_t1_dcl_xy, ARRAY_SIZE(nrm_t1_dcl_xy), {0.1f, 0.1f, 0.1f, 0.1f}, 0x0000b4b4},
26516 {"nrm_vec4(0.0, 0.0, 0.0, 0.0)", nrm_c0, ARRAY_SIZE(nrm_c0), {0.0f, 0.0f, 0.0f, 0.0f}, 0x00000000},
26517 {"nrm_vec4(2.0, 0.0, 0.0, 0.5)", nrm_c0, ARRAY_SIZE(nrm_c0), {2.0f, 0.0f, 0.0f, 0.5f}, 0x00ff0040},
26518 {"nrm_vec4(1.0)", nrm_c0, ARRAY_SIZE(nrm_c0), {1.0f, 1.0f, 1.0f, 1.0f}, 0x00939393},
26519 {"nrm_c0_swizzle", nrm_c0_swizzle, ARRAY_SIZE(nrm_c0_swizzle), {1.0f, 1.0f, 0.0f, 2.0f}, 0x007200e4},
26522 window = create_window();
26523 ok(!!window, "Failed to create a window.\n");
26525 d3d = Direct3DCreate9(D3D_SDK_VERSION);
26526 ok(!!d3d, "Failed to create a D3D object.\n");
26527 if (!(device = create_device(d3d, window, window, TRUE)))
26529 skip("Failed to create a D3D device, skipping tests.\n");
26530 IDirect3D9_Release(d3d);
26531 DestroyWindow(window);
26532 return;
26535 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
26536 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26537 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
26539 skip("No shader model 3 support, skipping tests.\n");
26540 IDirect3DDevice9_Release(device);
26541 IDirect3D9_Release(d3d);
26542 DestroyWindow(window);
26543 return;
26546 body_size = 0;
26547 for (i = 0; i < ARRAY_SIZE(tests); ++i)
26548 body_size = max(body_size, tests[i].body_size);
26550 ps_code = malloc(sizeof(ps_header) + body_size * sizeof(*ps_code) + sizeof(ps_footer));
26551 memcpy(ps_code, ps_header, sizeof(ps_header));
26553 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
26554 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26555 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
26556 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26557 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
26558 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26559 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vertex_shader);
26560 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26561 hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader);
26562 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26563 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
26564 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26566 for (i = 0; i < ARRAY_SIZE(tests); ++i)
26568 memcpy(ps_code + ARRAY_SIZE(ps_header), tests[i].ops, sizeof(*ps_code) * tests[i].body_size);
26569 memcpy(ps_code + ARRAY_SIZE(ps_header) + tests[i].body_size, ps_footer, sizeof(ps_footer));
26571 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &pixel_shader);
26572 ok(hr == D3D_OK, "Got unexpected hr %#lx, test %s.\n", hr, tests[i].name);
26573 hr = IDirect3DDevice9_BeginScene(device);
26574 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26575 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80808080, 0.0f, 0);
26576 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26577 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
26578 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26579 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, &tests[i].c0.x, 1);
26580 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26581 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
26582 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26583 hr = IDirect3DDevice9_EndScene(device);
26584 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26586 colour = getPixelColor(device, 320, 240);
26587 ok(color_match(colour, tests[i].expected_colour, 1),
26588 "test %s, expected 0x%08x, got 0x%08x.\n",
26589 tests[i].name, tests[i].expected_colour, colour);
26591 IDirect3DPixelShader9_Release(pixel_shader);
26593 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
26594 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26596 free(ps_code);
26597 IDirect3DVertexShader9_Release(vertex_shader);
26598 IDirect3DVertexDeclaration9_Release(vertex_declaration);
26599 refcount = IDirect3DDevice9_Release(device);
26600 ok(!refcount, "Device has %lu references left.\n", refcount);
26601 IDirect3D9_Release(d3d);
26602 DestroyWindow(window);
26605 static void test_desktop_window(void)
26607 IDirect3DVertexShader9 *shader;
26608 IDirect3DTexture9 *texture;
26609 IDirect3DDevice9 *device;
26610 unsigned int color;
26611 IDirect3D9 *d3d;
26612 ULONG refcount;
26613 D3DCAPS9 caps;
26614 HWND window;
26615 HRESULT hr;
26617 static const DWORD simple_vs[] =
26619 0xfffe0101, /* vs_1_1 */
26620 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
26621 0x00000009, 0xc0010000, 0x90e40000, 0xa0e40000, /* dp4 oPos.x, v0, c0 */
26622 0x00000009, 0xc0020000, 0x90e40000, 0xa0e40001, /* dp4 oPos.y, v0, c1 */
26623 0x00000009, 0xc0040000, 0x90e40000, 0xa0e40002, /* dp4 oPos.z, v0, c2 */
26624 0x00000009, 0xc0080000, 0x90e40000, 0xa0e40003, /* dp4 oPos.w, v0, c3 */
26625 0x0000ffff, /* end */
26628 window = create_window();
26629 d3d = Direct3DCreate9(D3D_SDK_VERSION);
26630 ok(!!d3d, "Failed to create a D3D object.\n");
26631 if (!(device = create_device(d3d, window, window, TRUE)))
26633 skip("Failed to create a D3D device, skipping tests.\n");
26634 IDirect3D9_Release(d3d);
26635 DestroyWindow(window);
26636 return;
26638 IDirect3DDevice9_Release(device);
26639 DestroyWindow(window);
26641 device = create_device(d3d, GetDesktopWindow(), GetDesktopWindow(), TRUE);
26642 ok(!!device, "Failed to create a D3D device.\n");
26644 if (device)
26646 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
26647 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
26648 color = getPixelColor(device, 1, 1);
26649 ok(color == 0x00ff0000, "Got unexpected color 0x%08x.\n", color);
26651 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
26652 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
26654 refcount = IDirect3DDevice9_Release(device);
26655 ok(!refcount, "Device has %lu references left.\n", refcount);
26657 else
26659 skip("Failed to create a D3D device for the desktop window, skipping tests.\n");
26662 /* test device with NULL HWND */
26663 device = create_device(d3d, NULL, NULL, TRUE);
26664 ok(device != NULL, "Failed to create a D3D device\n");
26666 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &texture, NULL);
26667 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26668 IDirect3DTexture9_Release(texture);
26670 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
26671 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
26672 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
26674 hr = IDirect3DDevice9_CreateVertexShader(device, simple_vs, &shader);
26675 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#lx.\n", hr);
26676 IDirect3DVertexShader9_Release(shader);
26678 else
26680 skip("Vertex shaders not supported.\n");
26683 IDirect3DDevice9_Release(device);
26685 IDirect3D9_Release(d3d);
26688 static void test_mismatched_sample_types_fill_texture(DWORD *bits, unsigned int pitch, D3DCOLOR colour,
26689 unsigned int size)
26691 unsigned int x, y;
26693 for (y = 0; y < size; ++y)
26695 DWORD *ptr = (DWORD *)(((BYTE *)bits) + (y * pitch));
26697 for (x = 0; x < size; ++x)
26698 *ptr++ = colour;
26702 static void test_mismatched_sample_types(void)
26704 /* MSDN suggests that sampling a texture with fewer dimensions than sampler has
26705 * is allowed while the opposite is not.
26706 * AMD, Intel, WARP return sampled texture values in both cases. The use of W
26707 * coordinate when sampling 3d texture with 2d sampler looks not entirely consistent.
26708 * Nvidia returns zero texture values for both cases while that is different
26709 * from unbound texture result (0, 0, 0, 1): it is (0, 0, 0, 0) for RGBA texture or,
26710 * in a general case, result of a fixup of zero texture color, e. g., (0, 0, 1, 1)
26711 * for D3DFMT_G16R16 texture. */
26713 IDirect3DVertexDeclaration9 *vertex_declaration;
26714 static IDirect3DPixelShader9 *ps_2d, *ps_3d;
26715 static IDirect3DVolumeTexture9 *volume;
26716 IDirect3DVertexShader9 *vertex_shader;
26717 static IDirect3DTexture9 *tex_2d;
26718 unsigned int colour, i, r, g, b;
26719 D3DLOCKED_RECT locked_rect;
26720 D3DLOCKED_BOX locked_box;
26721 IDirect3DDevice9 *device;
26722 IDirect3D9 *d3d;
26723 ULONG refcount;
26724 D3DCAPS9 caps;
26725 HWND window;
26726 HRESULT hr;
26728 static const D3DVERTEXELEMENT9 decl_elements[] =
26730 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
26731 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
26732 D3DDECL_END()
26734 static const struct
26736 struct vec3 position;
26737 struct vec3 t0;
26739 quad[] =
26741 {{-1.0f, -1.0f, 0.1f}, {0.0f, 0.0f, 0.0f}},
26742 {{-1.0f, 1.0f, 0.1f}, {0.0f, 1.0f, 0.5f}},
26743 {{ 1.0f, -1.0f, 0.1f}, {1.0f, 0.0f, 0.5f}},
26744 {{ 1.0f, 1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}},
26747 static const DWORD vs_code[] =
26749 0xfffe0300, /* vs_3_0 */
26750 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
26751 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
26752 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
26753 0x0200001f, 0x80000005, 0xe00f0001, /* dcl_texcoord0 o1 */
26754 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
26755 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
26756 0x0000ffff, /* end */
26759 static const DWORD ps_header[] =
26761 0xffff0300, /* ps_3_0 */
26762 0x05000051, 0xa00f0000, 0x3f333333, 0x3f4ccccd, 0x3f666666, 0x00000000,
26763 /* def c0, 0.7, 0.8, 0.9, 0.0 */
26765 static const DWORD ps_footer[] =
26767 0x03000042, 0x800f0001, 0x90e40000, 0xa0e40800, /* texld r1, v0, s0 */
26768 0x02020029, 0x80ff0001, 0xa0ff0000, /* if_eq r1.w, c0.w */
26769 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
26770 0x0000002b, /* endif */
26771 0x02000001, 0x800f0800, 0x80e40001, /* mov oC0, r1 */
26772 0x0000ffff, /* end */
26775 #define TEST_MISMATCHED_SAMPLE_BODY_WORDS 6
26777 static const DWORD ps_tex_2d[TEST_MISMATCHED_SAMPLE_BODY_WORDS] =
26779 0x0200001f, 0x80000005, 0x90030000, /* dcl_texcoord0 v0.xy */
26780 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
26782 static const DWORD ps_tex_3d[TEST_MISMATCHED_SAMPLE_BODY_WORDS] =
26784 0x0200001f, 0x80000005, 0x90070000, /* dcl_texcoord0 v0.xyz */
26785 0x0200001f, 0xa0000000, 0xa00f0800, /* dcl_volume s0 */
26788 static DWORD ps_code[ARRAY_SIZE(ps_header) + TEST_MISMATCHED_SAMPLE_BODY_WORDS + ARRAY_SIZE(ps_footer)];
26790 #define SAMPLE_ZERO 0x1
26791 #define RANDOM_W 0x2
26792 static const struct
26794 const char *name;
26795 IDirect3DBaseTexture9 **texture;
26796 IDirect3DPixelShader9 **pixel_shader;
26797 unsigned int expected_colour;
26798 unsigned int broken;
26800 tests[] =
26802 {"2d_2d", (IDirect3DBaseTexture9 **)&tex_2d, &ps_2d, 0x00707070},
26803 {"3d_3d", (IDirect3DBaseTexture9 **)&volume, &ps_3d, 0x00303030},
26804 /* Star Wars: The Old Republic uses mismatched samplers for rendering water. */
26805 {"2d_3d", (IDirect3DBaseTexture9 **)&tex_2d, &ps_3d, 0x00707070, SAMPLE_ZERO},
26806 {"3d_2d", (IDirect3DBaseTexture9 **)&volume, &ps_2d, 0x00303030, SAMPLE_ZERO | RANDOM_W},
26809 window = create_window();
26810 ok(!!window, "Failed to create a window.\n");
26812 d3d = Direct3DCreate9(D3D_SDK_VERSION);
26813 ok(!!d3d, "Failed to create a D3D object.\n");
26814 if (!(device = create_device(d3d, window, window, TRUE)))
26816 skip("Failed to create a D3D device, skipping tests.\n");
26817 IDirect3D9_Release(d3d);
26818 DestroyWindow(window);
26819 return;
26822 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
26823 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26824 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
26826 skip("No shader model 3 support, skipping tests.\n");
26827 goto done;
26829 if (!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP))
26831 skip("No volume texture support, skipping tests.\n");
26832 goto done;
26835 hr = IDirect3DDevice9_CreateVolumeTexture(device, 2, 2, 2, 1, 0, D3DFMT_A8R8G8B8,
26836 D3DPOOL_MANAGED, &volume, NULL);
26837 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26839 hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &locked_box, NULL, 0);
26840 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26841 test_mismatched_sample_types_fill_texture(locked_box.pBits, locked_box.RowPitch, 0x20202020, 2);
26842 test_mismatched_sample_types_fill_texture((DWORD *)((BYTE *)locked_box.pBits + locked_box.SlicePitch),
26843 locked_box.RowPitch, 0x40404040, 2);
26844 hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
26845 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26847 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8,
26848 D3DPOOL_MANAGED, &tex_2d, NULL);
26849 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26851 hr = IDirect3DTexture9_LockRect(tex_2d, 0, &locked_rect, NULL, 0);
26852 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26853 test_mismatched_sample_types_fill_texture(locked_rect.pBits, locked_rect.Pitch, 0x70707070, 2);
26854 hr = IDirect3DTexture9_UnlockRect(tex_2d, 0);
26855 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26857 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
26858 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26859 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
26860 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26861 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
26862 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26863 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vertex_shader);
26864 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26865 hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader);
26866 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26868 memcpy(ps_code, ps_header, sizeof(ps_header));
26869 memcpy(ps_code + ARRAY_SIZE(ps_header) + TEST_MISMATCHED_SAMPLE_BODY_WORDS, ps_footer, sizeof(ps_footer));
26871 memcpy(ps_code + ARRAY_SIZE(ps_header), ps_tex_2d,
26872 sizeof(*ps_code) * TEST_MISMATCHED_SAMPLE_BODY_WORDS);
26873 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps_2d);
26874 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26876 memcpy(ps_code + ARRAY_SIZE(ps_header), ps_tex_3d,
26877 sizeof(*ps_code) * TEST_MISMATCHED_SAMPLE_BODY_WORDS);
26878 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps_3d);
26879 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26881 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
26882 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26884 for (i = 0; i < ARRAY_SIZE(tests); ++i)
26886 hr = IDirect3DDevice9_BeginScene(device);
26887 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26888 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80808080, 0.0f, 0);
26889 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26891 hr = IDirect3DDevice9_SetTexture(device, 0, *tests[i].texture);
26892 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26893 hr = IDirect3DDevice9_SetPixelShader(device, *tests[i].pixel_shader);
26894 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26896 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
26897 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26898 hr = IDirect3DDevice9_EndScene(device);
26899 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26901 colour = getPixelColor(device, 320, 240);
26903 /* If texld returns zero, the test writes vec4(0.7, 0.8, 0.9, 0.0) - 0x00b2cce5.
26905 * When sampling the 3D texture with a 2D sampler, most drivers sample at the depth
26906 * coordinate we provide (0.5), but some use 0.0, while my radeon GPU uses 0.89. */
26907 r = (colour & 0x00ff0000) >> 16;
26908 g = (colour & 0x0000ff00) >> 8;
26909 b = (colour & 0x000000ff);
26910 todo_wine_if(!color_match(colour, tests[i].expected_colour, 1))
26911 ok(color_match(colour, tests[i].expected_colour, 1)
26912 || broken((tests[i].broken & SAMPLE_ZERO) && color_match(colour, 0x00b2cce5, 1))
26913 || broken((tests[i].broken & RANDOM_W) && r >= 0x1f && r <= 0x41 && r == g && r == b),
26914 "test %s, expected 0x%08x, got 0x%08x.\n",
26915 tests[i].name, tests[i].expected_colour, colour);
26917 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
26918 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26920 IDirect3DPixelShader9_Release(ps_2d);
26921 IDirect3DPixelShader9_Release(ps_3d);
26923 IDirect3DVertexShader9_Release(vertex_shader);
26924 IDirect3DVertexDeclaration9_Release(vertex_declaration);
26925 IDirect3DVolumeTexture9_Release(volume);
26926 IDirect3DTexture9_Release(tex_2d);
26928 done:
26929 refcount = IDirect3DDevice9_Release(device);
26930 ok(!refcount, "Device has %lu references left.\n", refcount);
26931 IDirect3D9_Release(d3d);
26932 DestroyWindow(window);
26934 #undef SAMPLE_ZERO
26935 #undef RANDOM_W
26938 static void test_draw_mapped_buffer(void)
26940 IDirect3DVertexBuffer9 *vb;
26941 IDirect3DIndexBuffer9 *ib;
26942 IDirect3DDevice9 *device;
26943 unsigned int color, i;
26944 IDirect3D9 *d3d;
26945 ULONG refcount;
26946 HWND window;
26947 HRESULT hr;
26948 void *data;
26950 static const short indices[] = {0, 1, 2};
26951 static const struct
26953 struct vec3 position;
26954 DWORD diffuse;
26956 quad[] =
26958 {{-1.0f, -1.0f, 0.1f}, 0xffff0000},
26959 {{-1.0f, 1.0f, 0.1f}, 0xffff0000},
26960 {{ 1.0f, 1.0f, 0.1f}, 0xffff0000},
26962 static const struct
26964 D3DPOOL pool;
26965 DWORD usage;
26967 tests[] =
26969 {D3DPOOL_DEFAULT, D3DUSAGE_DYNAMIC},
26970 {D3DPOOL_MANAGED, 0},
26971 {D3DPOOL_SYSTEMMEM, 0},
26974 window = create_window();
26975 ok(!!window, "Failed to create a window.\n");
26977 d3d = Direct3DCreate9(D3D_SDK_VERSION);
26978 ok(!!d3d, "Failed to create a D3D object.\n");
26979 if (!(device = create_device(d3d, window, window, TRUE)))
26981 skip("Failed to create a D3D device, skipping tests.\n");
26982 IDirect3D9_Release(d3d);
26983 DestroyWindow(window);
26984 return;
26987 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
26988 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26989 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
26990 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26992 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0,
26993 D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
26994 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26995 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), &data, 0);
26996 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26997 memcpy(data, indices, sizeof(indices));
26999 hr = IDirect3DDevice9_SetIndices(device, ib);
27000 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27002 for (i = 0; i < ARRAY_SIZE(tests); ++i)
27004 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), tests[i].usage,
27005 D3DFVF_XYZ | D3DFVF_DIFFUSE, tests[i].pool, &vb, NULL);
27006 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27007 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), &data, 0);
27008 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27009 memcpy(data, quad, sizeof(quad));
27011 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
27012 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27014 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
27015 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27016 hr = IDirect3DDevice9_BeginScene(device);
27017 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27018 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, ARRAY_SIZE(quad), 0, 1);
27019 ok(hr == D3D_OK, "Got unexpected hr %#lx, test %u.\n", hr, i);
27020 hr = IDirect3DDevice9_EndScene(device);
27021 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27023 color = getPixelColor(device, 160, 120);
27024 ok(color_match(color, 0x00ff0000, 1), "Got unexpected color 0x%08x, test %u.\n", color, i);
27025 color = getPixelColor(device, 480, 360);
27026 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x, test %u.\n", color, i);
27028 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
27029 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27031 hr = IDirect3DVertexBuffer9_Unlock(vb);
27032 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27034 /* One more time now when buffer object in wined3d is already created. */
27035 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), &data, D3DLOCK_DISCARD);
27036 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27037 memcpy(data, quad, sizeof(quad));
27039 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
27040 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27041 hr = IDirect3DDevice9_BeginScene(device);
27042 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27043 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, ARRAY_SIZE(quad), 0, 1);
27044 ok(hr == D3D_OK, "Got unexpected hr %#lx, test %u.\n", hr, i);
27045 hr = IDirect3DDevice9_EndScene(device);
27046 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27048 color = getPixelColor(device, 160, 120);
27049 ok(color_match(color, 0x00ff0000, 1), "Got unexpected color 0x%08x, test %u.\n", color, i);
27050 color = getPixelColor(device, 480, 360);
27051 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x, test %u.\n", color, i);
27053 hr = IDirect3DVertexBuffer9_Unlock(vb);
27054 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27055 IDirect3DVertexBuffer9_Release(vb);
27058 hr = IDirect3DIndexBuffer9_Unlock(ib);
27059 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27061 IDirect3DIndexBuffer9_Release(ib);
27062 refcount = IDirect3DDevice9_Release(device);
27063 ok(!refcount, "Device has %lu references left.\n", refcount);
27065 IDirect3D9_Release(d3d);
27066 DestroyWindow(window);
27069 static void test_sample_attached_rendertarget(void)
27071 D3DADAPTER_IDENTIFIER9 identifier;
27072 IDirect3DQuery9 *event_query;
27073 IDirect3DTexture9 *texture;
27074 IDirect3DVertexBuffer9 *vb;
27075 IDirect3DPixelShader9 *ps;
27076 IDirect3DDevice9 *device;
27077 IDirect3DSurface9 *rt;
27078 unsigned int color, i;
27079 IDirect3D9 *d3d;
27080 ULONG refcount;
27081 D3DCAPS9 caps;
27082 BOOL is_warp;
27083 HWND window;
27084 HRESULT hr;
27085 void *data;
27087 static const struct
27089 struct vec3 position;
27090 struct vec2 texcoord;
27092 quad[] =
27094 {{-1.0f, -1.0f, 0.1f}, {0.0f, 0.0f}},
27095 {{-1.0f, 1.0f, 0.1f}, {0.0f, 1.0f}},
27096 {{ 1.0f, -1.0f, 0.0f}, {1.0f, 0.0f}},
27097 {{ 1.0f, 1.0f, 0.1f}, {1.0f, 1.0f}},
27100 static const DWORD pixel_shader_code[] =
27102 0xffff0200, /* ps_2_0 */
27103 0x05000051, 0xa00f0000, 0x3e800000, 0x3e800000, 0x3e800000, 0x3e800000,
27104 /* def c0, 0.25, 0.25, 0.25, 0.25 */
27105 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
27106 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
27107 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
27108 0x03000002, 0x800f0000, 0x80e40000, 0xa0e40000, /* add r0, r0, c0 */
27109 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
27110 0x0000ffff
27113 window = create_window();
27114 ok(!!window, "Failed to create a window.\n");
27116 d3d = Direct3DCreate9(D3D_SDK_VERSION);
27117 ok(!!d3d, "Failed to create a D3D object.\n");
27119 hr = IDirect3D9_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
27120 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27121 is_warp = adapter_is_warp(&identifier);
27123 if (!(device = create_device(d3d, window, window, TRUE)))
27125 skip("Failed to create a D3D device, skipping tests.\n");
27126 IDirect3D9_Release(d3d);
27127 DestroyWindow(window);
27128 return;
27131 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
27132 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27133 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
27135 skip("No shader model 2 support, skipping tests.\n");
27136 IDirect3DDevice9_Release(device);
27137 IDirect3D9_Release(d3d);
27138 DestroyWindow(window);
27139 return;
27142 hr = IDirect3DDevice9_CreateQuery(device, D3DQUERYTYPE_EVENT, NULL);
27143 if (hr == D3DERR_NOTAVAILABLE)
27145 /* Without synchronization native d3d seems to show race condition on
27146 * render target update, similar to opengl without using texture barrier. */
27147 skip("Event queries are not supported, skipping test.\n");
27148 IDirect3DDevice9_Release(device);
27149 IDirect3D9_Release(d3d);
27150 DestroyWindow(window);
27151 return;
27154 hr = IDirect3DDevice9_CreateQuery(device, D3DQUERYTYPE_EVENT, &event_query);
27155 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27157 hr = IDirect3DQuery9_Issue(event_query, D3DISSUE_END);
27158 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27160 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), D3DUSAGE_DYNAMIC,
27161 D3DFVF_XYZ | D3DFVF_TEX1, D3DPOOL_DEFAULT, &vb, NULL);
27162 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27163 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), &data, 0);
27164 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27165 memcpy(data, quad, sizeof(quad));
27166 hr = IDirect3DVertexBuffer9_Unlock(vb);
27167 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27169 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
27170 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27172 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
27173 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27174 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
27175 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27176 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
27177 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27179 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET,
27180 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
27181 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27182 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &rt);
27183 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27185 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
27186 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27188 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
27189 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27191 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x01010101, 0.0, 0);
27192 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27193 check_rt_color(rt, 0x00010101);
27195 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &ps);
27196 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27198 hr = IDirect3DDevice9_BeginScene(device);
27199 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27201 hr = IDirect3DDevice9_SetPixelShader(device, ps);
27202 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27204 for (i = 0; i < 3; ++i)
27206 wait_query(event_query);
27208 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
27209 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27210 hr = IDirect3DQuery9_Issue(event_query, D3DISSUE_END);
27211 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27214 hr = IDirect3DDevice9_EndScene(device);
27215 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27217 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
27218 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27220 color = getPixelColor(device, 0, 0);
27221 if (is_warp || color == 0x00010101)
27222 skip("Sampling attached render targets is not supported.\n");
27223 else
27225 unsigned int expected_color = 0x00c1c1c1;
27226 unsigned int color = check_expected_rt_color(__LINE__, rt, expected_color);
27227 todo_wine_if(color != expected_color)
27228 ok(color == expected_color, "Got unexpected color 0x%08x.\n", color);
27231 IDirect3DQuery9_Release(event_query);
27233 IDirect3DVertexBuffer9_Release(vb);
27235 IDirect3DPixelShader9_Release(ps);
27236 IDirect3DSurface9_Release(rt);
27237 IDirect3DTexture9_Release(texture);
27239 refcount = IDirect3DDevice9_Release(device);
27240 ok(!refcount, "Device has %lu references left.\n", refcount);
27242 IDirect3D9_Release(d3d);
27243 DestroyWindow(window);
27246 static void test_alpha_to_coverage(void)
27248 static const struct
27250 struct vec3 position;
27251 struct vec2 texcoord;
27253 quad[] =
27255 {{-1.0f, -1.0f, 0.1f}, {0.0f, 0.0f}},
27256 {{-1.0f, 1.0f, 0.1f}, {0.0f, 1.0f}},
27257 {{ 1.0f, -1.0f, 0.1f}, {1.0f, 0.0f}},
27258 {{ 1.0f, 1.0f, 0.1f}, {1.0f, 1.0f}},
27261 IDirect3DSurface9 *rt, *ms_rt, *surface;
27262 D3DADAPTER_IDENTIFIER9 identifier;
27263 struct surface_readback rb;
27264 IDirect3DTexture9 *texture;
27265 IDirect3DStateBlock9 *sb;
27266 IDirect3DDevice9 *device;
27267 DWORD quality_levels;
27268 unsigned int colour;
27269 BOOL nvidia_mode;
27270 IDirect3D9 *d3d;
27271 ULONG refcount;
27272 HWND window;
27273 HRESULT hr;
27275 window = create_window();
27276 d3d = Direct3DCreate9(D3D_SDK_VERSION);
27277 ok(!!d3d, "Failed to create a D3D object.\n");
27279 if (IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
27280 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, &quality_levels) == D3DERR_NOTAVAILABLE)
27282 skip("Multisampling not supported for D3DFMT_A8R8G8B8.\n");
27283 IDirect3D9_Release(d3d);
27284 DestroyWindow(window);
27285 return;
27288 if (!(device = create_device(d3d, window, window, TRUE)))
27290 skip("Failed to create a 3D device.\n");
27291 IDirect3D9_Release(d3d);
27292 DestroyWindow(window);
27293 return;
27297 hr = IDirect3D9_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
27298 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27300 if (adapter_is_amd(&identifier))
27302 nvidia_mode = FALSE;
27304 else
27306 /* The ATOC pseudo format is introduced by NVIDIA. Some Intel GPUs
27307 * support alpha to coverage the same way as NVIDIA. */
27308 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
27309 D3DRTYPE_SURFACE, MAKEFOURCC('A','T','O','C')) != D3D_OK)
27311 win_skip("Alpha to coverage is not supported.\n");
27312 refcount = IDirect3DDevice9_Release(device);
27313 ok(!refcount, "Device has %lu references left.\n", refcount);
27314 IDirect3D9_Release(d3d);
27315 DestroyWindow(window);
27316 return;
27318 nvidia_mode = TRUE;
27321 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128,
27322 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
27323 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27324 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128,
27325 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &ms_rt, NULL);
27326 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27328 hr = IDirect3DDevice9_SetRenderTarget(device, 0, ms_rt);
27329 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27330 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
27331 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27333 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8,
27334 D3DPOOL_DEFAULT, &texture, NULL);
27335 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27337 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
27338 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27340 hr = IDirect3DDevice9_BeginScene(device);
27341 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27343 fill_surface(surface, 0xff2000ff, 0);
27345 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
27346 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27347 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
27348 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27350 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0f, 0);
27351 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27353 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
27354 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27355 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
27356 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27358 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
27359 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27361 if (nvidia_mode)
27363 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Y, MAKEFOURCC('A','T','O','C'));
27364 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27366 /* While undocumented, Nvidia also requires to enable alpha test to enable
27367 * alpha to coverage. Intel does not. */
27368 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
27369 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27371 else
27373 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, MAKEFOURCC('A','2','M','1'));
27374 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27377 hr = IDirect3DDevice9_CreateStateBlock(device, D3DSBT_VERTEXSTATE, &sb);
27378 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27380 fill_surface(surface, 0x40608000, 0);
27382 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
27383 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27385 hr = IDirect3DDevice9_StretchRect(device, ms_rt, NULL, rt, NULL, D3DTEXF_POINT);
27386 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27387 get_rt_readback(rt, &rb);
27388 colour = get_readback_color(&rb, 64, 64);
27390 /* NVIDIA is probably using some proprietary algorithm for averaging sample colour values. */
27391 ok(color_match(colour, 0x9f404080, 1) || color_match(colour, 0x9f485cbc, 1) /* NVIDIA */,
27392 "Got unexpected colour %08x.\n", colour);
27393 release_surface_readback(&rb);
27395 if (nvidia_mode)
27397 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Y, D3DFMT_UNKNOWN);
27398 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27400 else
27402 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, MAKEFOURCC('A','2','M','0'));
27403 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27406 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
27407 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27409 hr = IDirect3DDevice9_StretchRect(device, ms_rt, NULL, rt, NULL, D3DTEXF_POINT);
27410 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27411 get_rt_readback(rt, &rb);
27412 colour = get_readback_color(&rb, 64, 64);
27413 ok(colour == 0x40608000, "Got unexpected colour %08x.\n", colour);
27414 release_surface_readback(&rb);
27416 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff2000ff, 0.0f, 0);
27417 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27419 IDirect3DStateBlock9_Apply(sb);
27420 IDirect3DStateBlock9_Release(sb);
27422 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
27423 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27425 hr = IDirect3DDevice9_StretchRect(device, ms_rt, NULL, rt, NULL, D3DTEXF_POINT);
27426 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27427 get_rt_readback(rt, &rb);
27428 colour = get_readback_color(&rb, 64, 64);
27429 ok(color_match(colour, 0x9f404080, 1) || color_match(colour, 0x9f485cbc, 1) /* Nvidia */,
27430 "Got unexpected colour %08x.\n", colour);
27431 release_surface_readback(&rb);
27433 hr = IDirect3DDevice9_EndScene(device);
27434 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27435 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
27436 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27438 IDirect3DSurface9_Release(surface);
27439 IDirect3DTexture9_Release(texture);
27440 IDirect3DSurface9_Release(ms_rt);
27441 IDirect3DSurface9_Release(rt);
27442 refcount = IDirect3DDevice9_Release(device);
27443 ok(!refcount, "Device has %lu references left.\n", refcount);
27444 IDirect3D9_Release(d3d);
27445 DestroyWindow(window);
27448 static void test_sample_mask(void)
27450 IDirect3DSurface9 *rt, *ms_rt;
27451 struct surface_readback rb;
27452 IDirect3DDevice9 *device;
27453 unsigned int colour;
27454 IDirect3D9 *d3d;
27455 ULONG refcount;
27456 HWND window;
27457 HRESULT hr;
27459 static const struct
27461 struct vec3 position;
27462 DWORD diffuse;
27464 quad[] =
27466 {{-1.0f, -1.0f, 0.1f}, 0xffffffff},
27467 {{-1.0f, 1.0f, 0.1f}, 0xffffffff},
27468 {{ 1.0f, -1.0f, 0.1f}, 0xffffffff},
27469 {{ 1.0f, 1.0f, 0.1f}, 0xffffffff},
27472 window = create_window();
27473 d3d = Direct3DCreate9(D3D_SDK_VERSION);
27474 ok(!!d3d, "Failed to create a D3D object.\n");
27476 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
27477 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
27479 skip("Multisampling not supported for D3DFMT_A8R8G8B8.\n");
27480 IDirect3D9_Release(d3d);
27481 DestroyWindow(window);
27482 return;
27485 if (!(device = create_device(d3d, window, window, TRUE)))
27487 skip("Failed to create a 3D device.\n");
27488 IDirect3D9_Release(d3d);
27489 DestroyWindow(window);
27490 return;
27493 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128,
27494 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
27495 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27496 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128,
27497 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &ms_rt, NULL);
27498 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27500 hr = IDirect3DDevice9_SetRenderTarget(device, 0, ms_rt);
27501 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27502 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
27503 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27505 hr = IDirect3DDevice9_BeginScene(device);
27506 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27508 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
27509 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27510 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_MULTISAMPLEMASK, 0x5);
27511 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27513 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0f, 0);
27514 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27515 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
27516 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27517 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
27518 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27520 hr = IDirect3DDevice9_StretchRect(device, ms_rt, NULL, rt, NULL, D3DTEXF_POINT);
27521 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27522 get_rt_readback(rt, &rb);
27523 colour = get_readback_color(&rb, 64, 64);
27524 /* Multiple generations of Nvidia cards return broken results.
27525 * A mask with no bits or all bits set produce the expected results (0x00 / 0xff),
27526 * but any other mask behaves almost as if the result is 0.5 + (enabled / total)
27527 * samples. It's not quite that though (you'd expect 0xbf or 0xc0 instead of 0xbc).
27529 * I looked at a few other possible problems: Incorrectly enabled Z test, alpha test,
27530 * culling, the multisample mask affecting CopyRects. Neither of these make a difference. */
27531 ok(color_match(colour, 0xffff8080, 1) || broken(color_match(colour, 0xffffbcbc, 1)),
27532 "Got unexpected colour %08x.\n", colour);
27533 release_surface_readback(&rb);
27535 hr = IDirect3DDevice9_EndScene(device);
27536 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27538 IDirect3DSurface9_Release(ms_rt);
27539 IDirect3DSurface9_Release(rt);
27540 refcount = IDirect3DDevice9_Release(device);
27541 ok(!refcount, "Device has %lu references left.\n", refcount);
27542 IDirect3D9_Release(d3d);
27543 DestroyWindow(window);
27546 struct dynamic_vb_vertex
27548 struct vec3 position;
27549 DWORD diffuse;
27552 static void fill_dynamic_vb_quad(struct dynamic_vb_vertex *quad, unsigned int x, unsigned int y)
27554 unsigned int i;
27556 memset(quad, 0, 4 * sizeof(*quad));
27558 quad[0].position.x = quad[1].position.x = -1.0f + 0.01f * x;
27559 quad[2].position.x = quad[3].position.x = -1.0f + 0.01f * (x + 1);
27561 quad[0].position.y = quad[2].position.y = -1.0f + 0.01f * y;
27562 quad[1].position.y = quad[3].position.y = -1.0f + 0.01f * (y + 1);
27564 for (i = 0; i < 4; ++i)
27565 quad[i].diffuse = 0xff00ff00;
27568 static void test_dynamic_map_synchronization(void)
27570 IDirect3DVertexBuffer9 *buffer;
27571 IDirect3DDevice9 *device;
27572 IDirect3DSurface9 *rt;
27573 unsigned int x, y;
27574 IDirect3D9 *d3d;
27575 ULONG refcount;
27576 HWND window;
27577 HRESULT hr;
27578 void *data;
27580 window = create_window();
27581 d3d = Direct3DCreate9(D3D_SDK_VERSION);
27582 ok(!!d3d, "Failed to create a D3D object.\n");
27583 if (!(device = create_device(d3d, window, window, TRUE)))
27585 skip("Failed to create a D3D device, skipping tests.\n");
27586 IDirect3D9_Release(d3d);
27587 DestroyWindow(window);
27588 return;
27591 hr = IDirect3DDevice9_CreateVertexBuffer(device, 200 * 4 * sizeof(struct dynamic_vb_vertex),
27592 D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFVF_XYZ, D3DPOOL_DEFAULT, &buffer, NULL);
27593 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27595 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(struct dynamic_vb_vertex));
27596 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27597 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
27598 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27599 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
27600 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27601 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
27602 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27604 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0f, 0);
27605 ok(hr == D3D_OK, "Failed to clear, hr %#lx.\n", hr);
27607 hr = IDirect3DDevice9_BeginScene(device);
27608 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27610 for (y = 0; y < 200; ++y)
27612 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, 0, &data, D3DLOCK_DISCARD);
27613 ok(hr == D3D_OK, "Failed to map buffer, hr %#lx.\n", hr);
27615 fill_dynamic_vb_quad(data, 0, y);
27617 hr = IDirect3DVertexBuffer9_Unlock(buffer);
27618 ok(hr == D3D_OK, "Failed to map buffer, hr %#lx.\n", hr);
27620 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
27621 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27623 for (x = 1; x < 200; ++x)
27625 hr = IDirect3DVertexBuffer9_Lock(buffer, 4 * sizeof(struct dynamic_vb_vertex) * x,
27626 4 * sizeof(struct dynamic_vb_vertex), &data, D3DLOCK_NOOVERWRITE);
27627 ok(hr == D3D_OK, "Failed to map buffer, hr %#lx.\n", hr);
27629 fill_dynamic_vb_quad(data, x, y);
27631 hr = IDirect3DVertexBuffer9_Unlock(buffer);
27632 ok(hr == D3D_OK, "Failed to map buffer, hr %#lx.\n", hr);
27634 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4 * x, 2);
27635 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27639 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &rt);
27640 ok(hr == S_OK, "Failed to get render target, hr %#lx.\n", hr);
27641 check_rt_color(rt, 0x0000ff00);
27642 IDirect3DSurface9_Release(rt);
27644 hr = IDirect3DDevice9_EndScene(device);
27645 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27647 IDirect3DVertexBuffer9_Release(buffer);
27649 /* Castlevania: Lords of Shadow 2 locks a vertex and index buffer and keeps
27650 * both mapped for all of the draws in a frame. Test this by doing the same
27651 * draws, but with the buffer mapped the whole time. */
27653 hr = IDirect3DDevice9_CreateVertexBuffer(device, 200 * 4 * sizeof(struct dynamic_vb_vertex),
27654 D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFVF_XYZ, D3DPOOL_DEFAULT, &buffer, NULL);
27655 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27656 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(struct dynamic_vb_vertex));
27657 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27659 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0f, 0);
27660 ok(hr == D3D_OK, "Failed to clear, hr %#lx.\n", hr);
27662 hr = IDirect3DDevice9_BeginScene(device);
27663 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27665 for (y = 0; y < 200; ++y)
27667 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, 0, &data, D3DLOCK_DISCARD);
27668 ok(hr == D3D_OK, "Failed to map buffer, hr %#lx.\n", hr);
27670 fill_dynamic_vb_quad(data, 0, y);
27671 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
27672 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27674 for (x = 1; x < 200; ++x)
27676 fill_dynamic_vb_quad((struct dynamic_vb_vertex *)data + 4 * x, x, y);
27677 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4 * x, 2);
27678 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27681 hr = IDirect3DVertexBuffer9_Unlock(buffer);
27682 ok(hr == D3D_OK, "Failed to map buffer, hr %#lx.\n", hr);
27685 hr = IDirect3DDevice9_EndScene(device);
27686 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27688 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &rt);
27689 ok(hr == S_OK, "Failed to get render target, hr %#lx.\n", hr);
27690 check_rt_color(rt, 0x0000ff00);
27691 IDirect3DSurface9_Release(rt);
27693 IDirect3DVertexBuffer9_Release(buffer);
27694 refcount = IDirect3DDevice9_Release(device);
27695 ok(!refcount, "Device has %lu references left.\n", refcount);
27696 IDirect3D9_Release(d3d);
27697 DestroyWindow(window);
27700 static void test_filling_convention(void)
27702 static const DWORD colour_bottom = 0x00ffff00;
27703 static const DWORD colour_clear = 0x000000ff;
27704 static const DWORD colour_right = 0x00000000;
27705 static const DWORD colour_left = 0x00ff0000;
27706 static const DWORD colour_top = 0x0000ff00;
27707 unsigned int colour, expected, i, j, x, y;
27708 IDirect3DSurface9 *rt, *backbuffer, *cur;
27709 IDirect3DVertexShader9 *shader = NULL;
27710 struct surface_readback rb;
27711 IDirect3DDevice9 *device;
27712 IDirect3D9 *d3d;
27713 ULONG refcount;
27714 D3DCAPS9 caps;
27715 HWND window;
27716 HRESULT hr;
27717 BOOL todo;
27719 static const unsigned int vp_size = 8;
27720 const D3DVIEWPORT9 vp = { 0, 0, vp_size, vp_size, 0.0, 1.0 };
27721 static const DWORD vs_code[] =
27723 0xfffe0101, /* vs_1_1 */
27724 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
27725 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
27726 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
27727 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
27728 0x0000ffff /* end */
27731 /* This test data follows the examples in MSDN's
27732 * "Rasterization Rules (Direct3D 9)" article.
27734 * The eps offset is filled in later depending on the GPU generation. The -eps/+eps below
27735 * is kept for keeping the code similar to the same test in the other d3d versions.
27737 * For d3d10+ GPUs even an offset of 1/(1024^2) is enough to make a difference. dx9 GPUs
27738 * (or at least r500, on which this was tested) need an offset of 1/128. dx7 (or rather,
27739 * a Geforce 4 GO, AKA a rebranded geforce 2) need 1/64.
27741 * GameFace is the only software we found that we know is picky regarding small geometry
27742 * offsets. It needs d3d10 and newer. A number of games have been written for d3d9 that
27743 * actually need d3d10 hardware (e.g. ARGB32F with filtering, some fourcc hacks). There
27744 * might be something that needs the d3d10+ precision in the d3d9 API. So demand it if
27745 * we find a d3d10+ GPU. */
27746 float eps = 0.0f;
27747 struct
27749 struct vec3 position;
27750 DWORD diffuse;
27752 center_tris[] =
27754 /* left */
27755 {{-2.5f / 4.0f, -1.5f / 4.0f, 0.0f}, colour_left},
27756 {{-2.5f / 4.0f, 2.5f / 4.0f, 0.0f}, colour_left},
27757 {{-1.5f / 4.0f, 0.5f / 4.0f, 0.0f}, colour_left},
27759 /* top */
27760 {{-1.5f / 4.0f, 0.5f / 4.0f, 0.0f}, colour_top},
27761 {{-2.5f / 4.0f, 2.5f / 4.0f, 0.0f}, colour_top},
27762 {{-0.5f / 4.0f, 2.5f / 4.0f, 0.0f}, colour_top},
27764 /* right */
27765 {{-0.5f / 4.0f, -1.5f / 4.0f, 0.0f}, colour_right},
27766 {{-1.5f / 4.0f, 0.5f / 4.0f, 0.0f}, colour_right},
27767 {{-0.5f / 4.0f, 2.5f / 4.0f, 0.0f}, colour_right},
27769 /* bottom */
27770 {{-2.5f / 4.0f, -1.5f / 4.0f, 0.0f}, colour_bottom},
27771 {{-1.5f / 4.0f, 0.5f / 4.0f, 0.0f}, colour_bottom},
27772 {{-0.5f / 4.0f, -1.5f / 4.0f, 0.0f}, colour_bottom},
27775 edge_tris[] =
27777 /* left */
27778 {{-2.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_left},
27779 {{-2.0f / 4.0f, 3.0f / 4.0f, 0.0f}, colour_left},
27780 {{-1.0f / 4.0f, 1.0f / 4.0f, 0.0f}, colour_left},
27782 /* top */
27783 {{-1.0f / 4.0f, 1.0f / 4.0f, 0.0f}, colour_top},
27784 {{-2.0f / 4.0f, 3.0f / 4.0f, 0.0f}, colour_top},
27785 {{ 0.0f / 4.0f, 3.0f / 4.0f, 0.0f}, colour_top},
27787 /* right */
27788 {{ 0.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_right},
27789 {{-1.0f / 4.0f, 1.0f / 4.0f, 0.0f}, colour_right},
27790 {{ 0.0f / 4.0f, 3.0f / 4.0f, 0.0f}, colour_right},
27792 /* bottom */
27793 {{-2.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_bottom},
27794 {{-1.0f / 4.0f, 1.0f / 4.0f, 0.0f}, colour_bottom},
27795 {{ 0.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_bottom},
27797 nudge_right_tris[] =
27799 /* left */
27800 {{eps - 2.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_left},
27801 {{eps - 2.0f / 4.0f, 3.0f / 4.0f, 0.0f}, colour_left},
27802 {{eps - 1.0f / 4.0f, 1.0f / 4.0f, 0.0f}, colour_left},
27804 /* top */
27805 {{eps - 1.0f / 4.0f, 1.0f / 4.0f, 0.0f}, colour_top},
27806 {{eps - 2.0f / 4.0f, 3.0f / 4.0f, 0.0f}, colour_top},
27807 {{eps - 0.0f / 4.0f, 3.0f / 4.0f, 0.0f}, colour_top},
27809 /* right */
27810 {{eps - 0.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_right},
27811 {{eps - 1.0f / 4.0f, 1.0f / 4.0f, 0.0f}, colour_right},
27812 {{eps - 0.0f / 4.0f, 3.0f / 4.0f, 0.0f}, colour_right},
27814 /* bottom */
27815 {{eps - 2.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_bottom},
27816 {{eps - 1.0f / 4.0f, 1.0f / 4.0f, 0.0f}, colour_bottom},
27817 {{eps - 0.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_bottom},
27819 nudge_left_tris[] =
27821 {{-eps - 2.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_left},
27822 {{-eps - 2.0f / 4.0f, 3.0f / 4.0f, 0.0f}, colour_left},
27823 {{-eps - 1.0f / 4.0f, 1.0f / 4.0f, 0.0f}, colour_left},
27825 /* top */
27826 {{-eps - 1.0f / 4.0f, 1.0f / 4.0f, 0.0f}, colour_top},
27827 {{-eps - 2.0f / 4.0f, 3.0f / 4.0f, 0.0f}, colour_top},
27828 {{-eps - 0.0f / 4.0f, 3.0f / 4.0f, 0.0f}, colour_top},
27830 /* right */
27831 {{-eps - 0.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_right},
27832 {{-eps - 1.0f / 4.0f, 1.0f / 4.0f, 0.0f}, colour_right},
27833 {{-eps - 0.0f / 4.0f, 3.0f / 4.0f, 0.0f}, colour_right},
27835 /* bottom */
27836 {{-eps - 2.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_bottom},
27837 {{-eps - 1.0f / 4.0f, 1.0f / 4.0f, 0.0f}, colour_bottom},
27838 {{-eps - 0.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_bottom},
27840 nudge_top_tris[] =
27842 /* left */
27843 {{-2.0f / 4.0f, eps - 1.0f / 4.0f, 0.0f}, colour_left},
27844 {{-2.0f / 4.0f, eps + 3.0f / 4.0f, 0.0f}, colour_left},
27845 {{-1.0f / 4.0f, eps + 1.0f / 4.0f, 0.0f}, colour_left},
27847 /* top */
27848 {{-1.0f / 4.0f, eps + 1.0f / 4.0f, 0.0f}, colour_top},
27849 {{-2.0f / 4.0f, eps + 3.0f / 4.0f, 0.0f}, colour_top},
27850 {{ 0.0f / 4.0f, eps + 3.0f / 4.0f, 0.0f}, colour_top},
27852 /* right */
27853 {{ 0.0f / 4.0f, eps - 1.0f / 4.0f, 0.0f}, colour_right},
27854 {{-1.0f / 4.0f, eps + 1.0f / 4.0f, 0.0f}, colour_right},
27855 {{ 0.0f / 4.0f, eps + 3.0f / 4.0f, 0.0f}, colour_right},
27857 /* bottom */
27858 {{-2.0f / 4.0f, eps - 1.0f / 4.0f, 0.0f}, colour_bottom},
27859 {{-1.0f / 4.0f, eps + 1.0f / 4.0f, 0.0f}, colour_bottom},
27860 {{ 0.0f / 4.0f, eps - 1.0f / 4.0f, 0.0f}, colour_bottom},
27862 nudge_bottom_tris[] =
27864 /* left */
27865 {{-2.0f / 4.0f, -eps - 1.0f / 4.0f, 0.0f}, colour_left},
27866 {{-2.0f / 4.0f, -eps + 3.0f / 4.0f, 0.0f}, colour_left},
27867 {{-1.0f / 4.0f, -eps + 1.0f / 4.0f, 0.0f}, colour_left},
27869 /* top */
27870 {{-1.0f / 4.0f, -eps + 1.0f / 4.0f, 0.0f}, colour_top},
27871 {{-2.0f / 4.0f, -eps + 3.0f / 4.0f, 0.0f}, colour_top},
27872 {{ 0.0f / 4.0f, -eps + 3.0f / 4.0f, 0.0f}, colour_top},
27874 /* right */
27875 {{ 0.0f / 4.0f, -eps - 1.0f / 4.0f, 0.0f}, colour_right},
27876 {{-1.0f / 4.0f, -eps + 1.0f / 4.0f, 0.0f}, colour_right},
27877 {{ 0.0f / 4.0f, -eps + 3.0f / 4.0f, 0.0f}, colour_right},
27879 /* bottom */
27880 {{-2.0f / 4.0f, -eps - 1.0f / 4.0f, 0.0f}, colour_bottom},
27881 {{-1.0f / 4.0f, -eps + 1.0f / 4.0f, 0.0f}, colour_bottom},
27882 {{ 0.0f / 4.0f, -eps - 1.0f / 4.0f, 0.0f}, colour_bottom},
27885 const struct
27887 struct vec4 position;
27888 DWORD diffuse;
27890 center_tris_t[] =
27892 /* left */
27893 {{ 1.5f, 1.5f, 0.0f, 1.0f}, colour_left},
27894 {{ 2.5f, 3.5f, 0.0f, 1.0f}, colour_left},
27895 {{ 1.5f, 5.5f, 0.0f, 1.0f}, colour_left},
27897 /* top */
27898 {{ 1.5f, 1.5f, 0.0f, 1.0f}, colour_top},
27899 {{ 3.5f, 1.5f, 0.0f, 1.0f}, colour_top},
27900 {{ 2.5f, 3.5f, 0.0f, 1.0f}, colour_top},
27902 /* right */
27903 {{ 3.5f, 1.5f, 0.0f, 1.0f}, colour_right},
27904 {{ 3.5f, 5.5f, 0.0f, 1.0f}, colour_right},
27905 {{ 2.5f, 3.5f, 0.0f, 1.0f}, colour_right},
27907 /* bottom */
27908 {{ 2.5f, 3.5f, 0.0f, 1.0f}, colour_bottom},
27909 {{ 3.5f, 5.5f, 0.0f, 1.0f}, colour_bottom},
27910 {{ 1.5f, 5.5f, 0.0f, 1.0f}, colour_bottom},
27912 edge_tris_t[] =
27914 /* left */
27915 {{ 2.0f, 1.0f, 0.0f, 1.0f}, colour_left},
27916 {{ 3.0f, 3.0f, 0.0f, 1.0f}, colour_left},
27917 {{ 2.0f, 5.0f, 0.0f, 1.0f}, colour_left},
27919 /* top */
27920 {{ 2.0f, 1.0f, 0.0f, 1.0f}, colour_top},
27921 {{ 4.0f, 1.0f, 0.0f, 1.0f}, colour_top},
27922 {{ 3.0f, 3.0f, 0.0f, 1.0f}, colour_top},
27924 /* right */
27925 {{ 4.0f, 1.0f, 0.0f, 1.0f}, colour_right},
27926 {{ 4.0f, 5.0f, 0.0f, 1.0f}, colour_right},
27927 {{ 3.0f, 3.0f, 0.0f, 1.0f}, colour_right},
27929 /* bottom */
27930 {{ 3.0f, 3.0f, 0.0f, 1.0f}, colour_bottom},
27931 {{ 4.0f, 5.0f, 0.0f, 1.0f}, colour_bottom},
27932 {{ 2.0f, 5.0f, 0.0f, 1.0f}, colour_bottom},
27935 const struct
27937 const void *geometry;
27938 size_t stride;
27939 DWORD fvf;
27940 const char *expected[8];
27942 tests[] =
27945 center_tris,
27946 sizeof(center_tris[0]),
27947 D3DFVF_XYZ | D3DFVF_DIFFUSE,
27949 " ",
27950 " ",
27951 " TT ",
27952 " LR ",
27953 " LR ",
27954 " BB ",
27955 " ",
27960 edge_tris,
27961 sizeof(edge_tris[0]),
27962 D3DFVF_XYZ | D3DFVF_DIFFUSE,
27964 " ",
27965 " TT ",
27966 " LT ",
27967 " LR ",
27968 " LB ",
27969 " ",
27970 " ",
27975 nudge_right_tris,
27976 sizeof(nudge_right_tris[0]),
27977 D3DFVF_XYZ | D3DFVF_DIFFUSE,
27979 " ",
27980 " TT ",
27981 " TR ",
27982 " LR ",
27983 " BR ",
27984 " ",
27985 " ",
27990 nudge_left_tris,
27991 sizeof(nudge_left_tris[0]),
27992 D3DFVF_XYZ | D3DFVF_DIFFUSE,
27994 " ",
27995 " TT ",
27996 " LT ",
27997 " LR ",
27998 " LB ",
27999 " ",
28000 " ",
28005 nudge_top_tris,
28006 sizeof(nudge_top_tris[0]),
28007 D3DFVF_XYZ | D3DFVF_DIFFUSE,
28009 " ",
28010 " LT ",
28011 " LT ",
28012 " LB ",
28013 " LB ",
28014 " ",
28015 " ",
28020 nudge_bottom_tris,
28021 sizeof(nudge_bottom_tris[0]),
28022 D3DFVF_XYZ | D3DFVF_DIFFUSE,
28024 " ",
28025 " ",
28026 " LT ",
28027 " Lt ",
28028 " LB ",
28029 " lB ",
28030 " ",
28035 center_tris_t,
28036 sizeof(center_tris_t[0]),
28037 D3DFVF_XYZRHW | D3DFVF_DIFFUSE,
28039 " ",
28040 " ",
28041 " TT ",
28042 " LR ",
28043 " LR ",
28044 " BB ",
28045 " ",
28050 edge_tris_t,
28051 sizeof(edge_tris_t[0]),
28052 D3DFVF_XYZRHW | D3DFVF_DIFFUSE,
28054 " ",
28055 " TT ",
28056 " LT ",
28057 " LR ",
28058 " LB ",
28059 " ",
28060 " ",
28066 window = create_window();
28067 d3d = Direct3DCreate9(D3D_SDK_VERSION);
28068 ok(!!d3d, "Failed to create a D3D object.\n");
28070 if (!(device = create_device(d3d, window, window, TRUE)))
28072 skip("Failed to create a 3D device.\n");
28073 IDirect3D9_Release(d3d);
28074 DestroyWindow(window);
28075 return;
28078 hr = IDirect3DDevice9_CreateRenderTarget(device, vp_size, vp_size,
28079 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
28080 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
28081 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
28082 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
28084 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
28085 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
28086 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
28088 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &shader);
28089 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
28091 else
28092 skip("Skipping vertex shader codepath in filling convention test.\n");
28094 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
28095 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
28096 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
28097 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
28099 if (device_is_d3d10(device))
28100 eps = 1.0f / 512.0f;
28101 else
28102 eps = 1.0f / 64.0f;
28104 for (i = 0; i < 12; ++i)
28106 nudge_right_tris[i].position.x +=eps;
28107 nudge_left_tris[i].position.x -=eps;
28108 nudge_top_tris[i].position.y +=eps;
28109 nudge_bottom_tris[i].position.y -=eps;
28112 for (i = 0; i < ARRAY_SIZE(tests); ++i)
28114 hr = IDirect3DDevice9_SetFVF(device, tests[i].fvf);
28115 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
28117 /* Run tests with shader and fixed function vertex processing if shaders are
28118 * supported. There's no point in running the XYZRHW tests with a VS though. */
28119 if (shader && ((tests[i].fvf & D3DFVF_POSITION_MASK) == D3DFVF_XYZ))
28120 j = 0;
28121 else
28122 j = 2;
28124 for (; j < 4; ++j)
28126 cur = (j & 1) ? rt : backbuffer;
28128 hr = IDirect3DDevice9_SetVertexShader(device, (j & 2) ? NULL : shader);
28129 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
28131 hr = IDirect3DDevice9_SetRenderTarget(device, 0, cur);
28132 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
28133 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, colour_clear, 0.0f, 0);
28134 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
28135 hr = IDirect3DDevice9_SetViewport(device, &vp);
28136 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
28138 hr = IDirect3DDevice9_BeginScene(device);
28139 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
28140 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, tests[i].geometry, tests[i].stride);
28141 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
28142 hr = IDirect3DDevice9_EndScene(device);
28143 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
28145 get_rt_readback(cur, &rb);
28146 for (y = 0; y < 8; y++)
28148 for (x = 0; x < 8; x++)
28150 todo = FALSE;
28151 switch (tests[i].expected[y][x])
28153 case 'l': todo = TRUE;
28154 case 'L':
28155 expected = colour_left;
28156 break;
28157 case 't': todo = TRUE;
28158 case 'T':
28159 expected = colour_top;
28160 break;
28161 case 'r': todo = TRUE;
28162 case 'R':
28163 expected = colour_right;
28164 break;
28165 case 'b': todo = TRUE;
28166 case 'B':
28167 expected = colour_bottom;
28168 break;
28169 case ' ':
28170 expected = colour_clear;
28171 break;
28172 default:
28173 ok(0, "Unexpected entry in expected test char\n");
28174 expected = 0xdeadbeef;
28176 colour = get_readback_color(&rb, x, y);
28177 /* The nudge-to-bottom test fails on cards that give us a bottom-left
28178 * filling convention. The cause isn't the bottom part of the filling
28179 * convention, but because wined3d will nudge geometry to the left to
28180 * keep diagonals (the 'R' in test case 'edge_tris') intact. */
28181 todo_wine_if(todo && !color_match(colour, expected, 1))
28182 ok(color_match(colour, expected, 1), "Got unexpected colour %08x, %ux%u, case %u, j %u.\n",
28183 colour, x, y, i, j);
28186 release_surface_readback(&rb);
28188 /* For debugging */
28189 if (cur != backbuffer)
28191 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, backbuffer, NULL, D3DTEXF_POINT);
28192 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
28194 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
28195 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
28199 if (shader)
28200 IDirect3DVertexShader9_Release(shader);
28201 IDirect3DSurface9_Release(backbuffer);
28202 IDirect3DSurface9_Release(rt);
28203 refcount = IDirect3DDevice9_Release(device);
28204 ok(!refcount, "Device has %lu references left.\n", refcount);
28205 IDirect3D9_Release(d3d);
28206 DestroyWindow(window);
28209 static void test_managed_reset(void)
28211 struct d3d9_test_context context;
28212 IDirect3DTexture9 *texture;
28213 IDirect3DDevice9 *device;
28214 HRESULT hr;
28216 if (!init_test_context(&context))
28217 return;
28218 device = context.device;
28220 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
28221 ok(hr == S_OK, "Got hr %#lx.\n", hr);
28222 fill_texture(texture, 0x0000ff00, 0);
28224 draw_textured_quad(&context, texture);
28225 check_rt_color(context.backbuffer, 0x0000ff00);
28227 hr = reset_device(&context);
28228 ok(hr == S_OK, "Got hr %#lx.\n", hr);
28230 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
28231 ok(hr == S_OK, "Got hr %#lx.\n", hr);
28233 draw_textured_quad(&context, texture);
28234 check_rt_color(context.backbuffer, 0x0000ff00);
28236 IDirect3DTexture9_Release(texture);
28237 release_test_context(&context);
28240 static void test_managed_generate_mipmap(void)
28242 struct d3d9_test_context context;
28243 IDirect3DTexture9 *texture;
28244 IDirect3DDevice9 *device;
28245 HRESULT hr;
28247 if (!init_test_context(&context))
28248 return;
28249 device = context.device;
28251 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 0, D3DUSAGE_AUTOGENMIPMAP,
28252 D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
28253 ok(hr == S_OK, "Got hr %#lx.\n", hr);
28254 fill_texture(texture, 0x0000ff00, 0);
28256 IDirect3DTexture9_GenerateMipSubLevels(texture);
28258 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
28259 ok(hr == S_OK, "Got hr %#lx.\n", hr);
28261 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
28262 ok(hr == S_OK, "Got hr %#lx.\n", hr);
28263 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
28264 ok(hr == S_OK, "Got hr %#lx.\n", hr);
28266 draw_textured_quad(&context, texture);
28267 check_rt_color(context.backbuffer, 0x0000ff00);
28269 IDirect3DTexture9_Release(texture);
28270 release_test_context(&context);
28273 /* Some applications (Vivisector, Cryostasis) lock a mipmapped managed texture
28274 * at level 0, write every level at once, and expect it to be uploaded. */
28275 static void test_mipmap_upload(void)
28277 unsigned int j, width, level_count;
28278 struct d3d9_test_context context;
28279 IDirect3DTexture9 *texture;
28280 D3DLOCKED_RECT locked_rect;
28281 IDirect3DDevice9 *device;
28282 unsigned int *mem;
28283 HRESULT hr;
28285 if (!init_test_context(&context))
28286 return;
28287 device = context.device;
28289 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 0, 0,
28290 D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
28291 ok(hr == S_OK, "Got hr %#lx.\n", hr);
28293 level_count = IDirect3DBaseTexture9_GetLevelCount(texture);
28295 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
28296 ok(hr == S_OK, "Got hr %#lx.\n", hr);
28298 mem = locked_rect.pBits;
28300 for (j = 0; j < level_count; ++j)
28302 width = 32 >> j;
28303 memset(mem, 0x11 * (j + 1), width * width * 4);
28304 mem += width * width;
28307 hr = IDirect3DTexture9_UnlockRect(texture, 0);
28308 ok(hr == S_OK, "Got hr %#lx.\n", hr);
28310 for (j = 0; j < level_count; ++j)
28312 winetest_push_context("level %u", j);
28314 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
28315 ok(hr == S_OK, "Got hr %#lx.\n", hr);
28317 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
28318 ok(hr == S_OK, "Got hr %#lx.\n", hr);
28319 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, j);
28320 ok(hr == S_OK, "Got hr %#lx.\n", hr);
28322 draw_textured_quad(&context, texture);
28323 check_rt_color(context.backbuffer, 0x00111111 * (j + 1));
28325 winetest_pop_context();
28328 IDirect3DTexture9_Release(texture);
28329 release_test_context(&context);
28332 static void test_default_diffuse(void)
28334 IDirect3DVertexDeclaration9 *vertex_declaration;
28335 struct d3d9_test_context context;
28336 IDirect3DVertexBuffer9 *vb;
28337 IDirect3DDevice9 *device;
28338 HRESULT hr;
28339 void *data;
28341 static const D3DVERTEXELEMENT9 decl_elements_with_diffuse[] =
28343 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
28344 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
28345 D3DDECL_END()
28348 static const D3DVERTEXELEMENT9 decl_elements_no_diffuse[] =
28350 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
28351 D3DDECL_END()
28354 static const D3DVERTEXELEMENT9 decl_elements_missing_diffuse[] =
28356 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
28357 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
28358 D3DDECL_END()
28361 static const DWORD vs_code[] =
28363 0xfffe0200, /* vs_2_0 */
28364 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
28365 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
28366 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
28367 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
28368 0x0000ffff /* end */
28371 static const DWORD vs_no_diffuse_code[] =
28373 0xfffe0200, /* vs_2_0 */
28374 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
28375 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
28376 0x0000ffff /* end */
28379 static const DWORD ps_code[] =
28381 0xffff0200, /* ps_2_0 */
28382 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
28383 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
28384 0x0000ffff /* end */
28387 static const struct
28389 struct vec3 position;
28390 unsigned int diffuse;
28392 quad[] =
28394 {{-1.0f, -1.0f, 0.1f}, 0xff0000ff},
28395 {{-1.0f, 1.0f, 0.1f}, 0xff0000ff},
28396 {{ 1.0f, -1.0f, 0.1f}, 0xff0000ff},
28397 {{ 1.0f, 1.0f, 0.1f}, 0xff0000ff},
28400 static const struct
28402 const DWORD *ps;
28403 DWORD texture_source;
28405 ps_tests[] =
28407 {ps_code, 0},
28408 {NULL, D3DTA_CURRENT},
28409 {NULL, D3DTA_DIFFUSE},
28412 static const struct
28414 const DWORD *vs;
28415 const D3DVERTEXELEMENT9 *decl_elements;
28416 unsigned int expect_colour;
28418 vs_tests[] =
28420 {NULL, decl_elements_with_diffuse, 0x000000ff},
28421 {NULL, decl_elements_no_diffuse, 0x00ffffff},
28422 {NULL, decl_elements_missing_diffuse, 0x00000000},
28423 {vs_code, decl_elements_with_diffuse, 0x000000ff},
28424 {vs_code, decl_elements_no_diffuse, 0x00000000},
28425 {vs_code, decl_elements_missing_diffuse, 0x00000000},
28426 {vs_no_diffuse_code, decl_elements_with_diffuse, 0x00ffffff},
28427 {vs_no_diffuse_code, decl_elements_no_diffuse, 0x00ffffff},
28428 {vs_no_diffuse_code, decl_elements_missing_diffuse, 0x00ffffff},
28431 if (!init_test_context(&context))
28432 return;
28433 device = context.device;
28435 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
28436 ok(hr == S_OK, "Got hr %#lx.\n", hr);
28437 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
28438 ok(hr == S_OK, "Got hr %#lx.\n", hr);
28440 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad),
28441 D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &vb, NULL);
28442 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
28443 hr = IDirect3DVertexBuffer9_Lock(vb, 0, 0, &data, D3DLOCK_DISCARD);
28444 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
28445 memcpy(data, quad, sizeof(quad));
28446 hr = IDirect3DVertexBuffer9_Unlock(vb);
28447 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
28448 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
28449 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
28451 for (unsigned int i = 0; i < ARRAY_SIZE(ps_tests); ++i)
28453 winetest_push_context("PS test %u", i);
28455 if (ps_tests[i].ps)
28457 IDirect3DPixelShader9 *ps;
28459 hr = IDirect3DDevice9_CreatePixelShader(device, ps_tests[i].ps, &ps);
28460 ok(hr == S_OK, "Got hr %#lx.\n", hr);
28461 hr = IDirect3DDevice9_SetPixelShader(device, ps);
28462 ok(hr == S_OK, "Got hr %#lx.\n", hr);
28463 IDirect3DPixelShader9_Release(ps);
28465 else
28467 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
28468 ok(hr == S_OK, "Got hr %#lx.\n", hr);
28469 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
28470 ok(hr == S_OK, "Got hr %#lx.\n", hr);
28471 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, ps_tests[i].texture_source);
28472 ok(hr == S_OK, "Got hr %#lx.\n", hr);
28473 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
28474 ok(hr == S_OK, "Got hr %#lx.\n", hr);
28475 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, ps_tests[i].texture_source);
28476 ok(hr == S_OK, "Got hr %#lx.\n", hr);
28479 for (unsigned int j = 0; j < ARRAY_SIZE(vs_tests); ++j)
28481 unsigned int colour;
28483 winetest_push_context("VS test %u", j);
28485 if (vs_tests[j].vs)
28487 IDirect3DVertexShader9 *vs;
28489 hr = IDirect3DDevice9_CreateVertexShader(device, vs_tests[j].vs, &vs);
28490 ok(hr == S_OK, "Got hr %#lx.\n", hr);
28491 hr = IDirect3DDevice9_SetVertexShader(device, vs);
28492 ok(hr == S_OK, "Got hr %#lx.\n", hr);
28493 IDirect3DVertexShader9_Release(vs);
28495 else
28497 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
28498 ok(hr == S_OK, "Got hr %#lx.\n", hr);
28501 hr = IDirect3DDevice9_CreateVertexDeclaration(device, vs_tests[j].decl_elements, &vertex_declaration);
28502 ok(hr == S_OK, "Got hr %#lx.\n", hr);
28503 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
28504 ok(hr == S_OK, "Got hr %#lx.\n", hr);
28505 IDirect3DVertexDeclaration9_Release(vertex_declaration);
28507 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
28508 ok(hr == S_OK, "Got hr %#lx.\n", hr);
28510 hr = IDirect3DDevice9_BeginScene(device);
28511 ok(hr == S_OK, "Got hr %#lx.\n", hr);
28512 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
28513 ok(hr == S_OK, "Got hr %#lx.\n", hr);
28514 hr = IDirect3DDevice9_EndScene(device);
28515 ok(hr == S_OK, "Got hr %#lx.\n", hr);
28517 colour = getPixelColor(device, 320, 240);
28518 ok(colour == vs_tests[j].expect_colour, "Got unexpected colour %08x.\n", colour);
28520 winetest_pop_context();
28523 winetest_pop_context();
28526 IDirect3DVertexShader9_Release(vb);
28527 release_test_context(&context);
28530 /* Test the default values of attribute components when the vertex declaration
28531 * includes less than all 4 components. */
28532 static void test_default_attribute_components(void)
28534 IDirect3DVertexDeclaration9 *vertex_declaration;
28535 struct d3d9_test_context context;
28536 IDirect3DVertexShader9 *vs;
28537 IDirect3DDevice9 *device;
28538 HRESULT hr;
28540 static const DWORD vs_texcoord1_code[] =
28542 0xfffe0200, /* vs_2_0 */
28543 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
28544 0x0200001f, 0x80010005, 0x900f0001, /* dcl_texcoord1 v1 */
28545 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
28546 0x02000001, 0xd00f0000, 0x90390001, /* mov oD0, v1.yzwx */
28547 0x0000ffff /* end */
28550 static const DWORD vs_texcoord2_code[] =
28552 0xfffe0200, /* vs_2_0 */
28553 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
28554 0x0200001f, 0x80020005, 0x900f0001, /* dcl_texcoord2 v1 */
28555 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
28556 0x02000001, 0xd00f0000, 0x90390001, /* mov oD0, v1.yzwx */
28557 0x0000ffff /* end */
28560 static const DWORD vs_texcoord3_code[] =
28562 0xfffe0200, /* vs_2_0 */
28563 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
28564 0x0200001f, 0x80030005, 0x900f0001, /* dcl_texcoord3 v1 */
28565 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
28566 0x02000001, 0xd00f0000, 0x90390001, /* mov oD0, v1.yzwx */
28567 0x0000ffff /* end */
28570 static const DWORD vs_color1_code[] =
28572 0xfffe0200, /* vs_2_0 */
28573 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
28574 0x0200001f, 0x8001000a, 0x900f0001, /* dcl_color1 v1 */
28575 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
28576 0x02000001, 0xd00f0000, 0x90390001, /* mov oD0, v1.yzwx */
28577 0x0000ffff /* end */
28580 static const DWORD vs_color2_code[] =
28582 0xfffe0200, /* vs_2_0 */
28583 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
28584 0x0200001f, 0x8002000a, 0x900f0001, /* dcl_color2 v1 */
28585 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
28586 0x02000001, 0xd00f0000, 0x90390001, /* mov oD0, v1.yzwx */
28587 0x0000ffff /* end */
28590 static const DWORD vs_color3_code[] =
28592 0xfffe0200, /* vs_2_0 */
28593 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
28594 0x0200001f, 0x8003000a, 0x900f0001, /* dcl_color3 v1 */
28595 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
28596 0x02000001, 0xd00f0000, 0x90390001, /* mov oD0, v1.yzwx */
28597 0x0000ffff /* end */
28600 static const D3DVERTEXELEMENT9 decl_elements[] =
28602 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
28603 {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
28604 {0, 16, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
28605 {0, 24, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 3},
28606 {0, 36, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
28607 {0, 40, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 2},
28608 {0, 48, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 3},
28609 D3DDECL_END()
28612 static const struct
28614 struct vec3 position;
28615 float texcoord1;
28616 struct vec2 texcoord2;
28617 struct vec3 texcoord3;
28618 float color1;
28619 struct vec2 color2;
28620 struct vec3 color3;
28622 quad[] =
28624 {{-1.0f, -1.0f, 0.1f}, 0.1f, {0.2f, 0.2f}, {0.3f, 0.3f, 0.3f}, 0.1f, {0.2f, 0.2f}, {0.3f, 0.3f, 0.3f}},
28625 {{-1.0f, 1.0f, 0.1f}, 0.1f, {0.2f, 0.2f}, {0.3f, 0.3f, 0.3f}, 0.1f, {0.2f, 0.2f}, {0.3f, 0.3f, 0.3f}},
28626 {{ 1.0f, -1.0f, 0.1f}, 0.1f, {0.2f, 0.2f}, {0.3f, 0.3f, 0.3f}, 0.1f, {0.2f, 0.2f}, {0.3f, 0.3f, 0.3f}},
28627 {{ 1.0f, 1.0f, 0.1f}, 0.1f, {0.2f, 0.2f}, {0.3f, 0.3f, 0.3f}, 0.1f, {0.2f, 0.2f}, {0.3f, 0.3f, 0.3f}},
28630 static const struct
28632 const DWORD *vs_code;
28633 D3DCOLOR color;
28635 tests[] =
28637 {vs_texcoord1_code, 0x0000ff},
28638 {vs_texcoord2_code, 0x3300ff},
28639 {vs_texcoord3_code, 0x4c4cff},
28640 {vs_color1_code, 0x0000ff},
28641 {vs_color2_code, 0x3300ff},
28642 {vs_color3_code, 0x4c4cff},
28645 if (!init_test_context(&context))
28646 return;
28647 device = context.device;
28649 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
28650 ok(hr == S_OK, "Got hr %#lx.\n", hr);
28651 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
28652 ok(hr == S_OK, "Got hr %#lx.\n", hr);
28654 for (unsigned int j = 0; j < ARRAY_SIZE(tests); ++j)
28656 winetest_push_context("test %u", j);
28658 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
28659 ok(hr == S_OK, "Got hr %#lx.\n", hr);
28661 hr = IDirect3DDevice9_CreateVertexShader(device, tests[j].vs_code, &vs);
28662 ok(hr == S_OK, "Got hr %#lx.\n", hr);
28663 hr = IDirect3DDevice9_SetVertexShader(device, vs);
28664 ok(hr == S_OK, "Got hr %#lx.\n", hr);
28666 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
28667 ok(hr == S_OK, "Got hr %#lx.\n", hr);
28668 hr = IDirect3DDevice9_BeginScene(device);
28669 ok(hr == S_OK, "Got hr %#lx.\n", hr);
28670 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad, sizeof(*quad));
28671 ok(hr == S_OK, "Got hr %#lx.\n", hr);
28672 hr = IDirect3DDevice9_EndScene(device);
28673 ok(hr == S_OK, "Got hr %#lx.\n", hr);
28675 check_rt_color(context.backbuffer, tests[j].color);
28677 IDirect3DVertexShader9_Release(vs);
28678 winetest_pop_context();
28681 IDirect3DVertexDeclaration9_Release(vertex_declaration);
28682 release_test_context(&context);
28685 static void test_format_conversion(void)
28687 D3DADAPTER_IDENTIFIER9 identifier;
28688 struct d3d9_test_context context;
28689 HRESULT hr;
28691 static const struct
28693 D3DFORMAT src_format;
28694 D3DFORMAT dst_format;
28695 HRESULT expect_hr;
28696 bool broken_warp;
28698 tests[] =
28700 {D3DFMT_X8R8G8B8, D3DFMT_A8R8G8B8, S_OK},
28701 {D3DFMT_A8R8G8B8, D3DFMT_X8R8G8B8, S_OK},
28702 {D3DFMT_R5G6B5, D3DFMT_X8R8G8B8, S_OK},
28703 {D3DFMT_YUY2, D3DFMT_X8R8G8B8, S_OK, .broken_warp = true},
28704 {D3DFMT_YUY2, D3DFMT_R5G6B5, S_OK, .broken_warp = true},
28705 {D3DFMT_R32F, D3DFMT_R16F, D3DERR_NOTAVAILABLE},
28707 {D3DFMT_L8, D3DFMT_L8, S_OK},
28708 {D3DFMT_X8R8G8B8, D3DFMT_L8, D3DERR_NOTAVAILABLE},
28709 {D3DFMT_A8, D3DFMT_L8, D3DERR_NOTAVAILABLE},
28710 {D3DFMT_A8L8, D3DFMT_L8, D3DERR_NOTAVAILABLE},
28711 {D3DFMT_L16, D3DFMT_L8, D3DERR_NOTAVAILABLE},
28712 {D3DFMT_L8, D3DFMT_A8, D3DERR_NOTAVAILABLE},
28713 {D3DFMT_L8, D3DFMT_L16, D3DERR_NOTAVAILABLE},
28714 {D3DFMT_L8, D3DFMT_A8L8, D3DERR_NOTAVAILABLE},
28717 static const D3DFORMAT all_formats[] =
28719 D3DFMT_R8G8B8,
28720 D3DFMT_A8R8G8B8,
28721 D3DFMT_X8R8G8B8,
28722 D3DFMT_R5G6B5,
28723 D3DFMT_X1R5G5B5,
28724 D3DFMT_A1R5G5B5,
28725 D3DFMT_A4R4G4B4,
28726 D3DFMT_R3G3B2,
28727 D3DFMT_A8,
28728 D3DFMT_A8R3G3B2,
28729 D3DFMT_X4R4G4B4,
28730 D3DFMT_A2B10G10R10,
28731 D3DFMT_A8B8G8R8,
28732 D3DFMT_X8B8G8R8,
28733 D3DFMT_G16R16,
28734 D3DFMT_A2R10G10B10,
28735 D3DFMT_A16B16G16R16,
28736 D3DFMT_A8P8,
28737 D3DFMT_P8,
28738 D3DFMT_L8,
28739 D3DFMT_A8L8,
28740 D3DFMT_A4L4,
28741 D3DFMT_V8U8,
28742 D3DFMT_L6V5U5,
28743 D3DFMT_X8L8V8U8,
28744 D3DFMT_Q8W8V8U8,
28745 D3DFMT_V16U16,
28746 D3DFMT_A2W10V10U10,
28747 D3DFMT_UYVY,
28748 D3DFMT_YUY2,
28749 D3DFMT_DXT1,
28750 D3DFMT_DXT2,
28751 D3DFMT_DXT3,
28752 D3DFMT_DXT4,
28753 D3DFMT_DXT5,
28754 D3DFMT_MULTI2_ARGB8,
28755 D3DFMT_G8R8_G8B8,
28756 D3DFMT_R8G8_B8G8,
28757 D3DFMT_D16_LOCKABLE,
28758 D3DFMT_D32,
28759 D3DFMT_D15S1,
28760 D3DFMT_D24S8,
28761 D3DFMT_D24X8,
28762 D3DFMT_D24X4S4,
28763 D3DFMT_D16,
28764 D3DFMT_L16,
28765 D3DFMT_D32F_LOCKABLE,
28766 D3DFMT_D24FS8,
28767 D3DFMT_D32_LOCKABLE,
28768 D3DFMT_S8_LOCKABLE,
28769 D3DFMT_VERTEXDATA,
28770 D3DFMT_INDEX16,
28771 D3DFMT_INDEX32,
28772 D3DFMT_Q16W16V16U16,
28773 D3DFMT_R16F,
28774 D3DFMT_G16R16F,
28775 D3DFMT_A16B16G16R16F,
28776 D3DFMT_R32F,
28777 D3DFMT_G32R32F,
28778 D3DFMT_A32B32G32R32F,
28779 D3DFMT_CxV8U8,
28780 D3DFMT_A1,
28781 D3DFMT_A2B10G10R10_XR_BIAS,
28782 D3DFMT_BINARYBUFFER,
28783 200,
28786 if (!init_test_context(&context))
28787 return;
28789 hr = IDirect3D9_GetAdapterIdentifier(context.d3d, D3DADAPTER_DEFAULT, 0, &identifier);
28790 ok(hr == S_OK, "Failed to get adapter identifier, hr %#lx.\n", hr);
28792 for (unsigned int i = 0; i < ARRAY_SIZE(tests); ++i)
28794 hr = IDirect3D9_CheckDeviceFormatConversion(context.d3d, D3DADAPTER_DEFAULT,
28795 D3DDEVTYPE_HAL, tests[i].src_format, tests[i].dst_format);
28796 todo_wine_if (i == 5)
28797 ok(hr == tests[i].expect_hr
28798 || broken(tests[i].broken_warp && adapter_is_warp(&identifier) && hr == D3DERR_NOTAVAILABLE),
28799 "Got hr %#lx for %u to %u.\n", hr, tests[i].src_format, tests[i].dst_format);
28802 for (unsigned int src_format = 0; src_format < ARRAY_SIZE(all_formats); ++src_format)
28804 for (unsigned int dst_format = 0; dst_format < ARRAY_SIZE(all_formats); ++dst_format)
28806 hr = IDirect3D9_CheckDeviceFormatConversion(context.d3d, D3DADAPTER_DEFAULT,
28807 D3DDEVTYPE_HAL, all_formats[src_format], all_formats[dst_format]);
28808 if (src_format == dst_format)
28809 ok(hr == S_OK, "Got hr %#lx for %u to %u.\n",
28810 hr, all_formats[src_format], all_formats[dst_format]);
28811 else
28812 ok(hr == S_OK || hr == D3DERR_NOTAVAILABLE, "Got hr %#lx for %u to %u.\n",
28813 hr, all_formats[src_format], all_formats[dst_format]);
28817 release_test_context(&context);
28820 START_TEST(visual)
28822 D3DADAPTER_IDENTIFIER9 identifier;
28823 IDirect3D9 *d3d;
28824 HRESULT hr;
28826 if (!(d3d = Direct3DCreate9(D3D_SDK_VERSION)))
28828 skip("could not create D3D9 object\n");
28829 return;
28832 memset(&identifier, 0, sizeof(identifier));
28833 hr = IDirect3D9_GetAdapterIdentifier(d3d, 0, 0, &identifier);
28834 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#lx.\n", hr);
28835 trace("Driver string: \"%s\"\n", identifier.Driver);
28836 trace("Description string: \"%s\"\n", identifier.Description);
28837 /* Only Windows XP's default VGA driver should have an empty description */
28838 ok(identifier.Description[0] || broken(!strcmp(identifier.Driver, "vga.dll")), "Empty driver description.\n");
28839 trace("Device name string: \"%s\"\n", identifier.DeviceName);
28840 ok(identifier.DeviceName[0], "Empty device name.\n");
28841 trace("Driver version %d.%d.%d.%d\n",
28842 HIWORD(identifier.DriverVersion.HighPart), LOWORD(identifier.DriverVersion.HighPart),
28843 HIWORD(identifier.DriverVersion.LowPart), LOWORD(identifier.DriverVersion.LowPart));
28845 IDirect3D9_Release(d3d);
28847 test_sanity();
28848 depth_clamp_test();
28849 stretchrect_test();
28850 test_multisample_stretch_rect();
28851 lighting_test();
28852 test_specular_lighting();
28853 clear_test();
28854 test_clear_different_size_surfaces();
28855 color_fill_test();
28856 fog_test();
28857 test_cube_wrap();
28858 z_range_test();
28859 maxmip_test();
28860 offscreen_test();
28861 ds_size_test();
28862 test_blend();
28863 test_shademode();
28864 srgbtexture_test();
28865 release_buffer_test();
28866 float_texture_test();
28867 g16r16_texture_test();
28868 pixelshader_blending_test();
28869 texture_transform_flags_test();
28870 test_generate_mipmap();
28871 test_mipmap_autogen();
28872 fixed_function_decl_test();
28873 conditional_np2_repeat_test();
28874 fixed_function_bumpmap_test();
28875 test_pointsize();
28876 tssargtemp_test();
28877 np2_stretch_rect_test();
28878 yuv_color_test();
28879 yuv_layout_test();
28880 zwriteenable_test();
28881 alphatest_test();
28882 test_viewport();
28883 test_constant_clamp_vs();
28884 test_compare_instructions();
28885 test_mova();
28886 loop_index_test();
28887 sincos_test();
28888 sgn_test();
28889 clip_planes_test();
28890 test_vshader_input();
28891 test_vshader_float16();
28892 stream_test();
28893 fog_with_shader_test();
28894 texbem_test();
28895 texdepth_test();
28896 texkill_test();
28897 volume_v16u16_test();
28898 constant_clamp_ps_test();
28899 cnd_test();
28900 dp2add_ps_test();
28901 unbound_sampler_test();
28902 nested_loop_test();
28903 pretransformed_varying_test();
28904 vface_register_test();
28905 test_fragment_coords();
28906 multiple_rendertargets_test();
28907 texop_test();
28908 texop_range_test();
28909 alphareplicate_test();
28910 dp3_alpha_test();
28911 depth_buffer_test();
28912 depth_buffer2_test();
28913 depth_blit_test();
28914 intz_test();
28915 test_fetch4();
28916 shadow_test();
28917 fp_special_test();
28918 depth_bounds_test();
28919 srgbwrite_format_test();
28920 update_surface_test();
28921 multisample_get_rtdata_test();
28922 test_multisample_get_front_buffer_data();
28923 zenable_test();
28924 fog_special_test();
28925 volume_srgb_test();
28926 volume_dxtn_test();
28927 add_dirty_rect_test();
28928 test_buffer_no_dirty_update();
28929 multisampled_depth_buffer_test();
28930 resz_test();
28931 stencil_cull_test();
28932 test_per_stage_constant();
28933 test_3dc_formats();
28934 test_fog_interpolation();
28935 test_negative_fixedfunction_fog();
28936 test_position_index();
28937 test_table_fog_zw();
28938 test_signed_formats();
28939 test_multisample_mismatch();
28940 test_texcoordindex();
28941 test_vertex_blending();
28942 test_updatetexture();
28943 test_depthbias();
28944 test_flip();
28945 test_uninitialized_varyings();
28946 test_multisample_init();
28947 test_depth_stencil_init();
28948 test_texture_blending();
28949 test_color_clamping();
28950 test_line_antialiasing_blending();
28951 test_dsy();
28952 test_evict_bound_resources();
28953 test_max_index16();
28954 test_backbuffer_resize();
28955 test_drawindexedprimitiveup();
28956 test_vertex_texture();
28957 test_mvp_software_vertex_shaders();
28958 test_null_format();
28959 test_map_synchronisation();
28960 test_color_vertex();
28961 test_sysmem_draw();
28962 test_nrm_instruction();
28963 test_desktop_window();
28964 test_mismatched_sample_types();
28965 test_draw_mapped_buffer();
28966 test_sample_attached_rendertarget();
28967 test_alpha_to_coverage();
28968 test_sample_mask();
28969 test_dynamic_map_synchronization();
28970 test_filling_convention();
28971 test_managed_reset();
28972 test_managed_generate_mipmap();
28973 test_mipmap_upload();
28974 test_default_diffuse();
28975 test_default_attribute_components();
28976 test_format_conversion();