wined3d: Record a dirty rect in wined3d_texture_create_dc().
[wine.git] / dlls / d3d9 / tests / visual.c
blobbb8381cde3d0ddefaee6707879d0aecb07285bdd
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 <limits.h>
33 #include <math.h>
35 #define COBJMACROS
36 #include <d3d9.h>
37 #include "utils.h"
39 struct vec2
41 float x, y;
44 struct vec3
46 float x, y, z;
49 struct vec4
51 float x, y, z, w;
54 struct d3d9_test_context
56 HWND window;
57 IDirect3D9 *d3d;
58 IDirect3DDevice9 *device;
59 IDirect3DSurface9 *backbuffer;
62 static HWND create_window(void)
64 HWND hwnd;
65 RECT rect;
67 SetRect(&rect, 0, 0, 640, 480);
68 AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW | WS_VISIBLE, FALSE);
69 hwnd = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
70 0, 0, rect.right - rect.left, rect.bottom - rect.top, 0, 0, 0, 0);
71 return hwnd;
74 static BOOL compare_uint(unsigned int x, unsigned int y, unsigned int max_diff)
76 unsigned int diff = x > y ? x - y : y - x;
78 return diff <= max_diff;
81 static BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
83 return compare_uint(c1 & 0xff, c2 & 0xff, max_diff)
84 && compare_uint((c1 >> 8) & 0xff, (c2 >> 8) & 0xff, max_diff)
85 && compare_uint((c1 >> 16) & 0xff, (c2 >> 16) & 0xff, max_diff)
86 && compare_uint((c1 >> 24) & 0xff, (c2 >> 24) & 0xff, max_diff);
89 static BOOL compare_float(float f, float g, unsigned int ulps)
91 int x = *(int *)&f;
92 int y = *(int *)&g;
94 if (x < 0)
95 x = INT_MIN - x;
96 if (y < 0)
97 y = INT_MIN - y;
99 return compare_uint(x, y, ulps);
102 static BOOL compare_vec4(const struct vec4 *vec, float x, float y, float z, float w, unsigned int ulps)
104 return compare_float(vec->x, x, ulps)
105 && compare_float(vec->y, y, ulps)
106 && compare_float(vec->z, z, ulps)
107 && compare_float(vec->w, w, ulps);
110 static BOOL adapter_is_warp(const D3DADAPTER_IDENTIFIER9 *identifier)
112 return !strcmp(identifier->Driver, "d3d10warp.dll");
115 static BOOL adapter_is_vendor(const D3DADAPTER_IDENTIFIER9 *identifier, DWORD vendor)
117 return identifier->VendorId == vendor;
120 static BOOL adapter_is_amd(const D3DADAPTER_IDENTIFIER9 *identifier)
122 return adapter_is_vendor(identifier, 0x1002);
125 static BOOL device_is_d3d10(IDirect3DDevice9 *device)
127 IDirect3D9 *d3d;
128 HRESULT hr;
130 IDirect3DDevice9_GetDirect3D(device, &d3d);
131 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
132 D3DUSAGE_QUERY_FILTER, D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F);
133 IDirect3D9_Release(d3d);
135 return SUCCEEDED(hr);
138 /* Locks a given surface and returns the color at (x,y). It's the caller's
139 * responsibility to only pass in lockable surfaces and valid x,y coordinates */
140 static DWORD getPixelColorFromSurface(IDirect3DSurface9 *surface, UINT x, UINT y)
142 DWORD color;
143 HRESULT hr;
144 D3DSURFACE_DESC desc;
145 RECT rectToLock = {x, y, x+1, y+1};
146 D3DLOCKED_RECT lockedRect;
148 hr = IDirect3DSurface9_GetDesc(surface, &desc);
149 ok(hr == S_OK, "Got hr %#lx.\n", hr);
151 hr = IDirect3DSurface9_LockRect(surface, &lockedRect, &rectToLock, D3DLOCK_READONLY);
152 ok(hr == S_OK, "Got hr %#lx.\n", hr);
154 switch(desc.Format) {
155 case D3DFMT_A8R8G8B8:
157 color = ((DWORD *) lockedRect.pBits)[0];
158 break;
160 default:
161 trace("Error: unknown surface format: %d\n", desc.Format);
162 color = 0xdeadbeef;
163 break;
165 hr = IDirect3DSurface9_UnlockRect(surface);
166 ok(hr == S_OK, "Got hr %#lx.\n", hr);
167 return color;
170 struct surface_readback
172 IDirect3DSurface9 *surface;
173 D3DLOCKED_RECT locked_rect;
176 static void get_rt_readback(IDirect3DSurface9 *surface, struct surface_readback *rb)
178 IDirect3DDevice9 *device;
179 D3DSURFACE_DESC desc;
180 HRESULT hr;
182 memset(rb, 0, sizeof(*rb));
183 hr = IDirect3DSurface9_GetDevice(surface, &device);
184 ok(SUCCEEDED(hr), "Failed to get device, hr %#lx.\n", hr);
185 hr = IDirect3DSurface9_GetDesc(surface, &desc);
186 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#lx.\n", hr);
187 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, desc.Width, desc.Height,
188 desc.Format, D3DPOOL_SYSTEMMEM, &rb->surface, NULL);
189 if (FAILED(hr) || !rb->surface)
191 trace("Can't create an offscreen plain surface to read the render target data, hr %#lx.\n", hr);
192 goto error;
195 hr = IDirect3DDevice9_GetRenderTargetData(device, surface, rb->surface);
196 if (FAILED(hr))
198 trace("Can't read the render target data, hr %#lx.\n", hr);
199 goto error;
202 hr = IDirect3DSurface9_LockRect(rb->surface, &rb->locked_rect, NULL, D3DLOCK_READONLY);
203 if (FAILED(hr))
205 trace("Can't lock the offscreen surface, hr %#lx.\n", hr);
206 goto error;
208 IDirect3DDevice9_Release(device);
210 return;
212 error:
213 if (rb->surface)
214 IDirect3DSurface9_Release(rb->surface);
215 rb->surface = NULL;
216 IDirect3DDevice9_Release(device);
219 static DWORD get_readback_color(struct surface_readback *rb, unsigned int x, unsigned int y)
221 return rb->locked_rect.pBits
222 ? ((DWORD *)rb->locked_rect.pBits)[y * rb->locked_rect.Pitch / sizeof(DWORD) + x] : 0xdeadbeef;
225 static void release_surface_readback(struct surface_readback *rb)
227 HRESULT hr;
229 if (!rb->surface)
230 return;
231 if (rb->locked_rect.pBits && FAILED(hr = IDirect3DSurface9_UnlockRect(rb->surface)))
232 trace("Can't unlock the offscreen surface, hr %#lx.\n", hr);
233 IDirect3DSurface9_Release(rb->surface);
236 static DWORD getPixelColor(IDirect3DDevice9 *device, UINT x, UINT y)
238 DWORD ret;
239 IDirect3DSurface9 *rt;
240 struct surface_readback rb;
241 HRESULT hr;
243 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &rt);
244 ok(hr == S_OK, "Got hr %#lx.\n", hr);
246 get_rt_readback(rt, &rb);
247 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
248 * really important for these tests
250 ret = get_readback_color(&rb, x, y) & 0x00ffffff;
251 release_surface_readback(&rb);
253 IDirect3DSurface9_Release(rt);
254 return ret;
257 static D3DCOLOR check_expected_rt_color(unsigned int line, IDirect3DSurface9 *rt, D3DCOLOR expected_color)
259 unsigned int color = 0xdeadbeef;
260 struct surface_readback rb;
261 D3DSURFACE_DESC desc;
262 unsigned int x, y;
263 HRESULT hr;
265 hr = IDirect3DSurface9_GetDesc(rt, &desc);
266 ok_(__FILE__, line)(hr == S_OK, "Failed to get surface desc, hr %#lx.\n", hr);
268 get_rt_readback(rt, &rb);
269 for (y = 0; y < desc.Height; ++y)
271 for (x = 0; x < desc.Width; ++x)
273 color = get_readback_color(&rb, x, y) & 0x00ffffff;
274 if (color != expected_color)
275 break;
277 if (color != expected_color)
278 break;
280 release_surface_readback(&rb);
281 return color;
284 #define check_rt_color(a, b) check_rt_color_(__LINE__, a, b, false, 0, false)
285 #define check_rt_color_broken(a, b, c, d) check_rt_color_(__LINE__, a, b, false, c, d)
286 #define check_rt_color_todo(a, b) check_rt_color_(__LINE__, a, b, true, 0, false)
287 #define check_rt_color_todo_if(a, b, c) check_rt_color_(__LINE__, a, b, c, 0, false)
288 static void check_rt_color_(unsigned int line, IDirect3DSurface9 *rt, D3DCOLOR expected_color, bool todo,
289 D3DCOLOR broken_color, bool is_broken)
291 unsigned int color = check_expected_rt_color(line, rt, expected_color);
293 todo_wine_if (todo)
294 ok_(__FILE__, line)(color == expected_color || broken(is_broken && color == broken_color),
295 "Got unexpected color 0x%08x.\n", color);
298 static IDirect3DDevice9 *create_device(IDirect3D9 *d3d, HWND device_window, HWND focus_window, BOOL windowed)
300 D3DPRESENT_PARAMETERS present_parameters = {0};
301 IDirect3DDevice9 *device;
303 present_parameters.Windowed = windowed;
304 present_parameters.hDeviceWindow = device_window;
305 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
306 present_parameters.BackBufferWidth = 640;
307 present_parameters.BackBufferHeight = 480;
308 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
309 present_parameters.EnableAutoDepthStencil = TRUE;
310 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
312 if (SUCCEEDED(IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
313 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device)))
314 return device;
316 return NULL;
319 static void cleanup_device(IDirect3DDevice9 *device)
321 if (device)
323 D3DPRESENT_PARAMETERS present_parameters;
324 IDirect3DSwapChain9 *swapchain;
325 ULONG ref;
327 IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
328 IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
329 IDirect3DSwapChain9_Release(swapchain);
330 ref = IDirect3DDevice9_Release(device);
331 ok(!ref, "Unexpected refcount %lu.\n", ref);
332 DestroyWindow(present_parameters.hDeviceWindow);
336 static bool init_test_context(struct d3d9_test_context *context)
338 HRESULT hr;
340 memset(context, 0, sizeof(*context));
342 context->window = create_window();
343 context->d3d = Direct3DCreate9(D3D_SDK_VERSION);
344 ok(!!context->d3d, "Failed to create a D3D object.\n");
345 if (!(context->device = create_device(context->d3d, context->window, context->window, TRUE)))
347 skip("Failed to create a D3D device.\n");
348 IDirect3D9_Release(context->d3d);
349 DestroyWindow(context->window);
350 return false;
353 hr = IDirect3DDevice9_GetRenderTarget(context->device, 0, &context->backbuffer);
354 ok(hr == S_OK, "Failed to get backbuffer, hr %#lx.\n", hr);
356 return true;
359 #define release_test_context(a) release_test_context_(__LINE__, a)
360 static void release_test_context_(unsigned int line, struct d3d9_test_context *context)
362 ULONG refcount;
364 IDirect3DSurface9_Release(context->backbuffer);
365 refcount = IDirect3DDevice9_Release(context->device);
366 ok(!refcount, "Device has %lu references left.\n", refcount);
367 refcount = IDirect3D9_Release(context->d3d);
368 ok(!refcount, "D3D object has %lu references left.\n", refcount);
369 DestroyWindow(context->window);
372 static void draw_textured_quad(struct d3d9_test_context *context, IDirect3DTexture9 *texture)
374 IDirect3DDevice9 *device = context->device;
375 HRESULT hr;
377 static const struct
379 struct vec3 position;
380 struct vec2 texcoord;
382 quad[] =
384 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f}},
385 {{-1.0f, 1.0f, 0.0f}, {0.0f, 1.0f}},
386 {{ 1.0f, -1.0f, 0.0f}, {1.0f, 0.0f}},
387 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 1.0f}},
390 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
391 ok(hr == S_OK, "Got hr %#lx.\n", hr);
392 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
393 ok(hr == S_OK, "Got hr %#lx.\n", hr);
394 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
395 ok(hr == S_OK, "Got hr %#lx.\n", hr);
396 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
397 ok(hr == S_OK, "Got hr %#lx.\n", hr);
398 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
399 ok(hr == S_OK, "Got hr %#lx.\n", hr);
400 hr = IDirect3DDevice9_BeginScene(device);
401 ok(hr == S_OK, "Got hr %#lx.\n", hr);
402 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad, sizeof(*quad));
403 ok(hr == S_OK, "Got hr %#lx.\n", hr);
404 hr = IDirect3DDevice9_EndScene(device);
405 ok(hr == S_OK, "Got hr %#lx.\n", hr);
408 static HRESULT reset_device(struct d3d9_test_context *context)
410 D3DPRESENT_PARAMETERS present_parameters = {0};
411 HRESULT hr;
413 IDirect3DSurface9_Release(context->backbuffer);
415 present_parameters.BackBufferWidth = 640;
416 present_parameters.BackBufferHeight = 480;
417 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
418 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
419 present_parameters.hDeviceWindow = context->window;
420 present_parameters.Windowed = TRUE;
421 present_parameters.EnableAutoDepthStencil = TRUE;
422 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
423 hr = IDirect3DDevice9_Reset(context->device, &present_parameters);
425 if (SUCCEEDED(hr))
426 IDirect3DDevice9_GetRenderTarget(context->device, 0, &context->backbuffer);
428 return hr;
431 static void test_sanity(void)
433 IDirect3DDevice9 *device;
434 unsigned int color;
435 IDirect3D9 *d3d;
436 ULONG refcount;
437 HWND window;
438 HRESULT hr;
440 window = create_window();
441 d3d = Direct3DCreate9(D3D_SDK_VERSION);
442 ok(!!d3d, "Failed to create a D3D object.\n");
443 if (!(device = create_device(d3d, window, window, TRUE)))
445 skip("Failed to create a D3D device, skipping tests.\n");
446 goto done;
449 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
450 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
451 color = getPixelColor(device, 1, 1);
452 ok(color == 0x00ff0000, "Got unexpected color 0x%08x.\n", color);
454 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
455 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
457 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
458 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
459 color = getPixelColor(device, 639, 479);
460 ok(color == 0x0000ddee, "Got unexpected color 0x%08x.\n", color);
462 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
463 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
465 refcount = IDirect3DDevice9_Release(device);
466 ok(!refcount, "Device has %lu references left.\n", refcount);
467 done:
468 IDirect3D9_Release(d3d);
469 DestroyWindow(window);
472 static void lighting_test(void)
474 DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
475 DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
476 IDirect3DDevice9 *device;
477 D3DMATERIAL9 material;
478 unsigned int color, i;
479 IDirect3D9 *d3d;
480 ULONG refcount;
481 HWND window;
482 HRESULT hr;
484 static const D3DMATRIX mat =
486 1.0f, 0.0f, 0.0f, 0.0f,
487 0.0f, 1.0f, 0.0f, 0.0f,
488 0.0f, 0.0f, 1.0f, 0.0f,
489 0.0f, 0.0f, 0.0f, 1.0f,
490 }}},
491 mat_singular =
493 1.0f, 0.0f, 1.0f, 0.0f,
494 0.0f, 1.0f, 0.0f, 0.0f,
495 1.0f, 0.0f, 1.0f, 0.0f,
496 0.0f, 0.0f, 0.5f, 1.0f,
497 }}},
498 mat_transf =
500 0.0f, 0.0f, 1.0f, 0.0f,
501 0.0f, 1.0f, 0.0f, 0.0f,
502 -1.0f, 0.0f, 0.0f, 0.0f,
503 10.f, 10.0f, 10.0f, 1.0f,
504 }}},
505 mat_nonaffine =
507 1.0f, 0.0f, 0.0f, 0.0f,
508 0.0f, 1.0f, 0.0f, 0.0f,
509 0.0f, 0.0f, 1.0f, -1.0f,
510 10.f, 10.0f, 10.0f, 0.0f,
511 }}};
512 static const struct
514 struct vec3 position;
515 DWORD diffuse;
517 unlitquad[] =
519 {{-1.0f, -1.0f, 0.1f}, 0xffff0000},
520 {{-1.0f, 0.0f, 0.1f}, 0xffff0000},
521 {{ 0.0f, 0.0f, 0.1f}, 0xffff0000},
522 {{ 0.0f, -1.0f, 0.1f}, 0xffff0000},
524 litquad[] =
526 {{-1.0f, 0.0f, 0.1f}, 0xff00ff00},
527 {{-1.0f, 1.0f, 0.1f}, 0xff00ff00},
528 {{ 0.0f, 1.0f, 0.1f}, 0xff00ff00},
529 {{ 0.0f, 0.0f, 0.1f}, 0xff00ff00},
531 lighting_test[] =
533 {{-1.0f, -1.0f, 0.1f}, 0x8000ff00},
534 {{ 1.0f, -1.0f, 0.1f}, 0x80000000},
535 {{-1.0f, 1.0f, 0.1f}, 0x8000ff00},
536 {{ 1.0f, 1.0f, 0.1f}, 0x80000000},
538 static const struct
540 struct vec3 position;
541 struct vec3 normal;
542 DWORD diffuse;
544 unlitnquad[] =
546 {{0.0f, -1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
547 {{0.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
548 {{1.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
549 {{1.0f, -1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
551 litnquad[] =
553 {{0.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
554 {{0.0f, 1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
555 {{1.0f, 1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
556 {{1.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
558 nquad[] =
560 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
561 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
562 {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
563 {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
565 rotatedquad[] =
567 {{-10.0f, -11.0f, 11.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
568 {{-10.0f, -9.0f, 11.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
569 {{-10.0f, -9.0f, 9.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
570 {{-10.0f, -11.0f, 9.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
572 translatedquad[] =
574 {{-11.0f, -11.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
575 {{-11.0f, -9.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
576 {{ -9.0f, -9.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
577 {{ -9.0f, -11.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
579 static const WORD indices[] = {0, 1, 2, 2, 3, 0};
580 static const struct
582 const D3DMATRIX *world_matrix;
583 const void *quad;
584 unsigned int size;
585 DWORD expected;
586 const char *message;
588 tests[] =
590 {&mat, nquad, sizeof(nquad[0]), 0x000000ff, "Lit quad with light"},
591 {&mat_singular, nquad, sizeof(nquad[0]), 0x000000ff, "Lit quad with singular world matrix"},
592 {&mat_transf, rotatedquad, sizeof(rotatedquad[0]), 0x000000ff, "Lit quad with transformation matrix"},
593 {&mat_nonaffine, translatedquad, sizeof(translatedquad[0]), 0x00000000, "Lit quad with non-affine matrix"},
596 window = create_window();
597 d3d = Direct3DCreate9(D3D_SDK_VERSION);
598 ok(!!d3d, "Failed to create a D3D object.\n");
599 if (!(device = create_device(d3d, window, window, TRUE)))
601 skip("Failed to create a D3D device, skipping tests.\n");
602 goto done;
605 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
606 ok(hr == S_OK, "Got hr %#lx.\n", hr);
608 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), &mat);
609 ok(hr == S_OK, "Got hr %#lx.\n", hr);
610 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &mat);
611 ok(hr == S_OK, "Got hr %#lx.\n", hr);
612 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &mat);
613 ok(hr == S_OK, "Got hr %#lx.\n", hr);
614 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
615 ok(hr == S_OK, "Got hr %#lx.\n", hr);
616 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
617 ok(hr == S_OK, "Got hr %#lx.\n", hr);
618 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
619 ok(hr == S_OK, "Got hr %#lx.\n", hr);
620 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
621 ok(hr == S_OK, "Got hr %#lx.\n", hr);
622 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
623 ok(hr == S_OK, "Got hr %#lx.\n", hr);
625 hr = IDirect3DDevice9_SetFVF(device, fvf);
626 ok(hr == S_OK, "Got hr %#lx.\n", hr);
628 hr = IDirect3DDevice9_BeginScene(device);
629 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
631 /* No lights are defined... That means, lit vertices should be entirely black */
632 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
633 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
634 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
635 2, indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
636 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
638 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
639 ok(SUCCEEDED(hr), "Failed to enable lighting, hr %#lx.\n", hr);
640 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
641 2, indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
642 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
644 hr = IDirect3DDevice9_SetFVF(device, nfvf);
645 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
647 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
648 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
649 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
650 2, indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
651 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
653 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
654 ok(SUCCEEDED(hr), "Failed to enable lighting, hr %#lx.\n", hr);
655 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
656 2, indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
657 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
659 hr = IDirect3DDevice9_EndScene(device);
660 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
662 color = getPixelColor(device, 160, 360); /* Lower left quad - unlit without normals */
663 ok(color == 0x00ff0000, "Unlit quad without normals has color 0x%08x, expected 0x00ff0000.\n", color);
664 color = getPixelColor(device, 160, 120); /* Upper left quad - lit without normals */
665 ok(color == 0x00000000, "Lit quad without normals has color 0x%08x, expected 0x00000000.\n", color);
666 color = getPixelColor(device, 480, 360); /* Lower left quad - unlit with normals */
667 ok(color == 0x000000ff, "Unlit quad with normals has color 0x%08x, expected 0x000000ff.\n", color);
668 color = getPixelColor(device, 480, 120); /* Upper left quad - lit with normals */
669 ok(color == 0x00000000, "Lit quad with normals has color 0x%08x, expected 0x00000000.\n", color);
671 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
673 hr = IDirect3DDevice9_LightEnable(device, 0, TRUE);
674 ok(SUCCEEDED(hr), "Failed to enable light 0, hr %#lx.\n", hr);
676 for (i = 0; i < ARRAY_SIZE(tests); ++i)
678 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, tests[i].world_matrix);
679 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#lx.\n", hr);
681 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
682 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
684 hr = IDirect3DDevice9_BeginScene(device);
685 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
687 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
688 2, indices, D3DFMT_INDEX16, tests[i].quad, tests[i].size);
689 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
691 hr = IDirect3DDevice9_EndScene(device);
692 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
694 color = getPixelColor(device, 320, 240);
695 ok(color == tests[i].expected, "%s has color 0x%08x.\n", tests[i].message, color);
698 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &mat);
699 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#lx.\n", hr);
700 hr = IDirect3DDevice9_LightEnable(device, 0, FALSE);
701 ok(SUCCEEDED(hr), "Failed to disable light 0, hr %#lx.\n", hr);
703 memset(&material, 0, sizeof(material));
704 material.Diffuse.r = 0.0;
705 material.Diffuse.g = 0.0;
706 material.Diffuse.b = 0.0;
707 material.Diffuse.a = 1.0;
708 material.Ambient.r = 0.0;
709 material.Ambient.g = 0.0;
710 material.Ambient.b = 0.0;
711 material.Ambient.a = 0.0;
712 material.Specular.r = 0.0;
713 material.Specular.g = 0.0;
714 material.Specular.b = 0.0;
715 material.Specular.a = 0.0;
716 material.Emissive.r = 0.0;
717 material.Emissive.g = 0.0;
718 material.Emissive.b = 0.0;
719 material.Emissive.a = 0.0;
720 material.Power = 0.0;
721 hr = IDirect3DDevice9_SetMaterial(device, &material);
722 ok(hr == S_OK, "Got hr %#lx.\n", hr);
724 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
725 ok(hr == S_OK, "Got hr %#lx.\n", hr);
726 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
727 ok(hr == S_OK, "Got hr %#lx.\n", hr);
729 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
730 ok(hr == S_OK, "Got hr %#lx.\n", hr);
731 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
732 ok(hr == S_OK, "Got hr %#lx.\n", hr);
734 hr = IDirect3DDevice9_BeginScene(device);
735 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
737 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
738 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
739 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, lighting_test, sizeof(lighting_test[0]));
740 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
742 hr = IDirect3DDevice9_EndScene(device);
743 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
745 color = getPixelColor(device, 320, 240);
746 ok(color == 0x00ffffff, "Lit vertex alpha test returned color %08x, expected 0x00ffffff\n", color);
747 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
749 refcount = IDirect3DDevice9_Release(device);
750 ok(!refcount, "Device has %lu references left.\n", refcount);
751 done:
752 IDirect3D9_Release(d3d);
753 DestroyWindow(window);
756 static void test_specular_lighting(void)
758 static const unsigned int vertices_side = 5;
759 const unsigned int indices_count = (vertices_side - 1) * (vertices_side - 1) * 2 * 3;
760 static const DWORD fvf = D3DFVF_XYZ | D3DFVF_NORMAL;
761 static const D3DMATRIX mat =
763 1.0f, 0.0f, 0.0f, 0.0f,
764 0.0f, 1.0f, 0.0f, 0.0f,
765 0.0f, 0.0f, 1.0f, 0.0f,
766 0.0f, 0.0f, 0.0f, 1.0f,
767 }}};
768 static const D3DLIGHT9 directional =
770 D3DLIGHT_DIRECTIONAL,
771 {0.0f, 0.0f, 0.0f, 0.0f},
772 {1.0f, 1.0f, 1.0f, 0.0f},
773 {0.0f, 0.0f, 0.0f, 0.0f},
774 {0.0f, 0.0f, 0.0f},
775 {0.0f, 0.0f, 1.0f},
777 point =
779 D3DLIGHT_POINT,
780 {0.0f, 0.0f, 0.0f, 0.0f},
781 {1.0f, 1.0f, 1.0f, 0.0f},
782 {0.0f, 0.0f, 0.0f, 0.0f},
783 {0.0f, 0.0f, 0.0f},
784 {0.0f, 0.0f, 0.0f},
785 100.0f,
786 0.0f,
787 0.0f, 0.0f, 1.0f,
789 spot =
791 D3DLIGHT_SPOT,
792 {0.0f, 0.0f, 0.0f, 0.0f},
793 {1.0f, 1.0f, 1.0f, 0.0f},
794 {0.0f, 0.0f, 0.0f, 0.0f},
795 {0.0f, 0.0f, 0.0f},
796 {0.0f, 0.0f, 1.0f},
797 100.0f,
798 1.0f,
799 0.0f, 0.0f, 1.0f,
800 M_PI / 12.0f, M_PI / 3.0f
802 /* The chosen range value makes the test fail when using a manhattan
803 * distance metric vs the correct euclidean distance. */
804 point_range =
806 D3DLIGHT_POINT,
807 {0.0f, 0.0f, 0.0f, 0.0f},
808 {1.0f, 1.0f, 1.0f, 0.0f},
809 {0.0f, 0.0f, 0.0f, 0.0f},
810 {0.0f, 0.0f, 0.0f},
811 {0.0f, 0.0f, 0.0f},
812 1.2f,
813 0.0f,
814 0.0f, 0.0f, 1.0f,
816 point_side =
818 D3DLIGHT_POINT,
819 {0.0f, 0.0f, 0.0f, 0.0f},
820 {1.0f, 1.0f, 1.0f, 0.0f},
821 {0.0f, 0.0f, 0.0f, 0.0f},
822 {-1.1f, 0.0f, 1.1f},
823 {0.0f, 0.0f, 0.0f},
824 100.0f,
825 0.0f,
826 0.0f, 0.0f, 1.0f,
828 static const struct expected_color
830 unsigned int x, y, color;
832 expected_directional[] =
834 {160, 120, 0x00ffffff},
835 {320, 120, 0x00ffffff},
836 {480, 120, 0x00ffffff},
837 {160, 240, 0x00ffffff},
838 {320, 240, 0x00ffffff},
839 {480, 240, 0x00ffffff},
840 {160, 360, 0x00ffffff},
841 {320, 360, 0x00ffffff},
842 {480, 360, 0x00ffffff},
844 expected_directional_local[] =
846 {160, 120, 0x003c3c3c},
847 {320, 120, 0x00717171},
848 {480, 120, 0x003c3c3c},
849 {160, 240, 0x00717171},
850 {320, 240, 0x00ffffff},
851 {480, 240, 0x00717171},
852 {160, 360, 0x003c3c3c},
853 {320, 360, 0x00717171},
854 {480, 360, 0x003c3c3c},
856 expected_point[] =
858 {160, 120, 0x00282828},
859 {320, 120, 0x005a5a5a},
860 {480, 120, 0x00282828},
861 {160, 240, 0x005a5a5a},
862 {320, 240, 0x00ffffff},
863 {480, 240, 0x005a5a5a},
864 {160, 360, 0x00282828},
865 {320, 360, 0x005a5a5a},
866 {480, 360, 0x00282828},
868 expected_point_local[] =
870 {160, 120, 0x00000000},
871 {320, 120, 0x00070707},
872 {480, 120, 0x00000000},
873 {160, 240, 0x00070707},
874 {320, 240, 0x00ffffff},
875 {480, 240, 0x00070707},
876 {160, 360, 0x00000000},
877 {320, 360, 0x00070707},
878 {480, 360, 0x00000000},
880 expected_spot[] =
882 {160, 120, 0x00000000},
883 {320, 120, 0x00141414},
884 {480, 120, 0x00000000},
885 {160, 240, 0x00141414},
886 {320, 240, 0x00ffffff},
887 {480, 240, 0x00141414},
888 {160, 360, 0x00000000},
889 {320, 360, 0x00141414},
890 {480, 360, 0x00000000},
892 expected_spot_local[] =
894 {160, 120, 0x00000000},
895 {320, 120, 0x00020202},
896 {480, 120, 0x00000000},
897 {160, 240, 0x00020202},
898 {320, 240, 0x00ffffff},
899 {480, 240, 0x00020202},
900 {160, 360, 0x00000000},
901 {320, 360, 0x00020202},
902 {480, 360, 0x00000000},
904 expected_point_range[] =
906 {160, 120, 0x00000000},
907 {320, 120, 0x005a5a5a},
908 {480, 120, 0x00000000},
909 {160, 240, 0x005a5a5a},
910 {320, 240, 0x00ffffff},
911 {480, 240, 0x005a5a5a},
912 {160, 360, 0x00000000},
913 {320, 360, 0x005a5a5a},
914 {480, 360, 0x00000000},
916 expected_point_side[] =
918 {160, 120, 0x00000000},
919 {320, 120, 0x00000000},
920 {480, 120, 0x00000000},
921 {160, 240, 0x00000000},
922 {320, 240, 0x00000000},
923 {480, 240, 0x00000000},
924 {160, 360, 0x00000000},
925 {320, 360, 0x00000000},
926 {480, 360, 0x00000000},
928 expected_directional_0[] =
930 {160, 120, 0x00ffffff},
931 {320, 120, 0x00ffffff},
932 {480, 120, 0x00ffffff},
933 {160, 240, 0x00ffffff},
934 {320, 240, 0x00ffffff},
935 {480, 240, 0x00ffffff},
936 {160, 360, 0x00ffffff},
937 {320, 360, 0x00ffffff},
938 {480, 360, 0x00ffffff},
940 expected_directional_local_0[] =
942 {160, 120, 0x00ffffff},
943 {320, 120, 0x00ffffff},
944 {480, 120, 0x00ffffff},
945 {160, 240, 0x00ffffff},
946 {320, 240, 0x00ffffff},
947 {480, 240, 0x00ffffff},
948 {160, 360, 0x00ffffff},
949 {320, 360, 0x00ffffff},
950 {480, 360, 0x00ffffff},
952 expected_point_0[] =
954 {160, 120, 0x00aaaaaa},
955 {320, 120, 0x00cccccc},
956 {480, 120, 0x00aaaaaa},
957 {160, 240, 0x00cccccc},
958 {320, 240, 0x00ffffff},
959 {480, 240, 0x00cccccc},
960 {160, 360, 0x00aaaaaa},
961 {320, 360, 0x00cccccc},
962 {480, 360, 0x00aaaaaa},
964 expected_spot_0[] =
966 {160, 120, 0x00000000},
967 {320, 120, 0x002e2e2e},
968 {480, 120, 0x00000000},
969 {160, 240, 0x002e2e2e},
970 {320, 240, 0x00ffffff},
971 {480, 240, 0x002e2e2e},
972 {160, 360, 0x00000000},
973 {320, 360, 0x002e2e2e},
974 {480, 360, 0x00000000},
976 expected_point_range_0[] =
978 {160, 120, 0x00000000},
979 {320, 120, 0x00cccccc},
980 {480, 120, 0x00000000},
981 {160, 240, 0x00cccccc},
982 {320, 240, 0x00ffffff},
983 {480, 240, 0x00cccccc},
984 {160, 360, 0x00000000},
985 {320, 360, 0x00cccccc},
986 {480, 360, 0x00000000},
989 static const struct
991 const D3DLIGHT9 *light;
992 BOOL local_viewer;
993 float specular_power;
994 const struct expected_color *expected;
995 unsigned int expected_count;
997 tests[] =
999 {&directional, FALSE, 30.0f, expected_directional, ARRAY_SIZE(expected_directional)},
1000 {&directional, TRUE, 30.0f, expected_directional_local, ARRAY_SIZE(expected_directional_local)},
1001 {&point, FALSE, 30.0f, expected_point, ARRAY_SIZE(expected_point)},
1002 {&point, TRUE, 30.0f, expected_point_local, ARRAY_SIZE(expected_point_local)},
1003 {&spot, FALSE, 30.0f, expected_spot, ARRAY_SIZE(expected_spot)},
1004 {&spot, TRUE, 30.0f, expected_spot_local, ARRAY_SIZE(expected_spot_local)},
1005 {&point_range, FALSE, 30.0f, expected_point_range, ARRAY_SIZE(expected_point_range)},
1006 {&point_side, TRUE, 0.0f, expected_point_side, ARRAY_SIZE(expected_point_side)},
1007 {&directional, FALSE, 0.0f, expected_directional_0, ARRAY_SIZE(expected_directional_0)},
1008 {&directional, TRUE, 0.0f, expected_directional_local_0, ARRAY_SIZE(expected_directional_local_0)},
1009 {&point, FALSE, 0.0f, expected_point_0, ARRAY_SIZE(expected_point_0)},
1010 {&point, TRUE, 0.0f, expected_point_0, ARRAY_SIZE(expected_point_0)},
1011 {&spot, FALSE, 0.0f, expected_spot_0, ARRAY_SIZE(expected_spot_0)},
1012 {&spot, TRUE, 0.0f, expected_spot_0, ARRAY_SIZE(expected_spot_0)},
1013 {&point_range, FALSE, 0.0f, expected_point_range_0, ARRAY_SIZE(expected_point_range_0)},
1015 unsigned int color, i, j, x, y;
1016 IDirect3DDevice9 *device;
1017 D3DMATERIAL9 material;
1018 IDirect3D9 *d3d;
1019 ULONG refcount;
1020 HWND window;
1021 HRESULT hr;
1022 struct
1024 struct vec3 position;
1025 struct vec3 normal;
1026 } *quad;
1027 WORD *indices;
1029 quad = malloc(vertices_side * vertices_side * sizeof(*quad));
1030 indices = malloc(indices_count * sizeof(*indices));
1031 for (i = 0, y = 0; y < vertices_side; ++y)
1033 for (x = 0; x < vertices_side; ++x)
1035 quad[i].position.x = x * 2.0f / (vertices_side - 1) - 1.0f;
1036 quad[i].position.y = y * 2.0f / (vertices_side - 1) - 1.0f;
1037 quad[i].position.z = 1.0f;
1038 quad[i].normal.x = 0.0f;
1039 quad[i].normal.y = 0.0f;
1040 quad[i++].normal.z = -1.0f;
1043 for (i = 0, y = 0; y < (vertices_side - 1); ++y)
1045 for (x = 0; x < (vertices_side - 1); ++x)
1047 indices[i++] = y * vertices_side + x + 1;
1048 indices[i++] = y * vertices_side + x;
1049 indices[i++] = (y + 1) * vertices_side + x;
1050 indices[i++] = y * vertices_side + x + 1;
1051 indices[i++] = (y + 1) * vertices_side + x;
1052 indices[i++] = (y + 1) * vertices_side + x + 1;
1056 window = create_window();
1057 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1058 ok(!!d3d, "Failed to create a D3D object.\n");
1059 if (!(device = create_device(d3d, window, window, TRUE)))
1061 skip("Failed to create a D3D device, skipping tests.\n");
1062 goto done;
1065 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &mat);
1066 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#lx.\n", hr);
1067 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &mat);
1068 ok(SUCCEEDED(hr), "Failed to set view transform, hr %#lx.\n", hr);
1069 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &mat);
1070 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#lx.\n", hr);
1071 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
1072 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#lx.\n", hr);
1073 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
1074 ok(SUCCEEDED(hr), "Failed to disable z test, hr %#lx.\n", hr);
1075 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1076 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#lx.\n", hr);
1078 hr = IDirect3DDevice9_SetFVF(device, fvf);
1079 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
1081 hr = IDirect3DDevice9_LightEnable(device, 0, TRUE);
1082 ok(SUCCEEDED(hr), "Failed to enable light 0, hr %#lx.\n", hr);
1083 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARENABLE, TRUE);
1084 ok(SUCCEEDED(hr), "Failed to enable specular lighting, hr %#lx.\n", hr);
1086 for (i = 0; i < ARRAY_SIZE(tests); ++i)
1088 hr = IDirect3DDevice9_SetLight(device, 0, tests[i].light);
1089 ok(SUCCEEDED(hr), "Failed to set light parameters, hr %#lx.\n", hr);
1091 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LOCALVIEWER, tests[i].local_viewer);
1092 ok(SUCCEEDED(hr), "Failed to set local viewer state, hr %#lx.\n", hr);
1094 memset(&material, 0, sizeof(material));
1095 material.Specular.r = 1.0f;
1096 material.Specular.g = 1.0f;
1097 material.Specular.b = 1.0f;
1098 material.Specular.a = 1.0f;
1099 material.Power = tests[i].specular_power;
1100 hr = IDirect3DDevice9_SetMaterial(device, &material);
1101 ok(SUCCEEDED(hr), "Failed to set material, hr %#lx.\n", hr);
1103 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
1104 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
1106 hr = IDirect3DDevice9_BeginScene(device);
1107 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
1109 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST,
1110 0, vertices_side * vertices_side, indices_count / 3, indices,
1111 D3DFMT_INDEX16, quad, sizeof(quad[0]));
1112 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
1114 hr = IDirect3DDevice9_EndScene(device);
1115 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
1117 for (j = 0; j < tests[i].expected_count; ++j)
1119 color = getPixelColor(device, tests[i].expected[j].x, tests[i].expected[j].y);
1120 ok(color_match(color, tests[i].expected[j].color, 1),
1121 "Expected color 0x%08x at location (%u, %u), got 0x%08x, case %u.\n",
1122 tests[i].expected[j].color, tests[i].expected[j].x,
1123 tests[i].expected[j].y, color, i);
1127 refcount = IDirect3DDevice9_Release(device);
1128 ok(!refcount, "Device has %lu references left.\n", refcount);
1129 done:
1130 IDirect3D9_Release(d3d);
1131 DestroyWindow(window);
1132 free(indices);
1133 free(quad);
1136 static void clear_test(void)
1138 static const D3DMATRIX mat =
1140 1.0f, 0.0f, 0.0f, 0.0f,
1141 0.0f, 1.0f, 0.0f, 0.0f,
1142 0.0f, 0.0f, 1.0f, 0.0f,
1143 0.0f, 0.0f, 0.0f, 1.0f,
1144 }}};
1145 static const struct
1147 struct vec3 position;
1148 DWORD diffuse;
1150 quad[] =
1152 {{-1.0f, -1.0f, 0.1f}, 0xff7f7f7f},
1153 {{ 1.0f, -1.0f, 0.1f}, 0xff7f7f7f},
1154 {{-1.0f, 1.0f, 0.1f}, 0xff7f7f7f},
1155 {{ 1.0f, 1.0f, 0.1f}, 0xff7f7f7f},
1157 IDirect3DSurface9 *surface0, *surface1, *backbuffer;
1158 IDirect3DTexture9 *texture;
1159 HRESULT hr;
1160 D3DRECT rect[2];
1161 D3DRECT rect_negneg;
1162 D3DVIEWPORT9 old_vp, vp;
1163 RECT scissor;
1164 DWORD oldColorWrite;
1165 BOOL invalid_clear_failed = FALSE, srgb_supported;
1166 IDirect3DDevice9 *device;
1167 unsigned int color;
1168 IDirect3D9 *d3d;
1169 ULONG refcount;
1170 HWND window;
1172 window = create_window();
1173 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1174 ok(!!d3d, "Failed to create a D3D object.\n");
1175 if (!(device = create_device(d3d, window, window, TRUE)))
1177 skip("Failed to create a D3D device, skipping tests.\n");
1178 goto done;
1181 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
1182 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1184 /* Positive x, negative y */
1185 rect[0].x1 = 0;
1186 rect[0].y1 = 480;
1187 rect[0].x2 = 320;
1188 rect[0].y2 = 240;
1190 /* Positive x, positive y */
1191 rect[1].x1 = 0;
1192 rect[1].y1 = 0;
1193 rect[1].x2 = 320;
1194 rect[1].y2 = 240;
1195 /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
1196 * returns D3D_OK, but ignores the rectangle silently
1198 hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1199 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
1200 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
1202 /* negative x, negative y */
1203 rect_negneg.x1 = 640;
1204 rect_negneg.y1 = 240;
1205 rect_negneg.x2 = 320;
1206 rect_negneg.y2 = 0;
1207 hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
1208 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
1209 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
1211 color = getPixelColor(device, 160, 360); /* lower left quad */
1212 ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
1213 color = getPixelColor(device, 160, 120); /* upper left quad */
1214 if(invalid_clear_failed) {
1215 /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
1216 ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
1217 } else {
1218 /* If the negative rectangle was dropped silently, the correct ones are cleared */
1219 ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
1221 color = getPixelColor(device, 480, 360); /* lower right quad */
1222 ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
1223 color = getPixelColor(device, 480, 120); /* upper right quad */
1224 ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
1226 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1228 /* Hack to work around a nvidia windows driver bug. The clear below is supposed to
1229 * clear the red quad in the top left part of the render target. For some reason it
1230 * doesn't work if the clear color is 0xffffffff on some versions of the Nvidia Windows
1231 * driver(tested on 8.17.12.5896, Win7). A clear with a different color works around
1232 * this bug and fixes the clear with the white color. Even 0xfeffffff works, but let's
1233 * pick some obvious value
1235 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbabe, 0.0, 0);
1236 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1238 /* Test how the viewport affects clears */
1239 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
1240 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1241 hr = IDirect3DDevice9_GetViewport(device, &old_vp);
1242 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1244 vp.X = 160;
1245 vp.Y = 120;
1246 vp.Width = 160;
1247 vp.Height = 120;
1248 vp.MinZ = 0.0;
1249 vp.MaxZ = 1.0;
1250 hr = IDirect3DDevice9_SetViewport(device, &vp);
1251 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1252 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
1253 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1255 vp.X = 320;
1256 vp.Y = 240;
1257 vp.Width = 320;
1258 vp.Height = 240;
1259 vp.MinZ = 0.0;
1260 vp.MaxZ = 1.0;
1261 hr = IDirect3DDevice9_SetViewport(device, &vp);
1262 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1263 rect[0].x1 = 160;
1264 rect[0].y1 = 120;
1265 rect[0].x2 = 480;
1266 rect[0].y2 = 360;
1267 hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
1268 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1270 hr = IDirect3DDevice9_SetViewport(device, &old_vp);
1271 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1273 color = getPixelColor(device, 158, 118);
1274 ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
1275 color = getPixelColor(device, 162, 118);
1276 ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
1277 color = getPixelColor(device, 158, 122);
1278 ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
1279 color = getPixelColor(device, 162, 122);
1280 ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
1282 color = getPixelColor(device, 318, 238);
1283 ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
1284 color = getPixelColor(device, 322, 238);
1285 ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
1286 color = getPixelColor(device, 318, 242);
1287 ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
1288 color = getPixelColor(device, 322, 242);
1289 ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
1291 color = getPixelColor(device, 478, 358);
1292 ok(color == 0x0000ff00, "(478,358) has color %08x\n", color);
1293 color = getPixelColor(device, 482, 358);
1294 ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
1295 color = getPixelColor(device, 478, 362);
1296 ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
1297 color = getPixelColor(device, 482, 362);
1298 ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
1300 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1302 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
1303 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1305 SetRect(&scissor, 160, 120, 480, 360);
1306 hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
1307 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1308 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
1309 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1311 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
1312 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1313 hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1314 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1316 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
1317 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1319 color = getPixelColor(device, 158, 118);
1320 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
1321 color = getPixelColor(device, 162, 118);
1322 ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
1323 color = getPixelColor(device, 158, 122);
1324 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
1325 color = getPixelColor(device, 162, 122);
1326 ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
1328 color = getPixelColor(device, 158, 358);
1329 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
1330 color = getPixelColor(device, 162, 358);
1331 ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
1332 color = getPixelColor(device, 158, 358);
1333 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
1334 color = getPixelColor(device, 162, 362);
1335 ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
1337 color = getPixelColor(device, 478, 118);
1338 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
1339 color = getPixelColor(device, 478, 122);
1340 ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
1341 color = getPixelColor(device, 482, 122);
1342 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
1343 color = getPixelColor(device, 482, 358);
1344 ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
1346 color = getPixelColor(device, 478, 358);
1347 ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
1348 color = getPixelColor(device, 478, 362);
1349 ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
1350 color = getPixelColor(device, 482, 358);
1351 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
1352 color = getPixelColor(device, 482, 362);
1353 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
1355 color = getPixelColor(device, 318, 238);
1356 ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
1357 color = getPixelColor(device, 318, 242);
1358 ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
1359 color = getPixelColor(device, 322, 238);
1360 ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
1361 color = getPixelColor(device, 322, 242);
1362 ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
1364 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1366 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
1367 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1368 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
1369 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1371 /* Same nvidia windows driver trouble with white clears as earlier in the same test */
1372 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbeef, 0.0, 0);
1373 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1375 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
1376 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1378 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
1379 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1381 /* Colorwriteenable does not affect the clear */
1382 color = getPixelColor(device, 320, 240);
1383 ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
1385 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1387 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
1388 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1390 rect[0].x1 = 0;
1391 rect[0].y1 = 0;
1392 rect[0].x2 = 640;
1393 rect[0].y2 = 480;
1394 hr = IDirect3DDevice9_Clear(device, 0, rect, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
1395 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1397 color = getPixelColor(device, 320, 240);
1398 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff), 1),
1399 "Clear with count = 0, rect != NULL has color %08x\n", color);
1401 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1403 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
1404 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1405 hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
1406 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1408 color = getPixelColor(device, 320, 240);
1409 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1410 "Clear with count = 1, rect = NULL has color %08x\n", color);
1412 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1414 /* Test D3DRS_SRGBWRITEENABLE interactions with clears. */
1415 srgb_supported = SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
1416 D3DUSAGE_QUERY_SRGBWRITE, D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8));
1417 trace("sRGB writing to D3DFMT_A8R8G8B8 is %ssupported.\n", srgb_supported ? "" : "not ");
1418 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f7f7f7f, 0.0, 0);
1419 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
1421 color = getPixelColor(device, 320, 240);
1422 ok(color_match(color, 0x007f7f7f, 1), "Clear has color %08x.\n", color);
1424 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
1425 ok(SUCCEEDED(hr), "Failed to enable sRGB write, hr %#lx.\n", hr);
1427 /* Draw something to make sure the SRGBWRITEENABLE setting is applied. */
1428 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &mat);
1429 ok(SUCCEEDED(hr), "Failed to set world matrix, hr %#lx.\n", hr);
1430 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
1431 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#lx.\n", hr);
1432 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
1433 ok(SUCCEEDED(hr), "Failed to disable z test, hr %#lx.\n", hr);
1434 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1435 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#lx.\n", hr);
1436 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
1437 ok(SUCCEEDED(hr), "Failed to disable stencil test, hr %#lx.\n", hr);
1438 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
1439 ok(SUCCEEDED(hr), "Failed to disable culling, hr %#lx.\n", hr);
1440 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1441 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
1442 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1443 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
1444 hr = IDirect3DDevice9_BeginScene(device);
1445 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
1446 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad));
1447 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
1448 hr = IDirect3DDevice9_EndScene(device);
1449 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
1451 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f7f7f7f, 0.0, 0);
1452 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
1454 color = getPixelColor(device, 320, 240);
1455 ok(color_match(color, 0x00bbbbbb, 1), "Clear has color %08x.\n", color);
1457 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
1458 ok(SUCCEEDED(hr), "Failed to disable sRGB write, hr %#lx.\n", hr);
1460 /* Switching to a new render target seems to be enough to make Windows pick
1461 * up on the changed render state. */
1462 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 2, D3DUSAGE_RENDERTARGET,
1463 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
1464 ok(SUCCEEDED(hr), "Failed to create the offscreen render target, hr %#lx.\n", hr);
1465 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1466 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#lx.\n", hr);
1467 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface0);
1468 ok(SUCCEEDED(hr), "Failed to get offscreen surface, hr %#lx.\n", hr);
1469 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface0);
1470 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
1472 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f7f7f7f, 0.0, 0);
1473 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
1475 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1476 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
1478 hr = IDirect3DDevice9_StretchRect(device, surface0, NULL, backbuffer, NULL, D3DTEXF_NONE);
1479 ok(SUCCEEDED(hr), "Failed to blit surface, hr %#lx.\n", hr);
1481 color = getPixelColor(device, 64, 64);
1482 ok(color_match(color, 0x007f7f7f, 1), "Clear has color %08x.\n", color);
1484 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
1485 ok(SUCCEEDED(hr), "Failed to enable sRGB write, hr %#lx.\n", hr);
1487 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface0);
1488 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
1490 hr = IDirect3DDevice9_BeginScene(device);
1491 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
1492 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad));
1493 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
1494 hr = IDirect3DDevice9_EndScene(device);
1495 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
1497 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f7f7f7f, 0.0, 0);
1498 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
1500 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1501 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
1503 hr = IDirect3DDevice9_StretchRect(device, surface0, NULL, backbuffer, NULL, D3DTEXF_NONE);
1504 ok(SUCCEEDED(hr), "Failed to blit surface, hr %#lx.\n", hr);
1506 color = getPixelColor(device, 320, 240);
1507 ok(color_match(color, 0x00bbbbbb, 1), "Clear has color %08x.\n", color);
1509 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
1510 ok(SUCCEEDED(hr), "Failed to disable sRGB write, hr %#lx.\n", hr);
1511 /* Switching to another surface of the same texture is also enough to make
1512 * the setting "stick". */
1513 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface1);
1514 ok(SUCCEEDED(hr), "Failed to get offscreen surface, hr %#lx.\n", hr);
1515 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface1);
1516 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
1518 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f7f7f7f, 0.0, 0);
1519 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx\n", hr);
1521 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1522 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
1524 hr = IDirect3DDevice9_StretchRect(device, surface1, NULL, backbuffer, NULL, D3DTEXF_NONE);
1525 ok(SUCCEEDED(hr), "Failed to blit surface, hr %#lx.\n", hr);
1527 color = getPixelColor(device, 320, 240);
1528 ok(color_match(color, 0x007f7f7f, 1), "Clear has color %08x.\n", color);
1530 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1532 IDirect3DSurface9_Release(surface1);
1533 IDirect3DSurface9_Release(surface0);
1534 IDirect3DSurface9_Release(backbuffer);
1535 IDirect3DTexture9_Release(texture);
1536 refcount = IDirect3DDevice9_Release(device);
1537 ok(!refcount, "Device has %lu references left.\n", refcount);
1538 done:
1539 IDirect3D9_Release(d3d);
1540 DestroyWindow(window);
1543 static void test_clear_different_size_surfaces(void)
1545 IDirect3DSurface9 *ds, *rt, *rt2;
1546 IDirect3DDevice9 *device;
1547 D3DFORMAT ds_format;
1548 D3DLOCKED_RECT lr;
1549 unsigned int x, y;
1550 D3DVIEWPORT9 vp;
1551 IDirect3D9 *d3d;
1552 D3DCAPS9 caps;
1553 WORD *depth;
1554 HWND window;
1555 HRESULT hr;
1557 window = create_window();
1558 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1559 ok(!!d3d, "Failed to create D3D object.\n");
1560 if (!(device = create_device(d3d, window, window, TRUE)))
1562 skip("Failed to create D3D device.\n");
1563 goto done;
1566 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
1567 ok(hr == D3D_OK, "Failed to get device caps, hr %#lx.\n", hr);
1569 hr = IDirect3DDevice9_CreateRenderTarget(device, 1, 1, D3DFMT_A8R8G8B8,
1570 D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL);
1571 ok(hr == D3D_OK, "Failed to create render target surface, hr %#lx.\n", hr);
1572 hr = IDirect3DDevice9_CreateRenderTarget(device, 1, 2, D3DFMT_A8R8G8B8,
1573 D3DMULTISAMPLE_NONE, 0, TRUE, &rt2, NULL);
1574 ok(hr == D3D_OK, "Failed to create render target surface, hr %#lx.\n", hr);
1576 if (SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
1577 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D16_LOCKABLE)))
1579 ds_format = D3DFMT_D16_LOCKABLE;
1581 else
1583 ds_format = D3DFMT_D24S8;
1586 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 4, 4, ds_format,
1587 D3DMULTISAMPLE_NONE, 0, FALSE, &ds, NULL);
1588 ok(hr == D3D_OK, "Failed to create depth surface, hr %#lx.\n", hr);
1590 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
1591 ok(hr == D3D_OK, "Failed to set depth stencil surface, hr %#lx.\n", hr);
1592 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
1593 ok(hr == D3D_OK, "Failed to set render target, hr %#lx.\n", hr);
1594 if (caps.NumSimultaneousRTs >= 2)
1596 hr = IDirect3DDevice9_SetRenderTarget(device, 1, rt2);
1597 ok(hr == D3D_OK, "Failed to set render target, hr %#lx.\n", hr);
1600 vp.X = 0;
1601 vp.Y = 0;
1602 vp.Width = 640;
1603 vp.Height = 640;
1604 vp.MinZ = 0.0f;
1605 vp.MaxZ = 1.0f;
1606 hr = IDirect3DDevice9_SetViewport(device, &vp);
1607 ok(hr == D3D_OK, "Failed to set viewport, hr %#lx.\n", hr);
1609 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.5f, 0);
1610 ok(hr == D3D_OK, "Failed to clear, hr %#lx.\n", hr);
1612 check_rt_color(rt, 0x00ff0000);
1614 if (caps.NumSimultaneousRTs >= 2)
1615 check_rt_color(rt2, 0x00ff0000);
1617 if (ds_format == D3DFMT_D16_LOCKABLE)
1619 hr = IDirect3DSurface9_LockRect(ds, &lr, NULL, D3DLOCK_READONLY);
1620 ok(hr == D3D_OK, "Failed to lock rect, hr %#lx.\n", hr);
1621 for (y = 0; y < 4; ++y)
1623 depth = (WORD *)((BYTE *)lr.pBits + y * lr.Pitch);
1624 for (x = 0; x < 4; ++x)
1626 ok(compare_uint(depth[x], 0x7fff, 2), "Got depth 0x%04x at %u, %u.\n", depth[x], x, y);
1629 hr = IDirect3DSurface9_UnlockRect(ds);
1630 ok(hr == D3D_OK, "Failed to unlock rect, hr %#lx.\n", hr);
1631 IDirect3DSurface9_Release(ds);
1633 else
1635 skip("D3DFMT_D16_LOCKABLE is not supported.\n");
1638 IDirect3DSurface9_Release(rt);
1639 IDirect3DSurface9_Release(rt2);
1640 done:
1641 IDirect3D9_Release(d3d);
1642 DestroyWindow(window);
1645 static void color_fill_test(void)
1647 unsigned int fill_color, color, fill_a, expected_a;
1648 IDirect3DSurface9 *surface;
1649 IDirect3DTexture9 *texture;
1650 IDirect3DDevice9 *device;
1651 IDirect3D9 *d3d;
1652 ULONG refcount;
1653 HWND window;
1654 HRESULT hr;
1655 static const struct
1657 D3DPOOL pool;
1658 DWORD usage;
1659 HRESULT hr;
1661 resource_types[] =
1663 {D3DPOOL_DEFAULT, 0, D3DERR_INVALIDCALL},
1664 {D3DPOOL_DEFAULT, D3DUSAGE_DYNAMIC, D3DERR_INVALIDCALL},
1665 {D3DPOOL_DEFAULT, D3DUSAGE_RENDERTARGET, D3D_OK},
1666 {D3DPOOL_SYSTEMMEM, 0, D3DERR_INVALIDCALL},
1667 {D3DPOOL_MANAGED, 0, D3DERR_INVALIDCALL},
1668 {D3DPOOL_SCRATCH, 0, D3DERR_INVALIDCALL},
1670 static const struct
1672 D3DFORMAT format;
1673 const char *name;
1674 enum
1676 CHECK_FILL_VALUE = 0x1,
1677 BLOCKS = 0x2,
1678 FLOAT_VALUES = 0x4,
1679 } flags;
1680 unsigned int fill_i[4];
1681 float fill_f[4];
1683 formats[] =
1685 {D3DFMT_A8R8G8B8, "D3DFMT_A8R8G8B8", CHECK_FILL_VALUE,
1686 {0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef}},
1687 /* D3DFMT_X8R8G8B8 either set X = A or X = 0, depending on the driver. */
1688 {D3DFMT_R5G6B5, "D3DFMT_R5G6B5", CHECK_FILL_VALUE,
1689 {0xadfdadfd, 0xadfdadfd, 0xadfdadfd, 0xadfdadfd}},
1690 {D3DFMT_G16R16, "D3DFMT_G16R16", CHECK_FILL_VALUE,
1691 {0xbebeadad, 0xbebeadad, 0xbebeadad, 0xbebeadad}},
1692 {D3DFMT_A16B16G16R16, "D3DFMT_A16B16G16R16", CHECK_FILL_VALUE,
1693 {0xbebeadad, 0xdedeefef, 0xbebeadad, 0xdedeefef}},
1694 /* Real hardware reliably fills the surface with the blue channel but
1695 * the testbot fills it with 0x00. Wine incorrectly uses the alpha
1696 * channel. Don't bother checking the result because P8 surfaces are
1697 * essentially useless in d3d9. */
1698 {D3DFMT_P8, "D3DFMT_P8", 0,
1699 {0xefefefef, 0xefefefef, 0xefefefef, 0xefefefef}},
1700 /* Float formats. */
1701 {D3DFMT_R32F, "D3DFMT_R32F", CHECK_FILL_VALUE | FLOAT_VALUES,
1702 {0, 0, 0, 0}, {0xad / 255.0f, 0xad / 255.0f, 0xad / 255.0f, 0xad / 255.0f}},
1703 {D3DFMT_A32B32G32R32F, "D3DFMT_A32B32G32R32F", CHECK_FILL_VALUE | FLOAT_VALUES,
1704 {0, 0, 0, 0}, {0xad / 255.0f, 0xbe / 255.0f, 0xef / 255.0f, 0xde / 255.0f}},
1705 {D3DFMT_R16F, "D3DFMT_R16F", CHECK_FILL_VALUE,
1706 {0x396d396d, 0x396d396d, 0x396d396d, 0x396d396d}},
1707 {D3DFMT_G16R16F, "D3DFMT_G16R16F", CHECK_FILL_VALUE,
1708 {0x39f5396d, 0x39f5396d, 0x39f5396d, 0x39f5396d}},
1709 {D3DFMT_A16B16G16R16F, "D3DFMT_A16B16G16R16F", CHECK_FILL_VALUE,
1710 {0x39f5396d, 0x3af63b7f, 0x39f5396d, 0x3af63b7f}},
1711 /* Windows drivers produce different results for these formats.
1712 * No driver produces a YUV value that matches the input RGB
1713 * value, and no driver produces a proper DXT compression block.
1715 * Even the clear value 0 does not reliably produce a fill value
1716 * that will return vec4(0.0, 0.0, 0.0, 0.0) when sampled.
1718 * The YUV tests are disabled because they produce a driver-dependent
1719 * result on Wine.
1720 * {D3DFMT_YUY2, "D3DFMT_YUY2", BLOCKS},
1721 * {D3DFMT_UYVY, "D3DFMT_UYVY", BLOCKS}, */
1722 {D3DFMT_DXT1, "D3DFMT_DXT1", BLOCKS},
1723 /* Vendor-specific formats like ATI2N are a non-issue here since they're not
1724 * supported as offscreen plain surfaces and do not support D3DUSAGE_RENDERTARGET
1725 * when created as texture. */
1727 static const RECT rect = {4, 4, 8, 8}, rect2 = {5, 5, 7, 7};
1728 D3DLOCKED_RECT locked_rect;
1729 unsigned int i, j;
1731 window = create_window();
1732 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1733 ok(!!d3d, "Failed to create a D3D object.\n");
1734 if (!(device = create_device(d3d, window, window, TRUE)))
1736 skip("Failed to create a D3D device, skipping tests.\n");
1737 goto done;
1740 hr = IDirect3DDevice9_ColorFill(device, NULL, NULL, 0);
1741 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
1743 /* Test ColorFill on a the backbuffer (should pass) */
1744 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &surface);
1745 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1747 fill_color = 0x112233;
1748 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, fill_color);
1749 ok(SUCCEEDED(hr), "Color fill failed, hr %#lx.\n", hr);
1751 color = getPixelColor(device, 0, 0);
1752 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
1754 IDirect3DSurface9_Release(surface);
1756 /* Test ColorFill on a render target surface (should pass) */
1757 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8,
1758 D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL );
1759 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1761 fill_color = 0x445566;
1762 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, fill_color);
1763 ok(SUCCEEDED(hr), "Color fill failed, hr %#lx.\n", hr);
1765 color = getPixelColorFromSurface(surface, 0, 0);
1766 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
1768 IDirect3DSurface9_Release(surface);
1770 /* Test ColorFill on an offscreen plain surface in D3DPOOL_DEFAULT (should pass) */
1771 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
1772 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surface, NULL);
1773 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1775 fill_color = 0x778899;
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 /* Try ColorFill on an offscreen surface in sysmem (should fail) */
1785 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
1786 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1787 ok(hr == S_OK, "Got hr %#lx.\n", hr);
1789 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, 0);
1790 ok(hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
1792 IDirect3DSurface9_Release(surface);
1794 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 32, 32, D3DFMT_D16,
1795 D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL);
1796 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
1798 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, 0);
1799 ok(hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
1801 IDirect3DSurface9_Release(surface);
1803 for (i = 0; i < ARRAY_SIZE(resource_types); i++)
1805 texture = NULL;
1806 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, resource_types[i].usage,
1807 D3DFMT_A8R8G8B8, resource_types[i].pool, &texture, NULL);
1808 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx, i=%u.\n", hr, i);
1809 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
1810 ok(SUCCEEDED(hr), "Failed to get surface, hr %#lx, i=%u.\n", hr, i);
1812 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, fill_color);
1813 ok(hr == resource_types[i].hr, "Got unexpected hr %#lx, expected %#lx, i=%u.\n",
1814 hr, resource_types[i].hr, i);
1816 IDirect3DSurface9_Release(surface);
1817 IDirect3DTexture9_Release(texture);
1820 for (i = 0; i < ARRAY_SIZE(formats); i++)
1822 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
1823 D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, formats[i].format) != D3D_OK)
1825 skip("Offscreenplain %s surfaces not supported, skipping colorfill test\n", formats[i].name);
1826 continue;
1829 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
1830 formats[i].format, D3DPOOL_DEFAULT, &surface, NULL);
1831 ok(SUCCEEDED(hr), "Failed to create surface, hr %#lx, fmt=%s.\n", hr, formats[i].name);
1833 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, 0xdeadbeef);
1834 ok(SUCCEEDED(hr), "Failed to color fill, hr %#lx, fmt=%s.\n", hr, formats[i].name);
1836 hr = IDirect3DDevice9_ColorFill(device, surface, &rect, 0xdeadbeef);
1837 ok(SUCCEEDED(hr), "Failed to color fill, hr %#lx, fmt=%s.\n", hr, formats[i].name);
1839 if (SUCCEEDED(hr))
1841 hr = IDirect3DDevice9_ColorFill(device, surface, &rect2, 0xdeadbeef);
1842 if (formats[i].flags & BLOCKS)
1843 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx, fmt=%s.\n", hr, formats[i].name);
1844 else
1845 ok(SUCCEEDED(hr), "Failed to color fill, hr %#lx, fmt=%s.\n", hr, formats[i].name);
1848 if (!(formats[i].flags & CHECK_FILL_VALUE))
1850 IDirect3DSurface9_Release(surface);
1851 continue;
1854 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1855 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#lx, fmt=%s.\n", hr, formats[i].name);
1856 /* Windows drivers disagree on how to promote the 8 bit per channel
1857 * input argument to 16 bit for D3DFMT_G16R16. */
1858 if (formats[i].flags & FLOAT_VALUES)
1860 const struct vec4 *surface_data = locked_rect.pBits;
1861 ok(compare_vec4(surface_data, formats[i].fill_f[0], formats[i].fill_f[1],
1862 formats[i].fill_f[2], formats[i].fill_f[3], 1),
1863 "Expected clear values %f %f %f %f, got %f %f %f %f, fmt=%s\n",
1864 formats[i].fill_f[0], formats[i].fill_f[1],
1865 formats[i].fill_f[2], formats[i].fill_f[3],
1866 surface_data->x, surface_data->y, surface_data->z, surface_data->w,
1867 formats[i].name);
1869 else
1871 const unsigned int *surface_data = locked_rect.pBits;
1872 for (j = 0; j < 4; ++j)
1874 fill_a = (surface_data[j] & 0xff000000) >> 24;
1875 expected_a = (formats[i].fill_i[j] & 0xff000000) >> 24;
1876 ok(color_match(surface_data[j], formats[i].fill_i[j], 2) &&
1877 compare_uint(expected_a, fill_a, 2),
1878 "Expected clear value 0x%08x, got 0x%08x, fmt=%s, j=%u.\n",
1879 formats[i].fill_i[j], surface_data[j], formats[i].name, j);
1883 /* Fill the surface with something else to make sure the test below doesn't pass
1884 * due to stale contents by accident. */
1885 memset(locked_rect.pBits, 0x55, locked_rect.Pitch * 32);
1887 hr = IDirect3DSurface9_UnlockRect(surface);
1888 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#lx, fmt=%s.\n", hr, formats[i].name);
1890 /* Test clearing "to sysmem". Wined3d's delayed clear will perform the actual clear
1891 * in the lock call and try to fill the sysmem buffer instead of clearing on the
1892 * GPU and downloading it. */
1893 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, 0xdeadbeef);
1894 ok(SUCCEEDED(hr), "Failed to color fill, hr %#lx, fmt=%s.\n", hr, formats[i].name);
1895 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, D3DLOCK_READONLY);
1896 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#lx, fmt=%s.\n", hr, formats[i].name);
1898 if (formats[i].flags & FLOAT_VALUES)
1900 const struct vec4 *surface_data = locked_rect.pBits;
1901 ok(compare_vec4(surface_data, formats[i].fill_f[0], formats[i].fill_f[1],
1902 formats[i].fill_f[2], formats[i].fill_f[3], 1),
1903 "Expected clear values %f %f %f %f, got %f %f %f %f, fmt=%s\n",
1904 formats[i].fill_f[0], formats[i].fill_f[1],
1905 formats[i].fill_f[2], formats[i].fill_f[3],
1906 surface_data->x, surface_data->y, surface_data->z, surface_data->w,
1907 formats[i].name);
1909 else
1911 const unsigned int *surface_data = locked_rect.pBits;
1912 for (j = 0; j < 4; ++j)
1914 fill_a = (surface_data[j] & 0xff000000) >> 24;
1915 expected_a = (formats[i].fill_i[j] & 0xff000000) >> 24;
1916 ok(color_match(surface_data[j], formats[i].fill_i[j], 2) &&
1917 compare_uint(expected_a, fill_a, 2),
1918 "Expected clear value 0x%08x, got 0x%08x, fmt=%s, j=%u.\n",
1919 formats[i].fill_i[j], surface_data[j], formats[i].name, j);
1924 hr = IDirect3DSurface9_UnlockRect(surface);
1925 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#lx, fmt=%s.\n", hr, formats[i].name);
1927 IDirect3DSurface9_Release(surface);
1930 refcount = IDirect3DDevice9_Release(device);
1931 ok(!refcount, "Device has %lu references left.\n", refcount);
1932 done:
1933 IDirect3D9_Release(d3d);
1934 DestroyWindow(window);
1938 * c7 mova ARGB mov ARGB
1939 * -2.4 -2 0x00ffff00 -3 0x00ff0000
1940 * -1.6 -2 0x00ffff00 -2 0x00ffff00
1941 * -0.4 0 0x0000ffff -1 0x0000ff00
1942 * 0.4 0 0x0000ffff 0 0x0000ffff
1943 * 1.6 2 0x00ff00ff 1 0x000000ff
1944 * 2.4 2 0x00ff00ff 2 0x00ff00ff
1946 static void test_mova(void)
1948 IDirect3DVertexDeclaration9 *vertex_declaration;
1949 IDirect3DVertexShader9 *mova_shader;
1950 IDirect3DVertexShader9 *mov_shader;
1951 IDirect3DDevice9 *device;
1952 unsigned int i, j;
1953 IDirect3D9 *d3d;
1954 ULONG refcount;
1955 D3DCAPS9 caps;
1956 HWND window;
1957 HRESULT hr;
1959 static const DWORD mova_test[] =
1961 0xfffe0200, /* vs_2_0 */
1962 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1963 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
1964 0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
1965 0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
1966 0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
1967 0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
1968 0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
1969 0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
1970 0x0200002e, 0xb0010000, 0xa0000007, /* mova a0.x, c7.x */
1971 0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000, /* mov oD0, c[a0.x + 3] */
1972 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1973 0x0000ffff /* END */
1975 static const DWORD mov_test[] =
1977 0xfffe0101, /* vs_1_1 */
1978 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1979 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
1980 0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
1981 0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
1982 0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
1983 0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
1984 0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
1985 0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
1986 0x00000001, 0xb0010000, 0xa0000007, /* mov a0.x, c7.x */
1987 0x00000001, 0xd00f0000, 0xa0e42003, /* mov oD0, c[a0.x + 3] */
1988 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1989 0x0000ffff /* END */
1991 static const struct
1993 float in[4];
1994 unsigned int out;
1996 test_data[2][6] =
1999 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
2000 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
2001 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
2002 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
2003 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
2004 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
2007 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
2008 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
2009 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
2010 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
2011 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
2012 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
2015 static const struct vec3 quad[] =
2017 {-1.0f, -1.0f, 0.0f},
2018 {-1.0f, 1.0f, 0.0f},
2019 { 1.0f, -1.0f, 0.0f},
2020 { 1.0f, 1.0f, 0.0f},
2022 static const D3DVERTEXELEMENT9 decl_elements[] =
2024 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2025 D3DDECL_END()
2028 window = create_window();
2029 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2030 ok(!!d3d, "Failed to create a D3D object.\n");
2031 if (!(device = create_device(d3d, window, window, TRUE)))
2033 skip("Failed to create a D3D device, skipping tests.\n");
2034 goto done;
2037 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2038 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
2039 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
2041 skip("No vs_2_0 support, skipping tests.\n");
2042 IDirect3DDevice9_Release(device);
2043 goto done;
2046 hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
2047 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2048 hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
2049 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2050 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
2051 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2052 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
2053 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2055 hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
2056 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2057 for (j = 0; j < ARRAY_SIZE(test_data); ++j)
2059 for (i = 0; i < ARRAY_SIZE(*test_data); ++i)
2061 unsigned int color;
2063 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
2064 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2066 hr = IDirect3DDevice9_BeginScene(device);
2067 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2069 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2070 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2072 hr = IDirect3DDevice9_EndScene(device);
2073 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2075 color = getPixelColor(device, 320, 240);
2076 ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
2077 test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
2079 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2080 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2082 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
2083 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2085 hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
2086 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2089 IDirect3DVertexDeclaration9_Release(vertex_declaration);
2090 IDirect3DVertexShader9_Release(mova_shader);
2091 IDirect3DVertexShader9_Release(mov_shader);
2092 refcount = IDirect3DDevice9_Release(device);
2093 ok(!refcount, "Device has %lu references left.\n", refcount);
2094 done:
2095 IDirect3D9_Release(d3d);
2096 DestroyWindow(window);
2099 static void fog_test(void)
2101 float start = 0.0f, end = 1.0f;
2102 IDirect3DDevice9 *device;
2103 unsigned int color, i;
2104 IDirect3D9 *d3d;
2105 ULONG refcount;
2106 D3DCAPS9 caps;
2107 HWND window;
2108 HRESULT hr;
2110 /* Gets full z based fog with linear fog, no fog with specular color. */
2111 static const struct
2113 float x, y, z;
2114 D3DCOLOR diffuse;
2115 D3DCOLOR specular;
2117 untransformed_1[] =
2119 {-1.0f, -1.0f, 0.1f, 0xffff0000, 0xff000000},
2120 {-1.0f, 0.0f, 0.1f, 0xffff0000, 0xff000000},
2121 { 0.0f, 0.0f, 0.1f, 0xffff0000, 0xff000000},
2122 { 0.0f, -1.0f, 0.1f, 0xffff0000, 0xff000000},
2124 /* Ok, I am too lazy to deal with transform matrices. */
2125 untransformed_2[] =
2127 {-1.0f, 0.0f, 1.0f, 0xffff0000, 0xff000000},
2128 {-1.0f, 1.0f, 1.0f, 0xffff0000, 0xff000000},
2129 { 0.0f, 1.0f, 1.0f, 0xffff0000, 0xff000000},
2130 { 0.0f, 0.0f, 1.0f, 0xffff0000, 0xff000000},
2132 untransformed_3[] =
2134 {-1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
2135 {-1.0f, 1.0f, 0.5f, 0xffff0000, 0xff000000},
2136 { 1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
2137 { 1.0f, 1.0f, 0.5f, 0xffff0000, 0xff000000},
2139 far_quad1[] =
2141 {-1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
2142 {-1.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
2143 { 0.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
2144 { 0.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
2146 far_quad2[] =
2148 {-1.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
2149 {-1.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
2150 { 0.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
2151 { 0.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
2153 /* Untransformed ones. Give them a different diffuse color to make the
2154 * test look nicer. It also makes making sure that they are drawn
2155 * correctly easier. */
2156 static const struct
2158 float x, y, z, rhw;
2159 D3DCOLOR diffuse;
2160 D3DCOLOR specular;
2162 transformed_1[] =
2164 {320.0f, 0.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
2165 {640.0f, 0.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
2166 {640.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
2167 {320.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
2169 transformed_2[] =
2171 {320.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
2172 {640.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
2173 {640.0f, 480.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
2174 {320.0f, 480.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
2176 static const struct
2178 struct vec3 position;
2179 DWORD diffuse;
2181 rev_fog_quads[] =
2183 {{-1.0f, -1.0f, 0.1f}, 0x000000ff},
2184 {{-1.0f, 0.0f, 0.1f}, 0x000000ff},
2185 {{ 0.0f, 0.0f, 0.1f}, 0x000000ff},
2186 {{ 0.0f, -1.0f, 0.1f}, 0x000000ff},
2188 {{ 0.0f, -1.0f, 0.9f}, 0x000000ff},
2189 {{ 0.0f, 0.0f, 0.9f}, 0x000000ff},
2190 {{ 1.0f, 0.0f, 0.9f}, 0x000000ff},
2191 {{ 1.0f, -1.0f, 0.9f}, 0x000000ff},
2193 {{ 0.0f, 0.0f, 0.4f}, 0x000000ff},
2194 {{ 0.0f, 1.0f, 0.4f}, 0x000000ff},
2195 {{ 1.0f, 1.0f, 0.4f}, 0x000000ff},
2196 {{ 1.0f, 0.0f, 0.4f}, 0x000000ff},
2198 {{-1.0f, 0.0f, 0.7f}, 0x000000ff},
2199 {{-1.0f, 1.0f, 0.7f}, 0x000000ff},
2200 {{ 0.0f, 1.0f, 0.7f}, 0x000000ff},
2201 {{ 0.0f, 0.0f, 0.7f}, 0x000000ff},
2203 static const D3DMATRIX ident_mat =
2205 1.0f, 0.0f, 0.0f, 0.0f,
2206 0.0f, 1.0f, 0.0f, 0.0f,
2207 0.0f, 0.0f, 1.0f, 0.0f,
2208 0.0f, 0.0f, 0.0f, 1.0f
2209 }}};
2210 static const D3DMATRIX world_mat1 =
2212 1.0f, 0.0f, 0.0f, 0.0f,
2213 0.0f, 1.0f, 0.0f, 0.0f,
2214 0.0f, 0.0f, 1.0f, 0.0f,
2215 0.0f, 0.0f, -0.5f, 1.0f
2216 }}};
2217 static const D3DMATRIX world_mat2 =
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, 1.0f, 1.0f
2223 }}};
2224 static const D3DMATRIX proj_mat =
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, -1.0f, 1.0f
2230 }}};
2231 static const WORD Indices[] = {0, 1, 2, 2, 3, 0};
2232 static const WORD Indices2[] =
2234 0, 1, 2, 2, 3, 0,
2235 4, 5, 6, 6, 7, 4,
2236 8, 9, 10, 10, 11, 8,
2237 12, 13, 14, 14, 15, 12,
2240 window = create_window();
2241 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2242 ok(!!d3d, "Failed to create a D3D object.\n");
2243 if (!(device = create_device(d3d, window, window, TRUE)))
2245 skip("Failed to create a D3D device, skipping tests.\n");
2246 goto done;
2249 memset(&caps, 0, sizeof(caps));
2250 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2251 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2252 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
2253 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2255 /* Setup initial states: No lighting, fog on, fog color */
2256 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
2257 ok(SUCCEEDED(hr), "Failed to disable D3DRS_ZENABLE, hr %#lx.\n", hr);
2258 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2259 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2260 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
2261 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2262 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xff00ff00 /* A nice green */);
2263 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2264 /* Some of the tests seem to depend on the projection matrix explicitly
2265 * being set to an identity matrix, even though that's the default.
2266 * (AMD Radeon HD 6310, Windows 7) */
2267 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &ident_mat);
2268 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#lx.\n", hr);
2270 /* First test: Both table fog and vertex fog off */
2271 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
2272 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2273 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
2274 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2276 /* Start = 0, end = 1. Should be default, but set them */
2277 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
2278 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2279 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
2280 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2282 hr = IDirect3DDevice9_BeginScene(device);
2283 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
2285 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
2286 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
2288 /* Untransformed, vertex fog = NONE, table fog = NONE:
2289 * Read the fog weighting from the specular color. */
2290 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
2291 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
2292 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
2294 /* That makes it use the Z value */
2295 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
2296 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog vertex mode, hr %#lx.\n", hr);
2297 /* Untransformed, vertex fog != none (or table fog != none):
2298 * Use the Z value as input into the equation. */
2299 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
2300 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
2301 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
2303 /* transformed verts */
2304 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
2305 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
2306 /* Transformed, vertex fog != NONE, pixel fog == NONE:
2307 * Use specular color alpha component. */
2308 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
2309 2 /* PrimCount */, Indices, D3DFMT_INDEX16, transformed_1, sizeof(transformed_1[0]));
2310 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
2312 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
2313 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog table mode, hr %#lx.\n", hr);
2314 /* Transformed, table fog != none, vertex anything:
2315 * Use Z value as input to the fog equation. */
2316 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
2317 2 /* PrimCount */, Indices, D3DFMT_INDEX16, transformed_2, sizeof(transformed_2[0]));
2318 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
2320 hr = IDirect3DDevice9_EndScene(device);
2321 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2323 color = getPixelColor(device, 160, 360);
2324 ok(color == 0x00ff0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
2325 color = getPixelColor(device, 160, 120);
2326 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
2327 color = getPixelColor(device, 480, 120);
2328 ok(color == 0x00ffff00, "Transformed vertex with linear vertex fog has color %08x\n", color);
2329 if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
2331 color = getPixelColor(device, 480, 360);
2332 ok(color_match(color, 0x0000ff00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
2334 else
2336 /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
2337 * The settings above result in no fogging with vertex fog
2339 color = getPixelColor(device, 480, 120);
2340 ok(color == 0x00ffff00, "Transformed vertex with linear vertex fog has color %08x\n", color);
2341 trace("Info: Table fog not supported by this device\n");
2343 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2345 /* Now test the special case fogstart == fogend */
2346 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
2347 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2349 hr = IDirect3DDevice9_BeginScene(device);
2350 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
2352 start = 512;
2353 end = 512;
2354 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *)&start));
2355 ok(SUCCEEDED(hr), "Failed to set fog start, hr %#lx.\n", hr);
2356 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *)&end));
2357 ok(SUCCEEDED(hr), "Failed to set fog end, hr %#lx.\n", hr);
2359 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
2360 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
2361 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
2362 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog vertex mode, hr %#lx.\n", hr);
2363 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
2364 ok(SUCCEEDED(hr), "Failed to set D3DFOG_NONE fog table mode, hr %#lx.\n", hr);
2366 /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512.
2367 * Would result in a completely fog-free primitive because start > zcoord,
2368 * but because start == end, the primitive is fully covered by fog. The
2369 * same happens to the 2nd untransformed quad with z = 1.0. The third
2370 * transformed quad remains unfogged because the fogcoords are read from
2371 * the specular color and has fixed fogstart and fogend. */
2372 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
2373 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
2374 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
2375 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
2376 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
2377 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
2379 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
2380 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
2381 /* Transformed, vertex fog != NONE, pixel fog == NONE:
2382 * Use specular color alpha component. */
2383 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
2384 2 /* PrimCount */, Indices, D3DFMT_INDEX16, transformed_1, sizeof(transformed_1[0]));
2385 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
2387 hr = IDirect3DDevice9_EndScene(device);
2388 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
2390 color = getPixelColor(device, 160, 360);
2391 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
2392 color = getPixelColor(device, 160, 120);
2393 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
2394 color = getPixelColor(device, 480, 120);
2395 ok(color == 0x00ffff00, "Transformed vertex with linear vertex fog has color %08x\n", color);
2396 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2398 /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
2399 * but without shaders it seems to work everywhere
2401 end = 0.2;
2402 start = 0.8;
2403 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
2404 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2405 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
2406 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2407 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2408 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2410 /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
2411 * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
2412 * so skip this for now
2414 for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
2415 const char *mode = (i ? "table" : "vertex");
2416 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
2417 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2418 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
2419 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2420 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
2421 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2422 hr = IDirect3DDevice9_BeginScene(device);
2423 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
2424 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 16 /* NumVerts */,
2425 8 /* PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads, sizeof(rev_fog_quads[0]));
2426 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
2427 hr = IDirect3DDevice9_EndScene(device);
2428 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
2430 color = getPixelColor(device, 160, 360);
2431 ok(color_match(color, 0x0000ff00, 1),
2432 "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00 or 0x0000fe00\n", mode, color);
2434 color = getPixelColor(device, 160, 120);
2435 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x2b, 0xd4), 2),
2436 "Reversed %s fog: z=0.7 has color 0x%08x\n", mode, color);
2438 color = getPixelColor(device, 480, 120);
2439 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xaa, 0x55), 2),
2440 "Reversed %s fog: z=0.4 has color 0x%08x\n", mode, color);
2442 color = getPixelColor(device, 480, 360);
2443 ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
2445 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2447 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
2448 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
2449 break;
2453 if (caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
2455 /* A simple fog + non-identity world matrix test */
2456 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), &world_mat1);
2457 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2459 start = 0.0;
2460 end = 1.0;
2461 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *)&start));
2462 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2463 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *)&end));
2464 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2465 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
2466 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2467 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
2468 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2470 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
2471 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2473 hr = IDirect3DDevice9_BeginScene(device);
2474 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
2476 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
2477 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
2479 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
2480 2, Indices, D3DFMT_INDEX16, far_quad1, sizeof(far_quad1[0]));
2481 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
2482 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
2483 2, Indices, D3DFMT_INDEX16, far_quad2, sizeof(far_quad2[0]));
2484 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
2486 hr = IDirect3DDevice9_EndScene(device);
2487 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
2489 color = getPixelColor(device, 160, 360);
2490 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 4),
2491 "Unfogged quad has color %08x\n", color);
2492 color = getPixelColor(device, 160, 120);
2493 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2494 "Fogged out quad has color %08x\n", color);
2496 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2498 /* Test fog behavior with an orthogonal (but non-identity) projection matrix */
2499 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), &world_mat2);
2500 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2501 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &proj_mat);
2502 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2504 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
2505 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2507 hr = IDirect3DDevice9_BeginScene(device);
2508 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
2510 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
2511 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
2513 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
2514 2, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
2515 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
2516 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
2517 2, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
2518 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
2520 hr = IDirect3DDevice9_EndScene(device);
2521 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
2523 color = getPixelColor(device, 160, 360);
2524 ok(color_match(color, 0x00e51900, 4), "Partially fogged quad has color %08x\n", color);
2525 color = getPixelColor(device, 160, 120);
2526 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2527 "Fogged out quad has color %08x\n", color);
2529 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2531 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), &ident_mat);
2532 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2533 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &ident_mat);
2534 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2536 else
2538 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
2541 /* Test RANGEFOG vs FOGTABLEMODE */
2542 if ((caps.RasterCaps & (D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_FOGRANGE)) ==
2543 (D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_FOGRANGE))
2545 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
2546 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#lx.\n", hr);
2547 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
2548 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#lx.\n", hr);
2550 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_RANGEFOGENABLE, TRUE);
2551 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#lx.\n", hr);
2553 /* z=0.5, x = +/- 1.0, y = +/- 1.0. In case of z fog the fog coordinate is
2554 * 0.5. With range fog it is sqrt(x*x + y*y + z*z) = 1.5 for all vertices.
2555 * Note that the fog coordinate is interpolated linearly across the vertices,
2556 * so the different eye distance at the screen center should not matter. */
2557 start = 0.75f;
2558 end = 0.75001f;
2559 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
2560 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#lx.\n", hr);
2561 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
2562 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#lx.\n", hr);
2564 /* Table fog: Range fog is not used */
2565 hr = IDirect3DDevice9_BeginScene(device);
2566 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
2568 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
2569 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog table mode, hr %#lx.\n", hr);
2570 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
2571 untransformed_3, sizeof(*untransformed_3));
2572 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
2574 hr = IDirect3DDevice9_EndScene(device);
2575 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
2577 color = getPixelColor(device, 10, 10);
2578 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
2579 color = getPixelColor(device, 630, 10);
2580 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
2581 color = getPixelColor(device, 10, 470);
2582 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
2583 color = getPixelColor(device, 630, 470);
2584 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
2586 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2587 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed, hr %#lx.\n", hr);
2589 /* Vertex fog: Rangefog is used */
2590 hr = IDirect3DDevice9_BeginScene(device);
2591 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
2593 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
2594 ok(SUCCEEDED(hr), "Failed to set D3DFOG_NONE fog table mode, hr %#lx.\n", hr);
2595 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
2596 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog vertex mode, hr %#lx.\n", hr);
2597 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
2598 untransformed_3, sizeof(*untransformed_3));
2599 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
2601 hr = IDirect3DDevice9_EndScene(device);
2602 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
2604 color = getPixelColor(device, 10, 10);
2605 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2606 "Rangefog with vertex fog returned color 0x%08x\n", color);
2607 color = getPixelColor(device, 630, 10);
2608 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2609 "Rangefog with vertex fog returned color 0x%08x\n", color);
2610 color = getPixelColor(device, 10, 470);
2611 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2612 "Rangefog with vertex fog returned color 0x%08x\n", color);
2613 color = getPixelColor(device, 630, 470);
2614 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2615 "Rangefog with vertex fog returned color 0x%08x\n", color);
2617 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2618 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed, hr %#lx.\n", hr);
2620 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_RANGEFOGENABLE, FALSE);
2621 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#lx.\n", hr);
2623 else
2625 skip("Range fog or table fog not supported, skipping range fog tests\n");
2628 refcount = IDirect3DDevice9_Release(device);
2629 ok(!refcount, "Device has %lu references left.\n", refcount);
2630 done:
2631 IDirect3D9_Release(d3d);
2632 DestroyWindow(window);
2635 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
2636 * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
2637 * regardless of the actual addressing mode set. The way this test works is
2638 * that we sample in one of the corners of the cubemap with filtering enabled,
2639 * and check the interpolated color. There are essentially two reasonable
2640 * things an implementation can do: Either pick one of the faces and
2641 * interpolate the edge texel with itself (i.e., clamp within the face), or
2642 * interpolate between the edge texels of the three involved faces. It should
2643 * never involve the border color or the other side (texcoord wrapping) of a
2644 * face in the interpolation. */
2645 static void test_cube_wrap(void)
2647 IDirect3DVertexDeclaration9 *vertex_declaration;
2648 IDirect3DSurface9 *face_surface, *surface;
2649 IDirect3DCubeTexture9 *texture;
2650 D3DLOCKED_RECT locked_rect;
2651 IDirect3DDevice9 *device;
2652 unsigned int x, y, face;
2653 IDirect3D9 *d3d;
2654 ULONG refcount;
2655 D3DCAPS9 caps;
2656 HWND window;
2657 HRESULT hr;
2659 static const float quad[][6] =
2661 {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
2662 {-1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
2663 { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
2664 { 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
2666 static const D3DVERTEXELEMENT9 decl_elements[] =
2668 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2669 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2670 D3DDECL_END()
2672 static const struct
2674 D3DTEXTUREADDRESS mode;
2675 const char *name;
2677 address_modes[] =
2679 {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
2680 {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
2681 {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
2682 {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
2683 {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
2686 window = create_window();
2687 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2688 ok(!!d3d, "Failed to create a D3D object.\n");
2689 if (!(device = create_device(d3d, window, window, TRUE)))
2691 skip("Failed to create a D3D device, skipping tests.\n");
2692 goto done;
2695 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2696 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
2697 if (!(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP))
2699 skip("No cube texture support, skipping tests.\n");
2700 IDirect3DDevice9_Release(device);
2701 goto done;
2704 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
2705 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2706 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
2707 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2709 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
2710 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
2711 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2713 hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
2714 D3DPOOL_DEFAULT, &texture, NULL);
2715 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2717 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
2718 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2720 for (y = 0; y < 128; ++y)
2722 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2723 for (x = 0; x < 64; ++x)
2725 *ptr++ = 0xff0000ff;
2727 for (x = 64; x < 128; ++x)
2729 *ptr++ = 0xffff0000;
2733 hr = IDirect3DSurface9_UnlockRect(surface);
2734 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2736 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, 0, 0, &face_surface);
2737 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2739 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
2740 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2742 IDirect3DSurface9_Release(face_surface);
2744 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
2745 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2747 for (y = 0; y < 128; ++y)
2749 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2750 for (x = 0; x < 64; ++x)
2752 *ptr++ = 0xffff0000;
2754 for (x = 64; x < 128; ++x)
2756 *ptr++ = 0xff0000ff;
2760 hr = IDirect3DSurface9_UnlockRect(surface);
2761 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2763 /* Create cube faces */
2764 for (face = 1; face < 6; ++face)
2766 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
2767 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2769 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
2770 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2772 IDirect3DSurface9_Release(face_surface);
2775 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
2776 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2778 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
2779 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2780 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
2781 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2782 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
2783 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2785 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2786 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2788 for (x = 0; x < ARRAY_SIZE(address_modes); ++x)
2790 unsigned int color;
2792 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
2793 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2794 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
2795 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2797 hr = IDirect3DDevice9_BeginScene(device);
2798 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2800 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
2801 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2803 hr = IDirect3DDevice9_EndScene(device);
2804 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2806 color = getPixelColor(device, 320, 240);
2807 /* Modern AMD GPUs do slip into reading the border color. */
2808 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1)
2809 || broken(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xbf, 0x40), 1)
2810 && address_modes[x].mode == D3DTADDRESS_BORDER),
2811 "Got color 0x%08x for addressing mode %s, expected 0x000000ff.\n",
2812 color, address_modes[x].name);
2814 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2815 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2817 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
2818 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2821 IDirect3DVertexDeclaration9_Release(vertex_declaration);
2822 IDirect3DCubeTexture9_Release(texture);
2823 IDirect3DSurface9_Release(surface);
2824 refcount = IDirect3DDevice9_Release(device);
2825 ok(!refcount, "Device has %lu references left.\n", refcount);
2826 done:
2827 IDirect3D9_Release(d3d);
2828 DestroyWindow(window);
2831 static void offscreen_test(void)
2833 IDirect3DSurface9 *backbuffer, *offscreen;
2834 IDirect3DTexture9 *offscreenTexture;
2835 IDirect3DDevice9 *device;
2836 unsigned int color;
2837 IDirect3D9 *d3d;
2838 ULONG refcount;
2839 HWND window;
2840 HRESULT hr;
2842 static const float quad[][5] =
2844 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
2845 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
2846 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
2847 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
2850 window = create_window();
2851 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2852 ok(!!d3d, "Failed to create a D3D object.\n");
2853 if (!(device = create_device(d3d, window, window, TRUE)))
2855 skip("Failed to create a D3D device, skipping tests.\n");
2856 goto done;
2859 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
2860 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2862 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
2863 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
2864 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
2865 if (!offscreenTexture)
2867 trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5.\n");
2868 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
2869 D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
2870 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
2871 if (!offscreenTexture)
2873 skip("Cannot create an offscreen render target.\n");
2874 IDirect3DDevice9_Release(device);
2875 goto done;
2879 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2880 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2882 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
2883 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2885 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2886 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2888 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
2889 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2890 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
2891 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2892 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
2893 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2894 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
2895 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2896 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2897 ok(hr == S_OK, "Got hr %#lx.\n", hr);
2899 hr = IDirect3DDevice9_BeginScene(device);
2900 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
2902 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
2903 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
2904 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 1.0f, 0);
2905 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
2907 /* Draw without textures - Should result in a white quad. */
2908 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
2909 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
2911 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
2912 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
2913 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)offscreenTexture);
2914 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
2916 /* This time with the texture. */
2917 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
2918 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
2920 hr = IDirect3DDevice9_EndScene(device);
2921 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
2923 /* Center quad - should be white */
2924 color = getPixelColor(device, 320, 240);
2925 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2926 /* Some quad in the cleared part of the texture */
2927 color = getPixelColor(device, 170, 240);
2928 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
2929 /* Part of the originally cleared back buffer */
2930 color = getPixelColor(device, 10, 10);
2931 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2932 color = getPixelColor(device, 10, 470);
2933 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2935 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2937 IDirect3DSurface9_Release(backbuffer);
2938 IDirect3DTexture9_Release(offscreenTexture);
2939 IDirect3DSurface9_Release(offscreen);
2940 refcount = IDirect3DDevice9_Release(device);
2941 ok(!refcount, "Device has %lu references left.\n", refcount);
2942 done:
2943 IDirect3D9_Release(d3d);
2944 DestroyWindow(window);
2947 /* This test tests fog in combination with shaders.
2948 * What's tested: linear fog (vertex and table) with pixel shader
2949 * linear table fog with non foggy vertex shader
2950 * vertex fog with foggy vertex shader, non-linear
2951 * fog with shader, non-linear fog with foggy shader,
2952 * linear table fog with foggy shader */
2953 static void fog_with_shader_test(void)
2955 IDirect3DVertexShader9 *vertex_shader[4] = {NULL, NULL, NULL, NULL};
2956 IDirect3DPixelShader9 *pixel_shader[3] = {NULL, NULL, NULL};
2957 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
2958 IDirect3DDevice9 *device;
2959 unsigned int color, i, j;
2960 IDirect3D9 *d3d;
2961 ULONG refcount;
2962 D3DCAPS9 caps;
2963 HWND window;
2964 HRESULT hr;
2965 union
2967 float f;
2968 DWORD i;
2969 } start, end;
2971 /* basic vertex shader without fog computation ("non foggy") */
2972 static const DWORD vertex_shader_code1[] =
2974 0xfffe0101, /* vs_1_1 */
2975 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2976 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
2977 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2978 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
2979 0x0000ffff
2981 /* basic vertex shader with reversed fog computation ("foggy") */
2982 static const DWORD vertex_shader_code2[] =
2984 0xfffe0101, /* vs_1_1 */
2985 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2986 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
2987 0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
2988 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2989 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
2990 0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
2991 0x00000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
2992 0x0000ffff
2994 /* basic vertex shader with reversed fog computation ("foggy"), vs_2_0 */
2995 static const DWORD vertex_shader_code3[] =
2997 0xfffe0200, /* vs_2_0 */
2998 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2999 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
3000 0x05000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
3001 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
3002 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
3003 0x03000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
3004 0x03000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
3005 0x0000ffff
3007 /* basic pixel shader */
3008 static const DWORD pixel_shader_code[] =
3010 0xffff0101, /* ps_1_1 */
3011 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
3012 0x0000ffff
3014 static const DWORD pixel_shader_code2[] =
3016 0xffff0200, /* ps_2_0 */
3017 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
3018 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
3019 0x0000ffff
3021 struct
3023 struct vec3 position;
3024 DWORD diffuse;
3026 quad[] =
3028 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
3029 {{-1.0f, 1.0f, 0.0f}, 0xffff0000},
3030 {{ 1.0f, -1.0f, 0.0f}, 0xffff0000},
3031 {{ 1.0f, 1.0f, 0.0f}, 0xffff0000},
3033 static const D3DVERTEXELEMENT9 decl_elements[] =
3035 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3036 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
3037 D3DDECL_END()
3039 /* This reference data was collected on a nVidia GeForce 7600GS driver
3040 * version 84.19 DirectX version 9.0c on Windows XP. */
3041 static const struct test_data_t
3043 int vshader;
3044 int pshader;
3045 D3DFOGMODE vfog;
3046 D3DFOGMODE tfog;
3047 unsigned int color[11];
3049 test_data[] =
3051 /* only pixel shader: */
3052 {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
3053 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
3054 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
3055 {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
3056 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
3057 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
3058 {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
3059 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
3060 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
3061 {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
3062 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
3063 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
3064 {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
3065 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
3066 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
3068 /* vertex shader */
3069 {1, 0, D3DFOG_NONE, D3DFOG_NONE,
3070 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
3071 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
3072 {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
3073 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
3074 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
3075 {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
3076 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
3077 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
3079 {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
3080 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
3081 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
3082 {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
3083 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
3084 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
3086 /* vertex shader and pixel shader */
3087 /* The next 4 tests would read the fog coord output, but it isn't available.
3088 * The result is a fully fogged quad, no matter what the Z coord is. This is on
3089 * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
3090 * These tests should be disabled if some other hardware behaves differently
3092 {1, 1, D3DFOG_NONE, D3DFOG_NONE,
3093 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
3094 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
3095 {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
3096 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
3097 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
3098 {1, 1, D3DFOG_EXP, D3DFOG_NONE,
3099 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
3100 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
3101 {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
3102 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
3103 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
3105 /* These use the Z coordinate with linear table fog */
3106 {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
3107 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
3108 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
3109 {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
3110 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
3111 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
3112 {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
3113 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
3114 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
3115 {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
3116 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
3117 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
3119 /* Non-linear table fog without fog coord */
3120 {1, 1, D3DFOG_NONE, D3DFOG_EXP,
3121 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
3122 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
3123 {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
3124 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
3125 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
3127 /* These tests fail on older Nvidia drivers */
3128 /* foggy vertex shader */
3129 {2, 0, D3DFOG_NONE, D3DFOG_NONE,
3130 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
3131 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
3132 {2, 0, D3DFOG_EXP, D3DFOG_NONE,
3133 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
3134 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
3135 {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
3136 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
3137 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
3138 {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
3139 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
3140 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
3142 {3, 0, D3DFOG_NONE, D3DFOG_NONE,
3143 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
3144 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
3145 {3, 0, D3DFOG_EXP, D3DFOG_NONE,
3146 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
3147 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
3148 {3, 0, D3DFOG_EXP2, D3DFOG_NONE,
3149 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
3150 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
3151 {3, 0, D3DFOG_LINEAR, D3DFOG_NONE,
3152 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
3153 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
3155 /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
3156 * all using the fixed fog-coord linear fog
3158 /* vs_1_1 with ps_1_1 */
3159 {2, 1, D3DFOG_NONE, D3DFOG_NONE,
3160 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
3161 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
3162 {2, 1, D3DFOG_EXP, D3DFOG_NONE,
3163 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
3164 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
3165 {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
3166 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
3167 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
3168 {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
3169 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
3170 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
3172 /* vs_2_0 with ps_1_1 */
3173 {3, 1, D3DFOG_NONE, D3DFOG_NONE,
3174 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
3175 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
3176 {3, 1, D3DFOG_EXP, D3DFOG_NONE,
3177 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
3178 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
3179 {3, 1, D3DFOG_EXP2, D3DFOG_NONE,
3180 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
3181 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
3182 {3, 1, D3DFOG_LINEAR, D3DFOG_NONE,
3183 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
3184 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
3186 /* vs_1_1 with ps_2_0 */
3187 {2, 2, D3DFOG_NONE, D3DFOG_NONE,
3188 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
3189 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
3190 {2, 2, D3DFOG_EXP, D3DFOG_NONE,
3191 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
3192 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
3193 {2, 2, D3DFOG_EXP2, D3DFOG_NONE,
3194 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
3195 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
3196 {2, 2, D3DFOG_LINEAR, D3DFOG_NONE,
3197 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
3198 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
3200 /* vs_2_0 with ps_2_0 */
3201 {3, 2, D3DFOG_NONE, D3DFOG_NONE,
3202 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
3203 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
3204 {3, 2, D3DFOG_EXP, D3DFOG_NONE,
3205 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
3206 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
3207 {3, 2, D3DFOG_EXP2, D3DFOG_NONE,
3208 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
3209 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
3210 {3, 2, D3DFOG_LINEAR, D3DFOG_NONE,
3211 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
3212 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
3214 /* These use table fog. Here the shader-provided fog coordinate is
3215 * ignored and the z coordinate used instead
3217 {2, 1, D3DFOG_NONE, D3DFOG_EXP,
3218 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
3219 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
3220 {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
3221 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
3222 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
3223 {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
3224 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
3225 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
3227 static const D3DMATRIX identity =
3229 1.0f, 0.0f, 0.0f, 0.0f,
3230 0.0f, 1.0f, 0.0f, 0.0f,
3231 0.0f, 0.0f, 1.0f, 0.0f,
3232 0.0f, 0.0f, 0.0f, 1.0f,
3233 }}};
3235 window = create_window();
3236 d3d = Direct3DCreate9(D3D_SDK_VERSION);
3237 ok(!!d3d, "Failed to create a D3D object.\n");
3238 if (!(device = create_device(d3d, window, window, TRUE)))
3240 skip("Failed to create a D3D device, skipping tests.\n");
3241 goto done;
3244 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3245 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
3246 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0) || caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
3248 skip("No shader model 2 support, skipping tests.\n");
3249 IDirect3DDevice9_Release(device);
3250 goto done;
3253 /* NOTE: Changing these values will not affect the tests with foggy vertex
3254 * shader, as the values are hardcoded in the shader. */
3255 start.f = 0.1f;
3256 end.f = 0.9f;
3258 /* Some of the tests seem to depend on the projection matrix explicitly
3259 * being set to an identity matrix, even though that's the default.
3260 * (AMD Radeon HD 6310, Windows 7) */
3261 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
3262 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#lx.\n", hr);
3264 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
3265 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3266 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
3267 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3268 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code3, &vertex_shader[3]);
3269 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3270 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
3271 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3272 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code2, &pixel_shader[2]);
3273 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3274 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
3275 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3277 /* Setup initial states: No lighting, fog on, fog color */
3278 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3279 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3280 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
3281 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3282 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xff00ff00 /* A nice green */);
3283 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3284 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
3285 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3287 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
3288 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3289 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
3290 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3292 /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
3293 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
3294 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3295 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
3296 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3298 for (i = 0; i < ARRAY_SIZE(test_data); i++)
3300 hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
3301 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3302 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
3303 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3304 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
3305 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3306 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
3307 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3309 for(j=0; j < 11; j++)
3311 /* Don't use the whole zrange to prevent rounding errors */
3312 quad[0].position.z = 0.001f + (float)j / 10.02f;
3313 quad[1].position.z = 0.001f + (float)j / 10.02f;
3314 quad[2].position.z = 0.001f + (float)j / 10.02f;
3315 quad[3].position.z = 0.001f + (float)j / 10.02f;
3317 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff00ff, 1.0f, 0);
3318 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3320 hr = IDirect3DDevice9_BeginScene(device);
3321 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3323 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
3324 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3326 hr = IDirect3DDevice9_EndScene(device);
3327 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3329 /* As the red and green component are the result of blending use 5% tolerance on the expected value */
3330 color = getPixelColor(device, 128, 240);
3331 ok(color_match(color, test_data[i].color[j], 13),
3332 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
3333 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
3336 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3338 IDirect3DVertexShader9_Release(vertex_shader[1]);
3339 IDirect3DVertexShader9_Release(vertex_shader[2]);
3340 IDirect3DVertexShader9_Release(vertex_shader[3]);
3341 IDirect3DPixelShader9_Release(pixel_shader[1]);
3342 IDirect3DPixelShader9_Release(pixel_shader[2]);
3343 IDirect3DVertexDeclaration9_Release(vertex_declaration);
3344 refcount = IDirect3DDevice9_Release(device);
3345 ok(!refcount, "Device has %lu references left.\n", refcount);
3346 done:
3347 IDirect3D9_Release(d3d);
3348 DestroyWindow(window);
3351 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
3352 int i, x, y;
3353 HRESULT hr;
3354 IDirect3DTexture9 *texture[2] = {NULL, NULL};
3355 D3DLOCKED_RECT locked_rect;
3357 /* Generate the textures */
3358 for(i=0; i<2; i++)
3360 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
3361 D3DPOOL_MANAGED, &texture[i], NULL);
3362 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3364 hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
3365 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3366 for (y = 0; y < 128; ++y)
3368 if(i)
3369 { /* Set up black texture with 2x2 texel white spot in the middle */
3370 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
3371 for (x = 0; x < 128; ++x)
3373 *ptr++ = D3DCOLOR_ARGB(0xff, x * 2, y * 2, 0);
3376 else
3377 { /* Set up a displacement map which points away from the center parallel to the closest axis.
3378 * (if multiplied with bumpenvmat)
3380 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
3381 for (x = 0; x < 128; ++x)
3383 if(abs(x-64)>abs(y-64))
3385 if(x < 64)
3386 *ptr++ = 0xc000;
3387 else
3388 *ptr++ = 0x4000;
3390 else
3392 if(y < 64)
3393 *ptr++ = 0x0040;
3394 else
3395 *ptr++ = 0x00c0;
3400 hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
3401 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3403 hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
3404 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3406 /* Disable texture filtering */
3407 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
3408 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3409 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
3410 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3412 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3413 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3414 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3415 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3419 /* Test the behavior of the texbem instruction with normal 2D and projective
3420 * 2D textures. */
3421 static void texbem_test(void)
3423 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
3424 /* Use asymmetric matrix to test loading. */
3425 float bumpenvmat[4] = {0.0f, 0.5f, -0.5f, 0.0f};
3426 IDirect3DPixelShader9 *pixel_shader = NULL;
3427 IDirect3DTexture9 *texture1, *texture2;
3428 IDirect3DTexture9 *texture = NULL;
3429 D3DLOCKED_RECT locked_rect;
3430 IDirect3DDevice9 *device;
3431 unsigned int color, i;
3432 IDirect3D9 *d3d;
3433 ULONG refcount;
3434 D3DCAPS9 caps;
3435 HWND window;
3436 HRESULT hr;
3438 static const DWORD pixel_shader_code[] =
3440 0xffff0101, /* ps_1_1*/
3441 0x00000042, 0xb00f0000, /* tex t0*/
3442 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
3443 0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
3444 0x0000ffff
3446 static const DWORD double_texbem_code[] =
3448 0xffff0103, /* ps_1_3 */
3449 0x00000042, 0xb00f0000, /* tex t0 */
3450 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0 */
3451 0x00000042, 0xb00f0002, /* tex t2 */
3452 0x00000043, 0xb00f0003, 0xb0e40002, /* texbem t3, t2 */
3453 0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003, /* add r0, t1, t3 */
3454 0x0000ffff /* end */
3456 static const float quad[][7] =
3458 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
3459 {-1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
3460 { 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
3461 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
3463 static const float quad_proj[][9] =
3465 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 128.0f},
3466 {-1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f, 128.0f, 0.0f, 128.0f},
3467 { 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 128.0f, 0.0f, 0.0f, 128.0f},
3468 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
3470 static const float double_quad[] =
3472 -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f,
3473 -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f,
3474 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f,
3475 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f,
3477 static const D3DVERTEXELEMENT9 decl_elements[][4] =
3480 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3481 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3482 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
3483 D3DDECL_END()
3486 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3487 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3488 {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
3489 D3DDECL_END()
3493 window = create_window();
3494 d3d = Direct3DCreate9(D3D_SDK_VERSION);
3495 ok(!!d3d, "Failed to create a D3D object.\n");
3496 if (!(device = create_device(d3d, window, window, TRUE)))
3498 skip("Failed to create a D3D device, skipping tests.\n");
3499 goto done;
3502 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3503 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
3504 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
3506 skip("No ps_1_1 support, skipping tests.\n");
3507 IDirect3DDevice9_Release(device);
3508 goto done;
3511 generate_bumpmap_textures(device);
3513 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
3514 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
3515 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
3516 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
3517 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3519 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
3520 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3522 for(i=0; i<2; i++)
3524 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
3525 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3527 if(i)
3529 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
3530 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3533 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
3534 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3535 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
3536 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3538 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
3539 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3540 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
3541 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3543 hr = IDirect3DDevice9_BeginScene(device);
3544 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3546 if(!i)
3547 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
3548 else
3549 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
3550 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3552 hr = IDirect3DDevice9_EndScene(device);
3553 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3555 /* The Window 8 testbot (WARP) seems to use the transposed
3556 * D3DTSS_BUMPENVMAT matrix. */
3557 color = getPixelColor(device, 160, 240);
3558 ok(color_match(color, 0x007e8000, 4) || broken(color_match(color, 0x00007e00, 4)),
3559 "Got unexpected color 0x%08x.\n", color);
3560 color = getPixelColor(device, 480, 240);
3561 ok(color_match(color, 0x007e8000, 4) || broken(color_match(color, 0x00fe7e00, 4)),
3562 "Got unexpected color 0x%08x.\n", color);
3563 color = getPixelColor(device, 320, 120);
3564 ok(color_match(color, 0x007e8000, 4) || broken(color_match(color, 0x0080fe00, 4)),
3565 "Got unexpected color 0x%08x.\n", color);
3566 color = getPixelColor(device, 320, 360);
3567 ok(color_match(color, 0x007e8000, 4) || broken(color_match(color, 0x00800000, 4)),
3568 "Got unexpected color 0x%08x.\n", color);
3570 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3571 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3573 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3574 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3575 IDirect3DPixelShader9_Release(pixel_shader);
3577 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
3578 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3579 IDirect3DVertexDeclaration9_Release(vertex_declaration);
3582 /* clean up */
3583 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
3584 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3586 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3587 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3589 for(i=0; i<2; i++)
3591 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
3592 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3593 IDirect3DTexture9_Release(texture); /* For the GetTexture */
3594 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
3595 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3596 IDirect3DTexture9_Release(texture);
3599 /* Test double texbem */
3600 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
3601 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3602 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
3603 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3604 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
3605 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3606 hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
3607 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3609 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
3610 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3611 ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
3612 ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
3614 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3615 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3617 hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
3618 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3619 ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
3620 ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
3621 hr = IDirect3DTexture9_UnlockRect(texture1, 0);
3622 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3625 /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
3626 #define tex 0x00ff0000
3627 #define tex1 0x0000ff00
3628 #define origin 0x000000ff
3629 static const DWORD pixel_data[] = {
3630 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3631 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3632 0x000000ff, tex1 , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3633 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3634 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin, 0x000000ff, tex , 0x000000ff,
3635 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3636 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3637 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3639 #undef tex
3640 #undef tex1
3641 #undef origin
3643 hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
3644 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3645 for(i = 0; i < 8; i++) {
3646 memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
3648 hr = IDirect3DTexture9_UnlockRect(texture2, 0);
3649 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3652 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3653 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3654 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
3655 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3656 hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
3657 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3658 hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
3659 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3660 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
3661 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3662 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
3663 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3665 bumpenvmat[0] =-1.0; bumpenvmat[2] = 2.0;
3666 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.0;
3667 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
3668 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3669 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
3670 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3671 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
3672 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3673 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
3674 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3676 bumpenvmat[0] = 1.5; bumpenvmat[2] = 0.0;
3677 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.5;
3678 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
3679 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3680 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
3681 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3682 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
3683 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3684 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
3685 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3687 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3688 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3689 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3690 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3691 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3692 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3693 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3694 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3695 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3696 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3697 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3698 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3699 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3700 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3701 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3702 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3704 hr = IDirect3DDevice9_BeginScene(device);
3705 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
3706 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
3707 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#lx.\n", hr);
3708 hr = IDirect3DDevice9_EndScene(device);
3709 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
3710 /* The Window 8 testbot (WARP) seems to use the transposed
3711 * D3DTSS_BUMPENVMAT matrix. */
3712 color = getPixelColor(device, 320, 240);
3713 ok(color_match(color, 0x00ffff00, 1) || broken(color_match(color, 0x0000ffff, 1)),
3714 "Got unexpected color 0x%08x.\n", color);
3716 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3717 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3719 IDirect3DPixelShader9_Release(pixel_shader);
3720 IDirect3DTexture9_Release(texture);
3721 IDirect3DTexture9_Release(texture1);
3722 IDirect3DTexture9_Release(texture2);
3723 refcount = IDirect3DDevice9_Release(device);
3724 ok(!refcount, "Device has %lu references left.\n", refcount);
3725 done:
3726 IDirect3D9_Release(d3d);
3727 DestroyWindow(window);
3730 static void z_range_test(void)
3732 IDirect3DVertexShader9 *shader;
3733 IDirect3DDevice9 *device;
3734 unsigned int color;
3735 IDirect3D9 *d3d;
3736 ULONG refcount;
3737 D3DCAPS9 caps;
3738 HWND window;
3739 HRESULT hr;
3741 static const struct
3743 struct vec3 position;
3744 DWORD diffuse;
3746 quad[] =
3748 {{-1.0f, 0.0f, 1.1f}, 0xffff0000},
3749 {{-1.0f, 1.0f, 1.1f}, 0xffff0000},
3750 {{ 1.0f, 0.0f, -1.1f}, 0xffff0000},
3751 {{ 1.0f, 1.0f, -1.1f}, 0xffff0000},
3753 quad2[] =
3755 {{-1.0f, 0.0f, 1.1f}, 0xff0000ff},
3756 {{-1.0f, 1.0f, 1.1f}, 0xff0000ff},
3757 {{ 1.0f, 0.0f, -1.1f}, 0xff0000ff},
3758 {{ 1.0f, 1.0f, -1.1f}, 0xff0000ff},
3760 static const struct
3762 struct vec4 position;
3763 DWORD diffuse;
3765 quad3[] =
3767 {{640.0f, 240.0f, -1.1f, 1.0f}, 0xffffff00},
3768 {{640.0f, 480.0f, -1.1f, 1.0f}, 0xffffff00},
3769 {{ 0.0f, 240.0f, 1.1f, 1.0f}, 0xffffff00},
3770 {{ 0.0f, 480.0f, 1.1f, 1.0f}, 0xffffff00},
3772 quad4[] =
3774 {{640.0f, 240.0f, -1.1f, 1.0f}, 0xff00ff00},
3775 {{640.0f, 480.0f, -1.1f, 1.0f}, 0xff00ff00},
3776 {{ 0.0f, 240.0f, 1.1f, 1.0f}, 0xff00ff00},
3777 {{ 0.0f, 480.0f, 1.1f, 1.0f}, 0xff00ff00},
3779 static const DWORD shader_code[] =
3781 0xfffe0101, /* vs_1_1 */
3782 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
3783 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
3784 0x00000001, 0xd00f0000, 0xa0e40000, /* mov oD0, c0 */
3785 0x0000ffff /* end */
3787 static const float color_const_1[] = {1.0f, 0.0f, 0.0f, 1.0f};
3788 static const float color_const_2[] = {0.0f, 0.0f, 1.0f, 1.0f};
3790 window = create_window();
3791 d3d = Direct3DCreate9(D3D_SDK_VERSION);
3792 ok(!!d3d, "Failed to create a D3D object.\n");
3793 if (!(device = create_device(d3d, window, window, TRUE)))
3795 skip("Failed to create a D3D device, skipping tests.\n");
3796 goto done;
3799 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3800 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
3802 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
3803 * then call Present. Then clear the color buffer to make sure it has some defined content
3804 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
3805 * by the depth value. */
3806 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75f, 0);
3807 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
3808 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3809 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
3810 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
3811 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
3813 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3814 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
3815 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
3816 ok(SUCCEEDED(hr), "Failed to enable clipping, hr %#lx.\n", hr);
3817 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3818 ok(SUCCEEDED(hr), "Failed to enable z test, hr %#lx.\n", hr);
3819 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3820 ok(SUCCEEDED(hr), "Failed to disable z writes, hr %#lx.\n", hr);
3821 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
3822 ok(SUCCEEDED(hr), "Failed to set z function, hr %#lx.\n", hr);
3823 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3824 ok(SUCCEEDED(hr), "Failed set FVF, hr %#lx.\n", hr);
3826 hr = IDirect3DDevice9_BeginScene(device);
3827 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
3829 /* Test the untransformed vertex path */
3830 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
3831 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
3832 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
3833 ok(SUCCEEDED(hr), "Failed to set z function, hr %#lx.\n", hr);
3834 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
3835 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
3837 /* Test the transformed vertex path */
3838 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
3839 ok(SUCCEEDED(hr), "Failed set FVF, hr %#lx.\n", hr);
3841 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
3842 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
3843 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
3844 ok(SUCCEEDED(hr), "Failed to set z function, hr %#lx.\n", hr);
3845 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
3846 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
3848 hr = IDirect3DDevice9_EndScene(device);
3849 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
3851 /* Do not test the exact corner pixels, but go pretty close to them */
3853 /* Clipped because z > 1.0 */
3854 color = getPixelColor(device, 28, 238);
3855 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3856 color = getPixelColor(device, 28, 241);
3857 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
3858 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3859 else
3860 ok(color_match(color, 0x00ffff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
3862 /* Not clipped, > z buffer clear value(0.75).
3864 * On the r500 driver on Windows D3DCMP_GREATER and D3DCMP_GREATEREQUAL are broken for depth
3865 * values > 0.5. The range appears to be distorted, apparently an incoming value of ~0.875 is
3866 * equal to a stored depth buffer value of 0.5. */
3867 color = getPixelColor(device, 31, 238);
3868 ok(color_match(color, 0x00ff0000, 0), "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
3869 color = getPixelColor(device, 31, 241);
3870 ok(color_match(color, 0x00ffff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
3871 color = getPixelColor(device, 100, 238);
3872 ok(color_match(color, 0x00ff0000, 0) || broken(color_match(color, 0x00ffffff, 0)),
3873 "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
3874 color = getPixelColor(device, 100, 241);
3875 ok(color_match(color, 0x00ffff00, 0) || broken(color_match(color, 0x00ffffff, 0)),
3876 "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
3878 /* Not clipped, < z buffer clear value */
3879 color = getPixelColor(device, 104, 238);
3880 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
3881 color = getPixelColor(device, 104, 241);
3882 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
3883 color = getPixelColor(device, 318, 238);
3884 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
3885 color = getPixelColor(device, 318, 241);
3886 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
3888 /* Clipped because z < 0.0 */
3889 color = getPixelColor(device, 321, 238);
3890 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3891 color = getPixelColor(device, 321, 241);
3892 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
3893 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3894 else
3895 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3897 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3898 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
3900 /* Test the shader path */
3901 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
3903 skip("Vertex shaders not supported, skipping tests.\n");
3904 IDirect3DDevice9_Release(device);
3905 goto done;
3907 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
3908 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#lx.\n", hr);
3910 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
3911 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
3913 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3914 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
3915 hr = IDirect3DDevice9_SetVertexShader(device, shader);
3916 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
3918 hr = IDirect3DDevice9_BeginScene(device);
3919 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
3921 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, color_const_1, 1);
3922 ok(SUCCEEDED(hr), "Failed to set vs constant 0, hr %#lx.\n", hr);
3923 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
3924 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
3926 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
3927 ok(SUCCEEDED(hr), "Failed to set z function, hr %#lx.\n", hr);
3928 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, color_const_2, 1);
3929 ok(SUCCEEDED(hr), "Failed to set vs constant 0, hr %#lx.\n", hr);
3930 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
3931 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
3933 hr = IDirect3DDevice9_EndScene(device);
3934 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
3936 IDirect3DVertexShader9_Release(shader);
3938 /* Z < 1.0 */
3939 color = getPixelColor(device, 28, 238);
3940 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3942 /* 1.0 < z < 0.75 */
3943 color = getPixelColor(device, 31, 238);
3944 ok(color_match(color, 0x00ff0000, 0), "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
3945 color = getPixelColor(device, 100, 238);
3946 ok(color_match(color, 0x00ff0000, 0) || broken(color_match(color, 0x00ffffff, 0)),
3947 "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
3949 /* 0.75 < z < 0.0 */
3950 color = getPixelColor(device, 104, 238);
3951 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
3952 color = getPixelColor(device, 318, 238);
3953 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
3955 /* 0.0 < z */
3956 color = getPixelColor(device, 321, 238);
3957 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3959 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3960 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
3962 refcount = IDirect3DDevice9_Release(device);
3963 ok(!refcount, "Device has %lu references left.\n", refcount);
3964 done:
3965 IDirect3D9_Release(d3d);
3966 DestroyWindow(window);
3969 static void fill_surface(IDirect3DSurface9 *surface, DWORD color, DWORD flags)
3971 unsigned int byte_count;
3972 D3DSURFACE_DESC desc;
3973 unsigned int x, y;
3974 D3DLOCKED_RECT l;
3975 HRESULT hr;
3976 void *mem;
3978 memset(&desc, 0, sizeof(desc));
3979 memset(&l, 0, sizeof(l));
3980 hr = IDirect3DSurface9_GetDesc(surface, &desc);
3981 ok(hr == S_OK, "Got hr %#lx.\n", hr);
3983 switch(desc.Format)
3985 case D3DFMT_A8R8G8B8:
3986 case D3DFMT_X8R8G8B8:
3987 byte_count = 4;
3988 break;
3990 case D3DFMT_A1R5G5B5:
3991 case D3DFMT_X1R5G5B5:
3992 case D3DFMT_R5G6B5:
3993 byte_count = 2;
3994 break;
3996 default:
3997 ok(0, "Unsupported format %#x.\n", desc.Format);
3998 return;
4001 hr = IDirect3DSurface9_LockRect(surface, &l, NULL, flags);
4002 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4003 if(FAILED(hr)) return;
4005 for(y = 0; y < desc.Height; y++)
4007 mem = (BYTE *)l.pBits + y * l.Pitch;
4008 for(x = 0; x < l.Pitch / byte_count; ++x)
4010 if (byte_count == 4)
4011 ((DWORD *)mem)[x] = color;
4012 else
4013 ((WORD *)mem)[x] = color;
4016 hr = IDirect3DSurface9_UnlockRect(surface);
4017 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4020 static void fill_texture(IDirect3DTexture9 *texture, DWORD color, DWORD flags)
4022 IDirect3DSurface9 *surface;
4024 IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4025 fill_surface(surface, color, flags);
4026 IDirect3DSurface9_Release(surface);
4029 static void stretchrect_test(void)
4031 enum surface_type
4033 OFFSCREEN_32,
4034 OFFSCREEN_64,
4035 OFFSCREEN_DST_64,
4036 RT_32,
4037 RT_64,
4038 RT_DST_64,
4039 TEX_RT_32,
4040 TEX_RT_64,
4041 TEX_RT_DST_64,
4042 TEX_RT_DST_640_480,
4043 TEX_32,
4044 TEX_64,
4045 TEX_DST_64,
4046 BACKBUFFER,
4047 SURFACE_TYPE_COUNT,
4050 IDirect3DTexture9 *tex_rt32, *tex_rt64, *tex_rt_dest64, *tex_rt_dest640_480;
4051 IDirect3DSurface9 *surfaces[SURFACE_TYPE_COUNT];
4052 IDirect3DTexture9 *tex32, *tex64, *tex_dest64;
4053 IDirect3DSurface9 *surf_temp32, *surf_temp64;
4054 IDirect3DDevice9 *device;
4055 unsigned int color, i;
4056 IDirect3D9 *d3d;
4057 ULONG refcount;
4058 HWND window;
4059 HRESULT hr;
4061 static const RECT src_rect = {0, 0, 640, 480};
4062 static const RECT src_rect_flipy = {0, 480, 640, 0};
4063 static const RECT dst_rect = {0, 0, 640, 480};
4064 static const RECT dst_rect_flipy = {0, 480, 640, 0};
4065 static const RECT src_rect64 = {0, 0, 64, 64};
4066 static const RECT src_rect64_flipy = {0, 64, 64, 0};
4067 static const RECT dst_rect64 = {0, 0, 64, 64};
4068 static const RECT dst_rect64_flipy = {0, 64, 64, 0};
4070 static const struct error_condition_test
4072 enum surface_type src;
4073 const RECT *src_rect;
4074 enum surface_type dst;
4075 const RECT *dst_rect;
4076 D3DTEXTUREFILTERTYPE filter;
4077 BOOL allowed;
4078 BOOL todo;
4080 error_condition_tests[] =
4082 {OFFSCREEN_64, &src_rect64_flipy, OFFSCREEN_DST_64, &dst_rect64, D3DTEXF_NONE},
4083 {OFFSCREEN_64, &src_rect64, OFFSCREEN_DST_64, &dst_rect64_flipy, D3DTEXF_NONE},
4084 {OFFSCREEN_64, &src_rect64_flipy, TEX_RT_DST_64, &dst_rect64, D3DTEXF_NONE},
4085 {OFFSCREEN_64, &src_rect64, TEX_RT_DST_64, &dst_rect64_flipy, D3DTEXF_NONE},
4086 {OFFSCREEN_64, &src_rect64_flipy, RT_DST_64, &dst_rect64, D3DTEXF_NONE},
4087 {OFFSCREEN_64, &src_rect64, RT_DST_64, &dst_rect64_flipy, D3DTEXF_NONE},
4088 {OFFSCREEN_64, NULL, TEX_DST_64, NULL, D3DTEXF_NONE},
4089 {OFFSCREEN_32, NULL, OFFSCREEN_64, NULL, D3DTEXF_NONE, FALSE, TRUE},
4090 {OFFSCREEN_32, NULL, TEX_DST_64, NULL, D3DTEXF_NONE},
4091 {TEX_64, NULL, OFFSCREEN_64, NULL, D3DTEXF_NONE, FALSE, TRUE},
4092 {TEX_64, &src_rect64_flipy, TEX_RT_DST_64, &dst_rect64, D3DTEXF_NONE},
4093 {TEX_64, &src_rect64, TEX_RT_DST_64, &dst_rect64_flipy, D3DTEXF_NONE},
4094 {TEX_64, &src_rect64_flipy, RT_DST_64, &dst_rect64, D3DTEXF_NONE},
4095 {TEX_64, &src_rect64, RT_DST_64, &dst_rect64_flipy, D3DTEXF_NONE},
4096 {TEX_64, NULL, TEX_DST_64, NULL, D3DTEXF_NONE},
4097 {TEX_32, NULL, OFFSCREEN_64, NULL, D3DTEXF_NONE, FALSE, TRUE},
4098 {TEX_32, NULL, TEX_DST_64, NULL, D3DTEXF_NONE},
4099 {TEX_RT_64, NULL, OFFSCREEN_64, NULL, D3DTEXF_NONE, FALSE, TRUE},
4100 {TEX_RT_64, &src_rect64_flipy, TEX_RT_DST_64, &dst_rect64, D3DTEXF_NONE},
4101 {TEX_RT_64, &src_rect64, TEX_RT_DST_64, &dst_rect64_flipy, D3DTEXF_NONE},
4102 {TEX_RT_64, &src_rect64_flipy, RT_DST_64, &dst_rect64, D3DTEXF_NONE},
4103 {TEX_RT_64, &src_rect64, RT_DST_64, &dst_rect64_flipy, D3DTEXF_NONE},
4104 {TEX_RT_64, NULL, TEX_DST_64, NULL, D3DTEXF_NONE},
4105 {TEX_RT_32, NULL, OFFSCREEN_64, NULL, D3DTEXF_NONE, FALSE, TRUE},
4106 {TEX_RT_32, NULL, TEX_DST_64, NULL, D3DTEXF_NONE},
4107 {RT_64, NULL, OFFSCREEN_64, NULL, D3DTEXF_NONE, FALSE, TRUE},
4108 {RT_64, &src_rect64_flipy, TEX_RT_DST_64, &dst_rect64, D3DTEXF_NONE},
4109 {RT_64, &src_rect64, TEX_RT_DST_64, &dst_rect64_flipy, D3DTEXF_NONE},
4110 {RT_64, &src_rect64_flipy, RT_DST_64, &dst_rect64_flipy, D3DTEXF_NONE},
4111 {RT_64, &src_rect64, RT_DST_64, &dst_rect64_flipy, D3DTEXF_NONE},
4112 {RT_64, NULL, TEX_DST_64, NULL, D3DTEXF_NONE},
4113 {RT_32, NULL, OFFSCREEN_64, NULL, D3DTEXF_NONE, FALSE, TRUE},
4114 {RT_32, NULL, TEX_DST_64, NULL, D3DTEXF_NONE},
4115 {BACKBUFFER, &src_rect_flipy, TEX_RT_DST_640_480, &dst_rect, D3DTEXF_NONE},
4116 {BACKBUFFER, &src_rect, TEX_RT_DST_640_480, &dst_rect_flipy, D3DTEXF_NONE},
4117 /* Test filter. */
4118 {OFFSCREEN_64, NULL, OFFSCREEN_DST_64, NULL, D3DTEXF_NONE, TRUE},
4119 {OFFSCREEN_64, NULL, OFFSCREEN_DST_64, NULL, D3DTEXF_ANISOTROPIC},
4120 {OFFSCREEN_32, NULL, TEX_RT_DST_64, NULL, D3DTEXF_NONE, TRUE},
4121 {OFFSCREEN_32, NULL, TEX_RT_DST_64, NULL, D3DTEXF_ANISOTROPIC},
4122 {OFFSCREEN_64, NULL, TEX_RT_DST_64, NULL, D3DTEXF_ANISOTROPIC},
4123 {OFFSCREEN_64, NULL, TEX_RT_DST_64, NULL, D3DTEXF_PYRAMIDALQUAD},
4124 {OFFSCREEN_64, NULL, TEX_RT_DST_64, NULL, D3DTEXF_GAUSSIANQUAD},
4125 {OFFSCREEN_64, NULL, TEX_RT_DST_64, NULL, D3DTEXF_ANISOTROPIC},
4126 {OFFSCREEN_64, NULL, TEX_RT_DST_64, NULL, D3DTEXF_CONVOLUTIONMONO},
4127 {OFFSCREEN_64, NULL, TEX_RT_DST_64, NULL, 0xbadf},
4128 {TEX_64, NULL, RT_DST_64, NULL, D3DTEXF_NONE, TRUE},
4129 {TEX_64, NULL, RT_DST_64, NULL, D3DTEXF_ANISOTROPIC},
4130 {RT_64, NULL, RT_DST_64, NULL, D3DTEXF_ANISOTROPIC},
4131 {TEX_RT_64, NULL, TEX_RT_DST_64, NULL, D3DTEXF_NONE, TRUE},
4132 {TEX_RT_64, NULL, TEX_RT_DST_64, NULL, D3DTEXF_ANISOTROPIC},
4133 {RT_64, NULL, TEX_RT_DST_64, NULL, D3DTEXF_NONE, TRUE},
4134 {RT_64, NULL, TEX_RT_DST_64, NULL, D3DTEXF_ANISOTROPIC},
4135 {BACKBUFFER, NULL, TEX_RT_DST_640_480, NULL, D3DTEXF_NONE, TRUE},
4136 {BACKBUFFER, NULL, TEX_RT_DST_640_480, NULL, D3DTEXF_ANISOTROPIC},
4139 window = create_window();
4140 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4141 ok(!!d3d, "Failed to create a D3D object.\n");
4142 if (!(device = create_device(d3d, window, window, TRUE)))
4144 skip("Failed to create a D3D device, skipping tests.\n");
4145 goto done;
4148 /* Create our temporary surfaces in system memory. */
4149 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
4150 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
4151 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4152 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
4153 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
4154 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4156 /* Create offscreen plain surfaces in D3DPOOL_DEFAULT. */
4157 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
4158 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surfaces[OFFSCREEN_32], NULL);
4159 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4160 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
4161 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surfaces[OFFSCREEN_64], NULL);
4162 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4163 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
4164 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surfaces[OFFSCREEN_DST_64], NULL);
4165 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4167 /* Create render target surfaces. */
4168 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32,
4169 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surfaces[RT_32], NULL );
4170 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4171 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64,
4172 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surfaces[RT_64], NULL );
4173 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4174 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64,
4175 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surfaces[RT_DST_64], NULL );
4176 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4177 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &surfaces[BACKBUFFER]);
4178 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4180 /* Create render target textures. */
4181 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET,
4182 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
4183 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4184 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET,
4185 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
4186 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4187 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET,
4188 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
4189 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4190 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET,
4191 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest640_480, NULL);
4192 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4193 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surfaces[TEX_RT_32]);
4194 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4195 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surfaces[TEX_RT_64]);
4196 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4197 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surfaces[TEX_RT_DST_64]);
4198 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4199 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest640_480, 0, &surfaces[TEX_RT_DST_640_480]);
4200 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4202 /* Create regular textures in D3DPOOL_DEFAULT. */
4203 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
4204 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4205 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
4206 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4207 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
4208 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4209 hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surfaces[TEX_32]);
4210 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4211 hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surfaces[TEX_64]);
4212 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4213 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surfaces[TEX_DST_64]);
4214 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4216 /**********************************************************************
4217 * Tests for when the source parameter is an offscreen plain surface. *
4218 **********************************************************************/
4220 /* Fill the offscreen 64x64 surface with green. */
4221 fill_surface(surfaces[OFFSCREEN_64], 0xff00ff00, 0);
4223 /* offscreenplain ==> offscreenplain, same size. */
4224 hr = IDirect3DDevice9_StretchRect(device, surfaces[OFFSCREEN_64], NULL,
4225 surfaces[OFFSCREEN_DST_64], NULL, D3DTEXF_NONE);
4226 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4227 color = getPixelColorFromSurface(surfaces[OFFSCREEN_DST_64], 32, 32);
4228 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
4229 /* Blit without scaling. */
4230 hr = IDirect3DDevice9_StretchRect(device, surfaces[OFFSCREEN_64], &src_rect64,
4231 surfaces[OFFSCREEN_DST_64], &dst_rect64, D3DTEXF_NONE);
4232 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4234 /* offscreenplain ==> rendertarget texture, same size. */
4235 hr = IDirect3DDevice9_StretchRect(device, surfaces[OFFSCREEN_64], NULL,
4236 surfaces[TEX_RT_DST_64], NULL, D3DTEXF_NONE);
4237 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4238 /* We can't lock rendertarget textures, so copy to our temp surface first. */
4239 hr = IDirect3DDevice9_GetRenderTargetData(device, surfaces[TEX_RT_DST_64], surf_temp64);
4240 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4241 color = getPixelColorFromSurface(surf_temp64, 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[TEX_RT_DST_64], &dst_rect64, D3DTEXF_NONE);
4246 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4248 /* offscreenplain ==> rendertarget surface, same size. */
4249 hr = IDirect3DDevice9_StretchRect(device, surfaces[OFFSCREEN_64], NULL, surfaces[RT_DST_64], NULL, D3DTEXF_NONE);
4250 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4251 color = getPixelColorFromSurface(surfaces[RT_DST_64], 32, 32);
4252 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
4253 /* Blit without scaling. */
4254 hr = IDirect3DDevice9_StretchRect(device, surfaces[OFFSCREEN_64], &src_rect64,
4255 surfaces[RT_DST_64], &dst_rect64, D3DTEXF_NONE);
4256 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4258 /* Fill the smaller offscreen surface with red. */
4259 fill_surface(surfaces[OFFSCREEN_32], 0xffff0000, 0);
4261 /* offscreenplain ==> rendertarget texture, scaling. */
4262 hr = IDirect3DDevice9_StretchRect(device, surfaces[OFFSCREEN_32], NULL,
4263 surfaces[TEX_RT_DST_64], NULL, D3DTEXF_NONE);
4264 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4265 /* We can't lock rendertarget textures, so copy to our temp surface first. */
4266 hr = IDirect3DDevice9_GetRenderTargetData(device, surfaces[TEX_RT_DST_64], surf_temp64);
4267 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4268 color = getPixelColorFromSurface(surf_temp64, 48, 48);
4269 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
4271 /* offscreenplain ==> rendertarget surface, scaling. */
4272 hr = IDirect3DDevice9_StretchRect(device, surfaces[OFFSCREEN_32], NULL, surfaces[RT_DST_64], NULL, D3DTEXF_NONE);
4273 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4274 color = getPixelColorFromSurface(surfaces[RT_DST_64], 48, 48);
4275 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
4277 /*************************************************************
4278 * Tests for when the source parameter is a regular texture. *
4279 *************************************************************/
4281 /* Fill the surface of the regular texture with blue. */
4282 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT. */
4283 fill_surface(surf_temp64, 0xff0000ff, 0);
4284 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surfaces[TEX_64], NULL);
4285 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4287 /* texture ==> rendertarget texture, same size. */
4288 hr = IDirect3DDevice9_StretchRect(device, surfaces[TEX_64], NULL, surfaces[TEX_RT_DST_64], NULL, D3DTEXF_NONE);
4289 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4290 /* We can't lock rendertarget textures, so copy to our temp surface first. */
4291 hr = IDirect3DDevice9_GetRenderTargetData(device, surfaces[TEX_RT_DST_64], surf_temp64);
4292 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4293 color = getPixelColorFromSurface(surf_temp64, 32, 32);
4294 ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
4295 /* Blit without scaling. */
4296 hr = IDirect3DDevice9_StretchRect(device, surfaces[TEX_64], &src_rect64,
4297 surfaces[TEX_RT_DST_64], &dst_rect64, D3DTEXF_NONE);
4298 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4300 /* texture ==> rendertarget surface, same size. */
4301 hr = IDirect3DDevice9_StretchRect(device, surfaces[TEX_64], NULL, surfaces[RT_DST_64], NULL, D3DTEXF_NONE);
4302 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4303 color = getPixelColorFromSurface(surfaces[RT_DST_64], 32, 32);
4304 ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
4305 /* Blit without scaling. */
4306 hr = IDirect3DDevice9_StretchRect(device, surfaces[TEX_64], &src_rect64,
4307 surfaces[RT_DST_64], &dst_rect64, D3DTEXF_NONE);
4308 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4310 /* Fill the surface of the smaller regular texture with red. */
4311 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT. */
4312 fill_surface(surf_temp32, 0xffff0000, 0);
4313 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surfaces[TEX_32], NULL);
4314 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4316 /* texture ==> rendertarget texture, scaling. */
4317 hr = IDirect3DDevice9_StretchRect(device, surfaces[TEX_32], NULL, surfaces[TEX_RT_DST_64], NULL, D3DTEXF_NONE);
4318 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4319 /* We can't lock rendertarget textures, so copy to our temp surface first. */
4320 hr = IDirect3DDevice9_GetRenderTargetData(device, surfaces[TEX_RT_DST_64], surf_temp64);
4321 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4322 color = getPixelColorFromSurface(surf_temp64, 48, 48);
4323 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
4325 /* texture ==> rendertarget surface, scaling. */
4326 hr = IDirect3DDevice9_StretchRect(device, surfaces[TEX_32], NULL, surfaces[RT_DST_64], NULL, D3DTEXF_NONE);
4327 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4328 color = getPixelColorFromSurface(surfaces[RT_DST_64], 48, 48);
4329 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
4331 /******************************************************************
4332 * Tests for when the source parameter is a rendertarget texture. *
4333 ******************************************************************/
4335 /* Fill the surface of the rendertarget texture with white. */
4336 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT. */
4337 fill_surface(surf_temp64, 0xffffffff, 0);
4338 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surfaces[TEX_RT_64], NULL);
4339 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4341 /* rendertarget texture ==> rendertarget texture, same size. */
4342 hr = IDirect3DDevice9_StretchRect(device, surfaces[TEX_RT_64], NULL, surfaces[TEX_RT_DST_64], NULL, D3DTEXF_NONE);
4343 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4344 /* We can't lock rendertarget textures, so copy to our temp surface first. */
4345 hr = IDirect3DDevice9_GetRenderTargetData(device, surfaces[TEX_RT_DST_64], surf_temp64);
4346 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4347 color = getPixelColorFromSurface(surf_temp64, 32, 32);
4348 ok(color == 0xffffffff, "Got unexpected color 0x%08x.\n", color);
4349 /* Blit without scaling. */
4350 hr = IDirect3DDevice9_StretchRect(device, surfaces[TEX_RT_64], &src_rect64,
4351 surfaces[TEX_RT_DST_64], &dst_rect64, D3DTEXF_NONE);
4352 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4354 /* rendertarget texture ==> rendertarget surface, same size. */
4355 hr = IDirect3DDevice9_StretchRect(device, surfaces[TEX_RT_64], NULL, surfaces[RT_DST_64], NULL, D3DTEXF_NONE);
4356 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4357 color = getPixelColorFromSurface(surfaces[RT_DST_64], 32, 32);
4358 ok(color == 0xffffffff, "Got unexpected color 0x%08x.\n", color);
4359 /* Blit without scaling. */
4360 hr = IDirect3DDevice9_StretchRect(device, surfaces[TEX_RT_64], &src_rect64,
4361 surfaces[RT_DST_64], &dst_rect64, D3DTEXF_NONE);
4362 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4364 /* Fill the surface of the smaller rendertarget texture with red. */
4365 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT. */
4366 fill_surface(surf_temp32, 0xffff0000, 0);
4367 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surfaces[TEX_RT_32], NULL);
4368 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4370 /* rendertarget texture ==> rendertarget texture, scaling. */
4371 hr = IDirect3DDevice9_StretchRect(device, surfaces[TEX_RT_32], NULL, surfaces[TEX_RT_DST_64], NULL, D3DTEXF_NONE);
4372 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4373 /* We can't lock rendertarget textures, so copy to our temp surface first. */
4374 hr = IDirect3DDevice9_GetRenderTargetData(device, surfaces[TEX_RT_DST_64], surf_temp64);
4375 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4376 color = getPixelColorFromSurface(surf_temp64, 48, 48);
4377 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
4379 /* rendertarget texture ==> rendertarget surface, scaling. */
4380 hr = IDirect3DDevice9_StretchRect(device, surfaces[TEX_RT_32], NULL, surfaces[RT_DST_64], NULL, D3DTEXF_NONE);
4381 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4382 color = getPixelColorFromSurface(surfaces[RT_DST_64], 48, 48);
4383 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
4385 /******************************************************************
4386 * Tests for when the source parameter is a rendertarget surface. *
4387 ******************************************************************/
4389 /* Fill the surface of the rendertarget surface with black. */
4390 fill_surface(surfaces[RT_64], 0xff000000, 0);
4392 /* rendertarget surface ==> rendertarget texture, same size. */
4393 hr = IDirect3DDevice9_StretchRect(device, surfaces[RT_64], NULL, surfaces[TEX_RT_DST_64], NULL, D3DTEXF_NONE);
4394 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4395 /* We can't lock rendertarget textures, so copy to our temp surface first. */
4396 hr = IDirect3DDevice9_GetRenderTargetData(device, surfaces[TEX_RT_DST_64], surf_temp64);
4397 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4398 color = getPixelColorFromSurface(surf_temp64, 32, 32);
4399 ok(color == 0xff000000, "Got unexpected color 0x%08x.\n", color);
4400 /* Blit without scaling. */
4401 hr = IDirect3DDevice9_StretchRect(device, surfaces[RT_64], &src_rect64,
4402 surfaces[TEX_RT_DST_64], &dst_rect64, D3DTEXF_NONE);
4403 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4405 /* rendertarget surface ==> rendertarget surface, same size. */
4406 hr = IDirect3DDevice9_StretchRect(device, surfaces[RT_64], NULL, surfaces[RT_DST_64], NULL, D3DTEXF_NONE);
4407 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4408 color = getPixelColorFromSurface(surfaces[RT_DST_64], 32, 32);
4409 ok(color == 0xff000000, "Got unexpected color 0x%08x.\n", color);
4410 /* Blit without scaling. */
4411 hr = IDirect3DDevice9_StretchRect(device, surfaces[RT_64], &src_rect64,
4412 surfaces[RT_DST_64], &dst_rect64, D3DTEXF_NONE);
4413 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4415 /* Fill the surface of the smaller rendertarget texture with red. */
4416 fill_surface(surfaces[RT_32], 0xffff0000, 0);
4418 /* rendertarget surface ==> rendertarget texture, scaling. */
4419 hr = IDirect3DDevice9_StretchRect(device, surfaces[RT_32], NULL, surfaces[TEX_RT_DST_64], NULL, D3DTEXF_NONE);
4420 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4421 /* We can't lock rendertarget textures, so copy to our temp surface first. */
4422 hr = IDirect3DDevice9_GetRenderTargetData(device, surfaces[TEX_RT_DST_64], surf_temp64);
4423 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4424 color = getPixelColorFromSurface(surf_temp64, 48, 48);
4425 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
4427 /* rendertarget surface ==> rendertarget surface, scaling. */
4428 hr = IDirect3DDevice9_StretchRect(device, surfaces[RT_32], NULL, surfaces[RT_DST_64], NULL, D3DTEXF_NONE);
4429 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4430 color = getPixelColorFromSurface(surfaces[RT_DST_64], 48, 48);
4431 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
4433 /* backbuffer ==> surface tests (no scaling). */
4434 /* Blit with NULL rectangles. */
4435 hr = IDirect3DDevice9_StretchRect(device, surfaces[BACKBUFFER], NULL,
4436 surfaces[TEX_RT_DST_640_480], NULL, D3DTEXF_NONE);
4437 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4438 /* Blit without scaling. */
4439 hr = IDirect3DDevice9_StretchRect(device, surfaces[BACKBUFFER], &src_rect,
4440 surfaces[TEX_RT_DST_640_480], &dst_rect, D3DTEXF_NONE);
4441 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4443 /* Test error conditions. */
4444 for (i = 0; i < ARRAY_SIZE(error_condition_tests); ++i)
4446 const struct error_condition_test *test = &error_condition_tests[i];
4448 hr = IDirect3DDevice9_StretchRect(device, surfaces[test->src], test->src_rect,
4449 surfaces[test->dst], test->dst_rect, test->filter);
4450 todo_wine_if(test->todo)
4451 ok(hr == test->allowed ? D3D_OK : D3DERR_INVALIDCALL, "Test %u, got unexpected hr %#lx.\n", i, hr);
4454 /* TODO: Test format conversions. */
4456 for (i = 0; i < ARRAY_SIZE(surfaces); ++i)
4458 IDirect3DSurface9_Release(surfaces[i]);
4461 IDirect3DSurface9_Release(surf_temp32);
4462 IDirect3DSurface9_Release(surf_temp64);
4463 IDirect3DTexture9_Release(tex_rt32);
4464 IDirect3DTexture9_Release(tex_rt64);
4465 IDirect3DTexture9_Release(tex_rt_dest64);
4466 IDirect3DTexture9_Release(tex_rt_dest640_480);
4467 IDirect3DTexture9_Release(tex32);
4468 IDirect3DTexture9_Release(tex64);
4469 IDirect3DTexture9_Release(tex_dest64);
4470 refcount = IDirect3DDevice9_Release(device);
4471 ok(!refcount, "Device has %lu references left.\n", refcount);
4472 done:
4473 IDirect3D9_Release(d3d);
4474 DestroyWindow(window);
4477 static void test_multisample_stretch_rect(void)
4479 static const D3DTEXTUREFILTERTYPE filters[] =
4481 D3DTEXF_NONE,
4482 D3DTEXF_POINT,
4483 D3DTEXF_LINEAR,
4485 IDirect3DSurface9 *rt, *ms_rt, *ms_rt2, *rt_r5g6b5;
4486 struct surface_readback rb;
4487 IDirect3DDevice9 *device;
4488 unsigned int color, i;
4489 DWORD quality_levels;
4490 IDirect3D9 *d3d;
4491 ULONG refcount;
4492 HWND window;
4493 HRESULT hr;
4494 RECT rect;
4496 window = create_window();
4497 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4498 ok(!!d3d, "Failed to create a D3D object.\n");
4500 if (IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
4501 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, &quality_levels) == D3DERR_NOTAVAILABLE)
4503 skip("Multisampling not supported for D3DFMT_A8R8G8B8.\n");
4504 IDirect3D9_Release(d3d);
4505 DestroyWindow(window);
4506 return;
4509 if (!(device = create_device(d3d, window, window, TRUE)))
4511 skip("Failed to create a 3D device.\n");
4512 IDirect3D9_Release(d3d);
4513 DestroyWindow(window);
4514 return;
4517 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128,
4518 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
4519 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4520 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128,
4521 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_2_SAMPLES, quality_levels - 1, FALSE, &ms_rt, NULL);
4522 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4523 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128,
4524 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_2_SAMPLES, quality_levels - 1, FALSE, &ms_rt2, NULL);
4525 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4527 hr = IDirect3DDevice9_SetRenderTarget(device, 0, ms_rt);
4528 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4529 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff00ff, 0.0f, 0);
4530 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4532 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
4533 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
4535 for (i = 0; i < ARRAY_SIZE(filters); ++i)
4537 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
4538 ok(hr == D3D_OK, "Test %u, got unexpected hr %#lx.\n", i, hr);
4539 hr = IDirect3DDevice9_StretchRect(device, ms_rt, NULL, rt, NULL, filters[i]);
4540 ok(hr == D3D_OK, "Test %u, got unexpected hr %#lx.\n", i, hr);
4541 color = getPixelColor(device, 64, 64);
4542 ok(color == 0x00ff00ff, "Test %u, got unexpected color 0x%08x.\n", i, color);
4545 /* Scaling */
4546 SetRect(&rect, 0, 0, 64, 64);
4547 for (i = 0; i < ARRAY_SIZE(filters); ++i)
4549 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
4550 ok(hr == D3D_OK, "Test %u, got unexpected hr %#lx.\n", i, hr);
4551 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, ms_rt2, NULL, D3DTEXF_NONE);
4552 ok(hr == D3D_OK, "Test %u, got unexpected hr %#lx.\n", i, hr);
4554 hr = IDirect3DDevice9_StretchRect(device, ms_rt, NULL, rt, &rect, filters[i]);
4555 ok(hr == D3D_OK, "Test %u, got unexpected hr %#lx.\n", i, hr);
4556 get_rt_readback(rt, &rb);
4557 color = get_readback_color(&rb, 32, 32);
4558 ok(color == 0x00ff00ff, "Test %u, got unexpected color 0x%08x.\n", i, color);
4559 color = get_readback_color(&rb, 64, 64);
4560 ok(color == 0xffffffff, "Test %u, got unexpected color 0x%08x.\n", i, color);
4561 color = get_readback_color(&rb, 96, 96);
4562 ok(color == 0xffffffff, "Test %u, got unexpected color 0x%08x.\n", i, color);
4563 release_surface_readback(&rb);
4565 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
4566 ok(hr == D3D_OK, "Test %u, got unexpected hr %#lx.\n", i, hr);
4567 hr = IDirect3DDevice9_StretchRect(device, ms_rt, &rect, rt, NULL, filters[i]);
4568 ok(hr == D3D_OK, "Test %u, got unexpected hr %#lx.\n", i, hr);
4569 get_rt_readback(rt, &rb);
4570 color = get_readback_color(&rb, 32, 32);
4571 ok(color == 0x00ff00ff, "Test %u, got unexpected color 0x%08x.\n", i, color);
4572 color = get_readback_color(&rb, 64, 64);
4573 ok(color == 0x00ff00ff, "Test %u, got unexpected color 0x%08x.\n", i, color);
4574 color = get_readback_color(&rb, 96, 96);
4575 ok(color == 0x00ff00ff, "Test %u, got unexpected color 0x%08x.\n", i, color);
4576 release_surface_readback(&rb);
4578 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0f, 0);
4579 ok(hr == D3D_OK, "Test %u, got unexpected hr %#lx.\n", i, hr);
4580 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, ms_rt, &rect, filters[i]);
4581 ok(hr == D3D_OK, "Test %u, got unexpected hr %#lx.\n", i, hr);
4582 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
4583 ok(hr == D3D_OK, "Test %u, got unexpected hr %#lx.\n", i, hr);
4584 hr = IDirect3DDevice9_StretchRect(device, ms_rt, &rect, rt, NULL, filters[i]);
4585 ok(hr == D3D_OK, "Test %u, got unexpected hr %#lx.\n", i, hr);
4586 get_rt_readback(rt, &rb);
4587 color = get_readback_color(&rb, 32, 32);
4588 ok(color == 0xffffff00, "Test %u, got unexpected color 0x%08x.\n", i, color);
4589 color = get_readback_color(&rb, 64, 64);
4590 ok(color == 0xffffff00, "Test %u, got unexpected color 0x%08x.\n", i, color);
4591 color = get_readback_color(&rb, 96, 96);
4592 ok(color == 0xffffff00, "Test %u, got unexpected color 0x%08x.\n", i, color);
4593 release_surface_readback(&rb);
4595 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff00ff, 0.0f, 0);
4596 ok(hr == D3D_OK, "Test %u, got unexpected hr %#lx.\n", i, hr);
4597 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, ms_rt, NULL, D3DTEXF_NONE);
4598 ok(hr == D3D_OK, "Test %u, got unexpected hr %#lx.\n", i, hr);
4600 hr = IDirect3DDevice9_StretchRect(device, ms_rt, &rect, ms_rt2, NULL, filters[i]);
4601 ok(hr == D3D_OK, "Test %u, got unexpected hr %#lx.\n", i, hr);
4602 hr = IDirect3DDevice9_StretchRect(device, ms_rt2, &rect, rt, NULL, filters[i]);
4603 ok(hr == D3D_OK, "Test %u, got unexpected hr %#lx.\n", i, hr);
4604 get_rt_readback(rt, &rb);
4605 color = get_readback_color(&rb, 32, 32);
4606 ok(color == 0x00ff00ff, "Test %u, got unexpected color 0x%08x.\n", i, color);
4607 color = get_readback_color(&rb, 64, 64);
4608 ok(color == 0x00ff00ff, "Test %u, got unexpected color 0x%08x.\n", i, color);
4609 color = get_readback_color(&rb, 96, 96);
4610 ok(color == 0x00ff00ff, "Test %u, got unexpected color 0x%08x.\n", i, color);
4611 release_surface_readback(&rb);
4614 /* Format conversion */
4615 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128,
4616 D3DFMT_R5G6B5, D3DMULTISAMPLE_NONE, 0, FALSE, &rt_r5g6b5, NULL);
4617 if (FAILED(hr))
4619 skip("Failed to create D3DFMT_R5G6B5 render target.\n");
4620 goto done;
4623 for (i = 0; i < ARRAY_SIZE(filters); ++i)
4625 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
4626 ok(hr == D3D_OK, "Test %u, got unexpected hr %#lx.\n", i, hr);
4627 hr = IDirect3DDevice9_StretchRect(device, ms_rt, NULL, rt_r5g6b5, NULL, filters[i]);
4628 ok(hr == D3D_OK, "Test %u, got unexpected hr %#lx.\n", i, hr);
4629 hr = IDirect3DDevice9_StretchRect(device, rt_r5g6b5, NULL, rt, NULL, filters[i]);
4630 ok(hr == D3D_OK, "Test %u, got unexpected hr %#lx.\n", i, hr);
4631 color = getPixelColor(device, 64, 64);
4632 ok(color == 0x00ff00ff, "Test %u, got unexpected color 0x%08x.\n", i, color);
4635 IDirect3DSurface9_Release(rt_r5g6b5);
4637 done:
4638 IDirect3DSurface9_Release(ms_rt2);
4639 IDirect3DSurface9_Release(ms_rt);
4640 IDirect3DSurface9_Release(rt);
4641 refcount = IDirect3DDevice9_Release(device);
4642 ok(!refcount, "Device has %lu references left.\n", refcount);
4643 IDirect3D9_Release(d3d);
4644 DestroyWindow(window);
4647 static void maxmip_test(void)
4649 IDirect3DTexture9 *texture;
4650 IDirect3DSurface9 *surface;
4651 IDirect3DDevice9 *device;
4652 unsigned int color;
4653 IDirect3D9 *d3d;
4654 ULONG refcount;
4655 D3DCAPS9 caps;
4656 HWND window;
4657 HRESULT hr;
4658 DWORD ret;
4660 static const struct
4662 struct
4664 float x, y, z;
4665 float s, t;
4667 v[4];
4669 quads[] =
4672 {-1.0, -1.0, 0.0, 0.0, 0.0},
4673 {-1.0, 0.0, 0.0, 0.0, 1.0},
4674 { 0.0, -1.0, 0.0, 1.0, 0.0},
4675 { 0.0, 0.0, 0.0, 1.0, 1.0},
4678 { 0.0, -1.0, 0.0, 0.0, 0.0},
4679 { 0.0, 0.0, 0.0, 0.0, 1.0},
4680 { 1.0, -1.0, 0.0, 1.0, 0.0},
4681 { 1.0, 0.0, 0.0, 1.0, 1.0},
4684 { 0.0, 0.0, 0.0, 0.0, 0.0},
4685 { 0.0, 1.0, 0.0, 0.0, 1.0},
4686 { 1.0, 0.0, 0.0, 1.0, 0.0},
4687 { 1.0, 1.0, 0.0, 1.0, 1.0},
4690 {-1.0, 0.0, 0.0, 0.0, 0.0},
4691 {-1.0, 1.0, 0.0, 0.0, 1.0},
4692 { 0.0, 0.0, 0.0, 1.0, 0.0},
4693 { 0.0, 1.0, 0.0, 1.0, 1.0},
4697 window = create_window();
4698 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4699 ok(!!d3d, "Failed to create a D3D object.\n");
4700 if (!(device = create_device(d3d, window, window, TRUE)))
4702 skip("Failed to create a D3D device, skipping tests.\n");
4703 goto done;
4706 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4707 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
4708 if (!(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP))
4710 skip("No mipmap support, skipping tests.\n");
4711 IDirect3DDevice9_Release(device);
4712 goto done;
4715 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0,
4716 D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
4717 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
4719 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4720 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4721 fill_surface(surface, 0xffff0000, 0);
4722 IDirect3DSurface9_Release(surface);
4723 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
4724 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4725 fill_surface(surface, 0xff00ff00, 0);
4726 IDirect3DSurface9_Release(surface);
4727 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
4728 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4729 fill_surface(surface, 0xff0000ff, 0);
4730 IDirect3DSurface9_Release(surface);
4732 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4733 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4734 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4735 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4737 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4738 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
4739 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4740 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4742 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
4743 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4745 hr = IDirect3DDevice9_BeginScene(device);
4746 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
4748 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
4749 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#lx.\n", hr);
4750 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
4751 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
4753 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
4754 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#lx.\n", hr);
4755 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
4756 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
4758 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
4759 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#lx.\n", hr);
4760 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
4761 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
4763 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
4764 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#lx.\n", hr);
4765 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
4766 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
4768 hr = IDirect3DDevice9_EndScene(device);
4769 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
4771 /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
4772 color = getPixelColor(device, 160, 360);
4773 ok(color == 0x00ff0000, "MaxMip 0, no mipfilter has color 0x%08x.\n", color);
4774 color = getPixelColor(device, 480, 360);
4775 ok(color == 0x00ff0000, "MaxMip 1, no mipfilter has color 0x%08x.\n", color);
4776 color = getPixelColor(device, 480, 120);
4777 ok(color == 0x00ff0000, "MaxMip 2, no mipfilter has color 0x%08x.\n", color);
4778 color = getPixelColor(device, 160, 120);
4779 ok(color == 0x00ff0000, "MaxMip 3, no mipfilter has color 0x%08x.\n", color);
4780 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4781 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4783 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4784 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4786 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
4787 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4789 hr = IDirect3DDevice9_BeginScene(device);
4790 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
4792 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
4793 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#lx.\n", hr);
4794 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
4795 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
4797 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
4798 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#lx.\n", hr);
4799 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
4800 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
4802 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
4803 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#lx.\n", hr);
4804 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
4805 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
4807 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
4808 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#lx.\n", hr);
4809 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
4810 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
4812 hr = IDirect3DDevice9_EndScene(device);
4813 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
4815 /* Max Mip level 0-2 sample from the specified texture level, Max Mip
4816 * level 3 (> levels in texture) samples from the highest level in the
4817 * texture (level 2). */
4818 color = getPixelColor(device, 160, 360);
4819 ok(color == 0x00ff0000, "MaxMip 0, point mipfilter has color 0x%08x.\n", color);
4820 color = getPixelColor(device, 480, 360);
4821 ok(color == 0x0000ff00, "MaxMip 1, point mipfilter has color 0x%08x.\n", color);
4822 color = getPixelColor(device, 480, 120);
4823 ok(color == 0x000000ff, "MaxMip 2, point mipfilter has color 0x%08x.\n", color);
4824 color = getPixelColor(device, 160, 120);
4825 ok(color == 0x000000ff, "MaxMip 3, point mipfilter has color 0x%08x.\n", color);
4826 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4827 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4829 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
4830 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4832 hr = IDirect3DDevice9_BeginScene(device);
4833 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
4835 /* Mipmapping OFF, LOD level smaller than MAXMIPLEVEL. LOD level limits */
4836 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4837 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#lx.\n", hr);
4838 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
4839 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#lx.\n", hr);
4840 ret = IDirect3DTexture9_SetLOD(texture, 1);
4841 ok(ret == 0, "Got unexpected LOD %lu.\n", ret);
4842 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
4843 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
4845 /* Mipmapping ON, LOD level smaller than max mip level. LOD level limits */
4846 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4847 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#lx.\n", hr);
4848 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
4849 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#lx.\n", hr);
4850 ret = IDirect3DTexture9_SetLOD(texture, 2);
4851 ok(ret == 1, "Got unexpected LOD %lu.\n", ret);
4852 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
4853 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
4855 /* Mipmapping ON, LOD level bigger than max mip level. MAXMIPLEVEL limits */
4856 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
4857 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#lx.\n", hr);
4858 ret = IDirect3DTexture9_SetLOD(texture, 1);
4859 ok(ret == 2, "Got unexpected LOD %lu.\n", ret);
4860 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
4861 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
4863 /* Mipmapping OFF, LOD level bigger than max mip level. LOD level limits */
4864 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4865 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#lx.\n", hr);
4866 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
4867 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#lx.\n", hr);
4868 ret = IDirect3DTexture9_SetLOD(texture, 1);
4869 ok(ret == 1, "Got unexpected LOD %lu.\n", ret);
4870 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
4871 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
4873 hr = IDirect3DDevice9_EndScene(device);
4874 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
4876 /* Max Mip level 0-2 sample from the specified texture level, Max Mip
4877 * level 3 (> levels in texture) samples from the highest level in the
4878 * texture (level 2). */
4879 color = getPixelColor(device, 160, 360);
4880 ok(color == 0x0000ff00, "MaxMip 0, LOD 1, none mipfilter has color 0x%08x.\n", color);
4881 color = getPixelColor(device, 480, 360);
4882 ok(color == 0x000000ff, "MaxMip 1, LOD 2, point mipfilter has color 0x%08x.\n", color);
4883 color = getPixelColor(device, 480, 120);
4884 ok(color == 0x000000ff, "MaxMip 2, LOD 1, point mipfilter has color 0x%08x.\n", color);
4885 color = getPixelColor(device, 160, 120);
4886 ok(color == 0x0000ff00, "MaxMip 2, LOD 1, none mipfilter has color 0x%08x.\n", color);
4888 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4889 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4891 IDirect3DTexture9_Release(texture);
4892 refcount = IDirect3DDevice9_Release(device);
4893 ok(!refcount, "Device has %lu references left.\n", refcount);
4894 done:
4895 IDirect3D9_Release(d3d);
4896 DestroyWindow(window);
4899 static void release_buffer_test(void)
4901 IDirect3DVertexBuffer9 *vb;
4902 IDirect3DIndexBuffer9 *ib;
4903 IDirect3DDevice9 *device;
4904 unsigned int color;
4905 IDirect3D9 *d3d;
4906 ULONG refcount;
4907 HWND window;
4908 HRESULT hr;
4909 BYTE *data;
4911 static const short indices[] = {3, 4, 5};
4912 static const struct
4914 struct vec3 position;
4915 DWORD diffuse;
4917 quad[] =
4919 {{-1.0f, -1.0f, 0.1f}, 0xffff0000},
4920 {{-1.0f, 1.0f, 0.1f}, 0xffff0000},
4921 {{ 1.0f, 1.0f, 0.1f}, 0xffff0000},
4923 {{-1.0f, -1.0f, 0.1f}, 0xff00ff00},
4924 {{-1.0f, 1.0f, 0.1f}, 0xff00ff00},
4925 {{ 1.0f, 1.0f, 0.1f}, 0xff00ff00},
4928 window = create_window();
4929 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4930 ok(!!d3d, "Failed to create a D3D object.\n");
4931 if (!(device = create_device(d3d, window, window, TRUE)))
4933 skip("Failed to create a D3D device, skipping tests.\n");
4934 goto done;
4937 /* Index and vertex buffers should always be creatable */
4938 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0,
4939 D3DFVF_XYZ | D3DFVF_DIFFUSE, D3DPOOL_MANAGED, &vb, NULL);
4940 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#lx.\n", hr);
4941 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
4942 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4943 memcpy(data, quad, sizeof(quad));
4944 hr = IDirect3DVertexBuffer9_Unlock(vb);
4945 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4947 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0,
4948 D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
4949 ok(SUCCEEDED(hr), "Failed to create index buffer, hr %#lx.\n", hr);
4950 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
4951 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4952 memcpy(data, indices, sizeof(indices));
4953 hr = IDirect3DIndexBuffer9_Unlock(ib);
4954 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4956 hr = IDirect3DDevice9_SetIndices(device, ib);
4957 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4958 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
4959 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4960 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
4961 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4962 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4963 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
4965 /* Now destroy the bound index buffer and draw again */
4966 refcount = IDirect3DIndexBuffer9_Release(ib);
4967 ok(!refcount, "Unexpected refcount %lu.\n", refcount);
4969 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
4970 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4972 hr = IDirect3DDevice9_BeginScene(device);
4973 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
4974 /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent
4975 * D3D from making assumptions about the indices or vertices. */
4976 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
4977 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
4978 hr = IDirect3DDevice9_EndScene(device);
4979 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
4981 color = getPixelColor(device, 160, 120);
4982 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1), "Got unexpected color 0x%08x.\n", color);
4983 color = getPixelColor(device, 480, 360);
4984 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1), "Got unexpected color 0x%08x.\n", color);
4986 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4987 ok(hr == S_OK, "Got hr %#lx.\n", hr);
4989 /* Index buffer was already destroyed as part of the test */
4990 IDirect3DVertexBuffer9_Release(vb);
4991 refcount = IDirect3DDevice9_Release(device);
4992 ok(!refcount, "Device has %lu references left.\n", refcount);
4993 done:
4994 IDirect3D9_Release(d3d);
4995 DestroyWindow(window);
4998 static void float_texture_test(void)
5000 IDirect3DTexture9 *texture;
5001 IDirect3DDevice9 *device;
5002 unsigned int color;
5003 D3DLOCKED_RECT lr;
5004 IDirect3D9 *d3d;
5005 ULONG refcount;
5006 float *data;
5007 HWND window;
5008 HRESULT hr;
5010 static const float quad[] =
5012 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
5013 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
5014 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
5015 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
5018 window = create_window();
5019 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5020 ok(!!d3d, "Failed to create a D3D object.\n");
5021 if (!(device = create_device(d3d, window, window, TRUE)))
5023 skip("Failed to create a D3D device, skipping tests.\n");
5024 goto done;
5027 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
5028 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK)
5030 skip("D3DFMT_R32F textures not supported\n");
5031 IDirect3DDevice9_Release(device);
5032 goto done;
5035 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F, D3DPOOL_MANAGED, &texture, NULL);
5036 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
5038 memset(&lr, 0, sizeof(lr));
5039 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5040 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5041 data = lr.pBits;
5042 *data = 0.0;
5043 hr = IDirect3DTexture9_UnlockRect(texture, 0);
5044 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5046 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
5047 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
5048 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
5049 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5051 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
5052 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
5054 hr = IDirect3DDevice9_BeginScene(device);
5055 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
5056 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5057 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
5058 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
5059 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
5060 hr = IDirect3DDevice9_EndScene(device);
5061 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
5063 color = getPixelColor(device, 240, 320);
5064 ok(color == 0x0000ffff, "R32F with value 0.0 has color %08x, expected 0x0000ffff\n", color);
5066 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5067 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5069 IDirect3DTexture9_Release(texture);
5070 refcount = IDirect3DDevice9_Release(device);
5071 ok(!refcount, "Device has %lu references left.\n", refcount);
5072 done:
5073 IDirect3D9_Release(d3d);
5074 DestroyWindow(window);
5077 static void g16r16_texture_test(void)
5079 IDirect3DTexture9 *texture;
5080 IDirect3DDevice9 *device;
5081 unsigned int color;
5082 D3DLOCKED_RECT lr;
5083 IDirect3D9 *d3d;
5084 ULONG refcount;
5085 DWORD *data;
5086 HWND window;
5087 HRESULT hr;
5089 static const float quad[] =
5091 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
5092 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
5093 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
5094 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
5097 window = create_window();
5098 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5099 ok(!!d3d, "Failed to create a D3D object.\n");
5100 if (!(device = create_device(d3d, window, window, TRUE)))
5102 skip("Failed to create a D3D device, skipping tests.\n");
5103 goto done;
5106 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
5107 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK)
5109 skip("D3DFMT_G16R16 textures not supported\n");
5110 IDirect3DDevice9_Release(device);
5111 goto done;
5114 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16, D3DPOOL_MANAGED, &texture, NULL);
5115 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
5117 memset(&lr, 0, sizeof(lr));
5118 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5119 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5120 data = lr.pBits;
5121 *data = 0x0f00f000;
5122 hr = IDirect3DTexture9_UnlockRect(texture, 0);
5123 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5125 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
5126 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
5127 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
5128 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5130 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
5131 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
5133 hr = IDirect3DDevice9_BeginScene(device);
5134 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
5135 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5136 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
5137 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
5138 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
5139 hr = IDirect3DDevice9_EndScene(device);
5140 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
5142 color = getPixelColor(device, 240, 320);
5143 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
5144 "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
5146 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5147 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5149 IDirect3DTexture9_Release(texture);
5150 refcount = IDirect3DDevice9_Release(device);
5151 ok(!refcount, "Device has %lu references left.\n", refcount);
5152 done:
5153 IDirect3D9_Release(d3d);
5154 DestroyWindow(window);
5157 #define check_rect(a, b, c) check_rect_(__LINE__, a, b, c)
5158 static void check_rect_(unsigned int line, struct surface_readback *rb, RECT r, const char *message)
5160 LONG x_coords[2][2] =
5162 {r.left - 1, r.left + 1},
5163 {r.right + 1, r.right - 1},
5165 LONG y_coords[2][2] =
5167 {r.top - 1, r.top + 1},
5168 {r.bottom + 1, r.bottom - 1}
5170 unsigned int color, i, j, x_side, y_side;
5171 int x, y;
5173 if (r.left < 0 && r.top < 0 && r.right < 0 && r.bottom < 0)
5175 BOOL all_match = TRUE;
5177 for (y = 0; y < 480; ++y)
5179 for (x = 0; x < 640; ++x)
5181 color = get_readback_color(rb, x, y);
5182 if (color != 0xff000000)
5184 all_match = FALSE;
5185 break;
5188 if (!all_match)
5189 break;
5191 ok_(__FILE__, line)(all_match, "%s: pixel (%d, %d) has color %08x.\n", message, x, y, color);
5192 return;
5195 for (i = 0; i < 2; ++i)
5197 for (j = 0; j < 2; ++j)
5199 for (x_side = 0; x_side < 2; ++x_side)
5201 for (y_side = 0; y_side < 2; ++y_side)
5203 unsigned int expected = (x_side == 1 && y_side == 1) ? 0xffffffff : 0xff000000;
5205 x = x_coords[i][x_side];
5206 y = y_coords[j][y_side];
5207 if (x < 0 || x >= 640 || y < 0 || y >= 480)
5208 continue;
5209 color = get_readback_color(rb, x, y);
5210 ok_(__FILE__, line)(color == expected, "%s: pixel (%d, %d) has color %08x, expected %08x.\n",
5211 message, x, y, color, expected);
5218 struct projected_textures_test_run
5220 const char *message;
5221 DWORD flags;
5222 IDirect3DVertexDeclaration9 *decl;
5223 BOOL vs, ps;
5224 RECT rect;
5227 static void projected_textures_test(IDirect3DDevice9 *device,
5228 struct projected_textures_test_run tests[4])
5230 unsigned int i;
5232 static const DWORD vertex_shader[] =
5234 0xfffe0101, /* vs_1_1 */
5235 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5236 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
5237 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5238 0x00000001, 0xe00f0000, 0x90e40001, /* mov oT0, v1 */
5239 0x0000ffff /* end */
5241 static const DWORD pixel_shader[] =
5243 0xffff0103, /* ps_1_3 */
5244 0x00000042, 0xb00f0000, /* tex t0 */
5245 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
5246 0x0000ffff /* end */
5248 IDirect3DVertexShader9 *vs = NULL;
5249 IDirect3DPixelShader9 *ps = NULL;
5250 IDirect3D9 *d3d;
5251 D3DCAPS9 caps;
5252 HRESULT hr;
5253 IDirect3DSurface9 *backbuffer;
5254 struct surface_readback rb;
5256 IDirect3DDevice9_GetDirect3D(device, &d3d);
5257 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5258 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5259 IDirect3D9_Release(d3d);
5261 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
5263 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader, &vs);
5264 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5266 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 3))
5268 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader, &ps);
5269 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5272 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
5273 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#lx.\n", hr);
5275 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0f, 0);
5276 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5278 hr = IDirect3DDevice9_BeginScene(device);
5279 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
5281 for (i = 0; i < 4; ++i)
5283 DWORD value = 0xdeadbeef;
5284 static const float proj_quads[] =
5286 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 4.0f, 6.0f,
5287 -1.0f, 0.0f, 0.1f, 0.0f, 4.0f, 4.0f, 6.0f,
5288 0.0f, -1.0f, 0.1f, 4.0f, 0.0f, 4.0f, 6.0f,
5289 0.0f, 0.0f, 0.1f, 4.0f, 4.0f, 4.0f, 6.0f,
5291 0.0f, -1.0f, 0.1f, 0.0f, 0.0f, 4.0f, 6.0f,
5292 0.0f, 0.0f, 0.1f, 0.0f, 4.0f, 4.0f, 6.0f,
5293 1.0f, -1.0f, 0.1f, 4.0f, 0.0f, 4.0f, 6.0f,
5294 1.0f, 0.0f, 0.1f, 4.0f, 4.0f, 4.0f, 6.0f,
5296 -1.0f, 0.0f, 0.1f, 0.0f, 0.0f, 4.0f, 6.0f,
5297 -1.0f, 1.0f, 0.1f, 0.0f, 4.0f, 4.0f, 6.0f,
5298 0.0f, 0.0f, 0.1f, 4.0f, 0.0f, 4.0f, 6.0f,
5299 0.0f, 1.0f, 0.1f, 4.0f, 4.0f, 4.0f, 6.0f,
5301 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, 4.0f, 6.0f,
5302 0.0f, 1.0f, 0.1f, 0.0f, 4.0f, 4.0f, 6.0f,
5303 1.0f, 0.0f, 0.1f, 4.0f, 0.0f, 4.0f, 6.0f,
5304 1.0f, 1.0f, 0.1f, 4.0f, 4.0f, 4.0f, 6.0f,
5307 if (tests[i].vs)
5309 if (!vs)
5311 skip("Vertex shaders not supported, skipping\n");
5312 continue;
5314 hr = IDirect3DDevice9_SetVertexShader(device, vs);
5316 else
5317 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5318 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5319 if (tests[i].ps)
5321 if (!ps)
5323 skip("Pixel shaders not supported, skipping\n");
5324 continue;
5326 hr = IDirect3DDevice9_SetPixelShader(device, ps);
5328 else
5329 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5330 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5332 hr = IDirect3DDevice9_SetVertexDeclaration(device, tests[i].decl);
5333 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5335 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, tests[i].flags);
5336 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5337 hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, &value);
5338 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5339 ok(value == tests[i].flags, "Got value %#lx.\n", value);
5341 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
5342 &proj_quads[i * 4 * 7], 7 * sizeof(float));
5343 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5346 hr = IDirect3DDevice9_EndScene(device);
5347 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5349 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5350 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5351 if (vs) IDirect3DVertexShader9_Release(vs);
5352 if (ps) IDirect3DPixelShader9_Release(ps);
5354 get_rt_readback(backbuffer, &rb);
5355 for (i = 0; i < 4; ++i)
5357 if ((!tests[i].vs || vs) && (!tests[i].ps || ps))
5358 check_rect(&rb, tests[i].rect, tests[i].message);
5360 release_surface_readback(&rb);
5361 IDirect3DSurface9_Release(backbuffer);
5364 static void texture_transform_flags_test(void)
5366 HRESULT hr;
5367 IDirect3D9 *d3d;
5368 D3DFORMAT fmt = D3DFMT_X8R8G8B8;
5369 D3DCAPS9 caps;
5370 IDirect3DTexture9 *texture = NULL;
5371 IDirect3DVolumeTexture9 *volume = NULL;
5372 unsigned int color, x, y, z, w, h;
5373 IDirect3DDevice9 *device;
5374 D3DLOCKED_RECT lr;
5375 D3DLOCKED_BOX lb;
5376 ULONG refcount;
5377 HWND window;
5378 IDirect3DVertexDeclaration9 *decl, *decl2, *decl3, *decl4;
5380 static const D3DVERTEXELEMENT9 decl_elements[] = {
5381 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5382 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5383 D3DDECL_END()
5385 static const D3DVERTEXELEMENT9 decl_elements2[] = {
5386 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5387 {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5388 D3DDECL_END()
5390 static const D3DVERTEXELEMENT9 decl_elements3[] = {
5391 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5392 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5393 D3DDECL_END()
5395 static const D3DVERTEXELEMENT9 decl_elements4[] = {
5396 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5397 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5398 D3DDECL_END()
5400 static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
5401 0x00, 0xff, 0x00, 0x00,
5402 0x00, 0x00, 0x00, 0x00,
5403 0x00, 0x00, 0x00, 0x00};
5404 static const D3DMATRIX identity =
5406 1.0f, 0.0f, 0.0f, 0.0f,
5407 0.0f, 1.0f, 0.0f, 0.0f,
5408 0.0f, 0.0f, 1.0f, 0.0f,
5409 0.0f, 0.0f, 0.0f, 1.0f,
5410 }}};
5412 window = create_window();
5413 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5414 ok(!!d3d, "Failed to create a D3D object.\n");
5415 if (!(device = create_device(d3d, window, window, TRUE)))
5417 skip("Failed to create a D3D device, skipping tests.\n");
5418 goto done;
5421 memset(&lr, 0, sizeof(lr));
5422 memset(&lb, 0, sizeof(lb));
5423 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
5424 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK)
5425 fmt = D3DFMT_A16B16G16R16;
5427 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5428 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5429 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
5430 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5431 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
5432 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5433 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements4, &decl4);
5434 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5435 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
5436 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5437 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
5438 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5439 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
5440 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5441 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
5442 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5443 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
5444 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5445 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
5446 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5447 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
5448 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5449 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
5450 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5451 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
5452 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5453 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
5454 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5455 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
5456 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5458 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5459 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5460 w = min(1024, caps.MaxTextureWidth);
5461 h = min(1024, caps.MaxTextureHeight);
5462 hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
5463 0, fmt, D3DPOOL_MANAGED, &texture, NULL);
5464 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5465 if (!texture)
5467 skip("Failed to create the test texture.\n");
5468 IDirect3DDevice9_Release(device);
5469 goto done;
5472 /* Unfortunately there is no easy way to set up a texture coordinate passthrough
5473 * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
5474 * 1.0 in red and green for the x and y coords
5476 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5477 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5478 for(y = 0; y < h; y++) {
5479 for(x = 0; x < w; x++) {
5480 double r_f = (double) y / (double) h;
5481 double g_f = (double) x / (double) w;
5482 if(fmt == D3DFMT_A16B16G16R16) {
5483 unsigned short r, g;
5484 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
5485 r = (unsigned short) (r_f * 65536.0);
5486 g = (unsigned short) (g_f * 65536.0);
5487 dst[0] = r;
5488 dst[1] = g;
5489 dst[2] = 0;
5490 dst[3] = 65535;
5491 } else {
5492 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
5493 unsigned char r = (unsigned char) (r_f * 255.0);
5494 unsigned char g = (unsigned char) (g_f * 255.0);
5495 dst[0] = 0;
5496 dst[1] = g;
5497 dst[2] = r;
5498 dst[3] = 255;
5502 hr = IDirect3DTexture9_UnlockRect(texture, 0);
5503 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5504 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5505 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5507 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5508 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5509 hr = IDirect3DDevice9_BeginScene(device);
5510 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5511 if(SUCCEEDED(hr))
5513 static const float quad1[] =
5515 -1.0f, -1.0f, 0.1f, 1.0f, 1.0f,
5516 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f,
5517 0.0f, -1.0f, 0.1f, 1.0f, 1.0f,
5518 0.0f, 0.0f, 0.1f, 1.0f, 1.0f,
5520 static const float quad2[] =
5522 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f,
5523 -1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
5524 0.0f, 0.0f, 0.1f, 1.0f, 1.0f,
5525 0.0f, 1.0f, 0.1f, 1.0f, 1.0f,
5527 static const float quad3[] =
5529 0.0f, 0.0f, 0.1f, 0.5f, 0.5f,
5530 0.0f, 1.0f, 0.1f, 0.5f, 0.5f,
5531 1.0f, 0.0f, 0.1f, 0.5f, 0.5f,
5532 1.0f, 1.0f, 0.1f, 0.5f, 0.5f,
5534 static const float quad4[] =
5536 320.0f, 480.0f, 0.1f, 1.0f, 0.0f, 1.0f,
5537 320.0f, 240.0f, 0.1f, 1.0f, 0.0f, 1.0f,
5538 640.0f, 480.0f, 0.1f, 1.0f, 0.0f, 1.0f,
5539 640.0f, 240.0f, 0.1f, 1.0f, 0.0f, 1.0f,
5541 D3DMATRIX mat =
5543 0.0f, 0.0f, 0.0f, 0.0f,
5544 0.0f, 0.0f, 0.0f, 0.0f,
5545 0.0f, 0.0f, 0.0f, 0.0f,
5546 0.0f, 0.0f, 0.0f, 0.0f,
5547 }}};
5549 /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
5550 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
5551 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5552 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
5553 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5555 /* What happens with transforms enabled? */
5556 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
5557 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5558 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
5559 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5561 /* What happens if 4 coords are used, but only 2 given ?*/
5562 mat.m[2][0] = 1.0f;
5563 mat.m[3][1] = 1.0f;
5564 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
5565 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5566 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
5567 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5568 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
5569 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5571 /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
5572 * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
5573 * due to the coords in the vertices. (turns out red, indeed)
5575 memset(&mat, 0, sizeof(mat));
5576 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
5577 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5578 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
5579 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5580 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
5581 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5582 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5583 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5585 hr = IDirect3DDevice9_EndScene(device);
5586 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5588 color = getPixelColor(device, 160, 360);
5589 ok(color_match(color, 0x00ffff00, 1), "quad 1 has color %08x, expected 0x00ffff00\n", color);
5590 color = getPixelColor(device, 160, 120);
5591 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
5592 color = getPixelColor(device, 480, 120);
5593 ok(color_match(color, 0x0000ff00, 1), "quad 3 has color %08x, expected 0x0000ff00\n", color);
5594 color = getPixelColor(device, 480, 360);
5595 ok(color_match(color, 0x00ff0000, 1), "quad 4 has color %08x, expected 0x00ff0000\n", color);
5596 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5597 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5599 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
5600 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5602 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5603 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5604 hr = IDirect3DDevice9_BeginScene(device);
5605 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5606 if(SUCCEEDED(hr))
5608 static const float quad1[] =
5610 -1.0f, -1.0f, 0.1f, 0.8f, 0.2f,
5611 -1.0f, 0.0f, 0.1f, 0.8f, 0.2f,
5612 0.0f, -1.0f, 0.1f, 0.8f, 0.2f,
5613 0.0f, 0.0f, 0.1f, 0.8f, 0.2f,
5615 static const float quad2[] =
5617 -1.0f, 0.0f, 0.1f, 0.5f, 1.0f,
5618 -1.0f, 1.0f, 0.1f, 0.5f, 1.0f,
5619 0.0f, 0.0f, 0.1f, 0.5f, 1.0f,
5620 0.0f, 1.0f, 0.1f, 0.5f, 1.0f,
5622 static const float quad3[] =
5624 0.0f, 0.0f, 0.1f, 0.5f, 1.0f,
5625 0.0f, 1.0f, 0.1f, 0.5f, 1.0f,
5626 1.0f, 0.0f, 0.1f, 0.5f, 1.0f,
5627 1.0f, 1.0f, 0.1f, 0.5f, 1.0f,
5629 static const float quad4[] =
5631 0.0f, -1.0f, 0.1f, 0.8f, 0.2f,
5632 0.0f, 0.0f, 0.1f, 0.8f, 0.2f,
5633 1.0f, -1.0f, 0.1f, 0.8f, 0.2f,
5634 1.0f, 0.0f, 0.1f, 0.8f, 0.2f,
5636 D3DMATRIX mat =
5638 0.0f, 0.0f, 0.0f, 0.0f,
5639 0.0f, 0.0f, 0.0f, 0.0f,
5640 0.0f, 1.0f, 0.0f, 0.0f,
5641 0.0f, 0.0f, 0.0f, 0.0f,
5642 }}};
5644 /* What happens to the default 1 in the 3rd coordinate if it is disabled? */
5645 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
5646 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5647 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
5648 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5650 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
5651 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5653 /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
5654 * it behaves like COUNT2 because normal textures require 2 coords. */
5655 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
5656 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5657 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
5658 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5660 /* Just to be sure, the same as quad2 above */
5661 memset(&mat, 0, sizeof(mat));
5662 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
5663 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5664 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
5665 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5666 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
5667 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5669 /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
5670 * used? And what happens to the first? */
5671 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
5672 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5673 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
5674 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5676 hr = IDirect3DDevice9_EndScene(device);
5677 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5679 color = getPixelColor(device, 160, 360);
5680 ok(color_match(color, 0x00ff0000, 1), "quad 1 has color %08x, expected 0x00ff0000\n", color);
5681 color = getPixelColor(device, 160, 120);
5682 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
5683 color = getPixelColor(device, 480, 120);
5684 ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
5685 "quad 3 has color %08x, expected 0x00ff8000\n", color);
5686 color = getPixelColor(device, 480, 360);
5687 ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00ff0000, 1),
5688 "quad 4 has color %08x, expected 0x0033cc00\n", color);
5689 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5690 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5692 IDirect3DTexture9_Release(texture);
5694 /* Test projected textures, without any fancy matrices */
5695 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
5696 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5697 if (SUCCEEDED(hr))
5699 struct projected_textures_test_run projected_tests_1[4] =
5702 "D3DTTFF_COUNT4 | D3DTTFF_PROJECTED - bottom left",
5703 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED,
5704 decl3,
5705 FALSE, TRUE,
5706 {120, 300, 240, 390},
5709 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED - bottom right",
5710 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
5711 decl3,
5712 FALSE, TRUE,
5713 {400, 360, 480, 420},
5715 /* Try with some invalid values */
5717 "0xffffffff (draws like COUNT4 | PROJECTED) - top left",
5718 0xffffffff,
5719 decl3,
5720 FALSE, TRUE,
5721 {120, 60, 240, 150}
5724 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (draws non-projected) - top right",
5725 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
5726 decl4,
5727 FALSE, TRUE,
5728 {340, 210, 360, 225},
5731 struct projected_textures_test_run projected_tests_2[4] =
5734 "D3DTTFF_PROJECTED (like COUNT4 | PROJECTED, texcoord has 4 components) - bottom left",
5735 D3DTTFF_PROJECTED,
5736 decl3,
5737 FALSE, TRUE,
5738 {120, 300, 240, 390},
5741 "D3DTTFF_PROJECTED (like COUNT3 | PROJECTED, texcoord has only 3 components) - bottom right",
5742 D3DTTFF_PROJECTED,
5743 decl,
5744 FALSE, TRUE,
5745 {400, 360, 480, 420},
5748 "0xffffffff (like COUNT3 | PROJECTED, texcoord has only 3 components) - top left",
5749 0xffffffff,
5750 decl,
5751 FALSE, TRUE,
5752 {80, 120, 160, 180},
5755 "D3DTTFF_COUNT1 (draws non-projected) - top right",
5756 D3DTTFF_COUNT1,
5757 decl4,
5758 FALSE, TRUE,
5759 {340, 210, 360, 225},
5762 struct projected_textures_test_run projected_tests_3[4] =
5765 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - bottom left",
5766 D3DTTFF_PROJECTED,
5767 decl3,
5768 TRUE, FALSE,
5769 {120, 300, 240, 390},
5772 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - bottom right",
5773 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
5774 decl3,
5775 TRUE, TRUE,
5776 {440, 300, 560, 390},
5779 "0xffffffff (like COUNT4 | PROJECTED) - top left",
5780 0xffffffff,
5781 decl3,
5782 TRUE, TRUE,
5783 {120, 60, 240, 150},
5786 "D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - top right",
5787 D3DTTFF_PROJECTED,
5788 decl3,
5789 FALSE, FALSE,
5790 {440, 60, 560, 150},
5794 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &identity);
5795 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5797 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5798 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5799 for(x = 0; x < 4; x++) {
5800 memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
5802 hr = IDirect3DTexture9_UnlockRect(texture, 0);
5803 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5804 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5805 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5807 projected_textures_test(device, projected_tests_1);
5808 projected_textures_test(device, projected_tests_2);
5809 projected_textures_test(device, projected_tests_3);
5811 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5812 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5813 IDirect3DTexture9_Release(texture);
5816 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
5817 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5818 /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
5819 * Thus watch out if sampling from texels between 0 and 1.
5821 hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
5822 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
5823 if(!volume) {
5824 skip("Failed to create a volume texture\n");
5825 goto out;
5828 hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
5829 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5830 for(z = 0; z < 32; z++) {
5831 for(y = 0; y < 32; y++) {
5832 for(x = 0; x < 32; x++) {
5833 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
5834 void *mem = ((char *) lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
5835 float r_f = (float) x / 31.0;
5836 float g_f = (float) y / 31.0;
5837 float b_f = (float) z / 31.0;
5839 if(fmt == D3DFMT_A16B16G16R16) {
5840 unsigned short *mem_s = mem;
5841 mem_s[0] = r_f * 65535.0;
5842 mem_s[1] = g_f * 65535.0;
5843 mem_s[2] = b_f * 65535.0;
5844 mem_s[3] = 65535;
5845 } else {
5846 unsigned char *mem_c = mem;
5847 mem_c[0] = b_f * 255.0;
5848 mem_c[1] = g_f * 255.0;
5849 mem_c[2] = r_f * 255.0;
5850 mem_c[3] = 255;
5855 hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
5856 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5858 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
5859 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5861 hr = IDirect3DDevice9_BeginScene(device);
5862 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5863 if(SUCCEEDED(hr))
5865 static const float quad1[] =
5867 -1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5868 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5869 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5870 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5872 static const float quad2[] =
5874 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5875 -1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5876 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5877 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5879 static const float quad3[] =
5881 0.0f, 0.0f, 0.1f, 0.0f, 0.0f,
5882 0.0f, 1.0f, 0.1f, 0.0f, 0.0f,
5883 1.0f, 0.0f, 0.1f, 0.0f, 0.0f,
5884 1.0f, 1.0f, 0.1f, 0.0f, 0.0f,
5886 static const float quad4[] =
5888 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5889 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5890 1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5891 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5893 D3DMATRIX mat =
5895 1.0f, 0.0f, 0.0f, 0.0f,
5896 0.0f, 0.0f, 1.0f, 0.0f,
5897 0.0f, 1.0f, 0.0f, 0.0f,
5898 0.0f, 0.0f, 0.0f, 1.0f,
5899 }}};
5900 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5901 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5903 /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
5904 * values
5906 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
5907 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5908 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
5909 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5910 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5911 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5913 /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
5914 * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
5915 * otherwise the w will be missing(blue).
5916 * turns out that on nvidia cards the blue color is missing, so it is an output modification.
5917 * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3. */
5918 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
5919 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5920 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5921 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5923 /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 3 */
5924 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &identity);
5925 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5926 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
5927 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5928 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5929 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5930 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
5931 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5933 /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
5934 * disable. ATI extends it up to the amount of values needed for the volume texture
5936 memset(&mat, 0, sizeof(mat));
5937 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
5938 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5939 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
5940 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5941 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5942 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5943 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5944 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5946 hr = IDirect3DDevice9_EndScene(device);
5947 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5950 color = getPixelColor(device, 160, 360);
5951 ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
5952 color = getPixelColor(device, 160, 120);
5953 ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
5954 "quad 2 has color %08x, expected 0x00ffff00\n", color);
5955 color = getPixelColor(device, 480, 120);
5956 ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
5957 color = getPixelColor(device, 480, 360);
5958 ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
5960 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5961 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5963 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
5964 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5965 hr = IDirect3DDevice9_BeginScene(device);
5966 ok(hr == S_OK, "Got hr %#lx.\n", hr);
5967 if(SUCCEEDED(hr))
5969 static const float quad1[] =
5971 -1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5972 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5973 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5974 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5976 static const float quad2[] =
5978 -1.0f, 0.0f, 0.1f,
5979 -1.0f, 1.0f, 0.1f,
5980 0.0f, 0.0f, 0.1f,
5981 0.0f, 1.0f, 0.1f,
5983 static const float quad3[] =
5985 0.0f, 0.0f, 0.1f, 1.0f,
5986 0.0f, 1.0f, 0.1f, 1.0f,
5987 1.0f, 0.0f, 0.1f, 1.0f,
5988 1.0f, 1.0f, 0.1f, 1.0f,
5990 static const D3DMATRIX mat =
5992 0.0f, 0.0f, 0.0f, 0.0f,
5993 0.0f, 0.0f, 0.0f, 0.0f,
5994 0.0f, 0.0f, 0.0f, 0.0f,
5995 0.0f, 1.0f, 0.0f, 0.0f,
5996 }}};
5997 static const D3DMATRIX mat2 =
5999 0.0f, 0.0f, 0.0f, 1.0f,
6000 1.0f, 0.0f, 0.0f, 0.0f,
6001 0.0f, 1.0f, 0.0f, 0.0f,
6002 0.0f, 0.0f, 1.0f, 0.0f,
6003 }}};
6004 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
6005 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6007 /* Default values? 4 coords used, 3 passed. What happens to the 4th?
6008 * Use COUNT3 because newer Nvidia drivers return black when there are more (output) coords
6009 * than being used by the texture(volume tex -> 3). Again, as shown in earlier test the COUNTx
6010 * affects the post-transformation output, so COUNT3 plus the matrix above is OK for testing the
6011 * 4th *input* coordinate.
6013 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
6014 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6015 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
6016 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6017 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
6018 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6020 /* None passed */
6021 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &identity);
6022 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6023 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6024 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6025 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
6026 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6028 /* 4 used, 1 passed */
6029 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
6030 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6031 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat2);
6032 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6033 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
6034 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6036 hr = IDirect3DDevice9_EndScene(device);
6037 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6039 color = getPixelColor(device, 160, 360);
6040 ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
6041 color = getPixelColor(device, 160, 120);
6042 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
6043 color = getPixelColor(device, 480, 120);
6044 ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
6045 /* Quad4: unused */
6047 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6048 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6050 IDirect3DVolumeTexture9_Release(volume);
6052 out:
6053 IDirect3DVertexDeclaration9_Release(decl);
6054 IDirect3DVertexDeclaration9_Release(decl2);
6055 IDirect3DVertexDeclaration9_Release(decl3);
6056 IDirect3DVertexDeclaration9_Release(decl4);
6057 refcount = IDirect3DDevice9_Release(device);
6058 ok(!refcount, "Device has %lu references left.\n", refcount);
6059 done:
6060 IDirect3D9_Release(d3d);
6061 DestroyWindow(window);
6064 static void texdepth_test(void)
6066 IDirect3DPixelShader9 *shader;
6067 IDirect3DDevice9 *device;
6068 unsigned int color;
6069 IDirect3D9 *d3d;
6070 ULONG refcount;
6071 D3DCAPS9 caps;
6072 HWND window;
6073 HRESULT hr;
6075 static const float texdepth_test_data1[] = { 0.25f, 2.0f, 0.0f, 0.0f};
6076 static const float texdepth_test_data2[] = { 0.25f, 0.5f, 0.0f, 0.0f};
6077 static const float texdepth_test_data3[] = {-1.00f, 0.1f, 0.0f, 0.0f};
6078 static const float texdepth_test_data4[] = {-0.25f, -0.5f, 0.0f, 0.0f};
6079 static const float texdepth_test_data5[] = { 1.00f, -0.1f, 0.0f, 0.0f};
6080 static const float texdepth_test_data6[] = { 1.00f, 0.5f, 0.0f, 0.0f};
6081 static const float texdepth_test_data7[] = { 0.50f, 0.0f, 0.0f, 0.0f};
6082 static const DWORD shader_code[] =
6084 0xffff0104, /* ps_1_4 */
6085 0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c1, 0, 0, 1, 1 */
6086 0x00000001, 0x800f0005, 0xa0e40000, /* mov r5, c0 */
6087 0x0000fffd, /* phase */
6088 0x00000057, 0x800f0005, /* texdepth r5 */
6089 0x00000001, 0x800f0000, 0xa0e40001, /* mov r0, c1 */
6090 0x0000ffff /* end */
6092 static const float vertex[] =
6094 -1.0f, -1.0f, 0.0f,
6095 -1.0f, 1.0f, 0.0f,
6096 1.0f, -1.0f, 1.0f,
6097 1.0f, 1.0f, 1.0f,
6100 window = create_window();
6101 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6102 ok(!!d3d, "Failed to create a D3D object.\n");
6103 if (!(device = create_device(d3d, window, window, TRUE)))
6105 skip("Failed to create a D3D device, skipping tests.\n");
6106 goto done;
6109 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6110 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
6111 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 4))
6113 skip("No ps_1_4 support, skipping tests.\n");
6114 IDirect3DDevice9_Release(device);
6115 goto done;
6118 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
6119 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6121 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
6122 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6123 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6124 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
6125 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
6126 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6127 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
6128 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6129 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
6130 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6131 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6132 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6134 /* Fill the depth buffer with a gradient */
6135 hr = IDirect3DDevice9_BeginScene(device);
6136 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
6137 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
6138 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
6139 hr = IDirect3DDevice9_EndScene(device);
6140 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
6142 /* Now perform the actual tests. Same geometry, but with the shader */
6143 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
6144 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6145 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
6146 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6147 hr = IDirect3DDevice9_SetPixelShader(device, shader);
6148 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6150 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
6151 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6152 hr = IDirect3DDevice9_BeginScene(device);
6153 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
6154 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
6155 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
6156 hr = IDirect3DDevice9_EndScene(device);
6157 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
6159 color = getPixelColor(device, 158, 240);
6160 ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
6161 color = getPixelColor(device, 162, 240);
6162 ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
6164 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6165 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6167 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
6168 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6170 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
6171 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6172 hr = IDirect3DDevice9_BeginScene(device);
6173 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
6174 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
6175 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
6176 hr = IDirect3DDevice9_EndScene(device);
6177 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
6179 color = getPixelColor(device, 318, 240);
6180 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
6181 color = getPixelColor(device, 322, 240);
6182 ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
6184 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6185 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6187 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6188 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6190 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
6191 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6192 hr = IDirect3DDevice9_BeginScene(device);
6193 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
6194 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
6195 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
6196 hr = IDirect3DDevice9_EndScene(device);
6197 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
6199 color = getPixelColor(device, 1, 240);
6200 ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
6202 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6203 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6205 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
6206 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6208 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
6209 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6210 hr = IDirect3DDevice9_BeginScene(device);
6211 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
6212 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
6213 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
6214 hr = IDirect3DDevice9_EndScene(device);
6215 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
6217 color = getPixelColor(device, 318, 240);
6218 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
6219 color = getPixelColor(device, 322, 240);
6220 ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
6222 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6223 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6225 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
6226 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6228 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
6229 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6230 hr = IDirect3DDevice9_BeginScene(device);
6231 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
6232 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
6233 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
6234 hr = IDirect3DDevice9_EndScene(device);
6235 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
6237 color = getPixelColor(device, 1, 240);
6238 ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
6240 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6241 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6243 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
6244 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6246 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
6247 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6248 hr = IDirect3DDevice9_BeginScene(device);
6249 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
6250 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
6251 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
6252 hr = IDirect3DDevice9_EndScene(device);
6253 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
6255 color = getPixelColor(device, 638, 240);
6256 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
6258 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6259 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6261 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6262 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6264 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
6265 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6266 hr = IDirect3DDevice9_BeginScene(device);
6267 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
6268 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
6269 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
6270 hr = IDirect3DDevice9_EndScene(device);
6271 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
6273 color = getPixelColor(device, 638, 240);
6274 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
6276 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6277 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6279 IDirect3DPixelShader9_Release(shader);
6280 refcount = IDirect3DDevice9_Release(device);
6281 ok(!refcount, "Device has %lu references left.\n", refcount);
6282 done:
6283 IDirect3D9_Release(d3d);
6284 DestroyWindow(window);
6287 static void texkill_test(void)
6289 IDirect3DPixelShader9 *shader;
6290 IDirect3DDevice9 *device;
6291 unsigned int color;
6292 IDirect3D9 *d3d;
6293 ULONG refcount;
6294 D3DCAPS9 caps;
6295 HWND window;
6296 HRESULT hr;
6298 static const float vertex[] =
6300 /* bottom top right left */
6301 -1.0f, -1.0f, 1.0f, -0.1f, 0.9f, 0.9f, -0.1f,
6302 -1.0f, 1.0f, 1.0f, -0.1f, 0.9f, -0.1f, 0.9f,
6303 1.0f, -1.0f, 0.0f, 0.9f, -0.1f, 0.9f, -0.1f,
6304 1.0f, 1.0f, 0.0f, 0.9f, -0.1f, -0.1f, 0.9f,
6306 static const DWORD shader_code_11[] =
6308 0xffff0101, /* ps_1_1 */
6309 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
6310 0x00000041, 0xb00f0000, /* texkill t0 */
6311 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6312 0x0000ffff /* end */
6314 static const DWORD shader_code_20[] =
6316 0xffff0200, /* ps_2_0 */
6317 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
6318 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
6319 0x01000041, 0xb00f0000, /* texkill t0 */
6320 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
6321 0x0000ffff /* end */
6324 window = create_window();
6325 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6326 ok(!!d3d, "Failed to create a D3D object.\n");
6327 if (!(device = create_device(d3d, window, window, TRUE)))
6329 skip("Failed to create a D3D device, skipping tests.\n");
6330 goto done;
6333 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6334 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
6335 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
6337 skip("No ps_1_1 support, skipping tests.\n");
6338 IDirect3DDevice9_Release(device);
6339 goto done;
6342 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
6343 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6344 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
6345 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6347 hr = IDirect3DDevice9_SetPixelShader(device, shader);
6348 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6349 hr = IDirect3DDevice9_BeginScene(device);
6350 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
6351 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
6352 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
6353 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
6354 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
6355 hr = IDirect3DDevice9_EndScene(device);
6356 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
6358 color = getPixelColor(device, 63, 46);
6359 ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
6360 color = getPixelColor(device, 66, 46);
6361 ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
6362 color = getPixelColor(device, 63, 49);
6363 ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
6364 color = getPixelColor(device, 66, 49);
6365 ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
6367 color = getPixelColor(device, 578, 46);
6368 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
6369 color = getPixelColor(device, 575, 46);
6370 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
6371 color = getPixelColor(device, 578, 49);
6372 ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
6373 color = getPixelColor(device, 575, 49);
6374 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
6376 color = getPixelColor(device, 63, 430);
6377 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
6378 color = getPixelColor(device, 63, 433);
6379 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
6380 color = getPixelColor(device, 66, 433);
6381 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
6382 color = getPixelColor(device, 66, 430);
6383 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
6385 color = getPixelColor(device, 578, 430);
6386 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
6387 color = getPixelColor(device, 578, 433);
6388 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
6389 color = getPixelColor(device, 575, 433);
6390 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
6391 color = getPixelColor(device, 575, 430);
6392 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
6394 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6395 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6397 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6398 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6399 IDirect3DPixelShader9_Release(shader);
6401 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
6402 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6403 if (FAILED(IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader)))
6405 skip("Failed to create 2.0 test shader, most likely not supported.\n");
6406 IDirect3DDevice9_Release(device);
6407 goto done;
6410 hr = IDirect3DDevice9_SetPixelShader(device, shader);
6411 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6412 hr = IDirect3DDevice9_BeginScene(device);
6413 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
6414 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
6415 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
6416 hr = IDirect3DDevice9_EndScene(device);
6417 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
6419 color = getPixelColor(device, 63, 46);
6420 ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
6421 color = getPixelColor(device, 66, 46);
6422 ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
6423 color = getPixelColor(device, 63, 49);
6424 ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
6425 color = getPixelColor(device, 66, 49);
6426 ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
6428 color = getPixelColor(device, 578, 46);
6429 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
6430 color = getPixelColor(device, 575, 46);
6431 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
6432 color = getPixelColor(device, 578, 49);
6433 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
6434 color = getPixelColor(device, 575, 49);
6435 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
6437 color = getPixelColor(device, 63, 430);
6438 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
6439 color = getPixelColor(device, 63, 433);
6440 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
6441 color = getPixelColor(device, 66, 433);
6442 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
6443 color = getPixelColor(device, 66, 430);
6444 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
6446 color = getPixelColor(device, 578, 430);
6447 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
6448 color = getPixelColor(device, 578, 433);
6449 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
6450 color = getPixelColor(device, 575, 433);
6451 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
6452 color = getPixelColor(device, 575, 430);
6453 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
6455 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6456 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6458 IDirect3DPixelShader9_Release(shader);
6459 refcount = IDirect3DDevice9_Release(device);
6460 ok(!refcount, "Device has %lu references left.\n", refcount);
6461 done:
6462 IDirect3D9_Release(d3d);
6463 DestroyWindow(window);
6466 static void test_generate_mipmap(void)
6468 static const RECT r1 = {256, 256, 512, 512};
6469 static const RECT r2 = {512, 256, 768, 512};
6470 static const RECT r3 = {256, 512, 512, 768};
6471 static const RECT r4 = {512, 512, 768, 768};
6472 static const float quad[] =
6474 -0.5f, -0.5f, 0.1f, 0.0f, 0.0f,
6475 -0.5f, 0.5f, 0.1f, 0.0f, 1.0f,
6476 0.5f, -0.5f, 0.1f, 1.0f, 0.0f,
6477 0.5f, 0.5f, 0.1f, 1.0f, 1.0f,
6479 IDirect3DTexture9 *texture, *texture2;
6480 IDirect3DSurface9 *surface, *surface2;
6481 IDirect3DDevice9 *device;
6482 unsigned int color, x, y;
6483 D3DLOCKED_RECT lr;
6484 IDirect3D9 *d3d;
6485 ULONG refcount;
6486 HWND window;
6487 HRESULT hr;
6489 window = create_window();
6490 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6491 ok(!!d3d, "Failed to create a D3D object.\n");
6492 if (!(device = create_device(d3d, window, window, TRUE)))
6494 skip("Failed to create a D3D device, skipping tests.\n");
6495 goto done;
6498 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 1.0f, 0);
6499 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
6501 /* Make the texture big enough that a mipmap level > 0 is used. */
6502 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_RENDERTARGET,
6503 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, 0);
6504 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
6506 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, 0,
6507 D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &texture2, 0);
6508 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
6510 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6511 ok(SUCCEEDED(hr), "Failed to get surface, hr %#lx.\n", hr);
6512 hr = IDirect3DTexture9_GetSurfaceLevel(texture2, 0, &surface2);
6513 ok(SUCCEEDED(hr), "Failed to get surface, hr %#lx.\n", hr);
6514 hr = IDirect3DSurface9_LockRect(surface2, &lr, NULL, 0);
6515 ok(SUCCEEDED(hr), "Failed to map surface, hr %#lx.\n", hr);
6516 for (y = 0; y < 1024; ++y)
6518 for(x = 0; x < 1024; ++x)
6520 DWORD *dst = (DWORD *)((BYTE *)lr.pBits + y * lr.Pitch + x * 4);
6521 POINT pt;
6523 pt.x = x;
6524 pt.y = y;
6525 if (PtInRect(&r1, pt))
6526 *dst = 0xffff0000;
6527 else if (PtInRect(&r2, pt))
6528 *dst = 0xff00ff00;
6529 else if (PtInRect(&r3, pt))
6530 *dst = 0xff0000ff;
6531 else if (PtInRect(&r4, pt))
6532 *dst = 0xff000000;
6533 else
6534 *dst = 0xffffffff;
6537 hr = IDirect3DSurface9_UnlockRect(surface2);
6538 ok(SUCCEEDED(hr), "Failed to unmap surface, hr %#lx.\n", hr);
6540 hr = IDirect3DDevice9_UpdateSurface(device, surface2, NULL, surface, NULL);
6541 ok(SUCCEEDED(hr), "Failed to update surface, hr %#lx.\n", hr);
6543 IDirect3DSurface9_Release(surface2);
6544 IDirect3DSurface9_Release(surface);
6545 IDirect3DTexture9_Release(texture2);
6547 hr = IDirect3DTexture9_SetAutoGenFilterType(texture, D3DTEXF_LINEAR);
6548 ok(SUCCEEDED(hr), "Failed to set mipmap autogen filter type, hr %#lx.\n", hr);
6550 IDirect3DTexture9_GenerateMipSubLevels(texture);
6552 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
6553 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
6554 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
6555 ok(SUCCEEDED(hr), "Failed to set mipmap filtering, hr %#lx.\n", hr);
6556 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6557 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
6559 hr = IDirect3DDevice9_BeginScene(device);
6560 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
6561 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6562 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
6563 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6564 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
6565 hr = IDirect3DDevice9_EndScene(device);
6566 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
6567 IDirect3DTexture9_Release(texture);
6569 color = getPixelColor(device, 200, 200);
6570 ok(!color, "Unexpected color 0x%08x.\n", color);
6571 color = getPixelColor(device, 280, 200);
6572 ok(!color, "Unexpected color 0x%08x.\n", color);
6573 color = getPixelColor(device, 360, 200);
6574 ok(!color, "Unexpected color 0x%08x.\n", color);
6575 color = getPixelColor(device, 440, 200);
6576 ok(!color, "Unexpected color 0x%08x.\n", color);
6577 color = getPixelColor(device, 200, 270);
6578 ok(!color, "Unexpected color 0x%08x.\n", color);
6579 color = getPixelColor(device, 280, 270);
6580 ok(!color, "Unexpected color 0x%08x.\n", color);
6581 color = getPixelColor(device, 360, 270);
6582 ok(!color, "Unexpected color 0x%08x.\n", color);
6583 color = getPixelColor(device, 440, 270);
6584 ok(!color, "Unexpected color 0x%08x.\n", color);
6585 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6586 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
6588 refcount = IDirect3DDevice9_Release(device);
6589 ok(!refcount, "Device has %lu references left.\n", refcount);
6590 done:
6591 IDirect3D9_Release(d3d);
6592 DestroyWindow(window);
6595 static void test_mipmap_autogen(void)
6597 IDirect3DSurface9 *surface, *surface2, *surface3, *backbuffer;
6598 IDirect3DTexture9 *texture, *texture2, *texture3;
6599 IDirect3DCubeTexture9 *cube_texture;
6600 unsigned int color, i, x, y;
6601 IDirect3DDevice9 *device;
6602 D3DLOCKED_RECT lr;
6603 IDirect3D9 *d3d;
6604 ULONG refcount;
6605 D3DCAPS9 caps;
6606 HWND window;
6607 HRESULT hr;
6609 static const RECT r1 = {256, 256, 512, 512};
6610 static const RECT r2 = {512, 256, 768, 512};
6611 static const RECT r3 = {256, 512, 512, 768};
6612 static const RECT r4 = {512, 512, 768, 768};
6613 static const float quad[] =
6615 -0.5f, -0.5f, 0.1f, 0.0f, 0.0f,
6616 -0.5f, 0.5f, 0.1f, 0.0f, 1.0f,
6617 0.5f, -0.5f, 0.1f, 1.0f, 0.0f,
6618 0.5f, 0.5f, 0.1f, 1.0f, 1.0f,
6621 window = create_window();
6622 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6623 ok(!!d3d, "Failed to create a D3D object.\n");
6624 if (!(device = create_device(d3d, window, window, TRUE)))
6626 skip("Failed to create a D3D device, skipping tests.\n");
6627 goto done;
6630 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
6631 D3DFMT_X8R8G8B8, D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK)
6633 skip("No autogenmipmap support.\n");
6634 IDirect3DDevice9_Release(device);
6635 goto done;
6638 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6639 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#lx.\n", hr);
6641 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 1.0f, 0);
6642 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6644 /* Make the texture big enough that a mipmap level > 0 is used. */
6645 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
6646 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
6647 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6649 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6650 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6651 memset(&lr, 0, sizeof(lr));
6652 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
6653 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6654 for(y = 0; y < 1024; y++) {
6655 for(x = 0; x < 1024; x++) {
6656 DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
6657 POINT pt;
6659 pt.x = x;
6660 pt.y = y;
6661 if(PtInRect(&r1, pt)) {
6662 *dst = 0xffff0000;
6663 } else if(PtInRect(&r2, pt)) {
6664 *dst = 0xff00ff00;
6665 } else if(PtInRect(&r3, pt)) {
6666 *dst = 0xff0000ff;
6667 } else if(PtInRect(&r4, pt)) {
6668 *dst = 0xff000000;
6669 } else {
6670 *dst = 0xffffffff;
6674 hr = IDirect3DSurface9_UnlockRect(surface);
6675 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6676 IDirect3DSurface9_Release(surface);
6678 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6679 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6680 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
6681 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6682 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6683 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
6685 hr = IDirect3DDevice9_BeginScene(device);
6686 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
6687 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6688 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
6689 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6690 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
6691 hr = IDirect3DDevice9_EndScene(device);
6692 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
6693 IDirect3DTexture9_Release(texture);
6695 color = getPixelColor(device, 200, 200);
6696 ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
6697 color = getPixelColor(device, 280, 200);
6698 ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
6699 color = getPixelColor(device, 360, 200);
6700 ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
6701 color = getPixelColor(device, 440, 200);
6702 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
6703 color = getPixelColor(device, 200, 270);
6704 ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
6705 color = getPixelColor(device, 280, 270);
6706 ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
6707 color = getPixelColor(device, 360, 270);
6708 ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
6709 color = getPixelColor(device, 440, 270);
6710 ok(color == 0x00ffffff, "pixel 440/270 has color %08x, expected 0x00ffffff\n", color);
6711 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6712 ok(hr == S_OK, "Got hr %#lx.\n", hr);
6714 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6715 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
6716 if (!(caps.DevCaps2 & D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES))
6718 skip("Blitting from textures is not supported.\n");
6719 IDirect3DSurface9_Release(backbuffer);
6720 IDirect3DDevice9_Release(device);
6721 goto done;
6723 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1, 0,
6724 D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &texture, 0);
6725 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
6726 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
6727 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture2, 0);
6728 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
6729 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP | D3DUSAGE_RENDERTARGET,
6730 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture3, 0);
6731 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
6733 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6734 ok(SUCCEEDED(hr), "Failed to get surface, hr %#lx.\n", hr);
6735 memset(&lr, 0, sizeof(lr));
6736 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
6737 ok(SUCCEEDED(hr), "Failed to map surface, hr %#lx.\n", hr);
6738 for (y = 0; y < 1024; ++y)
6740 for (x = 0; x < 1024; ++x)
6742 DWORD *dst = (DWORD *)((BYTE *)lr.pBits + y * lr.Pitch + x * 4);
6743 POINT pt;
6745 pt.x = x;
6746 pt.y = y;
6747 if (PtInRect(&r1, pt))
6748 *dst = 0xffff0000;
6749 else if (PtInRect(&r2, pt))
6750 *dst = 0xff00ff00;
6751 else if (PtInRect(&r3, pt))
6752 *dst = 0xff0000ff;
6753 else if (PtInRect(&r4, pt))
6754 *dst = 0xff000000;
6755 else
6756 *dst = 0xffffffff;
6759 hr = IDirect3DSurface9_UnlockRect(surface);
6760 ok(SUCCEEDED(hr), "Failed to unmap surface, hr %#lx.\n", hr);
6761 IDirect3DSurface9_Release(surface);
6763 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)texture,
6764 (IDirect3DBaseTexture9 *)texture2);
6765 ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx.\n", hr);
6767 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture2);
6768 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
6770 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 1.0f, 0);
6771 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
6773 hr = IDirect3DDevice9_BeginScene(device);
6774 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
6775 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6776 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
6777 hr = IDirect3DDevice9_EndScene(device);
6778 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
6780 color = getPixelColor(device, 200, 200);
6781 ok(color == 0x00ffffff, "Unexpected color 0x%08x.\n", color);
6782 color = getPixelColor(device, 280, 200);
6783 ok(color == 0x000000ff, "Unexpected color 0x%08x.\n", color);
6784 color = getPixelColor(device, 360, 200);
6785 ok(color == 0x00000000, "Unexpected color 0x%08x.\n", color);
6786 color = getPixelColor(device, 440, 200);
6787 ok(color == 0x00ffffff, "Unexpected color 0x%08x.\n", color);
6788 color = getPixelColor(device, 200, 270);
6789 ok(color == 0x00ffffff, "Unexpected color 0x%08x.\n", color);
6790 color = getPixelColor(device, 280, 270);
6791 ok(color == 0x00ff0000, "Unexpected color 0x%08x.\n", color);
6792 color = getPixelColor(device, 360, 270);
6793 ok(color == 0x0000ff00, "Unexpected color 0x%08x.\n", color);
6794 color = getPixelColor(device, 440, 270);
6795 ok(color == 0x00ffffff, "Unexpected color 0x%08x.\n", color);
6797 hr = IDirect3DTexture9_GetSurfaceLevel(texture2, 0, &surface2);
6798 ok(SUCCEEDED(hr), "Failed to get surface, hr %#lx.\n", hr);
6799 hr = IDirect3DTexture9_GetSurfaceLevel(texture3, 0, &surface3);
6800 ok(SUCCEEDED(hr), "Failed to get surface, hr %#lx.\n", hr);
6801 hr = IDirect3DDevice9_StretchRect(device, surface2, NULL, surface3, NULL, D3DTEXF_POINT);
6802 ok(SUCCEEDED(hr), "Failed to blit texture, hr %#lx.\n", hr);
6804 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture3);
6805 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
6807 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 1.0f, 0);
6808 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
6810 hr = IDirect3DDevice9_BeginScene(device);
6811 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
6812 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6813 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
6814 hr = IDirect3DDevice9_EndScene(device);
6815 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
6817 color = getPixelColor(device, 200, 200);
6818 ok(color == 0x00ffffff, "Unexpected color 0x%08x.\n", color);
6819 color = getPixelColor(device, 280, 200);
6820 ok(color == 0x000000ff, "Unexpected color 0x%08x.\n", color);
6821 color = getPixelColor(device, 360, 200);
6822 ok(color == 0x00000000, "Unexpected color 0x%08x.\n", color);
6823 color = getPixelColor(device, 440, 200);
6824 ok(color == 0x00ffffff, "Unexpected color 0x%08x.\n", color);
6825 color = getPixelColor(device, 200, 270);
6826 ok(color == 0x00ffffff, "Unexpected color 0x%08x.\n", color);
6827 color = getPixelColor(device, 280, 270);
6828 ok(color == 0x00ff0000, "Unexpected color 0x%08x.\n", color);
6829 color = getPixelColor(device, 360, 270);
6830 ok(color == 0x0000ff00, "Unexpected color 0x%08x.\n", color);
6831 color = getPixelColor(device, 440, 270);
6832 ok(color == 0x00ffffff, "Unexpected color 0x%08x.\n", color);
6834 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface3);
6835 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
6837 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 1.0f, 0);
6838 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
6840 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
6841 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
6843 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 1.0f, 0);
6844 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
6846 hr = IDirect3DDevice9_BeginScene(device);
6847 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
6848 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6849 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
6850 hr = IDirect3DDevice9_EndScene(device);
6851 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
6853 color = getPixelColor(device, 200, 200);
6854 ok(color == 0x0000ffff, "Unexpected color 0x%08x.\n", color);
6856 IDirect3DSurface9_Release(surface3);
6857 IDirect3DSurface9_Release(surface2);
6858 IDirect3DTexture9_Release(texture3);
6859 IDirect3DTexture9_Release(texture2);
6860 IDirect3DTexture9_Release(texture);
6862 if (!(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP))
6864 skip("No cube textures support.\n");
6865 IDirect3DSurface9_Release(backbuffer);
6866 IDirect3DDevice9_Release(device);
6867 goto done;
6869 hr = IDirect3DDevice9_CreateCubeTexture(device, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
6870 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &cube_texture, 0);
6871 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
6872 for (i = 0; i < 6; ++i)
6874 hr = IDirect3DCubeTexture9_LockRect(cube_texture, i, 0, &lr, NULL, 0);
6875 ok(SUCCEEDED(hr), "Failed to map texture, hr %#lx.\n", hr);
6877 for (y = 0; y < 1024; ++y)
6879 for (x = 0; x < 1024; ++x)
6881 DWORD *dst = (DWORD *)((BYTE *)lr.pBits + y * lr.Pitch + x * 4);
6882 POINT pt;
6884 pt.x = x;
6885 pt.y = y;
6886 if (PtInRect(&r1, pt))
6887 *dst = 0xffff0000;
6888 else if (PtInRect(&r2, pt))
6889 *dst = 0xff00ff00;
6890 else if (PtInRect(&r3, pt))
6891 *dst = 0xff0000ff;
6892 else if (PtInRect(&r4, pt))
6893 *dst = 0xff000000;
6894 else
6895 *dst = 0xffffffff;
6898 hr = IDirect3DCubeTexture9_UnlockRect(cube_texture, i, 0);
6899 ok(SUCCEEDED(hr), "Failed to unmap texture, hr %#lx.\n", hr);
6902 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)cube_texture);
6903 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
6905 hr = IDirect3DDevice9_BeginScene(device);
6906 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
6907 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6908 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
6909 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6910 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
6911 hr = IDirect3DDevice9_EndScene(device);
6912 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
6913 IDirect3DCubeTexture9_Release(cube_texture);
6915 color = getPixelColor(device, 200, 200);
6916 ok(color == 0x00000000, "Unexpected color 0x%08x.\n", color);
6917 color = getPixelColor(device, 280, 200);
6918 ok(color == 0x00ffffff, "Unexpected color 0x%08x.\n", color);
6919 color = getPixelColor(device, 360, 200);
6920 ok(color == 0x00ffffff, "Unexpected color 0x%08x.\n", color);
6921 color = getPixelColor(device, 440, 200);
6922 ok(color == 0x00ffffff, "Unexpected color 0x%08x.\n", color);
6923 color = getPixelColor(device, 200, 270);
6924 ok(color == 0x00000000, "Unexpected color 0x%08x.\n", color);
6925 color = getPixelColor(device, 280, 270);
6926 ok(color == 0x00ffffff, "Unexpected color 0x%08x.\n", color);
6927 color = getPixelColor(device, 360, 270);
6928 ok(color == 0x00ffffff, "Unexpected color 0x%08x.\n", color);
6929 color = getPixelColor(device, 440, 270);
6930 ok(color == 0x0000ff00, "Unexpected color 0x%08x.\n", color);
6932 /* Test format not supporting D3DUSAGE_AUTOGENMIPMAP. */
6933 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
6934 D3DFMT_X8R8G8B8, D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_A1R5G5B5);
6935 if (hr != D3DOK_NOAUTOGEN)
6937 skip("D3DFMT_A1R5G5B5 support is not D3DOK_NOAUTOGEN (hr %#lx).\n", hr);
6939 else
6941 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
6942 D3DFMT_A1R5G5B5, D3DPOOL_MANAGED, &texture, 0);
6943 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
6945 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
6946 ok(SUCCEEDED(hr), "Failed to map texture, hr %#lx.\n", hr);
6947 for (y = 0; y < 1024; ++y)
6949 for (x = 0; x < 1024; ++x)
6951 WORD *dst = (WORD *)(((BYTE *)lr.pBits) + y * lr.Pitch + x * 2);
6952 POINT pt;
6954 pt.x = x;
6955 pt.y = y;
6956 if (PtInRect(&r1, pt))
6957 *dst = 0xfc00;
6958 else if (PtInRect(&r2, pt))
6959 *dst = 0x83e0;
6960 else if (PtInRect(&r3, pt))
6961 *dst = 0x801f;
6962 else if (PtInRect(&r4, pt))
6963 *dst = 0x8000;
6964 else
6965 *dst = 0xffff;
6968 hr = IDirect3DTexture9_UnlockRect(texture, 0);
6969 ok(SUCCEEDED(hr), "Failed to unmap texture, hr %#lx.\n", hr);
6971 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
6972 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
6974 hr = IDirect3DDevice9_BeginScene(device);
6975 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
6976 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6977 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
6978 hr = IDirect3DDevice9_EndScene(device);
6979 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
6980 IDirect3DTexture9_Release(texture);
6982 color = getPixelColor(device, 200, 200);
6983 ok(color == 0x00ffffff, "Unexpected color 0x%08x.\n", color);
6984 color = getPixelColor(device, 280, 200);
6985 ok(color == 0x000000ff, "Unexpected color 0x%08x.\n", color);
6986 color = getPixelColor(device, 360, 200);
6987 ok(color == 0x00000000, "Unexpected color 0x%08x.\n", color);
6988 color = getPixelColor(device, 440, 200);
6989 ok(color == 0x00ffffff, "Unexpected color 0x%08x.\n", color);
6990 color = getPixelColor(device, 200, 270);
6991 ok(color == 0x00ffffff, "Unexpected color 0x%08x.\n", color);
6992 color = getPixelColor(device, 280, 270);
6993 ok(color == 0x00ff0000, "Unexpected color 0x%08x.\n", color);
6994 color = getPixelColor(device, 360, 270);
6995 ok(color == 0x0000ff00, "Unexpected color 0x%08x.\n", color);
6996 color = getPixelColor(device, 440, 270);
6997 ok(color == 0x00ffffff, "Unexpected color 0x%08x.\n", color);
6998 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6999 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
7002 IDirect3DSurface9_Release(backbuffer);
7004 refcount = IDirect3DDevice9_Release(device);
7005 ok(!refcount, "Device has %lu references left.\n", refcount);
7006 done:
7007 IDirect3D9_Release(d3d);
7008 DestroyWindow(window);
7011 static void test_constant_clamp_vs(void)
7013 IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
7014 IDirect3DVertexDeclaration9 *decl;
7015 IDirect3DDevice9 *device;
7016 unsigned int color;
7017 IDirect3D9 *d3d;
7018 ULONG refcount;
7019 D3DCAPS9 caps;
7020 HWND window;
7021 HRESULT hr;
7023 static const DWORD shader_code_11[] =
7025 0xfffe0101, /* vs_1_1 */
7026 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7027 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
7028 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
7029 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7030 0x0000ffff /* end */
7032 static const DWORD shader_code_11_2[] =
7034 0xfffe0101, /* vs_1_1 */
7035 0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
7036 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
7037 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7038 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
7039 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
7040 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7041 0x0000ffff /* end */
7043 static const DWORD shader_code_20[] =
7045 0xfffe0200, /* vs_2_0 */
7046 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7047 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
7048 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
7049 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7050 0x0000ffff /* end */
7052 static const DWORD shader_code_20_2[] =
7054 0xfffe0200, /* vs_2_0 */
7055 0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
7056 0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
7057 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7058 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
7059 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
7060 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7061 0x0000ffff /* end */
7063 static const D3DVERTEXELEMENT9 decl_elements[] =
7065 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7066 D3DDECL_END()
7068 static const float quad1[] =
7070 -1.0f, -1.0f, 0.1f,
7071 -1.0f, 0.0f, 0.1f,
7072 0.0f, -1.0f, 0.1f,
7073 0.0f, 0.0f, 0.1f,
7075 static const float quad2[] =
7077 0.0f, -1.0f, 0.1f,
7078 0.0f, 0.0f, 0.1f,
7079 1.0f, -1.0f, 0.1f,
7080 1.0f, 0.0f, 0.1f,
7082 static const float quad3[] =
7084 0.0f, 0.0f, 0.1f,
7085 0.0f, 1.0f, 0.1f,
7086 1.0f, 0.0f, 0.1f,
7087 1.0f, 1.0f, 0.1f,
7089 static const float quad4[] =
7091 -1.0f, 0.0f, 0.1f,
7092 -1.0f, 1.0f, 0.1f,
7093 0.0f, 0.0f, 0.1f,
7094 0.0f, 1.0f, 0.1f,
7096 static const float test_data_c1[4] = { 1.25f, -0.50f, -1.50f, 1.0f};
7097 static const float test_data_c2[4] = {-0.50f, 1.25f, 2.00f, 1.0f};
7099 window = create_window();
7100 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7101 ok(!!d3d, "Failed to create a D3D object.\n");
7102 if (!(device = create_device(d3d, window, window, TRUE)))
7104 skip("Failed to create a D3D device, skipping tests.\n");
7105 goto done;
7108 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7109 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
7110 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
7112 skip("No vs_1_1 support, skipping tests.\n");
7113 IDirect3DDevice9_Release(device);
7114 goto done;
7117 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
7118 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7120 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
7121 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7122 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
7123 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7124 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
7125 if(FAILED(hr)) shader_20 = NULL;
7126 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
7127 if(FAILED(hr)) shader_20_2 = NULL;
7128 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
7129 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7131 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
7132 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7133 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
7134 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7135 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
7136 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7138 hr = IDirect3DDevice9_BeginScene(device);
7139 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
7141 hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
7142 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
7143 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
7144 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
7146 hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
7147 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
7148 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
7149 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
7151 if (shader_20)
7153 hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
7154 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
7155 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
7156 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
7159 if (shader_20_2)
7161 hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
7162 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
7163 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
7164 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
7167 hr = IDirect3DDevice9_EndScene(device);
7168 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
7170 color = getPixelColor(device, 160, 360);
7171 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
7172 "quad 1 has color %08x, expected 0x00bfbf80\n", color);
7173 color = getPixelColor(device, 480, 360);
7174 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
7175 "quad 2 has color %08x, expected 0x00bfbf80\n", color);
7176 if(shader_20) {
7177 color = getPixelColor(device, 480, 120);
7178 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
7179 "quad 3 has color %08x, expected 0x00bfbf80\n", color);
7181 if(shader_20_2) {
7182 color = getPixelColor(device, 160, 120);
7183 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
7184 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
7186 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7187 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7189 IDirect3DVertexDeclaration9_Release(decl);
7190 if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
7191 if(shader_20) IDirect3DVertexShader9_Release(shader_20);
7192 IDirect3DVertexShader9_Release(shader_11_2);
7193 IDirect3DVertexShader9_Release(shader_11);
7194 refcount = IDirect3DDevice9_Release(device);
7195 ok(!refcount, "Device has %lu references left.\n", refcount);
7196 done:
7197 IDirect3D9_Release(d3d);
7198 DestroyWindow(window);
7201 static void constant_clamp_ps_test(void)
7203 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
7204 IDirect3DDevice9 *device;
7205 unsigned int color;
7206 IDirect3D9 *d3d;
7207 ULONG refcount;
7208 D3DCAPS9 caps;
7209 HWND window;
7210 HRESULT hr;
7212 static const DWORD shader_code_11[] =
7214 0xffff0101, /* ps_1_1 */
7215 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
7216 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
7217 0x0000ffff /* end */
7219 static const DWORD shader_code_12[] =
7221 0xffff0102, /* ps_1_2 */
7222 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
7223 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
7224 0x0000ffff /* end */
7226 /* Skip 1.3 shaders because we have only 4 quads (ok, could make them
7227 * smaller if needed). 1.2 and 1.4 shaders behave the same, so it's
7228 * unlikely that 1.3 shaders are different. During development of this
7229 * test, 1.3 shaders were verified too. */
7230 static const DWORD shader_code_14[] =
7232 0xffff0104, /* ps_1_4 */
7233 /* Try to make one constant local. It gets clamped too, although the
7234 * binary contains the bigger numbers. */
7235 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
7236 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
7237 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
7238 0x0000ffff /* end */
7240 static const DWORD shader_code_20[] =
7242 0xffff0200, /* ps_2_0 */
7243 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
7244 0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
7245 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
7246 0x0000ffff /* end */
7248 static const float quad1[] =
7250 -1.0f, -1.0f, 0.1f,
7251 -1.0f, 0.0f, 0.1f,
7252 0.0f, -1.0f, 0.1f,
7253 0.0f, 0.0f, 0.1f,
7255 static const float quad2[] =
7257 0.0f, -1.0f, 0.1f,
7258 0.0f, 0.0f, 0.1f,
7259 1.0f, -1.0f, 0.1f,
7260 1.0f, 0.0f, 0.1f,
7262 static const float quad3[] =
7264 0.0f, 0.0f, 0.1f,
7265 0.0f, 1.0f, 0.1f,
7266 1.0f, 0.0f, 0.1f,
7267 1.0f, 1.0f, 0.1f,
7269 static const float quad4[] =
7271 -1.0f, 0.0f, 0.1f,
7272 -1.0f, 1.0f, 0.1f,
7273 0.0f, 0.0f, 0.1f,
7274 0.0f, 1.0f, 0.1f,
7276 static const float test_data_c1[4] = { 1.25f, -0.50f, -1.50f, 1.0f};
7277 static const float test_data_c2[4] = {-0.50f, 1.25f, 2.00f, 1.0f};
7279 window = create_window();
7280 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7281 ok(!!d3d, "Failed to create a D3D object.\n");
7282 if (!(device = create_device(d3d, window, window, TRUE)))
7284 skip("Failed to create a D3D device, skipping tests.\n");
7285 goto done;
7288 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7289 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
7290 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 4))
7292 skip("No ps_1_4 support, skipping tests.\n");
7293 IDirect3DDevice9_Release(device);
7294 goto done;
7297 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
7298 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7300 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
7301 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7302 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
7303 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7304 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
7305 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7306 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
7307 if(FAILED(hr)) shader_20 = NULL;
7309 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
7310 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7311 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
7312 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7313 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7314 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7316 hr = IDirect3DDevice9_BeginScene(device);
7317 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
7319 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
7320 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
7321 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
7322 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
7324 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
7325 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
7326 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
7327 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
7329 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
7330 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
7331 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
7332 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
7334 if (shader_20)
7336 hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
7337 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
7338 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
7339 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
7342 hr = IDirect3DDevice9_EndScene(device);
7343 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
7345 color = getPixelColor(device, 160, 360);
7346 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
7347 "quad 1 has color %08x, expected 0x00808000\n", color);
7348 color = getPixelColor(device, 480, 360);
7349 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
7350 "quad 2 has color %08x, expected 0x00808000\n", color);
7351 color = getPixelColor(device, 480, 120);
7352 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
7353 "quad 3 has color %08x, expected 0x00808000\n", color);
7354 if(shader_20) {
7355 color = getPixelColor(device, 160, 120);
7356 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
7357 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
7359 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7360 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7362 if(shader_20) IDirect3DPixelShader9_Release(shader_20);
7363 IDirect3DPixelShader9_Release(shader_14);
7364 IDirect3DPixelShader9_Release(shader_12);
7365 IDirect3DPixelShader9_Release(shader_11);
7366 refcount = IDirect3DDevice9_Release(device);
7367 ok(!refcount, "Device has %lu references left.\n", refcount);
7368 done:
7369 IDirect3D9_Release(d3d);
7370 DestroyWindow(window);
7373 static void dp2add_ps_test(void)
7375 IDirect3DPixelShader9 *shader_dp2add_sat;
7376 IDirect3DPixelShader9 *shader_dp2add;
7377 IDirect3DDevice9 *device;
7378 unsigned int color;
7379 IDirect3D9 *d3d;
7380 ULONG refcount;
7381 D3DCAPS9 caps;
7382 HWND window;
7383 HRESULT hr;
7385 /* DP2ADD is defined as: (src0.r * src1.r) + (src0.g * src1.g) + src2.
7386 * One D3D restriction of all shader instructions except SINCOS is that no more than 2
7387 * source tokens can be constants. So, for this exercise, we move contents of c0 to
7388 * r0 first.
7389 * The result here for the r,g,b components should be roughly 0.5:
7390 * (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
7391 static const DWORD shader_code_dp2add[] = {
7392 0xffff0200, /* ps_2_0 */
7393 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0 */
7395 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
7396 0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add r0.rgb, r0, r0, r0.a */
7398 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
7399 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
7400 0x0000ffff /* end */
7403 /* Test the _sat modifier, too. Result here should be:
7404 * DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
7405 * _SAT: ==> 1.0
7406 * ADD: (1.0 + -0.5) = 0.5
7408 static const DWORD shader_code_dp2add_sat[] = {
7409 0xffff0200, /* ps_2_0 */
7410 0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0 */
7412 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
7413 0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add_sat r0.rgb, r0, r0, r0.a */
7414 0x03000002, 0x80070000, 0x80e40000, 0xa0000000, /* add r0.rgb, r0, c0.r */
7416 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
7417 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
7418 0x0000ffff /* end */
7420 static const float quad[] =
7422 -1.0f, -1.0f, 0.1f,
7423 -1.0f, 1.0f, 0.1f,
7424 1.0f, -1.0f, 0.1f,
7425 1.0f, 1.0f, 0.1f,
7428 window = create_window();
7429 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7430 ok(!!d3d, "Failed to create a D3D object.\n");
7431 if (!(device = create_device(d3d, window, window, TRUE)))
7433 skip("Failed to create a D3D device, skipping tests.\n");
7434 goto done;
7437 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7438 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
7439 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
7441 skip("No ps_2_0 support, skipping tests.\n");
7442 IDirect3DDevice9_Release(device);
7443 goto done;
7446 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
7447 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7449 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
7450 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7452 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
7453 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7455 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7456 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7458 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
7459 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#lx.\n", hr);
7460 hr = IDirect3DDevice9_BeginScene(device);
7461 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
7462 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
7463 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#lx.\n", hr);
7464 hr = IDirect3DDevice9_EndScene(device);
7465 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
7467 color = getPixelColor(device, 360, 240);
7468 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1), "Got unexpected color 0x%08x.\n", color);
7470 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7471 ok(SUCCEEDED(hr), "Failed to present frame, hr %#lx.\n", hr);
7472 IDirect3DPixelShader9_Release(shader_dp2add);
7474 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
7475 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#lx.\n", hr);
7476 hr = IDirect3DDevice9_BeginScene(device);
7477 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
7478 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
7479 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#lx.\n", hr);
7480 hr = IDirect3DDevice9_EndScene(device);
7481 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
7483 color = getPixelColor(device, 360, 240);
7484 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1), "Got unexpected color 0x%08x.\n", color);
7486 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7487 ok(SUCCEEDED(hr), "Failed to present frame, hr %#lx.\n", hr);
7488 IDirect3DPixelShader9_Release(shader_dp2add_sat);
7490 refcount = IDirect3DDevice9_Release(device);
7491 ok(!refcount, "Device has %lu references left.\n", refcount);
7492 done:
7493 IDirect3D9_Release(d3d);
7494 DestroyWindow(window);
7497 static void cnd_test(void)
7499 IDirect3DPixelShader9 *shader_11_coissue_2, *shader_12_coissue_2, *shader_13_coissue_2, *shader_14_coissue_2;
7500 IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
7501 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
7502 IDirect3DDevice9 *device;
7503 unsigned int color;
7504 IDirect3D9 *d3d;
7505 ULONG refcount;
7506 D3DCAPS9 caps;
7507 HWND window;
7508 HRESULT hr;
7510 /* ps 1.x shaders are rather picky with writemasks and source swizzles.
7511 * The dp3 is used to copy r0.r to all components of r1, then copy r1.a to
7512 * r0.a. Essentially it does a mov r0.a, r0.r, which isn't allowed as-is
7513 * in 1.x pixel shaders. */
7514 static const DWORD shader_code_11[] =
7516 0xffff0101, /* ps_1_1 */
7517 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
7518 0x00000040, 0xb00f0000, /* texcoord t0 */
7519 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, ???(t0) */
7520 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
7521 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
7522 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
7523 0x0000ffff /* end */
7525 static const DWORD shader_code_12[] =
7527 0xffff0102, /* ps_1_2 */
7528 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
7529 0x00000040, 0xb00f0000, /* texcoord t0 */
7530 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
7531 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
7532 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
7533 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
7534 0x0000ffff /* end */
7536 static const DWORD shader_code_13[] =
7538 0xffff0103, /* ps_1_3 */
7539 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
7540 0x00000040, 0xb00f0000, /* texcoord t0 */
7541 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
7542 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3, r1, r0, c0 */
7543 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
7544 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
7545 0x0000ffff /* end */
7547 static const DWORD shader_code_14[] =
7549 0xffff0104, /* ps_1_3 */
7550 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
7551 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
7552 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
7553 0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0, c1, c2 */
7554 0x0000ffff /* end */
7557 /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
7558 * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
7559 * set by the compiler, it was added manually after compilation. Note that the COISSUE
7560 * flag on a color(.xyz) operation is only allowed after an alpha operation. DirectX doesn't
7561 * have proper docs, but GL_ATI_fragment_shader explains the pairing of color and alpha ops
7562 * well enough.
7564 * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
7565 * The input from t0 is [0;1]. 0.5 is subtracted, then we have to multiply with 2. Since
7566 * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
7567 * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
7569 static const DWORD shader_code_11_coissue[] =
7571 0xffff0101, /* ps_1_1 */
7572 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
7573 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
7574 0x00000040, 0xb00f0000, /* texcoord t0 */
7575 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
7576 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
7577 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
7578 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
7579 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
7580 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
7581 0x0000ffff /* end */
7583 static const DWORD shader_code_11_coissue_2[] =
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, 0x800f0000, 0x80e40001, /* mov r0, r1 */
7594 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
7595 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
7596 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
7597 0x0000ffff /* end */
7599 static const DWORD shader_code_12_coissue[] =
7601 0xffff0102, /* ps_1_2 */
7602 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
7603 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
7604 0x00000040, 0xb00f0000, /* texcoord t0 */
7605 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
7606 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
7607 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
7608 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
7609 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
7610 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
7611 0x0000ffff /* end */
7613 static const DWORD shader_code_12_coissue_2[] =
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, 0x800f0000, 0x80e40001, /* mov r0, r1 */
7624 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
7625 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
7626 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
7627 0x0000ffff /* end */
7629 static const DWORD shader_code_13_coissue[] =
7631 0xffff0103, /* ps_1_3 */
7632 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
7633 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
7634 0x00000040, 0xb00f0000, /* texcoord t0 */
7635 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
7636 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
7637 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
7638 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
7639 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
7640 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
7641 0x0000ffff /* end */
7643 static const DWORD shader_code_13_coissue_2[] =
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, 0x800f0000, 0x80e40001, /* mov r0, r1 */
7654 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
7655 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
7656 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
7657 0x0000ffff /* end */
7659 /* ps_1_4 does not have a different cnd behavior, just pass the [0;1]
7660 * texcrd result to cnd, it will compare against 0.5. */
7661 static const DWORD shader_code_14_coissue[] =
7663 0xffff0104, /* ps_1_4 */
7664 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
7665 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0.xyz, t0 */
7666 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
7667 0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0, c1, c2 */
7668 0x0000ffff /* end */
7670 static const DWORD shader_code_14_coissue_2[] =
7672 0xffff0104, /* ps_1_4 */
7673 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
7674 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0.xyz, t0 */
7675 0x00000001, 0x80080000, 0x80000000, /* mov r0.a, r0.x */
7676 0x00000001, 0x80070001, 0xa0ff0000, /* mov r1.xyz, c0.a */
7677 0x40000050, 0x80080001, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r1.a, r0.a, c1, c2 */
7678 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
7679 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
7680 0x0000ffff /* end */
7682 static const float quad1[] =
7684 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 1.0f,
7685 -1.0f, 0.0f, 0.1f, 0.0f, 1.0f, 0.0f,
7686 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f,
7687 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f,
7689 static const float quad2[] =
7691 0.0f, -1.0f, 0.1f, 0.0f, 0.0f, 1.0f,
7692 0.0f, 0.0f, 0.1f, 0.0f, 1.0f, 0.0f,
7693 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f,
7694 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f,
7696 static const float quad3[] =
7698 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, 1.0f,
7699 0.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f,
7700 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f,
7701 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f,
7703 static const float quad4[] =
7705 -1.0f, 0.0f, 0.1f, 0.0f, 0.0f, 1.0f,
7706 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f,
7707 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f,
7708 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f,
7710 static const float test_data_c1[4] = {0.0f, 0.0f, 0.0f, 0.0f};
7711 static const float test_data_c2[4] = {1.0f, 1.0f, 1.0f, 1.0f};
7712 static const float test_data_c1_coi[4] = {0.0f, 1.0f, 0.0f, 0.0f};
7713 static const float test_data_c2_coi[4] = {1.0f, 0.0f, 1.0f, 1.0f};
7715 window = create_window();
7716 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7717 ok(!!d3d, "Failed to create a D3D object.\n");
7718 if (!(device = create_device(d3d, window, window, TRUE)))
7720 skip("Failed to create a D3D device, skipping tests.\n");
7721 goto done;
7724 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7725 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
7726 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 4))
7728 skip("No ps_1_4 support, skipping tests.\n");
7729 IDirect3DDevice9_Release(device);
7730 goto done;
7733 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
7734 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7736 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
7737 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7738 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
7739 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7740 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
7741 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7742 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
7743 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7744 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
7745 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7746 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
7747 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7748 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
7749 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7750 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
7751 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7752 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue_2, &shader_11_coissue_2);
7753 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7754 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue_2, &shader_12_coissue_2);
7755 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7756 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue_2, &shader_13_coissue_2);
7757 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7758 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue_2, &shader_14_coissue_2);
7759 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7761 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
7762 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7763 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
7764 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7765 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7766 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7768 hr = IDirect3DDevice9_BeginScene(device);
7769 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
7771 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
7772 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
7773 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
7774 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
7776 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
7777 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
7778 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
7779 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
7781 hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
7782 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
7783 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
7784 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7786 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
7787 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
7788 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
7789 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
7791 hr = IDirect3DDevice9_EndScene(device);
7792 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
7794 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7795 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7797 /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
7798 color = getPixelColor(device, 158, 118);
7799 ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
7800 color = getPixelColor(device, 162, 118);
7801 ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
7802 color = getPixelColor(device, 158, 122);
7803 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
7804 color = getPixelColor(device, 162, 122);
7805 ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
7807 /* 1.1 shader. All 3 components get set, based on the .w comparison */
7808 color = getPixelColor(device, 158, 358);
7809 ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
7810 color = getPixelColor(device, 162, 358);
7811 ok(color_match(color, 0x00000000, 1), "pixel 162, 358 has color 0x%08x, expected 0x00000000.\n", color);
7812 color = getPixelColor(device, 158, 362);
7813 ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
7814 color = getPixelColor(device, 162, 362);
7815 ok(color_match(color, 0x00000000, 1), "pixel 162, 362 has color 0x%08x, expected 0x00000000.\n", color);
7817 /* 1.2 shader */
7818 color = getPixelColor(device, 478, 358);
7819 ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
7820 color = getPixelColor(device, 482, 358);
7821 ok(color_match(color, 0x00000000, 1), "pixel 482, 358 has color 0x%08x, expected 0x00000000.\n", color);
7822 color = getPixelColor(device, 478, 362);
7823 ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
7824 color = getPixelColor(device, 482, 362);
7825 ok(color_match(color, 0x00000000, 1), "pixel 482, 362 has color 0x%08x, expected 0x00000000.\n", color);
7827 /* 1.3 shader */
7828 color = getPixelColor(device, 478, 118);
7829 ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
7830 color = getPixelColor(device, 482, 118);
7831 ok(color_match(color, 0x00000000, 1), "pixel 482, 118 has color 0x%08x, expected 0x00000000.\n", color);
7832 color = getPixelColor(device, 478, 122);
7833 ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
7834 color = getPixelColor(device, 482, 122);
7835 ok(color_match(color, 0x00000000, 1), "pixel 482, 122 has color 0x%08x, expected 0x00000000.\n", color);
7837 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7838 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7840 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
7841 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7842 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
7843 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7844 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
7845 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7847 hr = IDirect3DDevice9_BeginScene(device);
7848 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
7850 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
7851 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
7852 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
7853 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
7855 hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
7856 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
7857 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
7858 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
7860 hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
7861 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
7862 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
7863 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
7865 hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
7866 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
7867 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
7868 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
7870 hr = IDirect3DDevice9_EndScene(device);
7871 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
7873 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7874 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7876 /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
7877 * that we swapped the values in c1 and c2 to make the other tests return some color
7879 color = getPixelColor(device, 158, 118);
7880 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
7881 color = getPixelColor(device, 162, 118);
7882 ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
7883 color = getPixelColor(device, 158, 122);
7884 ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
7885 color = getPixelColor(device, 162, 122);
7886 ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
7888 /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected
7889 * (The Win7 nvidia driver always selects c2)
7891 color = getPixelColor(device, 158, 358);
7892 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
7893 "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
7894 color = getPixelColor(device, 162, 358);
7895 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
7896 "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
7897 color = getPixelColor(device, 158, 362);
7898 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
7899 "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
7900 color = getPixelColor(device, 162, 362);
7901 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
7902 "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
7904 /* 1.2 shader */
7905 color = getPixelColor(device, 478, 358);
7906 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
7907 "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
7908 color = getPixelColor(device, 482, 358);
7909 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
7910 "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
7911 color = getPixelColor(device, 478, 362);
7912 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
7913 "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
7914 color = getPixelColor(device, 482, 362);
7915 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
7916 "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
7918 /* 1.3 shader */
7919 color = getPixelColor(device, 478, 118);
7920 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
7921 "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
7922 color = getPixelColor(device, 482, 118);
7923 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
7924 "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
7925 color = getPixelColor(device, 478, 122);
7926 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
7927 "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
7928 color = getPixelColor(device, 482, 122);
7929 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
7930 "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
7932 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7933 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7935 /* Retest with the coissue flag on the alpha instruction instead. This
7936 * works "as expected". The Windows 8 testbot (WARP) seems to handle this
7937 * the same as coissue on .rgb. */
7938 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
7939 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7941 hr = IDirect3DDevice9_BeginScene(device);
7942 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
7944 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue_2);
7945 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
7946 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
7947 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
7949 hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue_2);
7950 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
7951 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
7952 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
7954 hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue_2);
7955 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
7956 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
7957 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
7959 hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue_2);
7960 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
7961 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
7962 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
7964 hr = IDirect3DDevice9_EndScene(device);
7965 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
7967 /* 1.4 shader */
7968 color = getPixelColor(device, 158, 118);
7969 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
7970 color = getPixelColor(device, 162, 118);
7971 ok(color == 0x00000000, "pixel 162, 118 has color %08x, expected 0x00000000\n", color);
7972 color = getPixelColor(device, 158, 122);
7973 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
7974 color = getPixelColor(device, 162, 122);
7975 ok(color == 0x00000000, "pixel 162, 122 has color %08x, expected 0x00000000\n", color);
7977 /* 1.1 shader */
7978 color = getPixelColor(device, 238, 358);
7979 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
7980 "pixel 238, 358 has color %08x, expected 0x00ffffff\n", color);
7981 color = getPixelColor(device, 242, 358);
7982 ok(color_match(color, 0x00000000, 1),
7983 "pixel 242, 358 has color %08x, expected 0x00000000\n", color);
7984 color = getPixelColor(device, 238, 362);
7985 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
7986 "pixel 238, 362 has color %08x, expected 0x00ffffff\n", color);
7987 color = getPixelColor(device, 242, 362);
7988 ok(color_match(color, 0x00000000, 1),
7989 "pixel 242, 362 has color %08x, expected 0x00000000\n", color);
7991 /* 1.2 shader */
7992 color = getPixelColor(device, 558, 358);
7993 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
7994 "pixel 558, 358 has color %08x, expected 0x00ffffff\n", color);
7995 color = getPixelColor(device, 562, 358);
7996 ok(color_match(color, 0x00000000, 1),
7997 "pixel 562, 358 has color %08x, expected 0x00000000\n", color);
7998 color = getPixelColor(device, 558, 362);
7999 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
8000 "pixel 558, 362 has color %08x, expected 0x00ffffff\n", color);
8001 color = getPixelColor(device, 562, 362);
8002 ok(color_match(color, 0x00000000, 1),
8003 "pixel 562, 362 has color %08x, expected 0x00000000\n", color);
8005 /* 1.3 shader */
8006 color = getPixelColor(device, 558, 118);
8007 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
8008 "pixel 558, 118 has color %08x, expected 0x00ffffff\n", color);
8009 color = getPixelColor(device, 562, 118);
8010 ok(color_match(color, 0x00000000, 1),
8011 "pixel 562, 118 has color %08x, expected 0x00000000\n", color);
8012 color = getPixelColor(device, 558, 122);
8013 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
8014 "pixel 558, 122 has color %08x, expected 0x00ffffff\n", color);
8015 color = getPixelColor(device, 562, 122);
8016 ok(color_match(color, 0x00000000, 1),
8017 "pixel 562, 122 has color %08x, expected 0x00000000\n", color);
8019 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8020 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8022 IDirect3DPixelShader9_Release(shader_14_coissue_2);
8023 IDirect3DPixelShader9_Release(shader_13_coissue_2);
8024 IDirect3DPixelShader9_Release(shader_12_coissue_2);
8025 IDirect3DPixelShader9_Release(shader_11_coissue_2);
8026 IDirect3DPixelShader9_Release(shader_14_coissue);
8027 IDirect3DPixelShader9_Release(shader_13_coissue);
8028 IDirect3DPixelShader9_Release(shader_12_coissue);
8029 IDirect3DPixelShader9_Release(shader_11_coissue);
8030 IDirect3DPixelShader9_Release(shader_14);
8031 IDirect3DPixelShader9_Release(shader_13);
8032 IDirect3DPixelShader9_Release(shader_12);
8033 IDirect3DPixelShader9_Release(shader_11);
8034 refcount = IDirect3DDevice9_Release(device);
8035 ok(!refcount, "Device has %lu references left.\n", refcount);
8036 done:
8037 IDirect3D9_Release(d3d);
8038 DestroyWindow(window);
8041 static void nested_loop_test(void)
8043 IDirect3DVertexShader9 *vshader;
8044 IDirect3DPixelShader9 *shader;
8045 IDirect3DDevice9 *device;
8046 unsigned int color;
8047 IDirect3D9 *d3d;
8048 ULONG refcount;
8049 D3DCAPS9 caps;
8050 HWND window;
8051 HRESULT hr;
8053 static const DWORD shader_code[] =
8055 0xffff0300, /* ps_3_0 */
8056 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
8057 0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
8058 0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0 */
8059 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
8060 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
8061 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
8062 0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001, /* add r0, r0, c1 */
8063 0x0000001d, /* endloop */
8064 0x0000001d, /* endloop */
8065 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
8066 0x0000ffff /* end */
8068 static const DWORD vshader_code[] =
8070 0xfffe0300, /* vs_3_0 */
8071 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8072 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
8073 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
8074 0x0000ffff /* end */
8076 static const float quad[] =
8078 -1.0f, -1.0f, 0.1f,
8079 -1.0f, 1.0f, 0.1f,
8080 1.0f, -1.0f, 0.1f,
8081 1.0f, 1.0f, 0.1f,
8084 window = create_window();
8085 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8086 ok(!!d3d, "Failed to create a D3D object.\n");
8087 if (!(device = create_device(d3d, window, window, TRUE)))
8089 skip("Failed to create a D3D device, skipping tests.\n");
8090 goto done;
8093 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8094 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
8095 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
8097 skip("No shader model 3 support, skipping tests.\n");
8098 IDirect3DDevice9_Release(device);
8099 goto done;
8102 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8103 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8104 hr = IDirect3DDevice9_SetPixelShader(device, shader);
8105 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8106 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
8107 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8108 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
8109 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8110 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8111 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8112 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x0000ff00, 1.0f, 0);
8113 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8115 hr = IDirect3DDevice9_BeginScene(device);
8116 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
8117 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
8118 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
8119 hr = IDirect3DDevice9_EndScene(device);
8120 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
8122 color = getPixelColor(device, 360, 240);
8123 ok(color_match(color, 0x00800000, 1),
8124 "Nested loop test returned color 0x%08x, expected 0x00800000.\n", color);
8126 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8127 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8129 IDirect3DPixelShader9_Release(shader);
8130 IDirect3DVertexShader9_Release(vshader);
8131 refcount = IDirect3DDevice9_Release(device);
8132 ok(!refcount, "Device has %lu references left.\n", refcount);
8133 done:
8134 IDirect3D9_Release(d3d);
8135 DestroyWindow(window);
8138 static void pretransformed_varying_test(void)
8140 /* dcl_position: fails to compile */
8141 static const DWORD blendweight_code[] =
8143 0xffff0300, /* ps_3_0 */
8144 0x0200001f, 0x80000001, 0x900f0000, /* dcl_blendweight, v0 */
8145 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
8146 0x0000ffff /* end */
8148 static const DWORD blendindices_code[] =
8150 0xffff0300, /* ps_3_0 */
8151 0x0200001f, 0x80000002, 0x900f0000, /* dcl_blendindices, v0 */
8152 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
8153 0x0000ffff /* end */
8155 static const DWORD normal_code[] =
8157 0xffff0300, /* ps_3_0 */
8158 0x0200001f, 0x80000003, 0x900f0000, /* dcl_normal, v0 */
8159 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
8160 0x0000ffff /* end */
8162 /* psize: fails? */
8163 static const DWORD texcoord0_code[] =
8165 0xffff0300, /* ps_3_0 */
8166 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0, v0 */
8167 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
8168 0x0000ffff /* end */
8170 static const DWORD tangent_code[] =
8172 0xffff0300, /* ps_3_0 */
8173 0x0200001f, 0x80000006, 0x900f0000, /* dcl_tangent, v0 */
8174 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
8175 0x0000ffff /* end */
8177 static const DWORD binormal_code[] =
8179 0xffff0300, /* ps_3_0 */
8180 0x0200001f, 0x80000007, 0x900f0000, /* dcl_binormal, v0 */
8181 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
8182 0x0000ffff /* end */
8184 /* tessfactor: fails */
8185 /* positiont: fails */
8186 static const DWORD color_code[] =
8188 0xffff0300, /* ps_3_0 */
8189 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0, v0 */
8190 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
8191 0x0000ffff /* end */
8193 static const DWORD fog_code[] =
8195 0xffff0300, /* ps_3_0 */
8196 0x0200001f, 0x8000000b, 0x900f0000, /* dcl_fog, v0 */
8197 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
8198 0x0000ffff /* end */
8200 static const DWORD depth_code[] =
8202 0xffff0300, /* ps_3_0 */
8203 0x0200001f, 0x8000000c, 0x900f0000, /* dcl_depth, v0 */
8204 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
8205 0x0000ffff /* end */
8207 static const DWORD specular_code[] =
8209 0xffff0300, /* ps_3_0 */
8210 0x0200001f, 0x8001000a, 0x900f0000, /* dcl_color1, v0 */
8211 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
8212 0x0000ffff /* end */
8214 /* sample: fails */
8215 static const DWORD texcoord1_code[] =
8217 0xffff0300, /* ps_3_0 */
8218 0x0200001f, 0x80010005, 0x900f0000, /* dcl_texcoord1, v0 */
8219 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
8220 0x0000ffff /* end */
8222 static const DWORD texcoord1_alpha_code[] =
8224 0xffff0300, /* ps_3_0 */
8225 0x0200001f, 0x80010005, 0x900f0000, /* dcl_texcoord1, v0 */
8226 0x02000001, 0x800f0800, 0x90ff0000, /* mov oC0, v0.w */
8227 0x0000ffff /* end */
8230 static const struct
8232 const char *name;
8233 const DWORD *shader_code;
8234 unsigned int color;
8235 BOOL todo;
8236 BOOL broken;
8237 DWORD broken_color;
8239 tests[] =
8241 {"blendweight", blendweight_code, 0x00191919, TRUE },
8242 {"blendindices", blendindices_code, 0x00333333, TRUE },
8243 {"normal", normal_code, 0x004c4c4c, TRUE },
8244 {"texcoord0", texcoord0_code, 0x00808c8c, FALSE},
8245 {"tangent", tangent_code, 0x00999999, TRUE },
8246 {"binormal", binormal_code, 0x00b2b2b2, TRUE },
8247 {"color", color_code, 0x00e6e6e6, FALSE},
8248 {"fog", fog_code, 0x00666666, TRUE },
8249 {"depth", depth_code, 0x00cccccc, TRUE },
8250 {"specular", specular_code, 0x004488ff, FALSE},
8251 {"texcoord1", texcoord1_code, 0x00000000, FALSE},
8252 /* texcoord .w is 1.0 on r500 and WARP. See also test_uninitialized_varyings(). */
8253 {"texcoord1 alpha", texcoord1_alpha_code, 0x00000000, FALSE, TRUE, 0x00ffffff},
8255 /* Declare a monster vertex type :-) */
8256 static const D3DVERTEXELEMENT9 decl_elements[] = {
8257 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
8258 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
8259 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
8260 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
8261 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
8262 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
8263 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
8264 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
8265 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
8266 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8267 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
8268 D3DDECL_END()
8271 static const struct
8273 float pos_x, pos_y, pos_z, rhw;
8274 float weight_1, weight_2, weight_3, weight_4;
8275 float index_1, index_2, index_3, index_4;
8276 float normal_1, normal_2, normal_3, normal_4;
8277 float fog_1, fog_2, fog_3, fog_4;
8278 float texcoord_1, texcoord_2, texcoord_3, texcoord_4;
8279 float tangent_1, tangent_2, tangent_3, tangent_4;
8280 float binormal_1, binormal_2, binormal_3, binormal_4;
8281 float depth_1, depth_2, depth_3, depth_4;
8282 D3DCOLOR diffuse;
8283 D3DCOLOR specular;
8285 data[] =
8288 0.0f, 0.0f, 0.1f, 1.0f,
8289 0.1f, 0.1f, 0.1f, 0.1f,
8290 0.2f, 0.2f, 0.2f, 0.2f,
8291 0.3f, 0.3f, 0.3f, 0.3f,
8292 0.4f, 0.4f, 0.4f, 0.4f,
8293 0.5f, 0.55f, 0.55f, 0.55f,
8294 0.6f, 0.6f, 0.6f, 0.7f,
8295 0.7f, 0.7f, 0.7f, 0.6f,
8296 0.8f, 0.8f, 0.8f, 0.8f,
8297 0xe6e6e6e6, /* 0.9 * 256 */
8298 0x224488ff, /* Nothing special */
8301 640.0f, 0.0f, 0.1f, 1.0f,
8302 0.1f, 0.1f, 0.1f, 0.1f,
8303 0.2f, 0.2f, 0.2f, 0.2f,
8304 0.3f, 0.3f, 0.3f, 0.3f,
8305 0.4f, 0.4f, 0.4f, 0.4f,
8306 0.5f, 0.55f, 0.55f, 0.55f,
8307 0.6f, 0.6f, 0.6f, 0.7f,
8308 0.7f, 0.7f, 0.7f, 0.6f,
8309 0.8f, 0.8f, 0.8f, 0.8f,
8310 0xe6e6e6e6, /* 0.9 * 256 */
8311 0x224488ff, /* Nothing special */
8314 0.0f, 480.0f, 0.1f, 1.0f,
8315 0.1f, 0.1f, 0.1f, 0.1f,
8316 0.2f, 0.2f, 0.2f, 0.2f,
8317 0.3f, 0.3f, 0.3f, 0.3f,
8318 0.4f, 0.4f, 0.4f, 0.4f,
8319 0.5f, 0.55f, 0.55f, 0.55f,
8320 0.6f, 0.6f, 0.6f, 0.7f,
8321 0.7f, 0.7f, 0.7f, 0.6f,
8322 0.8f, 0.8f, 0.8f, 0.8f,
8323 0xe6e6e6e6, /* 0.9 * 256 */
8324 0x224488ff, /* Nothing special */
8327 640.0f, 480.0f, 0.1f, 1.0f,
8328 0.1f, 0.1f, 0.1f, 0.1f,
8329 0.2f, 0.2f, 0.2f, 0.2f,
8330 0.3f, 0.3f, 0.3f, 0.3f,
8331 0.4f, 0.4f, 0.4f, 0.4f,
8332 0.5f, 0.55f, 0.55f, 0.55f,
8333 0.6f, 0.6f, 0.6f, 0.7f,
8334 0.7f, 0.7f, 0.7f, 0.6f,
8335 0.8f, 0.8f, 0.8f, 0.8f,
8336 0xe6e6e6e6, /* 0.9 * 256 */
8337 0x224488ff, /* Nothing special */
8340 IDirect3DVertexDeclaration9 *decl;
8341 D3DADAPTER_IDENTIFIER9 identifier;
8342 IDirect3DDevice9 *device;
8343 unsigned int color, i;
8344 IDirect3D9 *d3d;
8345 ULONG refcount;
8346 D3DCAPS9 caps;
8347 HWND window;
8348 HRESULT hr;
8350 window = create_window();
8351 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8352 ok(!!d3d, "Failed to create a D3D object.\n");
8353 if (!(device = create_device(d3d, window, window, TRUE)))
8355 skip("Failed to create a D3D device, skipping tests.\n");
8356 goto done;
8359 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8360 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
8361 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
8363 skip("No shader model 3 support, skipping tests.\n");
8364 IDirect3DDevice9_Release(device);
8365 goto done;
8368 hr = IDirect3D9_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
8369 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#lx.\n", hr);
8370 if (adapter_is_warp(&identifier) && sizeof(UINT) == sizeof(UINT_PTR))
8372 /* Apparently the "monster" vertex declaration used in this test
8373 * overruns some stack buffer (DrawPrimitiveUP crashes with a
8374 * 0xc0000409 exception) on 32-bit WARP since Win 10 1809. */
8375 skip("Test crashes on recent 32-bit WARP.\n");
8376 IDirect3DDevice9_Release(device);
8377 goto done;
8380 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
8381 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8382 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
8383 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8385 for (i = 0; i < ARRAY_SIZE(tests); ++i)
8387 IDirect3DPixelShader9 *shader;
8389 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
8390 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8392 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &shader);
8393 ok(SUCCEEDED(hr), "Failed to create pixel shader for test %s, hr %#lx.\n", tests[i].name, hr);
8395 hr = IDirect3DDevice9_SetPixelShader(device, shader);
8396 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8398 hr = IDirect3DDevice9_BeginScene(device);
8399 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
8400 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(*data));
8401 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
8402 hr = IDirect3DDevice9_EndScene(device);
8403 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
8405 /* This isn't a weekend's job to fix, ignore the problem for now.
8406 * Needs a replacement pipeline. */
8407 color = getPixelColor(device, 360, 240);
8408 if (tests[i].todo)
8409 todo_wine ok(color_match(color, tests[i].color, 1)
8410 || broken(color_match(color, 0x00000000, 1)
8411 && tests[i].shader_code == blendindices_code),
8412 "Test %s returned color 0x%08x, expected 0x%08x (todo).\n",
8413 tests[i].name, color, tests[i].color);
8414 else
8415 ok(color_match(color, tests[i].color, 1)
8416 || broken(color_match(color, tests[i].broken_color, 1) && tests[i].broken),
8417 "Test %s returned color 0x%08x, expected 0x%08x.\n",
8418 tests[i].name, color, tests[i].color);
8420 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8421 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8423 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8424 ok(SUCCEEDED(hr), "Failed to set pixel shader for test %s, hr %#lx.\n", tests[i].name, hr);
8425 IDirect3DPixelShader9_Release(shader);
8428 IDirect3DVertexDeclaration9_Release(decl);
8429 refcount = IDirect3DDevice9_Release(device);
8430 ok(!refcount, "Device has %lu references left.\n", refcount);
8431 done:
8432 IDirect3D9_Release(d3d);
8433 DestroyWindow(window);
8436 static void test_compare_instructions(void)
8438 IDirect3DVertexShader9 *shader_slt_scalar;
8439 IDirect3DVertexShader9 *shader_sge_scalar;
8440 IDirect3DVertexShader9 *shader_slt_vec;
8441 IDirect3DVertexShader9 *shader_sge_vec;
8442 IDirect3DDevice9 *device;
8443 unsigned int color;
8444 IDirect3D9 *d3d;
8445 ULONG refcount;
8446 D3DCAPS9 caps;
8447 HWND window;
8448 HRESULT hr;
8450 static const DWORD shader_sge_vec_code[] =
8452 0xfffe0101, /* vs_1_1 */
8453 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8454 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8455 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
8456 0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001, /* sge oD0, r0, c1 */
8457 0x0000ffff /* end */
8459 static const DWORD shader_slt_vec_code[] =
8461 0xfffe0101, /* vs_1_1 */
8462 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8463 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8464 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
8465 0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001, /* slt oD0, r0, c1 */
8466 0x0000ffff /* end */
8468 static const DWORD shader_sge_scalar_code[] =
8470 0xfffe0101, /* vs_1_1 */
8471 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8472 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8473 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
8474 0x0000000d, 0xd0010000, 0x80000000, 0xa0550001, /* slt oD0.r, r0.r, c1.b */
8475 0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001, /* slt oD0.g, r0.g, c1.r */
8476 0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001, /* slt oD0.b, r0.b, c1.g */
8477 0x0000ffff /* end */
8479 static const DWORD shader_slt_scalar_code[] =
8481 0xfffe0101, /* vs_1_1 */
8482 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8483 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8484 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
8485 0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001, /* slt oD0.r, r0.r, c1.b */
8486 0x0000000c, 0xd0020000, 0x80550000, 0xa0000001, /* slt oD0.g, r0.g, c1.r */
8487 0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001, /* slt oD0.b, r0.b, c1.g */
8488 0x0000ffff /* end */
8490 static const float quad1[] =
8492 -1.0f, -1.0f, 0.1f,
8493 -1.0f, 0.0f, 0.1f,
8494 0.0f, -1.0f, 0.1f,
8495 0.0f, 0.0f, 0.1f,
8497 static const float quad2[] =
8499 0.0f, -1.0f, 0.1f,
8500 0.0f, 0.0f, 0.1f,
8501 1.0f, -1.0f, 0.1f,
8502 1.0f, 0.0f, 0.1f,
8504 static const float quad3[] =
8506 -1.0f, 0.0f, 0.1f,
8507 -1.0f, 1.0f, 0.1f,
8508 0.0f, 0.0f, 0.1f,
8509 0.0f, 1.0f, 0.1f,
8511 static const float quad4[] =
8513 0.0f, 0.0f, 0.1f,
8514 0.0f, 1.0f, 0.1f,
8515 1.0f, 0.0f, 0.1f,
8516 1.0f, 1.0f, 0.1f,
8518 static const float const0[4] = {0.8f, 0.2f, 0.2f, 0.2f};
8519 static const float const1[4] = {0.2f, 0.8f, 0.2f, 0.2f};
8521 window = create_window();
8522 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8523 ok(!!d3d, "Failed to create a D3D object.\n");
8524 if (!(device = create_device(d3d, window, window, TRUE)))
8526 skip("Failed to create a D3D device, skipping tests.\n");
8527 goto done;
8530 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8531 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
8532 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
8534 skip("No vs_1_1 support, skipping tests.\n");
8535 IDirect3DDevice9_Release(device);
8536 goto done;
8539 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
8540 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8542 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
8543 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8544 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
8545 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8546 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
8547 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8548 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
8549 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8550 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
8551 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8552 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
8553 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8554 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8555 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8557 hr = IDirect3DDevice9_BeginScene(device);
8558 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
8560 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
8561 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
8562 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
8563 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
8565 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
8566 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
8567 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
8568 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
8570 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
8571 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
8572 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
8573 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
8575 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
8576 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#lx.\n", hr);
8578 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
8579 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
8580 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
8581 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
8583 hr = IDirect3DDevice9_EndScene(device);
8584 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
8586 color = getPixelColor(device, 160, 360);
8587 ok(color == 0x00ff00ff, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00ff00ff\n", color);
8588 color = getPixelColor(device, 480, 360);
8589 ok(color == 0x0000ff00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000ff00\n", color);
8590 color = getPixelColor(device, 160, 120);
8591 ok(color == 0x00ffffff, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00ffffff\n", color);
8592 color = getPixelColor(device, 480, 160);
8593 ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
8595 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8596 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8598 IDirect3DVertexShader9_Release(shader_sge_vec);
8599 IDirect3DVertexShader9_Release(shader_slt_vec);
8600 IDirect3DVertexShader9_Release(shader_sge_scalar);
8601 IDirect3DVertexShader9_Release(shader_slt_scalar);
8602 refcount = IDirect3DDevice9_Release(device);
8603 ok(!refcount, "Device has %lu references left.\n", refcount);
8604 done:
8605 IDirect3D9_Release(d3d);
8606 DestroyWindow(window);
8609 static void test_vshader_input(void)
8611 IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
8612 IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
8613 IDirect3DVertexDeclaration9 *decl_nocolor;
8614 IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
8615 D3DADAPTER_IDENTIFIER9 identifier;
8616 IDirect3DPixelShader9 *ps;
8617 IDirect3DDevice9 *device;
8618 unsigned int color, i;
8619 IDirect3D9 *d3d;
8620 ULONG refcount;
8621 D3DCAPS9 caps;
8622 HWND window;
8623 HRESULT hr;
8624 BOOL warp;
8626 static const DWORD swapped_shader_code_3[] =
8628 0xfffe0300, /* vs_3_0 */
8629 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
8630 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
8631 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8632 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
8633 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
8634 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
8635 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
8636 0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
8637 0x0000ffff /* end */
8639 static const DWORD swapped_shader_code_1[] =
8641 0xfffe0101, /* vs_1_1 */
8642 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8643 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
8644 0x0000001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
8645 0x00000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
8646 0x00000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
8647 0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
8648 0x0000ffff /* end */
8650 static const DWORD swapped_shader_code_2[] =
8652 0xfffe0200, /* vs_2_0 */
8653 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8654 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
8655 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
8656 0x02000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
8657 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
8658 0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
8659 0x0000ffff /* end */
8661 static const DWORD texcoord_color_shader_code_3[] =
8663 0xfffe0300, /* vs_3_0 */
8664 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
8665 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
8666 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8667 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
8668 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
8669 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
8670 0x0000ffff /* end */
8672 static const DWORD texcoord_color_shader_code_2[] =
8674 0xfffe0200, /* vs_2_0 */
8675 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8676 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
8677 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8678 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
8679 0x0000ffff /* end */
8681 static const DWORD texcoord_color_shader_code_1[] =
8683 0xfffe0101, /* vs_1_1 */
8684 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8685 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
8686 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8687 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
8688 0x0000ffff /* end */
8690 static const DWORD color_color_shader_code_3[] =
8692 0xfffe0300, /* vs_3_0 */
8693 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
8694 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
8695 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8696 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
8697 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
8698 0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001, /* mul o1, c0, v1 */
8699 0x0000ffff /* end */
8701 static const DWORD color_color_shader_code_2[] =
8703 0xfffe0200, /* vs_2_0 */
8704 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8705 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
8706 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8707 0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
8708 0x0000ffff /* end */
8710 static const DWORD color_color_shader_code_1[] =
8712 0xfffe0101, /* vs_1_1 */
8713 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8714 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
8715 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8716 0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
8717 0x0000ffff /* end */
8719 static const DWORD ps3_code[] =
8721 0xffff0300, /* ps_3_0 */
8722 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
8723 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
8724 0x0000ffff /* end */
8726 static const float quad1[] =
8728 -1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
8729 -1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
8730 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
8731 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
8733 static const float quad2[] =
8735 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
8736 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
8737 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
8738 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
8740 static const float quad3[] =
8742 -1.0f, 0.0f, 0.1f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f,
8743 -1.0f, 1.0f, 0.1f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f,
8744 0.0f, 0.0f, 0.1f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
8745 0.0f, 1.0f, 0.1f, -1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
8747 static const float quad4[] =
8749 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
8750 0.0f, 1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
8751 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
8752 1.0f, 1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
8754 static const float quad1_modified[] =
8756 -1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
8757 -1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f,
8758 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
8759 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, -1.0f, -1.0f, -1.0f, 0.0f,
8761 static const float quad2_modified[] =
8763 0.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
8764 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
8765 1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
8766 1.0f, 0.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
8768 static const struct
8770 struct vec3 position;
8771 DWORD diffuse;
8773 quad1_color[] =
8775 {{-1.0f, -1.0f, 0.1f}, 0x00ff8040},
8776 {{-1.0f, 0.0f, 0.1f}, 0x00ff8040},
8777 {{ 0.0f, -1.0f, 0.1f}, 0x00ff8040},
8778 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
8780 quad2_color[] =
8782 {{ 0.0f, -1.0f, 0.1f}, 0x00ff8040},
8783 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
8784 {{ 1.0f, -1.0f, 0.1f}, 0x00ff8040},
8785 {{ 1.0f, 0.0f, 0.1f}, 0x00ff8040},
8787 quad3_color[] =
8789 {{-1.0f, 0.0f, 0.1f}, 0x00ff8040},
8790 {{-1.0f, 1.0f, 0.1f}, 0x00ff8040},
8791 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
8792 {{ 0.0f, 1.0f, 0.1f}, 0x00ff8040},
8794 static const float quad4_color[] =
8796 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f, 0.0f,
8797 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f, 0.0f,
8798 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f, 1.0f,
8799 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f, 1.0f,
8801 static const struct vec3 quad_nocolor[] =
8803 {-1.0f, -1.0f, 0.1f},
8804 {-1.0f, 1.0f, 0.1f},
8805 { 1.0f, -1.0f, 0.1f},
8806 { 1.0f, 1.0f, 0.1f},
8808 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] =
8810 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8811 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
8812 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
8813 D3DDECL_END()
8815 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] =
8817 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8818 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
8819 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
8820 D3DDECL_END()
8822 static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] =
8824 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8825 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
8826 D3DDECL_END()
8828 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] =
8830 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8831 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
8832 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
8833 D3DDECL_END()
8835 static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] =
8837 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8838 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
8839 D3DDECL_END()
8841 static const D3DVERTEXELEMENT9 decl_elements_color_color[] =
8843 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8844 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8845 D3DDECL_END()
8847 static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] =
8849 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8850 {0, 12, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8851 D3DDECL_END()
8853 static const D3DVERTEXELEMENT9 decl_elements_color_float[] =
8855 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8856 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8857 D3DDECL_END()
8859 static const D3DVERTEXELEMENT9 decl_elements_nocolor[] =
8861 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8862 D3DDECL_END()
8864 static const float normalize[4] = {1.0f / 256.0f, 1.0f / 256.0f, 1.0f / 256.0f, 1.0f / 256.0f};
8865 static const float no_normalize[4] = {1.0f, 1.0f, 1.0f, 1.0f};
8867 window = create_window();
8868 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8869 ok(!!d3d, "Failed to create a D3D object.\n");
8870 if (!(device = create_device(d3d, window, window, TRUE)))
8872 skip("Failed to create a D3D device, skipping tests.\n");
8873 goto done;
8876 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8877 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
8878 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
8880 skip("No vs_3_0 support, skipping tests.\n");
8881 IDirect3DDevice9_Release(device);
8882 goto done;
8884 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0))
8886 skip("No ps_3_0 support, skipping tests.\n");
8887 IDirect3DDevice9_Release(device);
8888 goto done;
8891 hr = IDirect3D9_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
8892 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#lx.\n", hr);
8893 warp = adapter_is_warp(&identifier);
8895 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
8896 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8897 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
8898 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8899 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
8900 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8901 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
8902 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8904 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
8905 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8906 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
8907 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8908 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
8909 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8910 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
8911 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8912 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_nocolor, &decl_nocolor);
8913 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8915 hr = IDirect3DDevice9_CreatePixelShader(device, ps3_code, &ps);
8916 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8918 for (i = 1; i <= 3; ++i)
8920 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
8921 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8922 if(i == 3) {
8923 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
8924 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8925 hr = IDirect3DDevice9_SetPixelShader(device, ps);
8926 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8927 } else if(i == 2){
8928 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
8929 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8930 } else if(i == 1) {
8931 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
8932 ok(hr == S_OK, "Got hr %#lx.\n", hr);
8935 hr = IDirect3DDevice9_BeginScene(device);
8936 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
8938 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
8939 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
8941 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
8942 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
8943 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
8944 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
8946 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
8947 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
8948 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
8949 if (i == 3 || i == 2)
8950 ok(SUCCEEDED(hr), "Failed to draw, i %u, hr %#lx.\n", i, hr);
8951 else if (i == 1)
8952 /* Succeeds or fails, depending on SW or HW vertex processing. */
8953 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
8955 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
8956 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
8957 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
8958 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
8960 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
8961 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
8962 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 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 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
8968 hr = IDirect3DDevice9_EndScene(device);
8969 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
8971 if(i == 3 || i == 2) {
8972 color = getPixelColor(device, 160, 360);
8973 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
8974 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00ffff80\n", color);
8976 /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
8977 color = getPixelColor(device, 480, 360);
8978 /* On the Windows 8 testbot (WARP) the draw succeeds, but uses
8979 * mostly random data as input. */
8980 ok(color == 0x00ffff00 || color == 0x00ff0000 || broken(warp),
8981 "Got unexpected color 0x%08x for quad 2 (1crd).\n", color);
8982 color = getPixelColor(device, 160, 120);
8983 /* Same as above, accept both the last used value and 0.0 for the undefined streams */
8984 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
8985 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00ff0080\n", color);
8987 color = getPixelColor(device, 480, 160);
8988 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
8989 } else if(i == 1) {
8990 color = getPixelColor(device, 160, 360);
8991 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
8992 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00ffff80\n", color);
8993 color = getPixelColor(device, 480, 360);
8994 /* Accept the clear color as well in this case, since SW VP
8995 * returns an error. On the Windows 8 testbot (WARP) the draw
8996 * succeeds, but uses mostly random data as input. */
8997 ok(color == 0x00ffff00 || color == 0x00ff0000 || broken(warp),
8998 "Got unexpected color 0x%08x for quad 2 (1crd).\n", color);
8999 color = getPixelColor(device, 160, 120);
9000 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
9001 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00ff0080\n", color);
9002 color = getPixelColor(device, 480, 160);
9003 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
9006 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9007 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9009 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
9010 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9012 /* Now find out if the whole streams are re-read, or just the last
9013 * active value for the vertices is used. */
9014 hr = IDirect3DDevice9_BeginScene(device);
9015 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
9017 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
9018 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
9020 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
9021 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
9022 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
9023 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
9025 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
9026 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
9027 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
9028 if (i == 3 || i == 2)
9029 ok(SUCCEEDED(hr), "Failed to draw, i %u, hr %#lx.\n", i, hr);
9030 else if (i == 1)
9031 /* Succeeds or fails, depending on SW or HW vertex processing. */
9032 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9034 hr = IDirect3DDevice9_EndScene(device);
9035 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
9037 color = getPixelColor(device, 480, 350);
9038 /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
9039 * as well.
9041 * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
9042 * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
9043 * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
9044 * refrast's result.
9046 * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
9048 ok(color == 0x000000ff || color == 0x00808080 || color == 0x00000000 || broken(warp),
9049 "Got unexpected color 0x%08x for quad 2 (different colors).\n", color);
9051 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9052 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9054 IDirect3DDevice9_SetVertexShader(device, NULL);
9055 IDirect3DDevice9_SetPixelShader(device, NULL);
9056 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
9058 IDirect3DVertexShader9_Release(swapped_shader);
9061 for (i = 1; i <= 3; ++i)
9063 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
9064 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9065 if(i == 3) {
9066 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
9067 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9068 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
9069 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9070 hr = IDirect3DDevice9_SetPixelShader(device, ps);
9071 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9072 } else if(i == 2){
9073 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
9074 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9075 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
9076 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9077 } else if(i == 1) {
9078 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
9079 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9080 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
9081 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9084 hr = IDirect3DDevice9_BeginScene(device);
9085 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
9087 hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
9088 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
9089 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
9090 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
9091 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
9092 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
9094 hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
9095 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
9097 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
9098 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#lx.\n", hr);
9099 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
9100 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
9101 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
9102 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
9104 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
9105 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#lx.\n", hr);
9106 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
9107 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
9108 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
9109 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
9111 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
9112 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
9113 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
9114 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
9116 hr = IDirect3DDevice9_EndScene(device);
9117 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
9119 color = getPixelColor(device, 160, 360);
9120 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
9121 "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
9122 color = getPixelColor(device, 480, 360);
9123 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
9124 "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
9125 color = getPixelColor(device, 160, 120);
9126 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
9127 "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
9128 color = getPixelColor(device, 480, 160);
9129 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
9130 "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00ffff00\n", color);
9132 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9133 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9135 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_nocolor);
9136 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
9138 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
9139 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
9141 hr = IDirect3DDevice9_BeginScene(device);
9142 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
9143 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_nocolor, sizeof(quad_nocolor[0]));
9144 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
9145 hr = IDirect3DDevice9_EndScene(device);
9146 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
9148 /* WARP and r500 return a color from a previous draw. In case of WARP it is random, although most of the
9149 * time it is the color of the last draw, which happens to be the one with quad4_color above. AMD's r500
9150 * uses the last D3DCOLOR attribute, which is the one from quad3_color.
9152 * Newer AMD cards and Nvidia return zero. */
9153 color = getPixelColor(device, 160, 360);
9154 ok(color_match(color, 0x00000000, 1) || broken(color_match(color, 0x00ff8040, 1)) || broken(warp),
9155 "Got unexpected color 0x%08x for no color attribute test.\n", color);
9157 IDirect3DDevice9_SetVertexShader(device, NULL);
9158 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
9159 IDirect3DDevice9_SetPixelShader(device, NULL);
9161 IDirect3DVertexShader9_Release(texcoord_color_shader);
9162 IDirect3DVertexShader9_Release(color_color_shader);
9165 IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
9166 IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
9167 IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
9168 IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
9170 IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
9171 IDirect3DVertexDeclaration9_Release(decl_color_color);
9172 IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
9173 IDirect3DVertexDeclaration9_Release(decl_color_float);
9174 IDirect3DVertexDeclaration9_Release(decl_nocolor);
9176 IDirect3DPixelShader9_Release(ps);
9177 refcount = IDirect3DDevice9_Release(device);
9178 ok(!refcount, "Device has %lu references left.\n", refcount);
9179 done:
9180 IDirect3D9_Release(d3d);
9181 DestroyWindow(window);
9184 static void srgbtexture_test(void)
9186 /* The result of sRGB to linear conversion for value 0x7f (~ .5) used on
9187 * texture mip level 0 should be 0x36 (~ 0.21), per this formula:
9188 * linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
9189 * This is true where srgb_color > 0.04045.
9190 * For the value of 0x3f used on mip level 1 the result should be 0x0d (~0.05). */
9191 struct IDirect3DTexture9 *texture;
9192 struct IDirect3DSurface9 *surface;
9193 IDirect3DDevice9 *device;
9194 unsigned int colour, i;
9195 IDirect3D9 *d3d;
9196 ULONG refcount;
9197 HWND window;
9198 DWORD value;
9199 HRESULT hr;
9201 static const float quad[] =
9203 -1.0f, -1.0f, 0.0f, 0.0f, 1.0f,
9204 -1.0f, 1.0f, 0.0f, 0.0f, 0.0f,
9205 1.0f, -1.0f, 0.0f, 1.0f, 1.0f,
9206 1.0f, 1.0f, 0.0f, 1.0f, 0.0f,
9208 static const struct
9210 D3DFORMAT format;
9211 const char *format_name;
9212 DWORD fill_colour1, fill_colour2;
9213 DWORD fill_colour_rb1, fill_colour_rb2;
9214 DWORD conv_colour1, conv_colour2;
9216 tests[] =
9218 {D3DFMT_A8R8G8B8, "A8R8G8B8",
9219 0xff7f7f7f, 0xff3f3f3f, 0x007f7f7f, 0x003f3f3f, 0x00363636, 0x000d0d0d},
9220 {D3DFMT_R5G6B5, "R5G6R5",
9221 0x7bef, 0x39e7, 0x007b7d7b, 0x003a3d3a, 0x00333433, 0x000a0c0a},
9222 {D3DFMT_A1R5G5B5, "A1R5G5R5",
9223 0xbdef, 0x9ce7, 0x007b7b7b, 0x003a3a3a, 0x00333433, 0x000a0a0a},
9224 {D3DFMT_X1R5G5B5, "X1R5G5R5",
9225 0x3def, 0x1ce7, 0x007b7b7b, 0x003a3a3a, 0x00333433, 0x000a0a0a},
9228 window = create_window();
9229 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9230 ok(!!d3d, "Failed to create a D3D object.\n");
9231 if (!(device = create_device(d3d, window, window, TRUE)))
9233 skip("Failed to create a D3D device, skipping tests.\n");
9234 goto done;
9237 for (i = 0; i < ARRAY_SIZE(tests); ++i)
9239 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
9240 D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE, tests[i].format) != D3D_OK)
9242 skip("%s textures with SRGBREAD are not supported.\n", tests[i].format_name);
9243 continue;
9246 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 2, 0, tests[i].format, D3DPOOL_MANAGED, &texture, NULL);
9247 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9248 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
9249 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9250 fill_surface(surface, tests[i].fill_colour1, 0);
9251 IDirect3DSurface9_Release(surface);
9252 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
9253 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9254 fill_surface(surface, tests[i].fill_colour2, 0);
9255 IDirect3DSurface9_Release(surface);
9257 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9258 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9259 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9260 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9262 /* AMD uses the LSB of the D3DSAMP_SRGBTEXTURE value.
9263 * NVIDIA ignores any values other than 0 and 1, leaving the previous
9264 * D3DSAMP_SRGBTEXTURE state.
9265 * Intel, WARP treat the value as boolean. */
9266 hr = IDirect3DDevice9_BeginScene(device);
9267 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9268 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, 0x7e41882a);
9269 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9270 hr = IDirect3DDevice9_GetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, &value);
9271 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9272 ok(value == 0x7e41882a, "Got unexpected value %#lx.\n", value);
9273 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9274 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9275 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
9276 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9277 hr = IDirect3DDevice9_EndScene(device);
9278 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9279 colour = getPixelColor(device, 320, 240);
9280 ok(color_match(colour, tests[i].fill_colour_rb1, 2)
9281 || broken(color_match(colour, tests[i].conv_colour1, 1)),
9282 "Format %s, got unexpected colour 0x%08x.\n", tests[i].format_name, colour);
9283 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9284 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9286 hr = IDirect3DDevice9_BeginScene(device);
9287 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9288 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, 100);
9289 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9290 hr = IDirect3DDevice9_GetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, &value);
9291 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9292 ok(value == 100, "Got unexpected value %#lx.\n", value);
9293 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
9294 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9295 hr = IDirect3DDevice9_EndScene(device);
9296 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9297 colour = getPixelColor(device, 320, 240);
9298 ok(color_match(colour, tests[i].fill_colour_rb1, 2)
9299 || broken(color_match(colour, tests[i].conv_colour1, 1)),
9300 "Format %s, got unexpected colour 0x%08x.\n", tests[i].format_name, colour);
9301 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9302 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9304 hr = IDirect3DDevice9_BeginScene(device);
9305 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9306 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, 2);
9307 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9308 hr = IDirect3DDevice9_GetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, &value);
9309 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9310 ok(value == 2, "Got unexpected value %#lx.\n", value);
9311 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
9312 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9313 hr = IDirect3DDevice9_EndScene(device);
9314 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9315 colour = getPixelColor(device, 320, 240);
9316 ok(color_match(colour, tests[i].fill_colour_rb1, 2)
9317 || broken(color_match(colour, tests[i].conv_colour1, 1)),
9318 "Format %s, got unexpected colour 0x%08x.\n", tests[i].format_name, colour);
9319 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9320 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9322 hr = IDirect3DDevice9_BeginScene(device);
9323 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9324 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, 3);
9325 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9326 hr = IDirect3DDevice9_GetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, &value);
9327 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9328 ok(value == 3, "Got unexpected value %#lx.\n", value);
9329 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
9330 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9331 hr = IDirect3DDevice9_EndScene(device);
9332 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9333 colour = getPixelColor(device, 320, 240);
9334 ok(color_match(colour, tests[i].fill_colour_rb1, 2)
9335 || color_match(colour, tests[i].conv_colour1, 3),
9336 "Format %s, got unexpected colour 0x%08x.\n", tests[i].format_name, colour);
9337 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9338 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9340 hr = IDirect3DDevice9_BeginScene(device);
9341 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9342 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
9343 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9344 hr = IDirect3DDevice9_GetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, &value);
9345 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9346 ok(value == TRUE, "Got unexpected value %#lx.\n", value);
9347 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
9348 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9349 hr = IDirect3DDevice9_EndScene(device);
9350 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9351 colour = getPixelColor(device, 320, 240);
9352 ok(color_match(colour, tests[i].conv_colour1, 3), "Format %s, got unexpected colour 0x%08x.\n",
9353 tests[i].format_name, colour);
9354 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9355 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9357 hr = IDirect3DDevice9_BeginScene(device);
9358 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9359 /* Set the other state to verify that the sampler just inherits old
9360 * D3DSAMP_SRGBTEXTURE but the old sampler is not preserved entirely on
9361 * NVIDIA. */
9362 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, 0x7e41882a);
9363 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9364 hr = IDirect3DDevice9_GetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, &value);
9365 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9366 ok(value == 0x7e41882a, "Got unexpected value %#lx.\n", value);
9367 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
9368 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9369 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
9370 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9371 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
9372 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9373 hr = IDirect3DDevice9_EndScene(device);
9374 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9375 colour = getPixelColor(device, 320, 240);
9376 ok(color_match(colour, tests[i].conv_colour2, 1)
9377 || color_match(colour, tests[i].fill_colour_rb2, 2),
9378 "Format %s, got unexpected colour 0x%08x.\n", tests[i].format_name, colour);
9379 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9380 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9382 hr = IDirect3DDevice9_BeginScene(device);
9383 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9384 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, 0);
9385 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9386 hr = IDirect3DDevice9_GetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, &value);
9387 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9388 ok(value == 0, "Got unexpected value %#lx.\n", value);
9389 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
9390 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9391 hr = IDirect3DDevice9_EndScene(device);
9392 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9393 colour = getPixelColor(device, 320, 240);
9394 ok(color_match(colour, tests[i].fill_colour_rb2, 2),
9395 "Format %s, got unexpected colour 0x%08x.\n", tests[i].format_name, colour);
9396 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9397 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9399 hr = IDirect3DDevice9_BeginScene(device);
9400 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9401 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, 0x7e41882a);
9402 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9403 hr = IDirect3DDevice9_GetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, &value);
9404 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9405 ok(value == 0x7e41882a, "Got unexpected value %#lx.\n", value);
9406 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9407 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9408 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
9409 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9410 hr = IDirect3DDevice9_EndScene(device);
9411 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9412 colour = getPixelColor(device, 320, 240);
9413 ok(color_match(colour, tests[i].fill_colour_rb2, 2)
9414 || broken(color_match(colour, tests[i].conv_colour2, 1)),
9415 "Format %s, got unexpected colour 0x%08x.\n", tests[i].format_name, colour);
9416 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9417 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9418 IDirect3DTexture9_Release(texture);
9420 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, 0);
9421 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9422 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
9423 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
9426 refcount = IDirect3DDevice9_Release(device);
9427 ok(!refcount, "Device has %lu references left.\n", refcount);
9428 done:
9429 IDirect3D9_Release(d3d);
9430 DestroyWindow(window);
9433 static void test_shademode(void)
9435 IDirect3DVertexBuffer9 *vb_strip;
9436 IDirect3DVertexBuffer9 *vb_list;
9437 unsigned int color0, color1, i;
9438 IDirect3DVertexShader9 *vs;
9439 IDirect3DPixelShader9 *ps;
9440 IDirect3DDevice9 *device;
9441 void *data = NULL;
9442 IDirect3D9 *d3d;
9443 ULONG refcount;
9444 D3DCAPS9 caps;
9445 HWND window;
9446 HRESULT hr;
9448 static const DWORD vs1_code[] =
9450 0xfffe0101, /* vs_1_1 */
9451 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
9452 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
9453 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
9454 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
9455 0x0000ffff
9457 static const DWORD vs2_code[] =
9459 0xfffe0200, /* vs_2_0 */
9460 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
9461 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
9462 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
9463 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
9464 0x0000ffff
9466 static const DWORD vs3_code[] =
9468 0xfffe0300, /* vs_3_0 */
9469 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
9470 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
9471 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
9472 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */
9473 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
9474 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
9475 0x0000ffff
9477 static const DWORD ps1_code[] =
9479 0xffff0101, /* ps_1_1 */
9480 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
9481 0x0000ffff
9483 static const DWORD ps2_code[] =
9485 0xffff0200, /* ps_2_0 */
9486 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
9487 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
9488 0x0000ffff
9490 static const DWORD ps3_code[] =
9492 0xffff0300, /* ps_3_0 */
9493 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
9494 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
9495 0x0000ffff
9497 static const struct
9499 struct vec3 position;
9500 DWORD diffuse;
9502 quad_strip[] =
9504 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
9505 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
9506 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
9507 {{ 1.0f, 1.0f, 0.0f}, 0xffffffff},
9509 quad_list[] =
9511 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
9512 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
9513 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
9515 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
9516 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
9517 {{ 1.0f, 1.0f, 0.0f}, 0xffffffff},
9519 static const struct test_shader
9521 DWORD version;
9522 const DWORD *code;
9524 novs = {0, NULL},
9525 vs_1 = {D3DVS_VERSION(1, 1), vs1_code},
9526 vs_2 = {D3DVS_VERSION(2, 0), vs2_code},
9527 vs_3 = {D3DVS_VERSION(3, 0), vs3_code},
9528 nops = {0, NULL},
9529 ps_1 = {D3DPS_VERSION(1, 1), ps1_code},
9530 ps_2 = {D3DPS_VERSION(2, 0), ps2_code},
9531 ps_3 = {D3DPS_VERSION(3, 0), ps3_code};
9532 static const struct
9534 const struct test_shader *vs, *ps;
9535 DWORD primtype;
9536 DWORD shademode;
9537 unsigned int color0, color1;
9538 BOOL todo;
9540 tests[] =
9542 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, FALSE},
9543 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_PHONG, 0x000dca28, 0x000d45c7, FALSE},
9544 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
9545 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_PHONG, 0x000dca28, 0x000d45c7, FALSE},
9546 {&novs, &nops, D3DPT_TRIANGLELIST, D3DSHADE_FLAT, 0x00ff0000, 0x000000ff, FALSE},
9547 {&novs, &nops, D3DPT_TRIANGLELIST, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
9548 {&vs_1, &ps_1, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, FALSE},
9549 {&vs_1, &ps_1, D3DPT_TRIANGLESTRIP, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
9550 {&vs_1, &ps_1, D3DPT_TRIANGLELIST, D3DSHADE_FLAT, 0x00ff0000, 0x000000ff, FALSE},
9551 {&vs_1, &ps_1, D3DPT_TRIANGLELIST, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
9552 {&novs, &ps_1, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, FALSE},
9553 {&vs_1, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, FALSE},
9554 {&vs_2, &ps_2, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, FALSE},
9555 {&vs_2, &ps_2, D3DPT_TRIANGLESTRIP, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
9556 {&vs_3, &ps_3, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, TRUE},
9557 {&vs_3, &ps_3, D3DPT_TRIANGLESTRIP, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
9560 window = create_window();
9561 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9562 ok(!!d3d, "Failed to create a D3D object.\n");
9563 if (!(device = create_device(d3d, window, window, TRUE)))
9565 skip("Failed to create a D3D device, skipping tests.\n");
9566 goto done;
9569 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9570 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9571 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
9572 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#lx.\n", hr);
9574 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9575 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9577 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip), 0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
9578 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9579 hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
9580 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9581 memcpy(data, quad_strip, sizeof(quad_strip));
9582 hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
9583 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9585 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list), 0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
9586 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9587 hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
9588 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9589 memcpy(data, quad_list, sizeof(quad_list));
9590 hr = IDirect3DVertexBuffer9_Unlock(vb_list);
9591 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9593 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9594 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
9596 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
9597 * the color fixups we have to do for FLAT shading will be dependent on that. */
9599 for (i = 0; i < ARRAY_SIZE(tests); ++i)
9601 if (tests[i].vs->version)
9603 if (caps.VertexShaderVersion >= tests[i].vs->version)
9605 hr = IDirect3DDevice9_CreateVertexShader(device, tests[i].vs->code, &vs);
9606 ok(hr == D3D_OK, "Failed to create vertex shader, hr %#lx.\n", hr);
9607 hr = IDirect3DDevice9_SetVertexShader(device, vs);
9608 ok(hr == D3D_OK, "Failed to set vertex shader, hr %#lx.\n", hr);
9610 else
9612 skip("Shader version unsupported, skipping some tests.\n");
9613 continue;
9616 else
9618 vs = NULL;
9620 if (tests[i].ps->version)
9622 if (caps.PixelShaderVersion >= tests[i].ps->version)
9624 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].ps->code, &ps);
9625 ok(hr == D3D_OK, "Failed to create pixel shader, hr %#lx.\n", hr);
9626 hr = IDirect3DDevice9_SetPixelShader(device, ps);
9627 ok(hr == D3D_OK, "Failed to set pixel shader, hr %#lx.\n", hr);
9629 else
9631 skip("Shader version unsupported, skipping some tests.\n");
9632 if (vs)
9634 IDirect3DDevice9_SetVertexShader(device, NULL);
9635 IDirect3DVertexShader9_Release(vs);
9637 continue;
9640 else
9642 ps = NULL;
9645 hr = IDirect3DDevice9_SetStreamSource(device, 0,
9646 tests[i].primtype == D3DPT_TRIANGLESTRIP ? vb_strip : vb_list, 0, sizeof(quad_strip[0]));
9647 ok(hr == D3D_OK, "Failed to set stream source, hr %#lx.\n", hr);
9649 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
9650 ok(hr == D3D_OK, "Failed to clear, hr %#lx.\n", hr);
9652 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, tests[i].shademode);
9653 ok(hr == D3D_OK, "Failed to set shade mode, hr %#lx.\n", hr);
9655 hr = IDirect3DDevice9_BeginScene(device);
9656 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
9657 hr = IDirect3DDevice9_DrawPrimitive(device, tests[i].primtype, 0, 2);
9658 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
9659 hr = IDirect3DDevice9_EndScene(device);
9660 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
9662 color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
9663 color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
9665 /* For D3DSHADE_FLAT it should take the color of the first vertex of
9666 * each triangle. This requires EXT_provoking_vertex or similar
9667 * functionality being available. */
9668 /* PHONG should be the same as GOURAUD, since no hardware implements
9669 * this. */
9670 todo_wine_if (tests[i].todo)
9672 ok(color_match(color0, tests[i].color0, 1), "Test %u shading has color0 %08x, expected %08x.\n",
9673 i, color0, tests[i].color0);
9674 ok(color_match(color1, tests[i].color1, 1), "Test %u shading has color1 %08x, expected %08x.\n",
9675 i, color1, tests[i].color1);
9677 IDirect3DDevice9_SetVertexShader(device, NULL);
9678 IDirect3DDevice9_SetPixelShader(device, NULL);
9680 if (ps)
9681 IDirect3DPixelShader9_Release(ps);
9682 if (vs)
9683 IDirect3DVertexShader9_Release(vs);
9686 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9687 ok(hr == D3D_OK, "Failed to present, hr %#lx.\n", hr);
9689 IDirect3DVertexBuffer9_Release(vb_strip);
9690 IDirect3DVertexBuffer9_Release(vb_list);
9691 refcount = IDirect3DDevice9_Release(device);
9692 ok(!refcount, "Device has %lu references left.\n", refcount);
9693 done:
9694 IDirect3D9_Release(d3d);
9695 DestroyWindow(window);
9698 static void test_blend(void)
9700 IDirect3DSurface9 *backbuffer, *offscreen;
9701 IDirect3DTexture9 *offscreenTexture;
9702 IDirect3DDevice9 *device;
9703 unsigned int color;
9704 IDirect3D9 *d3d;
9705 ULONG refcount;
9706 HWND window;
9707 HRESULT hr;
9709 static const struct
9711 struct vec3 position;
9712 DWORD diffuse;
9714 quad1[] =
9716 {{-1.0f, -1.0f, 0.1f}, 0x4000ff00},
9717 {{-1.0f, 0.0f, 0.1f}, 0x4000ff00},
9718 {{ 1.0f, -1.0f, 0.1f}, 0x4000ff00},
9719 {{ 1.0f, 0.0f, 0.1f}, 0x4000ff00},
9721 quad2[] =
9723 {{-1.0f, 0.0f, 0.1f}, 0xc00000ff},
9724 {{-1.0f, 1.0f, 0.1f}, 0xc00000ff},
9725 {{ 1.0f, 0.0f, 0.1f}, 0xc00000ff},
9726 {{ 1.0f, 1.0f, 0.1f}, 0xc00000ff},
9728 static const float composite_quad[][5] =
9730 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
9731 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
9732 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
9733 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
9736 window = create_window();
9737 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9738 ok(!!d3d, "Failed to create a D3D object.\n");
9739 if (!(device = create_device(d3d, window, window, TRUE)))
9741 skip("Failed to create a D3D device, skipping tests.\n");
9742 goto done;
9745 /* Clear the render target with alpha = 0.5 */
9746 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x80ff0000, 1.0f, 0);
9747 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9749 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
9750 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
9751 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
9753 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9754 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9756 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
9757 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9759 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9760 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9762 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9763 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9764 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9765 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9766 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
9767 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9768 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
9769 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9770 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9771 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9773 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
9774 ok(hr == S_OK, "Got hr %#lx.\n", hr);
9775 hr = IDirect3DDevice9_BeginScene(device);
9776 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
9778 /* Draw two quads, one with src alpha blending, one with dest alpha
9779 * blending. */
9780 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
9781 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
9782 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
9783 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
9784 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
9785 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
9787 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
9788 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
9789 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
9790 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
9791 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
9792 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
9794 /* Switch to the offscreen buffer, and redo the testing. The offscreen
9795 * render target doesn't have an alpha channel. DESTALPHA and INVDESTALPHA
9796 * "don't work" on render targets without alpha channel, they give
9797 * essentially ZERO and ONE blend factors. */
9798 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
9799 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
9800 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x80ff0000, 1.0f, 0);
9801 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
9803 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
9804 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
9805 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
9806 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
9807 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
9808 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
9810 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
9811 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
9812 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
9813 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
9814 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
9815 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
9817 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9818 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
9820 /* Render the offscreen texture onto the frame buffer to be able to
9821 * compare it regularly. Disable alpha blending for the final
9822 * composition. */
9823 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
9824 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
9825 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9826 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
9828 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
9829 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
9830 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
9831 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
9833 hr = IDirect3DDevice9_EndScene(device);
9834 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
9836 color = getPixelColor(device, 160, 360);
9837 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
9838 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
9840 color = getPixelColor(device, 160, 120);
9841 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
9842 "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
9844 color = getPixelColor(device, 480, 360);
9845 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
9846 "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
9848 color = getPixelColor(device, 480, 120);
9849 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
9850 "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
9852 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9854 IDirect3DSurface9_Release(backbuffer);
9855 IDirect3DTexture9_Release(offscreenTexture);
9856 IDirect3DSurface9_Release(offscreen);
9857 refcount = IDirect3DDevice9_Release(device);
9858 ok(!refcount, "Device has %lu references left.\n", refcount);
9859 done:
9860 IDirect3D9_Release(d3d);
9861 DestroyWindow(window);
9864 static void fixed_function_decl_test(void)
9866 IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
9867 IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_nocolor, *dcl_positiont;
9868 IDirect3DVertexBuffer9 *vb, *vb2;
9869 unsigned int color, size, i;
9870 IDirect3DDevice9 *device;
9871 BOOL s_ok, ub_ok, f_ok;
9872 IDirect3D9 *d3d;
9873 ULONG refcount;
9874 D3DCAPS9 caps;
9875 HWND window;
9876 void *data;
9877 HRESULT hr;
9879 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
9880 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9881 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9882 D3DDECL_END()
9884 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
9885 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9886 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9887 D3DDECL_END()
9889 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
9890 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9891 {0, 12, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9892 D3DDECL_END()
9894 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
9895 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9896 {1, 0, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9897 D3DDECL_END()
9899 static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
9900 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9901 {0, 12, D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9902 D3DDECL_END()
9904 static const D3DVERTEXELEMENT9 decl_elements_float[] = {
9905 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9906 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9907 D3DDECL_END()
9909 static const D3DVERTEXELEMENT9 decl_elements_nocolor[] = {
9910 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9911 D3DDECL_END()
9913 static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
9914 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
9915 {0, 16, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9916 D3DDECL_END()
9918 static const struct
9920 struct vec3 position;
9921 DWORD diffuse;
9923 quad1[] = /* D3DCOLOR */
9925 {{-1.0f, -1.0f, 0.1f}, 0x00ffff00},
9926 {{-1.0f, 0.0f, 0.1f}, 0x00ffff00},
9927 {{ 0.0f, -1.0f, 0.1f}, 0x00ffff00},
9928 {{ 0.0f, 0.0f, 0.1f}, 0x00ffff00},
9930 quad2[] = /* UBYTE4N */
9932 {{-1.0f, 0.0f, 0.1f}, 0x00ffff00},
9933 {{-1.0f, 1.0f, 0.1f}, 0x00ffff00},
9934 {{ 0.0f, 0.0f, 0.1f}, 0x00ffff00},
9935 {{ 0.0f, 1.0f, 0.1f}, 0x00ffff00},
9937 static const struct
9939 struct vec3 position;
9940 struct { unsigned short x, y, z, w; } color;
9942 quad3[] = /* USHORT4N */
9944 {{0.0f, -1.0f, 0.1f}, {0x0000, 0x0000, 0xffff, 0xffff}},
9945 {{0.0f, 0.0f, 0.1f}, {0x0000, 0x0000, 0xffff, 0xffff}},
9946 {{1.0f, -1.0f, 0.1f}, {0x0000, 0x0000, 0xffff, 0xffff}},
9947 {{1.0f, 0.0f, 0.1f}, {0x0000, 0x0000, 0xffff, 0xffff}},
9949 static const struct
9951 struct vec3 position;
9952 struct vec4 color;
9954 quad4[] =
9956 {{0.0f, 0.0f, 0.1f}, {1.0f, 0.0f, 0.0f, 0.0f}},
9957 {{0.0f, 1.0f, 0.1f}, {1.0f, 0.0f, 0.0f, 0.0f}},
9958 {{1.0f, 0.0f, 0.1f}, {1.0f, 0.0f, 0.0f, 0.0f}},
9959 {{1.0f, 1.0f, 0.1f}, {1.0f, 0.0f, 0.0f, 0.0f}},
9961 static const DWORD colors[] =
9963 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
9964 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
9965 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
9966 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
9967 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
9968 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
9969 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
9970 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
9971 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
9972 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
9973 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
9974 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
9975 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
9976 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
9977 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
9978 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
9980 static const float quads[] =
9982 -1.0f, -1.0f, 0.1f,
9983 -1.0f, 0.0f, 0.1f,
9984 0.0f, -1.0f, 0.1f,
9985 0.0f, 0.0f, 0.1f,
9987 0.0f, -1.0f, 0.1f,
9988 0.0f, 0.0f, 0.1f,
9989 1.0f, -1.0f, 0.1f,
9990 1.0f, 0.0f, 0.1f,
9992 0.0f, 0.0f, 0.1f,
9993 0.0f, 1.0f, 0.1f,
9994 1.0f, 0.0f, 0.1f,
9995 1.0f, 1.0f, 0.1f,
9997 -1.0f, 0.0f, 0.1f,
9998 -1.0f, 1.0f, 0.1f,
9999 0.0f, 0.0f, 0.1f,
10000 0.0f, 1.0f, 0.1f,
10002 static const struct
10004 struct vec4 position;
10005 DWORD diffuse;
10007 quad_transformed[] =
10009 {{ 90.0f, 110.0f, 0.1f, 2.0f}, 0x00ffff00},
10010 {{570.0f, 110.0f, 0.1f, 2.0f}, 0x00ffff00},
10011 {{ 90.0f, 300.0f, 0.1f, 2.0f}, 0x00ffff00},
10012 {{570.0f, 300.0f, 0.1f, 2.0f}, 0x00ffff00},
10015 window = create_window();
10016 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10017 ok(!!d3d, "Failed to create a D3D object.\n");
10018 if (!(device = create_device(d3d, window, window, TRUE)))
10020 skip("Failed to create a D3D device, skipping tests.\n");
10021 goto done;
10024 memset(&caps, 0, sizeof(caps));
10025 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10026 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10028 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
10029 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10031 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
10032 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10033 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
10034 ok(SUCCEEDED(hr) || hr == E_FAIL, "Got hr %#lx.\n", hr);
10035 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
10036 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10037 if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
10038 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
10039 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10040 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
10041 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10042 } else {
10043 trace("D3DDTCAPS_UBYTE4N not supported\n");
10044 dcl_ubyte_2 = NULL;
10045 dcl_ubyte = NULL;
10047 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
10048 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10049 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_nocolor, &dcl_nocolor);
10050 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10051 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
10052 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10054 size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
10055 hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
10056 0, 0, D3DPOOL_MANAGED, &vb, NULL);
10057 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10059 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10060 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
10062 hr = IDirect3DDevice9_BeginScene(device);
10063 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
10065 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
10066 if (dcl_color)
10068 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
10069 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
10070 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
10071 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
10074 /* Tests with non-standard fixed function types fail on the refrast. The
10075 * ATI driver partially accepts them, the NVIDIA driver accepts them all.
10076 * All those differences even though we're using software vertex
10077 * processing. Doh! */
10078 if (dcl_ubyte)
10080 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
10081 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
10082 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
10083 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
10084 ub_ok = SUCCEEDED(hr);
10087 if (dcl_short)
10089 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
10090 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
10091 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
10092 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
10093 s_ok = SUCCEEDED(hr);
10096 if (dcl_float)
10098 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
10099 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
10100 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
10101 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
10102 f_ok = SUCCEEDED(hr);
10105 hr = IDirect3DDevice9_EndScene(device);
10106 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
10108 if(dcl_short) {
10109 color = getPixelColor(device, 480, 360);
10110 ok(color == 0x000000ff || !s_ok,
10111 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
10113 if(dcl_ubyte) {
10114 color = getPixelColor(device, 160, 120);
10115 ok(color == 0x0000ffff || !ub_ok,
10116 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
10118 if(dcl_color) {
10119 color = getPixelColor(device, 160, 360);
10120 ok(color == 0x00ffff00,
10121 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
10123 if(dcl_float) {
10124 color = getPixelColor(device, 480, 120);
10125 ok(color == 0x00ff0000 || !f_ok,
10126 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
10128 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10130 /* The following test with vertex buffers doesn't serve to find out new
10131 * information from windows. It is a plain regression test because wined3d
10132 * uses different codepaths for attribute conversion with vertex buffers.
10133 * It makes sure that the vertex buffer one works, while the above tests
10134 * whether the immediate mode code works. */
10135 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
10136 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
10137 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
10138 hr = IDirect3DDevice9_BeginScene(device);
10139 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
10141 if (dcl_color)
10143 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
10144 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#lx.\n", hr);
10145 memcpy(data, quad1, sizeof(quad1));
10146 hr = IDirect3DVertexBuffer9_Unlock(vb);
10147 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#lx.\n", hr);
10148 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
10149 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
10150 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
10151 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#lx.\n", hr);
10152 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
10153 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
10156 if (dcl_ubyte)
10158 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
10159 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#lx.\n", hr);
10160 memcpy(data, quad2, sizeof(quad2));
10161 hr = IDirect3DVertexBuffer9_Unlock(vb);
10162 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#lx.\n", hr);
10163 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
10164 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
10165 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
10166 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#lx.\n", hr);
10167 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
10168 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
10169 ub_ok = SUCCEEDED(hr);
10172 if (dcl_short)
10174 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
10175 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#lx.\n", hr);
10176 memcpy(data, quad3, sizeof(quad3));
10177 hr = IDirect3DVertexBuffer9_Unlock(vb);
10178 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#lx.\n", hr);
10179 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
10180 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
10181 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
10182 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#lx.\n", hr);
10183 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
10184 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
10185 s_ok = SUCCEEDED(hr);
10188 if (dcl_float)
10190 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
10191 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#lx.\n", hr);
10192 memcpy(data, quad4, sizeof(quad4));
10193 hr = IDirect3DVertexBuffer9_Unlock(vb);
10194 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#lx.\n", hr);
10195 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
10196 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
10197 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
10198 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#lx.\n", hr);
10199 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
10200 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
10201 f_ok = SUCCEEDED(hr);
10204 hr = IDirect3DDevice9_EndScene(device);
10205 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
10207 if(dcl_short) {
10208 color = getPixelColor(device, 480, 360);
10209 ok(color == 0x000000ff || !s_ok,
10210 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
10212 if(dcl_ubyte) {
10213 color = getPixelColor(device, 160, 120);
10214 ok(color == 0x0000ffff || !ub_ok,
10215 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
10217 if(dcl_color) {
10218 color = getPixelColor(device, 160, 360);
10219 ok(color == 0x00ffff00,
10220 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
10222 if(dcl_float) {
10223 color = getPixelColor(device, 480, 120);
10224 ok(color == 0x00ff0000 || !f_ok,
10225 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
10227 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10229 /* Test with no diffuse color attribute. */
10230 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
10231 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
10233 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_nocolor);
10234 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
10235 hr = IDirect3DDevice9_BeginScene(device);
10236 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
10237 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quads, sizeof(float) * 3);
10238 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
10239 hr = IDirect3DDevice9_EndScene(device);
10240 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
10242 color = getPixelColor(device, 160, 360);
10243 ok(color == 0x00ffffff, "Got unexpected color 0x%08x in the no color attribute test.\n", color);
10245 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10247 /* Test what happens with specular lighting enabled and no specular color attribute. */
10248 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
10249 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
10250 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
10251 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARENABLE, TRUE);
10252 ok(SUCCEEDED(hr), "Failed to enable specular lighting, hr %#lx.\n", hr);
10253 hr = IDirect3DDevice9_BeginScene(device);
10254 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
10256 if (dcl_color)
10258 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
10259 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
10260 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
10261 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
10263 if (dcl_ubyte)
10265 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
10266 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
10267 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
10268 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
10269 ub_ok = SUCCEEDED(hr);
10271 if (dcl_short)
10273 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
10274 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
10275 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
10276 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
10277 s_ok = SUCCEEDED(hr);
10279 if (dcl_float)
10281 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
10282 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
10283 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
10284 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
10285 f_ok = SUCCEEDED(hr);
10288 hr = IDirect3DDevice9_EndScene(device);
10289 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
10290 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARENABLE, FALSE);
10291 ok(SUCCEEDED(hr), "Failed to disable specular lighting, hr %#lx.\n", hr);
10293 if (dcl_short)
10295 color = getPixelColor(device, 480, 360);
10296 ok(color == 0x000000ff || !s_ok,
10297 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff.\n", color);
10299 if (dcl_ubyte)
10301 color = getPixelColor(device, 160, 120);
10302 ok(color == 0x0000ffff || !ub_ok,
10303 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff.\n", color);
10305 if (dcl_color)
10307 color = getPixelColor(device, 160, 360);
10308 ok(color == 0x00ffff00,
10309 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00.\n", color);
10311 if (dcl_float)
10313 color = getPixelColor(device, 480, 120);
10314 ok(color == 0x00ff0000 || !f_ok,
10315 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000.\n", color);
10317 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10319 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
10320 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10321 memcpy(data, quad_transformed, sizeof(quad_transformed));
10322 hr = IDirect3DVertexBuffer9_Unlock(vb);
10323 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10325 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
10326 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10328 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
10329 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10331 hr = IDirect3DDevice9_BeginScene(device);
10332 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
10333 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
10334 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#lx.\n", hr);
10335 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
10336 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
10337 hr = IDirect3DDevice9_EndScene(device);
10338 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
10340 color = getPixelColor(device, 88, 108);
10341 ok(color == 0x000000ff,
10342 "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
10343 color = getPixelColor(device, 92, 108);
10344 ok(color == 0x000000ff,
10345 "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
10346 color = getPixelColor(device, 88, 112);
10347 ok(color == 0x000000ff,
10348 "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
10349 color = getPixelColor(device, 92, 112);
10350 ok(color == 0x00ffff00,
10351 "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
10353 color = getPixelColor(device, 568, 108);
10354 ok(color == 0x000000ff,
10355 "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
10356 color = getPixelColor(device, 572, 108);
10357 ok(color == 0x000000ff,
10358 "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
10359 color = getPixelColor(device, 568, 112);
10360 ok(color == 0x00ffff00,
10361 "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
10362 color = getPixelColor(device, 572, 112);
10363 ok(color == 0x000000ff,
10364 "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
10366 color = getPixelColor(device, 88, 298);
10367 ok(color == 0x000000ff,
10368 "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
10369 color = getPixelColor(device, 92, 298);
10370 ok(color == 0x00ffff00,
10371 "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
10372 color = getPixelColor(device, 88, 302);
10373 ok(color == 0x000000ff,
10374 "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
10375 color = getPixelColor(device, 92, 302);
10376 ok(color == 0x000000ff,
10377 "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
10379 color = getPixelColor(device, 568, 298);
10380 ok(color == 0x00ffff00,
10381 "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
10382 color = getPixelColor(device, 572, 298);
10383 ok(color == 0x000000ff,
10384 "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
10385 color = getPixelColor(device, 568, 302);
10386 ok(color == 0x000000ff,
10387 "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
10388 color = getPixelColor(device, 572, 302);
10389 ok(color == 0x000000ff,
10390 "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
10392 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10394 /* This test is pointless without those two declarations: */
10395 if((!dcl_color_2) || (!dcl_ubyte_2)) {
10396 skip("color-ubyte switching test declarations aren't supported\n");
10397 goto out;
10400 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
10401 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10402 memcpy(data, quads, sizeof(quads));
10403 hr = IDirect3DVertexBuffer9_Unlock(vb);
10404 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10405 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
10406 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
10407 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10408 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
10409 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10410 memcpy(data, colors, sizeof(colors));
10411 hr = IDirect3DVertexBuffer9_Unlock(vb2);
10412 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10414 for(i = 0; i < 2; i++) {
10415 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
10416 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10418 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
10419 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10420 if(i == 0) {
10421 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
10422 } else {
10423 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
10425 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10427 hr = IDirect3DDevice9_BeginScene(device);
10428 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
10430 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
10431 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
10432 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
10433 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
10434 ub_ok = SUCCEEDED(hr);
10436 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
10437 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
10438 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
10439 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
10441 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
10442 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
10443 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
10444 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
10445 ub_ok = (SUCCEEDED(hr) && ub_ok);
10447 hr = IDirect3DDevice9_EndScene(device);
10448 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
10450 if(i == 0) {
10451 color = getPixelColor(device, 480, 360);
10452 ok(color == 0x00ff0000,
10453 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
10454 color = getPixelColor(device, 160, 120);
10455 ok(color == 0x00ffffff,
10456 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
10457 color = getPixelColor(device, 160, 360);
10458 ok(color == 0x000000ff || !ub_ok,
10459 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
10460 color = getPixelColor(device, 480, 120);
10461 ok(color == 0x000000ff || !ub_ok,
10462 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
10463 } else {
10464 color = getPixelColor(device, 480, 360);
10465 ok(color == 0x000000ff,
10466 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
10467 color = getPixelColor(device, 160, 120);
10468 ok(color == 0x00ffffff,
10469 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
10470 color = getPixelColor(device, 160, 360);
10471 ok(color == 0x00ff0000 || !ub_ok,
10472 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
10473 color = getPixelColor(device, 480, 120);
10474 ok(color == 0x00ff0000 || !ub_ok,
10475 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
10477 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10480 IDirect3DVertexBuffer9_Release(vb2);
10481 out:
10482 IDirect3DVertexBuffer9_Release(vb);
10483 if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
10484 if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
10485 if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
10486 if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
10487 if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
10488 if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
10489 IDirect3DVertexDeclaration9_Release(dcl_nocolor);
10490 IDirect3DVertexDeclaration9_Release(dcl_positiont);
10491 refcount = IDirect3DDevice9_Release(device);
10492 ok(!refcount, "Device has %lu references left.\n", refcount);
10493 done:
10494 IDirect3D9_Release(d3d);
10495 DestroyWindow(window);
10498 static void test_vshader_float16(void)
10500 IDirect3DVertexDeclaration9 *vdecl = NULL;
10501 IDirect3DVertexBuffer9 *buffer = NULL;
10502 IDirect3DVertexShader9 *shader;
10503 IDirect3DDevice9 *device;
10504 unsigned int color;
10505 IDirect3D9 *d3d;
10506 ULONG refcount;
10507 D3DCAPS9 caps;
10508 HWND window;
10509 void *data;
10510 HRESULT hr;
10512 static const D3DVERTEXELEMENT9 decl_elements[] =
10514 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
10515 {0, 12, D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
10516 D3DDECL_END()
10518 static const DWORD shader_code[] =
10520 0xfffe0101, /* vs_1_1 */
10521 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10522 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
10523 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
10524 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
10525 0x0000ffff,
10527 static const struct vertex_float16color
10529 float x, y, z;
10530 DWORD c1, c2;
10532 quad[] =
10534 { -1.0, -1.0, 0.1, 0x3c000000, 0x00000000 }, /* green */
10535 { -1.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
10536 { 0.0, -1.0, 0.1, 0x3c000000, 0x00000000 },
10537 { 0.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
10539 { 0.0, -1.0, 0.1, 0x00003c00, 0x00000000 }, /* red */
10540 { 0.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
10541 { 1.0, -1.0, 0.1, 0x00003c00, 0x00000000 },
10542 { 1.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
10544 { 0.0, 0.0, 0.1, 0x00000000, 0x00003c00 }, /* blue */
10545 { 0.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
10546 { 1.0, 0.0, 0.1, 0x00000000, 0x00003c00 },
10547 { 1.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
10549 { -1.0, 0.0, 0.1, 0x00000000, 0x3c000000 }, /* alpha */
10550 { -1.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
10551 { 0.0, 0.0, 0.1, 0x00000000, 0x3c000000 },
10552 { 0.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
10555 window = create_window();
10556 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10557 ok(!!d3d, "Failed to create a D3D object.\n");
10558 if (!(device = create_device(d3d, window, window, TRUE)))
10560 skip("Failed to create a D3D device, skipping tests.\n");
10561 goto done;
10564 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10565 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
10566 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
10568 skip("No vs_3_0 support, skipping tests.\n");
10569 IDirect3DDevice9_Release(device);
10570 goto done;
10573 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff102030, 1.0f, 0);
10574 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10576 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
10577 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10578 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
10579 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10580 hr = IDirect3DDevice9_SetVertexShader(device, shader);
10581 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10583 hr = IDirect3DDevice9_BeginScene(device);
10584 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
10585 hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
10586 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
10587 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 0, sizeof(quad[0]));
10588 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
10589 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 4, sizeof(quad[0]));
10590 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
10591 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 8, sizeof(quad[0]));
10592 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
10593 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
10594 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
10595 hr = IDirect3DDevice9_EndScene(device);
10596 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
10598 color = getPixelColor(device, 480, 360);
10599 ok(color == 0x00ff0000,
10600 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
10601 color = getPixelColor(device, 160, 120);
10602 ok(color == 0x00000000,
10603 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
10604 color = getPixelColor(device, 160, 360);
10605 ok(color == 0x0000ff00,
10606 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
10607 color = getPixelColor(device, 480, 120);
10608 ok(color == 0x000000ff,
10609 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
10610 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10612 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
10613 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10615 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
10616 D3DPOOL_MANAGED, &buffer, NULL);
10617 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10618 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
10619 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10620 memcpy(data, quad, sizeof(quad));
10621 hr = IDirect3DVertexBuffer9_Unlock(buffer);
10622 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10623 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
10624 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10626 hr = IDirect3DDevice9_BeginScene(device);
10627 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
10628 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
10629 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
10630 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
10631 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
10632 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
10633 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
10634 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
10635 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
10636 hr = IDirect3DDevice9_EndScene(device);
10637 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
10639 color = getPixelColor(device, 480, 360);
10640 ok(color == 0x00ff0000,
10641 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
10642 color = getPixelColor(device, 160, 120);
10643 ok(color == 0x00000000,
10644 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
10645 color = getPixelColor(device, 160, 360);
10646 ok(color == 0x0000ff00,
10647 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
10648 color = getPixelColor(device, 480, 120);
10649 ok(color == 0x000000ff,
10650 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
10651 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10653 IDirect3DVertexDeclaration9_Release(vdecl);
10654 IDirect3DVertexShader9_Release(shader);
10655 IDirect3DVertexBuffer9_Release(buffer);
10656 refcount = IDirect3DDevice9_Release(device);
10657 ok(!refcount, "Device has %lu references left.\n", refcount);
10658 done:
10659 IDirect3D9_Release(d3d);
10660 DestroyWindow(window);
10663 static void conditional_np2_repeat_test(void)
10665 IDirect3DTexture9 *texture;
10666 IDirect3DDevice9 *device;
10667 unsigned int color, x, y;
10668 D3DLOCKED_RECT rect;
10669 IDirect3D9 *d3d;
10670 ULONG refcount;
10671 D3DCAPS9 caps;
10672 HWND window;
10673 HRESULT hr;
10674 DWORD *dst;
10676 static const float quad[] =
10678 -1.0f, -1.0f, 0.1f, -0.2f, -0.2f,
10679 -1.0f, 1.0f, 0.1f, -0.2f, 1.2f,
10680 1.0f, -1.0f, 0.1f, 1.2f, -0.2f,
10681 1.0f, 1.0f, 0.1f, 1.2f, 1.2f,
10684 window = create_window();
10685 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10686 ok(!!d3d, "Failed to create a D3D object.\n");
10687 if (!(device = create_device(d3d, window, window, TRUE)))
10689 skip("Failed to create a D3D device, skipping tests.\n");
10690 goto done;
10693 memset(&caps, 0, sizeof(caps));
10694 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10695 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10696 if (caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL)
10698 /* NP2 conditional requires the POW2 flag. Check that while we're at it */
10699 ok(caps.TextureCaps & D3DPTEXTURECAPS_POW2,
10700 "Card has conditional NP2 support without power of two restriction set\n");
10702 else if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
10704 skip("No conditional NP2 support, skipping conditional NP2 tests\n");
10705 IDirect3DDevice9_Release(device);
10706 goto done;
10708 else
10710 skip("Card has unconditional NP2 support, skipping conditional NP2 tests\n");
10711 IDirect3DDevice9_Release(device);
10712 goto done;
10715 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
10716 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
10718 hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
10719 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
10721 memset(&rect, 0, sizeof(rect));
10722 hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
10723 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
10724 for(y = 0; y < 10; y++) {
10725 for(x = 0; x < 10; x++) {
10726 dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
10727 if(x == 0 || x == 9 || y == 0 || y == 9) {
10728 *dst = 0x00ff0000;
10729 } else {
10730 *dst = 0x000000ff;
10734 hr = IDirect3DTexture9_UnlockRect(texture, 0);
10735 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
10737 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
10738 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
10739 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10740 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
10741 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
10742 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
10743 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
10744 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
10745 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
10746 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
10748 hr = IDirect3DDevice9_BeginScene(device);
10749 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
10750 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
10751 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
10752 hr = IDirect3DDevice9_EndScene(device);
10753 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
10755 color = getPixelColor(device, 1, 1);
10756 ok(color == 0x00ff0000, "NP2: Pixel 1, 1 has color %08x, expected 0x00ff0000\n", color);
10757 color = getPixelColor(device, 639, 479);
10758 ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
10760 color = getPixelColor(device, 135, 101);
10761 ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
10762 color = getPixelColor(device, 140, 101);
10763 ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
10764 color = getPixelColor(device, 135, 105);
10765 ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
10766 color = getPixelColor(device, 140, 105);
10767 ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
10769 color = getPixelColor(device, 135, 376);
10770 ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
10771 color = getPixelColor(device, 140, 376);
10772 ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
10773 color = getPixelColor(device, 135, 379);
10774 ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
10775 color = getPixelColor(device, 140, 379);
10776 ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
10778 color = getPixelColor(device, 500, 101);
10779 ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
10780 color = getPixelColor(device, 504, 101);
10781 ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
10782 color = getPixelColor(device, 500, 105);
10783 ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
10784 color = getPixelColor(device, 504, 105);
10785 ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
10787 color = getPixelColor(device, 500, 376);
10788 ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
10789 color = getPixelColor(device, 504, 376);
10790 ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
10791 color = getPixelColor(device, 500, 380);
10792 ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
10793 color = getPixelColor(device, 504, 380);
10794 ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
10796 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10798 IDirect3DTexture9_Release(texture);
10799 refcount = IDirect3DDevice9_Release(device);
10800 ok(!refcount, "Device has %lu references left.\n", refcount);
10801 done:
10802 IDirect3D9_Release(d3d);
10803 DestroyWindow(window);
10806 static void vface_register_test(void)
10808 IDirect3DSurface9 *surface, *backbuffer;
10809 IDirect3DVertexShader9 *vshader;
10810 IDirect3DPixelShader9 *shader;
10811 IDirect3DTexture9 *texture;
10812 IDirect3DDevice9 *device;
10813 unsigned int color;
10814 IDirect3D9 *d3d;
10815 ULONG refcount;
10816 D3DCAPS9 caps;
10817 HWND window;
10818 HRESULT hr;
10820 static const DWORD shader_code[] =
10822 0xffff0300, /* ps_3_0 */
10823 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
10824 0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
10825 0x0200001f, 0x80000000, 0x900f1001, /* dcl vFace */
10826 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
10827 0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001, /* cmp r0, vFace, c0, r1 */
10828 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
10829 0x0000ffff /* END */
10831 static const DWORD vshader_code[] =
10833 0xfffe0300, /* vs_3_0 */
10834 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10835 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
10836 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
10837 0x0000ffff /* end */
10839 static const float quad[] =
10841 -1.0f, -1.0f, 0.1f,
10842 1.0f, -1.0f, 0.1f,
10843 -1.0f, 0.0f, 0.1f,
10845 1.0f, -1.0f, 0.1f,
10846 1.0f, 0.0f, 0.1f,
10847 -1.0f, 0.0f, 0.1f,
10849 -1.0f, 0.0f, 0.1f,
10850 -1.0f, 1.0f, 0.1f,
10851 1.0f, 0.0f, 0.1f,
10853 1.0f, 0.0f, 0.1f,
10854 -1.0f, 1.0f, 0.1f,
10855 1.0f, 1.0f, 0.1f,
10857 static const float blit[] =
10859 0.0f, -1.0f, 0.1f, 0.0f, 0.0f,
10860 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
10861 0.0f, 1.0f, 0.1f, 0.0f, 1.0f,
10862 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
10865 window = create_window();
10866 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10867 ok(!!d3d, "Failed to create a D3D object.\n");
10868 if (!(device = create_device(d3d, window, window, TRUE)))
10870 skip("Failed to create a D3D device, skipping tests.\n");
10871 goto done;
10874 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10875 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
10876 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
10878 skip("No shader model 3 support, skipping tests.\n");
10879 IDirect3DDevice9_Release(device);
10880 goto done;
10883 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
10884 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10885 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
10886 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10887 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
10888 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10889 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
10890 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10891 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
10892 ok(SUCCEEDED(hr), "Failed to set cull mode, hr %#lx.\n", hr);
10893 hr = IDirect3DDevice9_SetPixelShader(device, shader);
10894 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10895 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
10896 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10897 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10898 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10899 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
10900 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10902 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
10903 ok(hr == S_OK, "Got hr %#lx.\n", hr);
10905 hr = IDirect3DDevice9_BeginScene(device);
10906 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
10908 /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
10909 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
10910 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
10911 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
10912 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
10913 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
10914 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
10915 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10916 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
10917 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
10918 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
10920 /* Blit the texture onto the back buffer to make it visible */
10921 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10922 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
10923 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
10924 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
10925 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
10926 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
10927 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10928 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#lx.\n", hr);
10929 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10930 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#lx.\n", hr);
10931 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
10932 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
10933 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
10934 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
10936 hr = IDirect3DDevice9_EndScene(device);
10937 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
10939 color = getPixelColor(device, 160, 360);
10940 ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
10941 color = getPixelColor(device, 160, 120);
10942 ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
10943 color = getPixelColor(device, 480, 360);
10944 ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
10945 color = getPixelColor(device, 480, 120);
10946 ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
10947 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10948 ok(SUCCEEDED(hr), "Present failed, hr %#lx.\n", hr);
10950 IDirect3DPixelShader9_Release(shader);
10951 IDirect3DVertexShader9_Release(vshader);
10952 IDirect3DSurface9_Release(surface);
10953 IDirect3DSurface9_Release(backbuffer);
10954 IDirect3DTexture9_Release(texture);
10955 refcount = IDirect3DDevice9_Release(device);
10956 ok(!refcount, "Device has %lu references left.\n", refcount);
10957 done:
10958 IDirect3D9_Release(d3d);
10959 DestroyWindow(window);
10962 static void fixed_function_bumpmap_test(void)
10964 IDirect3DVertexDeclaration9 *vertex_declaration;
10965 IDirect3DTexture9 *texture, *tex1, *tex2;
10966 D3DLOCKED_RECT locked_rect;
10967 IDirect3DDevice9 *device;
10968 unsigned int color, i;
10969 BOOL L6V5U5_supported;
10970 float scale, offset;
10971 IDirect3D9 *d3d;
10972 ULONG refcount;
10973 D3DCAPS9 caps;
10974 HWND window;
10975 HRESULT hr;
10977 static const float quad[][7] =
10979 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
10980 {-1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
10981 { 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
10982 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
10984 static const D3DVERTEXELEMENT9 decl_elements[] =
10986 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
10987 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
10988 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
10989 D3DDECL_END()
10991 /* use asymmetric matrix to test loading */
10992 static const float bumpenvmat[4] = {0.0f, 0.5f, -0.5f, 0.0f};
10994 window = create_window();
10995 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10996 ok(!!d3d, "Failed to create a D3D object.\n");
10997 if (!(device = create_device(d3d, window, window, TRUE)))
10999 skip("Failed to create a D3D device, skipping tests.\n");
11000 goto done;
11003 memset(&caps, 0, sizeof(caps));
11004 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11005 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11006 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP))
11008 skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
11009 IDirect3DDevice9_Release(device);
11010 goto done;
11013 /* This check is disabled, some Windows drivers do not handle
11014 * D3DUSAGE_QUERY_LEGACYBUMPMAP properly. They report that it is not
11015 * supported, but after that bump mapping works properly. So just test if
11016 * the format is generally supported, and check the BUMPENVMAP flag. */
11017 L6V5U5_supported = SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
11018 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_L6V5U5));
11019 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
11020 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_V8U8)))
11022 skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
11023 IDirect3DDevice9_Release(device);
11024 return;
11027 /* Generate the textures */
11028 generate_bumpmap_textures(device);
11030 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
11031 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11032 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
11033 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11034 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
11035 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11036 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
11037 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11039 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
11040 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11041 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
11042 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11043 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
11044 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11046 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
11047 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11048 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
11049 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11050 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
11051 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11053 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
11054 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11056 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
11057 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11059 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff00ff, 1.0f, 0);
11060 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11062 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
11063 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11064 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
11065 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11067 hr = IDirect3DDevice9_BeginScene(device);
11068 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11070 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
11071 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11073 hr = IDirect3DDevice9_EndScene(device);
11074 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11076 color = getPixelColor(device, 240, 60);
11077 ok(color_match(color, 0x005ea000, 4), "Got unexpected color 0x%08x.\n", color);
11078 color = getPixelColor(device, 400, 60);
11079 ok(color_match(color, 0x009ea000, 4), "Got unexpected color 0x%08x.\n", color);
11080 color = getPixelColor(device, 80, 180);
11081 ok(color_match(color, 0x005ea000, 4), "Got unexpected color 0x%08x.\n", color);
11082 color = getPixelColor(device, 560, 180);
11083 ok(color_match(color, 0x009ea000, 4), "Got unexpected color 0x%08x.\n", color);
11084 color = getPixelColor(device, 80, 300);
11085 ok(color_match(color, 0x005e6000, 4), "Got unexpected color 0x%08x.\n", color);
11086 color = getPixelColor(device, 560, 300);
11087 ok(color_match(color, 0x009e6000, 4), "Got unexpected color 0x%08x.\n", color);
11088 color = getPixelColor(device, 240, 420);
11089 ok(color_match(color, 0x005e6000, 4), "Got unexpected color 0x%08x.\n", color);
11090 color = getPixelColor(device, 400, 420);
11091 ok(color_match(color, 0x009e6000, 4), "Got unexpected color 0x%08x.\n", color);
11092 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11093 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11095 for(i = 0; i < 2; i++) {
11096 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
11097 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11098 IDirect3DTexture9_Release(texture); /* For the GetTexture */
11099 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
11100 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11101 IDirect3DTexture9_Release(texture); /* To destroy it */
11104 if (!L6V5U5_supported || !(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE))
11106 skip("L6V5U5 / D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping tests.\n");
11107 IDirect3DVertexDeclaration9_Release(vertex_declaration);
11108 IDirect3DDevice9_Release(device);
11109 goto done;
11112 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
11113 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11114 /* This test only tests the luminance part. The bumpmapping part was already tested above and
11115 * would only make this test more complicated
11117 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
11118 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11119 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
11120 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11122 memset(&locked_rect, 0, sizeof(locked_rect));
11123 hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
11124 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11125 *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
11126 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
11127 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11129 memset(&locked_rect, 0, sizeof(locked_rect));
11130 hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
11131 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11132 *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
11133 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
11134 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11136 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
11137 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11138 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
11139 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11141 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
11142 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11143 scale = 2.0;
11144 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
11145 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11146 offset = 0.1;
11147 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
11148 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11150 hr = IDirect3DDevice9_BeginScene(device);
11151 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
11152 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
11153 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
11154 hr = IDirect3DDevice9_EndScene(device);
11155 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
11157 color = getPixelColor(device, 320, 240);
11158 /* red: 1.0 * (0.25 * 2.0 + 0.1) = 1.0 * 0.6 = 0.6 = 0x99
11159 * green: 0.5 * (0.25 * 2.0 + 0.1) = 0.5 * 0.6 = 0.3 = 0x4c
11160 * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
11162 ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
11163 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11164 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11166 /* Check a result scale factor > 1.0 */
11167 scale = 10;
11168 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
11169 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11170 offset = 10;
11171 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
11172 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11174 hr = IDirect3DDevice9_BeginScene(device);
11175 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
11176 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
11177 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
11178 hr = IDirect3DDevice9_EndScene(device);
11179 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
11181 color = getPixelColor(device, 320, 240);
11182 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
11183 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11184 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11186 /* Check clamping in the scale factor calculation */
11187 scale = 1000;
11188 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
11189 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11190 offset = -1;
11191 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
11192 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11194 hr = IDirect3DDevice9_BeginScene(device);
11195 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
11196 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
11197 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
11198 hr = IDirect3DDevice9_EndScene(device);
11199 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
11201 color = getPixelColor(device, 320, 240);
11202 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
11203 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11204 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11206 IDirect3DTexture9_Release(tex1);
11207 IDirect3DTexture9_Release(tex2);
11208 IDirect3DVertexDeclaration9_Release(vertex_declaration);
11209 refcount = IDirect3DDevice9_Release(device);
11210 ok(!refcount, "Device has %lu references left.\n", refcount);
11211 done:
11212 IDirect3D9_Release(d3d);
11213 DestroyWindow(window);
11216 static void stencil_cull_test(void)
11218 IDirect3DDevice9 *device;
11219 IDirect3D9 *d3d;
11220 ULONG refcount;
11221 D3DCAPS9 caps;
11222 HWND window;
11223 HRESULT hr;
11224 static const struct
11226 struct vec3 position;
11228 quad1[] =
11230 {{-1.0f, -1.0f, 0.1f}},
11231 {{ 0.0f, -1.0f, 0.1f}},
11232 {{-1.0f, 0.0f, 0.1f}},
11233 {{ 0.0f, 0.0f, 0.1f}},
11235 quad2[] =
11237 {{ 0.0f, -1.0f, 0.1f}},
11238 {{ 1.0f, -1.0f, 0.1f}},
11239 {{ 0.0f, 0.0f, 0.1f}},
11240 {{ 1.0f, 0.0f, 0.1f}},
11242 quad3[] =
11244 {{ 0.0f, 0.0f, 0.1f}},
11245 {{ 1.0f, 0.0f, 0.1f}},
11246 {{ 0.0f, 1.0f, 0.1f}},
11247 {{ 1.0f, 1.0f, 0.1f}},
11249 quad4[] =
11251 {{-1.0f, 0.0f, 0.1f}},
11252 {{ 0.0f, 0.0f, 0.1f}},
11253 {{-1.0f, 1.0f, 0.1f}},
11254 {{ 0.0f, 1.0f, 0.1f}},
11256 struct
11258 struct vec3 position;
11259 DWORD diffuse;
11261 painter[] =
11263 {{-1.0f, -1.0f, 0.0f}, 0x00000000},
11264 {{ 1.0f, -1.0f, 0.0f}, 0x00000000},
11265 {{-1.0f, 1.0f, 0.0f}, 0x00000000},
11266 {{ 1.0f, 1.0f, 0.0f}, 0x00000000},
11268 static const WORD indices_cw[] = {0, 1, 3};
11269 static const WORD indices_ccw[] = {0, 2, 3};
11270 unsigned int color, i;
11272 window = create_window();
11273 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11274 ok(!!d3d, "Failed to create a D3D object.\n");
11275 if (!(device = create_device(d3d, window, window, TRUE)))
11277 skip("Cannot create a device with a D24S8 stencil buffer.\n");
11278 DestroyWindow(window);
11279 IDirect3D9_Release(d3d);
11280 return;
11282 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11283 ok(SUCCEEDED(hr), "Failed to get caps, hr %#lx.\n", hr);
11284 if (!(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED))
11286 skip("No two sided stencil support\n");
11287 goto cleanup;
11290 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
11291 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11292 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
11293 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11295 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
11296 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11297 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11298 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11299 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
11300 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11301 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
11302 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11303 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
11304 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11305 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
11306 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11308 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
11309 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11310 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
11311 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11312 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
11313 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11315 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
11316 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11317 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
11318 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11320 /* First pass: Fill the stencil buffer with some values... */
11321 hr = IDirect3DDevice9_BeginScene(device);
11322 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11324 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
11325 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11326 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST,
11327 0, 4, 1, indices_cw, D3DFMT_INDEX16, quad1, sizeof(*quad1));
11328 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11329 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST,
11330 0, 4, 1, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(*quad1));
11331 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11333 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
11334 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11335 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
11336 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11337 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST,
11338 0, 4, 1, indices_cw, D3DFMT_INDEX16, quad2, sizeof(*quad2));
11339 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11340 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST,
11341 0, 4, 1, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(*quad2));
11342 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11344 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
11345 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11346 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST,
11347 0, 4, 1, indices_cw, D3DFMT_INDEX16, quad3, sizeof(*quad3));
11348 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11349 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST,
11350 0, 4, 1, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(*quad3));
11351 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11353 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
11354 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11355 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST,
11356 0, 4, 1, indices_cw, D3DFMT_INDEX16, quad4, sizeof(*quad4));
11357 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11358 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST,
11359 0, 4, 1, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(*quad4));
11360 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11362 hr = IDirect3DDevice9_EndScene(device);
11363 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11365 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
11366 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11367 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
11368 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11369 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
11370 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11371 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
11372 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11373 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
11374 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11375 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
11376 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11378 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILMASK, 0x000000ff);
11379 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11381 /* 2nd pass: Make the stencil values visible */
11382 hr = IDirect3DDevice9_BeginScene(device);
11383 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11384 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11385 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11386 for (i = 0; i < 16; ++i)
11388 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x0000ff00 | i);
11389 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
11391 painter[0].diffuse = (i * 16); /* Creates shades of blue */
11392 painter[1].diffuse = (i * 16);
11393 painter[2].diffuse = (i * 16);
11394 painter[3].diffuse = (i * 16);
11395 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
11396 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11398 hr = IDirect3DDevice9_EndScene(device);
11399 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11401 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
11402 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11404 color = getPixelColor(device, 160, 420);
11405 ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
11406 color = getPixelColor(device, 160, 300);
11407 ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
11409 color = getPixelColor(device, 480, 420);
11410 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
11411 color = getPixelColor(device, 480, 300);
11412 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
11414 color = getPixelColor(device, 160, 180);
11415 ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
11416 color = getPixelColor(device, 160, 60);
11417 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
11419 color = getPixelColor(device, 480, 180);
11420 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
11421 color = getPixelColor(device, 480, 60);
11422 ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
11424 /* Test for reference truncation. */
11425 /* 1st pass: set stencil. */
11426 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0f, 0);
11427 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11428 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_REPLACE);
11429 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11430 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_REPLACE);
11431 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11432 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
11433 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11434 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x1cc);
11435 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11436 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILMASK, 0);
11437 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11438 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_ALWAYS);
11439 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11440 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
11441 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11442 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
11443 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11445 hr = IDirect3DDevice9_BeginScene(device);
11446 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11447 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
11448 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11449 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST,
11450 0, 4, 1, indices_cw, D3DFMT_INDEX16, quad1, sizeof(*quad1));
11451 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11452 hr = IDirect3DDevice9_EndScene(device);
11453 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11455 /* 2nd pass: draw image. */
11456 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
11457 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11459 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0xdb);
11460 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11461 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILMASK, 0x0f);
11462 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11463 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_LESS);
11464 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11466 hr = IDirect3DDevice9_BeginScene(device);
11467 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11468 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11469 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11470 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
11471 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11472 hr = IDirect3DDevice9_EndScene(device);
11473 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11475 color = getPixelColor(device, 280, 360);
11476 ok(color == 0x000000f0, "Got unexpected colour 0x%08x.\n", color);
11478 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11479 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11481 cleanup:
11482 refcount = IDirect3DDevice9_Release(device);
11483 ok(!refcount, "Device has %lu references left.\n", refcount);
11484 IDirect3D9_Release(d3d);
11485 DestroyWindow(window);
11488 static void test_fragment_coords(void)
11490 IDirect3DSurface9 *surface = NULL, *backbuffer;
11491 IDirect3DPixelShader9 *shader, *shader_frac;
11492 IDirect3DVertexShader9 *vshader;
11493 IDirect3DDevice9 *device;
11494 unsigned int color;
11495 D3DLOCKED_RECT lr;
11496 IDirect3D9 *d3d;
11497 ULONG refcount;
11498 D3DCAPS9 caps;
11499 HWND window;
11500 HRESULT hr;
11501 DWORD *pos;
11503 static const DWORD shader_code[] =
11505 0xffff0300, /* ps_3_0 */
11506 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
11507 0x03000002, 0x80030000, 0x90541000, 0xa1fe0000, /* sub r0.xy, vPos.xy, c0.zw */
11508 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
11509 0x02000001, 0x80080002, 0xa0550000, /* mov r2.a, c0.y */
11510 0x02000001, 0x80010002, 0xa0550000, /* mov r2.r, c0.y */
11511 0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001, /* cmp r2.g, r0.x, r1.x, r1.y */
11512 0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001, /* cmp r2.b, r0.y, r1.x, r1.y */
11513 0x02000001, 0x800f0800, 0x80e40002, /* mov oC0, r2 */
11514 0x0000ffff /* end */
11516 static const DWORD shader_frac_code[] =
11518 0xffff0300, /* ps_3_0 */
11519 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
11520 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
11521 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
11522 0x02000013, 0x80030000, 0x90541000, /* frc r0.xy, vPos.xy */
11523 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
11524 0x0000ffff /* end */
11526 static const DWORD vshader_code[] =
11528 0xfffe0300, /* vs_3_0 */
11529 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
11530 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
11531 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
11532 0x0000ffff /* end */
11534 static const float quad[] =
11536 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
11537 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
11538 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
11539 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
11541 float constant[4] = {1.0, 0.0, 320, 240};
11543 window = create_window();
11544 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11545 ok(!!d3d, "Failed to create a D3D object.\n");
11546 if (!(device = create_device(d3d, window, window, TRUE)))
11548 skip("Failed to create a D3D device, skipping tests.\n");
11549 goto done;
11552 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11553 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
11554 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
11556 skip("No shader model 3 support, skipping tests.\n");
11557 IDirect3DDevice9_Release(device);
11558 goto done;
11561 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
11562 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11563 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
11564 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11565 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
11566 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11567 hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
11568 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11569 hr = IDirect3DDevice9_SetPixelShader(device, shader);
11570 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11571 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
11572 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11573 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
11574 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11575 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
11576 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11578 hr = IDirect3DDevice9_BeginScene(device);
11579 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
11580 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
11581 ok(SUCCEEDED(hr), "Failed to set pixel shader constant, hr %#lx.\n", hr);
11582 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
11583 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
11584 hr = IDirect3DDevice9_EndScene(device);
11585 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
11587 /* This has to be pixel exact */
11588 color = getPixelColor(device, 319, 239);
11589 ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
11590 color = getPixelColor(device, 320, 239);
11591 ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
11592 color = getPixelColor(device, 319, 240);
11593 ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
11594 color = getPixelColor(device, 320, 240);
11595 ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
11596 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11598 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
11599 &surface, NULL);
11600 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11601 hr = IDirect3DDevice9_BeginScene(device);
11602 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
11603 constant[2] = 16; constant[3] = 16;
11604 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
11605 ok(SUCCEEDED(hr), "Failed to set pixel shader constant, hr %#lx.\n", hr);
11606 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
11607 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
11608 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
11609 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
11610 hr = IDirect3DDevice9_EndScene(device);
11611 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
11613 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
11614 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11616 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
11617 color = *pos & 0x00ffffff;
11618 ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
11619 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
11620 color = *pos & 0x00ffffff;
11621 ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
11622 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
11623 color = *pos & 0x00ffffff;
11624 ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
11625 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
11626 color = *pos & 0x00ffffff;
11627 ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
11629 hr = IDirect3DSurface9_UnlockRect(surface);
11630 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11632 /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
11633 * have full control over the multisampling setting inside this test
11635 hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
11636 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11637 hr = IDirect3DDevice9_BeginScene(device);
11638 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
11639 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
11640 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
11641 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
11642 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
11643 hr = IDirect3DDevice9_EndScene(device);
11644 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
11646 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11647 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11649 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
11650 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11652 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
11653 color = *pos & 0x00ffffff;
11654 ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
11656 hr = IDirect3DSurface9_UnlockRect(surface);
11657 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11659 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11660 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11661 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
11662 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11663 IDirect3DPixelShader9_Release(shader);
11664 IDirect3DPixelShader9_Release(shader_frac);
11665 IDirect3DVertexShader9_Release(vshader);
11666 if(surface) IDirect3DSurface9_Release(surface);
11667 IDirect3DSurface9_Release(backbuffer);
11668 refcount = IDirect3DDevice9_Release(device);
11669 ok(!refcount, "Device has %lu references left.\n", refcount);
11670 done:
11671 IDirect3D9_Release(d3d);
11672 DestroyWindow(window);
11675 static BOOL point_match(IDirect3DDevice9 *device, UINT x, UINT y, UINT r)
11677 D3DCOLOR color;
11679 color = D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
11680 if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
11681 if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
11682 if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
11683 if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
11685 ++r;
11686 color = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff);
11687 if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
11688 if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
11689 if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
11690 if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
11692 return TRUE;
11695 static void test_pointsize(void)
11697 static const float a = 1.0f, b = 1.0f, c = 1.0f;
11698 float ptsize, ptsizemax_orig, ptsizemin_orig;
11699 IDirect3DSurface9 *rt, *backbuffer;
11700 IDirect3DTexture9 *tex1, *tex2;
11701 IDirect3DDevice9 *device;
11702 IDirect3DVertexShader9 *vs;
11703 IDirect3DPixelShader9 *ps;
11704 unsigned int color, i, j;
11705 D3DLOCKED_RECT lr;
11706 IDirect3D9 *d3d;
11707 ULONG refcount;
11708 D3DCAPS9 caps;
11709 HWND window;
11710 HRESULT hr;
11712 static const RECT rect = {0, 0, 128, 128};
11713 static const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000, 0x00000000, 0x00000000};
11714 static const DWORD tex2_data[4] = {0x00000000, 0x0000ff00, 0x00000000, 0x0000ff00};
11715 static const float vertices[] =
11717 64.0f, 64.0f, 0.1f,
11718 128.0f, 64.0f, 0.1f,
11719 192.0f, 64.0f, 0.1f,
11720 256.0f, 64.0f, 0.1f,
11721 320.0f, 64.0f, 0.1f,
11722 384.0f, 64.0f, 0.1f,
11723 448.0f, 64.0f, 0.1f,
11724 512.0f, 64.0f, 0.1f,
11726 static const struct
11728 float x, y, z;
11729 float point_size;
11731 vertex_pointsize = {64.0f, 64.0f, 0.1f, 48.0f},
11732 vertex_pointsize_scaled = {64.0f, 64.0f, 0.1f, 24.0f},
11733 vertex_pointsize_zero = {64.0f, 64.0f, 0.1f, 0.0f};
11734 /* Writing a texture coordinate from the shader is technically unnecessary, but is required
11735 * to make Windows AMD r500 drivers work. Without it, texture coordinates in the pixel
11736 * shaders are 0. */
11737 static const DWORD vshader_code[] =
11739 0xfffe0101, /* vs_1_1 */
11740 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
11741 0x00000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
11742 0x00000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
11743 0x00000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
11744 0x00000004, 0xc00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad oPos, v0.w, c3, r0 */
11745 0x00000001, 0xe00f0000, 0x90e40000, /* mov oT0, v0 */
11746 0x00000001, 0xe00f0001, 0x90e40000, /* mov oT1, v0 */
11747 0x0000ffff
11749 static const DWORD vshader_psize_code[] =
11751 0xfffe0101, /* vs_1_1 */
11752 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
11753 0x0000001f, 0x80000004, 0x900f0001, /* dcl_psize v1 */
11754 0x00000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
11755 0x00000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
11756 0x00000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
11757 0x00000004, 0xc00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad oPos, v0.w, c3, r0 */
11758 0x00000001, 0xc00f0002, 0x90000001, /* mov oPts, v1.x */
11759 0x00000001, 0xe00f0000, 0x90e40000, /* mov oT0, v0 */
11760 0x00000001, 0xe00f0001, 0x90e40000, /* mov oT1, v0 */
11761 0x0000ffff
11763 static const DWORD pshader_code[] =
11765 0xffff0101, /* ps_1_1 */
11766 0x00000042, 0xb00f0000, /* tex t0 */
11767 0x00000042, 0xb00f0001, /* tex t1 */
11768 0x00000002, 0x800f0000, 0xb0e40000, 0xb0e40001, /* add r0, t0, t1 */
11769 0x0000ffff
11771 static const DWORD pshader2_code[] =
11773 0xffff0200, /* ps_2_0 */
11774 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
11775 0x0200001f, 0x80000000, 0xb00f0001, /* dcl t1 */
11776 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
11777 0x0200001f, 0x90000000, 0xa00f0801, /* dcl_2d s1 */
11778 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
11779 0x03000042, 0x800f0001, 0xb0e40001, 0xa0e40801, /* texld r1, t1, s1 */
11780 0x03000002, 0x800f0000, 0x80e40000, 0x80e40001, /* add r0, r0, r1 */
11781 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
11782 0x0000ffff
11784 static const DWORD pshader2_zw_code[] =
11786 0xffff0200, /* ps_2_0 */
11787 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
11788 0x0200001f, 0x80000000, 0xb00f0001, /* dcl t1 */
11789 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
11790 0x0200001f, 0x90000000, 0xa00f0801, /* dcl_2d s1 */
11791 0x02000001, 0x80030000, 0xb01b0000, /* mov r0.xy, t0.wzyx */
11792 0x02000001, 0x80030001, 0xb01b0001, /* mov r1.xy, t1.wzyx */
11793 0x03000042, 0x800f0000, 0x80e40000, 0xa0e40800, /* texld r0, r0, s0 */
11794 0x03000042, 0x800f0001, 0x80e40001, 0xa0e40801, /* texld r1, r1, s1 */
11795 0x03000002, 0x800f0000, 0x80e40000, 0x80e40001, /* add r0, r0, r1 */
11796 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
11797 0x0000ffff
11799 static const DWORD vshader3_code[] =
11801 0xfffe0300, /* vs_3_0 */
11802 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
11803 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
11804 0x0200001f, 0x80000005, 0xe00f0001, /* dcl_texcoord0 o1 */
11805 0x0200001f, 0x80010005, 0xe00f0002, /* dcl_texcoord1 o2 */
11806 0x03000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
11807 0x04000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
11808 0x04000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
11809 0x04000004, 0xe00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad o0, v0.w, c3, r0 */
11810 0x02000001, 0xe00f0001, 0x90000000, /* mov o1, v0.x */
11811 0x02000001, 0xe00f0002, 0x90000000, /* mov o2, v0.x */
11812 0x0000ffff
11814 static const DWORD vshader3_psize_code[] =
11816 0xfffe0300, /* vs_3_0 */
11817 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
11818 0x0200001f, 0x80000004, 0x90010001, /* dcl_psize v1.x */
11819 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
11820 0x0200001f, 0x80000004, 0xe00f0001, /* dcl_psize o1 */
11821 0x0200001f, 0x80000005, 0xe00f0002, /* dcl_texcoord0 o2 */
11822 0x0200001f, 0x80010005, 0xe00f0003, /* dcl_texcoord1 o3 */
11823 0x03000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
11824 0x04000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
11825 0x04000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
11826 0x04000004, 0xe00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad o0, v0.w, c3, r0 */
11827 0x02000001, 0xe00f0001, 0x90000001, /* mov o1, v1.x */
11828 0x02000001, 0xe00f0002, 0x90000000, /* mov o2, v0.x */
11829 0x02000001, 0xe00f0003, 0x90000000, /* mov o3, v0.x */
11830 0x0000ffff
11832 static const DWORD pshader3_code[] =
11834 0xffff0300, /* ps_3_0 */
11835 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
11836 0x0200001f, 0x80010005, 0x900f0001, /* dcl_texcoord1 v1 */
11837 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
11838 0x0200001f, 0x90000000, 0xa00f0801, /* dcl_2d s1 */
11839 0x03000042, 0x800f0000, 0x90e40000, 0xa0e40800, /* texld r0, v0, s0 */
11840 0x03000042, 0x800f0001, 0x90e40001, 0xa0e40801, /* texld r1, v1, s1 */
11841 0x03000002, 0x800f0800, 0x80e40000, 0x80e40001, /* add oC0, r0, r1 */
11842 0x0000ffff
11844 static const DWORD pshader3_zw_code[] =
11846 0xffff0300, /* ps_3_0 */
11847 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
11848 0x0200001f, 0x80010005, 0x900f0001, /* dcl_texcoord1 v1 */
11849 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
11850 0x0200001f, 0x90000000, 0xa00f0801, /* dcl_2d s1 */
11851 0x03000042, 0x800f0000, 0x90fe0000, 0xa0e40800, /* texld r0, v0.zw, s0 */
11852 0x03000042, 0x800f0001, 0x90fe0001, 0xa0e40801, /* texld r1, v1.zw, s1 */
11853 0x03000002, 0x800f0800, 0x80e40000, 0x80e40001, /* add oC0, r0, r1 */
11854 0x0000ffff
11856 static const struct test_shader
11858 DWORD version;
11859 const DWORD *code;
11861 novs = {0, NULL},
11862 vs1 = {D3DVS_VERSION(1, 1), vshader_code},
11863 vs1_psize = {D3DVS_VERSION(1, 1), vshader_psize_code},
11864 vs3 = {D3DVS_VERSION(3, 0), vshader3_code},
11865 vs3_psize = {D3DVS_VERSION(3, 0), vshader3_psize_code},
11866 nops = {0, NULL},
11867 ps1 = {D3DPS_VERSION(1, 1), pshader_code},
11868 ps2 = {D3DPS_VERSION(2, 0), pshader2_code},
11869 ps2_zw = {D3DPS_VERSION(2, 0), pshader2_zw_code},
11870 ps3 = {D3DPS_VERSION(3, 0), pshader3_code},
11871 ps3_zw = {D3DPS_VERSION(3, 0), pshader3_zw_code};
11872 static const struct
11874 const struct test_shader *vs;
11875 const struct test_shader *ps;
11876 DWORD accepted_fvf;
11877 unsigned int nonscaled_size, scaled_size;
11878 BOOL gives_0_0_texcoord;
11879 BOOL allow_broken;
11881 test_setups[] =
11883 {&novs, &nops, D3DFVF_XYZ, 32, 45, FALSE, FALSE},
11884 {&vs1, &ps1, D3DFVF_XYZ, 32, 32, FALSE, FALSE},
11885 {&novs, &ps1, D3DFVF_XYZ, 32, 45, FALSE, FALSE},
11886 {&vs1, &nops, D3DFVF_XYZ, 32, 32, FALSE, FALSE},
11887 {&novs, &ps2, D3DFVF_XYZ, 32, 45, FALSE, TRUE},
11888 {&novs, &ps2_zw, D3DFVF_XYZ, 32, 45, TRUE, FALSE},
11889 {&vs1, &ps2, D3DFVF_XYZ, 32, 32, FALSE, TRUE},
11890 {&vs1, &ps2_zw, D3DFVF_XYZ, 32, 32, TRUE, FALSE},
11891 {&vs3, &ps3, D3DFVF_XYZ, 32, 32, FALSE, TRUE},
11892 {&vs3, &ps3_zw, D3DFVF_XYZ, 32, 32, TRUE, FALSE},
11893 {&novs, &nops, D3DFVF_XYZ | D3DFVF_PSIZE, 48, 33, FALSE, FALSE},
11894 {&vs1_psize, &ps1, D3DFVF_XYZ | D3DFVF_PSIZE, 48, 24, FALSE, FALSE},
11895 {&vs3_psize, &ps3, D3DFVF_XYZ | D3DFVF_PSIZE, 48, 24, FALSE, TRUE},
11897 static const struct
11899 BOOL zero_size;
11900 BOOL scale;
11901 BOOL override_min;
11902 DWORD fvf;
11903 const void *vertex_data;
11904 unsigned int vertex_size;
11906 tests[] =
11908 {FALSE, FALSE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
11909 {FALSE, TRUE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
11910 {FALSE, FALSE, TRUE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
11911 {TRUE, FALSE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
11912 {FALSE, FALSE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize, sizeof(vertex_pointsize)},
11913 {FALSE, TRUE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize_scaled, sizeof(vertex_pointsize_scaled)},
11914 {FALSE, FALSE, TRUE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize, sizeof(vertex_pointsize)},
11915 {TRUE, FALSE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize_zero, sizeof(vertex_pointsize_zero)},
11917 /* Transforms the coordinate system [-1.0;1.0]x[1.0;-1.0] to
11918 * [0.0;0.0]x[640.0;480.0]. Z is untouched. */
11919 D3DMATRIX matrix =
11921 2.0f / 640.0f, 0.0f, 0.0f, 0.0f,
11922 0.0f, -2.0f / 480.0f, 0.0f, 0.0f,
11923 0.0f, 0.0f, 1.0f, 0.0f,
11924 -1.0f, 1.0f, 0.0f, 1.0f,
11925 }}};
11927 window = create_window();
11928 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11929 ok(!!d3d, "Failed to create a D3D object.\n");
11930 if (!(device = create_device(d3d, window, window, TRUE)))
11932 skip("Failed to create a D3D device, skipping tests.\n");
11933 goto done;
11936 memset(&caps, 0, sizeof(caps));
11937 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11938 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11939 if(caps.MaxPointSize < 32.0) {
11940 skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
11941 IDirect3DDevice9_Release(device);
11942 goto done;
11945 /* The r500 Windows driver needs a draw with regular texture coordinates at least once during the
11946 * device's lifetime, otherwise texture coordinate generation only works for texture 0. */
11947 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
11948 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11949 hr = IDirect3DDevice9_BeginScene(device);
11950 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
11951 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, vertices, sizeof(float) * 5);
11952 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
11953 hr = IDirect3DDevice9_EndScene(device);
11954 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
11956 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
11957 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11958 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11959 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
11960 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
11961 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11962 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
11963 ok(hr == S_OK, "Got hr %#lx.\n", hr);
11965 hr = IDirect3DDevice9_BeginScene(device);
11966 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
11968 ptsize = 15.0f;
11969 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
11970 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
11971 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
11972 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
11974 ptsize = 31.0f;
11975 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
11976 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
11977 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
11978 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
11980 ptsize = 30.75f;
11981 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
11982 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
11983 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
11984 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
11986 if (caps.MaxPointSize >= 63.0f)
11988 ptsize = 63.0f;
11989 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
11990 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
11991 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
11992 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
11994 ptsize = 62.75f;
11995 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
11996 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
11997 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
11998 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
12001 ptsize = 1.0f;
12002 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
12003 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
12004 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
12005 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
12007 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *)&ptsizemax_orig);
12008 ok(SUCCEEDED(hr), "Failed to get render state, hr %#lx.\n", hr);
12009 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *)&ptsizemin_orig);
12010 ok(SUCCEEDED(hr), "Failed to get render state, hr %#lx.\n", hr);
12012 /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
12013 ptsize = 15.0f;
12014 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
12015 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
12016 ptsize = 1.0f;
12017 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *(DWORD *)&ptsize);
12018 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
12019 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
12020 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
12022 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *(DWORD *)&ptsizemax_orig);
12023 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
12025 /* pointsize < pointsize_min < pointsize_max?
12026 * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
12027 ptsize = 1.0f;
12028 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
12029 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
12030 ptsize = 15.0f;
12031 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsize);
12032 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
12033 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
12034 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
12036 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsizemin_orig);
12037 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
12039 hr = IDirect3DDevice9_EndScene(device);
12040 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
12042 ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
12043 ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
12044 ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
12046 if (caps.MaxPointSize >= 63.0)
12048 ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
12049 ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
12052 ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
12053 /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
12054 ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
12055 /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
12056 ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
12058 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12060 /* The following code tests point sprites with two textures, to see if each texture coordinate unit
12061 * generates texture coordinates for the point(result: Yes, it does)
12063 * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
12064 * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
12065 * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
12067 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
12068 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12070 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
12071 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12072 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
12073 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12074 memset(&lr, 0, sizeof(lr));
12075 hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
12076 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12077 memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
12078 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
12079 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12080 memset(&lr, 0, sizeof(lr));
12081 hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
12082 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12083 memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
12084 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
12085 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12086 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
12087 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12088 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
12089 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12090 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12091 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12092 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12093 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12094 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
12095 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12096 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12097 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12098 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
12099 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12101 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
12102 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12103 ptsize = 32.0;
12104 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
12105 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12107 hr = IDirect3DDevice9_BeginScene(device);
12108 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
12109 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
12110 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
12111 hr = IDirect3DDevice9_EndScene(device);
12112 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
12114 color = getPixelColor(device, 64-4, 64-4);
12115 ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
12116 color = getPixelColor(device, 64-4, 64+4);
12117 ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
12118 color = getPixelColor(device, 64+4, 64+4);
12119 ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
12120 color = getPixelColor(device, 64+4, 64-4);
12121 ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
12122 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12124 matrix.m[0][0] = 1.0f / 64.0f;
12125 matrix.m[1][1] = -1.0f / 64.0f;
12126 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
12127 ok(SUCCEEDED(hr), "SetTransform failed, hr %#lx.\n", hr);
12129 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
12130 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#lx.\n", hr);
12132 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
12133 D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL );
12134 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#lx.\n", hr);
12136 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSCALE_A, *(DWORD *)&a);
12137 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#lx.\n", hr);
12138 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSCALE_B, *(DWORD *)&b);
12139 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#lx.\n", hr);
12140 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSCALE_C, *(DWORD *)&c);
12141 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#lx.\n", hr);
12142 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
12144 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, &matrix._11, 4);
12145 ok(SUCCEEDED(hr), "Failed to set vertex shader constants, hr %#lx.\n", hr);
12148 if (caps.MaxPointSize < 63.0f)
12150 skip("MaxPointSize %f < 63.0, skipping some tests.\n", caps.MaxPointSize);
12151 goto cleanup;
12154 for (i = 0; i < ARRAY_SIZE(test_setups); ++i)
12156 if (caps.VertexShaderVersion < test_setups[i].vs->version
12157 || caps.PixelShaderVersion < test_setups[i].ps->version)
12159 skip("Vertex / pixel shader version not supported, skipping test.\n");
12160 continue;
12162 if (test_setups[i].vs->code)
12164 hr = IDirect3DDevice9_CreateVertexShader(device, test_setups[i].vs->code, &vs);
12165 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#lx (case %u).\n", hr, i);
12167 else
12169 vs = NULL;
12171 if (test_setups[i].ps->code)
12173 hr = IDirect3DDevice9_CreatePixelShader(device, test_setups[i].ps->code, &ps);
12174 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#lx (case %u).\n", hr, i);
12176 else
12178 ps = NULL;
12181 hr = IDirect3DDevice9_SetVertexShader(device, vs);
12182 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
12183 hr = IDirect3DDevice9_SetPixelShader(device, ps);
12184 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
12186 for (j = 0; j < ARRAY_SIZE(tests); ++j)
12188 BOOL allow_broken = test_setups[i].allow_broken;
12189 unsigned int size = tests[j].override_min ? 63 : tests[j].zero_size ? 0 : tests[j].scale
12190 ? test_setups[i].scaled_size : test_setups[i].nonscaled_size;
12192 if (test_setups[i].accepted_fvf != tests[j].fvf)
12193 continue;
12195 ptsize = tests[j].zero_size ? 0.0f : 32.0f;
12196 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
12197 ok(SUCCEEDED(hr), "Failed to set pointsize, hr %#lx.\n", hr);
12199 ptsize = tests[j].override_min ? 63.0f : tests[j].zero_size ? 0.0f : ptsizemin_orig;
12200 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsize);
12201 ok(SUCCEEDED(hr), "Failed to set minimum pointsize, hr %#lx.\n", hr);
12203 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSCALEENABLE, tests[j].scale);
12204 ok(SUCCEEDED(hr), "Failed setting point scale state, hr %#lx.\n", hr);
12206 hr = IDirect3DDevice9_SetFVF(device, tests[j].fvf);
12207 ok(SUCCEEDED(hr), "Failed setting FVF, hr %#lx.\n", hr);
12209 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
12210 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
12211 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
12212 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
12214 hr = IDirect3DDevice9_BeginScene(device);
12215 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
12216 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1,
12217 tests[j].vertex_data, tests[j].vertex_size);
12218 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
12219 hr = IDirect3DDevice9_EndScene(device);
12220 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
12222 hr = IDirect3DDevice9_StretchRect(device, rt, &rect, backbuffer, &rect, D3DTEXF_NONE);
12223 ok(SUCCEEDED(hr), "Failed to blit, hr %#lx.\n", hr);
12224 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
12225 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
12227 if (tests[j].zero_size)
12229 /* Technically 0 pointsize is undefined in OpenGL but in practice it seems like
12230 * it does the "useful" thing on all the drivers I tried. */
12231 /* On WARP it does draw some pixels, most of the time. */
12232 color = getPixelColor(device, 64, 64);
12233 todo_wine_if(!color_match(color, 0x0000ffff, 0))
12234 ok(color_match(color, 0x0000ffff, 0)
12235 || broken(color_match(color, 0x00ff0000, 0))
12236 || broken(color_match(color, 0x00ffff00, 0))
12237 || broken(color_match(color, 0x00000000, 0))
12238 || broken(color_match(color, 0x0000ff00, 0)),
12239 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
12241 else
12243 struct surface_readback rb;
12245 get_rt_readback(backbuffer, &rb);
12246 /* On AMD apparently only the first texcoord is modified by the point coordinates
12247 * when using SM2/3 pixel shaders. */
12248 color = get_readback_color(&rb, 64 - size / 2 + 1, 64 - size / 2 + 1);
12249 ok(color_match(color, 0x00ff0000, 0),
12250 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
12251 color = get_readback_color(&rb, 64 + size / 2 - 1, 64 - size / 2 + 1);
12252 ok(color_match(color, test_setups[i].gives_0_0_texcoord ? 0x00ff0000 : 0x00ffff00, 0)
12253 || (allow_broken && broken(color_match(color, 0x00ff0000, 0))),
12254 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
12255 color = get_readback_color(&rb, 64 - size / 2 + 1, 64 + size / 2 - 1);
12256 ok(color_match(color, test_setups[i].gives_0_0_texcoord ? 0x00ff0000 : 0x00000000, 0),
12257 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
12258 color = get_readback_color(&rb, 64 + size / 2 - 1, 64 + size / 2 - 1);
12259 ok(color_match(color, test_setups[i].gives_0_0_texcoord ? 0x00ff0000 : 0x0000ff00, 0)
12260 || (allow_broken && broken(color_match(color, 0x00000000, 0))),
12261 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
12263 color = get_readback_color(&rb, 64 - size / 2 - 1, 64 - size / 2 - 1);
12264 ok(color_match(color, 0xff00ffff, 0),
12265 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
12266 color = get_readback_color(&rb, 64 + size / 2 + 1, 64 - size / 2 - 1);
12267 ok(color_match(color, 0xff00ffff, 0),
12268 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
12269 color = get_readback_color(&rb, 64 - size / 2 - 1, 64 + size / 2 + 1);
12270 ok(color_match(color, 0xff00ffff, 0),
12271 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
12272 color = get_readback_color(&rb, 64 + size / 2 + 1, 64 + size / 2 + 1);
12273 ok(color_match(color, 0xff00ffff, 0),
12274 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
12276 release_surface_readback(&rb);
12279 IDirect3DDevice9_SetVertexShader(device, NULL);
12280 IDirect3DDevice9_SetPixelShader(device, NULL);
12281 if (vs)
12282 IDirect3DVertexShader9_Release(vs);
12283 if (ps)
12284 IDirect3DVertexShader9_Release(ps);
12287 cleanup:
12288 IDirect3DSurface9_Release(backbuffer);
12289 IDirect3DSurface9_Release(rt);
12291 IDirect3DTexture9_Release(tex1);
12292 IDirect3DTexture9_Release(tex2);
12293 refcount = IDirect3DDevice9_Release(device);
12294 ok(!refcount, "Device has %lu references left.\n", refcount);
12295 done:
12296 IDirect3D9_Release(d3d);
12297 DestroyWindow(window);
12300 static void multiple_rendertargets_test(void)
12302 IDirect3DSurface9 *surf1, *surf2, *backbuf, *readback;
12303 IDirect3DPixelShader9 *ps1, *ps2;
12304 IDirect3DTexture9 *tex1, *tex2;
12305 IDirect3DVertexShader9 *vs;
12306 IDirect3DDevice9 *device;
12307 unsigned int color, i, j;
12308 IDirect3D9 *d3d;
12309 ULONG refcount;
12310 D3DCAPS9 caps;
12311 HWND window;
12312 HRESULT hr;
12314 static const DWORD vshader_code[] =
12316 0xfffe0300, /* vs_3_0 */
12317 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
12318 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
12319 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
12320 0x0000ffff /* end */
12322 static const DWORD pshader_code1[] =
12324 0xffff0300, /* ps_3_0 */
12325 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
12326 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
12327 0x0000ffff /* end */
12329 static const DWORD pshader_code2[] =
12331 0xffff0300, /* ps_3_0 */
12332 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
12333 0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0.0, 0.0, 1.0, 0.0 */
12334 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
12335 0x02000001, 0x800f0801, 0xa0e40001, /* mov oC1, c1 */
12336 0x0000ffff /* end */
12338 static const float quad[] =
12340 -1.0f, -1.0f, 0.1f,
12341 -1.0f, 1.0f, 0.1f,
12342 1.0f, -1.0f, 0.1f,
12343 1.0f, 1.0f, 0.1f,
12345 static const float texquad[] =
12347 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
12348 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
12349 0.0f, -1.0f, 0.1f, 1.0f, 0.0f,
12350 0.0f, 1.0f, 0.1f, 1.0f, 1.0f,
12352 0.0f, -1.0f, 0.1f, 0.0f, 0.0f,
12353 0.0f, 1.0f, 0.1f, 0.0f, 1.0f,
12354 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
12355 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
12358 window = create_window();
12359 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12360 ok(!!d3d, "Failed to create a D3D object.\n");
12361 if (!(device = create_device(d3d, window, window, TRUE)))
12363 skip("Failed to create a D3D device, skipping tests.\n");
12364 goto done;
12367 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12368 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
12369 if (caps.NumSimultaneousRTs < 2)
12371 skip("Only 1 simultaneous render target supported, skipping MRT test.\n");
12372 IDirect3DDevice9_Release(device);
12373 goto done;
12375 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
12377 skip("No shader model 3 support, skipping tests.\n");
12378 IDirect3DDevice9_Release(device);
12379 goto done;
12382 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
12383 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12385 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 16, 16,
12386 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
12387 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed, hr %#lx.\n", hr);
12389 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
12390 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
12391 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12392 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
12393 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
12394 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12395 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vs);
12396 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#lx.\n", hr);
12397 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code1, &ps1);
12398 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#lx.\n", hr);
12399 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code2, &ps2);
12400 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#lx.\n", hr);
12402 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
12403 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12404 hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
12405 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12406 hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
12407 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12409 hr = IDirect3DDevice9_SetVertexShader(device, vs);
12410 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#lx.\n", hr);
12411 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
12412 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12413 hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
12414 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12415 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
12416 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12418 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
12419 ok(SUCCEEDED(hr), "Clear failed, hr %#lx,\n", hr);
12420 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
12421 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#lx.\n", hr);
12422 color = getPixelColorFromSurface(readback, 8, 8);
12423 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
12424 "Expected color 0x000000ff, got 0x%08x.\n", color);
12425 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
12426 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#lx.\n", hr);
12427 color = getPixelColorFromSurface(readback, 8, 8);
12428 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
12429 "Expected color 0x000000ff, got 0x%08x.\n", color);
12431 /* Render targets not written by the pixel shader should be unmodified. */
12432 hr = IDirect3DDevice9_SetPixelShader(device, ps1);
12433 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
12434 hr = IDirect3DDevice9_BeginScene(device);
12435 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
12436 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
12437 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
12438 hr = IDirect3DDevice9_EndScene(device);
12439 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
12440 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
12441 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#lx.\n", hr);
12442 color = getPixelColorFromSurface(readback, 8, 8);
12443 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
12444 "Expected color 0xff00ff00, got 0x%08x.\n", color);
12445 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
12446 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#lx.\n", hr);
12447 for (i = 6; i < 10; ++i)
12449 for (j = 6; j < 10; ++j)
12451 color = getPixelColorFromSurface(readback, j, i);
12452 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
12453 "Expected color 0xff0000ff, got 0x%08x at %u, %u.\n", color, j, i);
12457 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
12458 ok(SUCCEEDED(hr), "Clear failed, hr %#lx,\n", hr);
12459 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
12460 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#lx.\n", hr);
12461 color = getPixelColorFromSurface(readback, 8, 8);
12462 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
12463 "Expected color 0x0000ff00, got 0x%08x.\n", color);
12464 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
12465 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#lx.\n", hr);
12466 color = getPixelColorFromSurface(readback, 8, 8);
12467 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
12468 "Expected color 0x0000ff00, got 0x%08x.\n", color);
12470 hr = IDirect3DDevice9_SetPixelShader(device, ps2);
12471 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
12473 hr = IDirect3DDevice9_BeginScene(device);
12474 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
12476 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
12477 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
12479 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12480 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
12481 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
12482 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
12483 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
12484 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
12485 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
12486 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
12487 hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
12488 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
12489 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
12490 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
12492 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
12493 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
12494 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
12495 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
12497 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
12498 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
12499 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
12500 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
12502 hr = IDirect3DDevice9_EndScene(device);
12503 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
12505 color = getPixelColor(device, 160, 240);
12506 ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
12507 color = getPixelColor(device, 480, 240);
12508 ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
12509 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12511 IDirect3DPixelShader9_Release(ps2);
12512 IDirect3DPixelShader9_Release(ps1);
12513 IDirect3DVertexShader9_Release(vs);
12514 IDirect3DTexture9_Release(tex1);
12515 IDirect3DTexture9_Release(tex2);
12516 IDirect3DSurface9_Release(surf1);
12517 IDirect3DSurface9_Release(surf2);
12518 IDirect3DSurface9_Release(backbuf);
12519 IDirect3DSurface9_Release(readback);
12520 refcount = IDirect3DDevice9_Release(device);
12521 ok(!refcount, "Device has %lu references left.\n", refcount);
12522 done:
12523 IDirect3D9_Release(d3d);
12524 DestroyWindow(window);
12527 static void pixelshader_blending_test(void)
12529 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
12530 IDirect3DTexture9 *offscreenTexture = NULL;
12531 unsigned int fmt_index, color;
12532 IDirect3DDevice9 *device;
12533 IDirect3D9 *d3d;
12534 ULONG refcount;
12535 HWND window;
12536 HRESULT hr;
12538 static const struct
12540 const char *fmtName;
12541 D3DFORMAT textureFormat;
12542 unsigned int resultColorBlending, resultColorNoBlending;
12544 test_formats[] =
12546 {"D3DFMT_G16R16", D3DFMT_G16R16, 0x001820ff, 0x002010ff},
12547 {"D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff},
12548 {"D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001820ff, 0x002010ff},
12549 {"D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00182000, 0x00201000},
12550 {"D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff},
12551 {"D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001820ff, 0x002010ff},
12552 {"D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00182000, 0x00201000},
12553 {"D3DFMT_L8", D3DFMT_L8, 0x00181818, 0x00202020},
12555 static const float quad[][5] =
12557 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
12558 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
12559 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
12560 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
12562 static const struct
12564 struct vec3 position;
12565 DWORD diffuse;
12567 quad1[] =
12569 {{-1.0f, -1.0f, 0.1f}, 0x80103000},
12570 {{-1.0f, 1.0f, 0.1f}, 0x80103000},
12571 {{ 1.0f, -1.0f, 0.1f}, 0x80103000},
12572 {{ 1.0f, 1.0f, 0.1f}, 0x80103000},
12574 quad2[] =
12576 {{-1.0f, -1.0f, 0.1f}, 0x80201000},
12577 {{-1.0f, 1.0f, 0.1f}, 0x80201000},
12578 {{ 1.0f, -1.0f, 0.1f}, 0x80201000},
12579 {{ 1.0f, 1.0f, 0.1f}, 0x80201000},
12582 window = create_window();
12583 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12584 ok(!!d3d, "Failed to create a D3D object.\n");
12585 if (!(device = create_device(d3d, window, window, TRUE)))
12587 skip("Failed to create a D3D device, skipping tests.\n");
12588 goto done;
12591 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
12592 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12594 for (fmt_index = 0; fmt_index < ARRAY_SIZE(test_formats); ++fmt_index)
12596 D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
12598 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
12599 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, fmt) != D3D_OK)
12601 skip("%s textures not supported as render targets.\n", test_formats[fmt_index].fmtName);
12602 continue;
12605 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
12606 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12608 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
12609 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
12610 if(!offscreenTexture) {
12611 continue;
12614 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
12615 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12616 if(!offscreen) {
12617 continue;
12620 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12621 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12623 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12624 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12625 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12626 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12627 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
12628 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12629 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
12630 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12631 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12632 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12634 /* Below we will draw two quads with different colors and try to blend
12635 * them together. The result color is compared with the expected
12636 * outcome. */
12637 hr = IDirect3DDevice9_BeginScene(device);
12638 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
12640 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
12641 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
12642 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 1.0f, 0);
12643 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
12645 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
12646 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
12648 /* Draw a quad using color 0x0010200. */
12649 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
12650 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
12651 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
12652 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
12653 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
12654 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
12656 /* Draw a quad using color 0x0020100. */
12657 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
12658 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
12659 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
12660 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
12661 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
12662 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
12664 /* We don't want to blend the result on the backbuffer. */
12665 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
12666 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
12668 /* Prepare rendering the 'blended' texture quad to the backbuffer. */
12669 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
12670 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
12671 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)offscreenTexture);
12672 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
12674 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
12675 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
12677 /* This time with the texture. */
12678 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
12679 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
12681 hr = IDirect3DDevice9_EndScene(device);
12682 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
12684 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
12685 D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK)
12687 /* Compare the color of the center quad with our expectation. */
12688 color = getPixelColor(device, 320, 240);
12689 ok(color_match(color, test_formats[fmt_index].resultColorBlending, 1),
12690 "Offscreen failed for %s: Got color 0x%08x, expected 0x%08x.\n",
12691 test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
12693 else
12695 /* No pixel shader blending is supported so expect garbage. The
12696 * type of 'garbage' depends on the driver version and OS. E.g. on
12697 * G16R16 ATI reports (on old r9600 drivers) 0x00ffffff and on
12698 * modern ones 0x002010ff which is also what NVIDIA reports. On
12699 * Vista NVIDIA seems to report 0x00ffffff on Geforce7 cards. */
12700 color = getPixelColor(device, 320, 240);
12701 ok((color == 0x00ffffff) || (color == test_formats[fmt_index].resultColorNoBlending),
12702 "Offscreen failed for %s: Got unexpected color 0x%08x, expected no color blending.\n",
12703 test_formats[fmt_index].fmtName, color);
12705 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12707 IDirect3DDevice9_SetTexture(device, 0, NULL);
12708 if(offscreenTexture) {
12709 IDirect3DTexture9_Release(offscreenTexture);
12711 if(offscreen) {
12712 IDirect3DSurface9_Release(offscreen);
12716 IDirect3DSurface9_Release(backbuffer);
12717 refcount = IDirect3DDevice9_Release(device);
12718 ok(!refcount, "Device has %lu references left.\n", refcount);
12719 done:
12720 IDirect3D9_Release(d3d);
12721 DestroyWindow(window);
12724 static void tssargtemp_test(void)
12726 IDirect3DDevice9 *device;
12727 unsigned int color;
12728 IDirect3D9 *d3d;
12729 ULONG refcount;
12730 D3DCAPS9 caps;
12731 HWND window;
12732 HRESULT hr;
12734 static const struct
12736 struct vec3 position;
12737 DWORD diffuse;
12739 quad[] =
12741 {{-1.0f, -1.0f, 0.1f}, 0x00ff0000},
12742 {{-1.0f, 1.0f, 0.1f}, 0x00ff0000},
12743 {{ 1.0f, -1.0f, 0.1f}, 0x00ff0000},
12744 {{ 1.0f, 1.0f, 0.1f}, 0x00ff0000},
12747 window = create_window();
12748 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12749 ok(!!d3d, "Failed to create a D3D object.\n");
12750 if (!(device = create_device(d3d, window, window, TRUE)))
12752 skip("Failed to create a D3D device, skipping tests.\n");
12753 goto done;
12756 memset(&caps, 0, sizeof(caps));
12757 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12758 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12759 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
12760 skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
12761 IDirect3DDevice9_Release(device);
12762 goto done;
12765 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
12766 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12768 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12769 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12770 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
12771 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12773 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12774 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12775 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
12776 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12777 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
12778 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12780 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
12781 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12782 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
12783 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12784 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
12785 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12787 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
12788 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12790 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
12791 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12792 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12793 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
12794 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12795 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12797 hr = IDirect3DDevice9_BeginScene(device);
12798 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
12799 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
12800 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
12801 hr = IDirect3DDevice9_EndScene(device);
12802 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
12804 color = getPixelColor(device, 320, 240);
12805 ok(color == 0x00ffff00, "TSSARGTEMP test returned color 0x%08x, expected 0x00ffff00\n", color);
12806 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12808 refcount = IDirect3DDevice9_Release(device);
12809 ok(!refcount, "Device has %lu references left.\n", refcount);
12810 done:
12811 IDirect3D9_Release(d3d);
12812 DestroyWindow(window);
12815 /* Drawing Indexed Geometry with instances*/
12816 static void stream_test(void)
12818 IDirect3DVertexDeclaration9 *pDecl = NULL;
12819 IDirect3DVertexShader9 *shader = NULL;
12820 IDirect3DVertexBuffer9 *vb3 = NULL;
12821 IDirect3DVertexBuffer9 *vb2 = NULL;
12822 IDirect3DVertexBuffer9 *vb = NULL;
12823 IDirect3DIndexBuffer9 *ib = NULL;
12824 unsigned int color, ind, i;
12825 IDirect3DDevice9 *device;
12826 IDirect3D9 *d3d;
12827 ULONG refcount;
12828 D3DCAPS9 caps;
12829 HWND window;
12830 HRESULT hr;
12831 BYTE *data;
12833 static const struct testdata
12835 DWORD idxVertex; /* number of instances in the first stream */
12836 DWORD idxColor; /* number of instances in the second stream */
12837 DWORD idxInstance; /* should be 1 ?? */
12838 unsigned int color1, color2, color3, color4;
12839 WORD strVertex; /* specify which stream to use 0-2*/
12840 WORD strColor;
12841 WORD strInstance;
12842 DWORD explicit_zero_freq;
12844 testcases[]=
12846 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 0 */
12847 {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 1 */
12848 {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 2 */
12849 {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 3 */
12850 {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 4 */
12851 {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 5 */
12852 {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 6 */
12853 {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 7 */
12854 {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 8 */
12855 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 9 */
12856 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 10 */
12857 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 11 */
12859 /* The number of instances is read from stream zero, even if stream zero is not
12860 * in use. Exact behavior of this corner case depends on the presence or absence
12861 * of D3DSTREAMSOURCE_INDEXEDDATA. r500 GPUs need D3DSTREAMSOURCE_INDEXEDDATA
12862 * to be present, otherwise they disable instancing and behave like in a non-
12863 * instanced draw. Nvidia drivers do not show different behavior with or without
12864 * D3DSTREAMSOURCE_INDEXEDDATA. Note however that setting the value to 0 is not
12865 * allowed by the d3d runtime.
12867 * The meaning of (D3DSTREAMSOURCE_INDEXEDDATA | 0) is driver dependent. r500
12868 * will fall back to non-instanced drawing. Geforce 7 will draw 1 instance.
12869 * Geforce 8+ will draw nothing. */
12870 {3, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1, 1}, /* 12 */
12871 {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 2, 3, 1, 2}, /* 13 */
12872 {1, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 2, 3, 1, 3}, /* 14 */
12873 {0, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 3, 1, 4}, /* 15 */
12875 static const DWORD shader_code[] =
12877 0xfffe0101, /* vs_1_1 */
12878 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
12879 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
12880 0x0000001f, 0x80000005, 0x900f0002, /* dcl_texcoord v2 */
12881 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
12882 0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
12883 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
12884 0x0000ffff
12886 /* Note that this set of coordinates and instancepos[] have an implicit
12887 * w = 1.0, which is added to w = 2.0, so the perspective divide divides
12888 * x, y and z by 2. */
12889 static const float quad[][3] =
12891 {-0.5f, -0.5f, 1.1f}, /*0 */
12892 {-0.5f, 0.5f, 1.1f}, /*1 */
12893 { 0.5f, -0.5f, 1.1f}, /*2 */
12894 { 0.5f, 0.5f, 1.1f}, /*3 */
12896 static const float vertcolor[][4] =
12898 {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
12899 {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
12900 {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
12901 {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
12903 /* 4 position for 4 instances */
12904 static const float instancepos[][3] =
12906 {-0.6f,-0.6f, 0.0f},
12907 { 0.6f,-0.6f, 0.0f},
12908 { 0.6f, 0.6f, 0.0f},
12909 {-0.6f, 0.6f, 0.0f},
12911 static const short indices[] = {0, 1, 2, 2, 1, 3};
12912 D3DVERTEXELEMENT9 decl[] =
12914 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
12915 {1, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
12916 {2, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
12917 D3DDECL_END()
12920 window = create_window();
12921 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12922 ok(!!d3d, "Failed to create a D3D object.\n");
12923 if (!(device = create_device(d3d, window, window, TRUE)))
12925 skip("Failed to create a D3D device, skipping tests.\n");
12926 goto done;
12929 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12930 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
12931 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
12933 skip("No vs_3_0 support, skipping tests.\n");
12934 IDirect3DDevice9_Release(device);
12935 goto done;
12938 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 0, &ind);
12939 ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq unexpected result, "
12940 "hr %#lx, ind %#x.\n", hr, ind);
12941 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
12942 ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq unexpected result, "
12943 "hr %#lx, ind %#x.\n", hr, ind);
12945 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
12946 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed, hr %#lx.\n", hr);
12948 /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
12949 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
12950 ok(hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
12952 /* check wrong cases */
12953 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
12954 ok(hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
12955 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
12956 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
12957 ok(ind == 1, "Got frequency %#x.\n", ind);
12958 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
12959 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12960 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
12961 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
12962 ok(ind == 2, "Got frequency %#x.\n", ind);
12963 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
12964 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12965 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
12966 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
12967 ok(ind == D3DSTREAMSOURCE_INDEXEDDATA, "Got frequency %#x.\n", ind);
12968 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
12969 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12970 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
12971 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
12972 ok(ind == D3DSTREAMSOURCE_INSTANCEDATA, "Got frequency %#x.\n", ind);
12973 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
12974 ok(hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
12975 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
12976 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
12977 ok(ind == D3DSTREAMSOURCE_INSTANCEDATA, "Got frequency %#x.\n", ind);
12979 /* set the default value back */
12980 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
12981 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12983 /* create all VertexBuffers*/
12984 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
12985 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12986 if(!vb) {
12987 skip("Failed to create a vertex buffer\n");
12988 IDirect3DDevice9_Release(device);
12989 goto done;
12991 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
12992 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12993 if(!vb2) {
12994 skip("Failed to create a vertex buffer\n");
12995 goto out;
12997 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
12998 ok(hr == S_OK, "Got hr %#lx.\n", hr);
12999 if(!vb3) {
13000 skip("Failed to create a vertex buffer\n");
13001 goto out;
13004 /* create IndexBuffer*/
13005 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
13006 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13007 if(!ib) {
13008 skip("Failed to create an index buffer\n");
13009 goto out;
13012 /* copy all Buffers (Vertex + Index)*/
13013 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
13014 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13015 memcpy(data, quad, sizeof(quad));
13016 hr = IDirect3DVertexBuffer9_Unlock(vb);
13017 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13018 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
13019 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13020 memcpy(data, vertcolor, sizeof(vertcolor));
13021 hr = IDirect3DVertexBuffer9_Unlock(vb2);
13022 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13023 hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
13024 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13025 memcpy(data, instancepos, sizeof(instancepos));
13026 hr = IDirect3DVertexBuffer9_Unlock(vb3);
13027 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13028 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
13029 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13030 memcpy(data, indices, sizeof(indices));
13031 hr = IDirect3DIndexBuffer9_Unlock(ib);
13032 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13034 /* create VertexShader */
13035 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
13036 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13037 if(!shader) {
13038 skip("Failed to create a vertex shader.\n");
13039 goto out;
13042 hr = IDirect3DDevice9_SetVertexShader(device, shader);
13043 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13045 hr = IDirect3DDevice9_SetIndices(device, ib);
13046 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13048 /* run all tests */
13049 for( i = 0; i < ARRAY_SIZE(testcases); ++i)
13051 struct testdata act = testcases[i];
13052 decl[0].Stream = act.strVertex;
13053 decl[1].Stream = act.strColor;
13054 decl[2].Stream = act.strInstance;
13055 /* create VertexDeclarations */
13056 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
13057 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13059 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
13060 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13062 hr = IDirect3DDevice9_BeginScene(device);
13063 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
13065 hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
13066 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
13068 /* If stream 0 is unused, set the stream frequency regardless to show
13069 * that the number if instances is read from it. */
13070 if (act.strVertex && act.strColor && act.strInstance)
13072 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0,
13073 D3DSTREAMSOURCE_INDEXEDDATA | act.explicit_zero_freq);
13074 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#lx.\n", hr);
13077 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex,
13078 (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
13079 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#lx.\n", hr);
13080 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
13081 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#lx.\n", hr);
13083 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor,
13084 (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
13085 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#lx.\n", hr);
13086 hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
13087 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#lx.\n", hr);
13089 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance,
13090 (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
13091 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#lx.\n", hr);
13092 hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
13093 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#lx.\n", hr);
13095 /* Non-indexed draw test. Only a single instance should be drawn. */
13096 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLELIST, 0, 1);
13097 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
13099 hr = IDirect3DDevice9_EndScene(device);
13100 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
13102 /* Check that only single triangle instance has beed drawn with non-indexed draw. */
13103 color = getPixelColor(device, 200, 340);
13104 ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
13105 color = getPixelColor(device, 400, 340);
13106 ok(color == 0x00ffffff, "has color 0x%08x, expected 0x%08x (case %i)\n", color, 0x00ffffff, i);
13107 color = getPixelColor(device, 400, 180);
13108 ok(color == 0x00ffffff, "has color 0x%08x, expected 0x%08x (case %i)\n", color, 0x00ffffff, i);
13109 color = getPixelColor(device, 200, 180);
13110 ok(color == 0x00ffffff, "has color 0x%08x, expected 0x%08x (case %i)\n", color, 0x00ffffff, i);
13112 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13113 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13115 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
13116 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13118 hr = IDirect3DDevice9_BeginScene(device);
13119 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
13121 /* Indexed draw test. */
13122 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
13123 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
13124 hr = IDirect3DDevice9_EndScene(device);
13125 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
13127 /* set all StreamSource && StreamSourceFreq back to default */
13128 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
13129 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#lx.\n", hr);
13130 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
13131 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#lx.\n", hr);
13132 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
13133 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#lx.\n", hr);
13134 hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
13135 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#lx.\n", hr);
13136 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
13137 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#lx.\n", hr);
13138 hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
13139 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#lx.\n", hr);
13141 hr = IDirect3DVertexDeclaration9_Release(pDecl);
13142 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13144 color = getPixelColor(device, 160, 360);
13145 ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
13146 color = getPixelColor(device, 480, 360);
13147 ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
13148 color = getPixelColor(device, 480, 120);
13149 ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
13150 color = getPixelColor(device, 160, 120);
13151 ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
13153 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13154 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13157 out:
13158 if(vb) IDirect3DVertexBuffer9_Release(vb);
13159 if(vb2)IDirect3DVertexBuffer9_Release(vb2);
13160 if(vb3)IDirect3DVertexBuffer9_Release(vb3);
13161 if(ib)IDirect3DIndexBuffer9_Release(ib);
13162 if(shader)IDirect3DVertexShader9_Release(shader);
13163 refcount = IDirect3DDevice9_Release(device);
13164 ok(!refcount, "Device has %lu references left.\n", refcount);
13165 done:
13166 IDirect3D9_Release(d3d);
13167 DestroyWindow(window);
13170 static void np2_stretch_rect_test(void)
13172 IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
13173 IDirect3DTexture9 *dsttex = NULL;
13174 IDirect3DDevice9 *device;
13175 unsigned int color;
13176 IDirect3D9 *d3d;
13177 ULONG refcount;
13178 HWND window;
13179 HRESULT hr;
13181 static const D3DRECT r1 = {0, 0, 50, 50 };
13182 static const D3DRECT r2 = {50, 0, 100, 50 };
13183 static const D3DRECT r3 = {50, 50, 100, 100};
13184 static const D3DRECT r4 = {0, 50, 50, 100};
13185 static const float quad[] =
13187 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
13188 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
13189 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
13190 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
13193 window = create_window();
13194 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13195 ok(!!d3d, "Failed to create a D3D object.\n");
13196 if (!(device = create_device(d3d, window, window, TRUE)))
13198 skip("Failed to create a D3D device, skipping tests.\n");
13199 goto done;
13202 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
13203 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13205 hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
13206 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
13207 hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
13208 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
13210 if(!src || !dsttex) {
13211 skip("One or more test resources could not be created\n");
13212 goto cleanup;
13215 hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
13216 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13218 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
13219 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13221 /* Clear the StretchRect destination for debugging */
13222 hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
13223 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13224 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
13225 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13227 hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
13228 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13230 hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
13231 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13232 hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
13233 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13234 hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
13235 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13236 hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
13237 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13239 /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
13240 * the target -> texture GL blit path
13242 hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
13243 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13244 IDirect3DSurface9_Release(dst);
13246 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
13247 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13249 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
13250 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13251 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
13252 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13253 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
13254 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13255 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
13256 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13258 hr = IDirect3DDevice9_BeginScene(device);
13259 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
13260 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
13261 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
13262 hr = IDirect3DDevice9_EndScene(device);
13263 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
13265 color = getPixelColor(device, 160, 360);
13266 ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
13267 color = getPixelColor(device, 480, 360);
13268 ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
13269 color = getPixelColor(device, 480, 120);
13270 ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
13271 color = getPixelColor(device, 160, 120);
13272 ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
13273 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13274 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13276 cleanup:
13277 if(src) IDirect3DSurface9_Release(src);
13278 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
13279 if(dsttex) IDirect3DTexture9_Release(dsttex);
13280 refcount = IDirect3DDevice9_Release(device);
13281 ok(!refcount, "Device has %lu references left.\n", refcount);
13282 done:
13283 IDirect3D9_Release(d3d);
13284 DestroyWindow(window);
13287 static void texop_test(void)
13289 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
13290 IDirect3DTexture9 *texture = NULL;
13291 D3DLOCKED_RECT locked_rect;
13292 IDirect3DDevice9 *device;
13293 unsigned int color, i;
13294 IDirect3D9 *d3d;
13295 ULONG refcount;
13296 D3DCAPS9 caps;
13297 HWND window;
13298 HRESULT hr;
13300 static const struct {
13301 float x, y, z;
13302 float s, t;
13303 D3DCOLOR diffuse;
13304 } quad[] = {
13305 {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
13306 {-1.0f, 1.0f, 0.1f, -1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
13307 { 1.0f, -1.0f, 0.1f, 1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
13308 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
13311 static const D3DVERTEXELEMENT9 decl_elements[] = {
13312 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
13313 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
13314 {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
13315 D3DDECL_END()
13318 static const struct {
13319 D3DTEXTUREOP op;
13320 const char *name;
13321 DWORD caps_flag;
13322 unsigned int result;
13323 } test_data[] = {
13324 {D3DTOP_SELECTARG1, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
13325 {D3DTOP_SELECTARG2, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
13326 {D3DTOP_MODULATE, "MODULATE", D3DTEXOPCAPS_MODULATE, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
13327 {D3DTOP_MODULATE2X, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
13328 {D3DTOP_MODULATE4X, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
13329 {D3DTOP_ADD, "ADD", D3DTEXOPCAPS_ADD, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
13330 {D3DTOP_ADDSIGNED, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
13331 {D3DTOP_ADDSIGNED2X, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
13332 {D3DTOP_SUBTRACT, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
13333 {D3DTOP_ADDSMOOTH, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
13334 {D3DTOP_BLENDDIFFUSEALPHA, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
13335 {D3DTOP_BLENDTEXTUREALPHA, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
13336 {D3DTOP_BLENDFACTORALPHA, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
13337 {D3DTOP_BLENDTEXTUREALPHAPM, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
13338 {D3DTOP_BLENDCURRENTALPHA, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
13339 {D3DTOP_MODULATEALPHA_ADDCOLOR, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
13340 {D3DTOP_MODULATECOLOR_ADDALPHA, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
13341 {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
13342 {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
13343 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
13344 {D3DTOP_DOTPRODUCT3, "DOTPRODUCT3", D3DTEXOPCAPS_DOTPRODUCT3, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
13345 {D3DTOP_MULTIPLYADD, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
13346 {D3DTOP_LERP, "LERP", D3DTEXOPCAPS_LERP, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
13349 window = create_window();
13350 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13351 ok(!!d3d, "Failed to create a D3D object.\n");
13352 if (!(device = create_device(d3d, window, window, TRUE)))
13354 skip("Failed to create a D3D device, skipping tests.\n");
13355 goto done;
13358 memset(&caps, 0, sizeof(caps));
13359 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13360 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13362 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
13363 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13364 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
13365 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13367 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
13368 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13369 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
13370 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13371 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
13372 hr = IDirect3DTexture9_UnlockRect(texture, 0);
13373 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13374 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
13375 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13377 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
13378 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13379 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
13380 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13381 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
13382 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13384 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
13385 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13387 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13388 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13389 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
13390 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13391 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
13392 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13394 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
13395 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13397 for (i = 0; i < ARRAY_SIZE(test_data); ++i)
13399 if (!(caps.TextureOpCaps & test_data[i].caps_flag))
13401 skip("tex operation %s not supported\n", test_data[i].name);
13402 continue;
13405 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
13406 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13408 hr = IDirect3DDevice9_BeginScene(device);
13409 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13411 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13412 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13414 hr = IDirect3DDevice9_EndScene(device);
13415 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13417 color = getPixelColor(device, 320, 240);
13418 ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
13419 test_data[i].name, color, test_data[i].result);
13421 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13422 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13425 IDirect3DTexture9_Release(texture);
13426 IDirect3DVertexDeclaration9_Release(vertex_declaration);
13427 refcount = IDirect3DDevice9_Release(device);
13428 ok(!refcount, "Device has %lu references left.\n", refcount);
13429 done:
13430 IDirect3D9_Release(d3d);
13431 DestroyWindow(window);
13434 static void yuv_color_test(void)
13436 HRESULT hr;
13437 IDirect3DSurface9 *surface, *target;
13438 D3DLOCKED_RECT lr;
13439 IDirect3D9 *d3d;
13440 D3DFORMAT skip_once = D3DFMT_UNKNOWN;
13441 IDirect3DDevice9 *device;
13442 unsigned int color, i;
13443 D3DSURFACE_DESC desc;
13444 ULONG refcount;
13445 HWND window;
13447 static const struct
13449 unsigned int in;
13450 D3DFORMAT format;
13451 const char *fmt_string;
13452 unsigned int left, right;
13454 test_data[] =
13456 {0x00000000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00008700, 0x00008700},
13457 {0xff000000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00008700, 0x004bff1c},
13458 {0x00ff0000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b30000, 0x00b30000},
13459 {0x0000ff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x004bff1c, 0x00008700},
13460 {0x000000ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x000030e1, 0x000030e1},
13461 {0xffff0000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b30000, 0x00ffd01c},
13462 {0xff00ff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x004bff1c, 0x004bff1c},
13463 {0xff0000ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x000030e1, 0x004bffff},
13464 {0x00ffff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ffd01c, 0x00b30000},
13465 {0x00ff00ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b300e1, 0x00b300e1},
13466 {0x0000ffff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x004bffff, 0x001030e1},
13467 {0xffffff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ffd01c, 0x00ffd01c},
13468 {0xffff00ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b300e1, 0x00ff79ff},
13469 {0xffffffff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ff79ff, 0x00ff79ff},
13470 {0x4cff4c54, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ff0000, 0x00ff0000},
13471 {0x00800080, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00000000, 0x00000000},
13472 {0xff80ff80, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ffffff, 0x00ffffff},
13473 {0x1c6b1cff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x000000fd, 0x000000fd},
13475 {0x00000000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00008700, 0x00008700},
13476 {0xff000000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b30000, 0x00b30000},
13477 {0x00ff0000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00008700, 0x004bff1c},
13478 {0x0000ff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x000030e1, 0x000030e1},
13479 {0x000000ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x004bff1c, 0x00008700},
13480 {0xffff0000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b30000, 0x00ffd01c},
13481 {0xff00ff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b300e1, 0x00b300e1},
13482 {0xff0000ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ffd01c, 0x00b30000},
13483 {0x00ffff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x000030e1, 0x004bffff},
13484 {0x00ff00ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x004bff1c, 0x004bff1c},
13485 {0x0000ffff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x004bffff, 0x000030e1},
13486 {0xffffff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b300e1, 0x00ff79ff},
13487 {0xffff00ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ffd01c, 0x00ffd01c},
13488 {0xffffffff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ff79ff, 0x00ff79ff},
13489 {0x4cff4c54, D3DFMT_YUY2, "D3DFMT_YUY2", 0x000b8b00, 0x00b6ffa3},
13490 {0x00800080, D3DFMT_YUY2, "D3DFMT_YUY2", 0x0000ff00, 0x0000ff00},
13491 {0xff80ff80, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ff00ff, 0x00ff00ff},
13492 {0x1c6b1cff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x006dff45, 0x0000d500},
13495 window = create_window();
13496 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13497 ok(!!d3d, "Failed to create a D3D object.\n");
13498 if (!(device = create_device(d3d, window, window, TRUE)))
13500 skip("Failed to create a D3D device, skipping tests.\n");
13501 goto done;
13504 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
13505 ok(SUCCEEDED(hr), "Failed to get render target, hr %#lx.\n", hr);
13506 hr = IDirect3DSurface9_GetDesc(target, &desc);
13507 ok(SUCCEEDED(hr), "Failed to get surface description, hr %#lx.\n", hr);
13509 for (i = 0; i < ARRAY_SIZE(test_data); i++)
13511 /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect.
13512 * Thus use StretchRect to draw the YUV surface onto the screen instead of drawPrimitive. */
13513 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
13514 D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, test_data[i].format)))
13516 if (skip_once != test_data[i].format)
13518 skip("%s is not supported.\n", test_data[i].fmt_string);
13519 skip_once = test_data[i].format;
13521 continue;
13523 if (FAILED(IDirect3D9_CheckDeviceFormatConversion(d3d, 0,
13524 D3DDEVTYPE_HAL, test_data[i].format, desc.Format)))
13526 if (skip_once != test_data[i].format)
13528 skip("Driver cannot blit %s surfaces.\n", test_data[i].fmt_string);
13529 skip_once = test_data[i].format;
13531 continue;
13534 /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1.
13535 * However, Nvidia Windows drivers have problems with 2x1 YUY2/UYVY surfaces, so use a 4x1 surface and
13536 * fill the second block with dummy data. If the surface has a size of 2x1, those drivers ignore the
13537 * second luminance value, resulting in an incorrect color in the right pixel. */
13538 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 4, 1, test_data[i].format,
13539 D3DPOOL_DEFAULT, &surface, NULL);
13540 ok(SUCCEEDED(hr), "Failed to create surface, hr %#lx.\n", hr);
13543 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
13544 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#lx.\n", hr);
13545 ((DWORD *)lr.pBits)[0] = test_data[i].in;
13546 ((DWORD *)lr.pBits)[1] = 0x00800080;
13547 hr = IDirect3DSurface9_UnlockRect(surface);
13548 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#lx.\n", hr);
13550 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 1.0f, 0);
13551 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
13552 hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
13553 ok(SUCCEEDED(hr), "Failed to draw surface onto backbuffer, hr %#lx.\n", hr);
13555 /* Some Windows drivers (mostly Nvidia, but also some VM drivers) insist on doing linear filtering
13556 * although we asked for point filtering. Be careful when reading the results and use the pixel
13557 * centers. In the future we may want to add tests for the filtered pixels as well.
13559 * Unfortunately different implementations(Windows-Nvidia and Mac-AMD tested) interpret some colors
13560 * vastly differently, so we need a max diff of 18. */
13561 color = getPixelColor(device, 1, 240);
13562 ok(color_match(color, test_data[i].left, 18),
13563 "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s.\n",
13564 test_data[i].in, color, test_data[i].left, test_data[i].fmt_string);
13565 color = getPixelColor(device, 318, 240);
13566 ok(color_match(color, test_data[i].right, 18),
13567 "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s.\n",
13568 test_data[i].in, color, test_data[i].right, test_data[i].fmt_string);
13569 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13570 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
13571 IDirect3DSurface9_Release(surface);
13574 IDirect3DSurface9_Release(target);
13575 refcount = IDirect3DDevice9_Release(device);
13576 ok(!refcount, "Device has %lu references left.\n", refcount);
13577 done:
13578 IDirect3D9_Release(d3d);
13579 DestroyWindow(window);
13582 static void yuv_layout_test(void)
13584 unsigned int color, ref_color, fmt, i, x, y;
13585 HRESULT hr;
13586 IDirect3DSurface9 *surface, *target;
13587 D3DFORMAT format;
13588 const char *fmt_string;
13589 D3DLOCKED_RECT lr;
13590 IDirect3D9 *d3d;
13591 BYTE *buf, *chroma_buf, *u_buf, *v_buf;
13592 UINT width = 20, height = 16;
13593 IDirect3DDevice9 *device;
13594 ULONG refcount;
13595 D3DCAPS9 caps;
13596 D3DSURFACE_DESC desc;
13597 HWND window;
13599 static const struct
13601 DWORD color1, color2;
13602 DWORD rgb1, rgb2;
13604 test_data[] =
13606 { 0x000000, 0xffffff, 0x00008800, 0x00ff7dff },
13607 { 0xff0000, 0x00ffff, 0x004aff14, 0x00b800ee },
13608 { 0x00ff00, 0xff00ff, 0x000024ee, 0x00ffe114 },
13609 { 0x0000ff, 0xffff00, 0x00b80000, 0x004affff },
13610 { 0xffff00, 0x0000ff, 0x004affff, 0x00b80000 },
13611 { 0xff00ff, 0x00ff00, 0x00ffe114, 0x000024ee },
13612 { 0x00ffff, 0xff0000, 0x00b800ee, 0x004aff14 },
13613 { 0xffffff, 0x000000, 0x00ff7dff, 0x00008800 },
13616 static const struct
13618 D3DFORMAT format;
13619 const char *str;
13621 formats[] =
13623 { D3DFMT_UYVY, "D3DFMT_UYVY", },
13624 { D3DFMT_YUY2, "D3DFMT_YUY2", },
13625 { MAKEFOURCC('Y','V','1','2'), "D3DFMT_YV12", },
13626 { MAKEFOURCC('N','V','1','2'), "D3DFMT_NV12", },
13629 window = create_window();
13630 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13631 ok(!!d3d, "Failed to create a D3D object.\n");
13632 if (!(device = create_device(d3d, window, window, TRUE)))
13634 skip("Failed to create a D3D device, skipping tests.\n");
13635 goto done;
13638 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13639 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#lx.\n", hr);
13640 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2
13641 && !(caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL))
13643 skip("No NP2 texture support, skipping YUV texture layout test.\n");
13644 IDirect3DDevice9_Release(device);
13645 goto done;
13648 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
13649 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
13650 hr = IDirect3DSurface9_GetDesc(target, &desc);
13651 ok(SUCCEEDED(hr), "Failed to get surface description, hr %#lx.\n", hr);
13653 for (fmt = 0; fmt < ARRAY_SIZE(formats); fmt++)
13655 format = formats[fmt].format;
13656 fmt_string = formats[fmt].str;
13658 /* Some (all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in
13659 * StretchRect. Thus use StretchRect to draw the YUV surface onto the screen instead
13660 * of drawPrimitive. */
13661 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
13662 D3DRTYPE_SURFACE, format) != D3D_OK)
13664 skip("%s is not supported.\n", fmt_string);
13665 continue;
13667 if (FAILED(IDirect3D9_CheckDeviceFormatConversion(d3d, 0,
13668 D3DDEVTYPE_HAL, format, desc.Format)))
13670 skip("Driver cannot blit %s surfaces.\n", fmt_string);
13671 continue;
13674 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, width, height, format, D3DPOOL_DEFAULT, &surface, NULL);
13675 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
13677 for (i = 0; i < ARRAY_SIZE(test_data); i++)
13679 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
13680 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
13681 buf = lr.pBits;
13682 chroma_buf = buf + lr.Pitch * height;
13683 if (format == MAKEFOURCC('Y','V','1','2'))
13685 v_buf = chroma_buf;
13686 u_buf = chroma_buf + height / 2 * lr.Pitch/2;
13688 /* Draw the top left quarter of the screen with color1, the rest with color2 */
13689 for (y = 0; y < height; y++)
13691 for (x = 0; x < width; x += 2)
13693 DWORD color = (x < width / 2 && y < height / 2) ? test_data[i].color1 : test_data[i].color2;
13694 BYTE Y = (color >> 16) & 0xff;
13695 BYTE U = (color >> 8) & 0xff;
13696 BYTE V = (color >> 0) & 0xff;
13697 if (format == D3DFMT_UYVY)
13699 buf[y * lr.Pitch + 2 * x + 0] = U;
13700 buf[y * lr.Pitch + 2 * x + 1] = Y;
13701 buf[y * lr.Pitch + 2 * x + 2] = V;
13702 buf[y * lr.Pitch + 2 * x + 3] = Y;
13704 else if (format == D3DFMT_YUY2)
13706 buf[y * lr.Pitch + 2 * x + 0] = Y;
13707 buf[y * lr.Pitch + 2 * x + 1] = U;
13708 buf[y * lr.Pitch + 2 * x + 2] = Y;
13709 buf[y * lr.Pitch + 2 * x + 3] = V;
13711 else if (format == MAKEFOURCC('Y','V','1','2'))
13713 buf[y * lr.Pitch + x + 0] = Y;
13714 buf[y * lr.Pitch + x + 1] = Y;
13715 u_buf[(y / 2) * (lr.Pitch / 2) + (x / 2)] = U;
13716 v_buf[(y / 2) * (lr.Pitch / 2) + (x / 2)] = V;
13718 else if (format == MAKEFOURCC('N','V','1','2'))
13720 buf[y * lr.Pitch + x + 0] = Y;
13721 buf[y * lr.Pitch + x + 1] = Y;
13722 chroma_buf[(y / 2) * lr.Pitch + 2 * (x / 2) + 0] = U;
13723 chroma_buf[(y / 2) * lr.Pitch + 2 * (x / 2) + 1] = V;
13727 hr = IDirect3DSurface9_UnlockRect(surface);
13728 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
13730 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 1.0f, 0);
13731 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
13732 hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
13733 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
13735 /* Some Windows drivers (mostly Nvidia, but also some VM drivers) insist on doing linear filtering
13736 * although we asked for point filtering. To prevent running into precision problems, read at points
13737 * with some margin within each quadrant.
13739 * Unfortunately different implementations(Windows-Nvidia and Mac-AMD tested) interpret some colors
13740 * vastly differently, so we need a max diff of 18. */
13741 for (y = 0; y < 4; y++)
13743 for (x = 0; x < 4; x++)
13745 UINT xcoord = (1 + 2 * x) * 640 / 8;
13746 UINT ycoord = (1 + 2 * y) * 480 / 8;
13747 ref_color = (y < 2 && x < 2) ? test_data[i].rgb1 : test_data[i].rgb2;
13748 color = getPixelColor(device, xcoord, ycoord);
13749 ok(color_match(color, ref_color, 18),
13750 "Format %s: Got color %#x for pixel (%d/%d)/(%d/%d), pixel %d %d, expected %#x.\n",
13751 fmt_string, color, x, 4, y, 4, xcoord, ycoord, ref_color);
13754 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13755 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13757 IDirect3DSurface9_Release(surface);
13760 IDirect3DSurface9_Release(target);
13761 refcount = IDirect3DDevice9_Release(device);
13762 ok(!refcount, "Device has %lu references left.\n", refcount);
13763 done:
13764 IDirect3D9_Release(d3d);
13765 DestroyWindow(window);
13768 static void texop_range_test(void)
13770 IDirect3DTexture9 *texture;
13771 D3DLOCKED_RECT locked_rect;
13772 IDirect3DDevice9 *device;
13773 unsigned int color;
13774 IDirect3D9 *d3d;
13775 ULONG refcount;
13776 D3DCAPS9 caps;
13777 HWND window;
13778 HRESULT hr;
13780 static const struct
13782 float x, y, z;
13783 D3DCOLOR diffuse;
13785 quad[] =
13787 {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
13788 {-1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
13789 { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
13790 { 1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
13793 window = create_window();
13794 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13795 ok(!!d3d, "Failed to create a D3D object.\n");
13796 if (!(device = create_device(d3d, window, window, TRUE)))
13798 skip("Failed to create a D3D device, skipping tests.\n");
13799 goto done;
13802 /* We need ADD and SUBTRACT operations */
13803 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13804 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13805 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD))
13807 skip("D3DTOP_ADD is not supported, skipping value range test.\n");
13808 IDirect3DDevice9_Release(device);
13809 goto done;
13811 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT))
13813 skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test.\n");
13814 IDirect3DDevice9_Release(device);
13815 goto done;
13818 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13819 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13820 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13821 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
13822 /* Stage 1: result = diffuse(=1.0) + diffuse
13823 * stage 2: result = result - tfactor(= 0.5)
13825 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
13826 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13827 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
13828 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13829 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
13830 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13831 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
13832 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13833 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
13834 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13835 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
13836 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13837 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
13838 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13840 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
13841 ok(SUCCEEDED(hr), "Failed to clear device, hr %#lx.\n\n", hr);
13842 hr = IDirect3DDevice9_BeginScene(device);
13843 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13844 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13845 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13846 hr = IDirect3DDevice9_EndScene(device);
13847 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13849 color = getPixelColor(device, 320, 240);
13850 ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
13851 color);
13852 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13853 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13855 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
13856 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13857 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
13858 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13859 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
13860 hr = IDirect3DTexture9_UnlockRect(texture, 0);
13861 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13862 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
13863 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13865 /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
13866 * stage 2: result = result + diffuse(1.0)
13868 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
13869 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13870 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
13871 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13872 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
13873 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13874 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
13875 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13876 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
13877 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13878 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
13879 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13880 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
13881 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13883 hr = IDirect3DDevice9_BeginScene(device);
13884 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13885 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13886 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13887 hr = IDirect3DDevice9_EndScene(device);
13888 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13890 color = getPixelColor(device, 320, 240);
13891 ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
13892 color);
13893 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13894 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13896 IDirect3DTexture9_Release(texture);
13897 refcount = IDirect3DDevice9_Release(device);
13898 ok(!refcount, "Device has %lu references left.\n", refcount);
13899 done:
13900 IDirect3D9_Release(d3d);
13901 DestroyWindow(window);
13904 static void alphareplicate_test(void)
13906 IDirect3DDevice9 *device;
13907 unsigned int color;
13908 IDirect3D9 *d3d;
13909 ULONG refcount;
13910 HWND window;
13911 HRESULT hr;
13913 static const struct
13915 struct vec3 position;
13916 DWORD diffuse;
13918 quad[] =
13920 {{-1.0f, -1.0f, 0.1f}, 0x80ff00ff},
13921 {{-1.0f, 1.0f, 0.1f}, 0x80ff00ff},
13922 {{ 1.0f, -1.0f, 0.1f}, 0x80ff00ff},
13923 {{ 1.0f, 1.0f, 0.1f}, 0x80ff00ff},
13926 window = create_window();
13927 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13928 ok(!!d3d, "Failed to create a D3D object.\n");
13929 if (!(device = create_device(d3d, window, window, TRUE)))
13931 skip("Failed to create a D3D device, skipping tests.\n");
13932 goto done;
13935 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
13936 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13938 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13939 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13941 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
13942 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13943 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
13944 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13946 hr = IDirect3DDevice9_BeginScene(device);
13947 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
13948 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13949 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
13950 hr = IDirect3DDevice9_EndScene(device);
13951 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
13953 color = getPixelColor(device, 320, 240);
13954 ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
13955 color);
13956 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13957 ok(hr == S_OK, "Got hr %#lx.\n", hr);
13959 refcount = IDirect3DDevice9_Release(device);
13960 ok(!refcount, "Device has %lu references left.\n", refcount);
13961 done:
13962 IDirect3D9_Release(d3d);
13963 DestroyWindow(window);
13966 static void dp3_alpha_test(void)
13968 IDirect3DDevice9 *device;
13969 unsigned int color;
13970 IDirect3D9 *d3d;
13971 ULONG refcount;
13972 D3DCAPS9 caps;
13973 HWND window;
13974 HRESULT hr;
13976 static const struct
13978 struct vec3 position;
13979 DWORD diffuse;
13981 quad[] =
13983 {{-1.0f, -1.0f, 0.1f}, 0x408080c0},
13984 {{-1.0f, 1.0f, 0.1f}, 0x408080c0},
13985 {{ 1.0f, -1.0f, 0.1f}, 0x408080c0},
13986 {{ 1.0f, 1.0f, 0.1f}, 0x408080c0},
13989 window = create_window();
13990 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13991 ok(!!d3d, "Failed to create a D3D object.\n");
13992 if (!(device = create_device(d3d, window, window, TRUE)))
13994 skip("Failed to create a D3D device, skipping tests.\n");
13995 goto done;
13998 memset(&caps, 0, sizeof(caps));
13999 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
14000 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
14001 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3))
14003 skip("D3DTOP_DOTPRODUCT3 not supported\n");
14004 IDirect3DDevice9_Release(device);
14005 goto done;
14008 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
14009 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14011 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
14012 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14014 /* dp3_x4 r0, diffuse_bias, tfactor_bias
14015 * mov r0.a, diffuse.a
14016 * mov r0, r0.a
14018 * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
14019 * 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
14020 * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
14022 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
14023 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14024 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
14025 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14026 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
14027 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14028 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
14029 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14030 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
14031 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14032 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
14033 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14034 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
14035 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14036 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
14037 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14038 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
14039 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14040 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
14041 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
14043 hr = IDirect3DDevice9_BeginScene(device);
14044 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
14045 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14046 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
14047 hr = IDirect3DDevice9_EndScene(device);
14048 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
14050 color = getPixelColor(device, 320, 240);
14051 ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
14052 color);
14053 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14054 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14056 refcount = IDirect3DDevice9_Release(device);
14057 ok(!refcount, "Device has %lu references left.\n", refcount);
14058 done:
14059 IDirect3D9_Release(d3d);
14060 DestroyWindow(window);
14063 static void zwriteenable_test(void)
14065 IDirect3DDevice9 *device;
14066 unsigned int color;
14067 IDirect3D9 *d3d;
14068 ULONG refcount;
14069 HWND window;
14070 HRESULT hr;
14072 static const struct
14074 struct vec3 position;
14075 DWORD diffuse;
14077 quad1[] =
14079 {{-1.0f, -1.0f, 0.1f}, 0x00ff0000},
14080 {{-1.0f, 1.0f, 0.1f}, 0x00ff0000},
14081 {{ 1.0f, -1.0f, 0.1f}, 0x00ff0000},
14082 {{ 1.0f, 1.0f, 0.1f}, 0x00ff0000},
14084 quad2[] =
14086 {{-1.0f, -1.0f, 0.9f}, 0x0000ff00},
14087 {{-1.0f, 1.0f, 0.9f}, 0x0000ff00},
14088 {{ 1.0f, -1.0f, 0.9f}, 0x0000ff00},
14089 {{ 1.0f, 1.0f, 0.9f}, 0x0000ff00},
14092 window = create_window();
14093 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14094 ok(!!d3d, "Failed to create a D3D object.\n");
14095 if (!(device = create_device(d3d, window, window, TRUE)))
14097 skip("Failed to create a D3D device, skipping tests.\n");
14098 goto done;
14101 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
14102 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14104 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
14105 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14106 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
14107 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14108 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
14109 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14110 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
14111 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14112 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
14113 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
14115 hr = IDirect3DDevice9_BeginScene(device);
14116 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
14117 /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1,
14118 * zenable = D3DZB_FALSE, zwriteenable = TRUE. The red color is written
14119 * because the z test is disabled. The question is whether the z = 0.1
14120 * values are written into the Z buffer. After the draw, set
14121 * zenable = TRUE and draw a green quad at z = 0.9. If the values are
14122 * written, the z test will fail(0.9 > 0.1) and the red color remains. If
14123 * the values are not written, the z test succeeds(0.9 < 1.0) and the
14124 * green color is written. It turns out that the screen is green, so
14125 * zenable = D3DZB_FALSE and zwriteenable = TRUE does NOT write to the z
14126 * buffer. */
14127 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
14128 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
14129 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
14130 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
14131 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
14132 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
14133 hr = IDirect3DDevice9_EndScene(device);
14134 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
14136 color = getPixelColor(device, 320, 240);
14137 ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
14138 color);
14139 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14140 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14142 refcount = IDirect3DDevice9_Release(device);
14143 ok(!refcount, "Device has %lu references left.\n", refcount);
14144 done:
14145 IDirect3D9_Release(d3d);
14146 DestroyWindow(window);
14149 static void alphatest_test(void)
14151 #define ALPHATEST_PASSED 0x0000ff00
14152 #define ALPHATEST_FAILED 0x00ff0000
14153 IDirect3DDevice9 *device;
14154 unsigned int color, i, j;
14155 IDirect3D9 *d3d;
14156 ULONG refcount;
14157 D3DCAPS9 caps;
14158 DWORD value;
14159 HWND window;
14160 HRESULT hr;
14162 static const struct
14164 D3DCMPFUNC func;
14165 unsigned int color_less;
14166 unsigned int color_equal;
14167 unsigned int color_greater;
14169 testdata[] =
14171 {D3DCMP_NEVER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED},
14172 {D3DCMP_LESS, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED},
14173 {D3DCMP_EQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED},
14174 {D3DCMP_LESSEQUAL, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED},
14175 {D3DCMP_GREATER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED},
14176 {D3DCMP_NOTEQUAL, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED},
14177 {D3DCMP_GREATEREQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED},
14178 {D3DCMP_ALWAYS, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED},
14180 static const struct
14182 struct vec3 position;
14183 DWORD diffuse;
14185 quad[] =
14187 {{-1.0f, -1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
14188 {{-1.0f, 1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
14189 {{ 1.0f, -1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
14190 {{ 1.0f, 1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
14193 window = create_window();
14194 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14195 ok(!!d3d, "Failed to create a D3D object.\n");
14196 if (!(device = create_device(d3d, window, window, TRUE)))
14198 skip("Failed to create a D3D device, skipping tests.\n");
14199 goto done;
14202 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
14203 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
14205 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
14206 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
14207 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
14208 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14209 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
14210 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14212 for (j = 0; j < 2; ++j)
14214 if (j == 1)
14216 /* Try a pixel shader instead of fixed function. The wined3d code
14217 * may emulate the alpha test either for performance reasons
14218 * (floating point RTs) or to work around driver bugs (GeForce
14219 * 7x00 cards on MacOS). There may be a different codepath for ffp
14220 * and shader in this case, and the test should cover both. */
14221 IDirect3DPixelShader9 *ps;
14222 static const DWORD shader_code[] =
14224 0xffff0101, /* ps_1_1 */
14225 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
14226 0x0000ffff /* end */
14228 memset(&caps, 0, sizeof(caps));
14229 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
14230 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14231 if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
14232 break;
14235 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
14236 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14237 hr = IDirect3DDevice9_SetPixelShader(device, ps);
14238 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14239 IDirect3DPixelShader9_Release(ps);
14242 for(i = 0; i < ARRAY_SIZE(testdata); i++)
14244 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
14245 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14247 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
14248 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14249 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
14250 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14251 hr = IDirect3DDevice9_BeginScene(device);
14252 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
14253 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14254 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
14255 hr = IDirect3DDevice9_EndScene(device);
14256 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
14257 color = getPixelColor(device, 320, 240);
14258 ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
14259 color, testdata[i].color_less, testdata[i].func);
14260 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14261 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14263 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
14264 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14265 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
14266 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14267 hr = IDirect3DDevice9_BeginScene(device);
14268 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
14269 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14270 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
14271 hr = IDirect3DDevice9_EndScene(device);
14272 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
14273 color = getPixelColor(device, 320, 240);
14274 ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
14275 color, testdata[i].color_equal, testdata[i].func);
14276 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14277 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14279 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
14280 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14281 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
14282 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14283 hr = IDirect3DDevice9_BeginScene(device);
14284 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
14285 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14286 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
14287 hr = IDirect3DDevice9_EndScene(device);
14288 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
14289 color = getPixelColor(device, 320, 240);
14290 ok(color_match(color, testdata[i].color_greater, 1),
14291 "Alphatest failed, color 0x%08x, expected 0x%08x, alpha > ref, func %u.\n",
14292 color, testdata[i].color_greater, testdata[i].func);
14293 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14294 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed, hr %#lx.\n", hr);
14296 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0f, 0);
14297 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr %#lx.\n", hr);
14298 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0xff70);
14299 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr %#lx.\n", hr);
14300 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_ALPHAREF, &value);
14301 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr %#lx.\n", hr);
14302 ok(value == 0xff70, "Unexpected D3DRS_ALPHAREF value %#lx.\n", value);
14303 hr = IDirect3DDevice9_BeginScene(device);
14304 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr %#lx.\n", hr);
14305 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14306 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr %#lx.\n", hr);
14307 hr = IDirect3DDevice9_EndScene(device);
14308 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr %#lx.\n", hr);
14309 color = getPixelColor(device, 320, 240);
14310 ok(color_match(color, testdata[i].color_greater, 1),
14311 "Alphatest failed, color 0x%08x, expected 0x%08x, alpha > ref, func %u.\n",
14312 color, testdata[i].color_greater, testdata[i].func);
14313 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14314 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed, hr %#lx.\n", hr);
14319 refcount = IDirect3DDevice9_Release(device);
14320 ok(!refcount, "Device has %lu references left.\n", refcount);
14321 done:
14322 IDirect3D9_Release(d3d);
14323 DestroyWindow(window);
14326 static void sincos_test(void)
14328 IDirect3DVertexShader9 *sin_shader, *cos_shader;
14329 IDirect3DDevice9 *device;
14330 struct vec3 data[1280];
14331 IDirect3D9 *d3d;
14332 unsigned int i;
14333 ULONG refcount;
14334 D3DCAPS9 caps;
14335 HWND window;
14336 HRESULT hr;
14338 static const DWORD sin_shader_code[] =
14340 0xfffe0200, /* vs_2_0 */
14341 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
14342 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
14343 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
14344 0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.y, r1.x, c0, c1 */
14345 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
14346 0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002, /* mul oPos.y, r0.y, c2.w */
14347 0x02000001, 0xd00f0000, 0xa0a60002, /* mov oD0, c2.zyzz */
14348 0x0000ffff /* end */
14350 static const DWORD cos_shader_code[] =
14352 0xfffe0200, /* vs_2_0 */
14353 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
14354 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
14355 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
14356 0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.x, r1.x, c0, c1 */
14357 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
14358 0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002, /* mul oPos.y, r0.x, c2.w */
14359 0x02000001, 0xd00f0000, 0xa0a90002, /* mov oD0, c2.yzzz */
14360 0x0000ffff /* end */
14362 static const float sincosc1[4] = {D3DSINCOSCONST1};
14363 static const float sincosc2[4] = {D3DSINCOSCONST2};
14365 window = create_window();
14366 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14367 ok(!!d3d, "Failed to create a D3D object.\n");
14368 if (!(device = create_device(d3d, window, window, TRUE)))
14370 skip("Failed to create a D3D device, skipping tests.\n");
14371 goto done;
14374 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
14375 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
14376 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
14378 skip("No vs_2_0 support, skipping tests.\n");
14379 IDirect3DDevice9_Release(device);
14380 goto done;
14383 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
14384 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14386 hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
14387 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14388 hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
14389 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14390 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
14391 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14392 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
14393 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14394 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
14395 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14397 /* Generate a point from -1 to 1 every 0.5 pixels */
14398 for(i = 0; i < 1280; i++) {
14399 data[i].x = (-640.0 + i) / 640.0;
14400 data[i].y = 0.0;
14401 data[i].z = 0.1;
14404 hr = IDirect3DDevice9_BeginScene(device);
14405 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
14407 hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
14408 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
14409 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
14410 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
14412 hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
14413 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
14414 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
14415 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
14417 hr = IDirect3DDevice9_EndScene(device);
14418 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
14420 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14421 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14422 /* TODO: Find a way to properly validate the lines. Precision issues make this a kinda nasty task */
14424 IDirect3DVertexShader9_Release(sin_shader);
14425 IDirect3DVertexShader9_Release(cos_shader);
14426 refcount = IDirect3DDevice9_Release(device);
14427 ok(!refcount, "Device has %lu references left.\n", refcount);
14428 done:
14429 IDirect3D9_Release(d3d);
14430 DestroyWindow(window);
14433 static void loop_index_test(void)
14435 IDirect3DVertexShader9 *shader;
14436 IDirect3DDevice9 *device;
14437 unsigned int color;
14438 IDirect3D9 *d3d;
14439 float values[4];
14440 ULONG refcount;
14441 D3DCAPS9 caps;
14442 HWND window;
14443 HRESULT hr;
14445 static const DWORD shader_code[] =
14447 0xfffe0200, /* vs_2_0 */
14448 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
14449 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
14450 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
14451 0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1] */
14452 0x0000001d, /* endloop */
14453 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
14454 0x02000001, 0xd00f0000, 0x80e40000, /* mov oD0, r0 */
14455 0x0000ffff /* END */
14457 static const float quad[] =
14459 -1.0f, -1.0f, 0.1f,
14460 -1.0f, 1.0f, 0.1f,
14461 1.0f, -1.0f, 0.1f,
14462 1.0f, 1.0f, 0.1f,
14464 static const float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
14465 static const float one[4] = {1.0f, 1.0f, 1.0f, 1.0f};
14466 static const int i0[4] = {2, 10, -3, 0};
14468 window = create_window();
14469 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14470 ok(!!d3d, "Failed to create a D3D object.\n");
14471 if (!(device = create_device(d3d, window, window, TRUE)))
14473 skip("Failed to create a D3D device, skipping tests.\n");
14474 goto done;
14477 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
14478 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
14479 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
14481 skip("No vs_2_0 support, skipping tests.\n");
14482 IDirect3DDevice9_Release(device);
14483 goto done;
14486 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
14487 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14488 hr = IDirect3DDevice9_SetVertexShader(device, shader);
14489 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14490 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
14491 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14492 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
14493 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14495 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
14496 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14497 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
14498 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14499 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
14500 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14501 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
14502 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14503 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
14504 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14505 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
14506 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14507 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
14508 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14509 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
14510 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14511 values[0] = 1.0;
14512 values[1] = 1.0;
14513 values[2] = 0.0;
14514 values[3] = 0.0;
14515 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
14516 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14517 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
14518 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14519 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
14520 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14521 values[0] = -1.0;
14522 values[1] = 0.0;
14523 values[2] = 0.0;
14524 values[3] = 0.0;
14525 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
14526 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14527 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
14528 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14529 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
14530 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14531 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
14532 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14533 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
14534 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14536 hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
14537 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14539 hr = IDirect3DDevice9_BeginScene(device);
14540 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
14541 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
14542 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
14543 hr = IDirect3DDevice9_EndScene(device);
14544 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
14545 color = getPixelColor(device, 320, 240);
14546 ok(color_match(color, 0x0000ff00, 1),
14547 "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
14548 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14549 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14551 IDirect3DVertexShader9_Release(shader);
14552 refcount = IDirect3DDevice9_Release(device);
14553 ok(!refcount, "Device has %lu references left.\n", refcount);
14554 done:
14555 IDirect3D9_Release(d3d);
14556 DestroyWindow(window);
14559 static void sgn_test(void)
14561 IDirect3DVertexShader9 *shader;
14562 IDirect3DDevice9 *device;
14563 unsigned int color;
14564 IDirect3D9 *d3d;
14565 ULONG refcount;
14566 D3DCAPS9 caps;
14567 HWND window;
14568 HRESULT hr;
14570 static const DWORD shader_code[] =
14572 0xfffe0200, /* vs_2_0 */
14573 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position o0 */
14574 0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
14575 0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0 */
14576 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
14577 0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002, /* sgn r0, c0, r1, r2 */
14578 0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001, /* add oD0, r0, c1 */
14579 0x0000ffff /* end */
14581 static const float quad[] =
14583 -1.0f, -1.0f, 0.1f,
14584 -1.0f, 1.0f, 0.1f,
14585 1.0f, -1.0f, 0.1f,
14586 1.0f, 1.0f, 0.1f,
14589 window = create_window();
14590 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14591 ok(!!d3d, "Failed to create a D3D object.\n");
14592 if (!(device = create_device(d3d, window, window, TRUE)))
14594 skip("Failed to create a D3D device, skipping tests.\n");
14595 goto done;
14598 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
14599 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
14600 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
14602 skip("No vs_2_0 support, skipping tests.\n");
14603 IDirect3DDevice9_Release(device);
14604 goto done;
14607 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
14608 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14609 hr = IDirect3DDevice9_SetVertexShader(device, shader);
14610 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14611 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
14612 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14613 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
14614 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14616 hr = IDirect3DDevice9_BeginScene(device);
14617 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
14618 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
14619 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
14620 hr = IDirect3DDevice9_EndScene(device);
14621 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
14622 color = getPixelColor(device, 320, 240);
14623 ok(color_match(color, 0x008000ff, 1),
14624 "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
14625 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14626 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14628 IDirect3DVertexShader9_Release(shader);
14629 refcount = IDirect3DDevice9_Release(device);
14630 ok(!refcount, "Device has %lu references left.\n", refcount);
14631 done:
14632 IDirect3D9_Release(d3d);
14633 DestroyWindow(window);
14636 static void test_viewport(void)
14638 static const struct
14640 D3DVIEWPORT9 vp;
14641 float expected_z;
14642 RECT expected_rect;
14643 const char *message;
14645 tests[] =
14647 {{ 0, 0, 640, 480}, 0.001f, { 0, 120, 479, 359}, "Viewport (0, 0) - (640, 480)"},
14648 {{ 0, 0, 640, 480, 0.5f, 0.0f}, 0.501f,
14649 { 0, 120, 479, 359}, "Viewport (0, 0, 0.5) - (640, 480, 0.0)"},
14650 {{ 0, 0, 320, 240}, 0.001f, { 0, 60, 239, 179}, "Viewport (0, 0) - (320, 240)"},
14651 {{ 0, 0, 1280, 960}, 0.001f, { 0, 240, 639, 479}, "Viewport (0, 0) - (1280, 960)"},
14652 {{ 0, 0, 2000, 1600}, 0.001f, { 0, 400, 639, 479}, "Viewport (0, 0) - (2000, 1600)"},
14653 {{100, 100, 640, 480}, 0.001f, {100, 220, 579, 459}, "Viewport (100, 100) - (640, 480)"},
14654 {{ 0, 0, 8192, 8192}, 0.001f, {-10, -10, -10, -10}, "Viewport (0, 0) - (8192, 8192)"},
14655 /* AMD HD 2600 on XP draws nothing visible for this one. */
14656 /* {{ 0, 0, 8192, 480}, {-10, -10, -1, -1}, "(0, 0) - (8192, 480) viewport"}, */
14658 static const struct vec3 quad[] =
14660 {-1.5f, -0.5f, 1.0f},
14661 {-1.5f, 0.5f, 1.0f},
14662 { 0.5f, -0.5f, 1.0f},
14663 { 0.5f, 0.5f, 1.0f},
14665 IDirect3DSurface9 *backbuffer;
14666 const float z_eps = 0.0001;
14667 struct surface_readback rb;
14668 IDirect3DDevice9 *device;
14669 BOOL draw_succeeded;
14670 IDirect3D9 *d3d;
14671 unsigned int i;
14672 ULONG refcount;
14673 HWND window;
14674 HRESULT hr;
14676 window = create_window();
14677 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14678 ok(!!d3d, "Failed to create a D3D object.\n");
14679 if (!(device = create_device(d3d, window, window, TRUE)))
14681 skip("Failed to create a D3D device, skipping tests.\n");
14682 goto done;
14685 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
14686 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14688 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
14689 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14690 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
14691 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14693 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
14694 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14696 /* This crashes on Windows. */
14697 if (0)
14698 hr = IDirect3DDevice9_SetViewport(device, NULL);
14700 for (i = 0; i < ARRAY_SIZE(tests); ++i)
14702 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000,
14703 tests[i].expected_z - z_eps, 0);
14704 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14706 hr = IDirect3DDevice9_SetViewport(device, &tests[i].vp);
14707 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14709 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
14710 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14712 hr = IDirect3DDevice9_BeginScene(device);
14713 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14714 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
14715 ok(hr == D3D_OK || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#lx.\n", hr);
14716 draw_succeeded = hr == D3D_OK;
14717 hr = IDirect3DDevice9_EndScene(device);
14718 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14720 if (!draw_succeeded)
14721 continue;
14723 get_rt_readback(backbuffer, &rb);
14724 check_rect(&rb, tests[i].expected_rect, tests[i].message);
14725 release_surface_readback(&rb);
14727 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000,
14728 tests[i].expected_z + z_eps, 0);
14729 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14730 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
14731 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14733 hr = IDirect3DDevice9_BeginScene(device);
14734 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14735 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
14736 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14737 hr = IDirect3DDevice9_EndScene(device);
14738 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
14740 get_rt_readback(backbuffer, &rb);
14741 check_rect(&rb, tests[i].expected_rect, tests[i].message);
14742 release_surface_readback(&rb);
14745 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14746 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
14748 IDirect3DSurface9_Release(backbuffer);
14749 refcount = IDirect3DDevice9_Release(device);
14750 ok(!refcount, "Device has %lu references left.\n", refcount);
14751 done:
14752 IDirect3D9_Release(d3d);
14753 DestroyWindow(window);
14756 /* This test tests depth clamping / clipping behaviour:
14757 * - With software vertex processing, depth values are clamped to the
14758 * minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
14759 * when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
14760 * same as regular vertices here.
14761 * - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
14762 * Normal vertices are always clipped. Pretransformed vertices are
14763 * clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
14764 * - The viewport's MinZ/MaxZ is irrelevant for this.
14766 static void depth_clamp_test(void)
14768 IDirect3DDevice9 *device;
14769 unsigned int color;
14770 D3DVIEWPORT9 vp;
14771 IDirect3D9 *d3d;
14772 ULONG refcount;
14773 D3DCAPS9 caps;
14774 HWND window;
14775 HRESULT hr;
14777 static const struct
14779 struct vec4 position;
14780 DWORD diffuse;
14782 quad1[] =
14784 {{ 0.0f, 0.0f, 5.0f, 1.0f}, 0xff002b7f},
14785 {{640.0f, 0.0f, 5.0f, 1.0f}, 0xff002b7f},
14786 {{ 0.0f, 480.0f, 5.0f, 1.0f}, 0xff002b7f},
14787 {{640.0f, 480.0f, 5.0f, 1.0f}, 0xff002b7f},
14789 quad2[] =
14791 {{ 0.0f, 300.0f, 10.0f, 1.0f}, 0xfff9e814},
14792 {{640.0f, 300.0f, 10.0f, 1.0f}, 0xfff9e814},
14793 {{ 0.0f, 360.0f, 10.0f, 1.0f}, 0xfff9e814},
14794 {{640.0f, 360.0f, 10.0f, 1.0f}, 0xfff9e814},
14796 quad3[] =
14798 {{112.0f, 108.0f, 5.0f, 1.0f}, 0xffffffff},
14799 {{208.0f, 108.0f, 5.0f, 1.0f}, 0xffffffff},
14800 {{112.0f, 204.0f, 5.0f, 1.0f}, 0xffffffff},
14801 {{208.0f, 204.0f, 5.0f, 1.0f}, 0xffffffff},
14803 quad4[] =
14805 {{ 42.0f, 41.0f, 10.0f, 1.0f}, 0xffffffff},
14806 {{112.0f, 41.0f, 10.0f, 1.0f}, 0xffffffff},
14807 {{ 42.0f, 108.0f, 10.0f, 1.0f}, 0xffffffff},
14808 {{112.0f, 108.0f, 10.0f, 1.0f}, 0xffffffff},
14810 static const struct
14812 struct vec3 position;
14813 DWORD diffuse;
14815 quad5[] =
14817 {{-0.5f, 0.5f, 10.0f}, 0xff14f914},
14818 {{ 0.5f, 0.5f, 10.0f}, 0xff14f914},
14819 {{-0.5f, -0.5f, 10.0f}, 0xff14f914},
14820 {{ 0.5f, -0.5f, 10.0f}, 0xff14f914},
14822 quad6[] =
14824 {{-1.0f, 0.5f, 10.0f}, 0xfff91414},
14825 {{ 1.0f, 0.5f, 10.0f}, 0xfff91414},
14826 {{-1.0f, 0.25f, 10.0f}, 0xfff91414},
14827 {{ 1.0f, 0.25f, 10.0f}, 0xfff91414},
14830 window = create_window();
14831 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14832 ok(!!d3d, "Failed to create a D3D object.\n");
14833 if (!(device = create_device(d3d, window, window, TRUE)))
14835 skip("Failed to create a D3D device, skipping tests.\n");
14836 goto done;
14839 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
14840 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
14842 vp.X = 0;
14843 vp.Y = 0;
14844 vp.Width = 640;
14845 vp.Height = 480;
14846 vp.MinZ = 0.0;
14847 vp.MaxZ = 7.5;
14849 hr = IDirect3DDevice9_SetViewport(device, &vp);
14850 if(FAILED(hr))
14852 /* Windows 7 rejects MaxZ > 1.0, Windows XP allows it. This doesn't break
14853 * the tests because the 7.5 is just intended to show that it doesn't have
14854 * any influence on the drawing or D3DRS_CLIPPING = FALSE. Set an accepted
14855 * viewport and continue.
14857 ok(broken(hr == D3DERR_INVALIDCALL), "D3D rejected maxZ > 1.0\n");
14858 vp.MaxZ = 1.0;
14859 hr = IDirect3DDevice9_SetViewport(device, &vp);
14861 ok(SUCCEEDED(hr), "SetViewport failed, hr %#lx.\n", hr);
14863 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0, 0);
14864 ok(SUCCEEDED(hr), "Clear failed, hr %#lx.\n", hr);
14866 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
14867 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
14868 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
14869 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
14870 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
14871 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
14872 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
14873 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
14875 hr = IDirect3DDevice9_BeginScene(device);
14876 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
14878 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
14879 ok(SUCCEEDED(hr), "SetFVF failed, hr %#lx.\n", hr);
14881 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
14882 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
14883 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
14884 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
14886 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
14887 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
14889 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
14890 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
14891 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
14892 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
14894 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
14895 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
14897 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
14898 ok(SUCCEEDED(hr), "SetFVF failed, hr %#lx.\n", hr);
14900 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
14901 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
14903 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
14904 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
14906 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
14907 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
14909 hr = IDirect3DDevice9_EndScene(device);
14910 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
14912 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
14914 color = getPixelColor(device, 75, 75);
14915 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
14916 color = getPixelColor(device, 150, 150);
14917 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
14918 color = getPixelColor(device, 320, 240);
14919 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
14920 color = getPixelColor(device, 320, 330);
14921 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
14922 color = getPixelColor(device, 320, 330);
14923 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
14925 else
14927 color = getPixelColor(device, 75, 75);
14928 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
14929 color = getPixelColor(device, 150, 150);
14930 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
14931 color = getPixelColor(device, 320, 240);
14932 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
14933 color = getPixelColor(device, 320, 330);
14934 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
14935 color = getPixelColor(device, 320, 330);
14936 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
14939 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14940 ok(hr == S_OK, "Got hr %#lx.\n", hr);
14942 refcount = IDirect3DDevice9_Release(device);
14943 ok(!refcount, "Device has %lu references left.\n", refcount);
14944 done:
14945 IDirect3D9_Release(d3d);
14946 DestroyWindow(window);
14949 static void depth_bounds_test(void)
14951 static const struct
14953 struct vec4 position;
14954 DWORD diffuse;
14956 quad1[] =
14958 {{ 0.0f, 0.0f, 0.0f, 1.0f}, 0xfff9e814},
14959 {{640.0f, 0.0f, 0.0f, 1.0f}, 0xfff9e814},
14960 {{ 0.0f, 480.0f, 1.0f, 1.0f}, 0xfff9e814},
14961 {{640.0f, 480.0f, 1.0f, 1.0f}, 0xfff9e814},
14963 quad2[] =
14965 {{ 0.0f, 0.0f, 0.6f, 1.0f}, 0xff002b7f},
14966 {{640.0f, 0.0f, 0.6f, 1.0f}, 0xff002b7f},
14967 {{ 0.0f, 480.0f, 0.6f, 1.0f}, 0xff002b7f},
14968 {{640.0f, 480.0f, 0.6f, 1.0f}, 0xff002b7f},
14970 quad3[] =
14972 {{ 0.0f, 100.0f, 0.6f, 1.0f}, 0xfff91414},
14973 {{640.0f, 100.0f, 0.6f, 1.0f}, 0xfff91414},
14974 {{ 0.0f, 160.0f, 0.6f, 1.0f}, 0xfff91414},
14975 {{640.0f, 160.0f, 0.6f, 1.0f}, 0xfff91414},
14978 union {
14979 DWORD d;
14980 float f;
14981 } tmpvalue;
14983 IDirect3DSurface9 *offscreen_surface = NULL;
14984 IDirect3DDevice9 *device;
14985 unsigned int color;
14986 IDirect3D9 *d3d;
14987 ULONG refcount;
14988 HWND window;
14989 HRESULT hr;
14991 window = create_window();
14992 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14993 ok(!!d3d, "Failed to create a D3D object.\n");
14994 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
14995 D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, MAKEFOURCC('N','V','D','B')) != D3D_OK)
14997 skip("No NVDB (depth bounds test) support, skipping tests.\n");
14998 goto done;
15000 if (!(device = create_device(d3d, window, window, TRUE)))
15002 skip("Failed to create a D3D device, skipping tests.\n");
15003 goto done;
15006 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
15007 MAKEFOURCC('N','V','D','B'), D3DPOOL_DEFAULT, &offscreen_surface, NULL);
15008 ok(FAILED(hr), "Able to create surface, hr %#lx.\n", hr);
15009 if (offscreen_surface) IDirect3DSurface9_Release(offscreen_surface);
15011 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
15012 ok(SUCCEEDED(hr), "Clear failed, hr %#lx.\n", hr);
15014 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
15015 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15016 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
15017 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15018 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
15019 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15020 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
15021 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15024 hr = IDirect3DDevice9_BeginScene(device);
15025 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
15027 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
15028 ok(SUCCEEDED(hr), "SetFVF failed, hr %#lx.\n", hr);
15030 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
15031 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
15033 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, MAKEFOURCC('N','V','D','B'));
15034 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15036 tmpvalue.f = 0.625;
15037 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
15038 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15040 tmpvalue.f = 0.75;
15041 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_W, tmpvalue.d);
15042 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15044 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
15045 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
15047 tmpvalue.f = 0.75;
15048 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
15049 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15051 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
15052 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
15054 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, 0);
15055 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15057 hr = IDirect3DDevice9_EndScene(device);
15058 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
15060 color = getPixelColor(device, 150, 130);
15061 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
15062 color = getPixelColor(device, 150, 200);
15063 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
15064 color = getPixelColor(device, 150, 300-5);
15065 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
15066 color = getPixelColor(device, 150, 300+5);
15067 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
15068 color = getPixelColor(device, 150, 330);
15069 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
15070 color = getPixelColor(device, 150, 360-5);
15071 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
15072 color = getPixelColor(device, 150, 360+5);
15073 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
15075 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15076 ok(hr == S_OK, "Got hr %#lx.\n", hr);
15077 refcount = IDirect3DDevice9_Release(device);
15078 ok(!refcount, "Device has %lu references left.\n", refcount);
15079 done:
15080 IDirect3D9_Release(d3d);
15081 DestroyWindow(window);
15084 static void depth_buffer_test(void)
15086 static const struct
15088 struct vec3 position;
15089 DWORD diffuse;
15091 quad1[] =
15093 {{-1.0, 1.0, 0.33f}, 0xff00ff00},
15094 {{ 1.0, 1.0, 0.33f}, 0xff00ff00},
15095 {{-1.0, -1.0, 0.33f}, 0xff00ff00},
15096 {{ 1.0, -1.0, 0.33f}, 0xff00ff00},
15098 quad2[] =
15100 {{-1.0, 1.0, 0.50f}, 0xffff00ff},
15101 {{ 1.0, 1.0, 0.50f}, 0xffff00ff},
15102 {{-1.0, -1.0, 0.50f}, 0xffff00ff},
15103 {{ 1.0, -1.0, 0.50f}, 0xffff00ff},
15105 quad3[] =
15107 {{-1.0, 1.0, 0.66f}, 0xffff0000},
15108 {{ 1.0, 1.0, 0.66f}, 0xffff0000},
15109 {{-1.0, -1.0, 0.66f}, 0xffff0000},
15110 {{ 1.0, -1.0, 0.66f}, 0xffff0000},
15112 static const unsigned int expected_colors[4][4] =
15114 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
15115 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
15116 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
15117 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
15120 IDirect3DSurface9 *backbuffer, *rt1, *rt2, *rt3;
15121 IDirect3DDevice9 *device;
15122 unsigned int color, i, j;
15123 D3DVIEWPORT9 vp;
15124 IDirect3D9 *d3d;
15125 ULONG refcount;
15126 HWND window;
15127 HRESULT hr;
15129 window = create_window();
15130 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15131 ok(!!d3d, "Failed to create a D3D object.\n");
15132 if (!(device = create_device(d3d, window, window, TRUE)))
15134 skip("Failed to create a D3D device, skipping tests.\n");
15135 goto done;
15138 vp.X = 0;
15139 vp.Y = 0;
15140 vp.Width = 640;
15141 vp.Height = 480;
15142 vp.MinZ = 0.0;
15143 vp.MaxZ = 1.0;
15145 hr = IDirect3DDevice9_SetViewport(device, &vp);
15146 ok(SUCCEEDED(hr), "SetViewport failed, hr %#lx.\n", hr);
15148 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
15149 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15150 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
15151 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15152 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
15153 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15154 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
15155 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15156 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
15157 ok(SUCCEEDED(hr), "SetFVF failed, hr %#lx.\n", hr);
15159 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
15160 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#lx.\n", hr);
15161 hr = IDirect3DDevice9_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
15162 D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
15163 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#lx.\n", hr);
15164 hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
15165 D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
15166 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#lx.\n", hr);
15167 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
15168 D3DMULTISAMPLE_NONE, 0, FALSE, &rt3, NULL);
15169 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#lx.\n", hr);
15171 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt3);
15172 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#lx.\n", hr);
15173 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
15174 ok(SUCCEEDED(hr), "Clear failed, hr %#lx.\n", hr);
15176 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
15177 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#lx.\n", hr);
15178 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
15179 ok(SUCCEEDED(hr), "Clear failed, hr %#lx.\n", hr);
15181 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
15182 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#lx.\n", hr);
15183 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
15184 ok(SUCCEEDED(hr), "Clear failed, hr %#lx.\n", hr);
15186 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
15187 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#lx.\n", hr);
15188 hr = IDirect3DDevice9_BeginScene(device);
15189 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
15190 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
15191 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
15192 hr = IDirect3DDevice9_EndScene(device);
15193 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
15195 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
15196 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#lx.\n", hr);
15198 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
15199 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15201 hr = IDirect3DDevice9_BeginScene(device);
15202 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
15203 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
15204 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
15205 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
15206 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
15207 hr = IDirect3DDevice9_EndScene(device);
15208 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
15210 for (i = 0; i < 4; ++i)
15212 for (j = 0; j < 4; ++j)
15214 unsigned int x = 80 * ((2 * j) + 1);
15215 unsigned int y = 60 * ((2 * i) + 1);
15216 color = getPixelColor(device, x, y);
15217 ok(color_match(color, expected_colors[i][j], 0),
15218 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
15222 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15223 ok(hr == S_OK, "Got hr %#lx.\n", hr);
15225 IDirect3DSurface9_Release(backbuffer);
15226 IDirect3DSurface9_Release(rt3);
15227 IDirect3DSurface9_Release(rt2);
15228 IDirect3DSurface9_Release(rt1);
15229 refcount = IDirect3DDevice9_Release(device);
15230 ok(!refcount, "Device has %lu references left.\n", refcount);
15231 done:
15232 IDirect3D9_Release(d3d);
15233 DestroyWindow(window);
15236 /* Test that partial depth copies work the way they're supposed to. The clear
15237 * on rt2 only needs a partial copy of the onscreen depth/stencil buffer, and
15238 * the following draw should only copy back the part that was modified. */
15239 static void depth_buffer2_test(void)
15241 static const struct
15243 struct vec3 position;
15244 DWORD diffuse;
15246 quad[] =
15248 {{-1.0f, 1.0f, 0.66f}, 0xffff0000},
15249 {{ 1.0f, 1.0f, 0.66f}, 0xffff0000},
15250 {{-1.0f, -1.0f, 0.66f}, 0xffff0000},
15251 {{ 1.0f, -1.0f, 0.66f}, 0xffff0000},
15254 IDirect3DSurface9 *backbuffer, *rt1, *rt2;
15255 IDirect3DDevice9 *device;
15256 unsigned int color, i, j;
15257 D3DVIEWPORT9 vp;
15258 IDirect3D9 *d3d;
15259 ULONG refcount;
15260 HWND window;
15261 HRESULT hr;
15263 window = create_window();
15264 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15265 ok(!!d3d, "Failed to create a D3D object.\n");
15266 if (!(device = create_device(d3d, window, window, TRUE)))
15268 skip("Failed to create a D3D device, skipping tests.\n");
15269 goto done;
15272 vp.X = 0;
15273 vp.Y = 0;
15274 vp.Width = 640;
15275 vp.Height = 480;
15276 vp.MinZ = 0.0;
15277 vp.MaxZ = 1.0;
15279 hr = IDirect3DDevice9_SetViewport(device, &vp);
15280 ok(SUCCEEDED(hr), "SetViewport failed, hr %#lx.\n", hr);
15282 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
15283 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15284 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
15285 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15286 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
15287 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15288 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
15289 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15290 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
15291 ok(SUCCEEDED(hr), "SetFVF failed, hr %#lx.\n", hr);
15293 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
15294 D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
15295 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#lx.\n", hr);
15296 hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
15297 D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
15298 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#lx.\n", hr);
15299 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
15300 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#lx.\n", hr);
15302 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
15303 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#lx.\n", hr);
15304 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
15305 ok(SUCCEEDED(hr), "Clear failed, hr %#lx.\n", hr);
15307 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
15308 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#lx.\n", hr);
15309 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 0.5f, 0);
15310 ok(SUCCEEDED(hr), "Clear failed, hr %#lx.\n", hr);
15312 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
15313 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#lx.\n", hr);
15314 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
15315 ok(SUCCEEDED(hr), "Clear failed, hr %#lx.\n", hr);
15317 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
15318 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#lx.\n", hr);
15320 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
15321 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15323 hr = IDirect3DDevice9_BeginScene(device);
15324 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
15325 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15326 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
15327 hr = IDirect3DDevice9_EndScene(device);
15328 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
15330 for (i = 0; i < 4; ++i)
15332 for (j = 0; j < 4; ++j)
15334 unsigned int x = 80 * ((2 * j) + 1);
15335 unsigned int y = 60 * ((2 * i) + 1);
15336 color = getPixelColor(device, x, y);
15337 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
15338 "Expected color 0x0000ff00 at %u,%u, got 0x%08x.\n", x, y, color);
15342 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15343 ok(hr == S_OK, "Got hr %#lx.\n", hr);
15345 IDirect3DSurface9_Release(backbuffer);
15346 IDirect3DSurface9_Release(rt2);
15347 IDirect3DSurface9_Release(rt1);
15348 refcount = IDirect3DDevice9_Release(device);
15349 ok(!refcount, "Device has %lu references left.\n", refcount);
15350 done:
15351 IDirect3D9_Release(d3d);
15352 DestroyWindow(window);
15355 static void depth_blit_test(void)
15357 static const struct
15359 struct vec3 position;
15360 DWORD diffuse;
15362 quad1[] =
15364 {{-1.0f, 1.0f, 0.33f}, 0xff00ff00},
15365 {{ 1.0f, 1.0f, 0.33f}, 0xff00ff00},
15366 {{-1.0f, -1.0f, 0.33f}, 0xff00ff00},
15367 {{ 1.0f, -1.0f, 0.33f}, 0xff00ff00},
15369 quad2[] =
15371 {{-1.0f, 1.0f, 0.66f}, 0xff0000ff},
15372 {{ 1.0f, 1.0f, 0.66f}, 0xff0000ff},
15373 {{-1.0f, -1.0f, 0.66f}, 0xff0000ff},
15374 {{ 1.0f, -1.0f, 0.66f}, 0xff0000ff},
15376 static const unsigned int expected_colors[4][4] =
15378 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
15379 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
15380 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
15381 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
15384 IDirect3DSurface9 *backbuffer, *ds1, *ds2, *ds3;
15385 IDirect3DDevice9 *device;
15386 unsigned int color, i, j;
15387 RECT src_rect, dst_rect;
15388 D3DVIEWPORT9 vp;
15389 IDirect3D9 *d3d;
15390 ULONG refcount;
15391 HWND window;
15392 HRESULT hr;
15394 window = create_window();
15395 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15396 ok(!!d3d, "Failed to create a D3D object.\n");
15397 if (!(device = create_device(d3d, window, window, TRUE)))
15399 skip("Failed to create a D3D device, skipping tests.\n");
15400 goto done;
15403 vp.X = 0;
15404 vp.Y = 0;
15405 vp.Width = 640;
15406 vp.Height = 480;
15407 vp.MinZ = 0.0;
15408 vp.MaxZ = 1.0;
15410 hr = IDirect3DDevice9_SetViewport(device, &vp);
15411 ok(SUCCEEDED(hr), "SetViewport failed, hr %#lx.\n", hr);
15413 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
15414 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#lx.\n", hr);
15415 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds1);
15416 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#lx.\n", hr);
15417 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8, 0, 0, FALSE, &ds2, NULL);
15418 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#lx.\n", hr);
15419 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds2);
15420 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#lx.\n", hr);
15421 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 320, 240, D3DFMT_D24S8, 0, 0, FALSE, &ds3, NULL);
15422 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#lx.\n", hr);
15424 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
15425 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15426 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
15427 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15428 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
15429 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15430 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
15431 ok(SUCCEEDED(hr), "SetFVF failed, hr %#lx.\n", hr);
15433 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
15434 ok(SUCCEEDED(hr), "Clear failed, hr %#lx.\n", hr);
15435 SetRect(&dst_rect, 0, 0, 480, 360);
15436 hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 0.5f, 0);
15437 ok(SUCCEEDED(hr), "Clear failed, hr %#lx.\n", hr);
15438 SetRect(&dst_rect, 0, 0, 320, 240);
15439 hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
15440 ok(SUCCEEDED(hr), "Clear failed, hr %#lx.\n", hr);
15442 /* Partial blit. */
15443 SetRect(&src_rect, 0, 0, 320, 240);
15444 SetRect(&dst_rect, 0, 0, 320, 240);
15445 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
15446 ok(hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
15447 /* Flipped. */
15448 SetRect(&src_rect, 0, 0, 640, 480);
15449 SetRect(&dst_rect, 0, 480, 640, 0);
15450 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
15451 ok(hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
15452 /* Full, explicit. */
15453 SetRect(&src_rect, 0, 0, 640, 480);
15454 SetRect(&dst_rect, 0, 0, 640, 480);
15455 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
15456 ok(SUCCEEDED(hr), "StretchRect failed, hr %#lx.\n", hr);
15457 /* Filtered blit. */
15458 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_LINEAR);
15459 ok(SUCCEEDED(hr), "StretchRect failed, hr %#lx.\n", hr);
15460 /* Depth -> color blit.*/
15461 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, backbuffer, NULL, D3DTEXF_POINT);
15462 ok(hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
15463 IDirect3DSurface9_Release(backbuffer);
15464 /* Full surface, different sizes */
15465 hr = IDirect3DDevice9_StretchRect(device, ds3, NULL, ds1, NULL, D3DTEXF_POINT);
15466 ok(hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
15467 hr = IDirect3DDevice9_StretchRect(device, ds1, NULL, ds3, NULL, D3DTEXF_POINT);
15468 ok(hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
15470 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds1);
15471 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#lx.\n", hr);
15472 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
15473 ok(SUCCEEDED(hr), "Clear failed, hr %#lx.\n", hr);
15474 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_POINT);
15475 ok(SUCCEEDED(hr), "StretchRect failed, hr %#lx.\n", hr);
15477 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
15478 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15479 hr = IDirect3DDevice9_BeginScene(device);
15480 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
15481 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
15482 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
15483 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
15484 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
15485 hr = IDirect3DDevice9_EndScene(device);
15486 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
15488 for (i = 0; i < 4; ++i)
15490 for (j = 0; j < 4; ++j)
15492 unsigned int x = 80 * ((2 * j) + 1);
15493 unsigned int y = 60 * ((2 * i) + 1);
15494 color = getPixelColor(device, x, y);
15495 ok(color_match(color, expected_colors[i][j], 0),
15496 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
15500 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15501 ok(hr == S_OK, "Got hr %#lx.\n", hr);
15503 IDirect3DSurface9_Release(ds3);
15504 IDirect3DSurface9_Release(ds2);
15505 IDirect3DSurface9_Release(ds1);
15506 refcount = IDirect3DDevice9_Release(device);
15507 ok(!refcount, "Device has %lu references left.\n", refcount);
15508 done:
15509 IDirect3D9_Release(d3d);
15510 DestroyWindow(window);
15513 static void intz_test(void)
15515 static const DWORD ps_code[] =
15517 0xffff0200, /* ps_2_0 */
15518 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
15519 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
15520 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
15521 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
15522 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
15523 0x03010042, 0x800f0001, 0xb0e40000, 0xa0e40800, /* texldp r1, t0, s0 */
15524 0x02000001, 0x80020000, 0x80000001, /* mov r0.y, r1.x */
15525 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
15526 0x0000ffff, /* end */
15528 struct
15530 float x, y, z;
15531 float s, t, p, q;
15533 quad[] =
15535 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
15536 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
15537 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
15538 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
15540 half_quad_1[] =
15542 { -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
15543 { 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
15544 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
15545 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
15547 half_quad_2[] =
15549 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
15550 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
15551 { -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
15552 { 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
15554 struct
15556 unsigned int x, y, color;
15558 expected_colors[] =
15560 { 80, 100, 0x20204020},
15561 {240, 100, 0x6060bf60},
15562 {400, 100, 0x9f9f409f},
15563 {560, 100, 0xdfdfbfdf},
15564 { 80, 450, 0x20204020},
15565 {240, 450, 0x6060bf60},
15566 {400, 450, 0x9f9f409f},
15567 {560, 450, 0xdfdfbfdf},
15570 IDirect3DSurface9 *original_rt, *rt;
15571 struct surface_readback rb;
15572 IDirect3DTexture9 *texture;
15573 IDirect3DPixelShader9 *ps;
15574 IDirect3DDevice9 *device;
15575 IDirect3DSurface9 *ds;
15576 IDirect3D9 *d3d;
15577 ULONG refcount;
15578 D3DCAPS9 caps;
15579 HWND window;
15580 HRESULT hr;
15581 UINT i;
15583 window = create_window();
15584 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15585 ok(!!d3d, "Failed to create a D3D object.\n");
15586 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
15587 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'))))
15589 skip("No INTZ support, skipping INTZ test.\n");
15590 goto done;
15592 if (!(device = create_device(d3d, window, window, TRUE)))
15594 skip("Failed to create a D3D device, skipping tests.\n");
15595 goto done;
15598 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
15599 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#lx.\n", hr);
15600 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
15602 skip("No pixel shader 2.0 support, skipping INTZ test.\n");
15603 IDirect3DDevice9_Release(device);
15604 goto done;
15606 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
15608 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
15609 IDirect3DDevice9_Release(device);
15610 goto done;
15613 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
15614 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#lx.\n", hr);
15616 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
15617 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
15618 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#lx.\n", hr);
15619 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
15620 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
15621 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#lx.\n", hr);
15622 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
15623 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#lx.\n", hr);
15625 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
15626 ok(SUCCEEDED(hr), "SetFVF failed, hr %#lx.\n", hr);
15627 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
15628 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15629 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
15630 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15631 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
15632 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15633 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
15634 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
15636 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
15637 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#lx.\n", hr);
15638 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
15639 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#lx.\n", hr);
15640 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
15641 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#lx.\n", hr);
15642 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
15643 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#lx.\n", hr);
15644 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
15645 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#lx.\n", hr);
15647 /* Render offscreen, using the INTZ texture as depth buffer */
15648 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
15649 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#lx.\n", hr);
15650 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
15651 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#lx.\n", hr);
15652 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15653 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#lx.\n", hr);
15654 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
15655 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#lx.\n", hr);
15657 /* Setup the depth/stencil surface. */
15658 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
15659 ok(SUCCEEDED(hr), "Clear failed, hr %#lx.\n", hr);
15661 hr = IDirect3DDevice9_BeginScene(device);
15662 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
15663 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15664 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
15665 hr = IDirect3DDevice9_EndScene(device);
15666 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
15668 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
15669 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#lx.\n", hr);
15670 IDirect3DSurface9_Release(ds);
15671 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
15672 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#lx.\n", hr);
15673 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
15674 ok(SUCCEEDED(hr), "SetTexture failed, hr %#lx.\n", hr);
15675 hr = IDirect3DDevice9_SetPixelShader(device, ps);
15676 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#lx.\n", hr);
15678 /* Read the depth values back. */
15679 hr = IDirect3DDevice9_BeginScene(device);
15680 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
15681 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15682 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
15683 hr = IDirect3DDevice9_EndScene(device);
15684 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
15686 get_rt_readback(original_rt, &rb);
15687 for (i = 0; i < ARRAY_SIZE(expected_colors); ++i)
15689 unsigned int color = get_readback_color(&rb, expected_colors[i].x, expected_colors[i].y);
15690 ok(color_match(color, expected_colors[i].color, 1),
15691 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
15692 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
15694 release_surface_readback(&rb);
15696 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15697 ok(SUCCEEDED(hr), "Present failed, hr %#lx.\n", hr);
15699 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
15700 ok(SUCCEEDED(hr), "SetTexture failed, hr %#lx.\n", hr);
15701 IDirect3DTexture9_Release(texture);
15703 /* Render onscreen while using the INTZ texture as depth buffer */
15704 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
15705 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
15706 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
15707 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#lx.\n", hr);
15708 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
15709 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#lx.\n", hr);
15710 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
15711 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#lx.\n", hr);
15713 /* Setup the depth/stencil surface. */
15714 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
15715 ok(SUCCEEDED(hr), "Clear failed, hr %#lx.\n", hr);
15717 hr = IDirect3DDevice9_BeginScene(device);
15718 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
15719 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15720 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
15721 hr = IDirect3DDevice9_EndScene(device);
15722 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
15724 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
15725 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#lx.\n", hr);
15726 IDirect3DSurface9_Release(ds);
15727 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
15728 ok(SUCCEEDED(hr), "SetTexture failed, hr %#lx.\n", hr);
15729 hr = IDirect3DDevice9_SetPixelShader(device, ps);
15730 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#lx.\n", hr);
15732 /* Read the depth values back. */
15733 hr = IDirect3DDevice9_BeginScene(device);
15734 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
15735 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15736 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
15737 hr = IDirect3DDevice9_EndScene(device);
15738 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
15740 get_rt_readback(original_rt, &rb);
15741 for (i = 0; i < ARRAY_SIZE(expected_colors); ++i)
15743 unsigned int color = get_readback_color(&rb, expected_colors[i].x, expected_colors[i].y);
15744 ok(color_match(color, expected_colors[i].color, 1),
15745 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
15746 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
15748 release_surface_readback(&rb);
15750 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15751 ok(SUCCEEDED(hr), "Present failed, hr %#lx.\n", hr);
15753 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
15754 ok(SUCCEEDED(hr), "SetTexture failed, hr %#lx.\n", hr);
15755 IDirect3DTexture9_Release(texture);
15757 /* Render offscreen, then onscreen, and finally check the INTZ texture in both areas */
15758 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
15759 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
15760 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
15761 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#lx.\n", hr);
15763 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
15764 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#lx.\n", hr);
15765 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15766 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#lx.\n", hr);
15767 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
15768 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#lx.\n", hr);
15770 /* Setup the depth/stencil surface. */
15771 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
15772 ok(SUCCEEDED(hr), "Clear failed, hr %#lx.\n", hr);
15774 hr = IDirect3DDevice9_BeginScene(device);
15775 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
15776 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_1, sizeof(*half_quad_1));
15777 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
15778 hr = IDirect3DDevice9_EndScene(device);
15779 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
15781 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
15782 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#lx.\n", hr);
15784 hr = IDirect3DDevice9_BeginScene(device);
15785 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
15786 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_2, sizeof(*half_quad_2));
15787 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
15788 hr = IDirect3DDevice9_EndScene(device);
15789 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
15791 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
15792 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#lx.\n", hr);
15793 IDirect3DSurface9_Release(ds);
15794 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
15795 ok(SUCCEEDED(hr), "SetTexture failed, hr %#lx.\n", hr);
15796 hr = IDirect3DDevice9_SetPixelShader(device, ps);
15797 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#lx.\n", hr);
15799 /* Read the depth values back. */
15800 hr = IDirect3DDevice9_BeginScene(device);
15801 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
15802 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15803 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
15804 hr = IDirect3DDevice9_EndScene(device);
15805 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
15807 get_rt_readback(original_rt, &rb);
15808 for (i = 0; i < ARRAY_SIZE(expected_colors); ++i)
15810 unsigned int color = get_readback_color(&rb, expected_colors[i].x, expected_colors[i].y);
15811 ok(color_match(color, expected_colors[i].color, 1),
15812 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
15813 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
15815 release_surface_readback(&rb);
15817 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15818 ok(SUCCEEDED(hr), "Present failed, hr %#lx.\n", hr);
15820 IDirect3DTexture9_Release(texture);
15821 IDirect3DPixelShader9_Release(ps);
15822 IDirect3DSurface9_Release(original_rt);
15823 IDirect3DSurface9_Release(rt);
15824 refcount = IDirect3DDevice9_Release(device);
15825 ok(!refcount, "Device has %lu references left.\n", refcount);
15826 done:
15827 IDirect3D9_Release(d3d);
15828 DestroyWindow(window);
15831 static void test_fetch4(void)
15833 static const DWORD vs_code[] =
15835 0xfffe0300, /* vs_3_0 */
15836 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
15837 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
15838 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
15839 0x0200001f, 0x80000005, 0xe00f0001, /* dcl_texcoord o1 */
15840 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
15841 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
15842 0x0000ffff,
15844 static const DWORD ps_code_texld[] =
15846 0xffff0300, /* ps_3_0 */
15847 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord v0 */
15848 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
15849 0x03000042, 0x800f0000, 0x90e40000, 0xa0e40800, /* texld r0, v0, s0 */
15850 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
15851 0x0000ffff, /* end */
15853 /* AMD and Wine use the projection on Fetch4, Intel UHD ignores it. */
15854 static const DWORD ps_code_texldp[] =
15856 0xffff0300, /* ps_3_0 */
15857 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord v0 */
15858 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
15859 /* The idea here is that if we project from .z, we get a 4x zoom. From
15860 * .w a 2x zoom. */
15861 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x40800000, 0x40000000, /* def c0, 0.0, 0.0, 4.0, 2.0 */
15862 0x02000001, 0x80030000, 0x90f40000, /* mov r0.xy, v0.xyww */
15863 0x02000001, 0x800c0000, 0xa0e00000, /* mov r0.zw, c0.xxzw */
15864 0x03010042, 0x800f0000, 0x80e40000, 0xa0e40800, /* texldp r0, r0, s0 */
15865 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
15866 0x0000ffff, /* end */
15868 static const DWORD ps_code_swizzle[] =
15870 /* Test texld when sampling with a .yzwx swizzle. */
15871 0xffff0300, /* ps_3_0 */
15872 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord v0 */
15873 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
15874 0x03000042, 0x800f0000, 0x90e40000, 0xa0390800, /* texld r0, v0, s0.yzwx */
15875 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
15876 0x0000ffff, /* end */
15878 /* Fetch4 uses the same D3D state as LOD bias, and therefore disables LOD
15879 * handling. Texldd/texldb/texldl give the same result as plain texld. */
15880 /* NOTE: The Radeon HD 5700 driver 8.17.10.1404 disables Fetch4 on these
15881 * instructions. */
15882 static const DWORD ps_code_texldd[] =
15884 0xffff0300, /* ps_3_0 */
15885 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord v0 */
15886 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
15887 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
15888 0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0 */
15889 0x02000001, 0x800f0002, 0xa0e40000, /* mov r2, c0 */
15890 0x0500005d, 0x800f0000, 0x90e40000, 0xa0e40800, 0xa0e40000, 0x80e40002, /* texldd r0, v0, s0, c0, r2 */
15891 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
15892 0x0000ffff, /* end */
15894 static const DWORD ps_code_texldb[] =
15896 0xffff0300, /* ps_3_0 */
15897 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord v0 */
15898 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
15899 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x40a00000, 0x40a00000, /* def c0, 0.0, 0.0, 5.0, 5.0 */
15900 0x03000002, 0x800f0000, 0x90e40000, 0xa0e40000, /* add r0, v0, c0 */
15901 0x03020042, 0x800f0000, 0x80e40000, 0xa0e40800, /* texldb r0, r0, s0 */
15902 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
15903 0x0000ffff, /* end */
15905 static const DWORD ps_code_texldl[] =
15907 0xffff0300, /* ps_3_0 */
15908 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord v0 */
15909 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
15910 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f000000, 0x3f000000, /* def c0, 0.0, 0.0, 0.5, 0.5 */
15911 0x03000002, 0x800f0000, 0x90e40000, 0xa0e40000, /* add r0, v0, c0 */
15912 0x0300005f, 0x800f0000, 0x80e40000, 0xa0e40800, /* texldl r0, r0, s0 */
15913 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
15914 0x0000ffff, /* end */
15916 static const DWORD ps_code_3d[] =
15918 0xffff0300, /* ps_3_0 */
15919 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord v0 */
15920 0x0200001f, 0xa0000000, 0xa00f0800, /* dcl_volume s0 */
15921 0x03000042, 0x800f0000, 0x90e40000, 0xa0e40800, /* texld r0, v0, s0 */
15922 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
15923 0x0000ffff, /* end */
15926 static const struct
15928 struct vec3 position;
15929 struct vec4 texcoord;
15931 quad[] =
15933 {{-1.0f, 1.0f, 1.0f}, {0.0f, 0.0f, 4.0f, 2.0f}},
15934 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.0f, 4.0f, 2.0f}},
15935 {{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f, 4.0f, 2.0f}},
15936 {{ 1.0f, -1.0f, 0.0f}, {1.0f, 1.0f, 4.0f, 2.0f}},
15938 quad2[] =
15940 /* Tilted on the z-axis to get a depth gradient in the depth test. */
15941 /* Note: Using 0.55f-0.6f to avoid rounding errors on depth tests. */
15942 {{-1.0f, 1.0f, 1.0f}, {0.0f, 0.0f, 0.6f, 0.0f}},
15943 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.0f, 0.6f, 0.0f}},
15944 {{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f, 0.6f, 0.0f}},
15945 {{ 1.0f, -1.0f, 0.0f}, {1.0f, 1.0f, 0.6f, 0.0f}},
15948 static const struct
15950 unsigned int x[4], y[4];
15951 D3DCOLOR colour_amd[16];
15952 D3DCOLOR colour_intel[16];
15953 D3DCOLOR colour_fetch4_off[16];
15954 D3DCOLOR colour_3d_fetch4_off[16];
15955 D3DCOLOR colour_3d_amd_zround[16];
15957 expected_colours =
15959 /* Sample positions. */
15960 {40, 200, 360, 520},
15961 {30, 150, 270, 390},
15962 /* AMD implementation (-0.5 texel offsets). */
15963 {0x131202f2, 0x1211f2f1, 0x1110f101, 0x10100101,
15964 0x02f204f4, 0xf2f1f4f3, 0xf101f303, 0x01010303,
15965 0x04f42322, 0xf4f32221, 0xf3032120, 0x03032020,
15966 0x23222322, 0x22212221, 0x21202120, 0x20202020},
15967 /* Intel UHD 620 implementation (no texel offsets).
15968 * We treat the Intel results as broken. */
15969 {0x13131313, 0x12131312, 0x11121211, 0x10111110,
15970 0x13021302, 0x120213f2, 0x11f212f1, 0x10f11101,
15971 0x02040204, 0xf20402f4, 0xf1f4f2f3, 0x01f3f103,
15972 0x04230423, 0xf4230422, 0xf322f421, 0x0321f320},
15973 /* Fetch4 off on 2D textures. */
15974 {0x13131313, 0x12121212, 0x11111111, 0x10101010,
15975 0x02020202, 0xf2f2f2f2, 0xf1f1f1f1, 0x01010101,
15976 0x04040404, 0xf4f4f4f4, 0xf3f3f3f3, 0x03030303,
15977 0x23232323, 0x22222222, 0x21212121, 0x20202020},
15978 /* Fetch4 off on 3D textures. */
15979 {0xff020202, 0xfff2f2f2, 0xfff1f1f1, 0xff010101,
15980 0xff050505, 0xfff4f4f4, 0xfff3f3f3, 0xff030303,
15981 0xff232323, 0xff222222, 0xff212121, 0xff202020,
15982 0xff131313, 0xff121212, 0xff111111, 0xff101010},
15983 /* Fetch4 on, 3D texture without nearest z rounding. */
15984 {0x02f204f4, 0xf2f1f4f3, 0xf101f303, 0x01010303,
15985 0x04f42322, 0xf4f32221, 0xf3032120, 0x03032020,
15986 0x23221312, 0x22211211, 0x21201110, 0x20201010,
15987 0x13121312, 0x12111211, 0x11101110, 0x10101010},
15990 static const DWORD fetch4_data[] = {0x10111213, 0x01f1f202, 0x03f3f404, 0x20212223};
15992 static const struct
15994 const char *name;
15995 const DWORD *ps_code;
15996 unsigned int projection;
15997 BOOL swizzled;
15998 DWORD ttff_flags;
16000 shaders[] =
16002 {"FFP", NULL, 0, FALSE, 0},
16003 {"texld", ps_code_texld, 0, FALSE, 0},
16004 {"texldp", ps_code_texldp, 2, FALSE, 0},
16005 {"texld_yzwx", ps_code_swizzle, 0, TRUE , 0},
16006 {"texldd", ps_code_texldd, 0, FALSE, 0},
16007 {"texldb", ps_code_texldb, 0, FALSE, 0},
16008 {"texldl", ps_code_texldl, 0, FALSE, 0},
16009 {"FFP_proj", NULL, 2, FALSE, D3DTTFF_PROJECTED},
16010 {"FFP_proj3", NULL, 4, FALSE, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED},
16013 static const struct
16015 const char *name;
16016 D3DFORMAT format;
16017 DWORD data;
16018 unsigned int x, y;
16019 unsigned int w, h;
16020 D3DCOLOR colour_amd[3];
16021 D3DCOLOR colour_intel[3];
16022 BOOL todo;
16024 format_tests[] =
16026 /* Enabled formats */
16028 "L8", D3DFMT_L8,
16029 0xff804010, 360, 30, 2, 2,
16030 {0x40400000, 0x40400000, 0x10400000},
16031 {0x40101040, 0x40101040, 0x40101040},
16034 "L16", D3DFMT_L16,
16035 0xff804010, 360, 30, 2, 2,
16036 {0xffff0000, 0xffff0000, 0x40ff0000},
16037 {0xff4040ff, 0xff4040ff, 0xff4040ff},
16040 "R16F", D3DFMT_R16F,
16041 0x38003c00, 360, 30, 2, 2,
16042 {0x80800000, 0x80800000, 0xff800000},
16043 {0x80ffff80, 0x80ffff80, 0x80ffff80},
16046 "R32F", D3DFMT_R32F,
16047 0x3f000000, 360, 30, 2, 2,
16048 {0x00000000, 0x00000000, 0x80000000},
16049 {0x00808000, 0x00808000, 0x00808000},
16052 "ATI1", MAKEFOURCC('A','T','I','1'),
16053 0xb97700ff, 360, 30, 4, 4,
16054 {0x6d6d6d6d, 0x6d6d6d6d, 0x49494949},
16055 {0xff6d00ff, 0xff6d00ff, 0xff4900ff},
16057 /* Unsupported on Intel, broken in Wine. */
16059 "A8", D3DFMT_A8,
16060 0xff804010, 360, 30, 2, 2,
16061 {0x40400000, 0x40400000, 0x10400000},
16062 {0x00000000, 0x00000000, 0x00000000},
16063 TRUE,
16065 /* Unsupported format. */
16067 "A8R8G8B8", D3DFMT_A8R8G8B8,
16068 0xff804010, 360, 270, 2, 2,
16069 {0x00000000, 0x00000000, 0xff804010},
16070 {0x00000000, 0x00000000, 0xff804010},
16074 static const struct
16076 D3DCOLOR colour_off, colour_amd, colour_intel;
16077 unsigned int x, y;
16079 expected_depth[][4] =
16082 /* Shadow samplers. */
16083 {0xffffffff, 0xffffffff, 0xffffffff, 20, 15},
16084 {0xffffffff, 0xffffffff, 0xffffffff, 260, 15},
16085 {0x00000000, 0x00000000, 0x00000000, 20, 255},
16086 {0x00000000, 0x00000000, 0x00000000, 260, 135},
16089 /* DF16. */
16090 {0xfffe0000, 0xfedfdfbf, 0xffffffff, 20, 15},
16091 {0xff9f0000, 0x9f7f7f5f, 0x9fbfbf9f, 260, 15},
16092 {0xff800000, 0x7f5f5f3f, 0x9f809f80, 20, 255},
16093 {0xff600000, 0x5f3f3f1f, 0x80809f60, 260, 135},
16096 /* DF24. */
16097 {0xffff0000, 0xffdfdfbf, 0xffffffff, 20, 15},
16098 {0xff9f0000, 0x9f7f7f5f, 0x9fbfbf9f, 260, 15},
16099 {0xff800000, 0x7f5f5f3f, 0x9f809f80, 20, 255},
16100 {0xff600000, 0x5f3f3f1f, 0x80809f60, 260, 135},
16103 /* INTZ. */
16104 {0xffffffff, 0xffdfdfbf, 0xffffffff, 20, 15},
16105 {0x9f9f9f9f, 0x9f7f7f5f, 0x9fbfbf9f, 260, 15},
16106 {0x7f7f7f7f, 0x7f5f5f3f, 0x9f809f80, 20, 255},
16107 {0x5f5f5f5f, 0x5f3f3f1f, 0x80809f60, 260, 135},
16111 static const struct
16113 const char *name;
16114 D3DFORMAT format;
16115 unsigned int index;
16117 depth_tests[] =
16119 {"D16_LOCKABLE", D3DFMT_D16_LOCKABLE, 0},
16120 {"D32", D3DFMT_D32, 0},
16121 {"D15S1", D3DFMT_D15S1, 0},
16122 {"D24S8", D3DFMT_D24S8, 0},
16123 {"D24X8", D3DFMT_D24X8, 0},
16124 {"D24X4S4", D3DFMT_D24X4S4, 0},
16125 {"D16", D3DFMT_D16, 0},
16126 {"D32F_LOCKABLE", D3DFMT_D32F_LOCKABLE, 0},
16127 {"D24FS8", D3DFMT_D24FS8, 0},
16128 {"DF16", MAKEFOURCC('D','F','1','6'), 1},
16129 {"DF24", MAKEFOURCC('D','F','2','4'), 2},
16130 {"INTZ", MAKEFOURCC('I','N','T','Z'), 3},
16133 unsigned int colour, colour_amd, colour_intel, colour_off, colour_zround, i, j, k, x, y;
16134 IDirect3DPixelShader9 *ps[ARRAY_SIZE(shaders)];
16135 IDirect3DVolumeTexture9 *texture_3d;
16136 IDirect3DSurface9 *original_rt, *rt;
16137 IDirect3DPixelShader9 *ps_3d;
16138 struct surface_readback rb;
16139 IDirect3DVertexShader9 *vs;
16140 IDirect3DTexture9 *texture;
16141 IDirect3DDevice9 *device;
16142 D3DLOCKED_RECT lr;
16143 D3DLOCKED_BOX lb;
16144 IDirect3D9 *d3d;
16145 ULONG refcount;
16146 D3DCAPS9 caps;
16147 HWND window;
16148 HRESULT hr;
16150 window = create_window();
16151 d3d = Direct3DCreate9(D3D_SDK_VERSION);
16152 ok(!!d3d, "Failed to create a D3D object.\n");
16153 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
16154 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('D','F','2','4'))))
16156 skip("No DF24 support, skipping Fetch4 test.\n");
16157 goto done;
16159 if (!(device = create_device(d3d, window, window, TRUE)))
16161 skip("Failed to create a D3D device, skipping tests.\n");
16162 goto done;
16165 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
16166 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16167 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0))
16169 skip("No pixel shader 3.0 support, skipping FETCH4 test.\n");
16170 IDirect3DDevice9_Release(device);
16171 goto done;
16173 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
16174 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16175 hr = IDirect3DDevice9_CreateRenderTarget(device, 8, 8, D3DFMT_A8R8G8B8,
16176 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
16177 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16179 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
16180 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16181 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
16182 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16183 for (i = 0; i < ARRAY_SIZE(fetch4_data); ++i)
16184 memcpy((BYTE *)lr.pBits + i * lr.Pitch, &fetch4_data[i], sizeof(fetch4_data[i]));
16185 hr = IDirect3DTexture9_UnlockRect(texture, 0);
16186 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16188 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
16189 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16190 for (i = 0; i < ARRAY_SIZE(shaders); ++i)
16192 if (!shaders[i].ps_code)
16194 ps[i] = NULL;
16195 continue;
16198 hr = IDirect3DDevice9_CreatePixelShader(device, shaders[i].ps_code, &ps[i]);
16199 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16201 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_3d, &ps_3d);
16202 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16204 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
16205 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16206 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
16207 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16208 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
16209 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16210 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
16211 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16212 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
16213 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16214 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
16215 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16217 /* According to the documentation, Fetch4 is enabled when
16218 * D3DSAMP_MIPMAPLODBIAS == GET4 and D3DSAMP_MAGFILTER == D3DTEXF_POINT.
16219 * In practice, it seems that only GET4 is required.
16221 * AMD r500 hardware always uses POINT filtering with Fetch4. The driver
16222 * later on corrected this by adding a -0.5 texel offset. */
16223 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPMAPLODBIAS, MAKEFOURCC('G','E','T','4'));
16224 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16225 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
16226 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16227 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
16228 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16229 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
16230 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16231 /* Fetch4 should work with any texture wrapping mode, and does in Wine.
16232 * However, AMD RX 580 devices force clamping when fetch4 is on.
16233 * No other driver/hardware does this, but to avoid problems, we test with
16234 * CLAMP on. */
16235 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
16236 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16237 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
16238 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16239 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
16240 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16242 /* Test basic Fetch4 sampling. */
16243 for (i = 0; i < ARRAY_SIZE(shaders); ++i)
16245 hr = IDirect3DDevice9_SetVertexShader(device, ps[i] ? vs : NULL);
16246 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16247 hr = IDirect3DDevice9_SetPixelShader(device, ps[i]);
16248 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16249 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, shaders[i].ttff_flags);
16250 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16252 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
16253 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16254 hr = IDirect3DDevice9_BeginScene(device);
16255 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16256 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16257 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16258 hr = IDirect3DDevice9_EndScene(device);
16259 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16261 get_rt_readback(original_rt, &rb);
16262 for (j = 0; j < ARRAY_SIZE(expected_colours.colour_amd); ++j)
16264 unsigned int projection = shaders[i].projection;
16266 x = expected_colours.x[j % 4];
16267 y = expected_colours.y[j / 4];
16268 colour_amd = expected_colours.colour_amd[j];
16269 if (projection)
16270 colour_amd = expected_colours.colour_amd[j / 4 / projection * 4 + (j % 4) / projection];
16271 if (shaders[i].swizzled)
16272 colour_amd = (colour_amd << 8) | (colour_amd >> 24);
16273 colour_intel = expected_colours.colour_intel[j];
16274 colour_off = expected_colours.colour_fetch4_off[j];
16275 colour = get_readback_color(&rb, x, y);
16277 ok(color_match(colour, colour_amd, 1) || broken(color_match(colour, colour_intel, 1))
16278 || broken(color_match(colour, colour_off, 1)),
16279 "Test %s: Got unexpected colour 0x%08x at (%u, %u).\n",
16280 shaders[i].name, colour, x, y);
16282 release_surface_readback(&rb);
16284 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16285 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16287 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, 0);
16288 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16290 /* Test Fetch4 format support. */
16291 for (i = 0; i < ARRAY_SIZE(format_tests); ++i)
16293 IDirect3DTexture9 *tex;
16295 hr = IDirect3DDevice9_CreateTexture(device, format_tests[i].w, format_tests[i].h,
16296 1, 0, format_tests[i].format, D3DPOOL_MANAGED, &tex, NULL);
16297 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16298 hr = IDirect3DTexture9_LockRect(tex, 0, &lr, NULL, 0);
16299 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16300 memcpy(lr.pBits, &format_tests[i].data, 4);
16301 hr = IDirect3DTexture9_UnlockRect(tex, 0);
16302 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16303 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex);
16304 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16306 for (j = 0; j < ARRAY_SIZE(format_tests[i].colour_amd); ++j)
16308 hr = IDirect3DDevice9_SetVertexShader(device, ps[j] ? vs : NULL);
16309 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16310 hr = IDirect3DDevice9_SetPixelShader(device, ps[j]);
16311 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16313 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
16314 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16315 hr = IDirect3DDevice9_BeginScene(device);
16316 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16317 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
16318 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16319 hr = IDirect3DDevice9_EndScene(device);
16320 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16322 get_rt_readback(original_rt, &rb);
16323 colour_amd = format_tests[i].colour_amd[j];
16324 colour_intel = format_tests[i].colour_intel[j];
16325 colour = get_readback_color(&rb, format_tests[i].x, format_tests[i].y);
16326 /* On windows just test the R channel, since G/B might be 0xff or 0x00. */
16327 todo_wine_if(format_tests[i].todo)
16328 ok(color_match(colour, colour_amd, 2) || broken(color_match(colour, colour_intel, 2))
16329 || broken(color_match(colour & 0x00ff0000, colour_amd & 0x00ff0000, 2)),
16330 "Test %s on %s: Got unexpected colour 0x%08x at (%u, %u).\n",
16331 shaders[j].name, format_tests[i].name, colour, format_tests[i].x, format_tests[i].y);
16332 release_surface_readback(&rb);
16334 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16335 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16337 IDirect3DTexture9_Release(tex);
16340 hr = IDirect3DDevice9_CreateVolumeTexture(device, 4, 4, 2, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture_3d, NULL);
16341 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16342 hr = IDirect3DVolumeTexture9_LockBox(texture_3d, 0, &lb, NULL, 0);
16343 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16344 for (i = 0; i < ARRAY_SIZE(fetch4_data); ++i)
16346 memcpy((BYTE *)lb.pBits + i * lb.RowPitch, &fetch4_data[i], sizeof(fetch4_data[i]));
16347 /* Shift the lower level, to keep it different. */
16348 memcpy((BYTE *)lb.pBits + i * lb.RowPitch + lb.SlicePitch, &fetch4_data[(i + 1) % 4], sizeof(fetch4_data[i]));
16350 hr = IDirect3DVolumeTexture9_UnlockBox(texture_3d, 0);
16351 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16352 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture_3d);
16353 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16355 /* Test Fetch4 with 3D textures. */
16356 for (i = 0; i < 2; ++i)
16358 hr = IDirect3DDevice9_SetVertexShader(device, i ? vs : NULL);
16359 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16360 hr = IDirect3DDevice9_SetPixelShader(device, i ? ps_3d : NULL);
16361 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16363 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
16364 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16365 hr = IDirect3DDevice9_BeginScene(device);
16366 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16367 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
16368 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16369 hr = IDirect3DDevice9_EndScene(device);
16370 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16371 get_rt_readback(original_rt, &rb);
16372 for (j = 0; j < ARRAY_SIZE(expected_colours.colour_amd); ++j)
16374 x = expected_colours.x[j % 4];
16375 y = expected_colours.y[j / 4];
16376 colour_amd = expected_colours.colour_amd[j];
16377 colour_intel = expected_colours.colour_intel[j];
16378 colour_off = expected_colours.colour_3d_fetch4_off[j];
16379 colour_zround = expected_colours.colour_3d_amd_zround[j];
16380 colour = get_readback_color(&rb, x, y);
16382 /* Note: Fetch4 on 3D textures have different results based on the vendor/driver
16383 * - AMD "HD 5700" rounds to nearest "z" texel, and does fetch4 normally on .xy
16384 * - AMD "R500" has fetch4 disabled
16385 * - AMD "R580" has fetch4 enabled sampling at .xy0
16386 * - Intel UHD 620 sample with fetch4 at .xy0 */
16387 ok(color_match(colour, colour_off, 2) || broken(color_match(colour, colour_zround, 2)
16388 || color_match(colour, colour_intel, 2) || color_match(colour, colour_amd, 2)),
16389 "Test 3D %s: Got unexpected colour 0x%08x at (%u, %u).\n", shaders[i].name, colour, x, y);
16391 release_surface_readback(&rb);
16392 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16393 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16396 /* Test Fetch4 with depth textures. */
16397 for (i = 0; i < ARRAY_SIZE(depth_tests); ++i)
16399 D3DFORMAT format = depth_tests[i].format;
16400 IDirect3DTexture9 *depth_texture;
16401 IDirect3DSurface9 *ds;
16403 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
16404 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format)))
16406 skip("Skipping %s depth test, unsupported format.\n", depth_tests[i].name);
16407 continue;
16410 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1,
16411 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &depth_texture, NULL);
16412 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16413 hr = IDirect3DTexture9_GetSurfaceLevel(depth_texture, 0, &ds);
16414 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16415 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16416 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16417 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
16418 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16419 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
16420 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16421 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
16422 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16423 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
16424 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16425 hr = IDirect3DDevice9_SetSamplerState(device, 0,
16426 D3DSAMP_MIPMAPLODBIAS, MAKEFOURCC('G','E','T','1'));
16427 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16429 /* Setup the depth/stencil surface. */
16430 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
16431 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16433 /* Render to the depth surface. */
16434 hr = IDirect3DDevice9_BeginScene(device);
16435 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16436 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
16437 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16438 hr = IDirect3DDevice9_EndScene(device);
16439 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16441 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16442 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16443 IDirect3DSurface9_Release(ds);
16444 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
16445 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16446 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)depth_texture);
16447 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16449 /* Set a shader for depth sampling, otherwise Windows does not show
16450 * anything. */
16451 hr = IDirect3DDevice9_SetVertexShader(device, vs);
16452 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16453 hr = IDirect3DDevice9_SetPixelShader(device, ps[1]); /* texld */
16454 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16456 for (j = 0; j < 2; ++j)
16458 hr = IDirect3DDevice9_SetSamplerState(device, 0,
16459 D3DSAMP_MIPMAPLODBIAS, MAKEFOURCC('G','E','T', j ? '4' : '1' ));
16460 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16462 /* Do the actual shadow mapping. */
16463 hr = IDirect3DDevice9_BeginScene(device);
16464 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16465 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
16466 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16467 hr = IDirect3DDevice9_EndScene(device);
16468 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16470 get_rt_readback(original_rt, &rb);
16471 for (k = 0; k < ARRAY_SIZE(expected_depth[depth_tests[i].index]); ++k)
16473 x = expected_depth[depth_tests[i].index][k].x;
16474 y = expected_depth[depth_tests[i].index][k].y;
16475 colour_amd = expected_depth[depth_tests[i].index][k].colour_amd;
16476 colour_intel = expected_depth[depth_tests[i].index][k].colour_intel;
16477 colour_off = expected_depth[depth_tests[i].index][k].colour_off;
16478 colour = get_readback_color(&rb, x, y);
16480 /* When Fetch4 is off, ignore the .g and .b channels on
16481 * windows. Some implementations will replicate the .r channel
16482 * to .g and .b, others will return 0 for .g and .b. */
16483 if (!j)
16484 ok(color_match(colour, colour_off, 2)
16485 || broken(color_match(colour & 0x00ff0000, colour_off & 0x00ff0000, 2)),
16486 "Test off: Got unexpected colour 0x%08x for format %s at (%u, %u).\n",
16487 colour, depth_tests[i].name, x, y);
16488 else
16489 ok(color_match(colour, colour_amd, 2) || broken(color_match(colour, colour_intel, 2)),
16490 "Test on: Got unexpected colour 0x%08x for format %s at (%u, %u).\n",
16491 colour, depth_tests[i].name, x, y);
16493 release_surface_readback(&rb);
16495 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16496 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16499 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
16500 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
16501 IDirect3DTexture9_Release(depth_texture);
16504 IDirect3DVolumeTexture9_Release(texture_3d);
16505 IDirect3DTexture9_Release(texture);
16506 for (i = 0; i < ARRAY_SIZE(ps); ++i)
16508 if (ps[i])
16509 IDirect3DPixelShader9_Release(ps[i]);
16511 IDirect3DPixelShader9_Release(ps_3d);
16512 IDirect3DVertexShader9_Release(vs);
16513 IDirect3DSurface9_Release(rt);
16514 IDirect3DSurface9_Release(original_rt);
16515 refcount = IDirect3DDevice9_Release(device);
16516 ok(!refcount, "Device has %lu references left.\n", refcount);
16517 done:
16518 IDirect3D9_Release(d3d);
16519 DestroyWindow(window);
16522 static void shadow_test(void)
16524 static const DWORD ps_code[] =
16526 0xffff0200, /* ps_2_0 */
16527 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
16528 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
16529 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
16530 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
16531 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
16532 0x03010042, 0x800f0001, 0xb0e40000, 0xa0e40800, /* texldp r1, t0, s0 */
16533 0x02000001, 0x80020000, 0x80000001, /* mov r0.y, r1.x */
16534 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
16535 0x0000ffff, /* end */
16537 struct
16539 D3DFORMAT format;
16540 const char *name;
16542 formats[] =
16544 {D3DFMT_D16_LOCKABLE, "D3DFMT_D16_LOCKABLE"},
16545 {D3DFMT_D32, "D3DFMT_D32"},
16546 {D3DFMT_D15S1, "D3DFMT_D15S1"},
16547 {D3DFMT_D24S8, "D3DFMT_D24S8"},
16548 {D3DFMT_D24X8, "D3DFMT_D24X8"},
16549 {D3DFMT_D24X4S4, "D3DFMT_D24X4S4"},
16550 {D3DFMT_D16, "D3DFMT_D16"},
16551 {D3DFMT_D32F_LOCKABLE, "D3DFMT_D32F_LOCKABLE"},
16552 {D3DFMT_D24FS8, "D3DFMT_D24FS8"},
16554 struct
16556 float x, y, z;
16557 float s, t, p, q;
16559 quad[] =
16561 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
16562 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
16563 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
16564 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
16566 struct
16568 unsigned int x, y, color;
16570 expected_colors[] =
16572 {400, 60, 0x00000000},
16573 {560, 180, 0xffff00ff},
16574 {560, 300, 0xffff00ff},
16575 {400, 420, 0xffffffff},
16576 {240, 420, 0xffffffff},
16577 { 80, 300, 0x00000000},
16578 { 80, 180, 0x00000000},
16579 {240, 60, 0x00000000},
16582 IDirect3DSurface9 *original_ds, *original_rt, *rt;
16583 struct surface_readback rb;
16584 IDirect3DPixelShader9 *ps;
16585 IDirect3DDevice9 *device;
16586 IDirect3D9 *d3d;
16587 ULONG refcount;
16588 D3DCAPS9 caps;
16589 HWND window;
16590 HRESULT hr;
16591 UINT i;
16593 window = create_window();
16594 d3d = Direct3DCreate9(D3D_SDK_VERSION);
16595 ok(!!d3d, "Failed to create a D3D object.\n");
16596 if (!(device = create_device(d3d, window, window, TRUE)))
16598 skip("Failed to create a D3D device, skipping tests.\n");
16599 goto done;
16602 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
16603 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#lx.\n", hr);
16604 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
16606 skip("No pixel shader 2.0 support, skipping shadow test.\n");
16607 IDirect3DDevice9_Release(device);
16608 goto done;
16611 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
16612 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#lx.\n", hr);
16613 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
16614 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#lx.\n", hr);
16616 hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
16617 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
16618 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#lx.\n", hr);
16619 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
16620 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#lx.\n", hr);
16622 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
16623 ok(SUCCEEDED(hr), "SetFVF failed, hr %#lx.\n", hr);
16624 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
16625 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
16626 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
16627 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
16628 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
16629 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
16630 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
16631 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
16633 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
16634 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#lx.\n", hr);
16635 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
16636 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#lx.\n", hr);
16637 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
16638 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#lx.\n", hr);
16639 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
16640 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#lx.\n", hr);
16641 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
16642 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#lx.\n", hr);
16644 for (i = 0; i < ARRAY_SIZE(formats); ++i)
16646 D3DFORMAT format = formats[i].format;
16647 IDirect3DTexture9 *texture;
16648 IDirect3DSurface9 *ds;
16649 unsigned int j;
16651 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
16652 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format)))
16653 continue;
16655 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
16656 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture, NULL);
16657 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#lx.\n", hr);
16659 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
16660 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#lx.\n", hr);
16662 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16663 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#lx.\n", hr);
16665 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
16666 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#lx.\n", hr);
16668 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
16669 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#lx.\n", hr);
16671 /* Setup the depth/stencil surface. */
16672 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
16673 ok(SUCCEEDED(hr), "Clear failed, hr %#lx.\n", hr);
16675 hr = IDirect3DDevice9_BeginScene(device);
16676 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
16677 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16678 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
16679 hr = IDirect3DDevice9_EndScene(device);
16680 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
16682 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16683 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#lx.\n", hr);
16684 IDirect3DSurface9_Release(ds);
16686 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
16687 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#lx.\n", hr);
16689 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
16690 ok(SUCCEEDED(hr), "SetTexture failed, hr %#lx.\n", hr);
16692 hr = IDirect3DDevice9_SetPixelShader(device, ps);
16693 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#lx.\n", hr);
16695 /* Do the actual shadow mapping. */
16696 hr = IDirect3DDevice9_BeginScene(device);
16697 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
16698 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16699 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
16700 hr = IDirect3DDevice9_EndScene(device);
16701 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
16703 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
16704 ok(SUCCEEDED(hr), "SetTexture failed, hr %#lx.\n", hr);
16705 IDirect3DTexture9_Release(texture);
16707 get_rt_readback(original_rt, &rb);
16708 for (j = 0; j < ARRAY_SIZE(expected_colors); ++j)
16710 unsigned int color = get_readback_color(&rb, expected_colors[j].x, expected_colors[j].y);
16711 /* Geforce 7 on Windows returns 1.0 in alpha when the depth format is D24S8 or D24X8,
16712 * whereas other GPUs (all AMD, newer Nvidia) return the same value they return in .rgb.
16713 * Accept alpha mismatches as broken but make sure to check the color channels. */
16714 ok(color_match(color, expected_colors[j].color, 0)
16715 || broken(color_match(color & 0x00ffffff, expected_colors[j].color & 0x00ffffff, 0)),
16716 "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
16717 expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
16718 formats[i].name, color);
16720 release_surface_readback(&rb);
16722 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16723 ok(SUCCEEDED(hr), "Present failed, hr %#lx.\n", hr);
16726 IDirect3DPixelShader9_Release(ps);
16727 IDirect3DSurface9_Release(original_ds);
16728 IDirect3DSurface9_Release(original_rt);
16729 IDirect3DSurface9_Release(rt);
16730 refcount = IDirect3DDevice9_Release(device);
16731 ok(!refcount, "Device has %lu references left.\n", refcount);
16732 done:
16733 IDirect3D9_Release(d3d);
16734 DestroyWindow(window);
16737 static void clip_planes(IDirect3DDevice9 *device, const char *test_name)
16739 static const struct
16741 struct vec3 position;
16742 DWORD diffuse;
16744 quad1[] =
16746 {{-1.0f, -1.0f, 0.0f}, 0xfff9e814},
16747 {{-1.0f, 1.0f, 0.0f}, 0xfff9e814},
16748 {{ 1.0f, -1.0f, 0.0f}, 0xfff9e814},
16749 {{ 1.0f, 1.0f, 0.0f}, 0xfff9e814},
16751 quad2[] =
16753 {{-1.0f, -1.0f, 0.0f}, 0xff002b7f},
16754 {{-1.0f, 1.0f, 0.0f}, 0xff002b7f},
16755 {{ 1.0f, -1.0f, 0.0f}, 0xff002b7f},
16756 {{ 1.0f, 1.0f, 0.0f}, 0xff002b7f},
16758 unsigned int color;
16759 HRESULT hr;
16761 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 1.0, 0);
16762 ok(SUCCEEDED(hr), "Clear failed, hr %#lx.\n", hr);
16764 hr = IDirect3DDevice9_BeginScene(device);
16765 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
16767 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
16768 ok(SUCCEEDED(hr), "SetFVF failed, hr %#lx.\n", hr);
16770 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
16771 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
16772 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
16773 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
16775 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0x1);
16776 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
16777 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
16778 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
16780 hr = IDirect3DDevice9_EndScene(device);
16781 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
16783 color = getPixelColor(device, 1, 240);
16784 ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
16785 color = getPixelColor(device, 638, 240);
16786 ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
16788 color = getPixelColor(device, 1, 241);
16789 ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
16790 color = getPixelColor(device, 638, 241);
16791 ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
16794 static void clip_planes_test(void)
16796 IDirect3DSurface9 *offscreen_surface, *original_rt;
16797 IDirect3DTexture9 *offscreen = NULL;
16798 IDirect3DVertexShader9 *shader;
16799 IDirect3DDevice9 *device;
16800 IDirect3D9 *d3d;
16801 ULONG refcount;
16802 D3DCAPS9 caps;
16803 HWND window;
16804 HRESULT hr;
16806 static const float plane0[4] = {0.0f, 1.0f, 0.0f, 0.5f / 480.0f}; /* a quarter-pixel offset */
16807 static const DWORD shader_code[] =
16809 0xfffe0200, /* vs_2_0 */
16810 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
16811 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
16812 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
16813 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
16814 0x0000ffff /* end */
16817 window = create_window();
16818 d3d = Direct3DCreate9(D3D_SDK_VERSION);
16819 ok(!!d3d, "Failed to create a D3D object.\n");
16820 if (!(device = create_device(d3d, window, window, TRUE)))
16822 skip("Failed to create a D3D device, skipping tests.\n");
16823 goto done;
16826 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
16827 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
16828 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
16830 skip("No vs_2_0 support, skipping tests.\n");
16831 IDirect3DDevice9_Release(device);
16832 goto done;
16835 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
16836 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#lx.\n", hr);
16838 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
16839 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
16840 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
16841 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
16842 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
16843 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
16844 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
16845 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
16847 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
16848 ok(hr == S_OK, "Got hr %#lx.\n", hr);
16849 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
16850 ok(hr == S_OK, "Got hr %#lx.\n", hr);
16852 IDirect3DDevice9_SetClipPlane(device, 0, plane0);
16854 clip_planes(device, "Onscreen FFP");
16856 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen, NULL);
16857 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#lx.\n", hr);
16858 hr = IDirect3DTexture9_GetSurfaceLevel(offscreen, 0, &offscreen_surface);
16859 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#lx.\n", hr);
16860 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
16861 ok(hr == S_OK, "Got hr %#lx.\n", hr);
16863 clip_planes(device, "Offscreen FFP");
16865 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16866 ok(hr == S_OK, "Got hr %#lx.\n", hr);
16868 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
16869 ok(hr == S_OK, "Got hr %#lx.\n", hr);
16870 hr = IDirect3DDevice9_SetVertexShader(device, shader);
16871 ok(hr == S_OK, "Got hr %#lx.\n", hr);
16873 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
16874 ok(hr == S_OK, "Got hr %#lx.\n", hr);
16876 clip_planes(device, "Onscreen vertex shader");
16878 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
16879 ok(hr == S_OK, "Got hr %#lx.\n", hr);
16881 clip_planes(device, "Offscreen vertex shader");
16883 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16884 ok(hr == S_OK, "Got hr %#lx.\n", hr);
16886 IDirect3DVertexShader9_Release(shader);
16887 IDirect3DSurface9_Release(original_rt);
16888 IDirect3DSurface9_Release(offscreen_surface);
16889 IDirect3DTexture9_Release(offscreen);
16890 refcount = IDirect3DDevice9_Release(device);
16891 ok(!refcount, "Device has %lu references left.\n", refcount);
16892 done:
16893 IDirect3D9_Release(d3d);
16894 DestroyWindow(window);
16897 static void fp_special_test(void)
16899 /* Microsoft's assembler generates nan and inf with "1.#QNAN" and "1.#INF." respectively */
16900 static const DWORD vs_header[] =
16902 0xfffe0200, /* vs_2_0 */
16903 0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0 */
16904 0x05000051, 0xa00f0001, 0x7fc00000, 0xff800000, 0x7f800000, 0x00000000, /* def c1, nan, -inf, inf, 0 */
16905 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
16906 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
16909 static const DWORD vs_log[] = {0x0200000f, 0x80010000, 0x90000001}; /* log r0.x, v1.x */
16910 static const DWORD vs_pow[] =
16911 {0x03000020, 0x80010000, 0x90000001, 0x90000001}; /* pow r0.x, v1.x, v1.x */
16912 static const DWORD vs_nrm[] = {0x02000024, 0x80070000, 0x90000001}; /* nrm r0.xyz, v1.x */
16913 static const DWORD vs_rcp1[] = {0x02000006, 0x80010000, 0x90000001}; /* rcp r0.x, v1.x */
16914 static const DWORD vs_rcp2[] = {0x02000006, 0x80010000, 0x91000001}; /* rcp r0.x, -v1.x */
16915 static const DWORD vs_rsq1[] = {0x02000007, 0x80010000, 0x90000001}; /* rsq r0.x, v1.x */
16916 static const DWORD vs_rsq2[] = {0x02000007, 0x80010000, 0x91000001}; /* rsq r0.x, -v1.x */
16917 static const DWORD vs_lit[] = {0x02000010, 0x800f0000, 0x90000001, /* lit r0, v1.xxxx */
16918 0x02000001, 0x80010000, 0x80aa0000}; /* mov r0.x, v0.z */
16919 static const DWORD vs_def1[] = {0x02000001, 0x80010000, 0xa0000001}; /* mov r0.x, c1.x */
16920 static const DWORD vs_def2[] = {0x02000001, 0x80010000, 0xa0550001}; /* mov r0.x, c1.y */
16921 static const DWORD vs_def3[] = {0x02000001, 0x80010000, 0xa0aa0001}; /* mov r0.x, c1.z */
16923 static const DWORD vs_footer[] =
16925 0x03000005, 0x80020000, 0x80000000, 0xa0ff0000, /* mul r0.y, r0.x, c0.w */
16926 0x0300000d, 0x80040000, 0x80000000, 0x80550000, /* sge r0.z, r0.x, r0.y */
16927 0x0300000d, 0x80020000, 0x80e40000, 0x80000000, /* sge r0.y, r0, r0.x */
16928 0x03000005, 0x80040000, 0x80550000, 0x80e40000, /* mul r0.z, r0.y, r0 */
16929 0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000, /* max r0.w, -r0.z, r0.z */
16930 0x0300000c, 0x80020000, 0x80000000, 0x80000000, /* slt r0.y, r0.x, r0.x */
16931 0x03000002, 0x80040000, 0x80550000, 0x80550000, /* add r0.z, r0.y, r0.y */
16932 0x0300000c, 0x80020000, 0xa0000000, 0x80ff0000, /* slt r0.y, c0.x, r0.w */
16933 0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000, /* max r0.w, -r0.z, r0.z */
16934 0x03000002, 0x80040000, 0x81550000, 0xa0e40000, /* add r0.z, -r0.y, c0 */
16935 0x0300000c, 0x80080000, 0xa0000000, 0x80e40000, /* slt r0.w, c0.x, r0 */
16936 0x03000005, 0x80040000, 0x80ff0000, 0x80e40000, /* mul r0.z, r0.w, r0 */
16937 0x04000004, 0x80020000, 0x80aa0000, 0xa0e40000, 0x80e40000, /* mad r0.y, r0.z, c0, r0 */
16938 0x02000001, 0xe0030000, 0x80e40000, /* mov oT0.xy, r0 */
16939 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
16940 0x0000ffff, /* end */
16943 static const struct
16945 const char *name;
16946 const DWORD *ops;
16947 DWORD size;
16948 unsigned int r500, r600, nv40, nv50, warp;
16950 vs_body[] =
16952 /* The basic ideas here are:
16953 * 2.0 * +/-INF == +/-INF
16954 * NAN != NAN
16956 * The vertex shader value is written to the red component, with 0.0
16957 * and +/-INF mapping to 0xff, and NAN to 0x7f. Anything else should
16958 * result in 0x00. The pixel shader value is written to the green
16959 * component, but here 0.0 also results in 0x00. The actual value is
16960 * written to the blue component.
16962 * There are considerable differences between graphics cards in how
16963 * these are handled, but pow and nrm never generate INF or NAN on
16964 * real hardware. */
16965 {"log", vs_log, sizeof(vs_log), 0x00000000, 0x00000000, 0x00ff0000, 0x00ff7f00, 0x00ff8000},
16966 {"pow", vs_pow, sizeof(vs_pow), 0x000000ff, 0x000000ff, 0x0000ff00, 0x000000ff, 0x00008000},
16967 {"nrm", vs_nrm, sizeof(vs_nrm), 0x00ff0000, 0x00ff0000, 0x0000ff00, 0x00ff0000, 0x00008000},
16968 {"rcp1", vs_rcp1, sizeof(vs_rcp1), 0x000000ff, 0x000000ff, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
16969 {"rcp2", vs_rcp2, sizeof(vs_rcp2), 0x000000ff, 0x00000000, 0x00ff0000, 0x00ff7f00, 0x00ff8000},
16970 {"rsq1", vs_rsq1, sizeof(vs_rsq1), 0x000000ff, 0x000000ff, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
16971 {"rsq2", vs_rsq2, sizeof(vs_rsq2), 0x000000ff, 0x000000ff, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
16972 {"lit", vs_lit, sizeof(vs_lit), 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
16973 {"def1", vs_def1, sizeof(vs_def1), 0x000000ff, 0x00007f00, 0x0000ff00, 0x00007f00, 0x00008000},
16974 {"def2", vs_def2, sizeof(vs_def2), 0x00ff0000, 0x00ff7f00, 0x00ff0000, 0x00ff7f00, 0x00ff8000},
16975 {"def3", vs_def3, sizeof(vs_def3), 0x00ff00ff, 0x00ff7f00, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
16978 static const DWORD ps_code[] =
16980 0xffff0200, /* ps_2_0 */
16981 0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0 */
16982 0x0200001f, 0x80000000, 0xb0030000, /* dcl t0.xy */
16983 0x0300000b, 0x80010001, 0xb0e40000, 0xa0e40000, /* max r1.x, t0, c0 */
16984 0x0300000a, 0x80010000, 0xb0e40000, 0xa0e40000, /* min r0.x, t0, c0 */
16985 0x03000002, 0x80010000, 0x80e40000, 0x81e40001, /* add r0.x, r0, -r1 */
16986 0x04000004, 0x80010001, 0xb0e40000, 0xa0ff0000, 0xb1e40000, /* mad r1.x, t0, c0.w. -t0 */
16987 0x02000023, 0x80010002, 0x80e40001, /* abs r2.x, r1 */
16988 0x02000023, 0x80010000, 0x80e40000, /* abs r0.x, r0 */
16989 0x02000023, 0x80010001, 0xb0e40000, /* abs r1.x, t0 */
16990 0x04000058, 0x80010002, 0x81e40002, 0xa0aa0000, 0xa0e40000, /* cmp r2.x, -r2, c0.z, c0 */
16991 0x02000023, 0x80010002, 0x80e40002, /* abs r2.x, r2 */
16992 0x04000058, 0x80010001, 0x81e40001, 0xa0aa0000, 0xa0e40000, /* cmp r1.x, -r1, c0.z, c0 */
16993 0x02000023, 0x80010001, 0x80e40001, /* abs r1.x, r1 */
16994 0x04000058, 0x80010003, 0x81e40002, 0xa0aa0000, 0xa0e40000, /* cmp r3.x, -r2, c0.z, c0 */
16995 0x04000058, 0x80010002, 0x81e40001, 0xa0aa0000, 0xa0e40000, /* cmp r2.x, -r1, c0.z, c0 */
16996 0x04000058, 0x80010000, 0x81e40000, 0xa0550000, 0xa0e40000, /* cmp r0.x, -r0, c0.y, c0 */
16997 0x03000005, 0x80010002, 0x80e40002, 0x80e40003, /* mul r2.x, r2, r3 */
16998 0x04000058, 0x80010000, 0x81e40002, 0xa0aa0000, 0x80e40000, /* cmp r0.x, -r2, c0.z, r0 */
16999 0x04000058, 0x80020000, 0x81000001, 0x80000000, 0xa0000000, /* cmp r0.y, -r1.x, r0.x, c0.x */
17000 0x02000001, 0x80050000, 0xb0c90000, /* mov r0.xz, t0.yzxw */
17001 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.w, c0.z */
17002 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
17003 0x0000ffff, /* end */
17006 static const struct
17008 float x, y, z;
17009 float s;
17011 quad[] =
17013 { -1.0f, 1.0f, 0.0f, 0.0f},
17014 { 1.0f, 1.0f, 1.0f, 0.0f},
17015 { -1.0f, -1.0f, 0.0f, 0.0f},
17016 { 1.0f, -1.0f, 1.0f, 0.0f},
17019 IDirect3DPixelShader9 *ps;
17020 IDirect3DDevice9 *device;
17021 UINT body_size = 0;
17022 IDirect3D9 *d3d;
17023 DWORD *vs_code;
17024 ULONG refcount;
17025 D3DCAPS9 caps;
17026 HWND window;
17027 HRESULT hr;
17028 UINT i;
17030 window = create_window();
17031 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17032 ok(!!d3d, "Failed to create a D3D object.\n");
17033 if (!(device = create_device(d3d, window, window, TRUE)))
17035 skip("Failed to create a D3D device, skipping tests.\n");
17036 goto done;
17039 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
17040 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#lx.\n", hr);
17041 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0) || caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
17043 skip("No shader model 2.0 support, skipping floating point specials test.\n");
17044 IDirect3DDevice9_Release(device);
17045 goto done;
17048 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE1(0));
17049 ok(SUCCEEDED(hr), "SetFVF failed, hr %#lx.\n", hr);
17051 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
17052 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#lx.\n", hr);
17053 hr = IDirect3DDevice9_SetPixelShader(device, ps);
17054 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#lx.\n", hr);
17056 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
17057 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
17059 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
17060 ok(SUCCEEDED(hr), "Clear failed, hr %#lx.\n", hr);
17062 for (i = 0; i < ARRAY_SIZE(vs_body); ++i)
17064 if (vs_body[i].size > body_size) body_size = vs_body[i].size;
17067 vs_code = malloc(sizeof(vs_header) + body_size + sizeof(vs_footer));
17068 memcpy(vs_code, vs_header, sizeof(vs_header));
17070 for (i = 0; i < ARRAY_SIZE(vs_body); ++i)
17072 DWORD offset = ARRAY_SIZE(vs_header);
17073 IDirect3DVertexShader9 *vs;
17074 unsigned int color;
17076 memcpy(vs_code + offset, vs_body[i].ops, vs_body[i].size);
17077 offset += vs_body[i].size / sizeof(*vs_body[i].ops);
17078 memcpy(vs_code + offset, vs_footer, sizeof(vs_footer));
17080 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
17081 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#lx.\n", hr);
17082 hr = IDirect3DDevice9_SetVertexShader(device, vs);
17083 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#lx.\n", hr);
17085 hr = IDirect3DDevice9_BeginScene(device);
17086 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
17087 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17088 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
17089 hr = IDirect3DDevice9_EndScene(device);
17090 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
17092 color = getPixelColor(device, 320, 240);
17093 ok(color_match(color, vs_body[i].r500, 1)
17094 || color_match(color, vs_body[i].r600, 1)
17095 || color_match(color, vs_body[i].nv40, 1)
17096 || color_match(color, vs_body[i].nv50, 1)
17097 || broken(color_match(color, vs_body[i].warp, 1)),
17098 "Expected color 0x%08x, 0x%08x, 0x%08x or 0x%08x for instruction \"%s\", got 0x%08x.\n",
17099 vs_body[i].r500, vs_body[i].r600, vs_body[i].nv40, vs_body[i].nv50, vs_body[i].name, color);
17101 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17102 ok(SUCCEEDED(hr), "Present failed, hr %#lx.\n", hr);
17104 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
17105 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#lx.\n", hr);
17106 IDirect3DVertexShader9_Release(vs);
17109 free(vs_code);
17111 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
17112 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#lx.\n", hr);
17113 IDirect3DPixelShader9_Release(ps);
17114 refcount = IDirect3DDevice9_Release(device);
17115 ok(!refcount, "Device has %lu references left.\n", refcount);
17116 done:
17117 IDirect3D9_Release(d3d);
17118 DestroyWindow(window);
17121 static void srgbwrite_format_test(void)
17123 IDirect3D9 *d3d;
17124 IDirect3DSurface9 *rt, *backbuffer;
17125 IDirect3DTexture9 *texture;
17126 IDirect3DDevice9 *device;
17127 unsigned int color, i;
17128 ULONG refcount;
17129 HWND window;
17130 HRESULT hr;
17132 static const unsigned int color_rgb = 0x00808080, color_srgb = 0x00bcbcbc;
17133 static const struct
17135 D3DFORMAT fmt;
17136 const char *name;
17138 formats[] =
17140 { D3DFMT_R5G6B5, "D3DFMT_R5G6B5" },
17141 { D3DFMT_X8R8G8B8, "D3DFMT_X8R8G8B8" },
17142 { D3DFMT_A8R8G8B8, "D3DFMT_A8R8G8B8" },
17143 { D3DFMT_A16B16G16R16F, "D3DFMT_A16B16G16R16F" },
17144 { D3DFMT_A32B32G32R32F, "D3DFMT_A32B32G32R32F" },
17146 static const struct
17148 float x, y, z;
17149 float u, v;
17151 quad[] =
17153 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f},
17154 {-1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
17155 { 1.0f, -1.0f, 0.1f, 0.0f, 1.0f},
17156 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f}
17159 window = create_window();
17160 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17161 ok(!!d3d, "Failed to create a D3D object.\n");
17162 if (!(device = create_device(d3d, window, window, TRUE)))
17164 skip("Failed to create a D3D device, skipping tests.\n");
17165 goto done;
17168 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
17169 ok(SUCCEEDED(hr), "SetFVF failed, hr %#lx.\n", hr);
17170 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
17171 ok(SUCCEEDED(hr), "GetBackBuffer failed, hr %#lx.\n", hr);
17172 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
17173 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#lx.\n", hr);
17174 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
17175 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
17177 for(i = 0; i < ARRAY_SIZE(formats); i++)
17179 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
17180 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, formats[i].fmt)))
17182 skip("Format %s not supported as render target, skipping test.\n",
17183 formats[i].name);
17184 continue;
17187 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, D3DUSAGE_RENDERTARGET,
17188 formats[i].fmt, D3DPOOL_DEFAULT, &texture, NULL);
17189 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#lx.\n", hr);
17190 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
17191 ok(SUCCEEDED(hr), "Clear failed, hr %#lx.\n", hr);
17193 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &rt);
17194 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#lx.\n", hr);
17195 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
17196 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#lx.\n", hr);
17197 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
17198 ok(SUCCEEDED(hr), "Clear failed, hr %#lx.\n", hr);
17200 hr = IDirect3DDevice9_BeginScene(device);
17201 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
17203 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
17204 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
17205 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
17206 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#lx.\n", hr);
17207 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17208 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
17210 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
17211 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
17212 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
17213 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
17214 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
17215 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
17216 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
17217 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#lx.\n", hr);
17218 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17219 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
17220 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
17221 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
17223 hr = IDirect3DDevice9_EndScene(device);
17224 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
17226 IDirect3DSurface9_Release(rt);
17227 IDirect3DTexture9_Release(texture);
17229 color = getPixelColor(device, 360, 240);
17230 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
17231 D3DUSAGE_QUERY_SRGBWRITE,
17232 D3DRTYPE_TEXTURE, formats[i].fmt) == D3D_OK)
17234 /* Big slop for R5G6B5 */
17235 ok(color_match(color, color_srgb, 5), "Format %s supports srgb, expected color 0x%08x, got 0x%08x\n",
17236 formats[i].name, color_srgb, color);
17238 else
17240 /* Big slop for R5G6B5 */
17241 ok(color_match(color, color_rgb, 5), "Format %s does not support srgb, expected color 0x%08x, got 0x%08x\n",
17242 formats[i].name, color_rgb, color);
17245 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17246 ok(SUCCEEDED(hr), "Present failed, hr %#lx.\n", hr);
17249 IDirect3DSurface9_Release(backbuffer);
17250 refcount = IDirect3DDevice9_Release(device);
17251 ok(!refcount, "Device has %lu references left.\n", refcount);
17252 done:
17253 IDirect3D9_Release(d3d);
17254 DestroyWindow(window);
17257 static void ds_size_test(void)
17259 IDirect3DSurface9 *ds, *rt, *old_rt, *old_ds, *readback;
17260 IDirect3DDevice9 *device;
17261 DWORD num_passes;
17262 IDirect3D9 *d3d;
17263 ULONG refcount;
17264 HWND window;
17265 HRESULT hr;
17267 static const struct
17269 float x, y, z;
17271 quad[] =
17273 {-1.0f, -1.0f, 0.0f},
17274 {-1.0f, 1.0f, 0.0f},
17275 { 1.0f, -1.0f, 0.0f},
17276 { 1.0f, 1.0f, 0.0f},
17279 window = create_window();
17280 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17281 ok(!!d3d, "Failed to create a D3D object.\n");
17282 if (!(device = create_device(d3d, window, window, TRUE)))
17284 skip("Failed to create a D3D device, skipping tests.\n");
17285 goto done;
17288 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
17289 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#lx.\n", hr);
17290 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 32, 32, D3DFMT_D24X8, D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
17291 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateDepthStencilSurface failed, hr %#lx.\n", hr);
17292 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
17293 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr %#lx.\n", hr);
17295 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
17296 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
17298 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
17299 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#lx.\n", hr);
17300 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
17301 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#lx.\n", hr);
17302 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
17303 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#lx.\n", hr);
17304 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
17305 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#lx.\n", hr);
17306 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
17307 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#lx.\n", hr);
17308 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &old_ds);
17309 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetDepthStencilSurface failed, hr %#lx.\n", hr);
17310 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
17311 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#lx.\n", hr);
17312 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
17313 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#lx.\n", hr);
17314 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
17315 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#lx.\n", hr);
17317 /* The D3DCLEAR_TARGET clear works. D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER returns OK,
17318 * but does not change the surface's contents. */
17319 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000FF, 0.0f, 0);
17320 ok(SUCCEEDED(hr), "Target clear failed, hr %#lx.\n", hr);
17321 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.2f, 0);
17322 ok(SUCCEEDED(hr), "Z Buffer clear failed, hr %#lx.\n", hr);
17323 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 0.5f, 0);
17324 ok(SUCCEEDED(hr), "Target and Z Buffer clear failed, hr %#lx.\n", hr);
17326 /* Nvidia does not clear the surface(The color is still 0x000000ff), AMD does(the color is 0x00ff0000) */
17328 /* Turning on any depth-related state results in a ValidateDevice failure */
17329 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
17330 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#lx.\n", hr);
17331 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
17332 ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "Got hr %#lx.\n", hr);
17333 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
17334 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#lx.\n", hr);
17335 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
17336 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#lx.\n", hr);
17337 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
17338 ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "Got hr %#lx.\n", hr);
17340 /* Try to draw with the device in an invalid state. */
17341 hr = IDirect3DDevice9_BeginScene(device);
17342 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
17343 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17344 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
17345 hr = IDirect3DDevice9_EndScene(device);
17346 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
17348 /* Don't check the resulting draw unless we find an app that needs it. On
17349 * NVIDIA ValidateDevice() returns CONFLICTINGRENDERSTATE, so the result
17350 * is undefined. On AMD D3D seems to assume the stored Z buffer value is
17351 * 0.0 for all pixels, even those that are covered by the depth buffer. */
17353 hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
17354 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#lx.\n", hr);
17355 hr = IDirect3DDevice9_SetDepthStencilSurface(device, old_ds);
17356 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#lx.\n", hr);
17357 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
17358 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#lx.\n", hr);
17360 IDirect3DSurface9_Release(readback);
17361 IDirect3DSurface9_Release(ds);
17362 IDirect3DSurface9_Release(rt);
17363 IDirect3DSurface9_Release(old_rt);
17364 IDirect3DSurface9_Release(old_ds);
17365 refcount = IDirect3DDevice9_Release(device);
17366 ok(!refcount, "Device has %lu references left.\n", refcount);
17367 done:
17368 IDirect3D9_Release(d3d);
17369 DestroyWindow(window);
17372 static void unbound_sampler_test(void)
17374 IDirect3DPixelShader9 *ps, *ps_cube, *ps_volume;
17375 IDirect3DSurface9 *rt, *old_rt;
17376 IDirect3DDevice9 *device;
17377 unsigned int color;
17378 IDirect3D9 *d3d;
17379 ULONG refcount;
17380 D3DCAPS9 caps;
17381 HWND window;
17382 HRESULT hr;
17384 static const DWORD ps_code[] =
17386 0xffff0200, /* ps_2_0 */
17387 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
17388 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
17389 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
17390 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
17391 0x0000ffff, /* end */
17393 static const DWORD ps_code_cube[] =
17395 0xffff0200, /* ps_2_0 */
17396 0x0200001f, 0x98000000, 0xa00f0800, /* dcl_cube s0 */
17397 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
17398 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
17399 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
17400 0x0000ffff, /* end */
17402 static const DWORD ps_code_volume[] =
17404 0xffff0200, /* ps_2_0 */
17405 0x0200001f, 0xa0000000, 0xa00f0800, /* dcl_volume s0 */
17406 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
17407 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
17408 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
17409 0x0000ffff, /* end */
17412 static const struct
17414 float x, y, z;
17415 float u, v;
17417 quad[] =
17419 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f},
17420 {-1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
17421 { 1.0f, -1.0f, 0.1f, 0.0f, 1.0f},
17422 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f}
17425 window = create_window();
17426 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17427 ok(!!d3d, "Failed to create a D3D object.\n");
17428 if (!(device = create_device(d3d, window, window, TRUE)))
17430 skip("Failed to create a D3D device, skipping tests.\n");
17431 goto done;
17434 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
17435 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
17436 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
17438 skip("No ps_2_0 support, skipping tests.\n");
17439 IDirect3DDevice9_Release(device);
17440 goto done;
17442 if (!(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP) || !(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP))
17444 skip("No cube / volume texture support, skipping tests.\n");
17445 IDirect3DDevice9_Release(device);
17446 goto done;
17449 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
17450 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStage failed, hr %#lx.\n", hr);
17452 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
17453 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#lx.\n", hr);
17454 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_cube, &ps_cube);
17455 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#lx.\n", hr);
17456 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_volume, &ps_volume);
17457 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#lx.\n", hr);
17459 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL);
17460 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#lx.\n", hr);
17462 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
17463 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#lx.\n", hr);
17465 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
17466 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#lx.\n", hr);
17468 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 );
17469 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#lx.\n", hr);
17471 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x56ffffff, 1.0f, 0);
17472 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#lx.\n", hr);
17474 hr = IDirect3DDevice9_SetPixelShader(device, ps);
17475 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#lx.\n", hr);
17477 hr = IDirect3DDevice9_BeginScene(device);
17478 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
17479 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17480 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
17481 hr = IDirect3DDevice9_EndScene(device);
17482 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
17484 color = getPixelColorFromSurface(rt, 32, 32);
17485 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
17487 /* Now try with a cube texture */
17488 hr = IDirect3DDevice9_SetPixelShader(device, ps_cube);
17489 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#lx.\n", hr);
17491 hr = IDirect3DDevice9_BeginScene(device);
17492 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
17493 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17494 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
17495 hr = IDirect3DDevice9_EndScene(device);
17496 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
17498 color = getPixelColorFromSurface(rt, 32, 32);
17499 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
17501 /* And then with a volume texture */
17502 hr = IDirect3DDevice9_SetPixelShader(device, ps_volume);
17503 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#lx.\n", hr);
17505 hr = IDirect3DDevice9_BeginScene(device);
17506 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
17507 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17508 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
17509 hr = IDirect3DDevice9_EndScene(device);
17510 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
17512 color = getPixelColorFromSurface(rt, 32, 32);
17513 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
17515 IDirect3DSurface9_Release(rt);
17516 IDirect3DSurface9_Release(old_rt);
17517 IDirect3DPixelShader9_Release(ps);
17518 IDirect3DPixelShader9_Release(ps_cube);
17519 IDirect3DPixelShader9_Release(ps_volume);
17520 refcount = IDirect3DDevice9_Release(device);
17521 ok(!refcount, "Device has %lu references left.\n", refcount);
17522 done:
17523 IDirect3D9_Release(d3d);
17524 DestroyWindow(window);
17527 static void update_surface_test(void)
17529 static const BYTE blocks[][8] =
17531 {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00}, /* White */
17532 {0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Red */
17533 {0xe0, 0xff, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00}, /* Yellow */
17534 {0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Green */
17535 {0xff, 0x07, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Cyan */
17536 {0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00}, /* Blue */
17537 {0x1f, 0xf8, 0x1f, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Magenta */
17539 static const struct
17541 unsigned int x, y, color;
17543 expected_colors[] =
17545 { 18, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0xff)},
17546 { 57, 240, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff)},
17547 {109, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0xff)},
17548 {184, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
17549 {290, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
17550 {440, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
17551 {584, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
17553 static const struct
17555 float x, y, z, w;
17556 float u, v;
17558 tri[] =
17560 { 0.0f, 480.0f, 0.0f, 1.0f, 0.0f, 0.0f},
17561 { 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
17562 {640.0f, 240.0f, 0.0f, 10.0f, 100.0f, 0.5f},
17564 static const RECT rect_2x2 = {0, 0, 2, 2};
17565 static const struct
17567 UINT src_level;
17568 UINT dst_level;
17569 const RECT *r;
17570 HRESULT hr;
17572 block_size_tests[] =
17574 {1, 0, NULL, D3D_OK},
17575 {0, 1, NULL, D3DERR_INVALIDCALL},
17576 {5, 4, NULL, D3DERR_INVALIDCALL},
17577 {4, 5, NULL, D3DERR_INVALIDCALL},
17578 {4, 5, &rect_2x2, D3DERR_INVALIDCALL},
17579 {5, 5, &rect_2x2, D3D_OK},
17582 IDirect3DSurface9 *src_surface, *dst_surface;
17583 IDirect3DTexture9 *src_tex, *dst_tex;
17584 IDirect3DDevice9 *device;
17585 IDirect3D9 *d3d;
17586 ULONG refcount;
17587 UINT count, i;
17588 HWND window;
17589 HRESULT hr;
17591 window = create_window();
17592 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17593 ok(!!d3d, "Failed to create a D3D object.\n");
17594 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
17595 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1)))
17597 skip("DXT1 not supported, skipping tests.\n");
17598 goto done;
17600 if (!(device = create_device(d3d, window, window, TRUE)))
17602 skip("Failed to create a D3D device, skipping tests.\n");
17603 goto done;
17606 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_SYSTEMMEM, &src_tex, NULL);
17607 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
17608 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_DEFAULT, &dst_tex, NULL);
17609 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
17611 count = IDirect3DTexture9_GetLevelCount(src_tex);
17612 ok(count == 7, "Got level count %u, expected 7.\n", count);
17614 for (i = 0; i < count; ++i)
17616 UINT row_count, block_count, x, y;
17617 D3DSURFACE_DESC desc;
17618 BYTE *row, *block;
17619 D3DLOCKED_RECT r;
17621 hr = IDirect3DTexture9_GetLevelDesc(src_tex, i, &desc);
17622 ok(SUCCEEDED(hr), "Failed to get level desc, hr %#lx.\n", hr);
17624 hr = IDirect3DTexture9_LockRect(src_tex, i, &r, NULL, 0);
17625 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#lx.\n", hr);
17627 row_count = ((desc.Height + 3) & ~3) / 4;
17628 block_count = ((desc.Width + 3) & ~3) / 4;
17629 row = r.pBits;
17631 for (y = 0; y < row_count; ++y)
17633 block = row;
17634 for (x = 0; x < block_count; ++x)
17636 memcpy(block, blocks[i], sizeof(blocks[i]));
17637 block += sizeof(blocks[i]);
17639 row += r.Pitch;
17642 hr = IDirect3DTexture9_UnlockRect(src_tex, i);
17643 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#lx.\n", hr);
17646 for (i = 0; i < ARRAY_SIZE(block_size_tests); ++i)
17648 hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, block_size_tests[i].src_level, &src_surface);
17649 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#lx.\n", hr);
17650 hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, block_size_tests[i].dst_level, &dst_surface);
17651 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#lx.\n", hr);
17653 hr = IDirect3DDevice9_UpdateSurface(device, src_surface, block_size_tests[i].r, dst_surface, NULL);
17654 ok(hr == block_size_tests[i].hr, "Update surface returned %#lx for test %u, expected %#lx.\n",
17655 hr, i, block_size_tests[i].hr);
17657 IDirect3DSurface9_Release(dst_surface);
17658 IDirect3DSurface9_Release(src_surface);
17661 for (i = 0; i < count; ++i)
17663 hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, i, &src_surface);
17664 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#lx.\n", hr);
17665 hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, i, &dst_surface);
17666 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#lx.\n", hr);
17668 hr = IDirect3DDevice9_UpdateSurface(device, src_surface, NULL, dst_surface, NULL);
17669 ok(SUCCEEDED(hr), "Failed to update surface at level %u, hr %#lx.\n", i, hr);
17671 IDirect3DSurface9_Release(dst_surface);
17672 IDirect3DSurface9_Release(src_surface);
17675 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
17676 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
17677 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
17678 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#lx.\n", hr);
17679 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
17680 ok(SUCCEEDED(hr), "SetFVF failed, hr %#lx.\n", hr);
17681 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)dst_tex);
17682 ok(SUCCEEDED(hr), "SetTexture failed, hr %#lx.\n", hr);
17683 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
17684 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#lx.\n", hr);
17685 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
17686 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#lx.\n", hr);
17688 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0f, 0);
17689 ok(SUCCEEDED(hr), "Clear failed, hr %#lx.\n", hr);
17691 hr = IDirect3DDevice9_BeginScene(device);
17692 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
17693 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 1, tri, sizeof(*tri));
17694 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
17695 hr = IDirect3DDevice9_EndScene(device);
17696 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
17698 for (i = 0; i < ARRAY_SIZE(expected_colors); ++i)
17700 unsigned int color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
17701 ok(color_match(color, expected_colors[i].color, 0),
17702 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
17703 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
17706 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17707 ok(SUCCEEDED(hr), "Present failed, hr %#lx.\n", hr);
17709 IDirect3DTexture9_Release(dst_tex);
17710 IDirect3DTexture9_Release(src_tex);
17711 refcount = IDirect3DDevice9_Release(device);
17712 ok(!refcount, "Device has %lu references left.\n", refcount);
17713 done:
17714 IDirect3D9_Release(d3d);
17715 DestroyWindow(window);
17718 static void multisample_get_rtdata_test(void)
17720 IDirect3DSurface9 *original_ds, *original_rt, *rt, *readback;
17721 IDirect3DDevice9 *device;
17722 IDirect3D9 *d3d;
17723 ULONG refcount;
17724 HWND window;
17725 HRESULT hr;
17727 window = create_window();
17728 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17729 ok(!!d3d, "Failed to create a D3D object.\n");
17730 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
17731 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
17733 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping tests.\n");
17734 goto done;
17736 if (!(device = create_device(d3d, window, window, TRUE)))
17738 skip("Failed to create a D3D device, skipping tests.\n");
17739 goto done;
17742 hr = IDirect3DDevice9_CreateRenderTarget(device, 256, 256, D3DFMT_A8R8G8B8,
17743 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
17744 ok(SUCCEEDED(hr), "Failed to create render target, hr %#lx.\n", hr);
17745 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 256, 256, D3DFMT_A8R8G8B8,
17746 D3DPOOL_SYSTEMMEM, &readback, NULL);
17747 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#lx.\n", hr);
17749 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
17750 ok(SUCCEEDED(hr), "Failed to get render target, hr %#lx.\n", hr);
17751 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
17752 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#lx.\n", hr);
17754 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
17755 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
17756 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
17757 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#lx.\n", hr);
17759 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
17760 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#lx.\n", hr);
17761 hr = IDirect3DDevice9_GetRenderTargetData(device, rt, readback);
17762 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
17764 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
17765 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#lx.\n", hr);
17766 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
17767 ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#lx.\n", hr);
17769 IDirect3DSurface9_Release(original_ds);
17770 IDirect3DSurface9_Release(original_rt);
17771 IDirect3DSurface9_Release(readback);
17772 IDirect3DSurface9_Release(rt);
17773 refcount = IDirect3DDevice9_Release(device);
17774 ok(!refcount, "Device has %lu references left.\n", refcount);
17775 done:
17776 IDirect3D9_Release(d3d);
17777 DestroyWindow(window);
17780 static void test_multisample_get_front_buffer_data(void)
17782 IDirect3DSwapChain9 *swapchain;
17783 D3DPRESENT_PARAMETERS d3dpp;
17784 IDirect3DSurface9 *readback;
17785 IDirect3DTexture9 *texture;
17786 IDirect3DDevice9 *device;
17787 unsigned int color;
17788 IDirect3D9 *d3d;
17789 ULONG refcount;
17790 HWND window;
17791 HRESULT hr;
17793 window = create_window();
17794 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17795 ok(!!d3d, "Failed to create D3D object.\n");
17796 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
17797 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
17799 skip("Multisampling not supported for D3DFMT_A8R8G8B8.\n");
17800 goto done;
17802 if (!(device = create_device(d3d, window, window, FALSE)))
17804 skip("Failed to create D3D device.\n");
17805 goto done;
17808 hr = IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
17809 ok(hr == D3D_OK, "Failed to get the implicit swapchain, hr %#lx.\n", hr);
17810 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &d3dpp);
17811 ok(hr == D3D_OK, "Failed to get present parameters, hr %#lx.\n", hr);
17812 IDirect3DSwapChain9_Release(swapchain);
17813 d3dpp.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
17814 d3dpp.MultiSampleQuality = 0;
17815 hr = IDirect3DDevice9_Reset(device, &d3dpp);
17816 ok(hr == D3D_OK, "Failed to reset device, hr %#lx.\n", hr);
17818 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00f0ff0f, 0.0, 0);
17819 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#lx.\n", hr);
17820 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17821 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
17823 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 640, 480, D3DFMT_A8R8G8B8,
17824 D3DPOOL_SYSTEMMEM, &readback, NULL);
17825 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#lx.\n", hr);
17826 hr = IDirect3DDevice9_GetFrontBufferData(device, 0, readback);
17827 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
17828 color = getPixelColorFromSurface(readback, 320, 240);
17829 ok((color & 0x00ffffff) == 0x00f0ff0f, "Got unexpected color 0x%08x.\n", color);
17830 IDirect3DSurface9_Release(readback);
17832 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
17833 0, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &texture, NULL);
17834 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
17836 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &readback);
17837 ok(SUCCEEDED(hr), "Failed to create surface, hr %#lx.\n", hr);
17838 hr = IDirect3DDevice9_GetFrontBufferData(device, 0, readback);
17839 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
17840 color = getPixelColorFromSurface(readback, 320, 240);
17841 ok((color & 0x00ffffff) == 0x00f0ff0f, "Got unexpected color 0x%08x.\n", color);
17842 IDirect3DSurface9_Release(readback);
17843 IDirect3DTexture9_Release(texture);
17845 refcount = IDirect3DDevice9_Release(device);
17846 ok(!refcount, "Device has %lu references left.\n", refcount);
17847 done:
17848 IDirect3D9_Release(d3d);
17849 DestroyWindow(window);
17852 static void multisampled_depth_buffer_test(void)
17854 IDirect3DDevice9 *device = 0;
17855 IDirect3DSurface9 *original_rt, *rt, *readback, *ds, *original_ds;
17856 IDirect3D9 *d3d;
17857 D3DCAPS9 caps;
17858 HRESULT hr;
17859 D3DPRESENT_PARAMETERS present_parameters;
17860 unsigned int i;
17861 static const struct
17863 float x, y, z;
17864 D3DCOLOR color;
17866 quad_1[] =
17868 { -1.0f, 1.0f, 0.0f, 0xffff0000},
17869 { 1.0f, 1.0f, 1.0f, 0xffff0000},
17870 { -1.0f, -1.0f, 0.0f, 0xffff0000},
17871 { 1.0f, -1.0f, 1.0f, 0xffff0000},
17873 quad_2[] =
17875 { -1.0f, 1.0f, 1.0f, 0xff0000ff},
17876 { 1.0f, 1.0f, 0.0f, 0xff0000ff},
17877 { -1.0f, -1.0f, 1.0f, 0xff0000ff},
17878 { 1.0f, -1.0f, 0.0f, 0xff0000ff},
17880 static const struct
17882 unsigned int x, y, color;
17884 expected_colors[] =
17886 { 80, 100, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
17887 {240, 100, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
17888 {400, 100, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
17889 {560, 100, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
17890 { 80, 450, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
17891 {240, 450, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
17892 {400, 450, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
17893 {560, 450, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
17896 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17897 ok(!!d3d, "Failed to create a D3D object.\n");
17899 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
17900 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
17902 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled depth buffer test.\n");
17903 IDirect3D9_Release(d3d);
17904 return;
17906 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
17907 D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
17909 skip("Multisampling not supported for D3DFMT_D24S8, skipping multisampled depth buffer test.\n");
17910 IDirect3D9_Release(d3d);
17911 return;
17914 ZeroMemory(&present_parameters, sizeof(present_parameters));
17915 present_parameters.Windowed = TRUE;
17916 present_parameters.hDeviceWindow = create_window();
17917 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
17918 present_parameters.BackBufferWidth = 640;
17919 present_parameters.BackBufferHeight = 480;
17920 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
17921 present_parameters.EnableAutoDepthStencil = TRUE;
17922 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
17923 present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
17925 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
17926 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,
17927 &present_parameters, &device);
17928 ok(hr == D3D_OK, "Failed to create a device, hr %#lx.\n", hr);
17930 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
17931 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#lx.\n", hr);
17932 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
17934 skip("No unconditional NP2 texture support, skipping multisampled depth buffer test.\n");
17935 goto cleanup;
17938 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
17939 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
17940 ok(SUCCEEDED(hr), "Failed to create render target, hr %#lx.\n", hr);
17941 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
17942 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
17943 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#lx.\n", hr);
17945 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
17946 ok(SUCCEEDED(hr), "Failed to get render target, hr %#lx.\n", hr);
17947 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
17948 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#lx.\n", hr);
17950 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
17951 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
17952 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
17953 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
17954 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
17955 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
17956 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
17957 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
17958 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
17959 ok(SUCCEEDED(hr), "SetFVF failed, hr %#lx.\n", hr);
17961 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
17962 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#lx.\n", hr);
17964 /* Render onscreen and then offscreen */
17965 hr = IDirect3DDevice9_BeginScene(device);
17966 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
17967 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
17968 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
17969 hr = IDirect3DDevice9_EndScene(device);
17970 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
17972 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, rt, NULL, D3DTEXF_POINT);
17973 ok(SUCCEEDED(hr), "StretchRect failed, hr %#lx.\n", hr);
17974 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
17975 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
17977 hr = IDirect3DDevice9_BeginScene(device);
17978 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
17979 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
17980 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
17981 hr = IDirect3DDevice9_EndScene(device);
17982 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
17984 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, readback, NULL, D3DTEXF_POINT);
17985 ok(SUCCEEDED(hr), "StretchRect failed, hr %#lx.\n", hr);
17987 for (i = 0; i < ARRAY_SIZE(expected_colors); ++i)
17989 unsigned int color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
17990 ok(color_match(color, expected_colors[i].color, 1),
17991 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
17992 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
17995 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
17996 ok(SUCCEEDED(hr), "StretchRect failed, hr %#lx.\n", hr);
17997 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17998 ok(hr == S_OK, "Got hr %#lx.\n", hr);
18000 /* Render offscreen and then onscreen */
18001 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
18002 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#lx.\n", hr);
18003 IDirect3DSurface9_Release(ds);
18004 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
18005 D3DMULTISAMPLE_2_SAMPLES, 0, TRUE, &ds, NULL);
18006 ok(SUCCEEDED(hr), "Failed to create depth/stencil, hr %#lx.\n", hr);
18007 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
18008 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#lx.\n", hr);
18010 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
18011 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#lx.\n", hr);
18013 hr = IDirect3DDevice9_BeginScene(device);
18014 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
18015 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
18016 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
18017 hr = IDirect3DDevice9_EndScene(device);
18018 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
18020 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
18021 ok(SUCCEEDED(hr), "StretchRect failed, hr %#lx.\n", hr);
18022 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
18023 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
18025 hr = IDirect3DDevice9_BeginScene(device);
18026 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
18027 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
18028 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
18029 hr = IDirect3DDevice9_EndScene(device);
18030 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
18032 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, readback, NULL, D3DTEXF_POINT);
18033 ok(SUCCEEDED(hr), "StretchRect failed, hr %#lx.\n", hr);
18035 for (i = 0; i < ARRAY_SIZE(expected_colors); ++i)
18037 unsigned int color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
18038 ok(color_match(color, expected_colors[i].color, 1),
18039 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
18040 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
18043 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18044 ok(hr == S_OK, "Got hr %#lx.\n", hr);
18046 IDirect3DSurface9_Release(ds);
18047 IDirect3DSurface9_Release(readback);
18048 IDirect3DSurface9_Release(rt);
18049 IDirect3DSurface9_Release(original_rt);
18050 cleanup_device(device);
18052 ZeroMemory(&present_parameters, sizeof(present_parameters));
18053 present_parameters.Windowed = TRUE;
18054 present_parameters.hDeviceWindow = create_window();
18055 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
18056 present_parameters.BackBufferWidth = 640;
18057 present_parameters.BackBufferHeight = 480;
18058 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
18059 present_parameters.EnableAutoDepthStencil = TRUE;
18060 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
18061 present_parameters.MultiSampleType = D3DMULTISAMPLE_NONE;
18063 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
18064 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,
18065 &present_parameters, &device);
18066 ok(hr == D3D_OK, "Failed to create a device, hr %#lx.\n", hr);
18068 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
18069 ok(SUCCEEDED(hr), "Failed to clear depth buffer, hr %#lx.\n", hr);
18071 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
18072 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
18073 ok(SUCCEEDED(hr), "Failed to create render target, hr %#lx.\n", hr);
18074 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
18075 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
18076 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#lx.\n", hr);
18077 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
18078 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &ds, NULL);
18079 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#lx.\n", hr);
18081 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
18082 ok(SUCCEEDED(hr), "Failed to get render target, hr %#lx.\n", hr);
18083 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
18084 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#lx.\n", hr);
18085 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
18086 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
18087 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
18088 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#lx.\n", hr);
18090 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
18091 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18092 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
18093 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18094 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
18095 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18096 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
18097 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18098 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
18099 ok(SUCCEEDED(hr), "SetFVF failed, hr %#lx.\n", hr);
18101 /* Render to a multisampled offscreen frame buffer and then blit to
18102 * the onscreen (not multisampled) frame buffer. */
18103 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
18104 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#lx.\n", hr);
18106 hr = IDirect3DDevice9_BeginScene(device);
18107 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
18108 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
18109 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
18110 hr = IDirect3DDevice9_EndScene(device);
18111 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
18113 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
18114 ok(SUCCEEDED(hr), "StretchRect failed, hr %#lx.\n", hr);
18115 hr = IDirect3DDevice9_StretchRect(device, ds, NULL, original_ds, NULL, D3DTEXF_POINT);
18116 ok(SUCCEEDED(hr), "StretchRect failed, hr %#lx.\n", hr);
18118 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
18119 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
18120 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
18121 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#lx.\n", hr);
18123 hr = IDirect3DDevice9_BeginScene(device);
18124 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
18125 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
18126 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
18127 hr = IDirect3DDevice9_EndScene(device);
18128 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
18130 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, readback, NULL, D3DTEXF_POINT);
18131 ok(SUCCEEDED(hr), "StretchRect failed, hr %#lx.\n", hr);
18133 for (i = 0; i < ARRAY_SIZE(expected_colors); ++i)
18135 unsigned int color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
18136 ok(color_match(color, expected_colors[i].color, 1),
18137 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
18138 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
18141 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18142 ok(hr == S_OK, "Got hr %#lx.\n", hr);
18144 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
18145 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#lx.\n", hr);
18146 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
18147 ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#lx.\n", hr);
18149 IDirect3DSurface9_Release(original_ds);
18150 IDirect3DSurface9_Release(original_rt);
18151 IDirect3DSurface9_Release(ds);
18152 IDirect3DSurface9_Release(readback);
18153 IDirect3DSurface9_Release(rt);
18154 cleanup:
18155 cleanup_device(device);
18156 IDirect3D9_Release(d3d);
18159 static void resz_test(void)
18161 IDirect3DDevice9 *device = 0;
18162 IDirect3DSurface9 *rt, *original_rt, *ds, *readback, *intz_ds;
18163 D3DCAPS9 caps;
18164 HRESULT hr;
18165 D3DPRESENT_PARAMETERS present_parameters;
18166 unsigned int i;
18167 static const DWORD ps_code[] =
18169 0xffff0200, /* ps_2_0 */
18170 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
18171 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
18172 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
18173 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
18174 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
18175 0x02000001, 0x80010001, 0x80e40000, /* mov r1.x, r0 */
18176 0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texldp r0, t0, s0 */
18177 0x02000001, 0x80020001, 0x80000000, /* mov r1.y, r0.x */
18178 0x02000001, 0x800f0800, 0x80e40001, /* mov oC0, r1 */
18179 0x0000ffff, /* end */
18181 static const struct
18183 float x, y, z;
18184 float s, t, p, q;
18186 quad[] =
18188 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
18189 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
18190 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
18191 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
18193 static const struct
18195 unsigned int x, y, color;
18197 expected_colors[] =
18199 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
18200 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
18201 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
18202 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
18203 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
18204 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
18205 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
18206 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
18208 IDirect3DTexture9 *texture;
18209 IDirect3DPixelShader9 *ps;
18210 IDirect3D9 *d3d;
18211 DWORD value;
18213 d3d = Direct3DCreate9(D3D_SDK_VERSION);
18214 ok(!!d3d, "Failed to create a D3D object.\n");
18216 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
18217 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
18219 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping RESZ test.\n");
18220 IDirect3D9_Release(d3d);
18221 return;
18223 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
18224 D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
18226 skip("Multisampling not supported for D3DFMT_D24S8, skipping RESZ test.\n");
18227 IDirect3D9_Release(d3d);
18228 return;
18231 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
18232 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'))))
18234 skip("No INTZ support, skipping RESZ test.\n");
18235 IDirect3D9_Release(d3d);
18236 return;
18239 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
18240 D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, MAKEFOURCC('R','E','S','Z'))))
18242 skip("No RESZ support, skipping RESZ test.\n");
18243 IDirect3D9_Release(d3d);
18244 return;
18247 ZeroMemory(&present_parameters, sizeof(present_parameters));
18248 present_parameters.Windowed = TRUE;
18249 present_parameters.hDeviceWindow = create_window();
18250 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
18251 present_parameters.BackBufferWidth = 640;
18252 present_parameters.BackBufferHeight = 480;
18253 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
18254 present_parameters.EnableAutoDepthStencil = FALSE;
18255 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
18256 present_parameters.MultiSampleType = D3DMULTISAMPLE_NONE;
18258 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
18259 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
18260 ok(hr == D3D_OK, "Failed to create a device, hr %#lx.\n", hr);
18262 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
18263 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#lx.\n", hr);
18264 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
18266 skip("No pixel shader 2.0 support, skipping INTZ test.\n");
18267 cleanup_device(device);
18268 IDirect3D9_Release(d3d);
18269 return;
18271 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
18273 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
18274 cleanup_device(device);
18275 IDirect3D9_Release(d3d);
18276 return;
18279 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
18280 ok(SUCCEEDED(hr), "Failed to get render target, hr %#lx.\n", hr);
18282 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
18283 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
18284 ok(SUCCEEDED(hr), "Failed to create render target, hr %#lx.\n", hr);
18285 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
18286 D3DMULTISAMPLE_2_SAMPLES, 0, TRUE, &ds, NULL);
18287 ok(SUCCEEDED(hr), "Failed to create depth/stencil, hr %#lx.\n", hr);
18288 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
18289 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
18290 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#lx.\n", hr);
18292 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
18293 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
18294 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#lx.\n", hr);
18295 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &intz_ds);
18296 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#lx.\n", hr);
18297 hr = IDirect3DDevice9_SetDepthStencilSurface(device, intz_ds);
18298 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#lx.\n", hr);
18299 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
18300 ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#lx.\n", hr);
18301 IDirect3DSurface9_Release(intz_ds);
18302 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
18303 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#lx.\n", hr);
18305 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
18306 ok(SUCCEEDED(hr), "SetFVF failed, hr %#lx.\n", hr);
18307 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
18308 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18309 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
18310 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18311 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
18312 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18313 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
18314 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18316 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
18317 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#lx.\n", hr);
18318 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
18319 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#lx.\n", hr);
18320 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
18321 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#lx.\n", hr);
18322 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
18323 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#lx.\n", hr);
18324 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
18325 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#lx.\n", hr);
18327 /* Render offscreen (multisampled), blit the depth buffer
18328 * into the INTZ texture and then check its contents */
18329 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
18330 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
18331 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
18332 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#lx.\n", hr);
18333 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
18334 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#lx.\n", hr);
18336 hr = IDirect3DDevice9_BeginScene(device);
18337 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
18338 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18339 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
18341 /* The destination depth texture has to be bound to sampler 0 */
18342 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
18343 ok(SUCCEEDED(hr), "SetTexture failed, hr %#lx.\n", hr);
18345 /* the ATI "spec" says you have to do a dummy draw to ensure correct commands ordering */
18346 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
18347 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18348 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
18349 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18350 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
18351 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18352 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18353 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
18354 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
18355 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18356 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
18357 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18358 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
18359 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18361 /* The actual multisampled depth buffer resolve happens here */
18362 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
18363 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#lx.\n", hr);
18364 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, &value);
18365 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
18366 ok(value == 0x7fa05000, "Got value %#lx.\n", value);
18368 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
18369 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
18370 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
18371 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#lx.\n", hr);
18372 hr = IDirect3DDevice9_SetPixelShader(device, ps);
18373 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#lx.\n", hr);
18375 /* Read the depth values back */
18376 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18377 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
18378 hr = IDirect3DDevice9_EndScene(device);
18379 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
18381 for (i = 0; i < ARRAY_SIZE(expected_colors); ++i)
18383 unsigned int color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
18384 ok(color_match(color, expected_colors[i].color, 1),
18385 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
18386 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
18389 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18390 ok(hr == S_OK, "Got hr %#lx.\n", hr);
18392 IDirect3DSurface9_Release(ds);
18393 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
18394 ok(SUCCEEDED(hr), "SetTexture failed, hr %#lx.\n", hr);
18395 IDirect3DTexture9_Release(texture);
18396 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
18397 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#lx.\n", hr);
18398 IDirect3DPixelShader9_Release(ps);
18399 IDirect3DSurface9_Release(readback);
18400 IDirect3DSurface9_Release(original_rt);
18401 IDirect3DSurface9_Release(rt);
18402 cleanup_device(device);
18404 ZeroMemory(&present_parameters, sizeof(present_parameters));
18405 present_parameters.Windowed = TRUE;
18406 present_parameters.hDeviceWindow = create_window();
18407 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
18408 present_parameters.BackBufferWidth = 640;
18409 present_parameters.BackBufferHeight = 480;
18410 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
18411 present_parameters.EnableAutoDepthStencil = TRUE;
18412 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
18413 present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
18415 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
18416 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
18417 ok(hr == D3D_OK, "Failed to create a device, hr %#lx.\n", hr);
18419 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
18420 ok(SUCCEEDED(hr), "Failed to get render target, hr %#lx.\n", hr);
18421 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
18422 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#lx.\n", hr);
18423 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
18424 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
18425 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#lx.\n", hr);
18426 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
18427 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
18428 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#lx.\n", hr);
18429 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &intz_ds);
18430 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#lx.\n", hr);
18431 hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
18432 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
18433 hr = IDirect3DDevice9_SetDepthStencilSurface(device, intz_ds);
18434 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#lx.\n", hr);
18435 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
18436 ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#lx.\n", hr);
18437 IDirect3DSurface9_Release(intz_ds);
18438 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
18439 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#lx.\n", hr);
18441 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
18442 ok(SUCCEEDED(hr), "SetFVF failed, hr %#lx.\n", hr);
18443 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
18444 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18445 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
18446 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18447 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
18448 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18449 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
18450 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18452 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
18453 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#lx.\n", hr);
18454 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
18455 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#lx.\n", hr);
18456 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
18457 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#lx.\n", hr);
18458 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
18459 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#lx.\n", hr);
18460 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
18461 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#lx.\n", hr);
18463 /* Render onscreen, blit the depth buffer into the INTZ texture
18464 * and then check its contents */
18465 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
18466 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
18467 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
18468 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#lx.\n", hr);
18469 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
18470 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#lx.\n", hr);
18472 hr = IDirect3DDevice9_BeginScene(device);
18473 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
18474 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18475 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
18476 hr = IDirect3DDevice9_EndScene(device);
18477 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
18479 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
18480 ok(SUCCEEDED(hr), "SetTexture failed, hr %#lx.\n", hr);
18482 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
18483 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18484 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
18485 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18486 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
18487 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18488 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18489 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
18490 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
18491 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18492 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
18493 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18494 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
18495 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18497 /* The actual multisampled depth buffer resolve happens here */
18498 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
18499 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#lx.\n", hr);
18500 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, &value);
18501 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
18502 ok(value == 0x7fa05000, "Got value %#lx.\n", value);
18504 hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
18505 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
18506 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
18507 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#lx.\n", hr);
18508 hr = IDirect3DDevice9_SetPixelShader(device, ps);
18509 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#lx.\n", hr);
18511 /* Read the depth values back */
18512 hr = IDirect3DDevice9_BeginScene(device);
18513 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
18514 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18515 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
18516 hr = IDirect3DDevice9_EndScene(device);
18517 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
18519 for (i = 0; i < ARRAY_SIZE(expected_colors); ++i)
18521 unsigned int color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
18522 ok(color_match(color, expected_colors[i].color, 1),
18523 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
18524 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
18527 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18528 ok(hr == S_OK, "Got hr %#lx.\n", hr);
18531 /* Test edge cases - try with no texture at all */
18532 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
18533 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#lx.\n", hr);
18534 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
18535 ok(SUCCEEDED(hr), "SetTexture failed, hr %#lx.\n", hr);
18536 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
18537 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#lx.\n", hr);
18538 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
18539 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#lx.\n", hr);
18541 hr = IDirect3DDevice9_BeginScene(device);
18542 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
18543 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18544 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
18545 hr = IDirect3DDevice9_EndScene(device);
18546 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
18548 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
18549 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#lx.\n", hr);
18551 /* With a non-multisampled depth buffer */
18552 IDirect3DSurface9_Release(ds);
18553 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
18554 D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
18555 ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr %#lx.\n", hr);
18557 hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
18558 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
18559 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
18560 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#lx.\n", hr);
18561 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
18562 ok(SUCCEEDED(hr), "SetTexture failed, hr %#lx.\n", hr);
18564 hr = IDirect3DDevice9_BeginScene(device);
18565 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
18566 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18567 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
18569 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
18570 ok(SUCCEEDED(hr), "SetTexture failed, hr %#lx.\n", hr);
18572 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
18573 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18574 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
18575 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18576 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
18577 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18578 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18579 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
18580 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
18581 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18582 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
18583 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18584 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
18585 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
18586 hr = IDirect3DDevice9_EndScene(device);
18587 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
18589 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
18590 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#lx.\n", hr);
18592 hr = IDirect3DDevice9_SetPixelShader(device, ps);
18593 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#lx.\n", hr);
18595 /* Read the depth values back. */
18596 hr = IDirect3DDevice9_BeginScene(device);
18597 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
18598 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18599 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
18600 hr = IDirect3DDevice9_EndScene(device);
18601 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
18603 for (i = 0; i < ARRAY_SIZE(expected_colors); ++i)
18605 unsigned int color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
18606 ok(color_match(color, expected_colors[i].color, 1),
18607 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
18608 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
18611 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18612 ok(hr == S_OK, "Got hr %#lx.\n", hr);
18614 /* Without a current depth-stencil buffer set */
18615 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
18616 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#lx.\n", hr);
18617 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
18618 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#lx.\n", hr);
18620 hr = IDirect3DDevice9_BeginScene(device);
18621 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
18622 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18623 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
18624 hr = IDirect3DDevice9_EndScene(device);
18625 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
18627 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
18628 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#lx.\n", hr);
18630 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
18631 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#lx.\n", hr);
18632 IDirect3DSurface9_Release(ds);
18633 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
18634 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
18635 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
18636 ok(SUCCEEDED(hr), "SetTexture failed, hr %#lx.\n", hr);
18637 IDirect3DTexture9_Release(texture);
18638 IDirect3DPixelShader9_Release(ps);
18639 IDirect3DSurface9_Release(readback);
18640 IDirect3DSurface9_Release(original_rt);
18641 cleanup_device(device);
18642 IDirect3D9_Release(d3d);
18645 static void zenable_test(void)
18647 static const struct
18649 struct vec4 position;
18650 D3DCOLOR diffuse;
18652 tquad[] =
18654 {{ 0.0f, 480.0f, -0.5f, 1.0f}, 0xff00ff00},
18655 {{ 0.0f, 0.0f, -0.5f, 1.0f}, 0xff00ff00},
18656 {{640.0f, 480.0f, 1.5f, 1.0f}, 0xff00ff00},
18657 {{640.0f, 0.0f, 1.5f, 1.0f}, 0xff00ff00},
18659 unsigned int color, x, y, i, j, test;
18660 IDirect3DDevice9 *device;
18661 IDirect3D9 *d3d;
18662 ULONG refcount;
18663 D3DCAPS9 caps;
18664 HWND window;
18665 HRESULT hr;
18666 IDirect3DSurface9 *ds;
18668 window = create_window();
18669 d3d = Direct3DCreate9(D3D_SDK_VERSION);
18670 ok(!!d3d, "Failed to create a D3D object.\n");
18671 if (!(device = create_device(d3d, window, window, TRUE)))
18673 skip("Failed to create a D3D device, skipping tests.\n");
18674 goto done;
18677 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
18678 ok(SUCCEEDED(hr), "Failed to get depth stencil surface, hr %#lx.\n", hr);
18680 for (test = 0; test < 2; ++test)
18682 /* The Windows 8 testbot (WARP) appears to clip with
18683 * ZENABLE = D3DZB_TRUE and no depth buffer set. */
18684 static const D3DCOLOR expected_broken[] =
18686 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
18687 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
18688 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
18689 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
18692 if (!test)
18694 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
18695 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#lx.\n", hr);
18697 else
18699 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
18700 ok(SUCCEEDED(hr), "Failed to disable z-buffering, hr %#lx.\n", hr);
18701 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
18702 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#lx.\n", hr);
18703 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.0f, 0);
18704 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#lx.\n", hr);
18706 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
18707 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
18709 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0f, 0);
18710 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#lx.\n", hr);
18711 hr = IDirect3DDevice9_BeginScene(device);
18712 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
18713 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tquad, sizeof(*tquad));
18714 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
18715 hr = IDirect3DDevice9_EndScene(device);
18716 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
18718 for (i = 0; i < 4; ++i)
18720 for (j = 0; j < 4; ++j)
18722 x = 80 * ((2 * j) + 1);
18723 y = 60 * ((2 * i) + 1);
18724 color = getPixelColor(device, x, y);
18725 ok(color_match(color, 0x0000ff00, 1)
18726 || broken(color_match(color, expected_broken[i * 4 + j], 1) && !test),
18727 "Expected color 0x0000ff00 at %u, %u, got 0x%08x, test %u.\n",
18728 x, y, color, test);
18732 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18733 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#lx.\n", hr);
18736 IDirect3DSurface9_Release(ds);
18738 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
18739 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
18741 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1)
18742 && caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
18744 static const DWORD vs_code[] =
18746 0xfffe0101, /* vs_1_1 */
18747 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
18748 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
18749 0x00000001, 0xd00f0000, 0x90e40000, /* mov oD0, v0 */
18750 0x0000ffff
18752 static const DWORD ps_code[] =
18754 0xffff0101, /* ps_1_1 */
18755 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
18756 0x0000ffff /* end */
18758 static const struct vec3 quad[] =
18760 {-1.0f, -1.0f, -0.5f},
18761 {-1.0f, 1.0f, -0.5f},
18762 { 1.0f, -1.0f, 1.5f},
18763 { 1.0f, 1.0f, 1.5f},
18765 static const unsigned int expected[] =
18767 0x00ff0000, 0x0060df60, 0x009fdf9f, 0x00ff0000,
18768 0x00ff0000, 0x00609f60, 0x009f9f9f, 0x00ff0000,
18769 0x00ff0000, 0x00606060, 0x009f609f, 0x00ff0000,
18770 0x00ff0000, 0x00602060, 0x009f209f, 0x00ff0000,
18772 /* The Windows 8 testbot (WARP) appears to not clip z for regular
18773 * vertices either. */
18774 static const unsigned int expected_broken[] =
18776 0x0020df20, 0x0060df60, 0x009fdf9f, 0x00dfdfdf,
18777 0x00209f20, 0x00609f60, 0x009f9f9f, 0x00df9fdf,
18778 0x00206020, 0x00606060, 0x009f609f, 0x00df60df,
18779 0x00202020, 0x00602060, 0x009f209f, 0x00df20df,
18782 IDirect3DVertexShader9 *vs;
18783 IDirect3DPixelShader9 *ps;
18785 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
18786 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
18787 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
18788 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#lx.\n", hr);
18789 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
18790 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#lx.\n", hr);
18791 hr = IDirect3DDevice9_SetVertexShader(device, vs);
18792 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
18793 hr = IDirect3DDevice9_SetPixelShader(device, ps);
18794 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
18796 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
18797 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#lx.\n", hr);
18798 hr = IDirect3DDevice9_BeginScene(device);
18799 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
18800 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18801 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
18802 hr = IDirect3DDevice9_EndScene(device);
18803 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
18805 for (i = 0; i < 4; ++i)
18807 for (j = 0; j < 4; ++j)
18809 x = 80 * ((2 * j) + 1);
18810 y = 60 * ((2 * i) + 1);
18811 color = getPixelColor(device, x, y);
18812 ok(color_match(color, expected[i * 4 + j], 1)
18813 || broken(color_match(color, expected_broken[i * 4 + j], 1)),
18814 "Expected color 0x%08x at %u, %u, got 0x%08x.\n", expected[i * 4 + j], x, y, color);
18818 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18819 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#lx.\n", hr);
18821 IDirect3DPixelShader9_Release(ps);
18822 IDirect3DVertexShader9_Release(vs);
18825 refcount = IDirect3DDevice9_Release(device);
18826 ok(!refcount, "Device has %lu references left.\n", refcount);
18827 done:
18828 IDirect3D9_Release(d3d);
18829 DestroyWindow(window);
18832 static void fog_special_test(void)
18834 static const struct
18836 struct vec3 position;
18837 D3DCOLOR diffuse;
18839 quad[] =
18841 {{ -1.0f, -1.0f, 0.0f}, 0xff00ff00},
18842 {{ -1.0f, 1.0f, 0.0f}, 0xff00ff00},
18843 {{ 1.0f, -1.0f, 1.0f}, 0xff00ff00},
18844 {{ 1.0f, 1.0f, 1.0f}, 0xff00ff00}
18846 static const struct
18848 DWORD vertexmode, tablemode;
18849 BOOL vs, ps;
18850 unsigned int color_left, color_right;
18852 tests[] =
18854 {D3DFOG_LINEAR, D3DFOG_NONE, FALSE, FALSE, 0x00ff0000, 0x00ff0000},
18855 {D3DFOG_LINEAR, D3DFOG_NONE, FALSE, TRUE, 0x00ff0000, 0x00ff0000},
18856 {D3DFOG_LINEAR, D3DFOG_NONE, TRUE, FALSE, 0x00ff0000, 0x00ff0000},
18857 {D3DFOG_LINEAR, D3DFOG_NONE, TRUE, TRUE, 0x00ff0000, 0x00ff0000},
18859 {D3DFOG_NONE, D3DFOG_LINEAR, FALSE, FALSE, 0x0000ff00, 0x00ff0000},
18860 {D3DFOG_NONE, D3DFOG_LINEAR, FALSE, TRUE, 0x0000ff00, 0x00ff0000},
18861 {D3DFOG_NONE, D3DFOG_LINEAR, TRUE, FALSE, 0x0000ff00, 0x00ff0000},
18862 {D3DFOG_NONE, D3DFOG_LINEAR, TRUE, TRUE, 0x0000ff00, 0x00ff0000},
18864 static const DWORD pixel_shader_code[] =
18866 0xffff0101, /* ps_1_1 */
18867 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
18868 0x0000ffff
18870 static const DWORD vertex_shader_code[] =
18872 0xfffe0101, /* vs_1_1 */
18873 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
18874 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
18875 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
18876 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
18877 0x0000ffff
18879 static const D3DMATRIX identity =
18881 1.0f, 0.0f, 0.0f, 0.0f,
18882 0.0f, 1.0f, 0.0f, 0.0f,
18883 0.0f, 0.0f, 1.0f, 0.0f,
18884 0.0f, 0.0f, 0.0f, 1.0f,
18885 }}};
18886 union
18888 float f;
18889 DWORD d;
18890 } conv;
18891 HRESULT hr;
18892 IDirect3DPixelShader9 *ps;
18893 IDirect3DVertexShader9 *vs;
18894 IDirect3DDevice9 *device;
18895 unsigned int color, i;
18896 IDirect3D9 *d3d;
18897 ULONG refcount;
18898 D3DCAPS9 caps;
18899 HWND window;
18901 window = create_window();
18902 d3d = Direct3DCreate9(D3D_SDK_VERSION);
18903 ok(!!d3d, "Failed to create a D3D object.\n");
18904 if (!(device = create_device(d3d, window, window, TRUE)))
18906 skip("Failed to create a D3D device, skipping tests.\n");
18907 goto done;
18910 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
18911 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
18912 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
18914 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code, &vs);
18915 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#lx.\n", hr);
18917 else
18919 skip("Vertex Shaders not supported, skipping some fog tests.\n");
18920 vs = NULL;
18922 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
18924 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &ps);
18925 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#lx.\n", hr);
18927 else
18929 skip("Pixel Shaders not supported, skipping some fog tests.\n");
18930 ps = NULL;
18933 /* The table fog tests seem to depend on the projection matrix explicitly
18934 * being set to an identity matrix, even though that's the default.
18935 * (AMD Radeon HD 6310, Windows 7) */
18936 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
18937 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#lx.\n", hr);
18939 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
18940 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
18941 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
18942 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
18943 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
18944 ok(SUCCEEDED(hr), "Failed to enable fog, hr %#lx.\n", hr);
18945 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffff0000);
18946 ok(SUCCEEDED(hr), "Failed to set fog color, hr %#lx.\n", hr);
18948 conv.f = 0.5f;
18949 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, conv.d);
18950 ok(SUCCEEDED(hr), "Failed to set fog start, hr %#lx.\n", hr);
18951 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, conv.d);
18952 ok(SUCCEEDED(hr), "Failed to set fog end, hr %#lx.\n", hr);
18954 for (i = 0; i < ARRAY_SIZE(tests); i++)
18956 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
18957 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#lx.\n", hr);
18959 if (!tests[i].vs)
18961 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
18962 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
18964 else if (vs)
18966 hr = IDirect3DDevice9_SetVertexShader(device, vs);
18967 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
18969 else
18971 continue;
18974 if (!tests[i].ps)
18976 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
18977 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
18979 else if (ps)
18981 hr = IDirect3DDevice9_SetPixelShader(device, ps);
18982 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
18984 else
18986 continue;
18989 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vertexmode);
18990 ok(SUCCEEDED(hr), "Failed to set fogvertexmode, hr %#lx.\n", hr);
18991 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tablemode);
18992 ok(SUCCEEDED(hr), "Failed to set fogtablemode, hr %#lx.\n", hr);
18994 hr = IDirect3DDevice9_BeginScene(device);
18995 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
18996 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18997 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
18998 hr = IDirect3DDevice9_EndScene(device);
18999 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
19001 color = getPixelColor(device, 310, 240);
19002 ok(color_match(color, tests[i].color_left, 1),
19003 "Expected left color 0x%08x, got 0x%08x, case %u.\n", tests[i].color_left, color, i);
19004 color = getPixelColor(device, 330, 240);
19005 ok(color_match(color, tests[i].color_right, 1),
19006 "Expected right color 0x%08x, got 0x%08x, case %u.\n", tests[i].color_right, color, i);
19008 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19009 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#lx.\n", hr);
19012 if (vs)
19013 IDirect3DVertexShader9_Release(vs);
19014 if (ps)
19015 IDirect3DPixelShader9_Release(ps);
19016 refcount = IDirect3DDevice9_Release(device);
19017 ok(!refcount, "Device has %lu references left.\n", refcount);
19018 done:
19019 IDirect3D9_Release(d3d);
19020 DestroyWindow(window);
19023 static void volume_srgb_test(void)
19025 HRESULT hr;
19026 IDirect3DVolumeTexture9 *tex1, *tex2;
19027 D3DPOOL pool;
19028 D3DLOCKED_BOX locked_box;
19029 IDirect3DDevice9 *device;
19030 unsigned int color, i, j;
19031 IDirect3D9 *d3d;
19032 ULONG refcount;
19033 HWND window;
19035 static const struct
19037 BOOL srgb;
19038 unsigned int color;
19040 tests[] =
19042 /* Try toggling on and off */
19043 { FALSE, 0x007f7f7f },
19044 { TRUE, 0x00363636 },
19045 { FALSE, 0x007f7f7f },
19047 static const struct
19049 struct vec3 pos;
19050 struct vec3 texcrd;
19052 quad[] =
19054 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
19055 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
19056 {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
19057 {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
19060 window = create_window();
19061 d3d = Direct3DCreate9(D3D_SDK_VERSION);
19062 ok(!!d3d, "Failed to create a D3D object.\n");
19063 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
19064 D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_VOLUMETEXTURE, D3DFMT_A8R8G8B8) != D3D_OK)
19066 skip("D3DFMT_A8R8G8B8 volume textures with SRGBREAD not supported.\n");
19067 goto done;
19069 if (!(device = create_device(d3d, window, window, TRUE)))
19071 skip("Failed to create a D3D device, skipping tests.\n");
19072 goto done;
19075 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
19076 ok(SUCCEEDED(hr), "Failed to set color op 0, hr %#lx.\n", hr);
19077 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
19078 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#lx.\n", hr);
19079 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
19080 ok(SUCCEEDED(hr), "Failed to set color op 0, hr %#lx.\n", hr);
19081 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
19082 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#lx.\n", hr);
19084 for (i = 0; i < 2; i++)
19086 if (!i)
19087 pool = D3DPOOL_SYSTEMMEM;
19088 else
19089 pool = D3DPOOL_MANAGED;
19091 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 1, 1, 1, 0, D3DFMT_A8R8G8B8, pool, &tex1, NULL);
19092 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#lx.\n", hr);
19093 hr = IDirect3DVolumeTexture9_LockBox(tex1, 0, &locked_box, NULL, 0);
19094 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#lx.\n", hr);
19095 *((DWORD *)locked_box.pBits) = 0x7f7f7f7f;
19096 hr = IDirect3DVolumeTexture9_UnlockBox(tex1, 0);
19097 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#lx.\n", hr);
19099 if (!i)
19101 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 1, 1, 1, 0,
19102 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
19103 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#lx.\n", hr);
19104 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex1, (IDirect3DBaseTexture9 *)tex2);
19105 ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx.\n", hr);
19106 IDirect3DVolumeTexture9_Release(tex1);
19108 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex2);
19109 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
19110 IDirect3DVolumeTexture9_Release(tex2);
19112 else
19114 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex1);
19115 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
19116 IDirect3DVolumeTexture9_Release(tex1);
19119 for (j = 0; j < ARRAY_SIZE(tests); j++)
19121 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, tests[j].srgb);
19122 ok(SUCCEEDED(hr), "Failed to set srgb state, hr %#lx.\n", hr);
19124 hr = IDirect3DDevice9_BeginScene(device);
19125 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
19126 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19127 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
19128 hr = IDirect3DDevice9_EndScene(device);
19129 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
19131 color = getPixelColor(device, 320, 240);
19132 ok(color_match(color, tests[j].color, 2),
19133 "Expected color 0x%08x, got 0x%08x, i = %u, j = %u.\n", tests[j].color, color, i, j);
19135 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19136 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#lx.\n", hr);
19140 refcount = IDirect3DDevice9_Release(device);
19141 ok(!refcount, "Device has %lu references left.\n", refcount);
19142 done:
19143 IDirect3D9_Release(d3d);
19144 DestroyWindow(window);
19147 static void volume_dxtn_test(void)
19149 IDirect3DVolumeTexture9 *texture;
19150 struct surface_readback rb;
19151 unsigned int colour, i, j;
19152 IDirect3DDevice9 *device;
19153 IDirect3DSurface9 *rt;
19154 D3DLOCKED_BOX box;
19155 IDirect3D9 *d3d;
19156 ULONG refcount;
19157 HWND window;
19158 HRESULT hr;
19160 static const BYTE dxt1_data[] =
19162 0x00, 0xf8, 0x00, 0xf8, 0xf0, 0xf0, 0xf0, 0xf0,
19163 0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00,
19164 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
19165 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
19167 static const BYTE dxt3_data[] =
19169 0xff, 0xee, 0xff, 0xee, 0xff, 0xee, 0xff, 0xee, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
19170 0xff, 0xdd, 0xff, 0xdd, 0xff, 0xdd, 0xff, 0xdd, 0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00,
19171 0xff, 0xcc, 0xff, 0xcc, 0xff, 0xcc, 0xff, 0xcc, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
19172 0xff, 0xbb, 0xff, 0xbb, 0xff, 0xbb, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
19174 static const BYTE dxt5_data[] =
19176 /* A 8x4x2 texture consisting of 4 4x4 blocks. The colours of the
19177 * blocks are red, green, blue and white. */
19178 0xff, 0xff, 0x80, 0x0d, 0xd8, 0x80, 0x0d, 0xd8, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
19179 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00,
19180 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
19181 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
19183 static const unsigned int dxt1_expected_colours[] =
19185 0xffff0000, 0x00000000, 0xff00ff00, 0xff00ff00,
19186 0xff0000ff, 0xff0000ff, 0xffffffff, 0xffffffff,
19188 static const unsigned int dxt3_expected_colours[] =
19190 0xffff0000, 0xeeff0000, 0xff00ff00, 0xdd00ff00,
19191 0xff0000ff, 0xcc0000ff, 0xffffffff, 0xbbffffff,
19193 static const unsigned int dxt5_expected_colours[] =
19195 0xffff0000, 0x00ff0000, 0xff00ff00, 0xff00ff00,
19196 0xff0000ff, 0xff0000ff, 0xffffffff, 0xffffffff
19199 static const struct
19201 const char *name;
19202 D3DFORMAT format;
19203 const BYTE *data;
19204 DWORD data_size;
19205 const unsigned int *expected_colours;
19207 tests[] =
19209 {"DXT1", D3DFMT_DXT1, dxt1_data, sizeof(dxt1_data), dxt1_expected_colours},
19210 {"DXT3", D3DFMT_DXT3, dxt3_data, sizeof(dxt3_data), dxt3_expected_colours},
19211 {"DXT5", D3DFMT_DXT5, dxt5_data, sizeof(dxt5_data), dxt5_expected_colours},
19214 static const struct
19216 struct vec3 position;
19217 struct vec3 texcrd;
19219 quads[] =
19221 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.25f}},
19222 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.25f}},
19223 {{ 0.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.25f}},
19224 {{ 0.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.25f}},
19226 {{ 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.75f}},
19227 {{ 0.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.75f}},
19228 {{ 1.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.75f}},
19229 {{ 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.75f}},
19232 window = create_window();
19233 d3d = Direct3DCreate9(D3D_SDK_VERSION);
19234 ok(!!d3d, "Failed to create a D3D object.\n");
19236 if (!(device = create_device(d3d, window, window, TRUE)))
19238 skip("Failed to create a D3D device, skipping tests.\n");
19239 goto done;
19242 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &rt);
19243 ok(SUCCEEDED(hr), "Failed to get render target, hr %#lx.\n", hr);
19245 for (i = 0; i < ARRAY_SIZE(tests); ++i)
19247 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
19248 D3DFMT_X8R8G8B8, 0, D3DRTYPE_VOLUMETEXTURE, tests[i].format)))
19250 skip("%s volume textures are not supported, skipping test.\n", tests[i].name);
19251 continue;
19253 hr = IDirect3DDevice9_CreateVolumeTexture(device, 8, 4, 2, 1, 0,
19254 tests[i].format, D3DPOOL_MANAGED, &texture, NULL);
19255 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#lx.\n", hr);
19257 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &box, NULL, 0);
19258 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#lx.\n", hr);
19259 memcpy(box.pBits, tests[i].data, tests[i].data_size);
19260 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
19261 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#lx.\n", hr);
19263 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
19264 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
19265 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
19266 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
19267 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
19268 ok(SUCCEEDED(hr), "Failed to set colour op, hr %#lx.\n", hr);
19269 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
19270 ok(SUCCEEDED(hr), "Failed to set colour arg, hr %#lx.\n", hr);
19271 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
19272 ok(SUCCEEDED(hr), "Failed to set colour op, hr %#lx.\n", hr);
19273 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
19274 ok(SUCCEEDED(hr), "Failed to set mag filter, hr %#lx.\n", hr);
19276 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
19277 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
19278 hr = IDirect3DDevice9_BeginScene(device);
19279 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
19280 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
19281 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
19282 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
19283 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
19284 hr = IDirect3DDevice9_EndScene(device);
19285 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
19287 get_rt_readback(rt, &rb);
19288 for (j = 0; j < ARRAY_SIZE(dxt1_expected_colours); ++j)
19290 colour = get_readback_color(&rb, 40 + 80 * j, 240);
19291 ok(color_match(colour, tests[i].expected_colours[j], 1),
19292 "Expected colour 0x%08x, got 0x%08x, case %u.\n", tests[i].expected_colours[j], colour, j);
19294 release_surface_readback(&rb);
19296 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19297 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
19298 IDirect3DVolumeTexture9_Release(texture);
19301 IDirect3DSurface9_Release(rt);
19302 refcount = IDirect3DDevice9_Release(device);
19303 ok(!refcount, "Device has %lu references left.\n", refcount);
19304 done:
19305 IDirect3D9_Release(d3d);
19306 DestroyWindow(window);
19309 static void volume_v16u16_test(void)
19311 IDirect3DVolumeTexture9 *texture;
19312 IDirect3DPixelShader9 *shader;
19313 IDirect3DDevice9 *device;
19314 unsigned int color, i;
19315 D3DLOCKED_BOX box;
19316 IDirect3D9 *d3d;
19317 ULONG refcount;
19318 D3DCAPS9 caps;
19319 SHORT *texel;
19320 HWND window;
19321 HRESULT hr;
19323 static const struct
19325 struct vec3 position;
19326 struct vec3 texcrd;
19328 quads[] =
19330 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.25f}},
19331 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.25f}},
19332 {{ 0.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.25f}},
19333 {{ 0.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.25f}},
19335 {{ 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.75f}},
19336 {{ 0.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.75f}},
19337 {{ 1.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.75f}},
19338 {{ 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.75f}},
19340 static const DWORD shader_code[] =
19342 0xffff0101, /* ps_1_1 */
19343 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, */
19344 0x3f000000, 0x3f000000, /* 0.5, 0.5 */
19345 0x00000042, 0xb00f0000, /* tex t0 */
19346 0x00000004, 0x800f0000, 0xb0e40000, 0xa0e40000, 0xa0e40000, /* mad r0, t0, c0, c0 */
19347 0x0000ffff /* end */
19350 window = create_window();
19351 d3d = Direct3DCreate9(D3D_SDK_VERSION);
19352 ok(!!d3d, "Failed to create a D3D object.\n");
19353 if (!(device = create_device(d3d, window, window, TRUE)))
19355 skip("Failed to create a D3D device, skipping tests.\n");
19356 goto done;
19359 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
19360 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
19361 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
19363 skip("No ps_1_1 support, skipping tests.\n");
19364 IDirect3DDevice9_Release(device);
19365 goto done;
19367 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
19368 D3DFMT_X8R8G8B8, 0, D3DRTYPE_VOLUMETEXTURE, D3DFMT_V16U16)))
19370 skip("Volume V16U16 textures are not supported, skipping test.\n");
19371 IDirect3DDevice9_Release(device);
19372 goto done;
19375 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
19376 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
19377 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
19378 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#lx.\n", hr);
19379 hr = IDirect3DDevice9_SetPixelShader(device, shader);
19380 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
19381 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
19382 ok(SUCCEEDED(hr), "Failed to set filter, hr %#lx.\n", hr);
19384 for (i = 0; i < 2; i++)
19386 D3DPOOL pool;
19388 if (i)
19389 pool = D3DPOOL_SYSTEMMEM;
19390 else
19391 pool = D3DPOOL_MANAGED;
19393 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 2, 2, 1, 0, D3DFMT_V16U16,
19394 pool, &texture, NULL);
19395 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#lx.\n", hr);
19397 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &box, NULL, 0);
19398 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#lx.\n", hr);
19400 texel = (SHORT *)((BYTE *)box.pBits + 0 * box.RowPitch + 0 * box.SlicePitch);
19401 texel[0] = 32767;
19402 texel[1] = 32767;
19403 texel = (SHORT *)((BYTE *)box.pBits + 1 * box.RowPitch + 0 * box.SlicePitch);
19404 texel[0] = -32768;
19405 texel[1] = 0;
19406 texel = (SHORT *)((BYTE *)box.pBits + 0 * box.RowPitch + 1 * box.SlicePitch);
19407 texel[0] = -16384;
19408 texel[1] = 16384;
19409 texel = (SHORT *)((BYTE *)box.pBits + 1 * box.RowPitch + 1 * box.SlicePitch);
19410 texel[0] = 0;
19411 texel[1] = 0;
19413 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
19414 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#lx.\n", hr);
19416 if (i)
19418 IDirect3DVolumeTexture9 *texture2;
19420 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 2, 2, 1, 0, D3DFMT_V16U16,
19421 D3DPOOL_DEFAULT, &texture2, NULL);
19422 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#lx.\n", hr);
19424 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)texture,
19425 (IDirect3DBaseTexture9 *)texture2);
19426 ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx.\n", hr);
19428 IDirect3DVolumeTexture9_Release(texture);
19429 texture = texture2;
19432 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
19433 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
19435 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
19436 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
19437 hr = IDirect3DDevice9_BeginScene(device);
19438 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
19439 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
19440 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
19441 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
19442 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
19443 hr = IDirect3DDevice9_EndScene(device);
19444 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
19446 color = getPixelColor(device, 120, 160);
19447 ok (color_match(color, 0x000080ff, 2),
19448 "Expected color 0x000080ff, got 0x%08x, V16U16 input -32768, 0.\n", color);
19449 color = getPixelColor(device, 120, 400);
19450 ok (color_match(color, 0x00ffffff, 2),
19451 "Expected color 0x00ffffff, got 0x%08x, V16U16 input 32767, 32767.\n", color);
19452 color = getPixelColor(device, 360, 160);
19453 ok (color_match(color, 0x007f7fff, 2),
19454 "Expected color 0x007f7fff, got 0x%08x, V16U16 input 0, 0.\n", color);
19455 color = getPixelColor(device, 360, 400);
19456 ok (color_match(color, 0x0040c0ff, 2),
19457 "Expected color 0x0040c0ff, got 0x%08x, V16U16 input -16384, 16384.\n", color);
19459 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19460 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
19462 IDirect3DVolumeTexture9_Release(texture);
19465 IDirect3DPixelShader9_Release(shader);
19466 refcount = IDirect3DDevice9_Release(device);
19467 ok(!refcount, "Device has %lu references left.\n", refcount);
19468 done:
19469 IDirect3D9_Release(d3d);
19470 DestroyWindow(window);
19473 static void add_dirty_rect_test_draw(IDirect3DDevice9 *device)
19475 HRESULT hr;
19476 static const struct
19478 struct vec3 position;
19479 struct vec2 texcoord;
19481 quad[] =
19483 {{-1.0, -1.0, 0.0}, {0.0, 0.0}},
19484 {{-1.0, 1.0, 0.0}, {0.0, 1.0}},
19485 {{ 1.0, -1.0, 0.0}, {1.0, 0.0}},
19486 {{ 1.0, 1.0, 0.0}, {1.0, 1.0}},
19489 hr = IDirect3DDevice9_BeginScene(device);
19490 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
19491 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad, sizeof(*quad));
19492 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
19493 hr = IDirect3DDevice9_EndScene(device);
19494 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
19497 static void add_dirty_rect_test(void)
19499 HRESULT hr;
19500 IDirect3DTexture9 *tex_dst1, *tex_dst2, *tex_src_red, *tex_src_green,
19501 *tex_managed, *tex_dynamic;
19502 IDirect3DSurface9 *surface_dst2, *surface_src_green, *surface_src_red,
19503 *surface_managed0, *surface_managed1, *surface_dynamic;
19504 IDirect3DDevice9 *device;
19505 unsigned int color, i;
19506 IDirect3D9 *d3d;
19507 ULONG refcount;
19508 DWORD *texel;
19509 HWND window;
19510 HDC dc;
19511 D3DLOCKED_RECT locked_rect;
19512 static const RECT part_rect = {96, 96, 160, 160};
19513 static const RECT oob_rect[] =
19515 { 0, 0, 200, 300},
19516 { 0, 0, 300, 200},
19517 {100, 100, 10, 10},
19518 {200, 300, 10, 10},
19519 {300, 200, 310, 210},
19520 { 0, 0, 0, 0},
19523 window = create_window();
19524 d3d = Direct3DCreate9(D3D_SDK_VERSION);
19525 ok(!!d3d, "Failed to create a D3D object.\n");
19526 if (!(device = create_device(d3d, window, window, TRUE)))
19528 skip("Failed to create a D3D device, skipping tests.\n");
19529 IDirect3D9_Release(d3d);
19530 DestroyWindow(window);
19531 return;
19534 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
19535 D3DPOOL_DEFAULT, &tex_dst1, NULL);
19536 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
19537 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
19538 D3DPOOL_DEFAULT, &tex_dst2, NULL);
19539 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
19540 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
19541 D3DPOOL_SYSTEMMEM, &tex_src_red, NULL);
19542 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
19543 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
19544 D3DPOOL_SYSTEMMEM, &tex_src_green, NULL);
19545 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
19546 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 2, 0, D3DFMT_X8R8G8B8,
19547 D3DPOOL_MANAGED, &tex_managed, NULL);
19548 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
19549 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, D3DUSAGE_DYNAMIC,
19550 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex_dynamic, NULL);
19551 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
19553 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dst2, 0, &surface_dst2);
19554 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#lx.\n", hr);
19555 hr = IDirect3DTexture9_GetSurfaceLevel(tex_src_green, 0, &surface_src_green);
19556 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#lx.\n", hr);
19557 hr = IDirect3DTexture9_GetSurfaceLevel(tex_src_red, 0, &surface_src_red);
19558 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#lx.\n", hr);
19559 hr = IDirect3DTexture9_GetSurfaceLevel(tex_managed, 0, &surface_managed0);
19560 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#lx.\n", hr);
19561 hr = IDirect3DTexture9_GetSurfaceLevel(tex_managed, 1, &surface_managed1);
19562 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#lx.\n", hr);
19563 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dynamic, 0, &surface_dynamic);
19564 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#lx.\n", hr);
19566 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
19567 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#lx.\n", hr);
19568 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
19569 ok(SUCCEEDED(hr), "Failed to set color op, hr %#lx.\n", hr);
19570 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
19571 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#lx.\n", hr);
19572 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
19573 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#lx.\n", hr);
19575 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst2);
19576 ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr);
19577 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_red,
19578 (IDirect3DBaseTexture9 *)tex_dst2);
19579 fill_surface(surface_src_green, 0x00000080, D3DLOCK_NO_DIRTY_UPDATE);
19580 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
19581 (IDirect3DBaseTexture9 *)tex_dst2);
19582 ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr);
19583 add_dirty_rect_test_draw(device);
19584 color = getPixelColor(device, 320, 240);
19585 ok(color_match(color, 0x00000080, 1), "Unexpected colour 0x%08x.\n", color);
19586 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19587 ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr);
19589 fill_surface(surface_src_red, 0x00ff0000, 0);
19590 fill_surface(surface_src_green, 0x0000ff00, 0);
19592 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
19593 (IDirect3DBaseTexture9 *)tex_dst1);
19594 ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx.\n", hr);
19596 /* The second UpdateTexture call writing to tex_dst2 is ignored because tex_src_green is not dirty. */
19597 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_red,
19598 (IDirect3DBaseTexture9 *)tex_dst2);
19599 ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx.\n", hr);
19600 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
19601 (IDirect3DBaseTexture9 *)tex_dst2);
19602 ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx.\n", hr);
19604 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst1);
19605 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
19606 add_dirty_rect_test_draw(device);
19607 color = getPixelColor(device, 320, 240);
19608 ok(color_match(color, 0x0000ff00, 1),
19609 "Expected color 0x0000ff00, got 0x%08x.\n", color);
19610 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19611 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
19613 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst2);
19614 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
19615 add_dirty_rect_test_draw(device);
19616 color = getPixelColor(device, 320, 240);
19617 ok(color_match(color, 0x00ff0000, 1),
19618 "Expected color 0x00ff0000, got 0x%08x.\n", color);
19619 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19620 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
19622 /* AddDirtyRect on the destination is ignored. */
19623 hr = IDirect3DTexture9_AddDirtyRect(tex_dst2, &part_rect);
19624 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#lx.\n", hr);
19625 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
19626 (IDirect3DBaseTexture9 *)tex_dst2);
19627 ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx.\n", hr);
19628 add_dirty_rect_test_draw(device);
19629 color = getPixelColor(device, 320, 240);
19630 ok(color_match(color, 0x00ff0000, 1),
19631 "Expected color 0x00ff0000, got 0x%08x.\n", color);
19632 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19633 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
19635 hr = IDirect3DTexture9_AddDirtyRect(tex_dst2, NULL);
19636 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#lx.\n", hr);
19637 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
19638 (IDirect3DBaseTexture9 *)tex_dst2);
19639 ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx.\n", hr);
19640 add_dirty_rect_test_draw(device);
19641 color = getPixelColor(device, 320, 240);
19642 ok(color_match(color, 0x00ff0000, 1),
19643 "Expected color 0x00ff0000, got 0x%08x.\n", color);
19644 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19645 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
19647 /* AddDirtyRect on the source makes UpdateTexture work. Partial rectangle
19648 * tracking is supported. */
19649 hr = IDirect3DTexture9_AddDirtyRect(tex_src_green, &part_rect);
19650 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#lx.\n", hr);
19651 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
19652 (IDirect3DBaseTexture9 *)tex_dst2);
19653 ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx.\n", hr);
19654 add_dirty_rect_test_draw(device);
19655 color = getPixelColor(device, 320, 240);
19656 ok(color_match(color, 0x0000ff00, 1),
19657 "Expected color 0x0000ff00, got 0x%08x.\n", color);
19658 color = getPixelColor(device, 1, 1);
19659 ok(color_match(color, 0x00ff0000, 1),
19660 "Expected color 0x00ff0000, got 0x%08x.\n", color);
19661 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19662 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
19664 hr = IDirect3DTexture9_AddDirtyRect(tex_src_green, NULL);
19665 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#lx.\n", hr);
19666 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
19667 (IDirect3DBaseTexture9 *)tex_dst2);
19668 ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx.\n", hr);
19669 add_dirty_rect_test_draw(device);
19670 color = getPixelColor(device, 1, 1);
19671 ok(color_match(color, 0x0000ff00, 1),
19672 "Expected color 0x0000ff00, got 0x%08x.\n", color);
19674 /* UpdateTexture() ignores locks made with D3DLOCK_NO_DIRTY_UPDATE. */
19675 fill_surface(surface_src_green, 0x00000080, D3DLOCK_NO_DIRTY_UPDATE);
19676 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
19677 (IDirect3DBaseTexture9 *)tex_dst2);
19678 ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx.\n", hr);
19679 add_dirty_rect_test_draw(device);
19680 color = getPixelColor(device, 320, 240);
19681 ok(color_match(color, 0x0000ff00, 1),
19682 "Expected color 0x0000ff00, got 0x%08x.\n", color);
19683 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19684 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
19686 /* Manually copying the surface works, though. */
19687 hr = IDirect3DDevice9_UpdateSurface(device, surface_src_green, NULL, surface_dst2, NULL);
19688 ok(hr == D3D_OK, "Failed to copy surface, hr %#lx.\n", hr);
19689 add_dirty_rect_test_draw(device);
19690 color = getPixelColor(device, 320, 240);
19691 ok(color_match(color, 0x00000080, 1), "Got unexpected colour 0x%08x.\n", color);
19692 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19693 ok(hr == D3D_OK, "Failed to present, hr %#lx.\n", hr);
19695 /* Readonly maps write to D3DPOOL_SYSTEMMEM, but don't record a dirty rectangle. */
19696 fill_surface(surface_src_green, 0x000000ff, D3DLOCK_READONLY);
19697 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
19698 (IDirect3DBaseTexture9 *)tex_dst2);
19699 ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx.\n", hr);
19700 add_dirty_rect_test_draw(device);
19701 color = getPixelColor(device, 320, 240);
19702 ok(color_match(color, 0x00000080, 1), "Got unexpected colour 0x%08x.\n", color);
19703 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19704 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
19706 hr = IDirect3DTexture9_AddDirtyRect(tex_src_green, NULL);
19707 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
19708 (IDirect3DBaseTexture9 *)tex_dst2);
19709 ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx.\n", hr);
19710 add_dirty_rect_test_draw(device);
19711 color = getPixelColor(device, 320, 240);
19712 ok(color_match(color, 0x000000ff, 1),
19713 "Expected color 0x000000ff, got 0x%08x.\n", color);
19714 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19715 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
19717 /* Maps without either of these flags record a dirty rectangle. */
19718 fill_surface(surface_src_green, 0x00ffffff, 0);
19719 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
19720 (IDirect3DBaseTexture9 *)tex_dst2);
19721 ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx.\n", hr);
19722 add_dirty_rect_test_draw(device);
19723 color = getPixelColor(device, 320, 240);
19724 ok(color_match(color, 0x00ffffff, 1),
19725 "Expected color 0x00ffffff, got 0x%08x.\n", color);
19726 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19727 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
19729 /* Partial LockRect works just like a partial AddDirtyRect call. */
19730 hr = IDirect3DTexture9_LockRect(tex_src_green, 0, &locked_rect, &part_rect, 0);
19731 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#lx.\n", hr);
19732 texel = locked_rect.pBits;
19733 for (i = 0; i < 64; i++)
19734 texel[i] = 0x00ff00ff;
19735 for (i = 1; i < 64; i++)
19736 memcpy((BYTE *)locked_rect.pBits + i * locked_rect.Pitch, locked_rect.pBits, locked_rect.Pitch);
19737 hr = IDirect3DTexture9_UnlockRect(tex_src_green, 0);
19738 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#lx.\n", hr);
19739 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
19740 (IDirect3DBaseTexture9 *)tex_dst2);
19741 ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx.\n", hr);
19742 add_dirty_rect_test_draw(device);
19743 color = getPixelColor(device, 320, 240);
19744 ok(color_match(color, 0x00ff00ff, 1),
19745 "Expected color 0x00ff00ff, got 0x%08x.\n", color);
19746 color = getPixelColor(device, 1, 1);
19747 ok(color_match(color, 0x00ffffff, 1),
19748 "Expected color 0x00ffffff, got 0x%08x.\n", color);
19749 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19750 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
19752 /* GetDC() records a dirty rect. */
19753 fill_surface(surface_src_green, 0x00000080, D3DLOCK_NO_DIRTY_UPDATE);
19754 hr = IDirect3DSurface9_GetDC(surface_src_green, &dc);
19755 ok(hr == S_OK, "Got hr %#lx.\n", hr);
19756 hr = IDirect3DSurface9_ReleaseDC(surface_src_green, dc);
19757 ok(hr == S_OK, "Got hr %#lx.\n", hr);
19758 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
19759 (IDirect3DBaseTexture9 *)tex_dst2);
19760 ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx.\n", hr);
19761 add_dirty_rect_test_draw(device);
19762 color = getPixelColor(device, 320, 240);
19763 ok(color_match(color, 0x00000080, 1), "Got unexpected color 0x%08x.\n", color);
19764 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19765 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
19767 fill_surface(surface_src_red, 0x00ff0000, 0);
19768 fill_surface(surface_src_green, 0x0000ff00, 0);
19770 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
19771 (IDirect3DBaseTexture9 *)tex_dst1);
19772 ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx.\n", hr);
19773 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst1);
19774 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
19775 add_dirty_rect_test_draw(device);
19776 color = getPixelColor(device, 320, 240);
19777 ok(color_match(color, 0x0000ff00, 1),
19778 "Expected color 0x0000ff00, got 0x%08x.\n", color);
19779 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19780 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
19782 /* UpdateSurface ignores the missing dirty marker. */
19783 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_red,
19784 (IDirect3DBaseTexture9 *)tex_dst2);
19785 hr = IDirect3DDevice9_UpdateSurface(device, surface_src_green, NULL, surface_dst2, NULL);
19786 ok(SUCCEEDED(hr), "Failed to update surface, hr %#lx.\n", hr);
19787 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst2);
19788 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
19789 add_dirty_rect_test_draw(device);
19790 color = getPixelColor(device, 320, 240);
19791 ok(color_match(color, 0x0000ff00, 1),
19792 "Expected color 0x0000ff00, got 0x%08x.\n", color);
19793 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19794 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
19796 fill_surface(surface_src_green, 0x000000ff, D3DLOCK_NO_DIRTY_UPDATE);
19798 /* So does drawing directly from the sysmem texture. */
19799 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_src_green);
19800 ok(hr == S_OK, "Failed to set texture, hr %#lx.\n", hr);
19801 add_dirty_rect_test_draw(device);
19802 color = getPixelColor(device, 320, 240);
19803 /* Radeon GPUs read zero from sysmem textures. */
19804 ok(color_match(color, 0x000000ff, 1) || broken(color_match(color, 0x00000000, 1)),
19805 "Got unexpected color 0x%08x.\n", color);
19807 /* Tests with managed textures. */
19808 fill_surface(surface_managed0, 0x00ff0000, 0);
19809 fill_surface(surface_managed1, 0x00ff0000, 0);
19810 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_managed);
19811 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
19812 add_dirty_rect_test_draw(device);
19813 color = getPixelColor(device, 320, 240);
19814 ok(color_match(color, 0x00ff0000, 1),
19815 "Expected color 0x00ff0000, got 0x%08x.\n", color);
19816 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19817 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
19818 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
19819 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#lx.\n", hr);
19820 add_dirty_rect_test_draw(device);
19821 color = getPixelColor(device, 320, 240);
19822 ok(color_match(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
19823 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19824 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
19826 /* Managed textures also honor D3DLOCK_NO_DIRTY_UPDATE. */
19827 fill_surface(surface_managed0, 0x0000ff00, D3DLOCK_NO_DIRTY_UPDATE);
19828 fill_surface(surface_managed1, 0x000000ff, D3DLOCK_NO_DIRTY_UPDATE);
19829 add_dirty_rect_test_draw(device);
19830 color = getPixelColor(device, 320, 240);
19831 ok(color_match(color, 0x00ff0000, 1),
19832 "Expected color 0x00ff0000, got 0x%08x.\n", color);
19833 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19834 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
19835 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
19836 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#lx.\n", hr);
19837 add_dirty_rect_test_draw(device);
19838 color = getPixelColor(device, 320, 240);
19839 ok(color_match(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
19840 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19841 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
19843 /* AddDirtyRect uploads the new contents.
19844 * Partial surface updates work, and two separate dirty rectangles are
19845 * tracked individually. Tested on Nvidia Kepler, other drivers untested. */
19846 hr = IDirect3DTexture9_AddDirtyRect(tex_managed, &part_rect);
19847 ok(hr == S_OK, "Failed to add dirty rect, hr %#lx.\n", hr);
19848 add_dirty_rect_test_draw(device);
19849 color = getPixelColor(device, 320, 240);
19850 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
19851 color = getPixelColor(device, 1, 1);
19852 ok(color_match(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
19853 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19854 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
19856 hr = IDirect3DTexture9_AddDirtyRect(tex_managed, NULL);
19857 ok(hr == S_OK, "Failed to add dirty rect, hr %#lx.\n", hr);
19858 add_dirty_rect_test_draw(device);
19859 color = getPixelColor(device, 320, 240);
19860 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
19861 color = getPixelColor(device, 1, 1);
19862 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
19863 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19864 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
19866 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
19867 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#lx.\n", hr);
19868 add_dirty_rect_test_draw(device);
19869 color = getPixelColor(device, 320, 240);
19870 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
19871 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19872 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
19874 /* So does EvictManagedResources. */
19875 fill_surface(surface_managed0, 0x00ffff00, D3DLOCK_NO_DIRTY_UPDATE);
19876 fill_surface(surface_managed1, 0x00ff00ff, D3DLOCK_NO_DIRTY_UPDATE);
19877 hr = IDirect3DDevice9_EvictManagedResources(device);
19878 ok(SUCCEEDED(hr), "Failed to evict managed resources, hr %#lx.\n", hr);
19879 add_dirty_rect_test_draw(device);
19880 color = getPixelColor(device, 320, 240);
19881 ok(color_match(color, 0x00ff00ff, 1), "Got unexpected color 0x%08x.\n", color);
19882 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19883 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
19884 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
19885 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#lx.\n", hr);
19886 add_dirty_rect_test_draw(device);
19887 color = getPixelColor(device, 320, 240);
19888 ok(color_match(color, 0x00ffff00, 1), "Got unexpected color 0x%08x.\n", color);
19889 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19890 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
19892 /* So does GetDC(). */
19893 fill_surface(surface_managed0, 0x00000080, D3DLOCK_NO_DIRTY_UPDATE);
19894 hr = IDirect3DSurface9_GetDC(surface_managed0, &dc);
19895 ok(hr == S_OK, "Got hr %#lx.\n", hr);
19896 hr = IDirect3DSurface9_ReleaseDC(surface_managed0, dc);
19897 ok(hr == S_OK, "Got hr %#lx.\n", hr);
19898 add_dirty_rect_test_draw(device);
19899 color = getPixelColor(device, 320, 240);
19900 ok(color_match(color, 0x00000080, 1), "Got unexpected color 0x%08x.\n", color);
19901 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19902 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
19904 /* Tests with dynamic textures */
19905 fill_surface(surface_dynamic, 0x0000ffff, 0);
19906 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dynamic);
19907 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
19908 add_dirty_rect_test_draw(device);
19909 color = getPixelColor(device, 320, 240);
19910 ok(color_match(color, 0x0000ffff, 1),
19911 "Expected color 0x0000ffff, got 0x%08x.\n", color);
19912 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19913 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
19915 /* Dynamic textures don't honor D3DLOCK_NO_DIRTY_UPDATE. */
19916 fill_surface(surface_dynamic, 0x00ffff00, D3DLOCK_NO_DIRTY_UPDATE);
19917 add_dirty_rect_test_draw(device);
19918 color = getPixelColor(device, 320, 240);
19919 ok(color_match(color, 0x00ffff00, 1),
19920 "Expected color 0x00ffff00, got 0x%08x.\n", color);
19921 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19922 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
19924 /* AddDirtyRect on a locked texture is allowed. */
19925 hr = IDirect3DTexture9_LockRect(tex_src_red, 0, &locked_rect, NULL, 0);
19926 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#lx.\n", hr);
19927 hr = IDirect3DTexture9_AddDirtyRect(tex_src_red, NULL);
19928 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#lx.\n", hr);
19929 hr = IDirect3DTexture9_UnlockRect(tex_src_red, 0);
19930 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#lx.\n", hr);
19932 /* Redundant AddDirtyRect calls are ok. */
19933 hr = IDirect3DTexture9_AddDirtyRect(tex_managed, NULL);
19934 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#lx.\n", hr);
19935 hr = IDirect3DTexture9_AddDirtyRect(tex_managed, NULL);
19936 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#lx.\n", hr);
19938 /* Test out-of-bounds regions. */
19939 for (i = 0; i < ARRAY_SIZE(oob_rect); ++i)
19941 hr = IDirect3DTexture9_AddDirtyRect(tex_src_red, &oob_rect[i]);
19942 ok(hr == D3DERR_INVALIDCALL, "[%u] Got unexpected hr %#lx.\n", i, hr);
19943 hr = IDirect3DTexture9_LockRect(tex_src_red, 0, &locked_rect, &oob_rect[i], 0);
19944 ok(SUCCEEDED(hr), "[%u] Got unexpected hr %#lx.\n", i, hr);
19945 hr = IDirect3DTexture9_UnlockRect(tex_src_red, 0);
19946 ok(SUCCEEDED(hr), "[%u] Got unexpected hr %#lx.\n", i, hr);
19949 IDirect3DSurface9_Release(surface_dst2);
19950 IDirect3DSurface9_Release(surface_managed1);
19951 IDirect3DSurface9_Release(surface_managed0);
19952 IDirect3DSurface9_Release(surface_src_red);
19953 IDirect3DSurface9_Release(surface_src_green);
19954 IDirect3DSurface9_Release(surface_dynamic);
19955 IDirect3DTexture9_Release(tex_src_red);
19956 IDirect3DTexture9_Release(tex_src_green);
19957 IDirect3DTexture9_Release(tex_dst1);
19958 IDirect3DTexture9_Release(tex_dst2);
19959 IDirect3DTexture9_Release(tex_managed);
19960 IDirect3DTexture9_Release(tex_dynamic);
19962 /* As above, test UpdateSurface() after locking the source with
19963 * D3DLOCK_NO_DIRTY_UPDATE, but this time do it immediately after creating
19964 * the destination texture. This is a regression test for a previously
19965 * broken code path. */
19967 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
19968 D3DPOOL_DEFAULT, &tex_dst2, NULL);
19969 ok(hr == D3D_OK, "Failed to create texture, hr %#lx.\n", hr);
19970 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
19971 D3DPOOL_SYSTEMMEM, &tex_src_green, NULL);
19972 ok(hr == D3D_OK, "Failed to create texture, hr %#lx.\n", hr);
19974 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dst2, 0, &surface_dst2);
19975 ok(hr == D3D_OK, "Failed to get surface level, hr %#lx.\n", hr);
19976 hr = IDirect3DTexture9_GetSurfaceLevel(tex_src_green, 0, &surface_src_green);
19977 ok(hr == D3D_OK, "Failed to get surface level, hr %#lx.\n", hr);
19979 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst2);
19980 ok(hr == D3D_OK, "Failed to set texture, hr %#lx.\n", hr);
19981 fill_surface(surface_src_green, 0x00ff0000, D3DLOCK_NO_DIRTY_UPDATE);
19982 hr = IDirect3DDevice9_UpdateSurface(device, surface_src_green, NULL, surface_dst2, NULL);
19983 ok(hr == D3D_OK, "Failed to copy rects, hr %#lx.\n", hr);
19984 add_dirty_rect_test_draw(device);
19985 color = getPixelColor(device, 320, 240);
19986 ok(color_match(color, 0x00ff0000, 1), "Got unexpected colour 0x%08x.\n", color);
19987 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19988 ok(hr == D3D_OK, "Failed to present, hr %#lx.\n", hr);
19990 IDirect3DSurface9_Release(surface_dst2);
19991 IDirect3DSurface9_Release(surface_src_green);
19992 IDirect3DTexture9_Release(tex_dst2);
19993 IDirect3DTexture9_Release(tex_src_green);
19995 refcount = IDirect3DDevice9_Release(device);
19996 ok(!refcount, "Device has %lu references left.\n", refcount);
19997 IDirect3D9_Release(d3d);
19998 DestroyWindow(window);
20001 static void test_buffer_no_dirty_update(void)
20003 unsigned int refcount, colour;
20004 IDirect3DVertexBuffer9 *vb;
20005 IDirect3DDevice9 *device;
20006 IDirect3D9 *d3d;
20007 HWND window;
20008 HRESULT hr;
20009 void *data;
20011 static const struct
20013 struct vec3 position;
20014 DWORD diffuse;
20016 green_quad[] =
20018 {{-1.0f, -1.0f, 0.1f}, 0xff00ff00},
20019 {{-1.0f, 1.0f, 0.1f}, 0xff00ff00},
20020 {{ 1.0f, -1.0f, 0.1f}, 0xff00ff00},
20022 {{ 1.0f, -1.0f, 0.1f}, 0xff00ff00},
20023 {{-1.0f, 1.0f, 0.1f}, 0xff00ff00},
20024 {{ 1.0f, 1.0f, 0.1f}, 0xff00ff00},
20026 red_quad[] =
20028 {{-1.0f, -1.0f, 0.1f}, 0xffff0000},
20029 {{-1.0f, 1.0f, 0.1f}, 0xffff0000},
20030 {{ 1.0f, -1.0f, 0.1f}, 0xffff0000},
20032 {{ 1.0f, -1.0f, 0.1f}, 0xffff0000},
20033 {{-1.0f, 1.0f, 0.1f}, 0xffff0000},
20034 {{ 1.0f, 1.0f, 0.1f}, 0xffff0000},
20037 window = create_window();
20038 d3d = Direct3DCreate9(D3D_SDK_VERSION);
20039 ok(!!d3d, "Failed to create a D3D object.\n");
20040 if (!(device = create_device(d3d, window, window, TRUE)))
20042 skip("Failed to create a D3D device.\n");
20043 goto done;
20046 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(green_quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
20047 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
20049 hr = IDirect3DVertexBuffer9_Lock(vb, 0, 0, &data, 0);
20050 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
20051 memcpy(data, red_quad, sizeof(red_quad));
20052 hr = IDirect3DVertexBuffer9_Unlock(vb);
20053 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
20055 hr = IDirect3DVertexBuffer9_Lock(vb, 0, 0, &data, D3DLOCK_NO_DIRTY_UPDATE);
20056 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
20057 memcpy(data, green_quad, sizeof(green_quad));
20058 hr = IDirect3DVertexBuffer9_Unlock(vb);
20059 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
20061 hr = IDirect3DDevice9_BeginScene(device);
20062 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
20063 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
20064 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
20065 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
20066 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
20067 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
20068 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
20069 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
20070 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
20071 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(*green_quad));
20072 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
20073 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLELIST, 0, 2);
20074 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
20075 hr = IDirect3DDevice9_EndScene(device);
20076 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
20077 colour = getPixelColor(device, 320, 240);
20078 ok(color_match(colour, 0x0000ff00, 1), "Got unexpected colour 0x%09x.\n", colour);
20080 IDirect3DVertexBuffer9_Release(vb);
20081 refcount = IDirect3DDevice9_Release(device);
20082 ok(!refcount, "Device has %u references left.\n", refcount);
20083 done:
20084 IDirect3D9_Release(d3d);
20085 DestroyWindow(window);
20088 static void test_per_stage_constant(void)
20090 IDirect3DDevice9 *device;
20091 unsigned int color;
20092 IDirect3D9 *d3d;
20093 ULONG refcount;
20094 D3DCAPS9 caps;
20095 HWND window;
20096 HRESULT hr;
20098 static const struct
20100 struct vec3 position;
20101 D3DCOLOR diffuse;
20103 quad[] =
20105 {{-1.0f, -1.0f, 0.1f}, 0xffff0000},
20106 {{-1.0f, 1.0f, 0.1f}, 0xffff0000},
20107 {{ 1.0f, -1.0f, 0.1f}, 0xffff0000},
20108 {{ 1.0f, 1.0f, 0.1f}, 0xffff0000},
20111 window = create_window();
20112 d3d = Direct3DCreate9(D3D_SDK_VERSION);
20113 ok(!!d3d, "Failed to create a D3D object.\n");
20114 if (!(device = create_device(d3d, window, window, TRUE)))
20116 skip("Failed to create a D3D device, skipping tests.\n");
20117 goto done;
20120 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
20121 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
20122 if (!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_PERSTAGECONSTANT))
20124 skip("Per-stage constants not supported, skipping tests.\n");
20125 IDirect3DDevice9_Release(device);
20126 goto done;
20129 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
20130 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
20131 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
20132 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
20133 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
20134 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
20135 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
20136 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
20137 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
20138 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
20140 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_CONSTANT, 0x80a1b2c3);
20141 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#lx.\n", hr);
20142 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_CONSTANT);
20143 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#lx.\n", hr);
20144 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
20145 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#lx.\n", hr);
20147 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
20148 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
20150 hr = IDirect3DDevice9_BeginScene(device);
20151 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
20152 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
20153 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
20154 hr = IDirect3DDevice9_EndScene(device);
20155 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
20157 color = getPixelColor(device, 320, 240);
20158 ok(color_match(color, 0x00a1b2c3, 1), "Got unexpected color 0x%08x.\n", color);
20159 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20160 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
20162 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_CONSTANT | D3DTA_COMPLEMENT);
20163 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#lx.\n", hr);
20165 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
20166 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
20168 hr = IDirect3DDevice9_BeginScene(device);
20169 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
20170 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
20171 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
20172 hr = IDirect3DDevice9_EndScene(device);
20173 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
20175 color = getPixelColor(device, 320, 240);
20176 ok(color_match(color, 0x005e4d3c, 1), "Got unexpected color 0x%08x.\n", color);
20177 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20178 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
20180 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_CONSTANT | D3DTA_ALPHAREPLICATE);
20181 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#lx.\n", hr);
20183 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
20184 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
20186 hr = IDirect3DDevice9_BeginScene(device);
20187 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
20188 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
20189 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
20190 hr = IDirect3DDevice9_EndScene(device);
20191 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
20193 color = getPixelColor(device, 320, 240);
20194 ok(color_match(color, 0x00808080, 1), "Got unexpected color 0x%08x.\n", color);
20195 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20196 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
20198 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_CONSTANT);
20199 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#lx.\n", hr);
20200 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
20201 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#lx.\n", hr);
20202 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_CURRENT);
20203 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#lx.\n", hr);
20205 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
20206 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
20208 hr = IDirect3DDevice9_BeginScene(device);
20209 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
20210 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
20211 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
20212 hr = IDirect3DDevice9_EndScene(device);
20213 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
20215 color = getPixelColor(device, 320, 240);
20216 ok(color_match(color, 0x0080007f, 1), "Got unexpected color 0x%08x.\n", color);
20217 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20218 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
20220 refcount = IDirect3DDevice9_Release(device);
20221 ok(!refcount, "Device has %lu references left.\n", refcount);
20222 done:
20223 IDirect3D9_Release(d3d);
20224 DestroyWindow(window);
20227 static void test_3dc_formats(void)
20229 static const char ati1n_data[] =
20231 /* A 4x4 texture with the color component at 50%. */
20232 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
20234 static const char ati2n_data[] =
20236 /* A 8x4 texture consisting of 2 4x4 blocks. The first block has 50% first color component,
20237 * 0% second component. Second block is the opposite. */
20238 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
20239 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
20241 static const struct
20243 struct vec3 position;
20244 struct vec2 texcoord;
20246 quads[] =
20248 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f}},
20249 {{-1.0f, 1.0f, 0.0f}, {0.0f, 1.0f}},
20250 {{ 0.0f, -1.0f, 1.0f}, {1.0f, 0.0f}},
20251 {{ 0.0f, 1.0f, 1.0f}, {1.0f, 1.0f}},
20253 {{ 0.0f, -1.0f, 0.0f}, {0.0f, 0.0f}},
20254 {{ 0.0f, 1.0f, 0.0f}, {0.0f, 1.0f}},
20255 {{ 1.0f, -1.0f, 1.0f}, {1.0f, 0.0f}},
20256 {{ 1.0f, 1.0f, 1.0f}, {1.0f, 1.0f}},
20258 static const DWORD ati1n_fourcc = MAKEFOURCC('A','T','I','1');
20259 static const DWORD ati2n_fourcc = MAKEFOURCC('A','T','I','2');
20260 static const struct
20262 struct vec2 position;
20263 D3DCOLOR amd_r500;
20264 D3DCOLOR amd_r600;
20265 D3DCOLOR nvidia_old;
20266 D3DCOLOR nvidia_new;
20268 expected_colors[] =
20270 {{ 80, 240}, 0x007fffff, 0x003f3f3f, 0x007f7f7f, 0x007f0000},
20271 {{240, 240}, 0x007fffff, 0x003f3f3f, 0x007f7f7f, 0x007f0000},
20272 {{400, 240}, 0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff},
20273 {{560, 240}, 0x007f00ff, 0x007f00ff, 0x007f00ff, 0x007f00ff},
20275 IDirect3D9 *d3d;
20276 IDirect3DDevice9 *device;
20277 unsigned int color, i;
20278 IDirect3DTexture9 *ati1n_texture, *ati2n_texture;
20279 D3DCAPS9 caps;
20280 D3DLOCKED_RECT rect;
20281 ULONG refcount;
20282 HWND window;
20283 HRESULT hr;
20285 window = create_window();
20286 d3d = Direct3DCreate9(D3D_SDK_VERSION);
20287 ok(!!d3d, "Failed to create a D3D object.\n");
20288 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
20289 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, ati1n_fourcc)))
20291 skip("ATI1N textures are not supported, skipping test.\n");
20292 goto done;
20294 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
20295 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, ati2n_fourcc)))
20297 skip("ATI2N textures are not supported, skipping test.\n");
20298 goto done;
20300 if (!(device = create_device(d3d, window, window, TRUE)))
20302 skip("Failed to create a D3D device, skipping tests.\n");
20303 goto done;
20305 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
20306 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
20307 if (!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP))
20309 skip("D3DTA_TEMP not supported, skipping tests.\n");
20310 IDirect3DDevice9_Release(device);
20311 goto done;
20314 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, ati1n_fourcc,
20315 D3DPOOL_MANAGED, &ati1n_texture, NULL);
20316 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
20318 hr = IDirect3DTexture9_LockRect(ati1n_texture, 0, &rect, NULL, 0);
20319 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#lx.\n", hr);
20320 memcpy(rect.pBits, ati1n_data, sizeof(ati1n_data));
20321 hr = IDirect3DTexture9_UnlockRect(ati1n_texture, 0);
20322 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#lx.\n", hr);
20324 hr = IDirect3DDevice9_CreateTexture(device, 8, 4, 1, 0, ati2n_fourcc,
20325 D3DPOOL_MANAGED, &ati2n_texture, NULL);
20326 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
20328 hr = IDirect3DTexture9_LockRect(ati2n_texture, 0, &rect, NULL, 0);
20329 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#lx.\n", hr);
20330 memcpy(rect.pBits, ati2n_data, sizeof(ati2n_data));
20331 hr = IDirect3DTexture9_UnlockRect(ati2n_texture, 0);
20332 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#lx.\n", hr);
20334 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0));
20335 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
20336 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BLENDTEXTUREALPHA);
20337 ok(SUCCEEDED(hr), "Failed to set color op, hr %#lx.\n", hr);
20338 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
20339 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#lx.\n", hr);
20340 /* The temporary register is initialized to 0. */
20341 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TEMP);
20342 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#lx.\n", hr);
20343 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
20344 ok(SUCCEEDED(hr), "Failed to set alpha op, hr %#lx.\n", hr);
20345 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
20346 ok(SUCCEEDED(hr), "Failed to set alpha arg, hr %#lx.\n", hr);
20347 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
20348 ok(SUCCEEDED(hr), "Failed to set color op, hr %#lx.\n", hr);
20349 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
20350 ok(SUCCEEDED(hr), "Failed to set mag filter, hr %#lx.\n", hr);
20352 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
20353 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
20354 hr = IDirect3DDevice9_BeginScene(device);
20355 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
20356 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)ati1n_texture);
20357 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
20358 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
20359 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
20360 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)ati2n_texture);
20361 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
20362 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
20363 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
20364 hr = IDirect3DDevice9_EndScene(device);
20365 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
20367 for (i = 0; i < 4; ++i)
20369 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
20370 ok (color_match(color, expected_colors[i].amd_r500, 1)
20371 || color_match(color, expected_colors[i].amd_r600, 1)
20372 || color_match(color, expected_colors[i].nvidia_old, 1)
20373 || color_match(color, expected_colors[i].nvidia_new, 1),
20374 "Got unexpected color 0x%08x, case %u.\n", color, i);
20377 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20378 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
20379 IDirect3DTexture9_Release(ati2n_texture);
20380 IDirect3DTexture9_Release(ati1n_texture);
20381 refcount = IDirect3DDevice9_Release(device);
20382 ok(!refcount, "Device has %lu references left.\n", refcount);
20384 done:
20385 IDirect3D9_Release(d3d);
20386 DestroyWindow(window);
20389 static void test_fog_interpolation(void)
20391 HRESULT hr;
20392 IDirect3DDevice9 *device;
20393 unsigned int color, i;
20394 IDirect3D9 *d3d;
20395 ULONG refcount;
20396 HWND window;
20398 static const struct
20400 struct vec3 position;
20401 D3DCOLOR diffuse;
20402 D3DCOLOR specular;
20404 quad[] =
20406 {{-1.0f, -1.0f, 0.0f}, 0xffff0000, 0xff000000},
20407 {{-1.0f, 1.0f, 0.0f}, 0xffff0000, 0xff000000},
20408 {{ 1.0f, -1.0f, 1.0f}, 0xffff0000, 0x00000000},
20409 {{ 1.0f, 1.0f, 1.0f}, 0xffff0000, 0x00000000},
20411 union
20413 DWORD d;
20414 float f;
20415 } conv;
20416 static const struct
20418 D3DFOGMODE vfog, tfog;
20419 D3DSHADEMODE shade;
20420 D3DCOLOR middle_color;
20421 BOOL todo;
20423 tests[] =
20425 {D3DFOG_NONE, D3DFOG_NONE, D3DSHADE_FLAT, 0x00007f80, FALSE},
20426 {D3DFOG_NONE, D3DFOG_NONE, D3DSHADE_GOURAUD, 0x00007f80, FALSE},
20427 {D3DFOG_EXP, D3DFOG_NONE, D3DSHADE_FLAT, 0x00007f80, TRUE},
20428 {D3DFOG_EXP, D3DFOG_NONE, D3DSHADE_GOURAUD, 0x00007f80, TRUE},
20429 {D3DFOG_NONE, D3DFOG_EXP, D3DSHADE_FLAT, 0x0000ea15, FALSE},
20430 {D3DFOG_NONE, D3DFOG_EXP, D3DSHADE_GOURAUD, 0x0000ea15, FALSE},
20431 {D3DFOG_EXP, D3DFOG_EXP, D3DSHADE_FLAT, 0x0000ea15, FALSE},
20432 {D3DFOG_EXP, D3DFOG_EXP, D3DSHADE_GOURAUD, 0x0000ea15, FALSE},
20434 static const D3DMATRIX ident_mat =
20436 1.0f, 0.0f, 0.0f, 0.0f,
20437 0.0f, 1.0f, 0.0f, 0.0f,
20438 0.0f, 0.0f, 1.0f, 0.0f,
20439 0.0f, 0.0f, 0.0f, 1.0f
20440 }}};
20441 D3DCAPS9 caps;
20443 window = create_window();
20444 d3d = Direct3DCreate9(D3D_SDK_VERSION);
20445 ok(!!d3d, "Failed to create a D3D object.\n");
20447 if (!(device = create_device(d3d, window, window, TRUE)))
20449 skip("Failed to create a D3D device, skipping tests.\n");
20450 IDirect3D9_Release(d3d);
20451 DestroyWindow(window);
20452 return;
20455 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
20456 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
20457 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
20458 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
20460 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
20461 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#lx.\n", hr);
20462 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
20463 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
20464 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
20465 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
20466 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
20467 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
20468 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
20469 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
20470 conv.f = 5.0;
20471 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGDENSITY, conv.d);
20472 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
20474 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
20475 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#lx.\n", hr);
20476 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
20477 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#lx.\n", hr);
20478 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x000000ff);
20479 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
20481 /* Some of the tests seem to depend on the projection matrix explicitly
20482 * being set to an identity matrix, even though that's the default.
20483 * (AMD Radeon X1600, AMD Radeon HD 6310, Windows 7). Without this,
20484 * the drivers seem to use a static z = 1.0 input for the fog equation.
20485 * The input value is independent of the actual z and w component of
20486 * the vertex position. */
20487 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &ident_mat);
20488 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#lx.\n", hr);
20490 for (i = 0; i < ARRAY_SIZE(tests); i++)
20492 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE) && tests[i].tfog)
20493 continue;
20495 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00808080, 0.0f, 0);
20496 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
20498 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, tests[i].shade);
20499 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
20500 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vfog);
20501 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
20502 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tfog);
20503 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
20504 hr = IDirect3DDevice9_BeginScene(device);
20505 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
20506 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
20507 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
20508 hr = IDirect3DDevice9_EndScene(device);
20509 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
20511 color = getPixelColor(device, 0, 240);
20512 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x, case %u.\n", color, i);
20513 color = getPixelColor(device, 320, 240);
20514 todo_wine_if (tests[i].todo)
20515 ok(color_match(color, tests[i].middle_color, 2),
20516 "Got unexpected color 0x%08x, case %u.\n", color, i);
20517 color = getPixelColor(device, 639, 240);
20518 ok(color_match(color, 0x0000fd02, 2), "Got unexpected color 0x%08x, case %u.\n", color, i);
20519 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20520 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
20523 refcount = IDirect3DDevice9_Release(device);
20524 ok(!refcount, "Device has %lu references left.\n", refcount);
20525 IDirect3D9_Release(d3d);
20526 DestroyWindow(window);
20529 static void test_negative_fixedfunction_fog(void)
20531 HRESULT hr;
20532 IDirect3DDevice9 *device;
20533 unsigned int color, i;
20534 IDirect3D9 *d3d;
20535 ULONG refcount;
20536 HWND window;
20538 static const struct
20540 struct vec3 position;
20541 D3DCOLOR diffuse;
20543 quad[] =
20545 {{-1.0f, -1.0f, -0.5f}, 0xffff0000},
20546 {{-1.0f, 1.0f, -0.5f}, 0xffff0000},
20547 {{ 1.0f, -1.0f, -0.5f}, 0xffff0000},
20548 {{ 1.0f, 1.0f, -0.5f}, 0xffff0000},
20550 static const struct
20552 struct vec4 position;
20553 D3DCOLOR diffuse;
20555 tquad[] =
20557 {{ 0.0f, 0.0f, -0.5f, 1.0f}, 0xffff0000},
20558 {{640.0f, 0.0f, -0.5f, 1.0f}, 0xffff0000},
20559 {{ 0.0f, 480.0f, -0.5f, 1.0f}, 0xffff0000},
20560 {{640.0f, 480.0f, -0.5f, 1.0f}, 0xffff0000},
20562 static const D3DMATRIX zero =
20564 1.0f, 0.0f, 0.0f, 0.0f,
20565 0.0f, 1.0f, 0.0f, 0.0f,
20566 0.0f, 0.0f, 0.0f, 0.0f,
20567 0.0f, 0.0f, 0.0f, 1.0f
20568 }}};
20569 /* Needed to make AMD drivers happy. Yeah, it is not supposed to
20570 * have an effect on RHW draws. */
20571 static const D3DMATRIX identity =
20573 1.0f, 0.0f, 0.0f, 0.0f,
20574 0.0f, 1.0f, 0.0f, 0.0f,
20575 0.0f, 0.0f, 1.0f, 0.0f,
20576 0.0f, 0.0f, 0.0f, 1.0f
20577 }}};
20578 static const struct
20580 DWORD pos_type;
20581 const void *quad;
20582 size_t stride;
20583 const D3DMATRIX *matrix;
20584 union
20586 float f;
20587 DWORD d;
20588 } start, end;
20589 D3DFOGMODE vfog, tfog;
20590 DWORD color, color_broken, color_broken2;
20592 tests[] =
20594 /* Run the XYZRHW tests first. Depth clamping is broken after RHW draws on the testbot.
20596 * Geforce8+ GPUs on Windows abs() table fog, everything else does not. */
20597 {D3DFVF_XYZRHW, tquad, sizeof(*tquad), &identity, { 0.0f}, {1.0f},
20598 D3DFOG_NONE, D3DFOG_LINEAR, 0x00ff0000, 0x00808000, 0x00808000},
20599 /* r200 GPUs and presumably all d3d8 and older HW clamp the fog
20600 * parameters to 0.0 and 1.0 in the table fog case. */
20601 {D3DFVF_XYZRHW, tquad, sizeof(*tquad), &identity, {-1.0f}, {0.0f},
20602 D3DFOG_NONE, D3DFOG_LINEAR, 0x00808000, 0x00ff0000, 0x0000ff00},
20603 /* test_fog_interpolation shows that vertex fog evaluates the fog
20604 * equation in the vertex pipeline. Start = -1.0 && end = 0.0 shows
20605 * that the abs happens before the fog equation is evaluated.
20607 * Vertex fog abs() behavior is the same on all GPUs. */
20608 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, { 0.0f}, {1.0f},
20609 D3DFOG_LINEAR, D3DFOG_NONE, 0x00808000, 0x00808000, 0x00808000},
20610 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, {-1.0f}, {0.0f},
20611 D3DFOG_LINEAR, D3DFOG_NONE, 0x0000ff00, 0x0000ff00, 0x0000ff00},
20612 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, { 0.0f}, {1.0f},
20613 D3DFOG_EXP, D3DFOG_NONE, 0x009b6400, 0x009b6400, 0x009b6400},
20615 D3DCAPS9 caps;
20617 window = create_window();
20618 d3d = Direct3DCreate9(D3D_SDK_VERSION);
20619 ok(!!d3d, "Failed to create a D3D object.\n");
20621 if (!(device = create_device(d3d, window, window, TRUE)))
20623 skip("Failed to create a D3D device, skipping tests.\n");
20624 IDirect3D9_Release(d3d);
20625 DestroyWindow(window);
20626 return;
20629 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
20630 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
20631 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
20632 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests.\n");
20634 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
20635 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
20636 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
20637 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
20638 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
20639 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
20640 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
20641 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
20642 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
20643 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
20645 for (i = 0; i < ARRAY_SIZE(tests); i++)
20647 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE) && tests[i].tfog)
20648 continue;
20650 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
20651 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
20653 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, tests[i].matrix);
20654 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#lx.\n", hr);
20655 hr = IDirect3DDevice9_SetFVF(device, tests[i].pos_type | D3DFVF_DIFFUSE);
20656 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#lx.\n", hr);
20657 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, tests[i].start.d);
20658 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
20659 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, tests[i].end.d);
20660 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
20661 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vfog);
20662 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
20663 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tfog);
20664 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
20666 hr = IDirect3DDevice9_BeginScene(device);
20667 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
20668 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tests[i].quad, tests[i].stride);
20669 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
20670 hr = IDirect3DDevice9_EndScene(device);
20671 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
20673 color = getPixelColor(device, 320, 240);
20674 ok(color_match(color, tests[i].color, 2) || broken(color_match(color, tests[i].color_broken, 2))
20675 || broken(color_match(color, tests[i].color_broken2, 2)),
20676 "Got unexpected color 0x%08x, case %u.\n", color, i);
20677 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20678 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
20681 refcount = IDirect3DDevice9_Release(device);
20682 ok(!refcount, "Device has %lu references left.\n", refcount);
20683 IDirect3D9_Release(d3d);
20684 DestroyWindow(window);
20687 static void test_position_index(void)
20689 static const D3DVERTEXELEMENT9 decl_elements[] =
20691 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
20692 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 1},
20693 D3DDECL_END()
20695 /* Declaring (and using) a position1 output semantic in a VS fails at draw time on AMD
20696 * but works on Nvidia.
20697 * MSDN is not consistent on this point. */
20698 static const DWORD vs_code[] =
20700 0xfffe0300, /* vs_3_0 */
20701 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
20702 0x0200001f, 0x80010000, 0x900f0001, /* dcl_position1 v1 */
20703 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position0 o0 */
20704 0x0200001f, 0x80010000, 0xe00f0001, /* dcl_position1 o1 */
20705 0x0200001f, 0x80000005, 0xe00f0002, /* dcl_texcoord0 o2 */
20706 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
20707 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
20708 0x02000001, 0xe00f0002, 0x90e40001, /* mov o2, v1 */
20709 0x0000ffff /* end */
20711 static const DWORD vs_code_2[] =
20713 0xfffe0300, /* vs_3_0 */
20714 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
20715 0x0200001f, 0x80010000, 0x900f0001, /* dcl_position1 v1 */
20716 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position0 o0 */
20717 0x0200001f, 0x80000005, 0xe00f0002, /* dcl_texcoord0 o2 */
20718 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
20719 0x02000001, 0xe00f0002, 0x90e40001, /* mov o2, v1 */
20720 0x0000ffff /* end */
20722 static const DWORD ps_code[] =
20724 0xffff0300, /* ps_3_0 */
20725 0x0200001f, 0x80010000, 0x900f0000, /* dcl_position1 v0 */
20726 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
20727 0x0000ffff /* end */
20729 static const DWORD ps_code_2[] =
20731 0xffff0300, /* ps_3_0 */
20732 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
20733 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
20734 0x0000ffff /* end */
20736 /* This one is considered invalid by the native shader assembler. */
20737 static const DWORD ps_code_bad[] =
20739 0xffff0300, /* ps_3_0 */
20740 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
20741 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
20742 0x0000ffff /* end */
20744 static const struct
20746 struct vec3 position;
20747 struct vec3 position1;
20749 quad[] =
20751 {{-1.0f, -1.0f, 0.5f}, {1.0f, 0.0f, 0.0f}},
20752 {{-1.0f, 1.0f, 0.5f}, {1.0f, 0.0f, 0.0f}},
20753 {{ 1.0f, -1.0f, 0.5f}, {0.0f, 1.0f, 0.0f}},
20754 {{ 1.0f, 1.0f, 0.5f}, {0.0f, 1.0f, 0.0f}},
20756 static const struct
20758 struct vec2 position;
20759 D3DCOLOR expected_color;
20760 D3DCOLOR broken_color;
20762 expected_colors[] =
20764 {{ 80, 240}, 0x00df2000, 0x00ff00ff},
20765 {{240, 240}, 0x009f6000, 0x00ff00ff},
20766 {{400, 240}, 0x00609f00, 0x00ff00ff},
20767 {{560, 240}, 0x0020df00, 0x00ff00ff},
20769 IDirect3D9 *d3d;
20770 IDirect3DDevice9 *device;
20771 IDirect3DVertexDeclaration9 *vertex_declaration;
20772 IDirect3DVertexShader9 *vs, *vs2;
20773 IDirect3DPixelShader9 *ps, *ps2;
20774 unsigned int color, i;
20775 D3DCAPS9 caps;
20776 ULONG refcount;
20777 HWND window;
20778 HRESULT hr;
20780 window = create_window();
20781 d3d = Direct3DCreate9(D3D_SDK_VERSION);
20782 ok(!!d3d, "Failed to create a D3D object.\n");
20783 if (!(device = create_device(d3d, window, window, TRUE)))
20785 skip("Failed to create a D3D device, skipping tests.\n");
20786 goto done;
20789 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
20790 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
20791 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0)
20792 || caps.PixelShaderVersion < D3DPS_VERSION(3, 0))
20794 skip("Shader model 3.0 unsupported, skipping tests.\n");
20795 IDirect3DDevice9_Release(device);
20796 goto done;
20799 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
20800 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed, hr %#lx\n", hr);
20802 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
20803 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#lx\n", hr);
20805 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
20806 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#lx.\n", hr);
20807 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code_2, &vs2);
20808 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#lx.\n", hr);
20810 hr = IDirect3DDevice9_SetVertexShader(device, vs);
20811 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
20813 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_bad, &ps);
20814 ok(hr == D3DERR_INVALIDCALL, "CreatePixelShader returned hr %#lx.\n", hr);
20816 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
20817 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#lx.\n", hr);
20818 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_2, &ps2);
20819 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#lx.\n", hr);
20821 hr = IDirect3DDevice9_SetPixelShader(device, ps);
20822 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
20824 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
20825 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
20826 hr = IDirect3DDevice9_BeginScene(device);
20827 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
20828 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
20829 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
20830 hr = IDirect3DDevice9_EndScene(device);
20831 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
20833 for (i = 0; i < ARRAY_SIZE(expected_colors); ++i)
20835 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
20836 ok (color_match(color, expected_colors[i].expected_color, 1)
20837 || broken(color_match(color, expected_colors[i].broken_color, 1)),
20838 "Got unexpected color 0x%08x, case %u.\n", color, i);
20841 hr = IDirect3DDevice9_SetPixelShader(device, ps2);
20842 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
20844 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
20845 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
20846 hr = IDirect3DDevice9_BeginScene(device);
20847 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
20848 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
20849 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
20850 hr = IDirect3DDevice9_EndScene(device);
20851 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
20853 for (i = 0; i < ARRAY_SIZE(expected_colors); ++i)
20855 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
20856 ok (color_match(color, expected_colors[i].expected_color, 1)
20857 || broken(color_match(color, expected_colors[i].broken_color, 1)),
20858 "Got unexpected color 0x%08x, case %u.\n", color, i);
20861 hr = IDirect3DDevice9_SetVertexShader(device, vs2);
20862 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
20864 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
20865 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
20866 hr = IDirect3DDevice9_BeginScene(device);
20867 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
20868 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
20869 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
20870 hr = IDirect3DDevice9_EndScene(device);
20871 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
20873 for (i = 0; i < ARRAY_SIZE(expected_colors); ++i)
20875 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
20876 ok (color_match(color, expected_colors[i].expected_color, 1),
20877 "Got unexpected color 0x%08x, case %u.\n", color, i);
20880 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20881 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
20883 IDirect3DPixelShader9_Release(ps2);
20884 IDirect3DPixelShader9_Release(ps);
20885 IDirect3DVertexShader9_Release(vs2);
20886 IDirect3DVertexShader9_Release(vs);
20887 IDirect3DVertexDeclaration9_Release(vertex_declaration);
20888 refcount = IDirect3DDevice9_Release(device);
20889 ok(!refcount, "Device has %lu references left.\n", refcount);
20891 done:
20892 IDirect3D9_Release(d3d);
20893 DestroyWindow(window);
20896 static void test_table_fog_zw(void)
20898 HRESULT hr;
20899 IDirect3DDevice9 *device;
20900 unsigned int color;
20901 IDirect3D9 *d3d;
20902 ULONG refcount;
20903 HWND window;
20904 D3DCAPS9 caps;
20905 static struct
20907 struct vec4 position;
20908 D3DCOLOR diffuse;
20910 quad[] =
20912 {{ 0.0f, 0.0f, 0.0f, 0.0f}, 0xffff0000},
20913 {{640.0f, 0.0f, 0.0f, 0.0f}, 0xffff0000},
20914 {{ 0.0f, 480.0f, 0.0f, 0.0f}, 0xffff0000},
20915 {{640.0f, 480.0f, 0.0f, 0.0f}, 0xffff0000},
20917 static const D3DMATRIX identity =
20919 1.0f, 0.0f, 0.0f, 0.0f,
20920 0.0f, 1.0f, 0.0f, 0.0f,
20921 0.0f, 0.0f, 1.0f, 0.0f,
20922 0.0f, 0.0f, 0.0f, 1.0f
20923 }}};
20924 static const struct
20926 float z, w;
20927 D3DZBUFFERTYPE z_test;
20928 unsigned int color;
20930 tests[] =
20932 {0.7f, 0.0f, D3DZB_TRUE, 0x004cb200},
20933 {0.7f, 0.0f, D3DZB_FALSE, 0x004cb200},
20934 {0.7f, 0.3f, D3DZB_TRUE, 0x004cb200},
20935 {0.7f, 0.3f, D3DZB_FALSE, 0x004cb200},
20936 {0.7f, 3.0f, D3DZB_TRUE, 0x004cb200},
20937 {0.7f, 3.0f, D3DZB_FALSE, 0x004cb200},
20938 {0.3f, 0.0f, D3DZB_TRUE, 0x00b24c00},
20939 {0.3f, 0.0f, D3DZB_FALSE, 0x00b24c00},
20941 unsigned int i;
20943 window = create_window();
20944 d3d = Direct3DCreate9(D3D_SDK_VERSION);
20945 ok(!!d3d, "Failed to create a D3D object.\n");
20947 if (!(device = create_device(d3d, window, window, TRUE)))
20949 skip("Failed to create a D3D device, skipping tests.\n");
20950 IDirect3D9_Release(d3d);
20951 DestroyWindow(window);
20952 return;
20955 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
20956 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
20957 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
20959 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping POSITIONT table fog test.\n");
20960 goto done;
20963 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
20964 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
20965 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
20966 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
20967 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
20968 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
20969 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
20970 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
20971 /* Work around an AMD Windows driver bug. Needs a proj matrix applied redundantly. */
20972 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
20973 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#lx.\n", hr);
20974 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
20975 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
20976 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
20977 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#lx.\n", hr);
20979 for (i = 0; i < ARRAY_SIZE(tests); ++i)
20981 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
20982 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
20984 quad[0].position.z = tests[i].z;
20985 quad[1].position.z = tests[i].z;
20986 quad[2].position.z = tests[i].z;
20987 quad[3].position.z = tests[i].z;
20988 quad[0].position.w = tests[i].w;
20989 quad[1].position.w = tests[i].w;
20990 quad[2].position.w = tests[i].w;
20991 quad[3].position.w = tests[i].w;
20992 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, tests[i].z_test);
20993 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
20995 hr = IDirect3DDevice9_BeginScene(device);
20996 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
20997 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
20998 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
20999 hr = IDirect3DDevice9_EndScene(device);
21000 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
21002 color = getPixelColor(device, 320, 240);
21003 ok(color_match(color, tests[i].color, 2),
21004 "Got unexpected color 0x%08x, expected 0x%08x, case %u.\n", color, tests[i].color, i);
21005 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
21006 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
21009 done:
21010 refcount = IDirect3DDevice9_Release(device);
21011 ok(!refcount, "Device has %lu references left.\n", refcount);
21012 IDirect3D9_Release(d3d);
21013 DestroyWindow(window);
21016 static void test_signed_formats(void)
21018 unsigned int expected_color, color, i, j, x, y;
21019 IDirect3DDevice9 *device;
21020 HWND window;
21021 HRESULT hr;
21022 IDirect3DTexture9 *texture, *texture_sysmem;
21023 IDirect3DSurface9 *src_surface, *dst_surface;
21024 D3DLOCKED_RECT locked_rect;
21025 IDirect3DPixelShader9 *shader, *shader_alpha;
21026 IDirect3D9 *d3d;
21027 D3DCAPS9 caps;
21028 ULONG refcount;
21030 /* The input data was designed for D3DFMT_L6V5U5 and then transferred
21031 * to the other formats because L6V5U5 is the lowest precision format.
21032 * It tests the extreme values -1.0 (-16) and 1.0 (15) for U/V and
21033 * 0.0 (0) and 1.0 (63) for L, the neutral point 0 as well as -1 and 1.
21034 * Some other intermediate values are tested too. The input value -15
21035 * (min + 1) is tested as well. Unlike what OpenGL 4.4 says in section
21036 * 2.3.4.1, this value does not represent -1.0. In the interest of re-
21037 * using the expected output data the 8 bit and 16 bit values in V8U8
21038 * and V16U16 match (post-normalization) the 5 bit input values. Thus
21039 * -1, 1 and -127 are not tested in V8U8.
21041 * 8 bit specific values like -127 are tested in the Q channel of
21042 * D3DFMT_Q8W8V8U8. Here d3d seems to follow the rules from the GL
21043 * spec. AMD's r200 is broken though and returns a value < -1.0 for
21044 * -128. The difference between using -127 or -128 as the lowest
21045 * possible value gets lost in the slop of 1 though. */
21046 static const USHORT content_v8u8[4][4] =
21048 {0x0000, 0x7f7f, 0x8880, 0x0000},
21049 {0x0080, 0x8000, 0x7f00, 0x007f},
21050 {0x193b, 0xe8c8, 0x0808, 0xf8f8},
21051 {0x4444, 0xc0c0, 0xa066, 0x22e0},
21053 static const DWORD content_v16u16[4][4] =
21055 {0x00000000, 0x7fff7fff, 0x88008000, 0x00000000},
21056 {0x00008000, 0x80000000, 0x7fff0000, 0x00007fff},
21057 {0x19993bbb, 0xe800c800, 0x08880888, 0xf800f800},
21058 {0x44444444, 0xc000c000, 0xa0006666, 0x2222e000},
21060 static const DWORD content_q8w8v8u8[4][4] =
21062 {0x00000000, 0xff7f7f7f, 0x7f008880, 0x817f0000},
21063 {0x10000080, 0x20008000, 0x30007f00, 0x4000007f},
21064 {0x5020193b, 0x6028e8c8, 0x70020808, 0x807ff8f8},
21065 {0x90414444, 0xa000c0c0, 0x8261a066, 0x834922e0},
21067 static const DWORD content_x8l8v8u8[4][4] =
21069 {0x00000000, 0x00ff7f7f, 0x00008880, 0x00ff0000},
21070 {0x00000080, 0x00008000, 0x00007f00, 0x0000007f},
21071 {0x0041193b, 0x0051e8c8, 0x00040808, 0x00fff8f8},
21072 {0x00824444, 0x0000c0c0, 0x00c2a066, 0x009222e0},
21074 /* D3DFMT_L6V5U5 has poor precision on some GPUs. On a GeForce 7 the highest V and U value (15)
21075 * results in the output color 0xfb, which is 4 steps away from the correct value 0xff. It is
21076 * not the ~0xf0 you'd get if you blindly left-shifted the 5 bit value to form an 8 bit value
21077 * though.
21079 * There may also be an off-by-one bug involved: The value -7 should result in the output 0x47,
21080 * but ends up as 0x4d. Likewise, -3 becomes 0x6e instead of 0x67. Those values are close to
21081 * the proper results of -6 and -2.
21083 * On Wine the emulation with unsigned R5G6B5 has poor precision, e.g. the signed 0 becomes 16,
21084 * and ((16 / 31) - 0.5) * 2.0 is 0.032 instead of 0.000. The final output result we read back
21085 * is 0x84 instead of 0x80. */
21086 static const USHORT content_l6v5u5[4][4] =
21088 {0x0000, 0xfdef, 0x0230, 0xfc00},
21089 {0x0010, 0x0200, 0x01e0, 0x000f},
21090 {0x4067, 0x53b9, 0x0421, 0xffff},
21091 {0x8108, 0x0318, 0xc28c, 0x909c},
21093 static const struct
21095 D3DFORMAT format;
21096 const char *name;
21097 const void *content;
21098 SIZE_T pixel_size;
21099 BOOL blue, alpha;
21100 unsigned int slop, slop_broken, alpha_broken;
21102 formats[] =
21104 {D3DFMT_V8U8, "D3DFMT_V8U8", content_v8u8, sizeof(WORD), FALSE, FALSE, 1, 0, FALSE},
21105 {D3DFMT_V16U16, "D3DFMT_V16U16", content_v16u16, sizeof(DWORD), FALSE, FALSE, 1, 0, FALSE},
21106 {D3DFMT_Q8W8V8U8, "D3DFMT_Q8W8V8U8", content_q8w8v8u8, sizeof(DWORD), TRUE, TRUE, 1, 0, TRUE },
21107 {D3DFMT_X8L8V8U8, "D3DFMT_X8L8V8U8", content_x8l8v8u8, sizeof(DWORD), TRUE, FALSE, 1, 0, FALSE},
21108 {D3DFMT_L6V5U5, "D3DFMT_L6V5U5", content_l6v5u5, sizeof(WORD), TRUE, FALSE, 4, 7, FALSE},
21110 static const struct
21112 D3DPOOL pool;
21113 UINT width;
21114 RECT src_rect;
21115 POINT dst_point;
21117 tests[] =
21119 {D3DPOOL_SYSTEMMEM, 4, {1, 1, 2, 3}, {2, 0}},
21120 {D3DPOOL_SYSTEMMEM, 1, {0, 1, 1, 3}, {0, 0}},
21121 {D3DPOOL_MANAGED, 4, {1, 1, 2, 3}, {2, 0}},
21122 {D3DPOOL_MANAGED, 1, {0, 1, 1, 3}, {0, 0}},
21124 static const DWORD shader_code[] =
21126 0xffff0101, /* ps_1_1 */
21127 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0,5, 0,5 */
21128 0x00000042, 0xb00f0000, /* tex t0 */
21129 0x00000004, 0x800f0000, 0xb0e40000, 0xa0e40000, 0xa0e40000, /* mad r0, t0, c0, c0 */
21130 0x0000ffff /* end */
21132 static const DWORD shader_code_alpha[] =
21134 /* The idea of this shader is to replicate the alpha value in .rg, and set
21135 * blue to 1.0 iff the alpha value is < -1.0 and 0.0 otherwise. */
21136 0xffff0101, /* ps_1_1 */
21137 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
21138 0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
21139 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
21140 0x00000042, 0xb00f0000, /* tex t0 */
21141 0x00000004, 0x80070000, 0xb0ff0000, 0xa0e40000, 0xa0e40000, /* mad r0.rgb, t0.a, c0, c0 */
21142 0x00000003, 0x80080000, 0xb1ff0000, 0xa0e40000, /* sub r0.a, -t0.a, c0 */
21143 0x00000050, 0x80080000, 0x80ff0000, 0xa0ff0001, 0xa0ff0002, /* cnd r0.a, r0.a, c1.a, c2.a */
21144 0x00000005, 0x80070001, 0xa0e40001, 0x80e40000, /* mul r1.rgb, c1, r0 */
21145 0x00000004, 0x80070000, 0x80ff0000, 0xa0e40002, 0x80e40001, /* mad r0.rgb, r0.a, c2, r1 */
21146 0x0000ffff /* end */
21148 static const struct
21150 struct vec3 position;
21151 struct vec2 texcrd;
21153 quad[] =
21155 /* Flip the y coordinate to make the input and
21156 * output arrays easier to compare. */
21157 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 1.0f}},
21158 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 0.0f}},
21159 {{ 1.0f, -1.0f, 0.0f}, { 1.0f, 1.0f}},
21160 {{ 1.0f, 1.0f, 0.0f}, { 1.0f, 0.0f}},
21162 static const D3DCOLOR expected_alpha[4][4] =
21164 {0x00808000, 0x007f7f00, 0x00ffff00, 0x00000000},
21165 {0x00909000, 0x00a0a000, 0x00b0b000, 0x00c0c000},
21166 {0x00d0d000, 0x00e0e000, 0x00f0f000, 0x00000000},
21167 {0x00101000, 0x00202000, 0x00010100, 0x00020200},
21169 static const BOOL alpha_broken[4][4] =
21171 {FALSE, FALSE, FALSE, FALSE},
21172 {FALSE, FALSE, FALSE, FALSE},
21173 {FALSE, FALSE, FALSE, TRUE },
21174 {FALSE, FALSE, FALSE, FALSE},
21176 static const D3DCOLOR expected_colors[4][4] =
21178 {0x00808080, 0x00fefeff, 0x00010780, 0x008080ff},
21179 {0x00018080, 0x00800180, 0x0080fe80, 0x00fe8080},
21180 {0x00ba98a0, 0x004767a8, 0x00888881, 0x007878ff},
21181 {0x00c3c3c0, 0x003f3f80, 0x00e51fe1, 0x005fa2c8},
21183 static const D3DCOLOR expected_colors2[4][4] =
21185 {0x00808080, 0x00fefeff, 0x00800180, 0x008080ff},
21186 {0x00018080, 0x00800180, 0x004767a8, 0x00fe8080},
21187 {0x00ba98a0, 0x004767a8, 0x00888881, 0x007878ff},
21188 {0x00c3c3c0, 0x003f3f80, 0x00e51fe1, 0x005fa2c8},
21190 static const D3DCOLOR expected_colors3[4] =
21192 0x00018080,
21193 0x00ba98a0,
21194 0x00ba98a0,
21195 0x00c3c3c0,
21198 window = create_window();
21199 d3d = Direct3DCreate9(D3D_SDK_VERSION);
21200 ok(!!d3d, "Failed to create a D3D object.\n");
21202 if (!(device = create_device(d3d, window, window, TRUE)))
21204 skip("Failed to create a D3D device, skipping tests.\n");
21205 IDirect3D9_Release(d3d);
21206 DestroyWindow(window);
21207 return;
21210 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
21211 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
21213 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
21215 skip("Pixel shaders not supported, skipping converted format test.\n");
21216 goto done;
21219 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
21220 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
21221 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
21222 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
21223 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
21224 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#lx.\n", hr);
21225 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_alpha, &shader_alpha);
21226 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#lx.\n", hr);
21228 for (i = 0; i < ARRAY_SIZE(formats); i++)
21230 hr = IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
21231 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, formats[i].format);
21232 if (FAILED(hr))
21234 skip("Format %s not supported, skipping.\n", formats[i].name);
21235 continue;
21238 for (j = 0; j < ARRAY_SIZE(tests); j++)
21240 texture_sysmem = NULL;
21241 hr = IDirect3DDevice9_CreateTexture(device, tests[j].width, 4, 1, 0,
21242 formats[i].format, tests[j].pool, &texture, NULL);
21243 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
21245 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
21246 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#lx.\n", hr);
21247 for (y = 0; y < 4; y++)
21249 memcpy((char *)locked_rect.pBits + y * locked_rect.Pitch,
21250 (char *)formats[i].content + y * 4 * formats[i].pixel_size,
21251 tests[j].width * formats[i].pixel_size);
21253 hr = IDirect3DTexture9_UnlockRect(texture, 0);
21254 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#lx.\n", hr);
21256 if (tests[j].pool == D3DPOOL_SYSTEMMEM)
21258 texture_sysmem = texture;
21259 hr = IDirect3DDevice9_CreateTexture(device, tests[j].width, 4, 1, 0,
21260 formats[i].format, D3DPOOL_DEFAULT, &texture, NULL);
21261 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
21263 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)texture_sysmem,
21264 (IDirect3DBaseTexture9 *)texture);
21265 ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx.\n", hr);
21268 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
21269 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
21270 hr = IDirect3DDevice9_SetPixelShader(device, shader_alpha);
21271 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
21273 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00330033, 0.0f, 0);
21274 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
21275 hr = IDirect3DDevice9_BeginScene(device);
21276 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
21277 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(*quad));
21278 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
21279 hr = IDirect3DDevice9_EndScene(device);
21280 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
21282 for (y = 0; y < 4; y++)
21284 for (x = 0; x < tests[j].width; x++)
21286 BOOL r200_broken = formats[i].alpha_broken && alpha_broken[y][x];
21287 if (formats[i].alpha)
21288 expected_color = expected_alpha[y][x];
21289 else
21290 expected_color = 0x00ffff00;
21292 color = getPixelColor(device, 80 + 160 * x, 60 + 120 * y);
21293 ok(color_match(color, expected_color, 1) || broken(r200_broken),
21294 "Expected color 0x%08x, got 0x%08x, format %s, test %u, location %ux%u.\n",
21295 expected_color, color, formats[i].name, j, x, y);
21298 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
21299 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
21301 hr = IDirect3DDevice9_SetPixelShader(device, shader);
21302 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
21304 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00330033, 0.0f, 0);
21305 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
21306 hr = IDirect3DDevice9_BeginScene(device);
21307 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
21308 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(*quad));
21309 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
21310 hr = IDirect3DDevice9_EndScene(device);
21311 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
21313 for (y = 0; y < 4; y++)
21315 for (x = 0; x < tests[j].width; x++)
21317 expected_color = expected_colors[y][x];
21318 if (!formats[i].blue)
21319 expected_color |= 0x000000ff;
21321 color = getPixelColor(device, 80 + 160 * x, 60 + 120 * y);
21322 ok(color_match(color, expected_color, formats[i].slop)
21323 || broken(color_match(color, expected_color, formats[i].slop_broken)),
21324 "Expected color 0x%08x, got 0x%08x, format %s, test %u, location %ux%u.\n",
21325 expected_color, color, formats[i].name, j, x, y);
21328 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
21329 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
21331 if (tests[j].pool != D3DPOOL_SYSTEMMEM)
21333 IDirect3DTexture9_Release(texture);
21334 continue;
21337 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &dst_surface);
21338 ok(SUCCEEDED(hr), "Failed to get surface, hr %#lx.\n", hr);
21339 IDirect3DTexture9_GetSurfaceLevel(texture_sysmem, 0, &src_surface);
21340 ok(SUCCEEDED(hr), "Failed to get surface, hr %#lx.\n", hr);
21342 hr = IDirect3DDevice9_UpdateSurface(device, src_surface,
21343 &tests[j].src_rect, dst_surface, &tests[j].dst_point);
21344 ok(SUCCEEDED(hr), "Failed to update surface, hr %#lx.\n", hr);
21346 IDirect3DSurface9_Release(dst_surface);
21347 IDirect3DSurface9_Release(src_surface);
21349 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00003300, 0.0f, 0);
21350 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
21351 hr = IDirect3DDevice9_BeginScene(device);
21352 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
21353 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(*quad));
21354 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
21355 hr = IDirect3DDevice9_EndScene(device);
21356 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
21358 for (y = 0; y < 4; y++)
21360 for (x = 0; x < tests[j].width; x++)
21362 if (tests[j].width == 4)
21363 expected_color = expected_colors2[y][x];
21364 else
21365 expected_color = expected_colors3[y];
21367 if (!formats[i].blue)
21368 expected_color |= 0x000000ff;
21370 color = getPixelColor(device, 80 + 160 * x, 60 + 120 * y);
21371 ok(color_match(color, expected_color, formats[i].slop)
21372 || broken(color_match(color, expected_color, formats[i].slop_broken)),
21373 "Expected color 0x%08x, got 0x%08x, format %s, test %u, location %ux%u.\n",
21374 expected_color, color, formats[i].name, j, x, y);
21377 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
21378 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
21380 IDirect3DTexture9_Release(texture_sysmem);
21381 IDirect3DTexture9_Release(texture);
21385 IDirect3DPixelShader9_Release(shader);
21386 IDirect3DPixelShader9_Release(shader_alpha);
21388 done:
21389 refcount = IDirect3DDevice9_Release(device);
21390 ok(!refcount, "Device has %lu references left.\n", refcount);
21391 IDirect3D9_Release(d3d);
21392 DestroyWindow(window);
21395 static void test_multisample_mismatch(void)
21397 IDirect3DDevice9 *device;
21398 unsigned int color;
21399 IDirect3D9 *d3d;
21400 HWND window;
21401 HRESULT hr;
21402 ULONG refcount;
21403 IDirect3DSurface9 *rt, *rt_multi, *ds;
21404 static const struct
21406 struct vec3 position;
21407 DWORD color;
21409 quad[] =
21411 {{ -1.0f, -1.0f, 0.0f}, 0x000000ff},
21412 {{ -1.0f, 1.0f, 0.0f}, 0x000000ff},
21413 {{ 1.0f, -1.0f, 1.0f}, 0x000000ff},
21414 {{ 1.0f, 1.0f, 1.0f}, 0x000000ff},
21417 window = create_window();
21418 d3d = Direct3DCreate9(D3D_SDK_VERSION);
21419 ok(!!d3d, "Failed to create a D3D object.\n");
21420 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
21421 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
21423 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisample mismatch test.\n");
21424 IDirect3D9_Release(d3d);
21425 return;
21427 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
21428 D3DFMT_D24X8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
21430 skip("Multisampling not supported for D3DFMT_D24X8, skipping multisample mismatch test.\n");
21431 IDirect3D9_Release(d3d);
21432 return;
21435 if (!(device = create_device(d3d, window, window, TRUE)))
21437 skip("Failed to create a D3D device, skipping tests.\n");
21438 IDirect3D9_Release(d3d);
21439 DestroyWindow(window);
21440 return;
21443 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
21444 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt_multi, NULL);
21445 ok(SUCCEEDED(hr), "Failed to create render target, hr %#lx.\n", hr);
21447 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.1f, 0);
21448 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
21450 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
21451 ok(SUCCEEDED(hr), "Failed to set depth stencil, hr %#lx.\n", hr);
21452 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &rt);
21453 ok(SUCCEEDED(hr), "Failed to get render target, hr %#lx.\n", hr);
21454 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt_multi);
21455 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
21457 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
21458 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
21459 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
21460 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
21462 /* Clear with incompatible buffers. Partial and combined clears. */
21463 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
21464 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
21465 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.3f, 0);
21466 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
21467 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x0000ff00, 0.5f, 0);
21468 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
21470 /* The color buffer is reliably cleared on AMD and Nvidia GPUs. */
21471 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
21472 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
21473 hr = IDirect3DDevice9_StretchRect(device, rt_multi, NULL, rt, NULL, D3DTEXF_POINT);
21474 ok(SUCCEEDED(hr), "StretchRect failed, hr %#lx.\n", hr);
21475 color = getPixelColor(device, 320, 240);
21476 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
21477 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
21478 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
21480 /* Check depth buffer values. AMD GPUs (r500 and evergreen tested) clear
21481 * the depth buffer like you'd expect in a correct framebuffer
21482 * setup. Nvidia doesn't clear it, neither in the Z only clear case nor in
21483 * the combined clear case.
21484 * In Wine we currently happen to allow the depth only clear case but
21485 * disallow the combined one. */
21486 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
21487 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
21488 hr = IDirect3DDevice9_BeginScene(device);
21489 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
21490 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
21491 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
21492 hr = IDirect3DDevice9_EndScene(device);
21493 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
21494 color = getPixelColor(device, 62, 240);
21495 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
21496 color = getPixelColor(device, 64, 240);
21497 ok(color_match(color, 0x0000ff00, 1) || color_match(color, 0x000000ff, 1),
21498 "Got unexpected color 0x%08x.\n", color);
21499 color = getPixelColor(device, 318, 240);
21500 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x000000ff, 1)),
21501 "Got unexpected color 0x%08x.\n", color);
21502 color = getPixelColor(device, 322, 240);
21503 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
21504 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
21505 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
21507 /* Draw with incompatible buffers. AMD even performs Z testing, and the Z test
21508 * results appear to be correct for this simple draw. Nvidia doesn't draw unless
21509 * the depth test is disabled. Setting ZFUNC = ALWAYS doesn't make the geometry
21510 * show up either. Only test the ZENABLE = FALSE case for now. */
21511 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
21512 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
21513 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt_multi);
21514 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
21515 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
21516 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
21517 hr = IDirect3DDevice9_BeginScene(device);
21518 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
21519 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
21520 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
21521 hr = IDirect3DDevice9_EndScene(device);
21522 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
21524 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
21525 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
21526 hr = IDirect3DDevice9_StretchRect(device, rt_multi, NULL, rt, NULL, D3DTEXF_POINT);
21527 ok(SUCCEEDED(hr), "StretchRect failed, hr %#lx.\n", hr);
21528 color = getPixelColor(device, 320, 240);
21529 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
21530 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
21531 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
21533 IDirect3DSurface9_Release(ds);
21535 /* Test the reverse situation: Multisampled depth buffer, single sampled color buffer.
21536 * Color clears work as expected, AMD also clears the depth buffer, Nvidia does not. */
21537 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24X8,
21538 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &ds, NULL);
21539 ok(SUCCEEDED(hr), "Failed to create depth/stencil, hr %#lx.\n", hr);
21540 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
21541 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#lx.\n", hr);
21542 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt_multi);
21543 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
21544 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ffff00, 0.1f, 0);
21545 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
21547 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
21548 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
21549 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
21550 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
21551 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.3f, 0);
21552 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
21553 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x0000ff00, 0.5f, 0);
21554 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
21556 color = getPixelColor(device, 320, 240);
21557 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
21558 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
21559 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
21561 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt_multi);
21562 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
21563 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
21564 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
21565 hr = IDirect3DDevice9_BeginScene(device);
21566 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
21567 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
21568 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
21569 hr = IDirect3DDevice9_EndScene(device);
21570 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
21572 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
21573 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
21574 hr = IDirect3DDevice9_StretchRect(device, rt_multi, NULL, rt, NULL, D3DTEXF_POINT);
21575 ok(SUCCEEDED(hr), "StretchRect failed, hr %#lx.\n", hr);
21576 color = getPixelColor(device, 62, 240);
21577 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
21578 color = getPixelColor(device, 318, 240);
21579 ok(color_match(color, 0x00ffff00, 1) || broken(color_match(color, 0x000000ff, 1)),
21580 "Got unexpected color 0x%08x.\n", color);
21581 color = getPixelColor(device, 322, 240);
21582 ok(color_match(color, 0x00ffff00, 1), "Got unexpected color 0x%08x.\n", color);
21583 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
21584 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
21586 /* Draw with a single sampled color buffer and a multisampled depth buffer. Again
21587 * AMD seems to perform correct Z testing, Nvidia doesn't draw unless the Z test
21588 * is disabled. Again only test the ZENABLE = FALSE case. */
21589 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
21590 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
21591 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
21592 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
21593 hr = IDirect3DDevice9_BeginScene(device);
21594 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
21595 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
21596 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
21597 hr = IDirect3DDevice9_EndScene(device);
21598 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
21599 color = getPixelColor(device, 320, 240);
21600 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
21601 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
21602 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
21604 /* Draw with both buffers single sampled but multisample quality set to 1 for depth buffer.
21605 * The difference in multisample quality parameter is ignored. */
21606 IDirect3DSurface9_Release(ds);
21607 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24X8,
21608 D3DMULTISAMPLE_NONE, 1, FALSE, &ds, NULL);
21609 ok(SUCCEEDED(hr), "Failed to create depth/stencil, hr %#lx.\n", hr);
21610 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
21611 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
21612 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
21613 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#lx.\n", hr);
21614 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x0000ff00, 0.5f, 0);
21615 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
21616 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
21617 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
21618 hr = IDirect3DDevice9_BeginScene(device);
21619 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
21620 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
21621 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
21622 hr = IDirect3DDevice9_EndScene(device);
21623 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
21624 color = getPixelColor(device, 62, 240);
21625 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
21626 color = getPixelColor(device, 322, 240);
21627 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
21628 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
21629 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
21631 IDirect3DSurface9_Release(rt);
21632 IDirect3DSurface9_Release(ds);
21633 IDirect3DSurface9_Release(rt_multi);
21635 refcount = IDirect3DDevice9_Release(device);
21636 ok(!refcount, "Device has %lu references left.\n", refcount);
21637 IDirect3D9_Release(d3d);
21638 DestroyWindow(window);
21641 static void test_texcoordindex(void)
21643 static const D3DMATRIX mat =
21645 1.0f, 0.0f, 0.0f, 0.0f,
21646 0.0f, 0.0f, 0.0f, 0.0f,
21647 0.0f, 0.0f, 0.0f, 0.0f,
21648 0.0f, 0.0f, 0.0f, 0.0f,
21649 }}};
21650 static const struct
21652 struct vec3 pos;
21653 struct vec2 texcoord1;
21654 struct vec2 texcoord2;
21655 struct vec2 texcoord3;
21657 quad[] =
21659 {{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f}, {0.0f, 0.0f}, {1.0f, 1.0f}},
21660 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 0.0f}},
21661 {{ 1.0f, -1.0f, 0.0f}, {1.0f, 1.0f}, {1.0f, 0.0f}, {0.0f, 1.0f}},
21662 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 0.0f}},
21664 IDirect3DDevice9 *device;
21665 unsigned int color;
21666 IDirect3D9 *d3d9;
21667 HWND window;
21668 HRESULT hr;
21669 IDirect3DTexture9 *texture1, *texture2;
21670 D3DLOCKED_RECT locked_rect;
21671 ULONG refcount;
21672 DWORD *ptr;
21674 window = create_window();
21675 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
21676 ok(!!d3d9, "Failed to create a D3D object.\n");
21677 if (!(device = create_device(d3d9, window, window, TRUE)))
21679 skip("Failed to create a D3D device, skipping tests.\n");
21680 IDirect3D9_Release(d3d9);
21681 DestroyWindow(window);
21682 return;
21685 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture1, NULL);
21686 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
21687 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
21688 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
21690 hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, D3DLOCK_DISCARD);
21691 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#lx.\n", hr);
21692 ptr = locked_rect.pBits;
21693 ptr[0] = 0xff000000;
21694 ptr[1] = 0xff00ff00;
21695 ptr[2] = 0xff0000ff;
21696 ptr[3] = 0xff00ffff;
21697 hr = IDirect3DTexture9_UnlockRect(texture1, 0);
21698 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#lx.\n", hr);
21700 hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, D3DLOCK_DISCARD);
21701 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#lx.\n", hr);
21702 ptr = locked_rect.pBits;
21703 ptr[0] = 0xff000000;
21704 ptr[1] = 0xff0000ff;
21705 ptr[2] = 0xffff0000;
21706 ptr[3] = 0xffff00ff;
21707 hr = IDirect3DTexture9_UnlockRect(texture2, 0);
21708 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#lx.\n", hr);
21710 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture1);
21711 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
21712 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *)texture2);
21713 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
21714 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX3);
21715 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
21716 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
21717 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
21718 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
21719 ok(SUCCEEDED(hr), "Failed to set color op, hr %#lx.\n", hr);
21720 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
21721 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#lx.\n", hr);
21722 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
21723 ok(SUCCEEDED(hr), "Failed to set color op, hr %#lx.\n", hr);
21724 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
21725 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#lx.\n", hr);
21726 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
21727 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#lx.\n", hr);
21728 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
21729 ok(SUCCEEDED(hr), "Failed to set color op, hr %#lx.\n", hr);
21731 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXCOORDINDEX, 1);
21732 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#lx.\n", hr);
21733 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXCOORDINDEX, 0);
21734 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#lx.\n", hr);
21736 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
21737 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
21739 hr = IDirect3DDevice9_BeginScene(device);
21740 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
21741 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
21742 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
21743 hr = IDirect3DDevice9_EndScene(device);
21744 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
21746 color = getPixelColor(device, 160, 120);
21747 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
21748 color = getPixelColor(device, 480, 120);
21749 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
21750 color = getPixelColor(device, 160, 360);
21751 ok(color_match(color, 0x00ff0000, 2), "Got unexpected color 0x%08x.\n", color);
21752 color = getPixelColor(device, 480, 360);
21753 ok(color_match(color, 0x00ffffff, 2), "Got unexpected color 0x%08x.\n", color);
21755 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
21756 ok(SUCCEEDED(hr), "Failed to set texture transform flags, hr %#lx.\n", hr);
21757 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE1, &mat);
21758 ok(SUCCEEDED(hr), "Failed to set transformation matrix, hr %#lx.\n", hr);
21760 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
21761 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
21763 hr = IDirect3DDevice9_BeginScene(device);
21764 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
21765 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
21766 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
21767 hr = IDirect3DDevice9_EndScene(device);
21768 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
21770 color = getPixelColor(device, 160, 120);
21771 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
21772 color = getPixelColor(device, 480, 120);
21773 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
21774 color = getPixelColor(device, 160, 360);
21775 ok(color_match(color, 0x00000000, 2), "Got unexpected color 0x%08x.\n", color);
21776 color = getPixelColor(device, 480, 360);
21777 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
21779 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
21780 ok(SUCCEEDED(hr), "Failed to set texture transform flags, hr %#lx.\n", hr);
21781 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXCOORDINDEX, 2);
21782 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#lx.\n", hr);
21784 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
21785 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
21787 hr = IDirect3DDevice9_BeginScene(device);
21788 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
21789 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
21790 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
21791 hr = IDirect3DDevice9_EndScene(device);
21792 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
21794 color = getPixelColor(device, 160, 120);
21795 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
21796 color = getPixelColor(device, 480, 120);
21797 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
21798 color = getPixelColor(device, 160, 360);
21799 ok(color_match(color, 0x00ff00ff, 2), "Got unexpected color 0x%08x.\n", color);
21800 color = getPixelColor(device, 480, 360);
21801 ok(color_match(color, 0x00ffff00, 2), "Got unexpected color 0x%08x.\n", color);
21803 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
21804 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
21806 IDirect3DTexture9_Release(texture1);
21807 IDirect3DTexture9_Release(texture2);
21809 refcount = IDirect3DDevice9_Release(device);
21810 ok(!refcount, "Device has %lu references left.\n", refcount);
21811 IDirect3D9_Release(d3d9);
21812 DestroyWindow(window);
21815 static void test_vertex_blending(void)
21817 IDirect3DVertexDeclaration9 *vertex_declaration;
21818 IDirect3DDevice9 *device;
21819 unsigned int color, i;
21820 IDirect3D9 *d3d;
21821 D3DCAPS9 caps;
21822 ULONG refcount;
21823 HWND window;
21824 HRESULT hr;
21826 static const D3DMATRIX view_mat =
21828 2.0f / 10.0f, 0.0f, 0.0f, 0.0f,
21829 0.0f, 2.0f / 10.0f, 0.0f, 0.0f,
21830 0.0f, 0.0f, 1.0f, 0.0f,
21831 0.0f, 0.0f, 0.0f, 1.0f
21832 }}},
21833 upper_left =
21835 1.0f, 0.0f, 0.0f, 0.0f,
21836 0.0f, 1.0f, 0.0f, 0.0f,
21837 0.0f, 0.0f, 1.0f, 0.0f,
21838 -4.0f, 4.0f, 0.0f, 1.0f
21839 }}},
21840 lower_left =
21842 1.0f, 0.0f, 0.0f, 0.0f,
21843 0.0f, 1.0f, 0.0f, 0.0f,
21844 0.0f, 0.0f, 1.0f, 0.0f,
21845 -4.0f, -4.0f, 0.0f, 1.0f
21846 }}},
21847 upper_right =
21849 1.0f, 0.0f, 0.0f, 0.0f,
21850 0.0f, 1.0f, 0.0f, 0.0f,
21851 0.0f, 0.0f, 1.0f, 0.0f,
21852 4.0f, 4.0f, 0.0f, 1.0f
21853 }}},
21854 lower_right =
21856 1.0f, 0.0f, 0.0f, 0.0f,
21857 0.0f, 1.0f, 0.0f, 0.0f,
21858 0.0f, 0.0f, 1.0f, 0.0f,
21859 4.0f, -4.0f, 0.0f, 1.0f
21860 }}};
21862 static const POINT quad_upper_right_points[] =
21864 {576, 48}, {-1, -1},
21866 quad_upper_right_empty_points[] =
21868 {64, 48}, {64, 432}, {576, 432}, {320, 240}, {-1, -1}
21870 quad_center_points[] =
21872 {320, 240}, {-1, -1}
21874 quad_center_empty_points[] =
21876 {64, 48}, {576, 48}, {64, 432}, {576, 432}, {-1, -1}
21878 quad_upper_center_points[] =
21880 {320, 48}, {-1, -1}
21882 quad_upper_center_empty_points[] =
21884 {320, 240}, {64, 48}, {576, 48}, {-1, -1}
21886 quad_fullscreen_points[] =
21888 {320, 48}, {320, 240}, {64, 48}, {576, 48}, {64, 432}, {576, 432}, {-1, -1}
21890 quad_fullscreen_empty_points[] =
21892 {-1, -1}
21895 static const struct
21897 DWORD fvf;
21898 D3DVERTEXELEMENT9 decl_elements[3];
21899 struct
21901 struct
21903 struct vec3 position;
21904 struct vec3 blendweights;
21906 vertex_data_float[4];
21907 struct
21909 struct vec3 position;
21910 D3DCOLOR blendweights;
21912 vertex_data_d3dcolor[4];
21913 } s;
21914 const POINT *quad_points;
21915 const POINT *empty_points;
21917 tests[] =
21919 /* upper right */
21921 D3DFVF_XYZB3,
21922 {{0}},
21923 {{{{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
21924 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
21925 {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
21926 {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}}}},
21927 quad_upper_right_points, quad_upper_right_empty_points
21929 /* center */
21931 D3DFVF_XYZB3,
21932 {{0}},
21933 {{{{-1.0f, -1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}},
21934 {{-1.0f, 1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}},
21935 {{ 1.0f, -1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}},
21936 {{ 1.0f, 1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}}}},
21937 quad_center_points, quad_center_empty_points
21939 /* upper center */
21941 D3DFVF_XYZB3,
21942 {{0}},
21943 {{{{-1.0f, -1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}},
21944 {{-1.0f, 1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}},
21945 {{ 1.0f, -1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}},
21946 {{ 1.0f, 1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}}}},
21947 quad_upper_center_points, quad_upper_center_empty_points
21949 /* full screen */
21951 D3DFVF_XYZB3,
21952 {{0}},
21953 {{{{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f, 0.0f}},
21954 {{-1.0f, 1.0f, 0.0f}, {1.0f, 0.0f, 0.0f}},
21955 {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}},
21956 {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}}}},
21957 quad_fullscreen_points, quad_fullscreen_empty_points
21959 /* D3DCOLOR, full screen */
21963 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
21964 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
21965 D3DDECL_END()
21967 {{{{0}}},
21968 {{{-1.0f, -1.0f, 0.0f}, 0x0000ff00},
21969 {{-1.0f, 1.0f, 0.0f}, 0x00ff0000},
21970 {{ 1.0f, -1.0f, 0.0f}, 0x000000ff},
21971 {{ 1.0f, 1.0f, 0.0f}, 0x00000000}}},
21972 quad_fullscreen_points, quad_fullscreen_empty_points
21976 window = create_window();
21977 d3d = Direct3DCreate9(D3D_SDK_VERSION);
21978 ok(!!d3d, "Failed to create a D3D object.\n");
21979 if (!(device = create_device(d3d, window, window, TRUE)))
21981 skip("Failed to create a D3D device, skipping tests.\n");
21982 goto done;
21985 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
21986 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
21987 if (caps.MaxVertexBlendMatrices < 4)
21989 skip("Only %lu vertex blend matrices supported, skipping tests.\n", caps.MaxVertexBlendMatrices);
21990 IDirect3DDevice9_Release(device);
21991 goto done;
21994 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
21995 ok(hr == S_OK, "Got hr %#lx.\n", hr);
21997 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &view_mat);
21998 ok(hr == S_OK, "Got hr %#lx.\n", hr);
22000 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), &upper_left);
22001 ok(hr == S_OK, "Got hr %#lx.\n", hr);
22002 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(1), &lower_left);
22003 ok(hr == S_OK, "Got hr %#lx.\n", hr);
22004 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(2), &lower_right);
22005 ok(hr == S_OK, "Got hr %#lx.\n", hr);
22006 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(3), &upper_right);
22007 ok(hr == S_OK, "Got hr %#lx.\n", hr);
22009 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_VERTEXBLEND, D3DVBF_3WEIGHTS);
22010 ok(hr == S_OK, "Got hr %#lx.\n", hr);
22012 for (i = 0; i < ARRAY_SIZE(tests); ++i)
22014 const POINT *point;
22016 if (tests[i].fvf)
22018 hr = IDirect3DDevice9_SetFVF(device, tests[i].fvf);
22019 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
22020 vertex_declaration = NULL;
22022 else
22024 hr = IDirect3DDevice9_CreateVertexDeclaration(device, tests[i].decl_elements, &vertex_declaration);
22025 ok(SUCCEEDED(hr), "Failed to create vertex declaration, hr %#lx.\n", hr);
22026 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
22027 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
22030 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
22031 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
22033 hr = IDirect3DDevice9_BeginScene(device);
22034 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
22036 if (tests[i].fvf)
22037 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
22038 tests[i].s.vertex_data_float, sizeof(*tests[i].s.vertex_data_float));
22039 else
22040 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
22041 tests[i].s.vertex_data_d3dcolor, sizeof(*tests[i].s.vertex_data_d3dcolor));
22042 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
22044 hr = IDirect3DDevice9_EndScene(device);
22045 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
22047 point = tests[i].quad_points;
22048 while (point->x != -1 && point->y != -1)
22050 color = getPixelColor(device, point->x, point->y);
22051 ok(color_match(color, 0x00ffffff, 1), "Expected quad at (%ld,%ld).\n", point->x, point->y);
22052 ++point;
22055 point = tests[i].empty_points;
22056 while (point->x != -1 && point->y != -1)
22058 color = getPixelColor(device, point->x, point->y);
22059 ok(color_match(color, 0x00000000, 1), "Unexpected quad at (%ld,%ld).\n", point->x, point->y);
22060 ++point;
22063 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
22064 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
22066 if (vertex_declaration)
22067 IDirect3DVertexDeclaration9_Release(vertex_declaration);
22070 refcount = IDirect3DDevice9_Release(device);
22071 ok(!refcount, "Device has %lu references left.\n", refcount);
22073 done:
22074 IDirect3D9_Release(d3d);
22075 DestroyWindow(window);
22078 static void test_updatetexture(void)
22080 BOOL r32f_supported, ati2n_supported, do_visual_test;
22081 unsigned int color, t, i, f, l, x, y, z;
22082 IDirect3DBaseTexture9 *src, *dst;
22083 D3DLOCKED_RECT locked_rect;
22084 D3DLOCKED_BOX locked_box;
22085 IDirect3DDevice9 *device;
22086 IDirect3D9 *d3d9;
22087 ULONG refcount;
22088 D3DCAPS9 caps;
22089 HWND window;
22090 HRESULT hr;
22091 static const struct
22093 struct vec3 pos;
22094 struct vec2 texcoord;
22096 quad[] =
22098 {{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f}},
22099 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f}},
22100 {{ 1.0f, -1.0f, 0.0f}, {1.0f, 1.0f}},
22101 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.0f}},
22103 static const struct
22105 struct vec3 pos;
22106 struct vec3 texcoord;
22108 quad_cube_tex[] =
22110 {{-1.0f, -1.0f, 0.0f}, {1.0f, -0.5f, 0.5f}},
22111 {{-1.0f, 1.0f, 0.0f}, {1.0f, 0.5f, 0.5f}},
22112 {{ 1.0f, -1.0f, 0.0f}, {1.0f, -0.5f, -0.5f}},
22113 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.5f, -0.5f}},
22115 static const struct
22117 UINT src_width, src_height;
22118 UINT dst_width, dst_height;
22119 UINT src_levels, dst_levels;
22120 D3DFORMAT src_format, dst_format;
22121 BOOL broken_result, broken_updatetex;
22123 tests[] =
22125 {8, 8, 8, 8, 0, 0, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 0 */
22126 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 1 */
22127 {8, 8, 8, 8, 2, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 2 */
22128 {8, 8, 8, 8, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 3 */
22129 {8, 8, 8, 8, 4, 0, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 4 */
22130 {8, 8, 2, 2, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 5 */
22131 /* The WARP renderer doesn't handle these cases correctly. */
22132 {8, 8, 8, 8, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, TRUE}, /* 6 */
22133 {8, 8, 4, 4, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, TRUE}, /* 7 */
22134 /* Not clear what happens here on Windows, it doesn't make much sense
22135 * though (on Nvidia it seems to upload the 4x4 surface into the 7x7
22136 * one or something like that). */
22137 /* {8, 8, 7, 7, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, */
22138 {8, 8, 8, 8, 1, 4, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 8 */
22139 /* For this one UpdateTexture() returns failure on WARP on > Win 10 1709. */
22140 {4, 4, 8, 8, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE, TRUE}, /* 9 */
22141 /* This one causes weird behavior on Windows (it probably writes out
22142 * of the texture memory). */
22143 /* {8, 8, 4, 4, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, */
22144 {8, 4, 4, 2, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 10 */
22145 {8, 4, 2, 4, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 11 */
22146 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_X8R8G8B8, FALSE}, /* 12 */
22147 {8, 8, 8, 8, 4, 4, D3DFMT_X8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 13 */
22148 /* The data is converted correctly on AMD, on Nvidia nothing happens
22149 * (it draws a black quad). */
22150 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_R5G6B5, TRUE}, /* 14 */
22151 /* Here the data is converted on AMD, just copied and "reinterpreted" as
22152 * a 32 bit float on Nvidia (specifically the tested value becomes a
22153 * very small float number which we get as 0 in the test). */
22154 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_R32F, TRUE}, /* 15 */
22155 /* This one doesn't seem to give the expected results on AMD. */
22156 /* {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_Q8W8V8U8, FALSE}, */
22157 {8, 8, 8, 8, 4, 4, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE}, /* 16 */
22158 {8, 8, 8, 8, 4, 2, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE}, /* 17 */
22159 {8, 8, 2, 2, 4, 2, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE}, /* 18 */
22161 static const struct
22163 D3DRESOURCETYPE type;
22164 DWORD fvf;
22165 const void *quad;
22166 unsigned int vertex_size;
22167 DWORD cap;
22168 const char *name;
22170 texture_types[] =
22172 {D3DRTYPE_TEXTURE, D3DFVF_XYZ | D3DFVF_TEX1,
22173 quad, sizeof(*quad), D3DPTEXTURECAPS_MIPMAP, "2D mipmapped"},
22175 {D3DRTYPE_CUBETEXTURE, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0),
22176 quad_cube_tex, sizeof(*quad_cube_tex), D3DPTEXTURECAPS_CUBEMAP, "Cube"},
22178 {D3DRTYPE_VOLUMETEXTURE, D3DFVF_XYZ | D3DFVF_TEX1,
22179 quad, sizeof(*quad), D3DPTEXTURECAPS_VOLUMEMAP, "Volume"}
22182 window = create_window();
22183 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
22184 ok(!!d3d9, "Failed to create a D3D object.\n");
22185 if (!(device = create_device(d3d9, window, window, TRUE)))
22187 skip("Failed to create a D3D device, skipping tests.\n");
22188 IDirect3D9_Release(d3d9);
22189 DestroyWindow(window);
22190 return;
22193 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
22194 ok(SUCCEEDED(hr), "Failed to get caps, hr %#lx.\n", hr);
22196 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
22197 ok(SUCCEEDED(hr), "Failed to set texture filtering state, hr %#lx.\n", hr);
22198 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
22199 ok(SUCCEEDED(hr), "Failed to set texture clamping state, hr %#lx.\n", hr);
22200 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
22201 ok(SUCCEEDED(hr), "Failed to set texture clamping state, hr %#lx.\n", hr);
22202 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
22203 ok(SUCCEEDED(hr), "Failed to set texture clamping state, hr %#lx.\n", hr);
22204 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
22205 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
22206 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
22207 ok(hr == D3D_OK, "Failed to set texture stage state, hr %#lx.\n", hr);
22208 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
22209 ok(hr == D3D_OK, "Failed to set texture stage state, hr %#lx.\n", hr);
22211 for (t = 0; t < ARRAY_SIZE(texture_types); ++t)
22213 if (!(caps.TextureCaps & texture_types[t].cap))
22215 skip("%s textures not supported, skipping some tests.\n", texture_types[t].name);
22216 continue;
22218 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
22219 D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_FILTER, texture_types[t].type, D3DFMT_A8R8G8B8)))
22221 skip("%s D3DFMT_A8R8G8B8 texture filtering is not supported, skipping some tests.\n",
22222 texture_types[t].name);
22223 continue;
22225 r32f_supported = TRUE;
22226 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
22227 D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_FILTER, texture_types[t].type, D3DFMT_R32F)))
22229 skip("%s R32F textures are not supported, skipping some tests.\n", texture_types[t].name);
22230 r32f_supported = FALSE;
22232 ati2n_supported = TRUE;
22233 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
22234 D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_FILTER, texture_types[t].type, MAKEFOURCC('A','T','I','2'))))
22236 skip("%s ATI2N textures are not supported, skipping some tests.\n", texture_types[t].name);
22237 ati2n_supported = FALSE;
22240 hr = IDirect3DDevice9_SetFVF(device, texture_types[t].fvf);
22241 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
22243 for (i = 0; i < ARRAY_SIZE(tests); ++i)
22245 if (tests[i].dst_format == D3DFMT_R32F && !r32f_supported)
22246 continue;
22247 if (tests[i].dst_format == MAKEFOURCC('A','T','I','2') && !ati2n_supported)
22248 continue;
22250 switch (texture_types[t].type)
22252 case D3DRTYPE_TEXTURE:
22253 hr = IDirect3DDevice9_CreateTexture(device,
22254 tests[i].src_width, tests[i].src_height,
22255 tests[i].src_levels, 0, tests[i].src_format, D3DPOOL_SYSTEMMEM,
22256 (IDirect3DTexture9 **)&src, NULL);
22257 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx, case %u, %u.\n", hr, t, i);
22258 hr = IDirect3DDevice9_CreateTexture(device,
22259 tests[i].dst_width, tests[i].dst_height,
22260 tests[i].dst_levels, 0, tests[i].dst_format, D3DPOOL_DEFAULT,
22261 (IDirect3DTexture9 **)&dst, NULL);
22262 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx, case %u, %u.\n", hr, t, i);
22263 break;
22264 case D3DRTYPE_CUBETEXTURE:
22265 hr = IDirect3DDevice9_CreateCubeTexture(device,
22266 tests[i].src_width,
22267 tests[i].src_levels, 0, tests[i].src_format, D3DPOOL_SYSTEMMEM,
22268 (IDirect3DCubeTexture9 **)&src, NULL);
22269 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx, case %u, %u.\n", hr, t, i);
22270 hr = IDirect3DDevice9_CreateCubeTexture(device,
22271 tests[i].dst_width,
22272 tests[i].dst_levels, 0, tests[i].dst_format, D3DPOOL_DEFAULT,
22273 (IDirect3DCubeTexture9 **)&dst, NULL);
22274 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx, case %u, %u.\n", hr, t, i);
22275 break;
22276 case D3DRTYPE_VOLUMETEXTURE:
22277 hr = IDirect3DDevice9_CreateVolumeTexture(device,
22278 tests[i].src_width, tests[i].src_height, tests[i].src_width,
22279 tests[i].src_levels, 0, tests[i].src_format, D3DPOOL_SYSTEMMEM,
22280 (IDirect3DVolumeTexture9 **)&src, NULL);
22281 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx, case %u, %u.\n", hr, t, i);
22282 hr = IDirect3DDevice9_CreateVolumeTexture(device,
22283 tests[i].dst_width, tests[i].dst_height, tests[i].dst_width,
22284 tests[i].dst_levels, 0, tests[i].dst_format, D3DPOOL_DEFAULT,
22285 (IDirect3DVolumeTexture9 **)&dst, NULL);
22286 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx, case %u, %u.\n", hr, t, i);
22287 break;
22288 default:
22289 trace("Unexpected resource type.\n");
22292 /* Skip the visual part of the test for ATI2N (laziness) and cases that
22293 * give a different (and unlikely to be useful) result. */
22294 do_visual_test = (tests[i].src_format == D3DFMT_A8R8G8B8 || tests[i].src_format == D3DFMT_X8R8G8B8)
22295 && tests[i].src_levels != 0
22296 && tests[i].src_width >= tests[i].dst_width && tests[i].src_height >= tests[i].dst_height
22297 && !(tests[i].src_width > tests[i].src_height && tests[i].dst_width < tests[i].dst_height);
22299 if (do_visual_test)
22301 DWORD *ptr = NULL;
22302 unsigned int width, height, depth, row_pitch = 0, slice_pitch = 0;
22304 for (f = 0; f < (texture_types[t].type == D3DRTYPE_CUBETEXTURE ? 6 : 1); ++f)
22306 width = tests[i].src_width;
22307 height = texture_types[t].type != D3DRTYPE_CUBETEXTURE ? tests[i].src_height : tests[i].src_width;
22308 depth = texture_types[t].type == D3DRTYPE_VOLUMETEXTURE ? width : 1;
22310 for (l = 0; l < tests[i].src_levels; ++l)
22312 switch (texture_types[t].type)
22314 case D3DRTYPE_TEXTURE:
22315 hr = IDirect3DTexture9_LockRect((IDirect3DTexture9 *)src,
22316 l, &locked_rect, NULL, 0);
22317 ptr = locked_rect.pBits;
22318 row_pitch = locked_rect.Pitch / sizeof(*ptr);
22319 break;
22320 case D3DRTYPE_CUBETEXTURE:
22321 hr = IDirect3DCubeTexture9_LockRect((IDirect3DCubeTexture9 *)src,
22322 f, l, &locked_rect, NULL, 0);
22323 ptr = locked_rect.pBits;
22324 row_pitch = locked_rect.Pitch / sizeof(*ptr);
22325 break;
22326 case D3DRTYPE_VOLUMETEXTURE:
22327 hr = IDirect3DVolumeTexture9_LockBox((IDirect3DVolumeTexture9 *)src,
22328 l, &locked_box, NULL, 0);
22329 ptr = locked_box.pBits;
22330 row_pitch = locked_box.RowPitch / sizeof(*ptr);
22331 slice_pitch = locked_box.SlicePitch / sizeof(*ptr);
22332 break;
22333 default:
22334 trace("Unexpected resource type.\n");
22336 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#lx.\n", hr);
22338 for (z = 0; z < depth; ++z)
22340 for (y = 0; y < height; ++y)
22342 for (x = 0; x < width; ++x)
22344 ptr[z * slice_pitch + y * row_pitch + x] = 0xff000000
22345 | (DWORD)(x / (width - 1.0f) * 255.0f) << 16
22346 | (DWORD)(y / (height - 1.0f) * 255.0f) << 8;
22351 switch (texture_types[t].type)
22353 case D3DRTYPE_TEXTURE:
22354 hr = IDirect3DTexture9_UnlockRect((IDirect3DTexture9 *)src, l);
22355 break;
22356 case D3DRTYPE_CUBETEXTURE:
22357 hr = IDirect3DCubeTexture9_UnlockRect((IDirect3DCubeTexture9 *)src, f, l);
22358 break;
22359 case D3DRTYPE_VOLUMETEXTURE:
22360 hr = IDirect3DVolumeTexture9_UnlockBox((IDirect3DVolumeTexture9 *)src, l);
22361 break;
22362 default:
22363 trace("Unexpected resource type.\n");
22365 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#lx.\n", hr);
22367 width >>= 1;
22368 if (!width)
22369 width = 1;
22370 height >>= 1;
22371 if (!height)
22372 height = 1;
22373 depth >>= 1;
22374 if (!depth)
22375 depth = 1;
22380 hr = IDirect3DDevice9_UpdateTexture(device, src, dst);
22381 if (FAILED(hr))
22383 todo_wine ok(SUCCEEDED(hr) || broken(tests[i].broken_updatetex),
22384 "Failed to update texture, hr %#lx, case %u, %u.\n", hr, t, i);
22385 IDirect3DBaseTexture9_Release(src);
22386 IDirect3DBaseTexture9_Release(dst);
22387 continue;
22389 ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx, case %u, %u.\n", hr, t, i);
22391 if (do_visual_test)
22393 hr = IDirect3DDevice9_SetTexture(device, 0, dst);
22394 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
22396 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 1.0f, 0);
22397 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
22399 hr = IDirect3DDevice9_BeginScene(device);
22400 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
22401 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
22402 texture_types[t].quad, texture_types[t].vertex_size);
22403 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
22404 hr = IDirect3DDevice9_EndScene(device);
22405 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
22407 color = getPixelColor(device, 320, 240);
22408 ok (color_match(color, 0x007f7f00, 3) || broken(tests[i].broken_result)
22409 || broken(color == 0x00adbeef), /* WARP device often just breaks down. */
22410 "Got unexpected color 0x%08x, case %u, %u.\n", color, t, i);
22413 IDirect3DBaseTexture9_Release(src);
22414 IDirect3DBaseTexture9_Release(dst);
22417 refcount = IDirect3DDevice9_Release(device);
22418 ok(!refcount, "Device has %lu references left.\n", refcount);
22419 IDirect3D9_Release(d3d9);
22420 DestroyWindow(window);
22423 static void test_depthbias(void)
22425 IDirect3DDevice9 *device;
22426 unsigned int color, i;
22427 IDirect3D9 *d3d;
22428 IDirect3DSurface9 *ds;
22429 D3DCAPS9 caps;
22430 ULONG refcount;
22431 HWND window;
22432 HRESULT hr;
22433 static const D3DFORMAT formats[] =
22435 D3DFMT_D16, D3DFMT_D24X8, D3DFMT_D32, D3DFMT_D24S8, MAKEFOURCC('I','N','T','Z'),
22437 /* The scaling factor detection function detects the wrong factor for
22438 * float formats on Nvidia, therefore the following tests are disabled.
22439 * The wined3d function detects 2^23 like for fixed point formats but
22440 * the test needs 2^22 to pass.
22442 * AMD GPUs need a different scaling factor for float depth buffers
22443 * (2^24) than fixed point (2^23), but the wined3d detection function
22444 * works there, producing the right result in the test.
22446 * D3DFMT_D32F_LOCKABLE, D3DFMT_D24FS8,
22450 static const struct
22452 struct vec3 position;
22454 quad[] =
22456 {{-1.0f, -1.0f, 0.0f}},
22457 {{-1.0f, 1.0f, 0.0f}},
22458 {{ 1.0f, -1.0f, 1.0f}},
22459 {{ 1.0f, 1.0f, 1.0f}},
22461 union
22463 float f;
22464 DWORD d;
22465 } conv;
22467 window = create_window();
22468 d3d = Direct3DCreate9(D3D_SDK_VERSION);
22469 ok(!!d3d, "Failed to create a D3D object.\n");
22470 if (!(device = create_device(d3d, window, window, TRUE)))
22472 skip("Failed to create a D3D device, skipping tests.\n");
22473 goto done;
22476 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
22477 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
22478 if (!(caps.RasterCaps & D3DPRASTERCAPS_DEPTHBIAS))
22480 IDirect3DDevice9_Release(device);
22481 skip("D3DPRASTERCAPS_DEPTHBIAS not supported.\n");
22482 goto done;
22485 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
22486 ok(hr == S_OK, "Got hr %#lx.\n", hr);
22487 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
22488 ok(hr == S_OK, "Got hr %#lx.\n", hr);
22489 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
22490 ok(SUCCEEDED(hr), "Failed to set color op, hr %#lx.\n", hr);
22491 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
22492 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#lx.\n", hr);
22493 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
22494 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
22496 for (i = 0; i < ARRAY_SIZE(formats); ++i)
22498 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
22499 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, formats[i])))
22501 skip("Depth format %u not supported, skipping.\n", formats[i]);
22502 continue;
22505 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, formats[i],
22506 D3DMULTISAMPLE_NONE, 0, FALSE, &ds, NULL);
22507 ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr %#lx.\n", hr);
22508 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
22509 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#lx.\n", hr);
22510 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 0.5f, 0);
22511 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
22513 hr = IDirect3DDevice9_BeginScene(device);
22514 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
22516 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x00ff0000);
22517 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
22518 conv.f = -0.2f;
22519 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DEPTHBIAS, conv.d);
22520 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
22521 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
22522 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
22524 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
22525 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
22526 conv.f = 0.0f;
22527 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DEPTHBIAS, conv.d);
22528 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
22529 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
22530 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
22532 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x000000ff);
22533 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
22534 conv.f = 0.2f;
22535 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DEPTHBIAS, conv.d);
22536 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
22537 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
22538 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
22540 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x00ffffff);
22541 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
22542 conv.f = 0.4f;
22543 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DEPTHBIAS, conv.d);
22544 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
22545 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
22546 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
22548 color = getPixelColor(device, 61, 240);
22549 ok(color_match(color, 0x00ffffff, 1), "Got unexpected color %08x at x=62, format %u.\n", color, formats[i]);
22550 color = getPixelColor(device, 65, 240);
22552 /* The broken results are for the WARP driver on the testbot. It seems to initialize
22553 * a scaling factor based on the first depth format that is used. Other formats with
22554 * a different depth size then render incorrectly. */
22555 todo_wine_if(!color_match(color, 0x000000ff, 1))
22556 ok(color_match(color, 0x000000ff, 1) || broken(color_match(color, 0x00ffffff, 1)),
22557 "Got unexpected color %08x at x=64, format %u.\n", color, formats[i]);
22558 color = getPixelColor(device, 190, 240);
22559 todo_wine_if(!color_match(color, 0x000000ff, 1))
22560 ok(color_match(color, 0x000000ff, 1) || broken(color_match(color, 0x00ffffff, 1)),
22561 "Got unexpected color %08x at x=190, format %u.\n", color, formats[i]);
22563 color = getPixelColor(device, 194, 240);
22564 todo_wine_if(!color_match(color, 0x0000ff00, 1))
22565 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ffffff, 1)),
22566 "Got unexpected color %08x at x=194, format %u.\n", color, formats[i]);
22567 color = getPixelColor(device, 318, 240);
22568 todo_wine_if(!color_match(color, 0x0000ff00, 1))
22569 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ffffff, 1)),
22570 "Got unexpected color %08x at x=318, format %u.\n", color, formats[i]);
22572 color = getPixelColor(device, 322, 240);
22573 todo_wine_if(!color_match(color, 0x00ff0000, 1))
22574 ok(color_match(color, 0x00ff0000, 1) || broken(color_match(color, 0x00000000, 1)),
22575 "Got unexpected color %08x at x=322, format %u.\n", color, formats[i]);
22576 color = getPixelColor(device, 446, 240);
22577 todo_wine_if(!color_match(color, 0x00ff0000, 1))
22578 ok(color_match(color, 0x00ff0000, 1) || broken(color_match(color, 0x00000000, 1)),
22579 "Got unexpected color %08x at x=446, format %u.\n", color, formats[i]);
22581 color = getPixelColor(device, 450, 240);
22582 ok(color_match(color, 0x00000000, 1), "Got unexpected color %08x at x=446, format %u.\n", color, formats[i]);
22584 hr = IDirect3DDevice9_EndScene(device);
22585 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
22587 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
22588 ok(hr == S_OK, "Got hr %#lx.\n", hr);
22589 IDirect3DSurface9_Release(ds);
22592 refcount = IDirect3DDevice9_Release(device);
22593 ok(!refcount, "Device has %lu references left.\n", refcount);
22595 done:
22596 IDirect3D9_Release(d3d);
22597 DestroyWindow(window);
22600 static void test_flip(void)
22602 IDirect3DDevice9 *device;
22603 unsigned int color, i;
22604 IDirect3D9 *d3d;
22605 ULONG refcount;
22606 HWND window;
22607 HRESULT hr;
22608 IDirect3DSurface9 *back_buffers[3], *test_surface;
22609 D3DPRESENT_PARAMETERS present_parameters = {0};
22611 window = create_window();
22612 d3d = Direct3DCreate9(D3D_SDK_VERSION);
22613 ok(!!d3d, "Failed to create a D3D object.\n");
22615 present_parameters.BackBufferWidth = 640;
22616 present_parameters.BackBufferHeight = 480;
22617 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
22618 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
22619 present_parameters.hDeviceWindow = window;
22620 present_parameters.Windowed = TRUE;
22621 present_parameters.BackBufferCount = 3;
22622 present_parameters.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
22623 if (FAILED(hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
22624 window, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device)))
22626 skip("Failed to create a D3D device, skipping tests.\n");
22627 IDirect3D9_Release(d3d);
22628 DestroyWindow(window);
22629 return;
22632 for (i = 0; i < ARRAY_SIZE(back_buffers); ++i)
22634 hr = IDirect3DDevice9_GetBackBuffer(device, 0, i, D3DBACKBUFFER_TYPE_MONO, &back_buffers[i]);
22635 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#lx.\n", hr);
22637 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &test_surface);
22638 ok(SUCCEEDED(hr), "Failed to get render target, hr %#lx.\n", hr);
22639 ok(test_surface == back_buffers[0], "Expected render target %p, got %p.\n", back_buffers[0], test_surface);
22640 IDirect3DSurface9_Release(test_surface);
22642 hr = IDirect3DDevice9_SetRenderTarget(device, 0, back_buffers[2]);
22643 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
22645 hr = IDirect3DDevice9_ColorFill(device, back_buffers[0], NULL, 0xffff0000);
22646 ok(SUCCEEDED(hr), "Failed to color fill, hr %#lx.\n", hr);
22647 hr = IDirect3DDevice9_ColorFill(device, back_buffers[1], NULL, 0xff00ff00);
22648 ok(SUCCEEDED(hr), "Failed to color fill, hr %#lx.\n", hr);
22649 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
22650 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx\n", hr);
22652 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
22653 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
22655 /* Render target is unmodified. */
22656 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &test_surface);
22657 ok(SUCCEEDED(hr), "Failed to get render target, hr %#lx.\n", hr);
22658 ok(test_surface == back_buffers[2], "Expected render target %p, got %p.\n", back_buffers[2], test_surface);
22659 IDirect3DSurface9_Release(test_surface);
22661 /* Backbuffer surface pointers are unmodified */
22662 for (i = 0; i < ARRAY_SIZE(back_buffers); ++i)
22664 hr = IDirect3DDevice9_GetBackBuffer(device, 0, i, D3DBACKBUFFER_TYPE_MONO, &test_surface);
22665 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#lx.\n", hr);
22666 ok(test_surface == back_buffers[i], "Expected back buffer %u = %p, got %p.\n",
22667 i, back_buffers[i], test_surface);
22668 IDirect3DSurface9_Release(test_surface);
22671 /* Contents were changed. */
22672 color = getPixelColorFromSurface(back_buffers[0], 1, 1);
22673 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
22674 color = getPixelColorFromSurface(back_buffers[1], 1, 1);
22675 ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
22677 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0f, 0);
22678 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx\n", hr);
22680 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
22681 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
22683 color = getPixelColorFromSurface(back_buffers[0], 1, 1);
22684 ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
22685 color = getPixelColorFromSurface(back_buffers[1], 1, 1);
22686 ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
22688 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
22689 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
22691 color = getPixelColorFromSurface(back_buffers[0], 1, 1);
22692 ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
22694 for (i = 0; i < ARRAY_SIZE(back_buffers); ++i)
22695 IDirect3DSurface9_Release(back_buffers[i]);
22697 refcount = IDirect3DDevice9_Release(device);
22698 ok(!refcount, "Device has %lu references left.\n", refcount);
22700 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
22701 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
22703 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisample flip test.\n");
22704 goto done;
22707 present_parameters.BackBufferCount = 2;
22708 present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
22709 present_parameters.Flags = 0;
22710 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
22711 window, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device);
22713 for (i = 0; i < present_parameters.BackBufferCount; ++i)
22715 hr = IDirect3DDevice9_GetBackBuffer(device, 0, i, D3DBACKBUFFER_TYPE_MONO, &back_buffers[i]);
22716 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#lx.\n", hr);
22719 hr = IDirect3DDevice9_SetRenderTarget(device, 0, back_buffers[1]);
22720 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
22721 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0f, 0);
22722 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
22724 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
22725 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
22727 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
22728 D3DMULTISAMPLE_NONE, 0, TRUE, &test_surface, NULL);
22729 ok(SUCCEEDED(hr), "Failed to create surface, hr %#lx.\n", hr);
22730 hr = IDirect3DDevice9_StretchRect(device, back_buffers[0], NULL, test_surface, NULL, D3DTEXF_POINT);
22731 ok(SUCCEEDED(hr), "StretchRect failed, hr %#lx.\n", hr);
22733 color = getPixelColorFromSurface(test_surface, 1, 1);
22734 ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
22736 IDirect3DSurface9_Release(test_surface);
22737 for (i = 0; i < present_parameters.BackBufferCount; ++i)
22738 IDirect3DSurface9_Release(back_buffers[i]);
22740 refcount = IDirect3DDevice9_Release(device);
22741 ok(!refcount, "Device has %lu references left.\n", refcount);
22743 done:
22744 IDirect3D9_Release(d3d);
22745 DestroyWindow(window);
22748 static void test_uninitialized_varyings(void)
22750 static const D3DMATRIX mat =
22752 1.0f, 0.0f, 0.0f, 0.0f,
22753 0.0f, 1.0f, 0.0f, 0.0f,
22754 0.0f, 0.0f, 1.0f, 0.0f,
22755 0.0f, 0.0f, 0.0f, 1.0f,
22756 }}};
22757 static const struct vec3 quad[] =
22759 {-1.0f, -1.0f, 0.1f},
22760 {-1.0f, 1.0f, 0.1f},
22761 { 1.0f, -1.0f, 0.1f},
22762 { 1.0f, 1.0f, 0.1f},
22764 static const DWORD vs1_code[] =
22766 0xfffe0101, /* vs_1_1 */
22767 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
22768 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
22769 0x0000ffff
22771 static const DWORD vs1_partial_code[] =
22773 0xfffe0101, /* vs_1_1 */
22774 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
22775 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
22776 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
22777 0x00000001, 0xd0010000, 0xa0e40000, /* mov oD0.x, c0 */
22778 0x00000001, 0xd0010001, 0xa0e40000, /* mov oD1.x, c0 */
22779 0x00000001, 0xe0010000, 0xa0e40000, /* mov oT0.x, c0 */
22780 0x0000ffff
22782 static const DWORD vs2_code[] =
22784 0xfffe0200, /* vs_2_0 */
22785 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
22786 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
22787 0x0000ffff
22789 static const DWORD vs2_partial_code[] =
22791 0xfffe0200, /* vs_2_0 */
22792 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
22793 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
22794 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
22795 0x02000001, 0xd0010000, 0xa0e40000, /* mov oD0.x, c0 */
22796 0x02000001, 0xd0010001, 0xa0e40000, /* mov oD1.x, c0 */
22797 0x02000001, 0xe0010000, 0xa0e40000, /* mov oT0.x, c0 */
22798 0x0000ffff
22800 static const DWORD vs3_code[] =
22802 0xfffe0300, /* vs_3_0 */
22803 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
22804 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
22805 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
22806 0x0000ffff
22808 static const DWORD vs3_partial_code[] =
22810 0xfffe0300, /* vs_3_0 */
22811 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
22812 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
22813 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */
22814 0x0200001f, 0x8001000a, 0xe00f0002, /* dcl_color1 o2 */
22815 0x0200001f, 0x80000005, 0xe00f0003, /* dcl_texcoord0 o3 */
22816 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
22817 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
22818 0x02000001, 0xe0010001, 0xa0e40000, /* mov o1.x, c0 */
22819 0x02000001, 0xe0010002, 0xa0e40000, /* mov o2.x, c0 */
22820 0x02000001, 0xe0010003, 0xa0e40000, /* mov o3.x, c0 */
22821 0x0000ffff
22823 static const DWORD ps1_diffuse_code[] =
22825 0xffff0101, /* ps_1_1 */
22826 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
22827 0x0000ffff
22829 static const DWORD ps1_specular_code[] =
22831 0xffff0101, /* ps_1_1 */
22832 0x00000001, 0x800f0000, 0x90e40001, /* mov r0, v1 */
22833 0x0000ffff
22835 static const DWORD ps1_texcoord_code[] =
22837 0xffff0101, /* ps_1_1 */
22838 0x00000040, 0xb00f0000, /* texcoord t0 */
22839 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
22840 0x0000ffff
22842 static const DWORD ps2_diffuse_code[] =
22844 0xffff0200, /* ps_2_0 */
22845 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
22846 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
22847 0x0000ffff
22849 static const DWORD ps2_specular_code[] =
22851 0xffff0200, /* ps_2_0 */
22852 0x0200001f, 0x80000000, 0x900f0001, /* dcl v1 */
22853 0x02000001, 0x800f0800, 0x90e40001, /* mov oC0, v1 */
22854 0x0000ffff
22856 static const DWORD ps2_texcoord_code[] =
22858 0xffff0200, /* ps_2_0 */
22859 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
22860 0x02000001, 0x800f0800, 0xb0e40000, /* mov oC0, t0 */
22861 0x0000ffff
22863 #if 0
22864 /* This has been left here for documentation purposes. It is referenced in disabled tests in the table below. */
22865 static const DWORD ps3_diffuse_code[] =
22867 0xffff0300, /* ps_3_0 */
22868 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
22869 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
22870 0x0000ffff
22872 #endif
22873 static const DWORD ps3_specular_code[] =
22875 0xffff0300, /* ps_3_0 */
22876 0x0200001f, 0x8001000a, 0x900f0001, /* dcl_color1 v1 */
22877 0x02000001, 0x800f0800, 0x90e40001, /* mov oC0, v1 */
22878 0x0000ffff
22880 static const DWORD ps3_texcoord_code[] =
22882 0xffff0300, /* ps_3_0 */
22883 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
22884 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
22885 0x0000ffff
22887 static const struct
22889 DWORD vs_version;
22890 const DWORD *vs;
22891 DWORD ps_version;
22892 const DWORD *ps;
22893 D3DCOLOR expected;
22894 BOOL allow_zero_alpha;
22895 BOOL partial;
22896 BOOL broken_warp;
22898 /* On AMD specular color is generally initialized to 0x00000000 and texcoords to 0xff000000
22899 * while on Nvidia it's the opposite. Just allow both.
22901 * Partially initialized varyings reliably handle the component that has been initialized.
22902 * The uninitialized components generally follow the rule above, with some exceptions on
22903 * radeon cards. r500 and r600 GPUs have been found to set uninitialized components to 0.0,
22904 * 0.5 and 1.0 without a sensible pattern. */
22905 tests[] =
22907 {D3DVS_VERSION(1, 1), vs1_code, 0, NULL, 0xffffffff},
22908 { 0, NULL, D3DPS_VERSION(1, 1), ps1_texcoord_code, 0xff000000, TRUE},
22909 { 0, NULL, D3DPS_VERSION(2, 0), ps2_texcoord_code, 0xff000000, TRUE},
22910 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_diffuse_code, 0xffffffff},
22911 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_specular_code, 0xff000000, TRUE, FALSE, TRUE},
22912 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_texcoord_code, 0xff000000, TRUE},
22913 {D3DVS_VERSION(2, 0), vs2_code, D3DPS_VERSION(2, 0), ps2_diffuse_code, 0xffffffff},
22914 {D3DVS_VERSION(2, 0), vs2_code, D3DPS_VERSION(2, 0), ps2_specular_code, 0xff000000, TRUE, FALSE, TRUE},
22915 {D3DVS_VERSION(2, 0), vs2_code, D3DPS_VERSION(2, 0), ps2_texcoord_code, 0xff000000, TRUE},
22916 /* This test shows a lot of combinations of alpha and color that involve 1.0 and 0.0. Disable it.
22918 * AMD r500 sets alpha = 1.0, color = 0.0. Nvidia sets alpha = 1.0, color = 1.0. r600 Sets Alpha = 0.0,
22919 * color = 0.0. So far no combination with Alpha = 0.0, color = 1.0 has been found though.
22920 * {D3DVS_VERSION(3, 0), vs3_code, D3DPS_VERSION(3, 0), ps3_diffuse_code, 0xffffffff, FALSE, FALSE},
22922 * The same issues apply to the partially initialized COLOR0 varying, in addition to unreliable results
22923 * with partially initialized varyings in general.
22924 * {D3DVS_VERSION(3, 0), vs3_partial_code, D3DPS_VERSION(3, 0), ps3_diffuse_code, 0xff7fffff, TRUE, TRUE}, */
22925 {D3DVS_VERSION(3, 0), vs3_code, D3DPS_VERSION(3, 0), ps3_specular_code, 0xff000000, TRUE, FALSE, TRUE},
22926 {D3DVS_VERSION(3, 0), vs3_code, D3DPS_VERSION(3, 0), ps3_texcoord_code, 0xff000000, TRUE, FALSE, TRUE},
22927 {D3DVS_VERSION(1, 1), vs1_partial_code, 0, NULL, 0xff7fffff, FALSE, TRUE},
22928 {D3DVS_VERSION(1, 1), vs1_partial_code, D3DPS_VERSION(1, 1), ps1_diffuse_code, 0xff7fffff, FALSE, TRUE},
22929 {D3DVS_VERSION(1, 1), vs1_partial_code, D3DPS_VERSION(1, 1), ps1_specular_code, 0xff7f0000, TRUE, TRUE},
22930 {D3DVS_VERSION(1, 1), vs1_partial_code, D3DPS_VERSION(1, 1), ps1_texcoord_code, 0xff7f0000, TRUE, TRUE},
22931 {D3DVS_VERSION(2, 0), vs2_partial_code, D3DPS_VERSION(2, 0), ps2_diffuse_code, 0xff7fffff, FALSE, TRUE},
22932 {D3DVS_VERSION(2, 0), vs2_partial_code, D3DPS_VERSION(2, 0), ps2_specular_code, 0xff7f0000, TRUE, TRUE},
22933 {D3DVS_VERSION(2, 0), vs2_partial_code, D3DPS_VERSION(2, 0), ps2_texcoord_code, 0xff7f0000, TRUE, TRUE},
22934 {D3DVS_VERSION(3, 0), vs3_partial_code, D3DPS_VERSION(3, 0), ps3_specular_code, 0x007f0000, FALSE, TRUE},
22935 {D3DVS_VERSION(3, 0), vs3_partial_code, D3DPS_VERSION(3, 0), ps3_texcoord_code, 0xff7f0000, TRUE, TRUE},
22937 IDirect3DDevice9 *device;
22938 IDirect3D9 *d3d;
22939 HWND window;
22940 HRESULT hr;
22941 D3DADAPTER_IDENTIFIER9 identifier;
22942 IDirect3DSurface9 *backbuffer;
22943 struct surface_readback rb;
22944 IDirect3DVertexShader9 *vs;
22945 IDirect3DPixelShader9 *ps;
22946 unsigned int color, i;
22947 ULONG refcount;
22948 D3DCAPS9 caps;
22949 BOOL warp;
22951 window = create_window();
22952 d3d = Direct3DCreate9(D3D_SDK_VERSION);
22953 ok(!!d3d, "Failed to create a D3D object.\n");
22954 if (!(device = create_device(d3d, window, window, TRUE)))
22956 skip("Failed to create a D3D device, skipping tests.\n");
22957 IDirect3D9_Release(d3d);
22958 DestroyWindow(window);
22959 return;
22962 hr = IDirect3D9_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
22963 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#lx.\n", hr);
22964 warp = adapter_is_warp(&identifier);
22966 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
22967 ok(SUCCEEDED(hr), "Failed to get caps, hr %#lx.\n", hr);
22969 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
22970 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#lx.\n", hr);
22972 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &mat);
22973 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#lx.\n", hr);
22974 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &mat);
22975 ok(SUCCEEDED(hr), "Failed to set view transform, hr %#lx.\n", hr);
22976 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &mat);
22977 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#lx.\n", hr);
22978 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
22979 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#lx.\n", hr);
22980 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
22981 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#lx.\n", hr);
22982 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
22983 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#lx.\n", hr);
22984 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
22985 ok(SUCCEEDED(hr), "Failed to disable stencil test, hr %#lx.\n", hr);
22986 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
22987 ok(SUCCEEDED(hr), "Failed to disable culling, hr %#lx.\n", hr);
22989 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
22990 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
22992 for (i = 0; i < ARRAY_SIZE(tests); ++i)
22994 if (caps.VertexShaderVersion < tests[i].vs_version
22995 || caps.PixelShaderVersion < tests[i].ps_version)
22997 skip("Vertex / pixel shader version not supported, skipping test %u.\n", i);
22998 continue;
23000 if (tests[i].vs)
23002 hr = IDirect3DDevice9_CreateVertexShader(device, tests[i].vs, &vs);
23003 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#lx (case %u).\n", hr, i);
23005 else
23007 vs = NULL;
23009 if (tests[i].ps)
23011 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].ps, &ps);
23012 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#lx (case %u).\n", hr, i);
23014 else
23016 ps = NULL;
23019 hr = IDirect3DDevice9_SetVertexShader(device, vs);
23020 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
23021 hr = IDirect3DDevice9_SetPixelShader(device, ps);
23022 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
23024 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
23025 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
23027 hr = IDirect3DDevice9_BeginScene(device);
23028 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
23030 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
23031 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
23033 hr = IDirect3DDevice9_EndScene(device);
23034 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
23036 get_rt_readback(backbuffer, &rb);
23037 color = get_readback_color(&rb, 320, 240);
23038 ok(color_match(color, tests[i].expected, 1)
23039 || (tests[i].allow_zero_alpha && color_match(color, tests[i].expected & 0x00ffffff, 1))
23040 || (broken(warp && tests[i].broken_warp))
23041 || broken(tests[i].partial && color_match(color & 0x00ff0000, tests[i].expected & 0x00ff0000, 1)),
23042 "Got unexpected color 0x%08x, case %u.\n", color, i);
23043 release_surface_readback(&rb);
23045 if (vs)
23046 IDirect3DVertexShader9_Release(vs);
23047 if (ps)
23048 IDirect3DVertexShader9_Release(ps);
23051 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
23052 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
23054 IDirect3DSurface9_Release(backbuffer);
23055 refcount = IDirect3DDevice9_Release(device);
23056 ok(!refcount, "Device has %lu references left.\n", refcount);
23057 IDirect3D9_Release(d3d);
23058 DestroyWindow(window);
23061 static void test_multisample_init(void)
23063 IDirect3DDevice9 *device;
23064 unsigned int color, x, y;
23065 IDirect3D9 *d3d;
23066 IDirect3DSurface9 *back, *multi;
23067 ULONG refcount;
23068 HWND window;
23069 HRESULT hr;
23070 struct surface_readback rb;
23071 BOOL all_zero = TRUE;
23073 window = create_window();
23074 d3d = Direct3DCreate9(D3D_SDK_VERSION);
23075 ok(!!d3d, "Failed to create a D3D object.\n");
23077 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
23078 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
23080 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisample init test.\n");
23081 goto done;
23084 if (!(device = create_device(d3d, window, window, TRUE)))
23086 skip("Failed to create a D3D device, skipping tests.\n");
23087 goto done;
23090 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &back);
23091 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#lx.\n", hr);
23092 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
23093 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &multi, NULL);
23094 ok(SUCCEEDED(hr), "Failed to create multisampled render target, hr %#lx.\n", hr);
23096 hr = IDirect3DDevice9_StretchRect(device, multi, NULL, back, NULL, D3DTEXF_POINT);
23097 ok(SUCCEEDED(hr), "StretchRect failed, hr %#lx.\n", hr);
23099 get_rt_readback(back, &rb);
23100 for (y = 0; y < 480; ++y)
23102 for (x = 0; x < 640; x++)
23104 color = get_readback_color(&rb, x, y);
23105 if (!color_match(color, 0x00000000, 0))
23107 all_zero = FALSE;
23108 break;
23111 if (!all_zero)
23112 break;
23114 release_surface_readback(&rb);
23115 ok(all_zero, "Got unexpected color 0x%08x, position %ux%u.\n", color, x, y);
23117 IDirect3DSurface9_Release(multi);
23118 IDirect3DSurface9_Release(back);
23120 refcount = IDirect3DDevice9_Release(device);
23121 ok(!refcount, "Device has %lu references left.\n", refcount);
23123 done:
23124 IDirect3D9_Release(d3d);
23125 DestroyWindow(window);
23128 static void test_depth_stencil_init(void)
23130 IDirect3DDevice9 *device;
23131 IDirect3DSurface9 *ds[2];
23132 IDirect3DSurface9 *rt;
23133 IDirect3D9 *d3d;
23134 ULONG refcount;
23135 unsigned int i;
23136 HWND window;
23137 HRESULT hr;
23139 static const struct
23141 struct vec3 position;
23143 quad[] =
23145 {{-1.0f, -1.0f, 0.0f}},
23146 {{-1.0f, 1.0f, 0.0f}},
23147 {{ 1.0f, -1.0f, 0.0f}},
23148 {{ 1.0f, 1.0f, 0.0f}},
23151 window = create_window();
23152 d3d = Direct3DCreate9(D3D_SDK_VERSION);
23153 ok(!!d3d, "Failed to create D3D object.\n");
23154 if (!(device = create_device(d3d, window, window, TRUE)))
23156 skip("Failed to create D3D device.\n");
23157 goto done;
23160 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
23161 ok(hr == S_OK, "Failed to set render state, hr %#lx.\n", hr);
23162 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
23163 ok(hr == S_OK, "Failed to set render state, hr %#lx.\n", hr);
23164 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
23165 ok(hr == S_OK, "Failed to set render state, hr %#lx.\n", hr);
23166 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
23167 ok(hr == S_OK, "Failed to set color op, hr %#lx.\n", hr);
23168 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
23169 ok(hr == S_OK, "Failed to set color arg, hr %#lx.\n", hr);
23170 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
23171 ok(hr == S_OK, "Failed to set FVF, hr %#lx.\n", hr);
23173 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8, 0, 0, FALSE, &ds[0], NULL);
23174 ok(hr == S_OK, "Failed to create depth stencil surface, hr %#lx.\n", hr);
23175 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds[1]);
23176 ok(hr == S_OK, "Failed to get depth stencil surface, hr %#lx.\n", hr);
23178 for (i = 0; i < ARRAY_SIZE(ds); ++i)
23180 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds[i]);
23181 ok(hr == S_OK, "Failed to set depth stencil surface, hr %#lx.\n", hr);
23183 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
23184 ok(hr == S_OK, "Failed to clear, hr %#lx.\n", hr);
23186 hr = IDirect3DDevice9_BeginScene(device);
23187 ok(hr == S_OK, "Failed to begin scene, hr %#lx.\n", hr);
23188 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x000000ff);
23189 ok(hr == S_OK, "Failed to set render state, hr %#lx.\n", hr);
23190 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
23191 ok(hr == S_OK, "Failed to draw, hr %#lx.\n", hr);
23192 hr = IDirect3DDevice9_EndScene(device);
23193 ok(hr == S_OK, "Failed to end scene, hr %#lx.\n", hr);
23195 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &rt);
23196 ok(hr == S_OK, "Failed to get render target, hr %#lx.\n", hr);
23197 check_rt_color(rt, 0x000000ff);
23198 IDirect3DSurface9_Release(rt);
23200 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
23201 ok(hr == D3D_OK, "Failed to present, hr %#lx.\n", hr);
23203 IDirect3DSurface9_Release(ds[i]);
23206 refcount = IDirect3DDevice9_Release(device);
23207 ok(!refcount, "Device has %lu references left.\n", refcount);
23209 done:
23210 IDirect3D9_Release(d3d);
23211 DestroyWindow(window);
23214 static void test_texture_blending(void)
23216 #define STATE_END() {0xffffffff, 0xffffffff}
23217 #define IS_STATE_END(s) (s.name == 0xffffffff && s.value == 0xffffffff)
23219 IDirect3DTexture9 *texture_bumpmap, *texture_red;
23220 IDirect3DSurface9 *backbuffer;
23221 unsigned int color, i, j, k;
23222 struct surface_readback rb;
23223 D3DLOCKED_RECT locked_rect;
23224 IDirect3DDevice9 *device;
23225 IDirect3D9 *d3d;
23226 ULONG refcount;
23227 D3DCAPS9 caps;
23228 HWND window;
23229 HRESULT hr;
23231 static const struct
23233 struct vec3 position;
23234 DWORD diffuse;
23236 quad[] =
23238 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
23239 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
23240 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
23241 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
23244 static const float bumpenvmat[4] = {1.0f, 1.0f, 0.0f, 0.0f};
23246 struct texture_stage_state
23248 D3DTEXTURESTAGESTATETYPE name;
23249 DWORD value;
23252 struct texture_stage
23254 enum
23256 TEXTURE_INVALID,
23257 TEXTURE_NONE,
23258 TEXTURE_BUMPMAP,
23259 TEXTURE_RED,
23261 texture;
23262 struct texture_stage_state state[20];
23265 static const struct texture_stage default_stage_state =
23267 TEXTURE_NONE,
23269 {D3DTSS_COLOROP, D3DTOP_DISABLE},
23270 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
23271 {D3DTSS_COLORARG2, D3DTA_CURRENT},
23272 {D3DTSS_ALPHAOP, D3DTOP_DISABLE},
23273 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
23274 {D3DTSS_ALPHAARG2, D3DTA_CURRENT},
23275 {D3DTSS_BUMPENVMAT00, 0},
23276 {D3DTSS_BUMPENVMAT01, 0},
23277 {D3DTSS_BUMPENVMAT10, 0},
23278 {D3DTSS_BUMPENVMAT11, 0},
23279 {D3DTSS_BUMPENVLSCALE, 0},
23280 {D3DTSS_BUMPENVLOFFSET, 0},
23281 {D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE},
23282 {D3DTSS_COLORARG0, D3DTA_CURRENT},
23283 {D3DTSS_ALPHAARG0, D3DTA_CURRENT},
23284 {D3DTSS_RESULTARG, D3DTA_CURRENT},
23285 {D3DTSS_CONSTANT, 0},
23286 STATE_END(),
23290 const struct test
23292 DWORD tex_op_caps;
23293 unsigned int expected_color;
23294 struct texture_stage stage[8];
23296 tests[] =
23299 D3DTEXOPCAPS_DISABLE,
23300 0x80ffff02,
23303 TEXTURE_NONE,
23305 STATE_END(),
23311 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
23312 0x80ffff02,
23315 TEXTURE_NONE,
23317 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
23318 {D3DTSS_COLORARG1, D3DTA_CURRENT},
23319 STATE_END(),
23322 {TEXTURE_INVALID}
23326 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
23327 0x80ffff02,
23330 TEXTURE_NONE,
23332 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
23333 {D3DTSS_COLORARG1, D3DTA_CURRENT},
23334 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
23335 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
23336 STATE_END(),
23342 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
23343 0x80ffff02,
23346 TEXTURE_NONE,
23348 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
23349 {D3DTSS_COLORARG1, D3DTA_DIFFUSE},
23350 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
23351 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
23352 STATE_END(),
23358 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
23359 0x00000000,
23362 TEXTURE_NONE,
23364 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
23365 {D3DTSS_COLORARG1, D3DTA_TEMP},
23366 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
23367 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
23368 STATE_END(),
23374 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_SUBTRACT,
23375 0x80f0f000,
23378 TEXTURE_NONE,
23380 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
23381 {D3DTSS_COLORARG1, D3DTA_CURRENT},
23382 STATE_END(),
23386 TEXTURE_NONE,
23388 {D3DTSS_COLOROP, D3DTOP_SUBTRACT},
23389 {D3DTSS_COLORARG1, D3DTA_CURRENT},
23390 {D3DTSS_COLORARG2, D3DTA_CONSTANT},
23391 {D3DTSS_CONSTANT, 0x0f0f0f0f},
23392 STATE_END(),
23395 {TEXTURE_INVALID}
23399 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_SUBTRACT,
23400 0x71f0f000,
23403 TEXTURE_NONE,
23405 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
23406 {D3DTSS_COLORARG1, D3DTA_CURRENT},
23407 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
23408 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
23409 STATE_END(),
23413 TEXTURE_NONE,
23415 {D3DTSS_COLOROP, D3DTOP_SUBTRACT},
23416 {D3DTSS_COLORARG1, D3DTA_CURRENT},
23417 {D3DTSS_COLORARG2, D3DTA_CONSTANT},
23418 {D3DTSS_ALPHAOP, D3DTOP_SUBTRACT},
23419 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
23420 {D3DTSS_ALPHAARG2, D3DTA_CONSTANT},
23421 {D3DTSS_CONSTANT, 0x0f0f0f0f},
23422 STATE_END(),
23425 {TEXTURE_INVALID}
23430 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
23431 0x80ff0000,
23434 TEXTURE_BUMPMAP,
23436 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
23437 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
23438 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
23439 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
23440 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
23441 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
23442 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
23443 STATE_END(),
23448 TEXTURE_RED,
23450 {D3DTSS_COLOROP, D3DTOP_MODULATE},
23451 STATE_END(),
23454 {TEXTURE_INVALID}
23458 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
23459 0x80ff0000,
23462 TEXTURE_BUMPMAP,
23464 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
23465 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
23466 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
23467 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
23468 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
23469 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
23470 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
23471 STATE_END(),
23475 TEXTURE_RED,
23477 {D3DTSS_COLOROP, D3DTOP_MODULATE},
23478 STATE_END(),
23481 {TEXTURE_INVALID}
23485 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
23486 0x80ff0000,
23489 TEXTURE_BUMPMAP,
23491 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
23492 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
23493 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
23494 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
23495 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
23496 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
23497 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
23498 STATE_END(),
23502 TEXTURE_RED,
23504 {D3DTSS_COLOROP, D3DTOP_MODULATE},
23505 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
23506 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
23507 STATE_END(),
23510 {TEXTURE_INVALID}
23514 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
23515 0x00ff0000,
23518 TEXTURE_BUMPMAP,
23520 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
23521 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
23522 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
23523 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
23524 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
23525 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
23526 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
23527 STATE_END(),
23531 TEXTURE_RED,
23533 {D3DTSS_COLOROP, D3DTOP_MODULATE},
23534 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
23535 {D3DTSS_COLORARG2, D3DTA_CURRENT},
23536 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
23537 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
23538 STATE_END(),
23541 {TEXTURE_INVALID}
23545 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
23546 0x80ff0000,
23549 TEXTURE_BUMPMAP,
23551 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
23552 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
23553 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
23554 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
23555 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
23556 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
23557 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
23558 STATE_END(),
23562 TEXTURE_RED,
23564 {D3DTSS_COLOROP, D3DTOP_MODULATE},
23565 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
23566 {D3DTSS_COLORARG2, D3DTA_CURRENT},
23567 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
23568 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
23569 STATE_END(),
23572 {TEXTURE_INVALID}
23577 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE
23578 | D3DTEXOPCAPS_ADD,
23579 0x80ff0000,
23582 TEXTURE_BUMPMAP,
23584 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
23585 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
23586 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
23587 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
23588 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
23589 {D3DTSS_ALPHAOP, D3DTOP_ADD},
23590 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
23591 {D3DTSS_ALPHAARG2, D3DTA_CONSTANT},
23592 {D3DTSS_CONSTANT, 0x0fffffff},
23593 STATE_END(),
23597 TEXTURE_RED,
23599 {D3DTSS_COLOROP, D3DTOP_MODULATE},
23600 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
23601 {D3DTSS_COLORARG2, D3DTA_CURRENT},
23602 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
23603 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
23604 STATE_END(),
23607 {TEXTURE_INVALID}
23611 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE
23612 | D3DTEXOPCAPS_MODULATE2X,
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_MODULATE2X},
23624 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
23625 {D3DTSS_ALPHAARG2, D3DTA_CONSTANT},
23626 {D3DTSS_CONSTANT, 0x01ffffff},
23627 STATE_END(),
23631 TEXTURE_RED,
23633 {D3DTSS_COLOROP, D3DTOP_MODULATE},
23634 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
23635 {D3DTSS_COLORARG2, D3DTA_CURRENT},
23636 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
23637 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
23638 STATE_END(),
23641 {TEXTURE_INVALID}
23645 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE
23646 | D3DTEXOPCAPS_MODULATE2X,
23647 0x80ffff00,
23650 TEXTURE_BUMPMAP,
23652 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
23653 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
23654 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
23655 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
23656 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
23657 {D3DTSS_ALPHAOP, D3DTOP_MODULATE2X},
23658 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
23659 {D3DTSS_ALPHAARG2, D3DTA_CONSTANT},
23660 {D3DTSS_CONSTANT, 0x01ffffff},
23661 STATE_END(),
23665 TEXTURE_RED,
23667 {D3DTSS_COLOROP, D3DTOP_MODULATE},
23668 {D3DTSS_COLORARG1, D3DTA_CURRENT},
23669 {D3DTSS_COLORARG2, D3DTA_CURRENT},
23670 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
23671 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
23672 {D3DTSS_ALPHAARG2, D3DTA_CONSTANT},
23673 {D3DTSS_ALPHAARG0, D3DTA_CONSTANT},
23674 STATE_END(),
23677 {TEXTURE_INVALID}
23681 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP,
23682 0x01234567,
23685 TEXTURE_NONE,
23687 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
23688 {D3DTSS_COLORARG1, D3DTA_CONSTANT},
23689 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
23690 {D3DTSS_ALPHAARG1, D3DTA_CONSTANT},
23691 {D3DTSS_RESULTARG, D3DTA_TEMP},
23692 {D3DTSS_CONSTANT, 0x01234567},
23693 STATE_END(),
23697 TEXTURE_BUMPMAP,
23699 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
23700 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
23701 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
23702 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
23703 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
23704 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
23705 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
23706 {D3DTSS_RESULTARG, D3DTA_TEMP},
23707 STATE_END(),
23711 TEXTURE_RED,
23713 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
23714 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
23715 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
23716 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
23717 STATE_END(),
23721 TEXTURE_NONE,
23723 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
23724 {D3DTSS_COLORARG1, D3DTA_TEMP},
23725 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
23726 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
23727 STATE_END(),
23730 {TEXTURE_INVALID}
23734 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP,
23735 0x00234567,
23738 TEXTURE_NONE,
23740 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
23741 {D3DTSS_COLORARG1, D3DTA_CONSTANT},
23742 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
23743 {D3DTSS_ALPHAARG1, D3DTA_CONSTANT},
23744 {D3DTSS_RESULTARG, D3DTA_TEMP},
23745 {D3DTSS_CONSTANT, 0x01234567},
23746 STATE_END(),
23750 TEXTURE_BUMPMAP,
23752 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
23753 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
23754 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
23755 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
23756 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
23757 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
23758 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
23759 STATE_END(),
23763 TEXTURE_RED,
23765 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
23766 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
23767 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
23768 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
23769 STATE_END(),
23773 TEXTURE_NONE,
23775 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
23776 {D3DTSS_COLORARG1, D3DTA_TEMP},
23777 STATE_END(),
23780 {TEXTURE_INVALID}
23784 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP,
23785 0x01234567,
23788 TEXTURE_NONE,
23790 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
23791 {D3DTSS_COLORARG1, D3DTA_CONSTANT},
23792 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
23793 {D3DTSS_ALPHAARG1, D3DTA_CONSTANT},
23794 {D3DTSS_RESULTARG, D3DTA_TEMP},
23795 {D3DTSS_CONSTANT, 0x01234567},
23796 STATE_END(),
23800 TEXTURE_BUMPMAP,
23802 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
23803 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
23804 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
23805 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
23806 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
23807 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
23808 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
23809 {D3DTSS_RESULTARG, D3DTA_TEMP},
23810 STATE_END(),
23814 TEXTURE_RED,
23816 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
23817 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
23818 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
23819 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
23820 STATE_END(),
23824 TEXTURE_NONE,
23826 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
23827 {D3DTSS_COLORARG1, D3DTA_TEMP},
23828 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
23829 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
23830 STATE_END(),
23833 {TEXTURE_INVALID}
23837 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP,
23838 0x01234567,
23841 TEXTURE_NONE,
23843 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
23844 {D3DTSS_COLORARG1, D3DTA_CONSTANT},
23845 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
23846 {D3DTSS_ALPHAARG1, D3DTA_CONSTANT},
23847 {D3DTSS_RESULTARG, D3DTA_CURRENT},
23848 {D3DTSS_CONSTANT, 0x01234567},
23849 STATE_END(),
23853 TEXTURE_BUMPMAP,
23855 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
23856 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
23857 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
23858 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
23859 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
23860 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
23861 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
23862 {D3DTSS_RESULTARG, D3DTA_TEMP},
23863 STATE_END(),
23867 TEXTURE_RED,
23869 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
23870 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
23871 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
23872 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
23873 {D3DTSS_RESULTARG, D3DTA_TEMP},
23874 STATE_END(),
23878 TEXTURE_NONE,
23880 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
23881 {D3DTSS_COLORARG1, D3DTA_CURRENT},
23882 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
23883 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
23884 {D3DTSS_RESULTARG, D3DTA_CURRENT},
23885 STATE_END(),
23888 {TEXTURE_INVALID}
23893 window = create_window();
23894 d3d = Direct3DCreate9(D3D_SDK_VERSION);
23895 ok(!!d3d, "Failed to create a D3D object.\n");
23896 if (!(device = create_device(d3d, window, window, TRUE)))
23898 skip("Failed to create a D3D device.\n");
23899 goto done;
23902 memset(&caps, 0, sizeof(caps));
23903 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
23904 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr %#lx.\n", hr);
23906 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP))
23908 skip("D3DPMISCCAPS_TSSARGTEMP not supported.\n");
23909 IDirect3DDevice9_Release(device);
23910 goto done;
23913 if (!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_PERSTAGECONSTANT))
23915 skip("D3DPMISCCAPS_PERSTAGECONSTANT not supported.\n");
23916 IDirect3DDevice9_Release(device);
23917 goto done;
23920 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
23921 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_V8U8)))
23923 skip("D3DFMT_V8U8 not supported for legacy bump mapping.\n");
23924 IDirect3DDevice9_Release(device);
23925 goto done;
23928 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
23929 ok(hr == D3D_OK, "Can't get back buffer, hr %#lx.\n", hr);
23931 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture_bumpmap, NULL);
23932 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr %#lx.\n", hr);
23933 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture_red, NULL);
23934 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr %#lx.\n", hr);
23936 memset(&locked_rect, 0, sizeof(locked_rect));
23937 hr = IDirect3DTexture9_LockRect(texture_bumpmap, 0, &locked_rect, NULL, 0);
23938 ok(SUCCEEDED(hr), "LockRect failed, hr %#lx.\n", hr);
23939 *((WORD *)locked_rect.pBits) = 0xff00;
23940 hr = IDirect3DTexture9_UnlockRect(texture_bumpmap, 0);
23941 ok(SUCCEEDED(hr), "UnlockRect failed, hr %#lx.\n", hr);
23943 memset(&locked_rect, 0, sizeof(locked_rect));
23944 hr = IDirect3DTexture9_LockRect(texture_red, 0, &locked_rect, NULL, 0);
23945 ok(SUCCEEDED(hr), "LockRect failed, hr %#lx.\n", hr);
23946 *((DWORD *)locked_rect.pBits) = 0x00ff0000;
23947 hr = IDirect3DTexture9_UnlockRect(texture_red, 0);
23948 ok(SUCCEEDED(hr), "UnlockRect failed, hr %#lx.\n", hr);
23950 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
23951 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
23952 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
23953 ok(hr == D3D_OK, "Failed to disable lighting, hr %#lx.\n", hr);
23955 for (i = 0; i < ARRAY_SIZE(tests); ++i)
23957 const struct test *current_test = &tests[i];
23959 if ((caps.TextureOpCaps & current_test->tex_op_caps) != current_test->tex_op_caps)
23961 skip("Texture operations %#lx not supported.\n", current_test->tex_op_caps);
23962 continue;
23965 for (j = 0; j < caps.MaxTextureBlendStages; ++j)
23967 IDirect3DTexture9 *current_texture = NULL;
23969 for (k = 0; !IS_STATE_END(default_stage_state.state[k]); ++k)
23971 hr = IDirect3DDevice9_SetTextureStageState(device, j,
23972 default_stage_state.state[k].name, default_stage_state.state[k].value);
23973 ok(SUCCEEDED(hr), "Test %u: SetTextureStageState failed, hr %#lx.\n", i, hr);
23976 if (current_test->stage[j].texture != TEXTURE_INVALID)
23978 const struct texture_stage_state *current_state = current_test->stage[j].state;
23980 switch (current_test->stage[j].texture)
23982 case TEXTURE_RED:
23983 current_texture = texture_red;
23984 break;
23985 case TEXTURE_BUMPMAP:
23986 current_texture = texture_bumpmap;
23987 break;
23988 default:
23989 current_texture = NULL;
23990 break;
23993 for (k = 0; !IS_STATE_END(current_state[k]); ++k)
23995 hr = IDirect3DDevice9_SetTextureStageState(device, j,
23996 current_state[k].name, current_state[k].value);
23997 ok(SUCCEEDED(hr), "Test %u: SetTextureStageState failed, hr %#lx.\n", i, hr);
24001 hr = IDirect3DDevice9_SetTexture(device, j, (IDirect3DBaseTexture9 *)current_texture);
24002 ok(SUCCEEDED(hr), "Test %u: SetTexture failed, hr %#lx.\n", i, hr);
24005 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
24006 ok(hr == D3D_OK, "Test %u: IDirect3DDevice9_Clear failed, hr %#lx.\n", i, hr);
24008 hr = IDirect3DDevice9_BeginScene(device);
24009 ok(SUCCEEDED(hr), "Test %u: BeginScene failed, hr %#lx.\n", i, hr);
24010 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
24011 ok(SUCCEEDED(hr), "Test %u: DrawPrimitiveUP failed, hr %#lx.\n", i, hr);
24012 hr = IDirect3DDevice9_EndScene(device);
24013 ok(SUCCEEDED(hr), "Test %u: EndScene failed, hr %#lx.\n", i, hr);
24015 get_rt_readback(backbuffer, &rb);
24016 color = get_readback_color(&rb, 320, 240);
24017 ok(color_match(color, current_test->expected_color, 1),
24018 "Test %u: Got color 0x%08x, expected 0x%08x.\n", i, color, current_test->expected_color);
24019 release_surface_readback(&rb);
24020 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
24021 ok(SUCCEEDED(hr), "Test %u: Present failed, hr %#lx.\n", i, hr);
24024 IDirect3DTexture9_Release(texture_bumpmap);
24025 IDirect3DTexture9_Release(texture_red);
24026 IDirect3DSurface9_Release(backbuffer);
24027 refcount = IDirect3DDevice9_Release(device);
24028 ok(!refcount, "Device has %lu references left.\n", refcount);
24029 done:
24030 IDirect3D9_Release(d3d);
24031 DestroyWindow(window);
24034 static void test_color_clamping(void)
24036 static const D3DMATRIX mat =
24038 1.0f, 0.0f, 0.0f, 0.0f,
24039 0.0f, 1.0f, 0.0f, 0.0f,
24040 0.0f, 0.0f, 1.0f, 0.0f,
24041 0.0f, 0.0f, 0.0f, 1.0f,
24042 }}};
24043 static const struct vec3 quad[] =
24045 {-1.0f, -1.0f, 0.1f},
24046 {-1.0f, 1.0f, 0.1f},
24047 { 1.0f, -1.0f, 0.1f},
24048 { 1.0f, 1.0f, 0.1f},
24050 static const DWORD vs1_code[] =
24052 0xfffe0101, /* vs_1_1 */
24053 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
24054 0x00000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0 */
24055 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
24056 0x00000002, 0xd00f0000, 0xa0e40000, 0xa0e40000, /* add oD0, c0, c0 */
24057 0x00000002, 0xd00f0001, 0xa0e40000, 0xa0e40000, /* add oD1, c0, c0 */
24058 0x0000ffff
24060 static const DWORD vs2_code[] =
24062 0xfffe0200, /* vs_2_0 */
24063 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
24064 0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0 */
24065 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
24066 0x03000002, 0xd00f0000, 0xa0e40000, 0xa0e40000, /* add oD0, c0, c0 */
24067 0x03000002, 0xd00f0001, 0xa0e40000, 0xa0e40000, /* add oD1, c0, c0 */
24068 0x0000ffff
24070 static const DWORD vs3_code[] =
24072 0xfffe0300, /* vs_3_0 */
24073 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
24074 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
24075 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */
24076 0x0200001f, 0x8001000a, 0xe00f0002, /* dcl_color1 o2 */
24077 0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0 */
24078 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
24079 0x03000002, 0xe00f0001, 0xa0e40000, 0xa0e40000, /* add o1, c0, c0 */
24080 0x03000002, 0xe00f0002, 0xa0e40000, 0xa0e40000, /* add o2, c0, c0 */
24081 0x0000ffff
24083 static const DWORD ps1_code[] =
24085 0xffff0101, /* ps_1_1 */
24086 0x00000051, 0xa00f0000, 0x3e800000, 0x3e800000, 0x3e800000, 0x3e800000, /* def c0, 0.25, 0.25, 0.25, 0.25 */
24087 0x00000002, 0x800f0000, 0x90e40000, 0x90e40001, /* add r0, v0, v1 */
24088 0x00000005, 0x800f0000, 0x80e40000, 0xa0e40000, /* mul r0, r0, c0 */
24089 0x0000ffff
24091 static const DWORD ps2_code[] =
24093 0xffff0200, /* ps_2_0 */
24094 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
24095 0x0200001f, 0x80000000, 0x900f0001, /* dcl v1 */
24096 0x05000051, 0xa00f0000, 0x3e800000, 0x3e800000, 0x3e800000, 0x3e800000, /* def c0, 0.25, 0.25, 0.25, 0.25 */
24097 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
24098 0x03000002, 0x800f0000, 0x80e40000, 0x90e40001, /* add r0, r0, v1 */
24099 0x03000005, 0x800f0000, 0x80e40000, 0xa0e40000, /* mul r0, r0, c0 */
24100 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
24101 0x0000ffff
24103 static const DWORD ps3_code[] =
24105 0xffff0300, /* ps_3_0 */
24106 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
24107 0x0200001f, 0x8001000a, 0x900f0001, /* dcl_color1 v1 */
24108 0x05000051, 0xa00f0000, 0x3e800000, 0x3e800000, 0x3e800000, 0x3e800000, /* def c0, 0.25, 0.25, 0.25, 0.25 */
24109 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
24110 0x03000002, 0x800f0000, 0x80e40000, 0x90e40001, /* add r0, r0, v1 */
24111 0x03000005, 0x800f0800, 0x80e40000, 0xa0e40000, /* mul oC0, r0, c0 */
24112 0x0000ffff
24114 static const struct
24116 DWORD vs_version;
24117 const DWORD *vs;
24118 DWORD ps_version;
24119 const DWORD *ps;
24120 D3DCOLOR expected, broken;
24122 tests[] =
24124 {0, NULL, 0, NULL, 0x00404040},
24125 {0, NULL, D3DPS_VERSION(1, 1), ps1_code, 0x00404040, 0x00808080},
24126 {D3DVS_VERSION(1, 1), vs1_code, 0, NULL, 0x00404040},
24127 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_code, 0x007f7f7f},
24128 {D3DVS_VERSION(2, 0), vs2_code, D3DPS_VERSION(2, 0), ps2_code, 0x007f7f7f},
24129 {D3DVS_VERSION(3, 0), vs3_code, D3DPS_VERSION(3, 0), ps3_code, 0x00ffffff},
24131 IDirect3DVertexShader9 *vs;
24132 IDirect3DPixelShader9 *ps;
24133 IDirect3DDevice9 *device;
24134 unsigned int color, i;
24135 IDirect3D9 *d3d9;
24136 ULONG refcount;
24137 D3DCAPS9 caps;
24138 HWND window;
24139 HRESULT hr;
24141 window = create_window();
24142 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
24143 ok(!!d3d9, "Failed to create a D3D object.\n");
24144 if (!(device = create_device(d3d9, window, window, TRUE)))
24146 skip("Failed to create a D3D device, skipping tests.\n");
24147 IDirect3D9_Release(d3d9);
24148 DestroyWindow(window);
24149 return;
24152 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
24153 ok(SUCCEEDED(hr), "Failed to get caps, hr %#lx.\n", hr);
24155 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &mat);
24156 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#lx.\n", hr);
24157 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &mat);
24158 ok(SUCCEEDED(hr), "Failed to set view transform, hr %#lx.\n", hr);
24159 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &mat);
24160 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#lx.\n", hr);
24161 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
24162 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#lx.\n", hr);
24163 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
24164 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#lx.\n", hr);
24165 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
24166 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#lx.\n", hr);
24167 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
24168 ok(SUCCEEDED(hr), "Failed to disable stencil test, hr %#lx.\n", hr);
24169 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
24170 ok(SUCCEEDED(hr), "Failed to disable culling, hr %#lx.\n", hr);
24171 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
24172 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
24174 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xff404040);
24175 ok(SUCCEEDED(hr), "Failed to set texture factor, hr %#lx.\n", hr);
24176 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
24177 ok(SUCCEEDED(hr), "Failed to set color op, hr %#lx.\n", hr);
24178 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
24179 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#lx.\n", hr);
24180 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_SPECULAR);
24181 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#lx.\n", hr);
24182 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_MODULATE);
24183 ok(SUCCEEDED(hr), "Failed to set color op, hr %#lx.\n", hr);
24184 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
24185 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#lx.\n", hr);
24186 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
24187 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#lx.\n", hr);
24189 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
24190 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
24192 for (i = 0; i < ARRAY_SIZE(tests); ++i)
24194 if (caps.VertexShaderVersion < tests[i].vs_version
24195 || caps.PixelShaderVersion < tests[i].ps_version)
24197 skip("Vertex / pixel shader version not supported, skipping test %u.\n", i);
24198 continue;
24200 if (tests[i].vs)
24202 hr = IDirect3DDevice9_CreateVertexShader(device, tests[i].vs, &vs);
24203 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#lx (case %u).\n", hr, i);
24205 else
24207 vs = NULL;
24209 if (tests[i].ps)
24211 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].ps, &ps);
24212 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#lx (case %u).\n", hr, i);
24214 else
24216 ps = NULL;
24219 hr = IDirect3DDevice9_SetVertexShader(device, vs);
24220 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
24221 hr = IDirect3DDevice9_SetPixelShader(device, ps);
24222 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
24224 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
24225 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
24227 hr = IDirect3DDevice9_BeginScene(device);
24228 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
24230 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
24231 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
24233 hr = IDirect3DDevice9_EndScene(device);
24234 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
24236 color = getPixelColor(device, 320, 240);
24237 ok(color_match(color, tests[i].expected, 1) || broken(color_match(color, tests[i].broken, 1)),
24238 "Got unexpected color 0x%08x, case %u.\n", color, i);
24240 if (vs)
24241 IDirect3DVertexShader9_Release(vs);
24242 if (ps)
24243 IDirect3DVertexShader9_Release(ps);
24246 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
24247 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
24249 refcount = IDirect3DDevice9_Release(device);
24250 ok(!refcount, "Device has %lu references left.\n", refcount);
24251 IDirect3D9_Release(d3d9);
24252 DestroyWindow(window);
24255 static void test_line_antialiasing_blending(void)
24257 IDirect3DDevice9 *device;
24258 unsigned int color;
24259 IDirect3D9 *d3d9;
24260 ULONG refcount;
24261 D3DCAPS9 caps;
24262 HWND window;
24263 HRESULT hr;
24265 static const struct
24267 struct vec3 position;
24268 DWORD diffuse;
24270 green_quad[] =
24272 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
24273 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
24274 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
24275 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
24277 static const struct
24279 struct vec3 position;
24280 DWORD diffuse;
24282 red_quad[] =
24284 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
24285 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
24286 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
24287 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
24290 window = create_window();
24291 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
24292 ok(!!d3d9, "Failed to create a D3D object.\n");
24293 if (!(device = create_device(d3d9, window, window, TRUE)))
24295 skip("Failed to create a D3D device.\n");
24296 IDirect3D9_Release(d3d9);
24297 DestroyWindow(window);
24298 return;
24301 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
24302 ok(SUCCEEDED(hr), "Failed to get caps, hr %#lx.\n", hr);
24303 trace("Line antialiasing support: %#lx.\n", caps.LineCaps & D3DLINECAPS_ANTIALIAS);
24305 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
24306 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#lx.\n", hr);
24307 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
24308 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#lx.\n", hr);
24309 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
24310 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
24312 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
24313 ok(SUCCEEDED(hr), "Failed to enable blending, hr %#lx.\n", hr);
24314 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_BLENDOP, D3DBLENDOP_ADD);
24315 ok(SUCCEEDED(hr), "Failed to set blend op, hr %#lx.\n", hr);
24316 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
24317 ok(SUCCEEDED(hr), "Failed to set src blend, hr %#lx.\n", hr);
24318 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_DESTALPHA);
24319 ok(SUCCEEDED(hr), "Failed to set dest blend, hr %#lx.\n", hr);
24321 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
24322 ok(SUCCEEDED(hr), "Failed to set color op, hr %#lx.\n", hr);
24323 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
24324 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#lx.\n", hr);
24325 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
24326 ok(SUCCEEDED(hr), "Failed to set alpha op, hr %#lx.\n", hr);
24327 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
24328 ok(SUCCEEDED(hr), "Failed to set alpha arg, hr %#lx.\n", hr);
24330 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
24331 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
24333 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xccff0000, 0.0f, 0);
24334 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
24335 hr = IDirect3DDevice9_BeginScene(device);
24336 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
24337 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, green_quad, sizeof(*green_quad));
24338 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
24339 hr = IDirect3DDevice9_EndScene(device);
24340 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
24341 color = getPixelColor(device, 320, 240);
24342 ok(color_match(color, 0x00cc7f00, 1), "Got unexpected color 0x%08x.\n", color);
24344 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f00ff00, 0.0f, 0);
24345 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
24346 hr = IDirect3DDevice9_BeginScene(device);
24347 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
24348 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, red_quad, sizeof(*red_quad));
24349 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
24350 hr = IDirect3DDevice9_EndScene(device);
24351 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
24352 color = getPixelColor(device, 320, 240);
24353 ok(color_match(color, 0x00cc7f00, 1), "Got unexpected color 0x%08x.\n", color);
24355 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
24356 ok(SUCCEEDED(hr), "Failed to disable blending, hr %#lx.\n", hr);
24358 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xccff0000, 0.0f, 0);
24359 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
24360 hr = IDirect3DDevice9_BeginScene(device);
24361 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
24362 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, green_quad, sizeof(*green_quad));
24363 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
24364 hr = IDirect3DDevice9_EndScene(device);
24365 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
24366 color = getPixelColor(device, 320, 240);
24367 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
24369 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f00ff00, 0.0f, 0);
24370 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
24371 hr = IDirect3DDevice9_BeginScene(device);
24372 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
24373 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, red_quad, sizeof(*red_quad));
24374 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
24375 hr = IDirect3DDevice9_EndScene(device);
24376 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
24377 color = getPixelColor(device, 320, 240);
24378 ok(color_match(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
24380 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ANTIALIASEDLINEENABLE, TRUE);
24381 ok(SUCCEEDED(hr), "Failed to enable line antialiasing, hr %#lx.\n", hr);
24383 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xccff0000, 0.0f, 0);
24384 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
24385 hr = IDirect3DDevice9_BeginScene(device);
24386 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
24387 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, green_quad, sizeof(*green_quad));
24388 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
24389 hr = IDirect3DDevice9_EndScene(device);
24390 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
24391 color = getPixelColor(device, 320, 240);
24392 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
24394 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f00ff00, 0.0f, 0);
24395 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
24396 hr = IDirect3DDevice9_BeginScene(device);
24397 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
24398 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, red_quad, sizeof(*red_quad));
24399 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
24400 hr = IDirect3DDevice9_EndScene(device);
24401 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
24402 color = getPixelColor(device, 320, 240);
24403 ok(color_match(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
24405 refcount = IDirect3DDevice9_Release(device);
24406 ok(!refcount, "Device has %lu references left.\n", refcount);
24407 IDirect3D9_Release(d3d9);
24408 DestroyWindow(window);
24411 static void test_dsy(void)
24413 static const DWORD vs_code[] =
24415 0xfffe0300, /* vs_3_0 */
24416 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
24417 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
24418 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
24419 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */
24420 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
24421 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
24422 0x0000ffff
24424 static const DWORD ps_code[] =
24426 0xffff0300, /* ps_3_0 */
24427 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
24428 0x05000051, 0xa00f0000, 0x43700000, 0x3f000000, 0x00000000, 0x00000000, /* def c0, 240.0, 0.5, 0.0, 0.0 */
24429 0x0200005c, 0x800f0000, 0x90e40000, /* dsy r0, v0 */
24430 0x03000005, 0x800f0000, 0x80e40000, 0xa0000000, /* mul r0, r0, c0.x */
24431 0x03000002, 0x800f0800, 0x80e40000, 0xa0550000, /* add oC0, r0, c0.y */
24432 0x0000ffff
24434 static const struct
24436 struct vec3 pos;
24437 D3DCOLOR color;
24439 quad[] =
24441 {{-1.0f, -1.0f, 0.1f}, 0x00ff0000},
24442 {{-1.0f, 1.0f, 0.1f}, 0x0000ff00},
24443 {{ 1.0f, -1.0f, 0.1f}, 0x00ff0000},
24444 {{ 1.0f, 1.0f, 0.1f}, 0x0000ff00},
24446 IDirect3DSurface9 *backbuffer, *rt;
24447 IDirect3DVertexShader9 *vs;
24448 IDirect3DPixelShader9 *ps;
24449 IDirect3DDevice9 *device;
24450 unsigned int color;
24451 IDirect3D9 *d3d;
24452 ULONG refcount;
24453 D3DCAPS9 caps;
24454 HWND window;
24455 HRESULT hr;
24457 window = create_window();
24458 d3d = Direct3DCreate9(D3D_SDK_VERSION);
24459 ok(!!d3d, "Failed to create a D3D object.\n");
24460 if (!(device = create_device(d3d, window, window, TRUE)))
24462 skip("Failed to create a D3D device, skipping tests.\n");
24463 goto done;
24466 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
24467 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
24468 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0))
24470 skip("No ps_3_0 support, skipping dsy tests.\n");
24471 IDirect3DDevice9_Release(device);
24472 goto done;
24475 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
24476 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#lx.\n", hr);
24478 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
24479 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
24480 ok(SUCCEEDED(hr), "Failed to create offscreen render target, hr %#lx.\n", hr);
24481 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
24482 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
24484 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
24485 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#lx.\n", hr);
24486 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
24487 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#lx.\n", hr);
24489 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
24490 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
24491 hr = IDirect3DDevice9_SetVertexShader(device, vs);
24492 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
24493 hr = IDirect3DDevice9_SetPixelShader(device, ps);
24494 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
24496 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
24497 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
24498 hr = IDirect3DDevice9_BeginScene(device);
24499 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
24500 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
24501 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#lx.\n", hr);
24502 hr = IDirect3DDevice9_EndScene(device);
24503 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
24505 color = getPixelColor(device, 360, 240);
24506 ok(color_match(color, 0x00ff007f, 1), "Got unexpected color 0x%08x.\n", color);
24508 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
24509 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
24511 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
24512 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
24513 hr = IDirect3DDevice9_BeginScene(device);
24514 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
24515 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
24516 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#lx.\n", hr);
24517 hr = IDirect3DDevice9_EndScene(device);
24518 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
24520 color = getPixelColor(device, 360, 240);
24521 ok(color_match(color, 0x00ff007f, 1), "Got unexpected color 0x%08x.\n", color);
24523 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
24524 ok(SUCCEEDED(hr), "Failed to present frame, hr %#lx.\n", hr);
24526 IDirect3DSurface9_Release(rt);
24527 IDirect3DSurface9_Release(backbuffer);
24528 IDirect3DVertexShader9_Release(vs);
24529 IDirect3DPixelShader9_Release(ps);
24531 refcount = IDirect3DDevice9_Release(device);
24532 ok(!refcount, "Device has %lu references left.\n", refcount);
24533 done:
24534 IDirect3D9_Release(d3d);
24535 DestroyWindow(window);
24538 static void test_evict_bound_resources(void)
24540 IDirect3DVertexBuffer9 *vb;
24541 IDirect3DIndexBuffer9 *ib;
24542 IDirect3DDevice9 *device;
24543 unsigned int color;
24544 IDirect3D9 *d3d9;
24545 ULONG refcount;
24546 HWND window;
24547 void *data;
24548 HRESULT hr;
24550 static const struct
24552 struct vec3 position;
24553 DWORD diffuse;
24555 green_quad[] =
24557 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
24558 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
24559 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
24560 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
24562 static const unsigned short indices[] = {0, 1, 2, 3, 2, 1};
24564 window = create_window();
24565 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
24566 ok(!!d3d9, "Failed to create a D3D object.\n");
24568 if (!(device = create_device(d3d9, window, window, TRUE)))
24570 skip("Failed to create a D3D device.\n");
24571 IDirect3D9_Release(d3d9);
24572 DestroyWindow(window);
24573 return;
24576 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0,
24577 D3DFMT_INDEX16, D3DPOOL_MANAGED, &ib, NULL);
24578 ok(SUCCEEDED(hr), "Failed to create index buffer, hr %#lx.\n", hr);
24580 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(green_quad), 0,
24581 D3DFVF_XYZ | D3DFVF_DIFFUSE, D3DPOOL_MANAGED, &vb, NULL);
24582 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#lx.\n", hr);
24584 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
24585 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#lx.\n", hr);
24586 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
24587 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#lx.\n", hr);
24588 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
24589 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
24591 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
24592 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
24594 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(green_quad), &data, 0);
24595 ok(hr == D3D_OK, "Failed to lock vertex buffer, hr %#lx.\n", hr);
24596 memcpy(data, green_quad, sizeof(green_quad));
24597 hr = IDirect3DVertexBuffer9_Unlock(vb);
24598 ok(hr == D3D_OK, "Failed to unlock vertex buffer, hr %#lx.\n", hr);
24600 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), &data, 0);
24601 ok(hr == D3D_OK, "Failed to lock index buffer, hr %#lx.\n", hr);
24602 memcpy(data, indices, sizeof(indices));
24603 hr = IDirect3DIndexBuffer9_Unlock(ib);
24604 ok(hr == D3D_OK, "Failed to unlock index buffer, hr %#lx.\n", hr);
24606 hr = IDirect3DDevice9_SetIndices(device, ib);
24607 ok(hr == D3D_OK, "Failed to set index buffer, hr %#lx.\n", hr);
24608 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(*green_quad));
24609 ok(hr == D3D_OK, "Failed to set stream source, hr %#lx.\n", hr);
24611 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
24612 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
24613 hr = IDirect3DDevice9_BeginScene(device);
24614 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
24615 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
24616 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
24617 hr = IDirect3DDevice9_EndScene(device);
24618 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
24619 color = getPixelColor(device, 320, 240);
24620 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
24622 hr = IDirect3DDevice9_EvictManagedResources(device);
24623 ok(hr == D3D_OK, "Failed to evict managed resources, hr %#lx.\n", hr);
24625 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
24626 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
24627 hr = IDirect3DDevice9_BeginScene(device);
24628 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
24629 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
24630 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
24631 hr = IDirect3DDevice9_EndScene(device);
24632 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
24633 color = getPixelColor(device, 320, 240);
24634 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
24636 IDirect3DIndexBuffer9_Release(ib);
24637 IDirect3DVertexBuffer9_Release(vb);
24638 refcount = IDirect3DDevice9_Release(device);
24639 ok(!refcount, "Device has %lu references left.\n", refcount);
24640 IDirect3D9_Release(d3d9);
24641 DestroyWindow(window);
24644 /* This test shows that 0xffff is valid index in D3D9. */
24645 static void test_max_index16(void)
24647 static const struct vertex
24649 struct vec3 position;
24650 DWORD diffuse;
24652 green_quad[] =
24654 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
24655 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
24656 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
24657 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
24659 static const unsigned short indices[] = {0, 1, 2, 0xffff};
24660 static const unsigned int vertex_count = 0xffff + 1;
24662 D3DADAPTER_IDENTIFIER9 identifier;
24663 IDirect3DVertexBuffer9 *vb;
24664 IDirect3DIndexBuffer9 *ib;
24665 IDirect3DDevice9 *device;
24666 struct vertex *vb_data;
24667 unsigned int color;
24668 IDirect3D9 *d3d9;
24669 ULONG refcount;
24670 D3DCAPS9 caps;
24671 HWND window;
24672 void *data;
24673 HRESULT hr;
24674 BOOL warp;
24676 window = create_window();
24677 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
24678 ok(!!d3d9, "Failed to create a D3D object.\n");
24680 hr = IDirect3D9_GetAdapterIdentifier(d3d9, D3DADAPTER_DEFAULT, 0, &identifier);
24681 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#lx.\n", hr);
24682 warp = adapter_is_warp(&identifier);
24684 if (!(device = create_device(d3d9, window, window, TRUE)))
24686 skip("Failed to create a D3D device.\n");
24687 IDirect3D9_Release(d3d9);
24688 DestroyWindow(window);
24689 return;
24692 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
24693 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
24694 if (caps.MaxVertexIndex < 0xffff)
24696 skip("Max vertex index is lower than 0xffff (%#lx).\n", caps.MaxVertexIndex);
24697 IDirect3DDevice9_Release(device);
24698 IDirect3D9_Release(d3d9);
24699 DestroyWindow(window);
24700 return;
24703 hr = IDirect3DDevice9_CreateVertexBuffer(device, vertex_count * sizeof(*green_quad), 0,
24704 D3DFVF_XYZ | D3DFVF_DIFFUSE, D3DPOOL_MANAGED, &vb, NULL);
24705 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#lx.\n", hr);
24707 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0,
24708 D3DFMT_INDEX16, D3DPOOL_MANAGED, &ib, NULL);
24709 ok(SUCCEEDED(hr), "Failed to create index buffer, hr %#lx.\n", hr);
24711 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
24712 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#lx.\n", hr);
24713 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
24714 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#lx.\n", hr);
24715 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
24716 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
24718 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
24719 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
24721 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(green_quad), (void **)&vb_data, 0);
24722 ok(hr == D3D_OK, "Failed to lock vertex buffer, hr %#lx.\n", hr);
24723 vb_data[0] = green_quad[0];
24724 vb_data[1] = green_quad[1];
24725 vb_data[2] = green_quad[2];
24726 vb_data[0xffff] = green_quad[3];
24727 hr = IDirect3DVertexBuffer9_Unlock(vb);
24728 ok(hr == D3D_OK, "Failed to unlock vertex buffer, hr %#lx.\n", hr);
24730 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), &data, 0);
24731 ok(hr == D3D_OK, "Failed to lock index buffer, hr %#lx.\n", hr);
24732 memcpy(data, indices, sizeof(indices));
24733 hr = IDirect3DIndexBuffer9_Unlock(ib);
24734 ok(hr == D3D_OK, "Failed to unlock index buffer, hr %#lx.\n", hr);
24736 hr = IDirect3DDevice9_SetIndices(device, ib);
24737 ok(hr == D3D_OK, "Failed to set index buffer, hr %#lx.\n", hr);
24738 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(struct vertex));
24739 ok(hr == D3D_OK, "Failed to set stream source, hr %#lx.\n", hr);
24741 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
24742 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
24743 hr = IDirect3DDevice9_BeginScene(device);
24744 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
24745 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 0, vertex_count, 0, 2);
24746 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
24747 hr = IDirect3DDevice9_EndScene(device);
24748 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
24749 color = getPixelColor(device, 20, 20);
24750 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
24751 color = getPixelColor(device, 320, 240);
24752 ok(color_match(color, 0x0000ff00, 1) || broken(warp), "Got unexpected color 0x%08x.\n", color);
24753 color = getPixelColor(device, 620, 460);
24754 ok(color_match(color, 0x0000ff00, 1) || broken(warp), "Got unexpected color 0x%08x.\n", color);
24756 IDirect3DIndexBuffer9_Release(ib);
24757 IDirect3DVertexBuffer9_Release(vb);
24758 refcount = IDirect3DDevice9_Release(device);
24759 ok(!refcount, "Device has %lu references left.\n", refcount);
24760 IDirect3D9_Release(d3d9);
24761 DestroyWindow(window);
24764 static void test_backbuffer_resize(void)
24766 D3DPRESENT_PARAMETERS present_parameters = {0};
24767 IDirect3DSurface9 *backbuffer;
24768 IDirect3DDevice9 *device;
24769 unsigned int color;
24770 IDirect3D9 *d3d;
24771 ULONG refcount;
24772 HWND window;
24773 HRESULT hr;
24775 static const struct
24777 struct vec3 position;
24778 DWORD diffuse;
24780 quad[] =
24782 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
24783 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
24784 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
24785 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
24788 window = create_window();
24789 d3d = Direct3DCreate9(D3D_SDK_VERSION);
24790 ok(!!d3d, "Failed to create a D3D object.\n");
24791 if (!(device = create_device(d3d, window, window, TRUE)))
24793 skip("Failed to create a D3D device.\n");
24794 goto done;
24797 /* Wine d3d9 implementation had a bug which was triggered by a
24798 * SetRenderTarget() call with an unreferenced surface. */
24799 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
24800 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#lx.\n", hr);
24801 refcount = IDirect3DSurface9_Release(backbuffer);
24802 ok(!refcount, "Surface has %lu references left.\n", refcount);
24803 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
24804 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
24805 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
24806 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
24808 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
24809 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
24810 color = getPixelColor(device, 1, 1);
24811 ok(color == 0x00ff0000, "Got unexpected color 0x%08x.\n", color);
24813 present_parameters.BackBufferWidth = 800;
24814 present_parameters.BackBufferHeight = 600;
24815 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
24816 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
24817 present_parameters.hDeviceWindow = NULL;
24818 present_parameters.Windowed = TRUE;
24819 present_parameters.EnableAutoDepthStencil = TRUE;
24820 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
24821 hr = IDirect3DDevice9_Reset(device, &present_parameters);
24822 ok(SUCCEEDED(hr), "Failed to reset, hr %#lx.\n", hr);
24824 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
24825 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#lx.\n", hr);
24826 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
24827 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#lx.\n", hr);
24828 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
24829 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
24830 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
24831 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
24833 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
24834 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#lx.\n", hr);
24835 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
24836 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
24837 IDirect3DSurface9_Release(backbuffer);
24839 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
24840 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
24841 color = getPixelColor(device, 1, 1);
24842 ok(color == 0x00ffff00, "Got unexpected color 0x%08x.\n", color);
24843 color = getPixelColor(device, 700, 500);
24844 ok(color == 0x00ffff00, "Got unexpected color 0x%08x.\n", color);
24846 hr = IDirect3DDevice9_BeginScene(device);
24847 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
24848 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
24849 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
24850 hr = IDirect3DDevice9_EndScene(device);
24851 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
24852 color = getPixelColor(device, 1, 1);
24853 ok(color == 0x0000ff00, "Got unexpected color 0x%08x.\n", color);
24854 color = getPixelColor(device, 700, 500);
24855 ok(color == 0x0000ff00, "Got unexpected color 0x%08x.\n", color);
24857 refcount = IDirect3DDevice9_Release(device);
24858 ok(!refcount, "Device has %lu references left.\n", refcount);
24859 done:
24860 IDirect3D9_Release(d3d);
24861 DestroyWindow(window);
24864 static void test_drawindexedprimitiveup(void)
24866 static const struct vertex
24868 struct vec3 position;
24869 DWORD diffuse;
24871 quad[] =
24873 {{-1.0f, -1.0f, 0.1f}, 0xff00ff00},
24874 {{-1.0f, 1.0f, 0.1f}, 0xff0000ff},
24875 {{ 1.0f, -1.0f, 0.1f}, 0xffff0000},
24876 {{ 1.0f, 1.0f, 0.1f}, 0xff0000ff},
24878 {{-1.0f, -1.0f, 0.1f}, 0xff0000ff},
24879 {{-1.0f, 1.0f, 0.1f}, 0xff00ff00},
24880 {{ 1.0f, -1.0f, 0.1f}, 0xffff0000},
24881 {{ 1.0f, 1.0f, 0.1f}, 0xff00ff00},
24883 static const unsigned short indices[] = {0, 1, 2, 3, 4, 5, 6, 7};
24884 IDirect3DVertexBuffer9 *vb;
24885 IDirect3DDevice9 *device;
24886 UINT offset, stride;
24887 unsigned int color;
24888 IDirect3D9 *d3d;
24889 ULONG refcount;
24890 HWND window;
24891 HRESULT hr;
24893 window = create_window();
24894 d3d = Direct3DCreate9(D3D_SDK_VERSION);
24895 ok(!!d3d, "Failed to create a D3D object.\n");
24897 if (!(device = create_device(d3d, window, window, TRUE)))
24899 skip("Failed to create a D3D device.\n");
24900 IDirect3D9_Release(d3d);
24901 DestroyWindow(window);
24902 return;
24905 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
24906 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#lx.\n", hr);
24907 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
24908 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#lx.\n", hr);
24909 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
24910 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
24912 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
24913 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
24915 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
24916 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
24918 hr = IDirect3DDevice9_BeginScene(device);
24919 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
24920 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 4, 4, 2, indices + 4, D3DFMT_INDEX16, quad, sizeof(*quad));
24921 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
24922 hr = IDirect3DDevice9_EndScene(device);
24923 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
24925 color = getPixelColor(device, 160, 120);
24926 ok(color_match(color, 0x0040bf00, 1), "Got unexpected color 0x%08x.\n", color);
24927 color = getPixelColor(device, 480, 120);
24928 ok(color_match(color, 0x0040bf00, 1), "Got unexpected color 0x%08x.\n", color);
24929 color = getPixelColor(device, 160, 360);
24930 ok(color_match(color, 0x00404080, 1), "Got unexpected color 0x%08x.\n", color);
24931 color = getPixelColor(device, 480, 360);
24932 ok(color_match(color, 0x00bf4000, 1), "Got unexpected color 0x%08x.\n", color);
24934 hr = IDirect3DDevice9_GetStreamSource(device, 0, &vb, &offset, &stride);
24935 ok(SUCCEEDED(hr), "GetStreamSource failed, hr %#lx.\n", hr);
24936 ok(!vb, "Unexpected vb %p.\n", vb);
24937 ok(!offset, "Unexpected offset %u.\n", offset);
24938 ok(!stride, "Unexpected stride %u.\n", stride);
24940 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
24941 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
24943 hr = IDirect3DDevice9_BeginScene(device);
24944 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
24945 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 0, 4, 2, indices, D3DFMT_INDEX16, quad, sizeof(*quad));
24946 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
24947 hr = IDirect3DDevice9_EndScene(device);
24948 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
24950 color = getPixelColor(device, 160, 120);
24951 ok(color_match(color, 0x004000bf, 1), "Got unexpected color 0x%08x.\n", color);
24952 color = getPixelColor(device, 480, 120);
24953 ok(color_match(color, 0x004000bf, 1), "Got unexpected color 0x%08x.\n", color);
24954 color = getPixelColor(device, 160, 360);
24955 ok(color_match(color, 0x00408040, 1), "Got unexpected color 0x%08x.\n", color);
24956 color = getPixelColor(device, 480, 360);
24957 ok(color_match(color, 0x00bf0040, 1), "Got unexpected color 0x%08x.\n", color);
24959 refcount = IDirect3DDevice9_Release(device);
24960 ok(!refcount, "Device has %lu references left.\n", refcount);
24961 IDirect3D9_Release(d3d);
24962 DestroyWindow(window);
24965 static void test_vertex_texture(void)
24967 static const D3DVERTEXELEMENT9 decl_elements[] =
24969 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
24970 D3DDECL_END()
24972 static const struct vec3 quad[] =
24974 {-1.0f, -1.0f, 0.0f},
24975 {-1.0f, 1.0f, 0.0f},
24976 { 1.0f, -1.0f, 0.0f},
24977 { 1.0f, 1.0f, 0.0f},
24979 static const DWORD vs_code[] =
24981 0xfffe0300, /* vs_3_0 */
24982 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0, 0, 0, 0 */
24983 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
24984 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
24985 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
24986 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
24987 0x0300005f, 0xe00f0001, 0xa0000000, 0xa0e40800, /* texldl o1, c0.x, s0 */
24988 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
24989 0x0000ffff, /* end */
24991 static const DWORD ps_code[] =
24993 0xffff0300, /* ps_3_0 */
24994 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color v0 */
24995 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
24996 0x0000ffff, /* end */
24998 static const DWORD texture_data[4] = {0x00ffff00, 0x00ffff00, 0x00ffff00, 0x00ffff00};
24999 IDirect3DVertexDeclaration9 *declaration;
25000 IDirect3DTexture9 *texture;
25001 IDirect3DVertexShader9 *vs;
25002 IDirect3DPixelShader9 *ps;
25003 IDirect3DDevice9 *device;
25004 unsigned int color;
25005 D3DLOCKED_RECT lr;
25006 IDirect3D9 *d3d;
25007 ULONG refcount;
25008 D3DCAPS9 caps;
25009 HWND window;
25010 HRESULT hr;
25012 window = create_window();
25013 d3d = Direct3DCreate9(D3D_SDK_VERSION);
25014 ok(!!d3d, "Failed to create D3D object.\n");
25016 if (!(device = create_device(d3d, window, window, TRUE)))
25018 skip("Failed to create D3D device.\n");
25019 IDirect3D9_Release(d3d);
25020 DestroyWindow(window);
25021 return;
25024 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
25025 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
25026 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0) || caps.PixelShaderVersion < D3DPS_VERSION(3, 0))
25028 skip("SM3 is not supported.\n");
25029 goto done;
25031 if (!(caps.VertexTextureFilterCaps & D3DPTFILTERCAPS_MAGFPOINT)
25032 || !(caps.VertexTextureFilterCaps & D3DPTFILTERCAPS_MINFPOINT))
25034 skip("Vertex texture point filtering is not supported, caps %#lx.\n", caps.VertexTextureFilterCaps);
25035 goto done;
25037 hr = IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
25038 D3DUSAGE_QUERY_VERTEXTEXTURE, D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8);
25039 if (hr != D3D_OK)
25041 skip("No vertex texture fetch support for D3DFMT_A8R8G8B8, hr %#lx.\n", hr);
25042 goto done;
25045 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
25046 ok(hr == D3D_OK, "Failed to create texture, hr %#lx.\n", hr);
25047 memset(&lr, 0, sizeof(lr));
25048 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
25049 ok(hr == D3D_OK, "Failed to lock texture, hr %#lx.\n", hr);
25050 memcpy(lr.pBits, texture_data, sizeof(texture_data));
25051 hr = IDirect3DTexture9_UnlockRect(texture, 0);
25052 ok(hr == D3D_OK, "Failed to unlock texture, hr %#lx.\n", hr);
25054 hr = IDirect3DDevice9_SetTexture(device, D3DVERTEXTEXTURESAMPLER0, (IDirect3DBaseTexture9 *)texture);
25055 ok(hr == D3D_OK, "Failed to set texture, hr %#lx.\n", hr);
25057 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &declaration);
25058 ok(SUCCEEDED(hr), "Failed to create vertex declaration, hr %#lx.\n", hr);
25059 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
25060 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#lx.\n", hr);
25061 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
25062 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#lx.\n", hr);
25064 hr = IDirect3DDevice9_SetVertexDeclaration(device, declaration);
25065 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#lx.\n", hr);
25066 hr = IDirect3DDevice9_SetVertexShader(device, vs);
25067 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
25068 hr = IDirect3DDevice9_SetPixelShader(device, ps);
25069 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
25071 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
25072 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
25073 hr = IDirect3DDevice9_BeginScene(device);
25074 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
25075 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
25076 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
25077 hr = IDirect3DDevice9_EndScene(device);
25078 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
25079 color = getPixelColor(device, 160, 360);
25080 ok(color == texture_data[0], "Got unexpected color 0x%08x.\n", color);
25082 IDirect3DPixelShader9_Release(ps);
25083 IDirect3DVertexShader9_Release(vs);
25084 IDirect3DTexture9_Release(texture);
25085 IDirect3DVertexDeclaration9_Release(declaration);
25086 done:
25087 refcount = IDirect3DDevice9_Release(device);
25088 ok(!refcount, "Device has %lu references left.\n", refcount);
25089 IDirect3D9_Release(d3d);
25090 DestroyWindow(window);
25093 static void test_mvp_software_vertex_shaders(void)
25095 IDirect3DVertexDeclaration9 *vertex_declaration;
25096 D3DPRESENT_PARAMETERS present_parameters = {0};
25097 IDirect3DVertexShader9 *pure_sw_shader = NULL;
25098 IDirect3DVertexShader9 *reladdr_shader = NULL;
25099 unsigned int color, expected_color;
25100 IDirect3DDevice9 *device;
25101 IDirect3D9 *d3d;
25102 ULONG refcount;
25103 D3DCAPS9 caps;
25104 HWND window;
25105 HRESULT hr;
25107 static const float c_index[4] = {256.0f, 0.0f, 0.0f, 0.0f};
25108 static const float c_color[4] = {0.0f, 1.0f, 0.0f, 1.0f};
25109 static const DWORD reladdr_shader_code[] =
25111 0xfffe0200, /* vs_2_0 */
25112 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
25113 0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c1, 1.0, 1.0, 1.0, 1.0 */
25114 0x0200002e, 0xb0010000, 0xa0000000, /* mova a0.x, c0.x */
25115 0x03000001, 0xd00f0000, 0xa0e42000, 0xb0000000, /* mov oD0, c[a0.x] */
25116 0x02000001, 0xd0040000, 0xa0e40001, /* mov oD0.z, c1 */
25117 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
25118 0x0000ffff /* END */
25120 static const DWORD pure_sw_shader_code[] =
25122 0xfffe0200, /* vs_2_0 */
25123 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
25124 0x05000051, 0xa00f0100, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c256, 1.0, 1.0, 1.0, 1.0 */
25125 0x02000001, 0xd00f0000, 0xa0e40100, /* mov oD0, c256 */
25126 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
25127 0x0000ffff /* END */
25130 static const struct
25132 float position[3];
25133 DWORD color;
25135 quad[] =
25137 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
25138 {{-1.0f, 1.0f, 0.0f}, 0xffff0000},
25139 {{ 1.0f, 1.0f, 0.0f}, 0xffff0000},
25140 {{ 1.0f, -1.0f, 0.0f}, 0xffff0000},
25142 static const D3DVERTEXELEMENT9 decl_elements[] =
25144 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
25145 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
25146 D3DDECL_END()
25149 window = create_window();
25150 d3d = Direct3DCreate9(D3D_SDK_VERSION);
25151 ok(!!d3d, "Failed to create a D3D object.\n");
25153 present_parameters.Windowed = TRUE;
25154 present_parameters.hDeviceWindow = window;
25155 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
25156 present_parameters.BackBufferWidth = 640;
25157 present_parameters.BackBufferHeight = 480;
25158 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
25159 present_parameters.EnableAutoDepthStencil = TRUE;
25160 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
25162 if (FAILED(IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
25163 D3DCREATE_MIXED_VERTEXPROCESSING, &present_parameters, &device)))
25165 skip("Failed to create a D3D device, skipping tests.\n");
25166 goto done;
25169 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
25170 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
25171 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
25173 skip("No vs_2_0 support, skipping tests.\n");
25174 IDirect3DDevice9_Release(device);
25175 goto done;
25178 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
25179 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
25181 hr = IDirect3DDevice9_SetSoftwareVertexProcessing(device, 0);
25182 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25184 hr = IDirect3DDevice9_CreateVertexShader(device, reladdr_shader_code, &reladdr_shader);
25185 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25186 hr = IDirect3DDevice9_CreateVertexShader(device, pure_sw_shader_code, &pure_sw_shader);
25187 todo_wine
25188 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25189 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
25190 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25191 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
25192 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25194 hr = IDirect3DDevice9_SetVertexShader(device, pure_sw_shader);
25195 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25197 hr = IDirect3DDevice9_BeginScene(device);
25198 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25199 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
25200 todo_wine
25201 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
25202 hr = IDirect3DDevice9_EndScene(device);
25203 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25205 expected_color = 0; /* Nothing rendered. */
25206 color = getPixelColor(device, 5, 5);
25207 todo_wine
25208 ok(color == expected_color, "Expected color 0x%08x, got 0x%08x (sw shader in hw mode).\n",
25209 expected_color, color);
25211 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
25212 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25213 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
25214 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25216 hr = IDirect3DDevice9_BeginScene(device);
25217 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25218 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
25219 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25220 hr = IDirect3DDevice9_EndScene(device);
25221 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25223 expected_color = 0x00ff0000; /* Color from vertex data and not from the shader. */
25224 color = getPixelColor(device, 5, 5);
25225 ok(color == expected_color, "Expected color 0x%08x, got 0x%08x (sw shader in hw mode, second attempt).\n",
25226 expected_color, color);
25228 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
25229 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25230 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
25231 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25233 hr = IDirect3DDevice9_BeginScene(device);
25234 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25235 hr = IDirect3DDevice9_SetSoftwareVertexProcessing(device, 1);
25236 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25237 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
25238 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25239 hr = IDirect3DDevice9_EndScene(device);
25240 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25242 expected_color = 0x00ffffff;
25243 color = getPixelColor(device, 5, 5);
25244 todo_wine
25245 ok(color == expected_color, "Expected color 0x%08x, got 0x%08x (sw shader in sw mode).\n",
25246 expected_color, color);
25248 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
25249 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25250 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
25251 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25253 hr = IDirect3DDevice9_SetSoftwareVertexProcessing(device, 0);
25254 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25255 hr = IDirect3DDevice9_SetVertexShader(device, reladdr_shader);
25256 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25258 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, c_index, 1);
25259 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25260 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, (unsigned int)c_index[0], c_color, 1);
25261 todo_wine
25262 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25264 hr = IDirect3DDevice9_BeginScene(device);
25265 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25266 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
25267 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25268 hr = IDirect3DDevice9_EndScene(device);
25269 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25271 /* Index 256 is out of bounds for selected shader in HW mode. c[256] is 0 most of the time. It
25272 is not guaranteed across all the adapters though, so disabling test. */
25273 #if 0
25274 expected_color = 0x000000ff;
25275 color = getPixelColor(device, 5, 5);
25276 ok(color == expected_color, "Expected color 0x%08x, got 0x%08x (shader in hw mode).\n",
25277 expected_color, color);
25278 #endif
25280 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
25281 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25282 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
25283 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25285 hr = IDirect3DDevice9_BeginScene(device);
25286 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25287 hr = IDirect3DDevice9_SetSoftwareVertexProcessing(device, 1);
25288 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
25289 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25290 hr = IDirect3DDevice9_EndScene(device);
25291 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
25293 expected_color = 0x0000ffff; /* c[256] is c_color for SW shader. */
25294 color = getPixelColor(device, 5, 5);
25295 todo_wine
25296 ok(color == expected_color, "Expected color 0x%08x, got 0x%08x (shader in sw mode).\n",
25297 expected_color, color);
25299 IDirect3DVertexDeclaration9_Release(vertex_declaration);
25300 IDirect3DVertexShader9_Release(reladdr_shader);
25301 if (pure_sw_shader)
25302 IDirect3DVertexShader9_Release(pure_sw_shader);
25303 refcount = IDirect3DDevice9_Release(device);
25304 ok(!refcount, "Device has %lu references left.\n", refcount);
25305 done:
25306 IDirect3D9_Release(d3d);
25307 DestroyWindow(window);
25310 static void test_null_format(void)
25312 static const D3DVIEWPORT9 vp_part_400 = {0, 100, 400, 200, 0.0f, 1.0f};
25313 static const D3DVIEWPORT9 vp_lower = {0, 60, 640, 420, 0.0f, 1.0f};
25314 static const D3DVIEWPORT9 vp_560 = {0, 180, 560, 300, 0.0f, 1.0f};
25315 static const D3DVIEWPORT9 vp_full = {0, 0, 640, 480, 0.0f, 1.0f};
25316 static const DWORD null_fourcc = MAKEFOURCC('N','U','L','L');
25317 static const struct
25319 struct vec3 pos;
25320 DWORD diffuse;
25322 quad_partial[] =
25324 {{-1.0f, 0.5f, 0.1f}, 0x000000ff},
25325 {{ 0.5f, 0.5f, 0.1f}, 0x000000ff},
25326 {{-1.0f, -1.0f, 0.1f}, 0x000000ff},
25327 {{ 0.5f, -1.0f, 0.1f}, 0x000000ff},
25329 quad[] =
25331 {{-1.0f, 1.0f, 0.5f}, 0x00ff0000},
25332 {{ 1.0f, 1.0f, 0.5f}, 0x00ff0000},
25333 {{-1.0f, -1.0f, 0.5f}, 0x00ff0000},
25334 {{ 1.0f, -1.0f, 0.5f}, 0x00ff0000},
25336 quad_far[] =
25338 {{-1.0f, 1.0f, 1.0f}, 0x0000ff00},
25339 {{ 1.0f, 1.0f, 1.0f}, 0x0000ff00},
25340 {{-1.0f, -1.0f, 1.0f}, 0x0000ff00},
25341 {{ 1.0f, -1.0f, 1.0f}, 0x0000ff00},
25343 static const struct
25345 unsigned int x, y, color;
25347 expected_colors[] =
25349 {200, 30, 0x0000ff00},
25350 {440, 30, 0x0000ff00},
25351 {520, 30, 0x0000ff00},
25352 {600, 30, 0x0000ff00},
25353 {200, 90, 0x00000000},
25354 {440, 90, 0x0000ff00},
25355 {520, 90, 0x0000ff00},
25356 {600, 90, 0x0000ff00},
25357 {200, 150, 0x000000ff},
25358 {440, 150, 0x000000ff},
25359 {520, 150, 0x0000ff00},
25360 {600, 150, 0x0000ff00},
25361 {200, 320, 0x000000ff},
25362 {440, 320, 0x000000ff},
25363 {520, 320, 0x00000000},
25364 {600, 320, 0x0000ff00},
25366 expected_small[] =
25368 {100, 100, 0x00ff0000},
25369 {200, 100, 0x00ff0000},
25370 {300, 100, 0x00ff0000},
25371 {100, 150, 0x00000000},
25372 {200, 150, 0x00000000},
25373 {300, 150, 0x00ff0000},
25374 {100, 200, 0x00000000},
25375 {200, 200, 0x00000000},
25376 {300, 200, 0x00ff0000},
25378 IDirect3DSurface9 *original_rt, *small_rt, *null_rt, *small_null_rt;
25379 IDirect3DSurface9 *original_ds, *small_ds;
25380 struct surface_readback rb;
25381 IDirect3DDevice9 *device;
25382 unsigned int color, i;
25383 IDirect3D9 *d3d;
25384 HWND window;
25385 HRESULT hr;
25387 d3d = Direct3DCreate9(D3D_SDK_VERSION);
25388 ok(!!d3d, "Failed to create a D3D object.\n");
25390 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
25391 D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, null_fourcc)))
25393 skip("No NULL format support, skipping NULL test.\n");
25394 IDirect3D9_Release(d3d);
25395 return;
25398 window = create_window();
25399 if (!(device = create_device(d3d, window, window, TRUE)))
25401 skip("Failed to create a D3D device.\n");
25402 IDirect3D9_Release(d3d);
25403 DestroyWindow(window);
25404 return;
25407 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
25408 ok(SUCCEEDED(hr), "Failed to get render target, hr %#lx.\n", hr);
25410 hr = IDirect3DDevice9_CreateRenderTarget(device, 400, 300, D3DFMT_A8R8G8B8,
25411 D3DMULTISAMPLE_NONE, 0, FALSE, &small_rt, NULL);
25412 ok(SUCCEEDED(hr), "Failed to create render target, hr %#lx.\n", hr);
25413 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, null_fourcc,
25414 D3DMULTISAMPLE_NONE, 0, FALSE, &null_rt, NULL);
25415 ok(SUCCEEDED(hr), "Failed to create render target, hr %#lx.\n", hr);
25416 hr = IDirect3DDevice9_CreateRenderTarget(device, 400, 300, null_fourcc,
25417 D3DMULTISAMPLE_NONE, 0, FALSE, &small_null_rt, NULL);
25418 ok(SUCCEEDED(hr), "Failed to create render target, hr %#lx.\n", hr);
25420 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
25421 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
25422 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 400, 300, D3DFMT_D24S8, 0, 0, FALSE,
25423 &small_ds, NULL);
25424 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
25426 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
25427 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
25428 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
25429 ok(SUCCEEDED(hr), "Failed to enable depth test, hr %#lx.\n", hr);
25430 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
25431 ok(SUCCEEDED(hr), "Failed to set depth function, hr %#lx.\n", hr);
25432 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
25433 ok(SUCCEEDED(hr), "Failed to enable depth write, hr %#lx.\n", hr);
25434 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
25435 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
25437 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
25438 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
25440 /* Clear extends to viewport size > RT size even if format is not
25441 * "NULL". */
25442 hr = IDirect3DDevice9_SetRenderTarget(device, 0, small_rt);
25443 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
25445 hr = IDirect3DDevice9_SetViewport(device, &vp_full);
25446 ok(hr == D3D_OK, "Failed to set viewport, hr %#lx.\n", hr);
25448 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.2f, 0);
25449 ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#lx.\n", hr);
25451 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
25452 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
25454 hr = IDirect3DDevice9_BeginScene(device);
25455 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
25456 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
25457 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
25458 hr = IDirect3DDevice9_EndScene(device);
25459 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
25461 hr = IDirect3DDevice9_SetRenderTarget(device, 0, null_rt);
25462 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
25463 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
25464 ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#lx.\n", hr);
25466 /* Draw only extends to viewport size > RT size if format is "NULL". */
25467 hr = IDirect3DDevice9_SetRenderTarget(device, 0, small_rt);
25468 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
25469 hr = IDirect3DDevice9_SetViewport(device, &vp_lower);
25470 ok(hr == D3D_OK, "Failed to set viewport, hr %#lx.\n", hr);
25471 hr = IDirect3DDevice9_BeginScene(device);
25472 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
25473 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
25474 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
25475 hr = IDirect3DDevice9_EndScene(device);
25476 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
25478 hr = IDirect3DDevice9_SetRenderTarget(device, 0, small_null_rt);
25479 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
25480 hr = IDirect3DDevice9_SetViewport(device, &vp_560);
25481 ok(hr == D3D_OK, "Failed to set viewport, hr %#lx.\n", hr);
25482 hr = IDirect3DDevice9_BeginScene(device);
25483 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
25484 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
25485 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
25486 hr = IDirect3DDevice9_EndScene(device);
25487 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
25489 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
25490 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
25492 hr = IDirect3DDevice9_BeginScene(device);
25493 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
25494 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_partial, sizeof(*quad_partial));
25495 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
25496 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_far, sizeof(*quad_far));
25497 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
25498 hr = IDirect3DDevice9_EndScene(device);
25499 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
25501 get_rt_readback(original_rt, &rb);
25502 for (i = 0; i < ARRAY_SIZE(expected_colors); ++i)
25504 color = get_readback_color(&rb, expected_colors[i].x, expected_colors[i].y);
25505 ok(color_match(color, expected_colors[i].color, 1),
25506 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
25507 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
25509 release_surface_readback(&rb);
25511 /* Clears and draws on a depth buffer smaller than the "NULL" RT work just
25512 * fine. */
25513 hr = IDirect3DDevice9_SetRenderTarget(device, 0, null_rt);
25514 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
25515 hr = IDirect3DDevice9_SetDepthStencilSurface(device, small_ds);
25516 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
25517 hr = IDirect3DDevice9_SetViewport(device, &vp_full);
25518 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
25520 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.6f, 0);
25521 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
25523 hr = IDirect3DDevice9_SetViewport(device, &vp_part_400);
25524 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
25526 hr = IDirect3DDevice9_BeginScene(device);
25527 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
25528 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_partial, sizeof(*quad_partial));
25529 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
25531 hr = IDirect3DDevice9_SetRenderTarget(device, 0, small_rt);
25532 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
25534 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
25535 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
25537 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
25538 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
25539 hr = IDirect3DDevice9_EndScene(device);
25540 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
25542 get_rt_readback(small_rt, &rb);
25543 for (i = 0; i < ARRAY_SIZE(expected_small); ++i)
25545 color = get_readback_color(&rb, expected_small[i].x, expected_small[i].y);
25546 ok(color_match(color, expected_small[i].color, 1),
25547 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
25548 expected_small[i].color, expected_small[i].x, expected_small[i].y, color);
25550 release_surface_readback(&rb);
25552 hr = IDirect3DDevice9_StretchRect(device, small_rt, NULL, original_rt, NULL, D3DTEXF_POINT);
25553 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
25554 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
25555 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
25557 IDirect3DSurface9_Release(small_ds);
25558 IDirect3DSurface9_Release(original_ds);
25559 IDirect3DSurface9_Release(small_null_rt);
25560 IDirect3DSurface9_Release(null_rt);
25561 IDirect3DSurface9_Release(small_rt);
25562 IDirect3DSurface9_Release(original_rt);
25563 cleanup_device(device);
25564 IDirect3D9_Release(d3d);
25567 static void test_map_synchronisation(void)
25569 unsigned int colour, i, j, tri_count, size;
25570 LARGE_INTEGER frequency, diff, ts[3];
25571 D3DADAPTER_IDENTIFIER9 identifier;
25572 IDirect3DVertexBuffer9 *buffer;
25573 IDirect3DDevice9 *device;
25574 BOOL unsynchronised, ret;
25575 IDirect3D9 *d3d;
25576 ULONG refcount;
25577 D3DCAPS9 caps;
25578 HWND window;
25579 HRESULT hr;
25581 static const struct
25583 unsigned int flags;
25584 BOOL unsynchronised;
25586 tests[] =
25588 {0, FALSE},
25589 {D3DLOCK_NOOVERWRITE, TRUE},
25590 {D3DLOCK_DISCARD, FALSE},
25591 {D3DLOCK_NOOVERWRITE | D3DLOCK_DISCARD, TRUE},
25594 static const struct quad
25596 struct
25598 struct vec3 position;
25599 DWORD diffuse;
25600 } strip[4];
25602 quad1 =
25605 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
25606 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
25607 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
25608 {{ 1.0f, 1.0f, 0.0f}, 0xffffffff},
25611 quad2 =
25614 {{-1.0f, -1.0f, 0.0f}, 0xffffff00},
25615 {{-1.0f, 1.0f, 0.0f}, 0xffffff00},
25616 {{ 1.0f, -1.0f, 0.0f}, 0xffffff00},
25617 {{ 1.0f, 1.0f, 0.0f}, 0xffffff00},
25620 struct quad *quads;
25622 window = create_window();
25623 ok(!!window, "Failed to create a window.\n");
25625 d3d = Direct3DCreate9(D3D_SDK_VERSION);
25626 ok(!!d3d, "Failed to create a D3D object.\n");
25627 if (!(device = create_device(d3d, window, window, TRUE)))
25629 skip("Failed to create a D3D device, skipping tests.\n");
25630 IDirect3D9_Release(d3d);
25631 DestroyWindow(window);
25632 return;
25635 hr = IDirect3D9_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
25636 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#lx.\n", hr);
25637 /* Maps are always synchronised on WARP. */
25638 if (adapter_is_warp(&identifier))
25640 skip("Running on WARP, skipping test.\n");
25641 goto done;
25644 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
25645 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
25647 tri_count = 0x1000;
25648 if (tri_count > caps.MaxPrimitiveCount)
25650 skip("Device supports only %lu primitives, skipping test.\n", caps.MaxPrimitiveCount);
25651 goto done;
25653 size = (tri_count + 2) * sizeof(*quad1.strip);
25655 ret = QueryPerformanceFrequency(&frequency);
25656 ok(ret, "Failed to get performance counter frequency.\n");
25658 hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
25659 D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &buffer, NULL);
25660 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#lx.\n", hr);
25661 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, size, (void **)&quads, D3DLOCK_DISCARD);
25662 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#lx.\n", hr);
25663 for (j = 0; j < size / sizeof(*quads); ++j)
25665 quads[j] = quad1;
25667 hr = IDirect3DVertexBuffer9_Unlock(buffer);
25668 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#lx.\n", hr);
25670 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
25671 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
25672 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
25673 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
25674 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(*quads->strip));
25675 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#lx.\n", hr);
25677 /* Initial draw to initialise states, compile shaders, etc. */
25678 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
25679 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
25680 hr = IDirect3DDevice9_BeginScene(device);
25681 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
25682 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, tri_count);
25683 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
25684 hr = IDirect3DDevice9_EndScene(device);
25685 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
25686 /* Read the result to ensure the GPU has finished drawing. */
25687 colour = getPixelColor(device, 320, 240);
25689 /* Time drawing tri_count triangles. */
25690 ret = QueryPerformanceCounter(&ts[0]);
25691 ok(ret, "Failed to read performance counter.\n");
25692 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
25693 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
25694 hr = IDirect3DDevice9_BeginScene(device);
25695 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
25696 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, tri_count);
25697 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
25698 hr = IDirect3DDevice9_EndScene(device);
25699 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
25700 colour = getPixelColor(device, 320, 240);
25701 /* Time drawing a single triangle. */
25702 ret = QueryPerformanceCounter(&ts[1]);
25703 ok(ret, "Failed to read performance counter.\n");
25704 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
25705 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
25706 hr = IDirect3DDevice9_BeginScene(device);
25707 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
25708 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 1);
25709 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
25710 hr = IDirect3DDevice9_EndScene(device);
25711 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
25712 colour = getPixelColor(device, 320, 240);
25713 ret = QueryPerformanceCounter(&ts[2]);
25714 ok(ret, "Failed to read performance counter.\n");
25716 IDirect3DVertexBuffer9_Release(buffer);
25718 /* Estimate the number of triangles we can draw in 100ms. */
25719 diff.QuadPart = ts[1].QuadPart - ts[0].QuadPart + ts[1].QuadPart - ts[2].QuadPart;
25720 tri_count = (tri_count * frequency.QuadPart) / (diff.QuadPart * 10);
25721 tri_count = ((tri_count + 2 + 3) & ~3) - 2;
25722 if (tri_count > caps.MaxPrimitiveCount)
25724 skip("Would need to draw %u triangles, but the device only supports %lu primitives.\n",
25725 tri_count, caps.MaxPrimitiveCount);
25726 goto done;
25728 size = (tri_count + 2) * sizeof(*quad1.strip);
25730 for (i = 0; i < ARRAY_SIZE(tests); ++i)
25732 hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
25733 D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &buffer, NULL);
25734 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#lx.\n", hr);
25735 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, size, (void **)&quads, D3DLOCK_DISCARD);
25736 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#lx.\n", hr);
25737 for (j = 0; j < size / sizeof(*quads); ++j)
25739 quads[j] = quad1;
25741 hr = IDirect3DVertexBuffer9_Unlock(buffer);
25742 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#lx.\n", hr);
25744 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(*quads->strip));
25745 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#lx.\n", hr);
25747 /* Start a draw operation. */
25748 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
25749 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
25750 hr = IDirect3DDevice9_BeginScene(device);
25751 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
25752 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, tri_count);
25753 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
25754 hr = IDirect3DDevice9_EndScene(device);
25755 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
25757 /* Map the last quad while the draw is in progress. */
25758 hr = IDirect3DVertexBuffer9_Lock(buffer, size - sizeof(quad2),
25759 sizeof(quad2), (void **)&quads, tests[i].flags);
25760 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#lx.\n", hr);
25761 *quads = quad2;
25762 hr = IDirect3DVertexBuffer9_Unlock(buffer);
25763 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#lx.\n", hr);
25765 colour = getPixelColor(device, 320, 240);
25766 unsynchronised = color_match(colour, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1);
25767 ok(tests[i].unsynchronised == unsynchronised, "Expected %s map for flags %#x.\n",
25768 tests[i].unsynchronised ? "unsynchronised" : "synchronised", tests[i].flags);
25770 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
25771 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
25773 IDirect3DVertexBuffer9_Release(buffer);
25776 done:
25777 refcount = IDirect3DDevice9_Release(device);
25778 ok(!refcount, "Device has %lu references left.\n", refcount);
25779 IDirect3D9_Release(d3d);
25780 DestroyWindow(window);
25783 static void test_color_vertex(void)
25785 IDirect3DDevice9 *device;
25786 unsigned int colour, i;
25787 D3DMATERIAL9 material;
25788 IDirect3D9 *d3d;
25789 ULONG refcount;
25790 HWND window;
25791 HRESULT hr;
25793 /* The idea here is to set up ambient light parameters in a way that the
25794 * ambient colour from the material is just passed through. The emissive
25795 * colour is just passed through anyway. The sum of ambient + emissive
25796 * should allow deduction of where the material colour came from.
25798 * Note that in cases without a D3DFVF_DIFFUSE flag the first colour value
25799 * in the struct will be fed into the specular vertex colour slot. */
25800 static const struct
25802 DWORD fvf, color_vertex, ambient, emissive;
25803 unsigned int result;
25805 tests[] =
25807 {D3DFVF_DIFFUSE | D3DFVF_SPECULAR, FALSE, D3DMCS_COLOR1, D3DMCS_COLOR2, 0x000000c0},
25809 {D3DFVF_DIFFUSE | D3DFVF_SPECULAR, TRUE, D3DMCS_COLOR1, D3DMCS_COLOR2, 0x00ffff00},
25810 {D3DFVF_DIFFUSE | D3DFVF_SPECULAR, TRUE, D3DMCS_MATERIAL, D3DMCS_COLOR2, 0x0000ff80},
25811 {D3DFVF_DIFFUSE | D3DFVF_SPECULAR, TRUE, D3DMCS_COLOR1, D3DMCS_MATERIAL, 0x00ff0040},
25812 {D3DFVF_DIFFUSE | D3DFVF_SPECULAR, TRUE, D3DMCS_COLOR1, D3DMCS_COLOR1, 0x00ff0000},
25813 {D3DFVF_DIFFUSE | D3DFVF_SPECULAR, TRUE, D3DMCS_COLOR2, D3DMCS_COLOR2, 0x0000ff00},
25815 {D3DFVF_SPECULAR, TRUE, D3DMCS_COLOR1, D3DMCS_COLOR2, 0x00ff0080},
25816 {D3DFVF_SPECULAR, TRUE, D3DMCS_COLOR1, D3DMCS_MATERIAL, 0x000000c0},
25817 {D3DFVF_SPECULAR, TRUE, D3DMCS_MATERIAL, D3DMCS_COLOR2, 0x00ff0080},
25818 {D3DFVF_DIFFUSE, TRUE, D3DMCS_COLOR1, D3DMCS_COLOR2, 0x00ff0040},
25819 {D3DFVF_DIFFUSE, TRUE, D3DMCS_COLOR1, D3DMCS_MATERIAL, 0x00ff0040},
25820 {D3DFVF_DIFFUSE, TRUE, D3DMCS_COLOR2, D3DMCS_MATERIAL, 0x000000c0},
25822 {0, TRUE, D3DMCS_COLOR1, D3DMCS_COLOR2, 0x000000c0},
25825 static const struct
25827 struct vec3 position;
25828 DWORD diffuse;
25829 DWORD specular;
25831 quad[] =
25833 {{-1.0f, -1.0f, 0.0f}, 0xffff0000, 0xff00ff00},
25834 {{-1.0f, 1.0f, 0.0f}, 0xffff0000, 0xff00ff00},
25835 {{ 1.0f, -1.0f, 0.0f}, 0xffff0000, 0xff00ff00},
25836 {{ 1.0f, 1.0f, 0.0f}, 0xffff0000, 0xff00ff00},
25839 window = create_window();
25840 ok(!!window, "Failed to create a window.\n");
25842 d3d = Direct3DCreate9(D3D_SDK_VERSION);
25843 ok(!!d3d, "Failed to create a D3D object.\n");
25844 if (!(device = create_device(d3d, window, window, TRUE)))
25846 skip("Failed to create a D3D device, skipping tests.\n");
25847 IDirect3D9_Release(d3d);
25848 DestroyWindow(window);
25849 return;
25852 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
25853 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
25854 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_AMBIENT, 0xffffffff);
25855 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
25857 memset(&material, 0, sizeof(material));
25858 material.Ambient.b = 0.5f;
25859 material.Emissive.b = 0.25f;
25860 hr = IDirect3DDevice9_SetMaterial(device, &material);
25861 ok(SUCCEEDED(hr), "Failed to set material, hr %#lx\n", hr);
25863 for (i = 0; i < ARRAY_SIZE(tests); ++i)
25865 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORVERTEX, tests[i].color_vertex);
25866 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
25867 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_AMBIENTMATERIALSOURCE, tests[i].ambient);
25868 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
25869 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_EMISSIVEMATERIALSOURCE, tests[i].emissive);
25870 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
25871 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | tests[i].fvf);
25872 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
25874 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x77777777, 0.0f, 0);
25875 ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#lx.\n", hr);
25877 hr = IDirect3DDevice9_BeginScene(device);
25878 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
25879 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
25880 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
25881 hr = IDirect3DDevice9_EndScene(device);
25882 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
25884 colour = getPixelColor(device, 320, 240);
25885 ok(color_match(colour, tests[i].result, 1),
25886 "Expected colour 0x%08x for test %u, got 0x%08x.\n",
25887 tests[i].result, i, colour);
25890 refcount = IDirect3DDevice9_Release(device);
25891 ok(!refcount, "Device has %lu references left.\n", refcount);
25892 IDirect3D9_Release(d3d);
25893 DestroyWindow(window);
25896 static void test_sysmem_draw(void)
25898 IDirect3DVertexBuffer9 *vb, *vb_s0, *vb_s1, *dst_vb, *get_vb;
25899 IDirect3DVertexDeclaration9 *vertex_declaration;
25900 unsigned int colour, i, offset, stride;
25901 IDirect3DTexture9 *texture;
25902 IDirect3DIndexBuffer9 *ib;
25903 IDirect3DDevice9 *device;
25904 struct vec4 *dst_data;
25905 D3DLOCKED_RECT lr;
25906 IDirect3D9 *d3d;
25907 ULONG refcount;
25908 HWND window;
25909 HRESULT hr;
25910 BYTE *data;
25912 static const DWORD texture_data[4] = {0xffff0000, 0xff00ff00, 0xff0000ff, 0xffffffff};
25913 static const D3DVERTEXELEMENT9 decl_elements[] =
25915 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
25916 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
25917 D3DDECL_END()
25919 static const struct
25921 struct vec3 position;
25922 DWORD diffuse;
25924 quad[] =
25926 {{-0.5f, -0.5f, 0.0f}, 0xffff0000},
25927 {{-0.5f, 0.5f, 0.0f}, 0xff00ff00},
25928 {{ 0.5f, -0.5f, 0.0f}, 0xff0000ff},
25929 {{ 0.5f, 0.5f, 0.0f}, 0xffffffff},
25931 static const struct vec3 quad_s0[] =
25933 {-1.0f, -1.0f, 0.0f},
25934 {-1.0f, 1.0f, 0.0f},
25935 { 1.0f, -1.0f, 0.0f},
25936 { 1.0f, 1.0f, 0.0f},
25938 {-1.0f, -1.0f, 0.0f},
25939 {-1.0f, 1.0f, 0.0f},
25940 { 1.0f, -1.0f, 0.0f},
25941 { 1.0f, 1.0f, 0.0f},
25943 static const DWORD quad_s1[] =
25945 0xffff0000,
25946 0xff00ff00,
25947 0xff0000ff,
25948 0xffffffff,
25950 0xff443322,
25951 0xff443322,
25952 0xff443322,
25953 0xff443322,
25955 static const short indices[] = {5, 6, 7, 8, 0, 1, 2, 3};
25957 window = create_window();
25958 ok(!!window, "Failed to create a window.\n");
25960 d3d = Direct3DCreate9(D3D_SDK_VERSION);
25961 ok(!!d3d, "Failed to create a D3D object.\n");
25962 if (!(device = create_device(d3d, window, window, TRUE)))
25964 skip("Failed to create a D3D device, skipping tests.\n");
25965 IDirect3D9_Release(d3d);
25966 DestroyWindow(window);
25967 return;
25970 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
25971 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
25973 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_SYSTEMMEM, &vb, NULL);
25974 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
25975 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **)&data, 0);
25976 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
25977 memcpy(data, quad, sizeof(quad));
25978 hr = IDirect3DVertexBuffer9_Unlock(vb);
25979 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
25981 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x77777777, 0.0f, 0);
25982 ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#lx.\n", hr);
25984 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
25985 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
25986 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(*quad));
25987 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
25989 hr = IDirect3DDevice9_BeginScene(device);
25990 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
25991 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
25992 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
25993 hr = IDirect3DDevice9_EndScene(device);
25994 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
25996 colour = getPixelColor(device, 320, 240);
25997 ok(color_match(colour, 0x00007f7f, 1), "Got unexpected colour 0x%08x.\n", colour);
25999 hr = IDirect3DDevice9_CreateVertexBuffer(device, ARRAY_SIZE(quad) * sizeof(*dst_data),
26000 0, D3DFVF_XYZRHW, D3DPOOL_SYSTEMMEM, &dst_vb, NULL);
26001 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26002 hr = IDirect3DDevice9_ProcessVertices(device, 0, 0, ARRAY_SIZE(quad), dst_vb, NULL, 0);
26003 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26004 hr = IDirect3DVertexBuffer9_Lock(dst_vb, 0, 0, (void **)&dst_data, 0);
26005 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26006 for (i = 0; i < ARRAY_SIZE(quad); ++i)
26008 ok(compare_vec4(&dst_data[i], quad[i].position.x * 320.0f + 320.0f,
26009 -quad[i].position.y * 240.0f + 240.0f, 0.0f, 1.0f, 1),
26010 "Got unexpected vertex %u {%.8e, %.8e, %.8e, %.8e}.\n",
26011 i, dst_data[i].x, dst_data[i].y, dst_data[i].z, dst_data[i].w);
26013 hr = IDirect3DVertexBuffer9_Unlock(dst_vb);
26014 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26016 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0,
26017 D3DFMT_INDEX16, D3DPOOL_SYSTEMMEM, &ib, NULL);
26018 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26019 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **)&data, 0);
26020 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26021 memcpy(data, indices, sizeof(indices));
26022 hr = IDirect3DIndexBuffer9_Unlock(ib);
26023 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26025 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x77777777, 0.0f, 0);
26026 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26028 hr = IDirect3DDevice9_SetIndices(device, ib);
26029 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26031 hr = IDirect3DDevice9_BeginScene(device);
26032 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26033 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 0, 4, 4, 2);
26034 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26035 hr = IDirect3DDevice9_EndScene(device);
26036 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26038 colour = getPixelColor(device, 320, 240);
26039 ok(color_match(colour, 0x00007f7f, 1), "Got unexpected colour 0x%08x.\n", colour);
26041 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
26042 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26043 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
26044 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26046 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_s0), 0, 0, D3DPOOL_SYSTEMMEM, &vb_s0, NULL);
26047 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26048 hr = IDirect3DVertexBuffer9_Lock(vb_s0, 0, sizeof(quad_s0), (void **)&data, 0);
26049 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26050 memcpy(data, quad_s0, sizeof(quad_s0));
26051 hr = IDirect3DVertexBuffer9_Unlock(vb_s0);
26052 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26053 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_s1), 0, 0, D3DPOOL_SYSTEMMEM, &vb_s1, NULL);
26054 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26055 hr = IDirect3DVertexBuffer9_Lock(vb_s1, 0, sizeof(quad_s1), (void **)&data, 0);
26056 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26057 memcpy(data, quad_s1, sizeof(quad_s1));
26058 hr = IDirect3DVertexBuffer9_Unlock(vb_s1);
26059 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26061 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_s0, 0, sizeof(*quad_s0));
26062 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26063 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb_s1, 0, sizeof(*quad_s1));
26064 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26066 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x77777777, 0.0f, 0);
26067 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26069 hr = IDirect3DDevice9_BeginScene(device);
26070 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26071 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 0, 4, 4, 2);
26072 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26073 hr = IDirect3DDevice9_EndScene(device);
26074 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26076 colour = getPixelColor(device, 320, 240);
26077 ok(color_match(colour, 0x00007f7f, 1), "Got unexpected colour 0x%08x.\n", colour);
26079 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x77777777, 0.0f, 0);
26080 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26082 hr = IDirect3DDevice9_BeginScene(device);
26083 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26084 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 0, 5, 4, 2);
26085 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26086 hr = IDirect3DDevice9_EndScene(device);
26087 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26089 colour = getPixelColor(device, 320, 240);
26090 ok(color_match(colour, 0x00443322, 1), "Got unexpected colour 0x%08x.\n", colour);
26092 /* Test that releasing but not unbinding a vertex buffer doesn't break. */
26093 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
26094 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26095 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(*quad));
26096 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26097 hr = IDirect3DDevice9_SetIndices(device, ib);
26098 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26100 refcount = IDirect3DVertexBuffer9_Release(vb_s1);
26101 ok(!refcount, "Unexpected refcount %lu.\n", refcount);
26102 hr = IDirect3DDevice9_GetStreamSource(device, 1, &get_vb, &offset, &stride);
26103 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
26104 ok(get_vb == vb_s1, "Got unexpected vertex buffer %p.\n", get_vb);
26105 refcount = IDirect3DVertexBuffer9_Release(get_vb);
26106 ok(!refcount, "Unexpected refcount %lu.\n", refcount);
26108 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x77777777, 0.0f, 0);
26109 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26111 hr = IDirect3DDevice9_BeginScene(device);
26112 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26113 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 0, 4, 4, 2);
26114 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26115 hr = IDirect3DDevice9_EndScene(device);
26116 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26118 colour = getPixelColor(device, 320, 240);
26119 ok(color_match(colour, 0x00007f7f, 1), "Got unexpected colour 0x%08x.\n", colour);
26121 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
26122 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26123 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_s0, 0, sizeof(*quad_s0));
26124 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26126 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x77777777, 0.0f, 0);
26127 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26129 hr = IDirect3DDevice9_BeginScene(device);
26130 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26131 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 0, 4, 4, 2);
26132 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26133 hr = IDirect3DDevice9_EndScene(device);
26134 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26136 colour = getPixelColor(device, 320, 240);
26137 ok(color_match(colour, 0x00007f7f, 1), "Got unexpected colour 0x%08x.\n", colour);
26139 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &texture, NULL);
26140 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26141 memset(&lr, 0, sizeof(lr));
26142 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
26143 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26144 memcpy(lr.pBits, texture_data, sizeof(texture_data));
26145 hr = IDirect3DTexture9_UnlockRect(texture, 0);
26146 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26148 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
26149 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26151 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x77777777, 0.0f, 0);
26152 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26154 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
26155 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26157 hr = IDirect3DDevice9_BeginScene(device);
26158 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26159 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
26160 ok(hr == D3D_OK || hr == E_FAIL, "Got unexpected hr %#lx.\n", hr);
26161 hr = IDirect3DDevice9_EndScene(device);
26162 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26164 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
26165 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26167 IDirect3DTexture9_Release(texture);
26168 IDirect3DVertexBuffer9_Release(vb_s0);
26169 IDirect3DVertexDeclaration9_Release(vertex_declaration);
26170 IDirect3DIndexBuffer9_Release(ib);
26171 IDirect3DVertexBuffer9_Release(dst_vb);
26172 IDirect3DVertexBuffer9_Release(vb);
26173 refcount = IDirect3DDevice9_Release(device);
26174 ok(!refcount, "Device has %lu references left.\n", refcount);
26175 IDirect3D9_Release(d3d);
26176 DestroyWindow(window);
26179 static void test_nrm_instruction(void)
26181 IDirect3DVertexDeclaration9 *vertex_declaration;
26182 IDirect3DVertexShader9 *vertex_shader;
26183 IDirect3DPixelShader9 *pixel_shader;
26184 unsigned int body_size, colour, i;
26185 IDirect3DDevice9 *device;
26186 IDirect3D9 *d3d;
26187 DWORD *ps_code;
26188 ULONG refcount;
26189 D3DCAPS9 caps;
26190 HWND window;
26191 HRESULT hr;
26193 static const D3DVERTEXELEMENT9 decl_elements[] =
26195 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
26196 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
26197 {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
26198 D3DDECL_END()
26200 static const struct
26202 struct vec3 position;
26203 struct vec2 t0;
26204 struct vec4 t1;
26206 quad[] =
26208 {{-1.0f, -1.0f, 0.1f}, {1.0f, 1.0f}, {0.0f, 1.0f, 0.3f, 0.5f}},
26209 {{ 1.0f, -1.0f, 0.1f}, {1.0f, 1.0f}, {0.0f, 1.0f, 0.3f, 0.5f}},
26210 {{-1.0f, 1.0f, 0.1f}, {1.0f, 1.0f}, {0.0f, 1.0f, 0.3f, 0.5f}},
26211 {{ 1.0f, 1.0f, 0.1f}, {1.0f, 1.0f}, {0.0f, 1.0f, 0.3f, 0.5f}},
26214 static const DWORD vs_code[] =
26216 0xfffe0300, /* vs_3_0 */
26217 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
26218 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
26219 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
26220 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
26221 0x0200001f, 0x80000005, 0xe00f0001, /* dcl_texcoord0 o1 */
26222 0x0200001f, 0x80010005, 0xe00f0002, /* dcl_texcoord1 o2 */
26223 0x0200001f, 0x80020005, 0xe00f0003, /* dcl_texcoord2 o3 */
26224 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
26225 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
26226 0x02000001, 0xe00f0002, 0x90e40002, /* mov o2, v2 */
26227 0x02000024, 0x800f0000, 0x90e40002, /* nrm r0, v2 */
26228 0x02000001, 0xe00f0003, 0x80e40000, /* mov o3, r0 */
26229 0x0000ffff,
26231 static const DWORD ps_header[] =
26233 0xffff0300, /* ps_3_0 */
26235 static const DWORD ps_footer[] =
26237 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
26238 0x0000ffff, /* end */
26240 static const DWORD nrm_t0[] =
26242 0x0200001f, 0x80000005, 0x90070001, /* dcl_texcoord0 v0.xyz */
26243 0x02000024, 0x800f0000, 0x90e40001, /* nrm r0, v0 */
26245 static const DWORD nrm_xyz_t0[] =
26247 0x0200001f, 0x80000005, 0x90070000, /* dcl_texcoord0 v0.xyz */
26248 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
26249 0x02000024, 0x80070000, 0x90e40000, /* nrm r0.xyz, v0 */
26250 0x02000001, 0x80040000, 0x80ff0000, /* mov r0.z, r0.w */
26252 static const DWORD nrm_t1[] =
26254 0x0200001f, 0x80010005, 0x900f0000, /* dcl_texcoord1 v0.xyzw */
26255 0x02000024, 0x800f0000, 0x90e40000, /* nrm r0, v0 */
26257 static const DWORD nrm_vs_t1[] =
26259 0x0200001f, 0x80020005, 0x900f0000, /* dcl_texcoord2 v0.xyzw */
26260 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
26262 static const DWORD nrm_t1_xyz[] =
26264 0x0200001f, 0x80010005, 0x900f0000, /* dcl_texcoord1 v0.xyzw */
26265 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
26266 0x02000024, 0x80070000, 0x90e40000, /* nrm r0.xyz, t1 */
26267 0x02000001, 0x80040000, 0x80ff0000, /* mov r0.z, r0.w */
26269 static const DWORD nrm_t1_xy[] =
26271 0x0200001f, 0x80010005, 0x900f0000, /* dcl_texcoord1 v0.xyzw */
26272 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
26273 0x02000024, 0x800f0000, 0x90540000, /* nrm r0, v0.xy */
26275 static const DWORD nrm_xyz_t1_yw[] =
26277 0x0200001f, 0x80010005, 0x900f0000, /* dcl_texcoord1 v0.xyzw */
26278 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
26279 0x02000024, 0x80070000, 0x90fd0000, /* nrm r0.xyz, v0.yw */
26281 static const DWORD nrm_t1_dcl_xy[] =
26283 0x0200001f, 0x80010005, 0x90030000, /* dcl_texcoord1 v0.xy */
26284 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
26285 0x02000024, 0x800f0000, 0x90540000, /* nrm r0, v0 */
26287 static const DWORD nrm_c0[] =
26289 0x02000024, 0x800f0000, 0xa0e40000, /* nrm r0, c0 */
26290 0x02000001, 0x80040000, 0x80ff0000, /* mov r0.z, r0.w */
26292 static const DWORD nrm_c0_swizzle[] =
26294 0x02000024, 0x800f0000, 0xa0390000, /* nrm r0, c0.yzwx */
26297 static const struct
26299 const char *name;
26300 const DWORD *ops;
26301 DWORD body_size;
26302 struct vec4 c0;
26303 unsigned int expected_colour;
26305 tests[] =
26307 {"nrm_t0", nrm_t0, ARRAY_SIZE(nrm_t0), {0.0f}, 0x00b4b400},
26308 {"nrm_xyz_t0", nrm_xyz_t0, ARRAY_SIZE(nrm_xyz_t0), {0.1f, 0.1f, 0.1f, 0.1f}, 0x00b4b419},
26309 {"nrm_t1", nrm_t1, ARRAY_SIZE(nrm_t1), {0.0f}, 0x0000f449},
26310 {"nrm_vs_t1", nrm_vs_t1, ARRAY_SIZE(nrm_vs_t1), {0.0f}, 0x0000f449},
26311 {"nrm_t1_xyz", nrm_t1_xyz, ARRAY_SIZE(nrm_t1_xyz), {0.1f, 0.1f, 0.1f, 0.1f}, 0x0000f419},
26312 {"nrm_t1_xy", nrm_t1_xy, ARRAY_SIZE(nrm_t1_xy), {0.1f, 0.1f, 0.1f, 0.1f}, 0x0000b4b4},
26313 {"nrm_xyz_t1_yw", nrm_xyz_t1_yw, ARRAY_SIZE(nrm_xyz_t1_yw), {0.1f, 0.1f, 0.1f, 0.1f}, 0x00d06868},
26314 {"nrm_t1_dcl_xy", nrm_t1_dcl_xy, ARRAY_SIZE(nrm_t1_dcl_xy), {0.1f, 0.1f, 0.1f, 0.1f}, 0x0000b4b4},
26315 {"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},
26316 {"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},
26317 {"nrm_vec4(1.0)", nrm_c0, ARRAY_SIZE(nrm_c0), {1.0f, 1.0f, 1.0f, 1.0f}, 0x00939393},
26318 {"nrm_c0_swizzle", nrm_c0_swizzle, ARRAY_SIZE(nrm_c0_swizzle), {1.0f, 1.0f, 0.0f, 2.0f}, 0x007200e4},
26321 window = create_window();
26322 ok(!!window, "Failed to create a window.\n");
26324 d3d = Direct3DCreate9(D3D_SDK_VERSION);
26325 ok(!!d3d, "Failed to create a D3D object.\n");
26326 if (!(device = create_device(d3d, window, window, TRUE)))
26328 skip("Failed to create a D3D device, skipping tests.\n");
26329 IDirect3D9_Release(d3d);
26330 DestroyWindow(window);
26331 return;
26334 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
26335 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26336 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
26338 skip("No shader model 3 support, skipping tests.\n");
26339 IDirect3DDevice9_Release(device);
26340 IDirect3D9_Release(d3d);
26341 DestroyWindow(window);
26342 return;
26345 body_size = 0;
26346 for (i = 0; i < ARRAY_SIZE(tests); ++i)
26347 body_size = max(body_size, tests[i].body_size);
26349 ps_code = malloc(sizeof(ps_header) + body_size * sizeof(*ps_code) + sizeof(ps_footer));
26350 memcpy(ps_code, ps_header, sizeof(ps_header));
26352 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
26353 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26354 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
26355 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26356 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
26357 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26358 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vertex_shader);
26359 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26360 hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader);
26361 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26362 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
26363 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26365 for (i = 0; i < ARRAY_SIZE(tests); ++i)
26367 memcpy(ps_code + ARRAY_SIZE(ps_header), tests[i].ops, sizeof(*ps_code) * tests[i].body_size);
26368 memcpy(ps_code + ARRAY_SIZE(ps_header) + tests[i].body_size, ps_footer, sizeof(ps_footer));
26370 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &pixel_shader);
26371 ok(hr == D3D_OK, "Got unexpected hr %#lx, test %s.\n", hr, tests[i].name);
26372 hr = IDirect3DDevice9_BeginScene(device);
26373 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26374 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80808080, 0.0f, 0);
26375 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26376 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
26377 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26378 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, &tests[i].c0.x, 1);
26379 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26380 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
26381 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26382 hr = IDirect3DDevice9_EndScene(device);
26383 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26385 colour = getPixelColor(device, 320, 240);
26386 ok(color_match(colour, tests[i].expected_colour, 1),
26387 "test %s, expected 0x%08x, got 0x%08x.\n",
26388 tests[i].name, tests[i].expected_colour, colour);
26390 IDirect3DPixelShader9_Release(pixel_shader);
26392 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
26393 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26395 free(ps_code);
26396 IDirect3DVertexShader9_Release(vertex_shader);
26397 IDirect3DVertexDeclaration9_Release(vertex_declaration);
26398 refcount = IDirect3DDevice9_Release(device);
26399 ok(!refcount, "Device has %lu references left.\n", refcount);
26400 IDirect3D9_Release(d3d);
26401 DestroyWindow(window);
26404 static void test_desktop_window(void)
26406 IDirect3DVertexShader9 *shader;
26407 IDirect3DDevice9 *device;
26408 unsigned int color;
26409 IDirect3D9 *d3d;
26410 ULONG refcount;
26411 HWND window;
26412 HRESULT hr;
26414 static const DWORD simple_vs[] =
26416 0xfffe0101, /* vs_1_1 */
26417 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
26418 0x00000009, 0xc0010000, 0x90e40000, 0xa0e40000, /* dp4 oPos.x, v0, c0 */
26419 0x00000009, 0xc0020000, 0x90e40000, 0xa0e40001, /* dp4 oPos.y, v0, c1 */
26420 0x00000009, 0xc0040000, 0x90e40000, 0xa0e40002, /* dp4 oPos.z, v0, c2 */
26421 0x00000009, 0xc0080000, 0x90e40000, 0xa0e40003, /* dp4 oPos.w, v0, c3 */
26422 0x0000ffff, /* end */
26425 window = create_window();
26426 d3d = Direct3DCreate9(D3D_SDK_VERSION);
26427 ok(!!d3d, "Failed to create a D3D object.\n");
26428 if (!(device = create_device(d3d, window, window, TRUE)))
26430 skip("Failed to create a D3D device, skipping tests.\n");
26431 IDirect3D9_Release(d3d);
26432 DestroyWindow(window);
26433 return;
26435 IDirect3DDevice9_Release(device);
26436 DestroyWindow(window);
26438 device = create_device(d3d, GetDesktopWindow(), GetDesktopWindow(), TRUE);
26439 ok(!!device, "Failed to create a D3D device.\n");
26441 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
26442 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
26443 color = getPixelColor(device, 1, 1);
26444 ok(color == 0x00ff0000, "Got unexpected color 0x%08x.\n", color);
26446 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
26447 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
26449 refcount = IDirect3DDevice9_Release(device);
26450 ok(!refcount, "Device has %lu references left.\n", refcount);
26452 /* test device with NULL HWND */
26453 device = create_device(d3d, NULL, NULL, TRUE);
26454 ok(device != NULL, "Failed to create a D3D device\n");
26456 hr = IDirect3DDevice9_CreateVertexShader(device, simple_vs, &shader);
26457 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#lx.\n", hr);
26458 IDirect3DVertexShader9_Release(shader);
26460 IDirect3DDevice9_Release(device);
26462 IDirect3D9_Release(d3d);
26465 static void test_mismatched_sample_types_fill_texture(DWORD *bits, unsigned int pitch, D3DCOLOR colour,
26466 unsigned int size)
26468 unsigned int x, y;
26470 for (y = 0; y < size; ++y)
26472 DWORD *ptr = (DWORD *)(((BYTE *)bits) + (y * pitch));
26474 for (x = 0; x < size; ++x)
26475 *ptr++ = colour;
26479 static void test_mismatched_sample_types(void)
26481 /* MSDN suggests that sampling a texture with fewer dimensions than sampler has
26482 * is allowed while the opposite is not.
26483 * AMD, Intel, WARP return sampled texture values in both cases. The use of W
26484 * coordinate when sampling 3d texture with 2d sampler looks not entirely consistent.
26485 * Nvidia returns zero texture values for both cases while that is different
26486 * from unbound texture result (0, 0, 0, 1): it is (0, 0, 0, 0) for RGBA texture or,
26487 * in a general case, result of a fixup of zero texture color, e. g., (0, 0, 1, 1)
26488 * for D3DFMT_G16R16 texture. */
26490 IDirect3DVertexDeclaration9 *vertex_declaration;
26491 static IDirect3DPixelShader9 *ps_2d, *ps_3d;
26492 static IDirect3DVolumeTexture9 *volume;
26493 IDirect3DVertexShader9 *vertex_shader;
26494 static IDirect3DTexture9 *tex_2d;
26495 unsigned int colour, i, r, g, b;
26496 D3DLOCKED_RECT locked_rect;
26497 D3DLOCKED_BOX locked_box;
26498 IDirect3DDevice9 *device;
26499 IDirect3D9 *d3d;
26500 ULONG refcount;
26501 D3DCAPS9 caps;
26502 HWND window;
26503 HRESULT hr;
26505 static const D3DVERTEXELEMENT9 decl_elements[] =
26507 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
26508 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
26509 D3DDECL_END()
26511 static const struct
26513 struct vec3 position;
26514 struct vec3 t0;
26516 quad[] =
26518 {{-1.0f, -1.0f, 0.1f}, {0.0f, 0.0f, 0.0f}},
26519 {{-1.0f, 1.0f, 0.1f}, {0.0f, 1.0f, 0.5f}},
26520 {{ 1.0f, -1.0f, 0.1f}, {1.0f, 0.0f, 0.5f}},
26521 {{ 1.0f, 1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}},
26524 static const DWORD vs_code[] =
26526 0xfffe0300, /* vs_3_0 */
26527 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
26528 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
26529 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
26530 0x0200001f, 0x80000005, 0xe00f0001, /* dcl_texcoord0 o1 */
26531 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
26532 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
26533 0x0000ffff, /* end */
26536 static const DWORD ps_header[] =
26538 0xffff0300, /* ps_3_0 */
26539 0x05000051, 0xa00f0000, 0x3f333333, 0x3f4ccccd, 0x3f666666, 0x00000000,
26540 /* def c0, 0.7, 0.8, 0.9, 0.0 */
26542 static const DWORD ps_footer[] =
26544 0x03000042, 0x800f0001, 0x90e40000, 0xa0e40800, /* texld r1, v0, s0 */
26545 0x02020029, 0x80ff0001, 0xa0ff0000, /* if_eq r1.w, c0.w */
26546 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
26547 0x0000002b, /* endif */
26548 0x02000001, 0x800f0800, 0x80e40001, /* mov oC0, r1 */
26549 0x0000ffff, /* end */
26552 #define TEST_MISMATCHED_SAMPLE_BODY_WORDS 6
26554 static const DWORD ps_tex_2d[TEST_MISMATCHED_SAMPLE_BODY_WORDS] =
26556 0x0200001f, 0x80000005, 0x90030000, /* dcl_texcoord0 v0.xy */
26557 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
26559 static const DWORD ps_tex_3d[TEST_MISMATCHED_SAMPLE_BODY_WORDS] =
26561 0x0200001f, 0x80000005, 0x90070000, /* dcl_texcoord0 v0.xyz */
26562 0x0200001f, 0xa0000000, 0xa00f0800, /* dcl_volume s0 */
26565 static DWORD ps_code[ARRAY_SIZE(ps_header) + TEST_MISMATCHED_SAMPLE_BODY_WORDS + ARRAY_SIZE(ps_footer)];
26567 #define SAMPLE_ZERO 0x1
26568 #define RANDOM_W 0x2
26569 static const struct
26571 const char *name;
26572 IDirect3DBaseTexture9 **texture;
26573 IDirect3DPixelShader9 **pixel_shader;
26574 unsigned int expected_colour;
26575 unsigned int broken;
26577 tests[] =
26579 {"2d_2d", (IDirect3DBaseTexture9 **)&tex_2d, &ps_2d, 0x00707070},
26580 {"3d_3d", (IDirect3DBaseTexture9 **)&volume, &ps_3d, 0x00303030},
26581 /* Star Wars: The Old Republic uses mismatched samplers for rendering water. */
26582 {"2d_3d", (IDirect3DBaseTexture9 **)&tex_2d, &ps_3d, 0x00707070, SAMPLE_ZERO},
26583 {"3d_2d", (IDirect3DBaseTexture9 **)&volume, &ps_2d, 0x00303030, SAMPLE_ZERO | RANDOM_W},
26586 window = create_window();
26587 ok(!!window, "Failed to create a window.\n");
26589 d3d = Direct3DCreate9(D3D_SDK_VERSION);
26590 ok(!!d3d, "Failed to create a D3D object.\n");
26591 if (!(device = create_device(d3d, window, window, TRUE)))
26593 skip("Failed to create a D3D device, skipping tests.\n");
26594 IDirect3D9_Release(d3d);
26595 DestroyWindow(window);
26596 return;
26599 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
26600 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26601 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
26603 skip("No shader model 3 support, skipping tests.\n");
26604 goto done;
26606 if (!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP))
26608 skip("No volume texture support, skipping tests.\n");
26609 goto done;
26612 hr = IDirect3DDevice9_CreateVolumeTexture(device, 2, 2, 2, 1, 0, D3DFMT_A8R8G8B8,
26613 D3DPOOL_MANAGED, &volume, NULL);
26614 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26616 hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &locked_box, NULL, 0);
26617 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26618 test_mismatched_sample_types_fill_texture(locked_box.pBits, locked_box.RowPitch, 0x20202020, 2);
26619 test_mismatched_sample_types_fill_texture((DWORD *)((BYTE *)locked_box.pBits + locked_box.SlicePitch),
26620 locked_box.RowPitch, 0x40404040, 2);
26621 hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
26622 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26624 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8,
26625 D3DPOOL_MANAGED, &tex_2d, NULL);
26626 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26628 hr = IDirect3DTexture9_LockRect(tex_2d, 0, &locked_rect, NULL, 0);
26629 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26630 test_mismatched_sample_types_fill_texture(locked_rect.pBits, locked_rect.Pitch, 0x70707070, 2);
26631 hr = IDirect3DTexture9_UnlockRect(tex_2d, 0);
26632 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26634 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
26635 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26636 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
26637 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26638 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
26639 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26640 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vertex_shader);
26641 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26642 hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader);
26643 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26645 memcpy(ps_code, ps_header, sizeof(ps_header));
26646 memcpy(ps_code + ARRAY_SIZE(ps_header) + TEST_MISMATCHED_SAMPLE_BODY_WORDS, ps_footer, sizeof(ps_footer));
26648 memcpy(ps_code + ARRAY_SIZE(ps_header), ps_tex_2d,
26649 sizeof(*ps_code) * TEST_MISMATCHED_SAMPLE_BODY_WORDS);
26650 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps_2d);
26651 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26653 memcpy(ps_code + ARRAY_SIZE(ps_header), ps_tex_3d,
26654 sizeof(*ps_code) * TEST_MISMATCHED_SAMPLE_BODY_WORDS);
26655 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps_3d);
26656 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26658 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
26659 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26661 for (i = 0; i < ARRAY_SIZE(tests); ++i)
26663 hr = IDirect3DDevice9_BeginScene(device);
26664 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26665 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80808080, 0.0f, 0);
26666 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26668 hr = IDirect3DDevice9_SetTexture(device, 0, *tests[i].texture);
26669 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26670 hr = IDirect3DDevice9_SetPixelShader(device, *tests[i].pixel_shader);
26671 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26673 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
26674 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26675 hr = IDirect3DDevice9_EndScene(device);
26676 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26678 colour = getPixelColor(device, 320, 240);
26680 /* If texld returns zero, the test writes vec4(0.7, 0.8, 0.9, 0.0) - 0x00b2cce5.
26682 * When sampling the 3D texture with a 2D sampler, most drivers sample at the depth
26683 * coordinate we provide (0.5), but some use 0.0, while my radeon GPU uses 0.89. */
26684 r = (colour & 0x00ff0000) >> 16;
26685 g = (colour & 0x0000ff00) >> 8;
26686 b = (colour & 0x000000ff);
26687 todo_wine_if(!color_match(colour, tests[i].expected_colour, 1))
26688 ok(color_match(colour, tests[i].expected_colour, 1)
26689 || broken((tests[i].broken & SAMPLE_ZERO) && color_match(colour, 0x00b2cce5, 1))
26690 || broken((tests[i].broken & RANDOM_W) && r >= 0x1f && r <= 0x41 && r == g && r == b),
26691 "test %s, expected 0x%08x, got 0x%08x.\n",
26692 tests[i].name, tests[i].expected_colour, colour);
26694 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
26695 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26697 IDirect3DPixelShader9_Release(ps_2d);
26698 IDirect3DPixelShader9_Release(ps_3d);
26700 IDirect3DVertexShader9_Release(vertex_shader);
26701 IDirect3DVertexDeclaration9_Release(vertex_declaration);
26702 IDirect3DVolumeTexture9_Release(volume);
26703 IDirect3DTexture9_Release(tex_2d);
26705 done:
26706 refcount = IDirect3DDevice9_Release(device);
26707 ok(!refcount, "Device has %lu references left.\n", refcount);
26708 IDirect3D9_Release(d3d);
26709 DestroyWindow(window);
26711 #undef SAMPLE_ZERO
26712 #undef RANDOM_W
26715 static void test_draw_mapped_buffer(void)
26717 IDirect3DVertexBuffer9 *vb;
26718 IDirect3DIndexBuffer9 *ib;
26719 IDirect3DDevice9 *device;
26720 unsigned int color, i;
26721 IDirect3D9 *d3d;
26722 ULONG refcount;
26723 BOOL test_pass;
26724 HWND window;
26725 HRESULT hr;
26726 void *data;
26728 static const short indices[] = {0, 1, 2};
26729 static const struct
26731 struct vec3 position;
26732 DWORD diffuse;
26734 quad[] =
26736 {{-1.0f, -1.0f, 0.1f}, 0xffff0000},
26737 {{-1.0f, 1.0f, 0.1f}, 0xffff0000},
26738 {{ 1.0f, 1.0f, 0.1f}, 0xffff0000},
26740 static const struct
26742 D3DPOOL pool;
26743 DWORD usage;
26744 BOOL ignore_wine_result;
26746 tests[] =
26748 {D3DPOOL_DEFAULT, D3DUSAGE_DYNAMIC, TRUE},
26749 {D3DPOOL_MANAGED, 0},
26750 {D3DPOOL_SYSTEMMEM, 0},
26753 window = create_window();
26754 ok(!!window, "Failed to create a window.\n");
26756 d3d = Direct3DCreate9(D3D_SDK_VERSION);
26757 ok(!!d3d, "Failed to create a D3D object.\n");
26758 if (!(device = create_device(d3d, window, window, TRUE)))
26760 skip("Failed to create a D3D device, skipping tests.\n");
26761 IDirect3D9_Release(d3d);
26762 DestroyWindow(window);
26763 return;
26766 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
26767 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26768 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
26769 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26771 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0,
26772 D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
26773 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26774 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), &data, 0);
26775 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26776 memcpy(data, indices, sizeof(indices));
26778 hr = IDirect3DDevice9_SetIndices(device, ib);
26779 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26781 for (i = 0; i < ARRAY_SIZE(tests); ++i)
26783 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), tests[i].usage,
26784 D3DFVF_XYZ | D3DFVF_DIFFUSE, tests[i].pool, &vb, NULL);
26785 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26786 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), &data, 0);
26787 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26788 memcpy(data, quad, sizeof(quad));
26790 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
26791 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26793 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
26794 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26795 hr = IDirect3DDevice9_BeginScene(device);
26796 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26797 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, ARRAY_SIZE(quad), 0, 1);
26798 ok(hr == D3D_OK, "Got unexpected hr %#lx, test %u.\n", hr, i);
26799 hr = IDirect3DDevice9_EndScene(device);
26800 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26802 color = getPixelColor(device, 160, 120);
26803 ok(color_match(color, 0x00ff0000, 1), "Got unexpected color 0x%08x, test %u.\n", color, i);
26804 color = getPixelColor(device, 480, 360);
26805 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x, test %u.\n", color, i);
26807 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
26808 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26810 hr = IDirect3DVertexBuffer9_Unlock(vb);
26811 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26813 /* One more time now when buffer object in wined3d is already created. */
26814 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), &data, D3DLOCK_DISCARD);
26815 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26816 memcpy(data, quad, sizeof(quad));
26818 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
26819 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26820 hr = IDirect3DDevice9_BeginScene(device);
26821 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26822 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, ARRAY_SIZE(quad), 0, 1);
26823 ok(hr == D3D_OK, "Got unexpected hr %#lx, test %u.\n", hr, i);
26824 hr = IDirect3DDevice9_EndScene(device);
26825 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26827 color = getPixelColor(device, 160, 120);
26829 test_pass = color_match(color, 0x00ff0000, 1);
26830 todo_wine_if(tests[i].ignore_wine_result && !test_pass)
26831 ok(test_pass, "Got unexpected color 0x%08x, test %u.\n", color, i);
26833 color = getPixelColor(device, 480, 360);
26834 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x, test %u.\n", color, i);
26836 hr = IDirect3DVertexBuffer9_Unlock(vb);
26837 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26838 IDirect3DVertexBuffer9_Release(vb);
26841 hr = IDirect3DIndexBuffer9_Unlock(ib);
26842 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26844 IDirect3DIndexBuffer9_Release(ib);
26845 refcount = IDirect3DDevice9_Release(device);
26846 ok(!refcount, "Device has %lu references left.\n", refcount);
26848 IDirect3D9_Release(d3d);
26849 DestroyWindow(window);
26852 static void test_sample_attached_rendertarget(void)
26854 D3DADAPTER_IDENTIFIER9 identifier;
26855 IDirect3DQuery9 *event_query;
26856 IDirect3DTexture9 *texture;
26857 IDirect3DVertexBuffer9 *vb;
26858 IDirect3DPixelShader9 *ps;
26859 IDirect3DDevice9 *device;
26860 IDirect3DSurface9 *rt;
26861 unsigned int color, i;
26862 IDirect3D9 *d3d;
26863 ULONG refcount;
26864 BOOL is_warp;
26865 HWND window;
26866 HRESULT hr;
26867 void *data;
26869 static const struct
26871 struct vec3 position;
26872 struct vec2 texcoord;
26874 quad[] =
26876 {{-1.0f, -1.0f, 0.1f}, {0.0f, 0.0f}},
26877 {{-1.0f, 1.0f, 0.1f}, {0.0f, 1.0f}},
26878 {{ 1.0f, -1.0f, 0.0f}, {1.0f, 0.0f}},
26879 {{ 1.0f, 1.0f, 0.1f}, {1.0f, 1.0f}},
26882 static const DWORD pixel_shader_code[] =
26884 0xffff0200, /* ps_2_0 */
26885 0x05000051, 0xa00f0000, 0x3e800000, 0x3e800000, 0x3e800000, 0x3e800000,
26886 /* def c0, 0.25, 0.25, 0.25, 0.25 */
26887 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
26888 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
26889 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
26890 0x03000002, 0x800f0000, 0x80e40000, 0xa0e40000, /* add r0, r0, c0 */
26891 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
26892 0x0000ffff
26895 window = create_window();
26896 ok(!!window, "Failed to create a window.\n");
26898 d3d = Direct3DCreate9(D3D_SDK_VERSION);
26899 ok(!!d3d, "Failed to create a D3D object.\n");
26901 hr = IDirect3D9_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
26902 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26903 is_warp = adapter_is_warp(&identifier);
26905 if (!(device = create_device(d3d, window, window, TRUE)))
26907 skip("Failed to create a D3D device, skipping tests.\n");
26908 IDirect3D9_Release(d3d);
26909 DestroyWindow(window);
26910 return;
26913 hr = IDirect3DDevice9_CreateQuery(device, D3DQUERYTYPE_EVENT, NULL);
26914 if (hr == D3DERR_NOTAVAILABLE)
26916 /* Without synchronization native d3d seems to show race condition on
26917 * render target update, similar to opengl without using texture barrier. */
26918 skip("Event queries are not supported, skipping test.\n");
26919 IDirect3DDevice9_Release(device);
26920 IDirect3D9_Release(d3d);
26921 DestroyWindow(window);
26922 return;
26925 hr = IDirect3DDevice9_CreateQuery(device, D3DQUERYTYPE_EVENT, &event_query);
26926 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26928 hr = IDirect3DQuery9_Issue(event_query, D3DISSUE_END);
26929 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26931 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), D3DUSAGE_DYNAMIC,
26932 D3DFVF_XYZ | D3DFVF_TEX1, D3DPOOL_DEFAULT, &vb, NULL);
26933 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26934 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), &data, 0);
26935 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26936 memcpy(data, quad, sizeof(quad));
26937 hr = IDirect3DVertexBuffer9_Unlock(vb);
26938 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26940 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
26941 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26943 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
26944 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26945 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
26946 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26947 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
26948 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26950 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET,
26951 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
26952 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26953 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &rt);
26954 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26956 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
26957 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26959 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
26960 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26962 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x01010101, 0.0, 0);
26963 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26964 check_rt_color(rt, 0x00010101);
26966 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &ps);
26967 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26969 hr = IDirect3DDevice9_BeginScene(device);
26970 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26972 hr = IDirect3DDevice9_SetPixelShader(device, ps);
26973 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26975 for (i = 0; i < 3; ++i)
26977 wait_query(event_query);
26979 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
26980 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26981 hr = IDirect3DQuery9_Issue(event_query, D3DISSUE_END);
26982 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26985 hr = IDirect3DDevice9_EndScene(device);
26986 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26988 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
26989 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
26991 color = getPixelColor(device, 0, 0);
26992 if (is_warp || color == 0x00010101)
26993 skip("Sampling attached render targets is not supported.\n");
26994 else
26996 unsigned int expected_color = 0x00c1c1c1;
26997 unsigned int color = check_expected_rt_color(__LINE__, rt, expected_color);
26998 todo_wine_if(color != expected_color)
26999 ok(color == expected_color, "Got unexpected color 0x%08x.\n", color);
27002 IDirect3DQuery9_Release(event_query);
27004 IDirect3DVertexBuffer9_Release(vb);
27006 IDirect3DPixelShader9_Release(ps);
27007 IDirect3DSurface9_Release(rt);
27008 IDirect3DTexture9_Release(texture);
27010 refcount = IDirect3DDevice9_Release(device);
27011 ok(!refcount, "Device has %lu references left.\n", refcount);
27013 IDirect3D9_Release(d3d);
27014 DestroyWindow(window);
27017 static void test_alpha_to_coverage(void)
27019 static const struct
27021 struct vec3 position;
27022 struct vec2 texcoord;
27024 quad[] =
27026 {{-1.0f, -1.0f, 0.1f}, {0.0f, 0.0f}},
27027 {{-1.0f, 1.0f, 0.1f}, {0.0f, 1.0f}},
27028 {{ 1.0f, -1.0f, 0.1f}, {1.0f, 0.0f}},
27029 {{ 1.0f, 1.0f, 0.1f}, {1.0f, 1.0f}},
27032 IDirect3DSurface9 *rt, *ms_rt, *surface;
27033 D3DADAPTER_IDENTIFIER9 identifier;
27034 struct surface_readback rb;
27035 IDirect3DTexture9 *texture;
27036 IDirect3DStateBlock9 *sb;
27037 IDirect3DDevice9 *device;
27038 DWORD quality_levels;
27039 unsigned int colour;
27040 BOOL nvidia_mode;
27041 IDirect3D9 *d3d;
27042 ULONG refcount;
27043 HWND window;
27044 HRESULT hr;
27046 window = create_window();
27047 d3d = Direct3DCreate9(D3D_SDK_VERSION);
27048 ok(!!d3d, "Failed to create a D3D object.\n");
27050 if (IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
27051 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, &quality_levels) == D3DERR_NOTAVAILABLE)
27053 skip("Multisampling not supported for D3DFMT_A8R8G8B8.\n");
27054 IDirect3D9_Release(d3d);
27055 DestroyWindow(window);
27056 return;
27059 if (!(device = create_device(d3d, window, window, TRUE)))
27061 skip("Failed to create a 3D device.\n");
27062 IDirect3D9_Release(d3d);
27063 DestroyWindow(window);
27064 return;
27068 hr = IDirect3D9_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
27069 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27071 if (adapter_is_amd(&identifier))
27073 nvidia_mode = FALSE;
27075 else
27077 /* The ATOC pseudo format is introduced by NVIDIA. Some Intel GPUs
27078 * support alpha to coverage the same way as NVIDIA. */
27079 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
27080 D3DRTYPE_SURFACE, MAKEFOURCC('A','T','O','C')) != D3D_OK)
27082 win_skip("Alpha to coverage is not supported.\n");
27083 refcount = IDirect3DDevice9_Release(device);
27084 ok(!refcount, "Device has %lu references left.\n", refcount);
27085 IDirect3D9_Release(d3d);
27086 DestroyWindow(window);
27087 return;
27089 nvidia_mode = TRUE;
27092 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128,
27093 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
27094 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27095 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128,
27096 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &ms_rt, NULL);
27097 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27099 hr = IDirect3DDevice9_SetRenderTarget(device, 0, ms_rt);
27100 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27101 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
27102 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27104 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8,
27105 D3DPOOL_DEFAULT, &texture, NULL);
27106 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27108 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
27109 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27111 hr = IDirect3DDevice9_BeginScene(device);
27112 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27114 fill_surface(surface, 0xff2000ff, 0);
27116 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
27117 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27118 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
27119 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27121 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0f, 0);
27122 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27124 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
27125 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27126 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
27127 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27129 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
27130 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27132 if (nvidia_mode)
27134 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Y, MAKEFOURCC('A','T','O','C'));
27135 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27137 /* While undocumented, Nvidia also requires to enable alpha test to enable
27138 * alpha to coverage. Intel does not. */
27139 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
27140 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27142 else
27144 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, MAKEFOURCC('A','2','M','1'));
27145 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27148 hr = IDirect3DDevice9_CreateStateBlock(device, D3DSBT_VERTEXSTATE, &sb);
27149 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27151 fill_surface(surface, 0x40608000, 0);
27153 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
27154 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27156 hr = IDirect3DDevice9_StretchRect(device, ms_rt, NULL, rt, NULL, D3DTEXF_POINT);
27157 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27158 get_rt_readback(rt, &rb);
27159 colour = get_readback_color(&rb, 64, 64);
27161 /* NVIDIA is probably using some proprietary algorithm for averaging sample colour values. */
27162 ok(color_match(colour, 0x9f404080, 1) || color_match(colour, 0x9f485cbc, 1) /* NVIDIA */,
27163 "Got unexpected colour %08x.\n", colour);
27164 release_surface_readback(&rb);
27166 if (nvidia_mode)
27168 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Y, D3DFMT_UNKNOWN);
27169 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27171 else
27173 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, MAKEFOURCC('A','2','M','0'));
27174 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27177 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
27178 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27180 hr = IDirect3DDevice9_StretchRect(device, ms_rt, NULL, rt, NULL, D3DTEXF_POINT);
27181 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27182 get_rt_readback(rt, &rb);
27183 colour = get_readback_color(&rb, 64, 64);
27184 ok(colour == 0x40608000, "Got unexpected colour %08x.\n", colour);
27185 release_surface_readback(&rb);
27187 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff2000ff, 0.0f, 0);
27188 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27190 IDirect3DStateBlock9_Apply(sb);
27191 IDirect3DStateBlock9_Release(sb);
27193 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
27194 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27196 hr = IDirect3DDevice9_StretchRect(device, ms_rt, NULL, rt, NULL, D3DTEXF_POINT);
27197 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27198 get_rt_readback(rt, &rb);
27199 colour = get_readback_color(&rb, 64, 64);
27200 ok(color_match(colour, 0x9f404080, 1) || color_match(colour, 0x9f485cbc, 1) /* Nvidia */,
27201 "Got unexpected colour %08x.\n", colour);
27202 release_surface_readback(&rb);
27204 hr = IDirect3DDevice9_EndScene(device);
27205 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27206 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
27207 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27209 IDirect3DSurface9_Release(surface);
27210 IDirect3DTexture9_Release(texture);
27211 IDirect3DSurface9_Release(ms_rt);
27212 IDirect3DSurface9_Release(rt);
27213 refcount = IDirect3DDevice9_Release(device);
27214 ok(!refcount, "Device has %lu references left.\n", refcount);
27215 IDirect3D9_Release(d3d);
27216 DestroyWindow(window);
27219 static void test_sample_mask(void)
27221 IDirect3DSurface9 *rt, *ms_rt;
27222 struct surface_readback rb;
27223 IDirect3DDevice9 *device;
27224 unsigned int colour;
27225 IDirect3D9 *d3d;
27226 ULONG refcount;
27227 HWND window;
27228 HRESULT hr;
27230 static const struct
27232 struct vec3 position;
27233 DWORD diffuse;
27235 quad[] =
27237 {{-1.0f, -1.0f, 0.1f}, 0xffffffff},
27238 {{-1.0f, 1.0f, 0.1f}, 0xffffffff},
27239 {{ 1.0f, -1.0f, 0.1f}, 0xffffffff},
27240 {{ 1.0f, 1.0f, 0.1f}, 0xffffffff},
27243 window = create_window();
27244 d3d = Direct3DCreate9(D3D_SDK_VERSION);
27245 ok(!!d3d, "Failed to create a D3D object.\n");
27247 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
27248 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
27250 skip("Multisampling not supported for D3DFMT_A8R8G8B8.\n");
27251 IDirect3D9_Release(d3d);
27252 DestroyWindow(window);
27253 return;
27256 if (!(device = create_device(d3d, window, window, TRUE)))
27258 skip("Failed to create a 3D device.\n");
27259 IDirect3D9_Release(d3d);
27260 DestroyWindow(window);
27261 return;
27264 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128,
27265 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
27266 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27267 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128,
27268 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &ms_rt, NULL);
27269 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27271 hr = IDirect3DDevice9_SetRenderTarget(device, 0, ms_rt);
27272 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27273 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
27274 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27276 hr = IDirect3DDevice9_BeginScene(device);
27277 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27279 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
27280 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27281 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_MULTISAMPLEMASK, 0x5);
27282 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27284 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0f, 0);
27285 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27286 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
27287 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27288 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
27289 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27291 hr = IDirect3DDevice9_StretchRect(device, ms_rt, NULL, rt, NULL, D3DTEXF_POINT);
27292 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27293 get_rt_readback(rt, &rb);
27294 colour = get_readback_color(&rb, 64, 64);
27295 /* Multiple generations of Nvidia cards return broken results.
27296 * A mask with no bits or all bits set produce the expected results (0x00 / 0xff),
27297 * but any other mask behaves almost as if the result is 0.5 + (enabled / total)
27298 * samples. It's not quite that though (you'd expect 0xbf or 0xc0 instead of 0xbc).
27300 * I looked at a few other possible problems: Incorrectly enabled Z test, alpha test,
27301 * culling, the multisample mask affecting CopyRects. Neither of these make a difference. */
27302 ok(color_match(colour, 0xffff8080, 1) || broken(color_match(colour, 0xffffbcbc, 1)),
27303 "Got unexpected colour %08x.\n", colour);
27304 release_surface_readback(&rb);
27306 hr = IDirect3DDevice9_EndScene(device);
27307 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27309 IDirect3DSurface9_Release(ms_rt);
27310 IDirect3DSurface9_Release(rt);
27311 refcount = IDirect3DDevice9_Release(device);
27312 ok(!refcount, "Device has %lu references left.\n", refcount);
27313 IDirect3D9_Release(d3d);
27314 DestroyWindow(window);
27317 struct dynamic_vb_vertex
27319 struct vec3 position;
27320 DWORD diffuse;
27323 static void fill_dynamic_vb_quad(struct dynamic_vb_vertex *quad, unsigned int x, unsigned int y)
27325 unsigned int i;
27327 memset(quad, 0, 4 * sizeof(*quad));
27329 quad[0].position.x = quad[1].position.x = -1.0f + 0.01f * x;
27330 quad[2].position.x = quad[3].position.x = -1.0f + 0.01f * (x + 1);
27332 quad[0].position.y = quad[2].position.y = -1.0f + 0.01f * y;
27333 quad[1].position.y = quad[3].position.y = -1.0f + 0.01f * (y + 1);
27335 for (i = 0; i < 4; ++i)
27336 quad[i].diffuse = 0xff00ff00;
27339 static void test_dynamic_map_synchronization(void)
27341 IDirect3DVertexBuffer9 *buffer;
27342 IDirect3DDevice9 *device;
27343 IDirect3DSurface9 *rt;
27344 unsigned int x, y;
27345 IDirect3D9 *d3d;
27346 ULONG refcount;
27347 HWND window;
27348 HRESULT hr;
27349 void *data;
27351 window = create_window();
27352 d3d = Direct3DCreate9(D3D_SDK_VERSION);
27353 ok(!!d3d, "Failed to create a D3D object.\n");
27354 if (!(device = create_device(d3d, window, window, TRUE)))
27356 skip("Failed to create a D3D device, skipping tests.\n");
27357 IDirect3D9_Release(d3d);
27358 DestroyWindow(window);
27359 return;
27362 hr = IDirect3DDevice9_CreateVertexBuffer(device, 200 * 4 * sizeof(struct dynamic_vb_vertex),
27363 D3DUSAGE_DYNAMIC, D3DFVF_XYZ, D3DPOOL_DEFAULT, &buffer, NULL);
27364 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27366 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0f, 0);
27367 ok(hr == D3D_OK, "Failed to clear, hr %#lx.\n", hr);
27369 hr = IDirect3DDevice9_BeginScene(device);
27370 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27371 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(struct dynamic_vb_vertex));
27372 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27373 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
27374 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27375 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
27376 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27377 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
27378 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27380 for (y = 0; y < 200; ++y)
27382 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, 0, &data, D3DLOCK_DISCARD);
27383 ok(hr == D3D_OK, "Failed to map buffer, hr %#lx.\n", hr);
27385 fill_dynamic_vb_quad(data, 0, y);
27387 hr = IDirect3DVertexBuffer9_Unlock(buffer);
27388 ok(hr == D3D_OK, "Failed to map buffer, hr %#lx.\n", hr);
27390 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
27391 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27393 for (x = 1; x < 200; ++x)
27395 hr = IDirect3DVertexBuffer9_Lock(buffer, 4 * sizeof(struct dynamic_vb_vertex) * x,
27396 4 * sizeof(struct dynamic_vb_vertex), &data, D3DLOCK_NOOVERWRITE);
27397 ok(hr == D3D_OK, "Failed to map buffer, hr %#lx.\n", hr);
27399 fill_dynamic_vb_quad(data, x, y);
27401 hr = IDirect3DVertexBuffer9_Unlock(buffer);
27402 ok(hr == D3D_OK, "Failed to map buffer, hr %#lx.\n", hr);
27404 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4 * x, 2);
27405 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27409 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &rt);
27410 ok(hr == S_OK, "Failed to get render target, hr %#lx.\n", hr);
27411 check_rt_color(rt, 0x0000ff00);
27412 IDirect3DSurface9_Release(rt);
27414 hr = IDirect3DDevice9_EndScene(device);
27415 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27417 IDirect3DVertexBuffer9_Release(buffer);
27418 refcount = IDirect3DDevice9_Release(device);
27419 ok(!refcount, "Device has %lu references left.\n", refcount);
27420 IDirect3D9_Release(d3d);
27421 DestroyWindow(window);
27424 static void test_filling_convention(void)
27426 static const DWORD colour_bottom = 0x00ffff00;
27427 static const DWORD colour_clear = 0x000000ff;
27428 static const DWORD colour_right = 0x00000000;
27429 static const DWORD colour_left = 0x00ff0000;
27430 static const DWORD colour_top = 0x0000ff00;
27431 unsigned int colour, expected, i, j, x, y;
27432 IDirect3DSurface9 *rt, *backbuffer, *cur;
27433 IDirect3DVertexShader9 *shader = NULL;
27434 struct surface_readback rb;
27435 IDirect3DDevice9 *device;
27436 IDirect3D9 *d3d;
27437 ULONG refcount;
27438 D3DCAPS9 caps;
27439 HWND window;
27440 HRESULT hr;
27441 BOOL todo;
27443 static const unsigned int vp_size = 8;
27444 const D3DVIEWPORT9 vp = { 0, 0, vp_size, vp_size, 0.0, 1.0 };
27445 static const DWORD vs_code[] =
27447 0xfffe0101, /* vs_1_1 */
27448 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
27449 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
27450 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
27451 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
27452 0x0000ffff /* end */
27455 /* This test data follows the examples in MSDN's
27456 * "Rasterization Rules (Direct3D 9)" article.
27458 * The eps offset is filled in later depending on the GPU generation. The -eps/+eps below
27459 * is kept for keeping the code similar to the same test in the other d3d versions.
27461 * For d3d10+ GPUs even an offset of 1/(1024^2) is enough to make a difference. dx9 GPUs
27462 * (or at least r500, on which this was tested) need an offset of 1/128. dx7 (or rather,
27463 * a Geforce 4 GO, AKA a rebranded geforce 2) need 1/64.
27465 * GameFace is the only software we found that we know is picky regarding small geometry
27466 * offsets. It needs d3d10 and newer. A number of games have been written for d3d9 that
27467 * actually need d3d10 hardware (e.g. ARGB32F with filtering, some fourcc hacks). There
27468 * might be something that needs the d3d10+ precision in the d3d9 API. So demand it if
27469 * we find a d3d10+ GPU. */
27470 float eps = 0.0f;
27471 struct
27473 struct vec3 position;
27474 DWORD diffuse;
27476 center_tris[] =
27478 /* left */
27479 {{-2.5f / 4.0f, -1.5f / 4.0f, 0.0f}, colour_left},
27480 {{-2.5f / 4.0f, 2.5f / 4.0f, 0.0f}, colour_left},
27481 {{-1.5f / 4.0f, 0.5f / 4.0f, 0.0f}, colour_left},
27483 /* top */
27484 {{-1.5f / 4.0f, 0.5f / 4.0f, 0.0f}, colour_top},
27485 {{-2.5f / 4.0f, 2.5f / 4.0f, 0.0f}, colour_top},
27486 {{-0.5f / 4.0f, 2.5f / 4.0f, 0.0f}, colour_top},
27488 /* right */
27489 {{-0.5f / 4.0f, -1.5f / 4.0f, 0.0f}, colour_right},
27490 {{-1.5f / 4.0f, 0.5f / 4.0f, 0.0f}, colour_right},
27491 {{-0.5f / 4.0f, 2.5f / 4.0f, 0.0f}, colour_right},
27493 /* bottom */
27494 {{-2.5f / 4.0f, -1.5f / 4.0f, 0.0f}, colour_bottom},
27495 {{-1.5f / 4.0f, 0.5f / 4.0f, 0.0f}, colour_bottom},
27496 {{-0.5f / 4.0f, -1.5f / 4.0f, 0.0f}, colour_bottom},
27499 edge_tris[] =
27501 /* left */
27502 {{-2.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_left},
27503 {{-2.0f / 4.0f, 3.0f / 4.0f, 0.0f}, colour_left},
27504 {{-1.0f / 4.0f, 1.0f / 4.0f, 0.0f}, colour_left},
27506 /* top */
27507 {{-1.0f / 4.0f, 1.0f / 4.0f, 0.0f}, colour_top},
27508 {{-2.0f / 4.0f, 3.0f / 4.0f, 0.0f}, colour_top},
27509 {{ 0.0f / 4.0f, 3.0f / 4.0f, 0.0f}, colour_top},
27511 /* right */
27512 {{ 0.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_right},
27513 {{-1.0f / 4.0f, 1.0f / 4.0f, 0.0f}, colour_right},
27514 {{ 0.0f / 4.0f, 3.0f / 4.0f, 0.0f}, colour_right},
27516 /* bottom */
27517 {{-2.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_bottom},
27518 {{-1.0f / 4.0f, 1.0f / 4.0f, 0.0f}, colour_bottom},
27519 {{ 0.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_bottom},
27521 nudge_right_tris[] =
27523 /* left */
27524 {{eps - 2.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_left},
27525 {{eps - 2.0f / 4.0f, 3.0f / 4.0f, 0.0f}, colour_left},
27526 {{eps - 1.0f / 4.0f, 1.0f / 4.0f, 0.0f}, colour_left},
27528 /* top */
27529 {{eps - 1.0f / 4.0f, 1.0f / 4.0f, 0.0f}, colour_top},
27530 {{eps - 2.0f / 4.0f, 3.0f / 4.0f, 0.0f}, colour_top},
27531 {{eps - 0.0f / 4.0f, 3.0f / 4.0f, 0.0f}, colour_top},
27533 /* right */
27534 {{eps - 0.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_right},
27535 {{eps - 1.0f / 4.0f, 1.0f / 4.0f, 0.0f}, colour_right},
27536 {{eps - 0.0f / 4.0f, 3.0f / 4.0f, 0.0f}, colour_right},
27538 /* bottom */
27539 {{eps - 2.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_bottom},
27540 {{eps - 1.0f / 4.0f, 1.0f / 4.0f, 0.0f}, colour_bottom},
27541 {{eps - 0.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_bottom},
27543 nudge_left_tris[] =
27545 {{-eps - 2.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_left},
27546 {{-eps - 2.0f / 4.0f, 3.0f / 4.0f, 0.0f}, colour_left},
27547 {{-eps - 1.0f / 4.0f, 1.0f / 4.0f, 0.0f}, colour_left},
27549 /* top */
27550 {{-eps - 1.0f / 4.0f, 1.0f / 4.0f, 0.0f}, colour_top},
27551 {{-eps - 2.0f / 4.0f, 3.0f / 4.0f, 0.0f}, colour_top},
27552 {{-eps - 0.0f / 4.0f, 3.0f / 4.0f, 0.0f}, colour_top},
27554 /* right */
27555 {{-eps - 0.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_right},
27556 {{-eps - 1.0f / 4.0f, 1.0f / 4.0f, 0.0f}, colour_right},
27557 {{-eps - 0.0f / 4.0f, 3.0f / 4.0f, 0.0f}, colour_right},
27559 /* bottom */
27560 {{-eps - 2.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_bottom},
27561 {{-eps - 1.0f / 4.0f, 1.0f / 4.0f, 0.0f}, colour_bottom},
27562 {{-eps - 0.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_bottom},
27564 nudge_top_tris[] =
27566 /* left */
27567 {{-2.0f / 4.0f, eps - 1.0f / 4.0f, 0.0f}, colour_left},
27568 {{-2.0f / 4.0f, eps + 3.0f / 4.0f, 0.0f}, colour_left},
27569 {{-1.0f / 4.0f, eps + 1.0f / 4.0f, 0.0f}, colour_left},
27571 /* top */
27572 {{-1.0f / 4.0f, eps + 1.0f / 4.0f, 0.0f}, colour_top},
27573 {{-2.0f / 4.0f, eps + 3.0f / 4.0f, 0.0f}, colour_top},
27574 {{ 0.0f / 4.0f, eps + 3.0f / 4.0f, 0.0f}, colour_top},
27576 /* right */
27577 {{ 0.0f / 4.0f, eps - 1.0f / 4.0f, 0.0f}, colour_right},
27578 {{-1.0f / 4.0f, eps + 1.0f / 4.0f, 0.0f}, colour_right},
27579 {{ 0.0f / 4.0f, eps + 3.0f / 4.0f, 0.0f}, colour_right},
27581 /* bottom */
27582 {{-2.0f / 4.0f, eps - 1.0f / 4.0f, 0.0f}, colour_bottom},
27583 {{-1.0f / 4.0f, eps + 1.0f / 4.0f, 0.0f}, colour_bottom},
27584 {{ 0.0f / 4.0f, eps - 1.0f / 4.0f, 0.0f}, colour_bottom},
27586 nudge_bottom_tris[] =
27588 /* left */
27589 {{-2.0f / 4.0f, -eps - 1.0f / 4.0f, 0.0f}, colour_left},
27590 {{-2.0f / 4.0f, -eps + 3.0f / 4.0f, 0.0f}, colour_left},
27591 {{-1.0f / 4.0f, -eps + 1.0f / 4.0f, 0.0f}, colour_left},
27593 /* top */
27594 {{-1.0f / 4.0f, -eps + 1.0f / 4.0f, 0.0f}, colour_top},
27595 {{-2.0f / 4.0f, -eps + 3.0f / 4.0f, 0.0f}, colour_top},
27596 {{ 0.0f / 4.0f, -eps + 3.0f / 4.0f, 0.0f}, colour_top},
27598 /* right */
27599 {{ 0.0f / 4.0f, -eps - 1.0f / 4.0f, 0.0f}, colour_right},
27600 {{-1.0f / 4.0f, -eps + 1.0f / 4.0f, 0.0f}, colour_right},
27601 {{ 0.0f / 4.0f, -eps + 3.0f / 4.0f, 0.0f}, colour_right},
27603 /* bottom */
27604 {{-2.0f / 4.0f, -eps - 1.0f / 4.0f, 0.0f}, colour_bottom},
27605 {{-1.0f / 4.0f, -eps + 1.0f / 4.0f, 0.0f}, colour_bottom},
27606 {{ 0.0f / 4.0f, -eps - 1.0f / 4.0f, 0.0f}, colour_bottom},
27609 const struct
27611 struct vec4 position;
27612 DWORD diffuse;
27614 center_tris_t[] =
27616 /* left */
27617 {{ 1.5f, 1.5f, 0.0f, 1.0f}, colour_left},
27618 {{ 2.5f, 3.5f, 0.0f, 1.0f}, colour_left},
27619 {{ 1.5f, 5.5f, 0.0f, 1.0f}, colour_left},
27621 /* top */
27622 {{ 1.5f, 1.5f, 0.0f, 1.0f}, colour_top},
27623 {{ 3.5f, 1.5f, 0.0f, 1.0f}, colour_top},
27624 {{ 2.5f, 3.5f, 0.0f, 1.0f}, colour_top},
27626 /* right */
27627 {{ 3.5f, 1.5f, 0.0f, 1.0f}, colour_right},
27628 {{ 3.5f, 5.5f, 0.0f, 1.0f}, colour_right},
27629 {{ 2.5f, 3.5f, 0.0f, 1.0f}, colour_right},
27631 /* bottom */
27632 {{ 2.5f, 3.5f, 0.0f, 1.0f}, colour_bottom},
27633 {{ 3.5f, 5.5f, 0.0f, 1.0f}, colour_bottom},
27634 {{ 1.5f, 5.5f, 0.0f, 1.0f}, colour_bottom},
27636 edge_tris_t[] =
27638 /* left */
27639 {{ 2.0f, 1.0f, 0.0f, 1.0f}, colour_left},
27640 {{ 3.0f, 3.0f, 0.0f, 1.0f}, colour_left},
27641 {{ 2.0f, 5.0f, 0.0f, 1.0f}, colour_left},
27643 /* top */
27644 {{ 2.0f, 1.0f, 0.0f, 1.0f}, colour_top},
27645 {{ 4.0f, 1.0f, 0.0f, 1.0f}, colour_top},
27646 {{ 3.0f, 3.0f, 0.0f, 1.0f}, colour_top},
27648 /* right */
27649 {{ 4.0f, 1.0f, 0.0f, 1.0f}, colour_right},
27650 {{ 4.0f, 5.0f, 0.0f, 1.0f}, colour_right},
27651 {{ 3.0f, 3.0f, 0.0f, 1.0f}, colour_right},
27653 /* bottom */
27654 {{ 3.0f, 3.0f, 0.0f, 1.0f}, colour_bottom},
27655 {{ 4.0f, 5.0f, 0.0f, 1.0f}, colour_bottom},
27656 {{ 2.0f, 5.0f, 0.0f, 1.0f}, colour_bottom},
27659 const struct
27661 const void *geometry;
27662 size_t stride;
27663 DWORD fvf;
27664 const char *expected[8];
27666 tests[] =
27669 center_tris,
27670 sizeof(center_tris[0]),
27671 D3DFVF_XYZ | D3DFVF_DIFFUSE,
27673 " ",
27674 " ",
27675 " TT ",
27676 " LR ",
27677 " LR ",
27678 " BB ",
27679 " ",
27684 edge_tris,
27685 sizeof(edge_tris[0]),
27686 D3DFVF_XYZ | D3DFVF_DIFFUSE,
27688 " ",
27689 " TT ",
27690 " LT ",
27691 " LR ",
27692 " LB ",
27693 " ",
27694 " ",
27699 nudge_right_tris,
27700 sizeof(nudge_right_tris[0]),
27701 D3DFVF_XYZ | D3DFVF_DIFFUSE,
27703 " ",
27704 " TT ",
27705 " TR ",
27706 " LR ",
27707 " BR ",
27708 " ",
27709 " ",
27714 nudge_left_tris,
27715 sizeof(nudge_left_tris[0]),
27716 D3DFVF_XYZ | D3DFVF_DIFFUSE,
27718 " ",
27719 " TT ",
27720 " LT ",
27721 " LR ",
27722 " LB ",
27723 " ",
27724 " ",
27729 nudge_top_tris,
27730 sizeof(nudge_top_tris[0]),
27731 D3DFVF_XYZ | D3DFVF_DIFFUSE,
27733 " ",
27734 " LT ",
27735 " LT ",
27736 " LB ",
27737 " LB ",
27738 " ",
27739 " ",
27744 nudge_bottom_tris,
27745 sizeof(nudge_bottom_tris[0]),
27746 D3DFVF_XYZ | D3DFVF_DIFFUSE,
27748 " ",
27749 " ",
27750 " LT ",
27751 " Lt ",
27752 " LB ",
27753 " lB ",
27754 " ",
27759 center_tris_t,
27760 sizeof(center_tris_t[0]),
27761 D3DFVF_XYZRHW | D3DFVF_DIFFUSE,
27763 " ",
27764 " ",
27765 " TT ",
27766 " LR ",
27767 " LR ",
27768 " BB ",
27769 " ",
27774 edge_tris_t,
27775 sizeof(edge_tris_t[0]),
27776 D3DFVF_XYZRHW | D3DFVF_DIFFUSE,
27778 " ",
27779 " TT ",
27780 " LT ",
27781 " LR ",
27782 " LB ",
27783 " ",
27784 " ",
27790 window = create_window();
27791 d3d = Direct3DCreate9(D3D_SDK_VERSION);
27792 ok(!!d3d, "Failed to create a D3D object.\n");
27794 if (!(device = create_device(d3d, window, window, TRUE)))
27796 skip("Failed to create a 3D device.\n");
27797 IDirect3D9_Release(d3d);
27798 DestroyWindow(window);
27799 return;
27802 hr = IDirect3DDevice9_CreateRenderTarget(device, vp_size, vp_size,
27803 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
27804 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27805 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
27806 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27808 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
27809 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27810 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
27812 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &shader);
27813 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27815 else
27816 skip("Skipping vertex shader codepath in filling convention test.\n");
27818 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
27819 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27820 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
27821 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27823 if (device_is_d3d10(device))
27824 eps = 1.0f / 512.0f;
27825 else
27826 eps = 1.0f / 64.0f;
27828 for (i = 0; i < 12; ++i)
27830 nudge_right_tris[i].position.x +=eps;
27831 nudge_left_tris[i].position.x -=eps;
27832 nudge_top_tris[i].position.y +=eps;
27833 nudge_bottom_tris[i].position.y -=eps;
27836 for (i = 0; i < ARRAY_SIZE(tests); ++i)
27838 hr = IDirect3DDevice9_SetFVF(device, tests[i].fvf);
27839 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27841 /* Run tests with shader and fixed function vertex processing if shaders are
27842 * supported. There's no point in running the XYZRHW tests with a VS though. */
27843 if (shader && ((tests[i].fvf & D3DFVF_POSITION_MASK) == D3DFVF_XYZ))
27844 j = 0;
27845 else
27846 j = 2;
27848 for (; j < 4; ++j)
27850 cur = (j & 1) ? rt : backbuffer;
27852 hr = IDirect3DDevice9_SetVertexShader(device, (j & 2) ? NULL : shader);
27853 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27855 hr = IDirect3DDevice9_SetRenderTarget(device, 0, cur);
27856 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27857 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, colour_clear, 0.0f, 0);
27858 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27859 hr = IDirect3DDevice9_SetViewport(device, &vp);
27860 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27862 hr = IDirect3DDevice9_BeginScene(device);
27863 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27864 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, tests[i].geometry, tests[i].stride);
27865 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27866 hr = IDirect3DDevice9_EndScene(device);
27867 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27869 get_rt_readback(cur, &rb);
27870 for (y = 0; y < 8; y++)
27872 for (x = 0; x < 8; x++)
27874 todo = FALSE;
27875 switch (tests[i].expected[y][x])
27877 case 'l': todo = TRUE;
27878 case 'L':
27879 expected = colour_left;
27880 break;
27881 case 't': todo = TRUE;
27882 case 'T':
27883 expected = colour_top;
27884 break;
27885 case 'r': todo = TRUE;
27886 case 'R':
27887 expected = colour_right;
27888 break;
27889 case 'b': todo = TRUE;
27890 case 'B':
27891 expected = colour_bottom;
27892 break;
27893 case ' ':
27894 expected = colour_clear;
27895 break;
27896 default:
27897 ok(0, "Unexpected entry in expected test char\n");
27898 expected = 0xdeadbeef;
27900 colour = get_readback_color(&rb, x, y);
27901 /* The nudge-to-bottom test fails on cards that give us a bottom-left
27902 * filling convention. The cause isn't the bottom part of the filling
27903 * convention, but because wined3d will nudge geometry to the left to
27904 * keep diagonals (the 'R' in test case 'edge_tris') intact. */
27905 todo_wine_if(todo && !color_match(colour, expected, 1))
27906 ok(color_match(colour, expected, 1), "Got unexpected colour %08x, %ux%u, case %u, j %u.\n",
27907 colour, x, y, i, j);
27910 release_surface_readback(&rb);
27912 /* For debugging */
27913 if (cur != backbuffer)
27915 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, backbuffer, NULL, D3DTEXF_POINT);
27916 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27918 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
27919 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
27923 if (shader)
27924 IDirect3DVertexShader9_Release(shader);
27925 IDirect3DSurface9_Release(backbuffer);
27926 IDirect3DSurface9_Release(rt);
27927 refcount = IDirect3DDevice9_Release(device);
27928 ok(!refcount, "Device has %lu references left.\n", refcount);
27929 IDirect3D9_Release(d3d);
27930 DestroyWindow(window);
27933 static void test_managed_reset(void)
27935 struct d3d9_test_context context;
27936 IDirect3DTexture9 *texture;
27937 IDirect3DDevice9 *device;
27938 HRESULT hr;
27940 if (!init_test_context(&context))
27941 return;
27942 device = context.device;
27944 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
27945 ok(hr == S_OK, "Got hr %#lx.\n", hr);
27946 fill_texture(texture, 0x0000ff00, 0);
27948 draw_textured_quad(&context, texture);
27949 check_rt_color(context.backbuffer, 0x0000ff00);
27951 hr = reset_device(&context);
27952 ok(hr == S_OK, "Got hr %#lx.\n", hr);
27954 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
27955 ok(hr == S_OK, "Got hr %#lx.\n", hr);
27957 draw_textured_quad(&context, texture);
27958 check_rt_color(context.backbuffer, 0x0000ff00);
27960 IDirect3DTexture9_Release(texture);
27961 release_test_context(&context);
27964 static void test_managed_generate_mipmap(void)
27966 struct d3d9_test_context context;
27967 IDirect3DTexture9 *texture;
27968 IDirect3DDevice9 *device;
27969 HRESULT hr;
27971 if (!init_test_context(&context))
27972 return;
27973 device = context.device;
27975 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 0, D3DUSAGE_AUTOGENMIPMAP,
27976 D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
27977 ok(hr == S_OK, "Got hr %#lx.\n", hr);
27978 fill_texture(texture, 0x0000ff00, 0);
27980 IDirect3DTexture9_GenerateMipSubLevels(texture);
27982 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
27983 ok(hr == S_OK, "Got hr %#lx.\n", hr);
27985 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
27986 ok(hr == S_OK, "Got hr %#lx.\n", hr);
27987 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
27988 ok(hr == S_OK, "Got hr %#lx.\n", hr);
27990 draw_textured_quad(&context, texture);
27991 check_rt_color(context.backbuffer, 0x0000ff00);
27993 IDirect3DTexture9_Release(texture);
27994 release_test_context(&context);
27997 /* Some applications (Vivisector, Cryostasis) lock a mipmapped managed texture
27998 * at level 0, write every level at once, and expect it to be uploaded. */
27999 static void test_mipmap_upload(void)
28001 unsigned int j, width, level_count;
28002 struct d3d9_test_context context;
28003 IDirect3DTexture9 *texture;
28004 D3DLOCKED_RECT locked_rect;
28005 IDirect3DDevice9 *device;
28006 unsigned int *mem;
28007 HRESULT hr;
28009 if (!init_test_context(&context))
28010 return;
28011 device = context.device;
28013 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 0, 0,
28014 D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
28015 ok(hr == S_OK, "Got hr %#lx.\n", hr);
28017 level_count = IDirect3DBaseTexture9_GetLevelCount(texture);
28019 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
28020 ok(hr == S_OK, "Got hr %#lx.\n", hr);
28022 mem = locked_rect.pBits;
28024 for (j = 0; j < level_count; ++j)
28026 width = 32 >> j;
28027 memset(mem, 0x11 * (j + 1), width * width * 4);
28028 mem += width * width;
28031 hr = IDirect3DTexture9_UnlockRect(texture, 0);
28032 ok(hr == S_OK, "Got hr %#lx.\n", hr);
28034 for (j = 0; j < level_count; ++j)
28036 winetest_push_context("level %u", j);
28038 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
28039 ok(hr == S_OK, "Got hr %#lx.\n", hr);
28041 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
28042 ok(hr == S_OK, "Got hr %#lx.\n", hr);
28043 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, j);
28044 ok(hr == S_OK, "Got hr %#lx.\n", hr);
28046 draw_textured_quad(&context, texture);
28047 check_rt_color(context.backbuffer, 0x00111111 * (j + 1));
28049 winetest_pop_context();
28052 IDirect3DTexture9_Release(texture);
28053 release_test_context(&context);
28056 START_TEST(visual)
28058 D3DADAPTER_IDENTIFIER9 identifier;
28059 IDirect3D9 *d3d;
28060 HRESULT hr;
28062 if (!(d3d = Direct3DCreate9(D3D_SDK_VERSION)))
28064 skip("could not create D3D9 object\n");
28065 return;
28068 memset(&identifier, 0, sizeof(identifier));
28069 hr = IDirect3D9_GetAdapterIdentifier(d3d, 0, 0, &identifier);
28070 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#lx.\n", hr);
28071 trace("Driver string: \"%s\"\n", identifier.Driver);
28072 trace("Description string: \"%s\"\n", identifier.Description);
28073 /* Only Windows XP's default VGA driver should have an empty description */
28074 ok(identifier.Description[0] || broken(!strcmp(identifier.Driver, "vga.dll")), "Empty driver description.\n");
28075 trace("Device name string: \"%s\"\n", identifier.DeviceName);
28076 ok(identifier.DeviceName[0], "Empty device name.\n");
28077 trace("Driver version %d.%d.%d.%d\n",
28078 HIWORD(identifier.DriverVersion.HighPart), LOWORD(identifier.DriverVersion.HighPart),
28079 HIWORD(identifier.DriverVersion.LowPart), LOWORD(identifier.DriverVersion.LowPart));
28081 IDirect3D9_Release(d3d);
28083 test_sanity();
28084 depth_clamp_test();
28085 stretchrect_test();
28086 test_multisample_stretch_rect();
28087 lighting_test();
28088 test_specular_lighting();
28089 clear_test();
28090 test_clear_different_size_surfaces();
28091 color_fill_test();
28092 fog_test();
28093 test_cube_wrap();
28094 z_range_test();
28095 maxmip_test();
28096 offscreen_test();
28097 ds_size_test();
28098 test_blend();
28099 test_shademode();
28100 srgbtexture_test();
28101 release_buffer_test();
28102 float_texture_test();
28103 g16r16_texture_test();
28104 pixelshader_blending_test();
28105 texture_transform_flags_test();
28106 test_generate_mipmap();
28107 test_mipmap_autogen();
28108 fixed_function_decl_test();
28109 conditional_np2_repeat_test();
28110 fixed_function_bumpmap_test();
28111 test_pointsize();
28112 tssargtemp_test();
28113 np2_stretch_rect_test();
28114 yuv_color_test();
28115 yuv_layout_test();
28116 zwriteenable_test();
28117 alphatest_test();
28118 test_viewport();
28119 test_constant_clamp_vs();
28120 test_compare_instructions();
28121 test_mova();
28122 loop_index_test();
28123 sincos_test();
28124 sgn_test();
28125 clip_planes_test();
28126 test_vshader_input();
28127 test_vshader_float16();
28128 stream_test();
28129 fog_with_shader_test();
28130 texbem_test();
28131 texdepth_test();
28132 texkill_test();
28133 volume_v16u16_test();
28134 constant_clamp_ps_test();
28135 cnd_test();
28136 dp2add_ps_test();
28137 unbound_sampler_test();
28138 nested_loop_test();
28139 pretransformed_varying_test();
28140 vface_register_test();
28141 test_fragment_coords();
28142 multiple_rendertargets_test();
28143 texop_test();
28144 texop_range_test();
28145 alphareplicate_test();
28146 dp3_alpha_test();
28147 depth_buffer_test();
28148 depth_buffer2_test();
28149 depth_blit_test();
28150 intz_test();
28151 test_fetch4();
28152 shadow_test();
28153 fp_special_test();
28154 depth_bounds_test();
28155 srgbwrite_format_test();
28156 update_surface_test();
28157 multisample_get_rtdata_test();
28158 test_multisample_get_front_buffer_data();
28159 zenable_test();
28160 fog_special_test();
28161 volume_srgb_test();
28162 volume_dxtn_test();
28163 add_dirty_rect_test();
28164 test_buffer_no_dirty_update();
28165 multisampled_depth_buffer_test();
28166 resz_test();
28167 stencil_cull_test();
28168 test_per_stage_constant();
28169 test_3dc_formats();
28170 test_fog_interpolation();
28171 test_negative_fixedfunction_fog();
28172 test_position_index();
28173 test_table_fog_zw();
28174 test_signed_formats();
28175 test_multisample_mismatch();
28176 test_texcoordindex();
28177 test_vertex_blending();
28178 test_updatetexture();
28179 test_depthbias();
28180 test_flip();
28181 test_uninitialized_varyings();
28182 test_multisample_init();
28183 test_depth_stencil_init();
28184 test_texture_blending();
28185 test_color_clamping();
28186 test_line_antialiasing_blending();
28187 test_dsy();
28188 test_evict_bound_resources();
28189 test_max_index16();
28190 test_backbuffer_resize();
28191 test_drawindexedprimitiveup();
28192 test_vertex_texture();
28193 test_mvp_software_vertex_shaders();
28194 test_null_format();
28195 test_map_synchronisation();
28196 test_color_vertex();
28197 test_sysmem_draw();
28198 test_nrm_instruction();
28199 test_desktop_window();
28200 test_mismatched_sample_types();
28201 test_draw_mapped_buffer();
28202 test_sample_attached_rendertarget();
28203 test_alpha_to_coverage();
28204 test_sample_mask();
28205 test_dynamic_map_synchronization();
28206 test_filling_convention();
28207 test_managed_reset();
28208 test_managed_generate_mipmap();
28209 test_mipmap_upload();