push 212f1dad91f15aefd8e676124180e0b86d7c9ee6
[wine/hacks.git] / dlls / d3d9 / tests / visual.c
blob5574313768b33e75d3cb3137be819d368530b1d7
1 /*
2 * Copyright 2005, 2007-2008 Henri Verbeet
3 * Copyright (C) 2007-2008 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 #define COBJMACROS
32 #include <d3d9.h>
33 #include "wine/test.h"
35 static HMODULE d3d9_handle = 0;
37 static HWND create_window(void)
39 WNDCLASS wc = {0};
40 HWND ret;
41 wc.lpfnWndProc = DefWindowProc;
42 wc.lpszClassName = "d3d9_test_wc";
43 RegisterClass(&wc);
45 ret = CreateWindow("d3d9_test_wc", "d3d9_test",
46 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
47 return ret;
50 static BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
52 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
53 c1 >>= 8; c2 >>= 8;
54 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
55 c1 >>= 8; c2 >>= 8;
56 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
57 c1 >>= 8; c2 >>= 8;
58 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
59 return TRUE;
62 /* Locks a given surface and returns the color at (x,y). It's the caller's
63 * responsibility to only pass in lockable surfaces and valid x,y coordinates */
64 static DWORD getPixelColorFromSurface(IDirect3DSurface9 *surface, UINT x, UINT y)
66 DWORD color;
67 HRESULT hr;
68 D3DSURFACE_DESC desc;
69 RECT rectToLock = {x, y, x+1, y+1};
70 D3DLOCKED_RECT lockedRect;
72 hr = IDirect3DSurface9_GetDesc(surface, &desc);
73 if(FAILED(hr)) /* This is not a test */
75 trace("Can't get the surface description, hr=%08x\n", hr);
76 return 0xdeadbeef;
79 hr = IDirect3DSurface9_LockRect(surface, &lockedRect, &rectToLock, D3DLOCK_READONLY);
80 if(FAILED(hr)) /* This is not a test */
82 trace("Can't lock the surface, hr=%08x\n", hr);
83 return 0xdeadbeef;
85 switch(desc.Format) {
86 case D3DFMT_A8R8G8B8:
88 color = ((DWORD *) lockedRect.pBits)[0] & 0xffffffff;
89 break;
91 default:
92 trace("Error: unknown surface format: %d\n", desc.Format);
93 color = 0xdeadbeef;
94 break;
96 hr = IDirect3DSurface9_UnlockRect(surface);
97 if(FAILED(hr))
99 trace("Can't unlock the surface, hr=%08x\n", hr);
101 return color;
104 static DWORD getPixelColor(IDirect3DDevice9 *device, UINT x, UINT y)
106 DWORD ret;
107 IDirect3DSurface9 *surf;
108 HRESULT hr;
109 D3DLOCKED_RECT lockedRect;
110 RECT rectToLock = {x, y, x+1, y+1};
112 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 640, 480, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf, NULL);
113 if(FAILED(hr) || !surf ) /* This is not a test */
115 trace("Can't create an offscreen plain surface to read the render target data, hr=%08x\n", hr);
116 return 0xdeadbeef;
119 hr = IDirect3DDevice9_GetFrontBufferData(device, 0, surf);
120 if(FAILED(hr))
122 trace("Can't read the front buffer data, hr=%08x\n", hr);
123 ret = 0xdeadbeed;
124 goto out;
127 hr = IDirect3DSurface9_LockRect(surf, &lockedRect, &rectToLock, D3DLOCK_READONLY);
128 if(FAILED(hr))
130 trace("Can't lock the offscreen surface, hr=%08x\n", hr);
131 ret = 0xdeadbeec;
132 goto out;
135 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
136 * really important for these tests
138 ret = ((DWORD *) lockedRect.pBits)[0] & 0x00ffffff;
139 hr = IDirect3DSurface9_UnlockRect(surf);
140 if(FAILED(hr))
142 trace("Can't unlock the offscreen surface, hr=%08x\n", hr);
145 out:
146 if(surf) IDirect3DSurface9_Release(surf);
147 return ret;
150 static IDirect3DDevice9 *init_d3d9(void)
152 IDirect3D9 * (__stdcall * d3d9_create)(UINT SDKVersion) = 0;
153 IDirect3D9 *d3d9_ptr = 0;
154 IDirect3DDevice9 *device_ptr = 0;
155 D3DPRESENT_PARAMETERS present_parameters;
156 HRESULT hr;
157 D3DADAPTER_IDENTIFIER9 identifier;
159 d3d9_create = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9");
160 ok(d3d9_create != NULL, "Failed to get address of Direct3DCreate9\n");
161 if (!d3d9_create) return NULL;
163 d3d9_ptr = d3d9_create(D3D_SDK_VERSION);
164 if (!d3d9_ptr)
166 skip("could not create D3D9\n");
167 return NULL;
170 ZeroMemory(&present_parameters, sizeof(present_parameters));
171 present_parameters.Windowed = FALSE;
172 present_parameters.hDeviceWindow = create_window();
173 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
174 present_parameters.BackBufferWidth = 640;
175 present_parameters.BackBufferHeight = 480;
176 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
177 present_parameters.EnableAutoDepthStencil = TRUE;
178 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
180 memset(&identifier, 0, sizeof(identifier));
181 hr = IDirect3D9_GetAdapterIdentifier(d3d9_ptr, 0, 0, &identifier);
182 ok(hr == D3D_OK, "Failed to get adapter identifier description\n");
183 trace("Driver string: \"%s\"\n", identifier.Driver);
184 trace("Description string: \"%s\"\n", identifier.Description);
185 trace("Device name string: \"%s\"\n", identifier.DeviceName);
186 trace("Driver version %d.%d.%d.%d\n",
187 HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
188 HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
190 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
191 if(FAILED(hr)) {
192 present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
193 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
194 if(FAILED(hr)) {
195 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
198 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D_CreateDevice returned: %08x\n", hr);
200 return device_ptr;
203 struct vertex
205 float x, y, z;
206 DWORD diffuse;
209 struct tvertex
211 float x, y, z, rhw;
212 DWORD diffuse;
215 struct nvertex
217 float x, y, z;
218 float nx, ny, nz;
219 DWORD diffuse;
222 static void lighting_test(IDirect3DDevice9 *device)
224 HRESULT hr;
225 DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
226 DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
227 DWORD color;
228 D3DMATERIAL9 material, old_material;
229 DWORD cop, carg;
231 float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
232 0.0f, 1.0f, 0.0f, 0.0f,
233 0.0f, 0.0f, 1.0f, 0.0f,
234 0.0f, 0.0f, 0.0f, 1.0f };
236 struct vertex unlitquad[] =
238 {-1.0f, -1.0f, 0.1f, 0xffff0000},
239 {-1.0f, 0.0f, 0.1f, 0xffff0000},
240 { 0.0f, 0.0f, 0.1f, 0xffff0000},
241 { 0.0f, -1.0f, 0.1f, 0xffff0000},
243 struct vertex litquad[] =
245 {-1.0f, 0.0f, 0.1f, 0xff00ff00},
246 {-1.0f, 1.0f, 0.1f, 0xff00ff00},
247 { 0.0f, 1.0f, 0.1f, 0xff00ff00},
248 { 0.0f, 0.0f, 0.1f, 0xff00ff00},
250 struct nvertex unlitnquad[] =
252 { 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
253 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
254 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
255 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
257 struct nvertex litnquad[] =
259 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
260 { 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
261 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
262 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
264 WORD Indices[] = {0, 1, 2, 2, 3, 0};
266 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
267 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
269 /* Setup some states that may cause issues */
270 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
271 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
272 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
273 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
274 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
275 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
276 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
277 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
278 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
279 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
280 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
281 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
282 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
283 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
284 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
285 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
286 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
287 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
288 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
289 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
290 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
291 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
292 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
293 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
295 hr = IDirect3DDevice9_SetFVF(device, fvf);
296 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
298 hr = IDirect3DDevice9_BeginScene(device);
299 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
300 if(hr == D3D_OK)
302 /* No lights are defined... That means, lit vertices should be entirely black */
303 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
304 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
305 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
306 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
307 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
309 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
310 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
311 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
312 2 /*PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
313 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
315 hr = IDirect3DDevice9_SetFVF(device, nfvf);
316 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
318 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
319 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
320 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
321 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
322 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
324 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
325 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
326 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
327 2 /*PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
328 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
330 IDirect3DDevice9_EndScene(device);
331 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
334 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
336 color = getPixelColor(device, 160, 360); /* lower left quad - unlit without normals */
337 ok(color == 0x00ff0000, "Unlit quad without normals has color %08x\n", color);
338 color = getPixelColor(device, 160, 120); /* upper left quad - lit without normals */
339 ok(color == 0x00000000, "Lit quad without normals has color %08x\n", color);
340 color = getPixelColor(device, 480, 360); /* lower left quad - unlit with normals */
341 ok(color == 0x000000ff, "Unlit quad with normals has color %08x\n", color);
342 color = getPixelColor(device, 480, 120); /* upper left quad - lit with normals */
343 ok(color == 0x00000000, "Lit quad with normals has color %08x\n", color);
345 hr = IDirect3DDevice9_GetMaterial(device, &old_material);
346 ok(hr == D3D_OK, "IDirect3DDevice9_GetMaterial returned %08x\n", hr);
347 memset(&material, 0, sizeof(material));
348 material.Diffuse.r = 0.0;
349 material.Diffuse.g = 0.0;
350 material.Diffuse.b = 0.0;
351 material.Diffuse.a = 1.0;
352 material.Ambient.r = 0.0;
353 material.Ambient.g = 0.0;
354 material.Ambient.b = 0.0;
355 material.Ambient.a = 0.0;
356 material.Specular.r = 0.0;
357 material.Specular.g = 0.0;
358 material.Specular.b = 0.0;
359 material.Specular.a = 0.0;
360 material.Emissive.r = 0.0;
361 material.Emissive.g = 0.0;
362 material.Emissive.b = 0.0;
363 material.Emissive.a = 0.0;
364 material.Power = 0.0;
365 IDirect3DDevice9_SetMaterial(device, &material);
366 ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
368 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
369 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
370 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
371 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
373 hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLOROP, &cop);
374 ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
375 hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_COLORARG1, &carg);
376 ok(hr == D3D_OK, "IDirect3DDevice9_GetTextureStageState returned %08x\n", hr);
377 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
378 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
379 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
380 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
382 hr = IDirect3DDevice9_BeginScene(device);
383 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
384 if(SUCCEEDED(hr)) {
385 struct vertex lighting_test[] = {
386 {-1.0, -1.0, 0.1, 0x8000ff00},
387 { 1.0, -1.0, 0.1, 0x80000000},
388 {-1.0, 1.0, 0.1, 0x8000ff00},
389 { 1.0, 1.0, 0.1, 0x80000000}
391 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
392 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
393 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, lighting_test, sizeof(lighting_test[0]));
394 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
396 hr = IDirect3DDevice9_EndScene(device);
397 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
400 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
401 color = getPixelColor(device, 320, 240);
402 ok(color == 0x00ffffff, "Lit vertex alpha test returned color %08x, expected 0x00ffffff\n", color);
404 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, cop);
405 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
406 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
407 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
408 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2);
409 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
410 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
411 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
412 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, carg);
413 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
414 hr = IDirect3DDevice9_SetMaterial(device, &old_material);
415 ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
418 static void clear_test(IDirect3DDevice9 *device)
420 /* Tests the correctness of clearing parameters */
421 HRESULT hr;
422 D3DRECT rect[2];
423 D3DRECT rect_negneg;
424 DWORD color;
425 D3DVIEWPORT9 old_vp, vp;
426 RECT scissor;
427 DWORD oldColorWrite;
428 BOOL invalid_clear_failed = FALSE;
430 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
431 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
433 /* Positive x, negative y */
434 rect[0].x1 = 0;
435 rect[0].y1 = 480;
436 rect[0].x2 = 320;
437 rect[0].y2 = 240;
439 /* Positive x, positive y */
440 rect[1].x1 = 0;
441 rect[1].y1 = 0;
442 rect[1].x2 = 320;
443 rect[1].y2 = 240;
444 /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
445 * returns D3D_OK, but ignores the rectangle silently
447 hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
448 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
449 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
451 /* negative x, negative y */
452 rect_negneg.x1 = 640;
453 rect_negneg.y1 = 240;
454 rect_negneg.x2 = 320;
455 rect_negneg.y2 = 0;
456 hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
457 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
458 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
460 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
462 color = getPixelColor(device, 160, 360); /* lower left quad */
463 ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
464 color = getPixelColor(device, 160, 120); /* upper left quad */
465 if(invalid_clear_failed) {
466 /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
467 ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
468 } else {
469 /* If the negative rectangle was dropped silently, the correct ones are cleared */
470 ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
472 color = getPixelColor(device, 480, 360); /* lower right quad */
473 ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
474 color = getPixelColor(device, 480, 120); /* upper right quad */
475 ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
477 /* Test how the viewport affects clears */
478 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
479 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
480 hr = IDirect3DDevice9_GetViewport(device, &old_vp);
481 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
483 vp.X = 160;
484 vp.Y = 120;
485 vp.Width = 160;
486 vp.Height = 120;
487 vp.MinZ = 0.0;
488 vp.MaxZ = 1.0;
489 hr = IDirect3DDevice9_SetViewport(device, &vp);
490 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
491 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
492 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
494 vp.X = 320;
495 vp.Y = 240;
496 vp.Width = 320;
497 vp.Height = 240;
498 vp.MinZ = 0.0;
499 vp.MaxZ = 1.0;
500 hr = IDirect3DDevice9_SetViewport(device, &vp);
501 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
502 rect[0].x1 = 160;
503 rect[0].y1 = 120;
504 rect[0].x2 = 480;
505 rect[0].y2 = 360;
506 hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
507 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
509 hr = IDirect3DDevice9_SetViewport(device, &old_vp);
510 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
512 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
513 color = getPixelColor(device, 158, 118);
514 ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
515 color = getPixelColor(device, 162, 118);
516 ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
517 color = getPixelColor(device, 158, 122);
518 ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
519 color = getPixelColor(device, 162, 122);
520 ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
522 color = getPixelColor(device, 318, 238);
523 ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
524 color = getPixelColor(device, 322, 238);
525 ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
526 color = getPixelColor(device, 318, 242);
527 ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
528 color = getPixelColor(device, 322, 242);
529 ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
531 color = getPixelColor(device, 478, 358);
532 ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
533 color = getPixelColor(device, 482, 358);
534 ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
535 color = getPixelColor(device, 478, 362);
536 ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
537 color = getPixelColor(device, 482, 362);
538 ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
540 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
541 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
543 scissor.left = 160;
544 scissor.right = 480;
545 scissor.top = 120;
546 scissor.bottom = 360;
547 hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
548 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
549 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
550 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
552 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
553 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
554 hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
555 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
557 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
558 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
560 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
561 color = getPixelColor(device, 158, 118);
562 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
563 color = getPixelColor(device, 162, 118);
564 ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
565 color = getPixelColor(device, 158, 122);
566 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
567 color = getPixelColor(device, 162, 122);
568 ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
570 color = getPixelColor(device, 158, 358);
571 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
572 color = getPixelColor(device, 162, 358);
573 ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
574 color = getPixelColor(device, 158, 358);
575 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
576 color = getPixelColor(device, 162, 362);
577 ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
579 color = getPixelColor(device, 478, 118);
580 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
581 color = getPixelColor(device, 478, 122);
582 ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
583 color = getPixelColor(device, 482, 122);
584 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
585 color = getPixelColor(device, 482, 358);
586 ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
588 color = getPixelColor(device, 478, 358);
589 ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
590 color = getPixelColor(device, 478, 362);
591 ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
592 color = getPixelColor(device, 482, 358);
593 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
594 color = getPixelColor(device, 482, 362);
595 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
597 color = getPixelColor(device, 318, 238);
598 ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
599 color = getPixelColor(device, 318, 242);
600 ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
601 color = getPixelColor(device, 322, 238);
602 ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
603 color = getPixelColor(device, 322, 242);
604 ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
606 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
607 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
608 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
609 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
611 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
612 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
614 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
615 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
617 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
619 /* Colorwriteenable does not affect the clear */
620 color = getPixelColor(device, 320, 240);
621 ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
624 typedef struct {
625 float in[4];
626 DWORD out;
627 } test_data_t;
630 * c7 mova ARGB mov ARGB
631 * -2.4 -2 0x00ffff00 -3 0x00ff0000
632 * -1.6 -2 0x00ffff00 -2 0x00ffff00
633 * -0.4 0 0x0000ffff -1 0x0000ff00
634 * 0.4 0 0x0000ffff 0 0x0000ffff
635 * 1.6 2 0x00ff00ff 1 0x000000ff
636 * 2.4 2 0x00ff00ff 2 0x00ff00ff
638 static void test_mova(IDirect3DDevice9 *device)
640 static const DWORD mova_test[] = {
641 0xfffe0200, /* vs_2_0 */
642 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
643 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
644 0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
645 0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
646 0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
647 0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
648 0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
649 0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
650 0x0200002e, 0xb0010000, 0xa0000007, /* mova a0.x, c7.x */
651 0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000, /* mov oD0, c[a0.x + 3] */
652 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
653 0x0000ffff /* END */
655 static const DWORD mov_test[] = {
656 0xfffe0101, /* vs_1_1 */
657 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
658 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
659 0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
660 0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
661 0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
662 0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
663 0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
664 0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
665 0x00000001, 0xb0010000, 0xa0000007, /* mov a0.x, c7.x */
666 0x00000001, 0xd00f0000, 0xa0e42003, /* mov oD0, c[a0.x + 3] */
667 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
668 0x0000ffff /* END */
671 static const test_data_t test_data[2][6] = {
673 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
674 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
675 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
676 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
677 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
678 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
681 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
682 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
683 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
684 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
685 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
686 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
690 static const float quad[][3] = {
691 {-1.0f, -1.0f, 0.0f},
692 {-1.0f, 1.0f, 0.0f},
693 { 1.0f, -1.0f, 0.0f},
694 { 1.0f, 1.0f, 0.0f},
697 static const D3DVERTEXELEMENT9 decl_elements[] = {
698 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
699 D3DDECL_END()
702 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
703 IDirect3DVertexShader9 *mova_shader = NULL;
704 IDirect3DVertexShader9 *mov_shader = NULL;
705 HRESULT hr;
706 UINT i, j;
708 hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
709 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
710 hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
711 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
712 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
713 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
714 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
715 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
717 hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
718 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
719 for(j = 0; j < 2; ++j)
721 for (i = 0; i < (sizeof(test_data[0]) / sizeof(test_data_t)); ++i)
723 DWORD color;
725 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
726 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
728 hr = IDirect3DDevice9_BeginScene(device);
729 ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
731 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
732 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
734 hr = IDirect3DDevice9_EndScene(device);
735 ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
737 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
738 ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
740 color = getPixelColor(device, 320, 240);
741 ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
742 test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
744 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
745 ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
747 hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
748 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
751 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
752 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
754 IDirect3DVertexDeclaration9_Release(vertex_declaration);
755 IDirect3DVertexShader9_Release(mova_shader);
756 IDirect3DVertexShader9_Release(mov_shader);
759 struct sVertex {
760 float x, y, z;
761 DWORD diffuse;
762 DWORD specular;
765 struct sVertexT {
766 float x, y, z, rhw;
767 DWORD diffuse;
768 DWORD specular;
771 static void fog_test(IDirect3DDevice9 *device)
773 HRESULT hr;
774 DWORD color;
775 BYTE r, g, b;
776 float start = 0.0f, end = 1.0f;
777 D3DCAPS9 caps;
778 int i;
780 /* Gets full z based fog with linear fog, no fog with specular color */
781 struct sVertex unstransformed_1[] = {
782 {-1, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
783 {-1, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
784 { 0, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
785 { 0, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
787 /* Ok, I am too lazy to deal with transform matrices */
788 struct sVertex unstransformed_2[] = {
789 {-1, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
790 {-1, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
791 { 0, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
792 { 0, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
794 /* Untransformed ones. Give them a different diffuse color to make the test look
795 * nicer. It also makes making sure that they are drawn correctly easier.
797 struct sVertexT transformed_1[] = {
798 {320, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
799 {640, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
800 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
801 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
803 struct sVertexT transformed_2[] = {
804 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
805 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
806 {640, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
807 {320, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
809 struct vertex rev_fog_quads[] = {
810 {-1.0, -1.0, 0.1, 0x000000ff},
811 {-1.0, 0.0, 0.1, 0x000000ff},
812 { 0.0, 0.0, 0.1, 0x000000ff},
813 { 0.0, -1.0, 0.1, 0x000000ff},
815 { 0.0, -1.0, 0.9, 0x000000ff},
816 { 0.0, 0.0, 0.9, 0x000000ff},
817 { 1.0, 0.0, 0.9, 0x000000ff},
818 { 1.0, -1.0, 0.9, 0x000000ff},
820 { 0.0, 0.0, 0.4, 0x000000ff},
821 { 0.0, 1.0, 0.4, 0x000000ff},
822 { 1.0, 1.0, 0.4, 0x000000ff},
823 { 1.0, 0.0, 0.4, 0x000000ff},
825 {-1.0, 0.0, 0.7, 0x000000ff},
826 {-1.0, 1.0, 0.7, 0x000000ff},
827 { 0.0, 1.0, 0.7, 0x000000ff},
828 { 0.0, 0.0, 0.7, 0x000000ff},
830 WORD Indices[] = {0, 1, 2, 2, 3, 0};
832 memset(&caps, 0, sizeof(caps));
833 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
834 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
835 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
836 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
838 /* Setup initial states: No lighting, fog on, fog color */
839 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
840 ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
841 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
842 ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
843 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
844 ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
846 /* First test: Both table fog and vertex fog off */
847 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
848 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
849 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
850 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
852 /* Start = 0, end = 1. Should be default, but set them */
853 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
854 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
855 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
856 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
858 if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
860 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
861 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
862 /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
863 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
864 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
865 sizeof(unstransformed_1[0]));
866 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
868 /* That makes it use the Z value */
869 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
870 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
871 /* Untransformed, vertex fog != none (or table fog != none):
872 * Use the Z value as input into the equation
874 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
875 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
876 sizeof(unstransformed_1[0]));
877 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
879 /* transformed verts */
880 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
881 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
882 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
883 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
884 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
885 sizeof(transformed_1[0]));
886 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
888 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
889 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
890 /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
891 * equation
893 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
894 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
895 sizeof(transformed_2[0]));
897 hr = IDirect3DDevice9_EndScene(device);
898 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
900 else
902 ok(FALSE, "BeginScene failed\n");
905 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
906 color = getPixelColor(device, 160, 360);
907 ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
908 color = getPixelColor(device, 160, 120);
909 ok(color == 0x0000FF00 || color == 0x0000FE00, "Untransformed vertex with linear vertex fog has color %08x\n", color);
910 color = getPixelColor(device, 480, 120);
911 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
912 if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
914 color = getPixelColor(device, 480, 360);
915 ok(color == 0x0000FF00 || color == 0x0000FE00, "Transformed vertex with linear table fog has color %08x\n", color);
917 else
919 /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
920 * The settings above result in no fogging with vertex fog
922 color = getPixelColor(device, 480, 120);
923 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
924 trace("Info: Table fog not supported by this device\n");
927 /* Now test the special case fogstart == fogend */
928 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
929 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
931 if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
933 start = 512;
934 end = 512;
935 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
936 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
937 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
938 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
940 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
941 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
942 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
943 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
944 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
945 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
947 /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
948 * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
949 * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
950 * The third transformed quad remains unfogged because the fogcoords are read from the specular
951 * color and has fixed fogstart and fogend.
953 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
954 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
955 sizeof(unstransformed_1[0]));
956 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
957 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
958 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
959 sizeof(unstransformed_1[0]));
960 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
962 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
963 ok( hr == D3D_OK, "SetFVF returned %08x\n", hr);
964 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
965 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
966 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
967 sizeof(transformed_1[0]));
968 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %08x\n", hr);
970 hr = IDirect3DDevice9_EndScene(device);
971 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
973 else
975 ok(FALSE, "BeginScene failed\n");
977 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
978 color = getPixelColor(device, 160, 360);
979 ok(color == 0x0000FF00 || color == 0x0000FE00, "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
980 color = getPixelColor(device, 160, 120);
981 ok(color == 0x0000FF00 || color == 0x0000FE00, "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
982 color = getPixelColor(device, 480, 120);
983 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
985 /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
986 * but without shaders it seems to work everywhere
988 end = 0.2;
989 start = 0.8;
990 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
991 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
992 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
993 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
994 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
995 ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
997 /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
998 * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
999 * so skip this for now
1001 for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1002 const char *mode = (i ? "table" : "vertex");
1003 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1004 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1005 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
1006 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1007 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
1008 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1009 hr = IDirect3DDevice9_BeginScene(device);
1010 ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %08x\n", hr);
1011 if(SUCCEEDED(hr)) {
1012 WORD Indices2[] = { 0, 1, 2, 2, 3, 0,
1013 4, 5, 6, 6, 7, 4,
1014 8, 9, 10, 10, 11, 8,
1015 12, 13, 14, 14, 15, 12};
1017 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
1018 16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
1019 sizeof(rev_fog_quads[0]));
1021 hr = IDirect3DDevice9_EndScene(device);
1022 ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %08x\n", hr);
1024 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1025 color = getPixelColor(device, 160, 360);
1026 ok(color == 0x0000FF00 || color == 0x0000FE00, "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00\n", mode, color);
1028 color = getPixelColor(device, 160, 120);
1029 r = (color & 0x00ff0000) >> 16;
1030 g = (color & 0x0000ff00) >> 8;
1031 b = (color & 0x000000ff);
1032 ok(r == 0x00 && g >= 0x29 && g <= 0x2d && b >= 0xd2 && b <= 0xd6,
1033 "Reversed %s fog: z=0.7 has color 0x%08x, expected\n", mode, color);
1035 color = getPixelColor(device, 480, 120);
1036 r = (color & 0x00ff0000) >> 16;
1037 g = (color & 0x0000ff00) >> 8;
1038 b = (color & 0x000000ff);
1039 ok(r == 0x00 && g >= 0xa8 && g <= 0xac && b >= 0x53 && b <= 0x57,
1040 "Reversed %s fog: z=0.4 has color 0x%08x, expected\n", mode, color);
1042 color = getPixelColor(device, 480, 360);
1043 ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
1045 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
1046 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
1047 break;
1050 /* Turn off the fog master switch to avoid confusing other tests */
1051 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1052 ok(hr == D3D_OK, "Turning off fog calculations returned %08x\n", hr);
1053 start = 0.0;
1054 end = 1.0;
1055 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1056 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1057 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1058 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1059 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1060 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %08x\n", hr);
1061 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1062 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %08x\n", hr);
1065 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
1066 * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
1067 * regardless of the actual addressing mode set. */
1068 static void test_cube_wrap(IDirect3DDevice9 *device)
1070 static const float quad[][6] = {
1071 {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1072 {-1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1073 { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1074 { 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
1077 static const D3DVERTEXELEMENT9 decl_elements[] = {
1078 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1079 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1080 D3DDECL_END()
1083 static const struct {
1084 D3DTEXTUREADDRESS mode;
1085 const char *name;
1086 } address_modes[] = {
1087 {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1088 {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1089 {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1090 {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1091 {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1094 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1095 IDirect3DCubeTexture9 *texture = NULL;
1096 IDirect3DSurface9 *surface = NULL;
1097 D3DLOCKED_RECT locked_rect;
1098 HRESULT hr;
1099 UINT x;
1100 INT y, face;
1102 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1103 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1104 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1105 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1107 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1108 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1109 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1111 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1112 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1114 for (y = 0; y < 128; ++y)
1116 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1117 for (x = 0; x < 64; ++x)
1119 *ptr++ = 0xffff0000;
1121 for (x = 64; x < 128; ++x)
1123 *ptr++ = 0xff0000ff;
1127 hr = IDirect3DSurface9_UnlockRect(surface);
1128 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1130 hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1131 D3DPOOL_DEFAULT, &texture, NULL);
1132 ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1134 /* Create cube faces */
1135 for (face = 0; face < 6; ++face)
1137 IDirect3DSurface9 *face_surface = NULL;
1139 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1140 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1142 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1143 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1145 IDirect3DSurface9_Release(face_surface);
1148 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1149 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1151 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1152 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1153 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1154 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1155 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1156 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1158 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1159 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1161 for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1163 DWORD color;
1165 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1166 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1167 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1168 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1170 hr = IDirect3DDevice9_BeginScene(device);
1171 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1173 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1174 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1176 hr = IDirect3DDevice9_EndScene(device);
1177 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1179 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1180 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1182 /* Due to the nature of this test, we sample essentially at the edge
1183 * between two faces. Because of this it's undefined from which face
1184 * the driver will sample. Fortunately that's not important for this
1185 * test, since all we care about is that it doesn't sample from the
1186 * other side of the surface or from the border. */
1187 color = getPixelColor(device, 320, 240);
1188 ok(color == 0x00ff0000 || color == 0x000000ff,
1189 "Got color 0x%08x for addressing mode %s, expected 0x00ff0000 or 0x000000ff.\n",
1190 color, address_modes[x].name);
1192 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1193 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1196 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1197 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1199 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1200 IDirect3DCubeTexture9_Release(texture);
1201 IDirect3DSurface9_Release(surface);
1204 static void offscreen_test(IDirect3DDevice9 *device)
1206 HRESULT hr;
1207 IDirect3DTexture9 *offscreenTexture = NULL;
1208 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1209 DWORD color;
1211 static const float quad[][5] = {
1212 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1213 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
1214 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1215 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
1218 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1219 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1221 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1222 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1223 if(!offscreenTexture) {
1224 trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1225 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1226 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
1227 if(!offscreenTexture) {
1228 skip("Cannot create an offscreen render target\n");
1229 goto out;
1233 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1234 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1235 if(!backbuffer) {
1236 goto out;
1239 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1240 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
1241 if(!offscreen) {
1242 goto out;
1245 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1246 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
1248 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1249 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1250 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1251 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
1252 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1253 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1254 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1255 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1256 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1257 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1259 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1260 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1261 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1262 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1263 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
1265 /* Draw without textures - Should result in a white quad */
1266 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1267 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1269 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1270 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
1271 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1272 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
1274 /* This time with the texture */
1275 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1276 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
1278 IDirect3DDevice9_EndScene(device);
1281 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1283 /* Center quad - should be white */
1284 color = getPixelColor(device, 320, 240);
1285 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1286 /* Some quad in the cleared part of the texture */
1287 color = getPixelColor(device, 170, 240);
1288 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1289 /* Part of the originally cleared back buffer */
1290 color = getPixelColor(device, 10, 10);
1291 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1292 if(0) {
1293 /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1294 * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1295 * the offscreen rendering mode this test would succeed or fail
1297 color = getPixelColor(device, 10, 470);
1298 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1301 out:
1302 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1304 /* restore things */
1305 if(backbuffer) {
1306 IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1307 IDirect3DSurface9_Release(backbuffer);
1309 if(offscreenTexture) {
1310 IDirect3DTexture9_Release(offscreenTexture);
1312 if(offscreen) {
1313 IDirect3DSurface9_Release(offscreen);
1317 /* This test tests fog in combination with shaders.
1318 * What's tested: linear fog (vertex and table) with pixel shader
1319 * linear table fog with non foggy vertex shader
1320 * vertex fog with foggy vertex shader
1321 * What's not tested: non linear fog with shader
1322 * table fog with foggy vertex shader
1324 static void fog_with_shader_test(IDirect3DDevice9 *device)
1326 HRESULT hr;
1327 DWORD color;
1328 union {
1329 float f;
1330 DWORD i;
1331 } start, end;
1332 unsigned int i, j;
1334 /* basic vertex shader without fog computation ("non foggy") */
1335 static const DWORD vertex_shader_code1[] = {
1336 0xfffe0101, /* vs_1_1 */
1337 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1338 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1339 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1340 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1341 0x0000ffff
1343 /* basic vertex shader with reversed fog computation ("foggy") */
1344 static const DWORD vertex_shader_code2[] = {
1345 0xfffe0101, /* vs_1_1 */
1346 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1347 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1348 0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1349 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1350 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1351 0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
1352 0x00000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
1353 0x0000ffff
1355 /* basic pixel shader */
1356 static const DWORD pixel_shader_code[] = {
1357 0xffff0101, /* ps_1_1 */
1358 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, vo */
1359 0x0000ffff
1362 static struct vertex quad[] = {
1363 {-1.0f, -1.0f, 0.0f, 0xFFFF0000 },
1364 {-1.0f, 1.0f, 0.0f, 0xFFFF0000 },
1365 { 1.0f, -1.0f, 0.0f, 0xFFFF0000 },
1366 { 1.0f, 1.0f, 0.0f, 0xFFFF0000 },
1369 static const D3DVERTEXELEMENT9 decl_elements[] = {
1370 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1371 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
1372 D3DDECL_END()
1375 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1376 IDirect3DVertexShader9 *vertex_shader[3] = {NULL, NULL, NULL};
1377 IDirect3DPixelShader9 *pixel_shader[2] = {NULL, NULL};
1379 /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1380 static const struct test_data_t {
1381 int vshader;
1382 int pshader;
1383 D3DFOGMODE vfog;
1384 D3DFOGMODE tfog;
1385 unsigned int color[11];
1386 } test_data[] = {
1387 /* only pixel shader: */
1388 {0, 1, 0, 3,
1389 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1390 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1391 {0, 1, 1, 3,
1392 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1393 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1394 {0, 1, 2, 3,
1395 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1396 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1397 {0, 1, 3, 0,
1398 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1399 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1400 {0, 1, 3, 3,
1401 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1402 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1404 /* vertex shader */
1405 {1, 0, 0, 0,
1406 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1407 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1408 {1, 0, 0, 3,
1409 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1410 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1411 {1, 0, 1, 3,
1412 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1413 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1415 {1, 0, 2, 3,
1416 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1417 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1418 {1, 0, 3, 3,
1419 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1420 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1422 /* vertex shader and pixel shader */
1423 {1, 1, 0, 3,
1424 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1425 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1426 {1, 1, 1, 3,
1427 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1428 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1429 {1, 1, 2, 3,
1430 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1431 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1433 {1, 1, 3, 3,
1434 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1435 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1438 #if 0 /* FIXME: these fail on GeForce 8500 */
1439 /* foggy vertex shader */
1440 {2, 0, 0, 0,
1441 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1442 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1443 {2, 0, 1, 0,
1444 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1445 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1446 {2, 0, 2, 0,
1447 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1448 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1449 {2, 0, 3, 0,
1450 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1451 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1452 #endif
1454 /* foggy vertex shader and pixel shader */
1455 {2, 1, 0, 0,
1456 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1457 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1458 {2, 1, 1, 0,
1459 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1460 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1461 {2, 1, 2, 0,
1462 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1463 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1464 {2, 1, 3, 0,
1465 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1466 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1470 /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1471 start.f=0.1f;
1472 end.f=0.9f;
1474 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1475 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1476 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1477 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1478 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1479 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1480 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1481 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1483 /* Setup initial states: No lighting, fog on, fog color */
1484 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1485 ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1486 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1487 ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1488 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1489 ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1490 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1491 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1493 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1494 ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1495 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1496 ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1498 /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1499 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1500 ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1501 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1502 ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1504 for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1506 hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1507 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1508 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1509 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1510 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1511 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1512 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1513 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1515 for(j=0; j < 11; j++)
1517 /* Don't use the whole zrange to prevent rounding errors */
1518 quad[0].z = 0.001f + (float)j / 10.02f;
1519 quad[1].z = 0.001f + (float)j / 10.02f;
1520 quad[2].z = 0.001f + (float)j / 10.02f;
1521 quad[3].z = 0.001f + (float)j / 10.02f;
1523 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1524 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1526 hr = IDirect3DDevice9_BeginScene(device);
1527 ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1529 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1530 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1532 hr = IDirect3DDevice9_EndScene(device);
1533 ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1535 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1537 /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1538 color = getPixelColor(device, 128, 240);
1539 ok(color_match(color, test_data[i].color[j], 13),
1540 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1541 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1545 /* reset states */
1546 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1547 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1548 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1549 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1550 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1551 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1552 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1553 ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1555 IDirect3DVertexShader9_Release(vertex_shader[1]);
1556 IDirect3DVertexShader9_Release(vertex_shader[2]);
1557 IDirect3DPixelShader9_Release(pixel_shader[1]);
1558 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1561 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
1562 unsigned int i, x, y;
1563 HRESULT hr;
1564 IDirect3DTexture9 *texture[2] = {NULL, NULL};
1565 D3DLOCKED_RECT locked_rect;
1567 /* Generate the textures */
1568 for(i=0; i<2; i++)
1570 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1571 D3DPOOL_MANAGED, &texture[i], NULL);
1572 ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1574 hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
1575 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1576 for (y = 0; y < 128; ++y)
1578 if(i)
1579 { /* Set up black texture with 2x2 texel white spot in the middle */
1580 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1581 for (x = 0; x < 128; ++x)
1583 if(y>62 && y<66 && x>62 && x<66)
1584 *ptr++ = 0xffffffff;
1585 else
1586 *ptr++ = 0xff000000;
1589 else
1590 { /* Set up a displacement map which points away from the center parallel to the closest axis.
1591 * (if multiplied with bumpenvmat)
1593 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1594 for (x = 0; x < 128; ++x)
1596 if(abs(x-64)>abs(y-64))
1598 if(x < 64)
1599 *ptr++ = 0xc000;
1600 else
1601 *ptr++ = 0x4000;
1603 else
1605 if(y < 64)
1606 *ptr++ = 0x0040;
1607 else
1608 *ptr++ = 0x00c0;
1613 hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
1614 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1616 hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
1617 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1619 /* Disable texture filtering */
1620 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1621 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1622 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1623 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1625 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1626 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
1627 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1628 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
1632 /* test the behavior of the texbem instruction
1633 * with normal 2D and projective 2D textures
1635 static void texbem_test(IDirect3DDevice9 *device)
1637 HRESULT hr;
1638 DWORD color;
1639 int i;
1641 static const DWORD pixel_shader_code[] = {
1642 0xffff0101, /* ps_1_1*/
1643 0x00000042, 0xb00f0000, /* tex t0*/
1644 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
1645 0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
1646 0x0000ffff
1648 static const DWORD double_texbem_code[] = {
1649 0xffff0103, /* ps_1_3 */
1650 0x00000042, 0xb00f0000, /* tex t0 */
1651 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0 */
1652 0x00000042, 0xb00f0002, /* tex t2 */
1653 0x00000043, 0xb00f0003, 0xb0e40002, /* texbem t3, t2 */
1654 0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003, /* add r0, t1, t3 */
1655 0x0000ffff /* end */
1659 static const float quad[][7] = {
1660 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
1661 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
1662 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
1663 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
1665 static const float quad_proj[][9] = {
1666 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 128.0f},
1667 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 128.0f, 0.0f, 128.0f},
1668 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f, 0.0f, 0.0f, 128.0f},
1669 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
1672 static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
1673 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1674 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1675 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1676 D3DDECL_END()
1678 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1679 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1680 {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1681 D3DDECL_END()
1682 } };
1684 /* use asymmetric matrix to test loading */
1685 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
1687 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1688 IDirect3DPixelShader9 *pixel_shader = NULL;
1689 IDirect3DTexture9 *texture = NULL, *texture1, *texture2;
1690 D3DLOCKED_RECT locked_rect;
1692 generate_bumpmap_textures(device);
1694 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1695 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1696 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1697 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1698 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
1700 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1701 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1703 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1704 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1706 for(i=0; i<2; i++)
1708 if(i)
1710 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
1711 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1714 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
1715 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1716 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1717 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1719 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
1720 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1721 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1722 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1724 hr = IDirect3DDevice9_BeginScene(device);
1725 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1727 if(!i)
1728 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1729 else
1730 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
1731 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1733 hr = IDirect3DDevice9_EndScene(device);
1734 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1736 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1737 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1739 color = getPixelColor(device, 320-32, 240);
1740 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1741 color = getPixelColor(device, 320+32, 240);
1742 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1743 color = getPixelColor(device, 320, 240-32);
1744 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1745 color = getPixelColor(device, 320, 240+32);
1746 ok(color_match(color, 0x00ffffff, 4), "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1748 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1749 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1750 IDirect3DPixelShader9_Release(pixel_shader);
1752 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1753 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1754 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1757 /* clean up */
1758 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1759 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1761 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
1762 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1764 for(i=0; i<2; i++)
1766 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
1767 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
1768 IDirect3DTexture9_Release(texture); /* For the GetTexture */
1769 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
1770 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1771 IDirect3DTexture9_Release(texture);
1774 /* Test double texbem */
1775 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
1776 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1777 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
1778 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1779 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
1780 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1781 hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
1782 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1784 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
1785 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1786 ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
1787 ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
1789 hr = IDirect3DTexture9_UnlockRect(texture, 0);
1790 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1792 hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
1793 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1794 ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
1795 ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
1796 hr = IDirect3DTexture9_UnlockRect(texture1, 0);
1797 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1800 /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
1801 #define tex 0x00ff0000
1802 #define tex1 0x0000ff00
1803 #define origin 0x000000ff
1804 static const DWORD pixel_data[] = {
1805 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1806 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1807 0x000000ff, tex1 , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1808 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1809 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin, 0x000000ff, tex , 0x000000ff,
1810 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1811 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1812 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1814 #undef tex1
1815 #undef tex2
1816 #undef origin
1818 hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
1819 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1820 for(i = 0; i < 8; i++) {
1821 memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
1823 hr = IDirect3DTexture9_UnlockRect(texture2, 0);
1824 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1827 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
1828 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1829 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
1830 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1831 hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
1832 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1833 hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
1834 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1835 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1836 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1837 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
1838 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1840 bumpenvmat[0] =-1.0; bumpenvmat[2] = 2.0;
1841 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.0;
1842 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1843 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1844 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1845 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1847 bumpenvmat[0] = 1.5; bumpenvmat[2] = 0.0;
1848 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.5;
1849 IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1850 IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1851 IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1852 IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1854 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1855 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1856 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1857 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1858 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1859 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1860 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1861 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1863 hr = IDirect3DDevice9_BeginScene(device);
1864 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1865 if(SUCCEEDED(hr)) {
1866 static const float double_quad[] = {
1867 -1.0, -1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
1868 1.0, -1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
1869 -1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
1870 1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
1873 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
1874 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1875 hr = IDirect3DDevice9_EndScene(device);
1876 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1878 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1879 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1880 color = getPixelColor(device, 320, 240);
1881 ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1883 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1884 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1885 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
1886 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1887 hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
1888 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1889 hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
1890 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1891 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1892 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1894 IDirect3DPixelShader9_Release(pixel_shader);
1895 IDirect3DTexture9_Release(texture);
1896 IDirect3DTexture9_Release(texture1);
1897 IDirect3DTexture9_Release(texture2);
1900 static void z_range_test(IDirect3DDevice9 *device)
1902 const struct vertex quad[] =
1904 {-1.0f, 0.0f, 1.1f, 0xffff0000},
1905 {-1.0f, 1.0f, 1.1f, 0xffff0000},
1906 { 1.0f, 0.0f, -1.1f, 0xffff0000},
1907 { 1.0f, 1.0f, -1.1f, 0xffff0000},
1909 const struct vertex quad2[] =
1911 {-1.0f, 0.0f, 1.1f, 0xff0000ff},
1912 {-1.0f, 1.0f, 1.1f, 0xff0000ff},
1913 { 1.0f, 0.0f, -1.1f, 0xff0000ff},
1914 { 1.0f, 1.0f, -1.1f, 0xff0000ff},
1917 const struct tvertex quad3[] =
1919 { 0, 240, 1.1f, 1.0, 0xffffff00},
1920 { 0, 480, 1.1f, 1.0, 0xffffff00},
1921 { 640, 240, -1.1f, 1.0, 0xffffff00},
1922 { 640, 480, -1.1f, 1.0, 0xffffff00},
1924 const struct tvertex quad4[] =
1926 { 0, 240, 1.1f, 1.0, 0xff00ff00},
1927 { 0, 480, 1.1f, 1.0, 0xff00ff00},
1928 { 640, 240, -1.1f, 1.0, 0xff00ff00},
1929 { 640, 480, -1.1f, 1.0, 0xff00ff00},
1931 HRESULT hr;
1932 DWORD color;
1933 IDirect3DVertexShader9 *shader;
1934 IDirect3DVertexDeclaration9 *decl;
1935 D3DCAPS9 caps;
1936 const DWORD shader_code[] = {
1937 0xfffe0101, /* vs_1_1 */
1938 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1939 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1940 0x00000001, 0xd00f0000, 0xa0e40000, /* mov oD0, c0 */
1941 0x0000ffff /* end */
1943 static const D3DVERTEXELEMENT9 decl_elements[] = {
1944 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1945 D3DDECL_END()
1947 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
1948 * then call Present. Then clear the color buffer to make sure it has some defined content
1949 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
1950 * by the depth value.
1952 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
1953 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1954 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1955 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
1957 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
1958 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1959 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
1960 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1961 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
1962 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1963 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
1964 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1965 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1966 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1968 hr = IDirect3DDevice9_BeginScene(device);
1969 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
1970 if(hr == D3D_OK)
1972 /* Test the untransformed vertex path */
1973 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
1974 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
1975 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
1976 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1977 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
1978 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
1980 /* Test the transformed vertex path */
1981 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
1982 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1984 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
1985 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
1986 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
1987 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1988 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
1989 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
1991 hr = IDirect3DDevice9_EndScene(device);
1992 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
1995 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1996 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1998 /* Do not test the exact corner pixels, but go pretty close to them */
2000 /* Clipped because z > 1.0 */
2001 color = getPixelColor(device, 28, 238);
2002 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2003 color = getPixelColor(device, 28, 241);
2004 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2006 /* Not clipped, > z buffer clear value(0.75) */
2007 color = getPixelColor(device, 31, 238);
2008 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2009 color = getPixelColor(device, 31, 241);
2010 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2011 color = getPixelColor(device, 100, 238);
2012 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2013 color = getPixelColor(device, 100, 241);
2014 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2016 /* Not clipped, < z buffer clear value */
2017 color = getPixelColor(device, 104, 238);
2018 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2019 color = getPixelColor(device, 104, 241);
2020 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2021 color = getPixelColor(device, 318, 238);
2022 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2023 color = getPixelColor(device, 318, 241);
2024 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2026 /* Clipped because z < 0.0 */
2027 color = getPixelColor(device, 321, 238);
2028 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2029 color = getPixelColor(device, 321, 241);
2030 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2032 /* Test the shader path */
2033 IDirect3DDevice9_GetDeviceCaps(device, &caps);
2034 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
2035 skip("Vertex shaders not supported\n");
2036 goto out;
2038 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
2039 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
2040 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2041 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
2043 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
2045 IDirect3DDevice9_SetVertexDeclaration(device, decl);
2046 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2047 IDirect3DDevice9_SetVertexShader(device, shader);
2048 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2050 hr = IDirect3DDevice9_BeginScene(device);
2051 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2052 if(hr == D3D_OK)
2054 float colorf[] = {1.0, 0.0, 0.0, 1.0};
2055 float colorf2[] = {0.0, 0.0, 1.0, 1.0};
2056 IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
2057 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
2058 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2059 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2060 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2061 IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
2062 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
2063 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %08x\n", hr);
2065 hr = IDirect3DDevice9_EndScene(device);
2066 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2069 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2070 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
2071 IDirect3DDevice9_SetVertexShader(device, NULL);
2072 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
2074 IDirect3DVertexDeclaration9_Release(decl);
2075 IDirect3DVertexShader9_Release(shader);
2077 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2078 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2079 /* Z < 1.0 */
2080 color = getPixelColor(device, 28, 238);
2081 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2083 /* 1.0 < z < 0.75 */
2084 color = getPixelColor(device, 31, 238);
2085 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2086 color = getPixelColor(device, 100, 238);
2087 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2089 /* 0.75 < z < 0.0 */
2090 color = getPixelColor(device, 104, 238);
2091 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2092 color = getPixelColor(device, 318, 238);
2093 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2095 /* 0.0 < z */
2096 color = getPixelColor(device, 321, 238);
2097 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2099 out:
2100 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2101 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2102 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2103 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2104 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2105 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2108 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2110 D3DSURFACE_DESC desc;
2111 D3DLOCKED_RECT l;
2112 HRESULT hr;
2113 unsigned int x, y;
2114 DWORD *mem;
2116 memset(&desc, 0, sizeof(desc));
2117 memset(&l, 0, sizeof(l));
2118 hr = IDirect3DSurface9_GetDesc(surface, &desc);
2119 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
2120 hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2121 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
2122 if(FAILED(hr)) return;
2124 for(y = 0; y < desc.Height; y++)
2126 mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2127 for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2129 mem[x] = color;
2132 hr = IDirect3DSurface9_UnlockRect(surface);
2133 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
2136 /* This tests a variety of possible StretchRect() situations */
2137 static void stretchrect_test(IDirect3DDevice9 *device)
2139 HRESULT hr;
2140 IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL;
2141 IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL;
2142 IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2143 IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2144 IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2145 IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2146 IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2147 IDirect3DSurface9 *orig_rt = NULL;
2148 DWORD color;
2150 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2151 ok(hr == D3D_OK, "Can't get render target, hr = %08x\n", hr);
2152 if(!orig_rt) {
2153 goto out;
2156 /* Create our temporary surfaces in system memory */
2157 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2158 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2159 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2160 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2162 /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2163 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2164 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2165 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2166 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2167 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2168 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %08x\n", hr);
2170 /* Create render target surfaces */
2171 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2172 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2173 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2174 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2175 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2176 ok(hr == D3D_OK, "Creating the render target surface failed with %08x\n", hr);
2178 /* Create render target textures */
2179 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2180 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2181 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2182 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2183 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2184 ok(hr == D3D_OK, "Creating the render target texture failed with %08x\n", hr);
2185 if (tex_rt32) {
2186 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2187 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2189 if (tex_rt64) {
2190 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2191 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2193 if (tex_rt_dest64) {
2194 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2195 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2198 /* Create regular textures in D3DPOOL_DEFAULT */
2199 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2200 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2201 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2202 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2203 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2204 ok(hr == D3D_OK, "Creating the regular texture failed with %08x\n", hr);
2205 if (tex32) {
2206 hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2207 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2209 if (tex64) {
2210 hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2211 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2213 if (tex_dest64) {
2214 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2215 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
2218 /*********************************************************************
2219 * Tests for when the source parameter is an offscreen plain surface *
2220 *********************************************************************/
2222 /* Fill the offscreen 64x64 surface with green */
2223 if (surf_offscreen64)
2224 fill_surface(surf_offscreen64, 0xff00ff00);
2226 /* offscreenplain ==> offscreenplain, same size */
2227 if(surf_offscreen64 && surf_offscreen_dest64) {
2228 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2229 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2231 if (hr == D3D_OK) {
2232 color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2233 ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2237 /* offscreenplain ==> rendertarget texture, same size */
2238 if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2239 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2240 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2242 /* We can't lock rendertarget textures, so copy to our temp surface first */
2243 if (hr == D3D_OK) {
2244 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2245 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2248 if (hr == D3D_OK) {
2249 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2250 ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2254 /* offscreenplain ==> rendertarget surface, same size */
2255 if(surf_offscreen64 && surf_rt_dest64) {
2256 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2257 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2259 if (hr == D3D_OK) {
2260 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2261 ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2265 /* offscreenplain ==> texture, same size (should fail) */
2266 if(surf_offscreen64 && surf_tex_dest64) {
2267 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2268 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2271 /* Fill the smaller offscreen surface with red */
2272 fill_surface(surf_offscreen32, 0xffff0000);
2274 /* offscreenplain ==> offscreenplain, scaling (should fail) */
2275 if(surf_offscreen32 && surf_offscreen64) {
2276 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2277 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2280 /* offscreenplain ==> rendertarget texture, scaling */
2281 if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2282 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2283 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2285 /* We can't lock rendertarget textures, so copy to our temp surface first */
2286 if (hr == D3D_OK) {
2287 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2288 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2291 if (hr == D3D_OK) {
2292 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2293 ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2297 /* offscreenplain ==> rendertarget surface, scaling */
2298 if(surf_offscreen32 && surf_rt_dest64) {
2299 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2300 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2302 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2303 ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2306 /* offscreenplain ==> texture, scaling (should fail) */
2307 if(surf_offscreen32 && surf_tex_dest64) {
2308 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2309 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2312 /************************************************************
2313 * Tests for when the source parameter is a regular texture *
2314 ************************************************************/
2316 /* Fill the surface of the regular texture with blue */
2317 if (surf_tex64 && surf_temp64) {
2318 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2319 fill_surface(surf_temp64, 0xff0000ff);
2320 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2321 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2324 /* texture ==> offscreenplain, same size */
2325 if(surf_tex64 && surf_offscreen64) {
2326 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2327 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2330 /* texture ==> rendertarget texture, same size */
2331 if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2332 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2333 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2335 /* We can't lock rendertarget textures, so copy to our temp surface first */
2336 if (hr == D3D_OK) {
2337 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2338 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2341 if (hr == D3D_OK) {
2342 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2343 ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2347 /* texture ==> rendertarget surface, same size */
2348 if(surf_tex64 && surf_rt_dest64) {
2349 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2350 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2352 if (hr == D3D_OK) {
2353 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2354 ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2358 /* texture ==> texture, same size (should fail) */
2359 if(surf_tex64 && surf_tex_dest64) {
2360 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2361 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2364 /* Fill the surface of the smaller regular texture with red */
2365 if (surf_tex32 && surf_temp32) {
2366 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2367 fill_surface(surf_temp32, 0xffff0000);
2368 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2369 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2372 /* texture ==> offscreenplain, scaling (should fail) */
2373 if(surf_tex32 && surf_offscreen64) {
2374 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2375 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2378 /* texture ==> rendertarget texture, scaling */
2379 if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
2380 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
2381 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2383 /* We can't lock rendertarget textures, so copy to our temp surface first */
2384 if (hr == D3D_OK) {
2385 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2386 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2389 if (hr == D3D_OK) {
2390 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2391 ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2395 /* texture ==> rendertarget surface, scaling */
2396 if(surf_tex32 && surf_rt_dest64) {
2397 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
2398 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2400 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2401 ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2404 /* texture ==> texture, scaling (should fail) */
2405 if(surf_tex32 && surf_tex_dest64) {
2406 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
2407 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2410 /*****************************************************************
2411 * Tests for when the source parameter is a rendertarget texture *
2412 *****************************************************************/
2414 /* Fill the surface of the rendertarget texture with white */
2415 if (surf_tex_rt64 && surf_temp64) {
2416 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2417 fill_surface(surf_temp64, 0xffffffff);
2418 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
2419 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2422 /* rendertarget texture ==> offscreenplain, same size */
2423 if(surf_tex_rt64 && surf_offscreen64) {
2424 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
2425 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2428 /* rendertarget texture ==> rendertarget texture, same size */
2429 if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2430 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2431 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2433 /* We can't lock rendertarget textures, so copy to our temp surface first */
2434 if (hr == D3D_OK) {
2435 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2436 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2439 if (hr == D3D_OK) {
2440 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2441 ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2445 /* rendertarget texture ==> rendertarget surface, same size */
2446 if(surf_tex_rt64 && surf_rt_dest64) {
2447 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
2448 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2450 if (hr == D3D_OK) {
2451 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2452 ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2456 /* rendertarget texture ==> texture, same size (should fail) */
2457 if(surf_tex_rt64 && surf_tex_dest64) {
2458 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
2459 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2462 /* Fill the surface of the smaller rendertarget texture with red */
2463 if (surf_tex_rt32 && surf_temp32) {
2464 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2465 fill_surface(surf_temp32, 0xffff0000);
2466 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
2467 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %08x\n", hr);
2470 /* rendertarget texture ==> offscreenplain, scaling (should fail) */
2471 if(surf_tex_rt32 && surf_offscreen64) {
2472 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
2473 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2476 /* rendertarget texture ==> rendertarget texture, scaling */
2477 if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2478 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2479 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2481 /* We can't lock rendertarget textures, so copy to our temp surface first */
2482 if (hr == D3D_OK) {
2483 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2484 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2487 if (hr == D3D_OK) {
2488 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2489 ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2493 /* rendertarget texture ==> rendertarget surface, scaling */
2494 if(surf_tex_rt32 && surf_rt_dest64) {
2495 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
2496 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2498 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2499 ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2502 /* rendertarget texture ==> texture, scaling (should fail) */
2503 if(surf_tex_rt32 && surf_tex_dest64) {
2504 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
2505 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2508 /*****************************************************************
2509 * Tests for when the source parameter is a rendertarget surface *
2510 *****************************************************************/
2512 /* Fill the surface of the rendertarget surface with black */
2513 if (surf_rt64)
2514 fill_surface(surf_rt64, 0xff000000);
2516 /* rendertarget texture ==> offscreenplain, same size */
2517 if(surf_rt64 && surf_offscreen64) {
2518 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
2519 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2522 /* rendertarget surface ==> rendertarget texture, same size */
2523 if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2524 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2525 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2527 /* We can't lock rendertarget textures, so copy to our temp surface first */
2528 if (hr == D3D_OK) {
2529 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2530 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2533 if (hr == D3D_OK) {
2534 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2535 ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2539 /* rendertarget surface ==> rendertarget surface, same size */
2540 if(surf_rt64 && surf_rt_dest64) {
2541 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
2542 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2544 if (hr == D3D_OK) {
2545 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2546 ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2550 /* rendertarget surface ==> texture, same size (should fail) */
2551 if(surf_rt64 && surf_tex_dest64) {
2552 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
2553 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2556 /* Fill the surface of the smaller rendertarget texture with red */
2557 if (surf_rt32)
2558 fill_surface(surf_rt32, 0xffff0000);
2560 /* rendertarget surface ==> offscreenplain, scaling (should fail) */
2561 if(surf_rt32 && surf_offscreen64) {
2562 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
2563 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2566 /* rendertarget surface ==> rendertarget texture, scaling */
2567 if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2568 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2569 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2571 /* We can't lock rendertarget textures, so copy to our temp surface first */
2572 if (hr == D3D_OK) {
2573 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2574 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %08x\n", hr);
2577 if (hr == D3D_OK) {
2578 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2579 ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2583 /* rendertarget surface ==> rendertarget surface, scaling */
2584 if(surf_rt32 && surf_rt_dest64) {
2585 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
2586 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
2588 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2589 ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2592 /* rendertarget surface ==> texture, scaling (should fail) */
2593 if(surf_rt32 && surf_tex_dest64) {
2594 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
2595 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2598 /* TODO: Test when source and destination RECT parameters are given... */
2599 /* TODO: Test format conversions */
2602 out:
2603 /* Clean up */
2604 if (surf_rt32)
2605 IDirect3DSurface9_Release(surf_rt32);
2606 if (surf_rt64)
2607 IDirect3DSurface9_Release(surf_rt64);
2608 if (surf_rt_dest64)
2609 IDirect3DSurface9_Release(surf_rt_dest64);
2610 if (surf_temp32)
2611 IDirect3DSurface9_Release(surf_temp32);
2612 if (surf_temp64)
2613 IDirect3DSurface9_Release(surf_temp64);
2614 if (surf_offscreen32)
2615 IDirect3DSurface9_Release(surf_offscreen32);
2616 if (surf_offscreen64)
2617 IDirect3DSurface9_Release(surf_offscreen64);
2618 if (surf_offscreen_dest64)
2619 IDirect3DSurface9_Release(surf_offscreen_dest64);
2621 if (tex_rt32) {
2622 if (surf_tex_rt32)
2623 IDirect3DSurface9_Release(surf_tex_rt32);
2624 IDirect3DTexture9_Release(tex_rt32);
2626 if (tex_rt64) {
2627 if (surf_tex_rt64)
2628 IDirect3DSurface9_Release(surf_tex_rt64);
2629 IDirect3DTexture9_Release(tex_rt64);
2631 if (tex_rt_dest64) {
2632 if (surf_tex_rt_dest64)
2633 IDirect3DSurface9_Release(surf_tex_rt_dest64);
2634 IDirect3DTexture9_Release(tex_rt_dest64);
2636 if (tex32) {
2637 if (surf_tex32)
2638 IDirect3DSurface9_Release(surf_tex32);
2639 IDirect3DTexture9_Release(tex32);
2641 if (tex64) {
2642 if (surf_tex64)
2643 IDirect3DSurface9_Release(surf_tex64);
2644 IDirect3DTexture9_Release(tex64);
2646 if (tex_dest64) {
2647 if (surf_tex_dest64)
2648 IDirect3DSurface9_Release(surf_tex_dest64);
2649 IDirect3DTexture9_Release(tex_dest64);
2652 if (orig_rt) {
2653 hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
2654 ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %08x\n", hr);
2655 IDirect3DSurface9_Release(orig_rt);
2659 static void maxmip_test(IDirect3DDevice9 *device)
2661 IDirect3DTexture9 *texture = NULL;
2662 IDirect3DSurface9 *surface = NULL;
2663 HRESULT hr;
2664 DWORD color;
2665 const float quads[] = {
2666 -1.0, -1.0, 0.0, 0.0, 0.0,
2667 -1.0, 0.0, 0.0, 0.0, 1.0,
2668 0.0, -1.0, 0.0, 1.0, 0.0,
2669 0.0, 0.0, 0.0, 1.0, 1.0,
2671 0.0, -1.0, 0.0, 0.0, 0.0,
2672 0.0, 0.0, 0.0, 0.0, 1.0,
2673 1.0, -1.0, 0.0, 1.0, 0.0,
2674 1.0, 0.0, 0.0, 1.0, 1.0,
2676 0.0, 0.0, 0.0, 0.0, 0.0,
2677 0.0, 1.0, 0.0, 0.0, 1.0,
2678 1.0, 0.0, 0.0, 1.0, 0.0,
2679 1.0, 1.0, 0.0, 1.0, 1.0,
2681 -1.0, 0.0, 0.0, 0.0, 0.0,
2682 -1.0, 1.0, 0.0, 0.0, 1.0,
2683 0.0, 0.0, 0.0, 1.0, 0.0,
2684 0.0, 1.0, 0.0, 1.0, 1.0,
2687 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2688 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2690 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
2691 &texture, NULL);
2692 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
2693 if(!texture)
2695 skip("Failed to create test texture\n");
2696 return;
2699 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
2700 fill_surface(surface, 0xffff0000);
2701 IDirect3DSurface9_Release(surface);
2702 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
2703 fill_surface(surface, 0xff00ff00);
2704 IDirect3DSurface9_Release(surface);
2705 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
2706 fill_surface(surface, 0xff0000ff);
2707 IDirect3DSurface9_Release(surface);
2709 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2710 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2711 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2712 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
2714 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2715 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2717 hr = IDirect3DDevice9_BeginScene(device);
2718 if(SUCCEEDED(hr))
2720 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2721 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2722 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2723 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2725 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2726 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2727 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2728 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2730 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2731 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2732 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2733 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2735 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2736 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2737 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2738 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2739 hr = IDirect3DDevice9_EndScene(device);
2742 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2743 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2744 /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
2745 color = getPixelColor(device, 160, 360);
2746 ok(color == 0x00FF0000, "MapMip 0, no mipfilter has color %08x\n", color);
2747 color = getPixelColor(device, 160, 120);
2748 ok(color == 0x00FF0000, "MapMip 3, no mipfilter has color %08x\n", color);
2749 color = getPixelColor(device, 480, 120);
2750 ok(color == 0x00FF0000, "MapMip 2, no mipfilter has color %08x\n", color);
2751 color = getPixelColor(device, 480, 360);
2752 ok(color == 0x00FF0000, "MapMip 1, no mipfilter has color %08x\n", color);
2754 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2755 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
2757 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
2758 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2760 hr = IDirect3DDevice9_BeginScene(device);
2761 if(SUCCEEDED(hr))
2763 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2764 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2765 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2766 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2768 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2769 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2770 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2771 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2773 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2774 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2775 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2776 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2778 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2779 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2780 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2781 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2782 hr = IDirect3DDevice9_EndScene(device);
2785 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2786 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2787 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2788 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2790 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2791 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2792 /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
2793 * samples from the highest level in the texture(level 2)
2795 color = getPixelColor(device, 160, 360);
2796 ok(color == 0x00FF0000, "MapMip 0, point mipfilter has color %08x\n", color);
2797 color = getPixelColor(device, 160, 120);
2798 ok(color == 0x000000FF, "MapMip 3, point mipfilter has color %08x\n", color);
2799 color = getPixelColor(device, 480, 120);
2800 ok(color == 0x000000FF, "MapMip 2, point mipfilter has color %08x\n", color);
2801 color = getPixelColor(device, 480, 360);
2802 ok(color == 0x0000FF00, "MapMip 1, point mipfilter has color %08x\n", color);
2804 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2805 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2806 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2807 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
2808 IDirect3DTexture9_Release(texture);
2811 static void release_buffer_test(IDirect3DDevice9 *device)
2813 IDirect3DVertexBuffer9 *vb = NULL;
2814 IDirect3DIndexBuffer9 *ib = NULL;
2815 HRESULT hr;
2816 BYTE *data;
2817 long ref;
2819 static const struct vertex quad[] = {
2820 {-1.0, -1.0, 0.1, 0xffff0000},
2821 {-1.0, 1.0, 0.1, 0xffff0000},
2822 { 1.0, 1.0, 0.1, 0xffff0000},
2824 {-1.0, -1.0, 0.1, 0xff00ff00},
2825 {-1.0, 1.0, 0.1, 0xff00ff00},
2826 { 1.0, 1.0, 0.1, 0xff00ff00}
2828 short indices[] = {3, 4, 5};
2830 /* Index and vertex buffers should always be creatable */
2831 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
2832 D3DPOOL_MANAGED, &vb, NULL);
2833 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
2834 if(!vb) {
2835 skip("Failed to create a vertex buffer\n");
2836 return;
2838 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
2839 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
2840 if(!ib) {
2841 skip("Failed to create an index buffer\n");
2842 return;
2845 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
2846 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
2847 memcpy(data, quad, sizeof(quad));
2848 hr = IDirect3DVertexBuffer9_Unlock(vb);
2849 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
2851 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
2852 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
2853 memcpy(data, indices, sizeof(indices));
2854 hr = IDirect3DIndexBuffer9_Unlock(ib);
2855 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2857 hr = IDirect3DDevice9_SetIndices(device, ib);
2858 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
2859 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
2860 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
2861 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2862 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
2864 /* Now destroy the bound index buffer and draw again */
2865 ref = IDirect3DIndexBuffer9_Release(ib);
2866 ok(ref == 0, "Index Buffer reference count is %08ld\n", ref);
2868 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
2869 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
2871 hr = IDirect3DDevice9_BeginScene(device);
2872 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2873 if(SUCCEEDED(hr))
2875 /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
2876 * making assumptions about the indices or vertices
2878 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
2879 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
2880 hr = IDirect3DDevice9_EndScene(device);
2881 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2884 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2885 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
2887 hr = IDirect3DDevice9_SetIndices(device, NULL);
2888 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2889 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
2890 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2892 /* Index buffer was already destroyed as part of the test */
2893 IDirect3DVertexBuffer9_Release(vb);
2896 static void float_texture_test(IDirect3DDevice9 *device)
2898 IDirect3D9 *d3d = NULL;
2899 HRESULT hr;
2900 IDirect3DTexture9 *texture = NULL;
2901 D3DLOCKED_RECT lr;
2902 float *data;
2903 DWORD color;
2904 float quad[] = {
2905 -1.0, -1.0, 0.1, 0.0, 0.0,
2906 -1.0, 1.0, 0.1, 0.0, 1.0,
2907 1.0, -1.0, 0.1, 1.0, 0.0,
2908 1.0, 1.0, 0.1, 1.0, 1.0,
2911 memset(&lr, 0, sizeof(lr));
2912 IDirect3DDevice9_GetDirect3D(device, &d3d);
2913 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
2914 D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
2915 skip("D3DFMT_R32F textures not supported\n");
2916 goto out;
2919 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
2920 D3DPOOL_MANAGED, &texture, NULL);
2921 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
2922 if(!texture) {
2923 skip("Failed to create R32F texture\n");
2924 goto out;
2927 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
2928 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
2929 data = lr.pBits;
2930 *data = 0.0;
2931 hr = IDirect3DTexture9_UnlockRect(texture, 0);
2932 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
2934 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2935 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2937 hr = IDirect3DDevice9_BeginScene(device);
2938 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2939 if(SUCCEEDED(hr))
2941 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2942 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
2944 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2945 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2947 hr = IDirect3DDevice9_EndScene(device);
2948 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2950 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2951 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
2953 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2954 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
2956 color = getPixelColor(device, 240, 320);
2957 ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
2959 out:
2960 if(texture) IDirect3DTexture9_Release(texture);
2961 IDirect3D9_Release(d3d);
2964 static void g16r16_texture_test(IDirect3DDevice9 *device)
2966 IDirect3D9 *d3d = NULL;
2967 HRESULT hr;
2968 IDirect3DTexture9 *texture = NULL;
2969 D3DLOCKED_RECT lr;
2970 DWORD *data;
2971 DWORD color, red, green, blue;
2972 float quad[] = {
2973 -1.0, -1.0, 0.1, 0.0, 0.0,
2974 -1.0, 1.0, 0.1, 0.0, 1.0,
2975 1.0, -1.0, 0.1, 1.0, 0.0,
2976 1.0, 1.0, 0.1, 1.0, 1.0,
2979 memset(&lr, 0, sizeof(lr));
2980 IDirect3DDevice9_GetDirect3D(device, &d3d);
2981 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
2982 D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
2983 skip("D3DFMT_G16R16 textures not supported\n");
2984 goto out;
2987 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
2988 D3DPOOL_MANAGED, &texture, NULL);
2989 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
2990 if(!texture) {
2991 skip("Failed to create D3DFMT_G16R16 texture\n");
2992 goto out;
2995 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
2996 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
2997 data = lr.pBits;
2998 *data = 0x0f00f000;
2999 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3000 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3002 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3003 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3005 hr = IDirect3DDevice9_BeginScene(device);
3006 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3007 if(SUCCEEDED(hr))
3009 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3010 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3012 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3013 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3015 hr = IDirect3DDevice9_EndScene(device);
3016 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3018 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3019 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3021 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3022 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3024 color = getPixelColor(device, 240, 320);
3025 red = (color & 0x00ff0000) >> 16;
3026 green = (color & 0x0000ff00) >> 8;
3027 blue = (color & 0x000000ff) >> 0;
3028 ok(blue == 0xff && red >= 0xef && red <= 0xf1 && green >= 0x0e && green <= 0x10,
3029 "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00F00FFF\n", color);
3031 out:
3032 if(texture) IDirect3DTexture9_Release(texture);
3033 IDirect3D9_Release(d3d);
3036 static void texture_transform_flags_test(IDirect3DDevice9 *device)
3038 HRESULT hr;
3039 IDirect3D9 *d3d;
3040 D3DFORMAT fmt = D3DFMT_X8R8G8B8;
3041 D3DCAPS9 caps;
3042 IDirect3DTexture9 *texture = NULL;
3043 IDirect3DVolumeTexture9 *volume = NULL;
3044 unsigned int x, y, z;
3045 D3DLOCKED_RECT lr;
3046 D3DLOCKED_BOX lb;
3047 DWORD color;
3048 UINT w, h;
3049 IDirect3DVertexDeclaration9 *decl, *decl2, *decl3;
3050 float identity[16] = {1.0, 0.0, 0.0, 0.0,
3051 0.0, 1.0, 0.0, 0.0,
3052 0.0, 0.0, 1.0, 0.0,
3053 0.0, 0.0, 0.0, 1.0};
3054 static const D3DVERTEXELEMENT9 decl_elements[] = {
3055 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3056 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3057 D3DDECL_END()
3059 static const D3DVERTEXELEMENT9 decl_elements2[] = {
3060 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3061 {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3062 D3DDECL_END()
3064 static const D3DVERTEXELEMENT9 decl_elements3[] = {
3065 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3066 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3067 D3DDECL_END()
3069 static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
3070 0x00, 0xff, 0x00, 0x00,
3071 0x00, 0x00, 0x00, 0x00,
3072 0x00, 0x00, 0x00, 0x00};
3074 memset(&lr, 0, sizeof(lr));
3075 memset(&lb, 0, sizeof(lb));
3076 IDirect3DDevice9_GetDirect3D(device, &d3d);
3077 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
3078 D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
3079 fmt = D3DFMT_A16B16G16R16;
3081 IDirect3D9_Release(d3d);
3083 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3084 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3085 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
3086 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3087 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
3088 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
3089 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
3090 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
3091 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
3092 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
3093 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
3094 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
3095 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3096 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
3097 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3098 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
3099 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3100 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
3101 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
3102 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
3103 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3104 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
3105 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3106 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3108 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3109 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
3110 w = min(1024, caps.MaxTextureWidth);
3111 h = min(1024, caps.MaxTextureHeight);
3112 hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
3113 0, fmt, D3DPOOL_MANAGED, &texture, NULL);
3114 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3115 if(!texture) {
3116 skip("Failed to create the test texture\n");
3117 return;
3120 /* Unfortunately there is no easy way to set up a texture coordinate passthrough
3121 * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
3122 * 1.0 in red and green for the x and y coords
3124 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3125 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
3126 for(y = 0; y < h; y++) {
3127 for(x = 0; x < w; x++) {
3128 double r_f = (double) y / (double) h;
3129 double g_f = (double) x / (double) w;
3130 if(fmt == D3DFMT_A16B16G16R16) {
3131 unsigned short r, g;
3132 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
3133 r = (unsigned short) (r_f * 65536.0);
3134 g = (unsigned short) (g_f * 65536.0);
3135 dst[0] = r;
3136 dst[1] = g;
3137 dst[2] = 0;
3138 dst[3] = 65535;
3139 } else {
3140 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
3141 unsigned char r = (unsigned char) (r_f * 255.0);
3142 unsigned char g = (unsigned char) (g_f * 255.0);
3143 dst[0] = 0;
3144 dst[1] = g;
3145 dst[2] = r;
3146 dst[3] = 255;
3150 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3151 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
3152 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3153 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3155 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3156 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3157 hr = IDirect3DDevice9_BeginScene(device);
3158 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3159 if(SUCCEEDED(hr))
3161 float quad1[] = {
3162 -1.0, -1.0, 0.1, 1.0, 1.0,
3163 -1.0, 0.0, 0.1, 1.0, 1.0,
3164 0.0, -1.0, 0.1, 1.0, 1.0,
3165 0.0, 0.0, 0.1, 1.0, 1.0,
3167 float quad2[] = {
3168 -1.0, 0.0, 0.1, 1.0, 1.0,
3169 -1.0, 1.0, 0.1, 1.0, 1.0,
3170 0.0, 0.0, 0.1, 1.0, 1.0,
3171 0.0, 1.0, 0.1, 1.0, 1.0,
3173 float quad3[] = {
3174 0.0, 0.0, 0.1, 0.5, 0.5,
3175 0.0, 1.0, 0.1, 0.5, 0.5,
3176 1.0, 0.0, 0.1, 0.5, 0.5,
3177 1.0, 1.0, 0.1, 0.5, 0.5,
3179 float quad4[] = {
3180 320, 480, 0.1, 1.0, 0.0, 1.0,
3181 320, 240, 0.1, 1.0, 0.0, 1.0,
3182 640, 480, 0.1, 1.0, 0.0, 1.0,
3183 640, 240, 0.1, 1.0, 0.0, 1.0,
3185 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3186 0.0, 0.0, 0.0, 0.0,
3187 0.0, 0.0, 0.0, 0.0,
3188 0.0, 0.0, 0.0, 0.0};
3190 /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
3191 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3192 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3193 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3194 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3196 /* What happens with transforms enabled? */
3197 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3198 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3199 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3200 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3202 /* What happens if 4 coords are used, but only 2 given ?*/
3203 mat[8] = 1.0;
3204 mat[13] = 1.0;
3205 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3206 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3207 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3208 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3209 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3210 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3212 /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
3213 * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
3214 * due to the coords in the vertices. (turns out red, indeed)
3216 memset(mat, 0, sizeof(mat));
3217 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3218 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3219 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
3220 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3221 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3222 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3223 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3224 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3226 hr = IDirect3DDevice9_EndScene(device);
3227 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3229 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3230 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3231 color = getPixelColor(device, 160, 360);
3232 ok(color == 0x00FFFF00 || color == 0x00FEFE00, "quad 1 has color %08x, expected 0x00FFFF00\n", color);
3233 color = getPixelColor(device, 160, 120);
3234 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3235 color = getPixelColor(device, 480, 120);
3236 ok(color == 0x0000FF00 || color == 0x0000FE00, "quad 3 has color %08x, expected 0x0000FF00\n", color);
3237 color = getPixelColor(device, 480, 360);
3238 ok(color == 0x00FF0000 || 0x00FE0000, "quad 4 has color %08x, expected 0x00FF0000\n", color);
3240 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3241 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3243 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3244 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3245 hr = IDirect3DDevice9_BeginScene(device);
3246 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3247 if(SUCCEEDED(hr))
3249 float quad1[] = {
3250 -1.0, -1.0, 0.1, 0.8, 0.2,
3251 -1.0, 0.0, 0.1, 0.8, 0.2,
3252 0.0, -1.0, 0.1, 0.8, 0.2,
3253 0.0, 0.0, 0.1, 0.8, 0.2,
3255 float quad2[] = {
3256 -1.0, 0.0, 0.1, 0.5, 1.0,
3257 -1.0, 1.0, 0.1, 0.5, 1.0,
3258 0.0, 0.0, 0.1, 0.5, 1.0,
3259 0.0, 1.0, 0.1, 0.5, 1.0,
3261 float quad3[] = {
3262 0.0, 0.0, 0.1, 0.5, 1.0,
3263 0.0, 1.0, 0.1, 0.5, 1.0,
3264 1.0, 0.0, 0.1, 0.5, 1.0,
3265 1.0, 1.0, 0.1, 0.5, 1.0,
3267 float quad4[] = {
3268 0.0, -1.0, 0.1, 0.8, 0.2,
3269 0.0, 0.0, 0.1, 0.8, 0.2,
3270 1.0, -1.0, 0.1, 0.8, 0.2,
3271 1.0, 0.0, 0.1, 0.8, 0.2,
3273 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3274 0.0, 0.0, 0.0, 0.0,
3275 0.0, 1.0, 0.0, 0.0,
3276 0.0, 0.0, 0.0, 0.0};
3278 /* What happens to the default 1 in the 3rd coordinate if it is disabled?
3280 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3281 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3282 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3283 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3285 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3286 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3288 /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
3289 * it behaves like COUNT2 because normal textures require 2 coords
3291 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3292 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3293 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
3294 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3296 /* Just to be sure, the same as quad2 above */
3297 memset(mat, 0, sizeof(mat));
3298 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3299 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3300 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3301 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3302 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3303 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3305 /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
3306 * used? And what happens to the first?
3308 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3309 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3310 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3311 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3313 hr = IDirect3DDevice9_EndScene(device);
3314 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3316 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3317 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3318 color = getPixelColor(device, 160, 360);
3319 ok(color == 0x00FF0000 || color == 0x00FE0000, "quad 1 has color %08x, expected 0x00FF0000\n", color);
3320 color = getPixelColor(device, 160, 120);
3321 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3322 color = getPixelColor(device, 480, 120);
3323 ok(color == 0x00ff8000 || color == 0x00fe7f00 || color == 0x00000000,
3324 "quad 3 has color %08x, expected 0x00ff8000\n", color);
3325 color = getPixelColor(device, 480, 360);
3326 ok(color == 0x0033cc00 || color == 0x0032cb00 || color == 0x00FF0000 || color == 0x00FE0000,
3327 "quad 4 has color %08x, expected 0x0033cc00\n", color);
3329 IDirect3DTexture9_Release(texture);
3331 /* Test projected textures, without any fancy matrices */
3332 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3333 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3334 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
3335 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
3336 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3337 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3338 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl3);
3339 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3341 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3342 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
3343 for(x = 0; x < 4; x++) {
3344 memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
3346 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3347 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
3348 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3349 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3351 hr = IDirect3DDevice9_BeginScene(device);
3352 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3353 if(SUCCEEDED(hr))
3355 const float proj_quads[] = {
3356 -1.0, -1.0, 0.1, 0.0, 0.0, 4.0, 6.0,
3357 1.0, -1.0, 0.1, 4.0, 0.0, 4.0, 6.0,
3358 -1.0, 0.0, 0.1, 0.0, 4.0, 4.0, 6.0,
3359 1.0, 0.0, 0.1, 4.0, 4.0, 4.0, 6.0,
3360 -1.0, 0.0, 0.1, 0.0, 0.0, 4.0, 6.0,
3361 1.0, 0.0, 0.1, 4.0, 0.0, 4.0, 6.0,
3362 -1.0, 1.0, 0.1, 0.0, 4.0, 4.0, 6.0,
3363 1.0, 1.0, 0.1, 4.0, 4.0, 4.0, 6.0,
3366 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3367 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3368 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[0*7], 7 * sizeof(float));
3369 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3371 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED);
3372 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3373 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[4*7], 7 * sizeof(float));
3374 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3376 hr = IDirect3DDevice9_EndScene(device);
3377 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3380 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3381 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
3382 IDirect3DTexture9_Release(texture);
3384 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3385 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3386 color = getPixelColor(device, 158, 118);
3387 ok(color == 0x00000000, "proj: Pixel 158/118 has color 0x%08x, expected 0x00000000\n", color);
3388 color = getPixelColor(device, 162, 118);
3389 ok(color == 0x00000000, "proj: Pixel 162/118 has color 0x%08x, expected 0x00000000\n", color);
3390 color = getPixelColor(device, 158, 122);
3391 ok(color == 0x00000000, "proj: Pixel 158/122 has color 0x%08x, expected 0x00000000\n", color);
3392 color = getPixelColor(device, 162, 122);
3393 ok(color == 0x00FFFFFF, "proj: Pixel 162/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3395 color = getPixelColor(device, 158, 178);
3396 ok(color == 0x00000000, "proj: Pixel 158/178 has color 0x%08x, expected 0x00000000\n", color);
3397 color = getPixelColor(device, 162, 178);
3398 ok(color == 0x00FFFFFF, "proj: Pixel 158/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3399 color = getPixelColor(device, 158, 182);
3400 ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3401 color = getPixelColor(device, 162, 182);
3402 ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3404 color = getPixelColor(device, 318, 118);
3405 ok(color == 0x00000000, "proj: Pixel 318/118 has color 0x%08x, expected 0x00000000\n", color);
3406 color = getPixelColor(device, 322, 118);
3407 ok(color == 0x00000000, "proj: Pixel 322/118 has color 0x%08x, expected 0x00000000\n", color);
3408 color = getPixelColor(device, 318, 122);
3409 ok(color == 0x00FFFFFF, "proj: Pixel 318/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3410 color = getPixelColor(device, 322, 122);
3411 ok(color == 0x00000000, "proj: Pixel 322/122 has color 0x%08x, expected 0x00000000\n", color);
3413 color = getPixelColor(device, 318, 178);
3414 ok(color == 0x00FFFFFF, "proj: Pixel 318/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3415 color = getPixelColor(device, 322, 178);
3416 ok(color == 0x00000000, "proj: Pixel 322/178 has color 0x%08x, expected 0x00000000\n", color);
3417 color = getPixelColor(device, 318, 182);
3418 ok(color == 0x00000000, "proj: Pixel 318/182 has color 0x%08x, expected 0x00000000\n", color);
3419 color = getPixelColor(device, 322, 182);
3420 ok(color == 0x00000000, "proj: Pixel 322/182 has color 0x%08x, expected 0x00000000\n", color);
3422 color = getPixelColor(device, 238, 298);
3423 ok(color == 0x00000000, "proj: Pixel 238/298 has color 0x%08x, expected 0x00000000\n", color);
3424 color = getPixelColor(device, 242, 298);
3425 ok(color == 0x00000000, "proj: Pixel 242/298 has color 0x%08x, expected 0x00000000\n", color);
3426 color = getPixelColor(device, 238, 302);
3427 ok(color == 0x00000000, "proj: Pixel 238/302 has color 0x%08x, expected 0x00000000\n", color);
3428 color = getPixelColor(device, 242, 302);
3429 ok(color == 0x00FFFFFF, "proj: Pixel 242/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3431 color = getPixelColor(device, 238, 388);
3432 ok(color == 0x00000000, "proj: Pixel 238/388 has color 0x%08x, expected 0x00000000\n", color);
3433 color = getPixelColor(device, 242, 388);
3434 ok(color == 0x00FFFFFF, "proj: Pixel 242/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3435 color = getPixelColor(device, 238, 392);
3436 ok(color == 0x00000000, "proj: Pixel 238/392 has color 0x%08x, expected 0x00000000\n", color);
3437 color = getPixelColor(device, 242, 392);
3438 ok(color == 0x00000000, "proj: Pixel 242/392 has color 0x%08x, expected 0x00000000\n", color);
3440 color = getPixelColor(device, 478, 298);
3441 ok(color == 0x00000000, "proj: Pixel 478/298 has color 0x%08x, expected 0x00000000\n", color);
3442 color = getPixelColor(device, 482, 298);
3443 ok(color == 0x00000000, "proj: Pixel 482/298 has color 0x%08x, expected 0x00000000\n", color);
3444 color = getPixelColor(device, 478, 302);
3445 ok(color == 0x00FFFFFF, "proj: Pixel 478/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3446 color = getPixelColor(device, 482, 302);
3447 ok(color == 0x00000000, "proj: Pixel 482/302 has color 0x%08x, expected 0x00000000\n", color);
3449 color = getPixelColor(device, 478, 388);
3450 ok(color == 0x00FFFFFF, "proj: Pixel 478/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3451 color = getPixelColor(device, 482, 388);
3452 ok(color == 0x00000000, "proj: Pixel 482/388 has color 0x%08x, expected 0x00000000\n", color);
3453 color = getPixelColor(device, 478, 392);
3454 ok(color == 0x00000000, "proj: Pixel 478/392 has color 0x%08x, expected 0x00000000\n", color);
3455 color = getPixelColor(device, 482, 392);
3456 ok(color == 0x00000000, "proj: Pixel 482/392 has color 0x%08x, expected 0x00000000\n", color);
3458 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3459 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3460 /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
3461 * Thus watch out if sampling from texels between 0 and 1.
3463 hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
3464 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
3465 "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
3466 if(!volume) {
3467 skip("Failed to create a volume texture\n");
3468 goto out;
3471 hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
3472 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
3473 for(z = 0; z < 32; z++) {
3474 for(y = 0; y < 32; y++) {
3475 for(x = 0; x < 32; x++) {
3476 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
3477 void *mem = ((char *) lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
3478 float r_f = (float) x / 31.0;
3479 float g_f = (float) y / 31.0;
3480 float b_f = (float) z / 31.0;
3482 if(fmt == D3DFMT_A16B16G16R16) {
3483 unsigned short *mem_s = mem;
3484 mem_s[0] = r_f * 65535.0;
3485 mem_s[1] = g_f * 65535.0;
3486 mem_s[2] = b_f * 65535.0;
3487 mem_s[3] = 65535;
3488 } else {
3489 unsigned char *mem_c = mem;
3490 mem_c[0] = b_f * 255.0;
3491 mem_c[1] = g_f * 255.0;
3492 mem_c[2] = r_f * 255.0;
3493 mem_c[3] = 255;
3498 hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
3499 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3501 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
3502 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
3504 hr = IDirect3DDevice9_BeginScene(device);
3505 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3506 if(SUCCEEDED(hr))
3508 float quad1[] = {
3509 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3510 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3511 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3512 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
3514 float quad2[] = {
3515 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3516 -1.0, 1.0, 0.1, 1.0, 1.0, 1.0,
3517 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3518 0.0, 1.0, 0.1, 1.0, 1.0, 1.0
3520 float quad3[] = {
3521 0.0, 0.0, 0.1, 0.0, 0.0,
3522 0.0, 1.0, 0.1, 0.0, 0.0,
3523 1.0, 0.0, 0.1, 0.0, 0.0,
3524 1.0, 1.0, 0.1, 0.0, 0.0
3526 float quad4[] = {
3527 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3528 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3529 1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3530 1.0, 0.0, 0.1, 1.0, 1.0, 1.0
3532 float mat[16] = {1.0, 0.0, 0.0, 0.0,
3533 0.0, 0.0, 1.0, 0.0,
3534 0.0, 1.0, 0.0, 0.0,
3535 0.0, 0.0, 0.0, 1.0};
3536 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3537 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3539 /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
3540 * values
3542 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3543 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3544 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3545 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3546 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3547 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3549 /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
3550 * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
3551 * otherwise the w will be missing(blue).
3552 * turns out that on nvidia cards the blue color is missing, so it is an output modification.
3553 * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
3555 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3556 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3557 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
3558 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3560 /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 4 */
3561 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3562 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3563 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3564 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3565 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3566 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3567 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3568 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3570 /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
3571 * disable. ATI extends it up to the amount of values needed for the volume texture
3573 memset(mat, 0, sizeof(mat));
3574 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3575 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3576 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3577 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3578 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3579 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3580 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3581 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3583 hr = IDirect3DDevice9_EndScene(device);
3584 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3586 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3587 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3589 color = getPixelColor(device, 160, 360);
3590 ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
3591 color = getPixelColor(device, 160, 120);
3592 ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
3593 "quad 2 has color %08x, expected 0x00ffff00\n", color);
3594 color = getPixelColor(device, 480, 120);
3595 ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
3596 color = getPixelColor(device, 480, 360);
3597 ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
3599 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
3600 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3601 hr = IDirect3DDevice9_BeginScene(device);
3602 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
3603 if(SUCCEEDED(hr))
3605 float quad1[] = {
3606 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3607 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3608 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3609 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
3611 float quad2[] = {
3612 -1.0, 0.0, 0.1,
3613 -1.0, 1.0, 0.1,
3614 0.0, 0.0, 0.1,
3615 0.0, 1.0, 0.1,
3617 float quad3[] = {
3618 0.0, 0.0, 0.1, 1.0,
3619 0.0, 1.0, 0.1, 1.0,
3620 1.0, 0.0, 0.1, 1.0,
3621 1.0, 1.0, 0.1, 1.0
3623 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3624 0.0, 0.0, 0.0, 0.0,
3625 0.0, 0.0, 0.0, 0.0,
3626 0.0, 1.0, 0.0, 0.0};
3627 float mat2[16] = {0.0, 0.0, 0.0, 1.0,
3628 1.0, 0.0, 0.0, 0.0,
3629 0.0, 1.0, 0.0, 0.0,
3630 0.0, 0.0, 1.0, 0.0};
3631 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3632 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3634 /* Default values? 4 coords used, 3 passed. What happens to the 4th?
3636 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3637 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3638 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3639 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3640 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3641 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3643 /* None passed */
3644 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3645 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3646 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3647 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
3648 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
3649 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3651 /* 4 used, 1 passed */
3652 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
3653 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3654 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
3655 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3656 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
3657 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3659 hr = IDirect3DDevice9_EndScene(device);
3660 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
3662 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3663 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3664 color = getPixelColor(device, 160, 360);
3665 ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
3666 color = getPixelColor(device, 160, 120);
3667 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
3668 color = getPixelColor(device, 480, 120);
3669 ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
3670 /* Quad4: unused */
3672 IDirect3DVolumeTexture9_Release(volume);
3674 out:
3675 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
3676 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
3677 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
3678 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3679 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3680 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
3681 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3682 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
3683 IDirect3DVertexDeclaration9_Release(decl);
3684 IDirect3DVertexDeclaration9_Release(decl2);
3685 IDirect3DVertexDeclaration9_Release(decl3);
3688 static void texdepth_test(IDirect3DDevice9 *device)
3690 IDirect3DPixelShader9 *shader;
3691 HRESULT hr;
3692 const float texdepth_test_data1[] = { 0.25, 2.0, 0.0, 0.0};
3693 const float texdepth_test_data2[] = { 0.25, 0.5, 0.0, 0.0};
3694 const float texdepth_test_data3[] = {-1.00, 0.1, 0.0, 0.0};
3695 const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
3696 const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
3697 const float texdepth_test_data6[] = { 1.00, 0.5, 0.0, 0.0};
3698 const float texdepth_test_data7[] = { 0.50, 0.0, 0.0, 0.0};
3699 DWORD shader_code[] = {
3700 0xffff0104, /* ps_1_4 */
3701 0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c1, 0, 0, 1, 1 */
3702 0x00000001, 0x800f0005, 0xa0e40000, /* mov r5, c0 */
3703 0x0000fffd, /* phase */
3704 0x00000057, 0x800f0005, /* texdepth r5 */
3705 0x00000001, 0x800f0000, 0xa0e40001, /* mov r0, c1 */
3706 0x0000ffff /* end */
3708 DWORD color;
3709 float vertex[] = {
3710 -1.0, -1.0, 0.0,
3711 1.0, -1.0, 1.0,
3712 -1.0, 1.0, 0.0,
3713 1.0, 1.0, 1.0
3716 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
3717 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
3719 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
3720 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
3721 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3722 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3723 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3724 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3725 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
3726 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3727 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3729 /* Fill the depth buffer with a gradient */
3730 hr = IDirect3DDevice9_BeginScene(device);
3731 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3732 if(SUCCEEDED(hr))
3734 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3735 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3736 hr = IDirect3DDevice9_EndScene(device);
3737 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3740 /* Now perform the actual tests. Same geometry, but with the shader */
3741 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
3742 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3743 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3744 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3745 hr = IDirect3DDevice9_SetPixelShader(device, shader);
3746 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3748 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
3749 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3750 hr = IDirect3DDevice9_BeginScene(device);
3751 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3752 if(SUCCEEDED(hr))
3754 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3755 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3757 hr = IDirect3DDevice9_EndScene(device);
3758 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3761 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3762 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3763 color = getPixelColor(device, 158, 240);
3764 ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3765 color = getPixelColor(device, 162, 240);
3766 ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
3768 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3770 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
3771 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3772 hr = IDirect3DDevice9_BeginScene(device);
3773 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3774 if(SUCCEEDED(hr))
3776 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3777 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3779 hr = IDirect3DDevice9_EndScene(device);
3780 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3783 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3784 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3785 color = getPixelColor(device, 318, 240);
3786 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3787 color = getPixelColor(device, 322, 240);
3788 ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3790 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3792 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
3793 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3794 hr = IDirect3DDevice9_BeginScene(device);
3795 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3796 if(SUCCEEDED(hr))
3798 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3799 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3801 hr = IDirect3DDevice9_EndScene(device);
3802 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3804 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3805 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3807 color = getPixelColor(device, 1, 240);
3808 ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
3810 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3812 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
3813 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3814 hr = IDirect3DDevice9_BeginScene(device);
3815 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3816 if(SUCCEEDED(hr))
3818 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3819 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3821 hr = IDirect3DDevice9_EndScene(device);
3822 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3824 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3825 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3826 color = getPixelColor(device, 318, 240);
3827 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3828 color = getPixelColor(device, 322, 240);
3829 ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
3831 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3833 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
3834 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3835 hr = IDirect3DDevice9_BeginScene(device);
3836 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3837 if(SUCCEEDED(hr))
3839 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3840 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3842 hr = IDirect3DDevice9_EndScene(device);
3843 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3845 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3846 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3848 color = getPixelColor(device, 1, 240);
3849 ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3851 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3853 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
3854 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3855 hr = IDirect3DDevice9_BeginScene(device);
3856 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3857 if(SUCCEEDED(hr))
3859 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3860 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3862 hr = IDirect3DDevice9_EndScene(device);
3863 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3865 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3866 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3868 color = getPixelColor(device, 638, 240);
3869 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
3871 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3873 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
3874 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
3875 hr = IDirect3DDevice9_BeginScene(device);
3876 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3877 if(SUCCEEDED(hr))
3879 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3880 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3882 hr = IDirect3DDevice9_EndScene(device);
3883 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3885 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3886 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3888 color = getPixelColor(device, 638, 240);
3889 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
3891 /* Cleanup */
3892 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3893 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3894 IDirect3DPixelShader9_Release(shader);
3896 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
3897 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3898 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3899 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
3902 static void texkill_test(IDirect3DDevice9 *device)
3904 IDirect3DPixelShader9 *shader;
3905 HRESULT hr;
3906 DWORD color;
3908 const float vertex[] = {
3909 /* bottom top right left */
3910 -1.0, -1.0, 1.0, -0.1, 0.9, 0.9, -0.1,
3911 1.0, -1.0, 0.0, 0.9, -0.1, 0.9, -0.1,
3912 -1.0, 1.0, 1.0, -0.1, 0.9, -0.1, 0.9,
3913 1.0, 1.0, 0.0, 0.9, -0.1, -0.1, 0.9,
3916 DWORD shader_code_11[] = {
3917 0xffff0101, /* ps_1_1 */
3918 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
3919 0x00000041, 0xb00f0000, /* texkill t0 */
3920 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
3921 0x0000ffff /* end */
3923 DWORD shader_code_20[] = {
3924 0xffff0200, /* ps_2_0 */
3925 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
3926 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
3927 0x01000041, 0xb00f0000, /* texkill t0 */
3928 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
3929 0x0000ffff /* end */
3932 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3933 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
3934 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
3935 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
3937 hr = IDirect3DDevice9_SetPixelShader(device, shader);
3938 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
3939 hr = IDirect3DDevice9_BeginScene(device);
3940 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
3941 if(SUCCEEDED(hr))
3943 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
3944 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
3945 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
3946 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3947 hr = IDirect3DDevice9_EndScene(device);
3948 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
3950 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3951 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
3952 color = getPixelColor(device, 63, 46);
3953 ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
3954 color = getPixelColor(device, 66, 46);
3955 ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
3956 color = getPixelColor(device, 63, 49);
3957 ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
3958 color = getPixelColor(device, 66, 49);
3959 ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
3961 color = getPixelColor(device, 578, 46);
3962 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3963 color = getPixelColor(device, 575, 46);
3964 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3965 color = getPixelColor(device, 578, 49);
3966 ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
3967 color = getPixelColor(device, 575, 49);
3968 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3970 color = getPixelColor(device, 63, 430);
3971 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3972 color = getPixelColor(device, 63, 433);
3973 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3974 color = getPixelColor(device, 66, 433);
3975 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
3976 color = getPixelColor(device, 66, 430);
3977 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3979 color = getPixelColor(device, 578, 430);
3980 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3981 color = getPixelColor(device, 578, 433);
3982 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3983 color = getPixelColor(device, 575, 433);
3984 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
3985 color = getPixelColor(device, 575, 430);
3986 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3988 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3989 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
3990 IDirect3DPixelShader9_Release(shader);
3992 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3993 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
3994 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
3995 if(FAILED(hr)) {
3996 skip("Failed to create 2.0 test shader, most likely not supported\n");
3997 return;
4000 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4001 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4002 hr = IDirect3DDevice9_BeginScene(device);
4003 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4004 if(SUCCEEDED(hr))
4006 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
4007 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4008 hr = IDirect3DDevice9_EndScene(device);
4009 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4011 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4013 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4014 color = getPixelColor(device, 63, 46);
4015 ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
4016 color = getPixelColor(device, 66, 46);
4017 ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
4018 color = getPixelColor(device, 63, 49);
4019 ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
4020 color = getPixelColor(device, 66, 49);
4021 ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
4023 color = getPixelColor(device, 578, 46);
4024 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4025 color = getPixelColor(device, 575, 46);
4026 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4027 color = getPixelColor(device, 578, 49);
4028 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4029 color = getPixelColor(device, 575, 49);
4030 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4032 color = getPixelColor(device, 63, 430);
4033 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4034 color = getPixelColor(device, 63, 433);
4035 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4036 color = getPixelColor(device, 66, 433);
4037 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4038 color = getPixelColor(device, 66, 430);
4039 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4041 color = getPixelColor(device, 578, 430);
4042 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
4043 color = getPixelColor(device, 578, 433);
4044 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
4045 color = getPixelColor(device, 575, 433);
4046 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
4047 color = getPixelColor(device, 575, 430);
4048 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
4050 /* Cleanup */
4051 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4052 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
4053 IDirect3DPixelShader9_Release(shader);
4056 static void x8l8v8u8_test(IDirect3DDevice9 *device)
4058 IDirect3D9 *d3d9;
4059 HRESULT hr;
4060 IDirect3DTexture9 *texture;
4061 IDirect3DPixelShader9 *shader;
4062 IDirect3DPixelShader9 *shader2;
4063 D3DLOCKED_RECT lr;
4064 DWORD color;
4065 DWORD shader_code[] = {
4066 0xffff0101, /* ps_1_1 */
4067 0x00000042, 0xb00f0000, /* tex t0 */
4068 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4069 0x0000ffff /* end */
4071 DWORD shader_code2[] = {
4072 0xffff0101, /* ps_1_1 */
4073 0x00000042, 0xb00f0000, /* tex t0 */
4074 0x00000001, 0x800f0000, 0xb0ff0000, /* mov r0, t0.w */
4075 0x0000ffff /* end */
4078 float quad[] = {
4079 -1.0, -1.0, 0.1, 0.5, 0.5,
4080 1.0, -1.0, 0.1, 0.5, 0.5,
4081 -1.0, 1.0, 0.1, 0.5, 0.5,
4082 1.0, 1.0, 0.1, 0.5, 0.5,
4085 memset(&lr, 0, sizeof(lr));
4086 IDirect3DDevice9_GetDirect3D(device, &d3d9);
4087 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4088 0, D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
4089 IDirect3D9_Release(d3d9);
4090 if(FAILED(hr)) {
4091 skip("No D3DFMT_X8L8V8U8 support\n");
4094 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4095 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4097 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
4098 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
4099 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4100 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
4101 *((DWORD *) lr.pBits) = 0x11ca3141;
4102 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4103 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
4105 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4106 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4107 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
4108 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4110 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4111 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4112 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4113 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4114 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4115 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4117 hr = IDirect3DDevice9_BeginScene(device);
4118 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4119 if(SUCCEEDED(hr))
4121 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4122 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4124 hr = IDirect3DDevice9_EndScene(device);
4125 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4127 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4128 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4129 color = getPixelColor(device, 578, 430);
4130 ok(color == 0x008262ca || color == 0x008363ca || color == 0x008362ca,
4131 "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
4133 hr = IDirect3DDevice9_SetPixelShader(device, shader2);
4134 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4135 hr = IDirect3DDevice9_BeginScene(device);
4136 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4137 if(SUCCEEDED(hr))
4139 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4140 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4142 hr = IDirect3DDevice9_EndScene(device);
4143 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4145 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4146 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4147 color = getPixelColor(device, 578, 430);
4148 ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
4150 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4151 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4152 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4153 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4154 IDirect3DPixelShader9_Release(shader);
4155 IDirect3DPixelShader9_Release(shader2);
4156 IDirect3DTexture9_Release(texture);
4159 static void autogen_mipmap_test(IDirect3DDevice9 *device)
4161 HRESULT hr;
4162 IDirect3D9 *d3d;
4163 IDirect3DTexture9 *texture = NULL;
4164 IDirect3DSurface9 *surface;
4165 DWORD color;
4166 const RECT r1 = {256, 256, 512, 512};
4167 const RECT r2 = {512, 256, 768, 512};
4168 const RECT r3 = {256, 512, 512, 768};
4169 const RECT r4 = {512, 512, 768, 768};
4170 unsigned int x, y;
4171 D3DLOCKED_RECT lr;
4172 memset(&lr, 0, sizeof(lr));
4174 IDirect3DDevice9_GetDirect3D(device, &d3d);
4175 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4176 D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
4177 skip("No autogenmipmap support\n");
4178 IDirect3D9_Release(d3d);
4179 return;
4181 IDirect3D9_Release(d3d);
4183 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4184 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4186 /* Make the mipmap big, so that a smaller mipmap is used
4188 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
4189 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4190 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4192 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4193 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
4194 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
4195 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
4196 for(y = 0; y < 1024; y++) {
4197 for(x = 0; x < 1024; x++) {
4198 DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
4199 POINT pt;
4201 pt.x = x;
4202 pt.y = y;
4203 if(PtInRect(&r1, pt)) {
4204 *dst = 0xffff0000;
4205 } else if(PtInRect(&r2, pt)) {
4206 *dst = 0xff00ff00;
4207 } else if(PtInRect(&r3, pt)) {
4208 *dst = 0xff0000ff;
4209 } else if(PtInRect(&r4, pt)) {
4210 *dst = 0xff000000;
4211 } else {
4212 *dst = 0xffffffff;
4216 hr = IDirect3DSurface9_UnlockRect(surface);
4217 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
4218 IDirect3DSurface9_Release(surface);
4220 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4221 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4222 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4223 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4225 hr = IDirect3DDevice9_BeginScene(device);
4226 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4227 if(SUCCEEDED(hr)) {
4228 const float quad[] = {
4229 -0.5, -0.5, 0.1, 0.0, 0.0,
4230 -0.5, 0.5, 0.1, 0.0, 1.0,
4231 0.5, -0.5, 0.1, 1.0, 0.0,
4232 0.5, 0.5, 0.1, 1.0, 1.0
4235 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4236 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4237 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4238 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4239 hr = IDirect3DDevice9_EndScene(device);
4240 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4242 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4243 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4244 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4245 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4246 IDirect3DTexture9_Release(texture);
4248 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4249 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4250 color = getPixelColor(device, 200, 200);
4251 ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
4252 color = getPixelColor(device, 280, 200);
4253 ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
4254 color = getPixelColor(device, 360, 200);
4255 ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
4256 color = getPixelColor(device, 440, 200);
4257 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4258 color = getPixelColor(device, 200, 270);
4259 ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
4260 color = getPixelColor(device, 280, 270);
4261 ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
4262 color = getPixelColor(device, 360, 270);
4263 ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
4264 color = getPixelColor(device, 440, 270);
4265 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4268 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
4270 IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
4271 IDirect3DVertexDeclaration9 *decl;
4272 HRESULT hr;
4273 DWORD color;
4274 DWORD shader_code_11[] = {
4275 0xfffe0101, /* vs_1_1 */
4276 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4277 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4278 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4279 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4280 0x0000ffff /* end */
4282 DWORD shader_code_11_2[] = {
4283 0xfffe0101, /* vs_1_1 */
4284 0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
4285 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
4286 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4287 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4288 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4289 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4290 0x0000ffff /* end */
4292 DWORD shader_code_20[] = {
4293 0xfffe0200, /* vs_2_0 */
4294 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4295 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4296 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4297 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4298 0x0000ffff /* end */
4300 DWORD shader_code_20_2[] = {
4301 0xfffe0200, /* vs_2_0 */
4302 0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
4303 0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
4304 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4305 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4306 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4307 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4308 0x0000ffff /* end */
4310 static const D3DVERTEXELEMENT9 decl_elements[] = {
4311 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4312 D3DDECL_END()
4314 float quad1[] = {
4315 -1.0, -1.0, 0.1,
4316 0.0, -1.0, 0.1,
4317 -1.0, 0.0, 0.1,
4318 0.0, 0.0, 0.1
4320 float quad2[] = {
4321 0.0, -1.0, 0.1,
4322 1.0, -1.0, 0.1,
4323 0.0, 0.0, 0.1,
4324 1.0, 0.0, 0.1
4326 float quad3[] = {
4327 0.0, 0.0, 0.1,
4328 1.0, 0.0, 0.1,
4329 0.0, 1.0, 0.1,
4330 1.0, 1.0, 0.1
4332 float quad4[] = {
4333 -1.0, 0.0, 0.1,
4334 0.0, 0.0, 0.1,
4335 -1.0, 1.0, 0.1,
4336 0.0, 1.0, 0.1
4338 float test_data_c1[4] = { 1.25, -0.50, -1.50, 1.0};
4339 float test_data_c2[4] = { -0.50, 1.25, 2.00, 1.0};
4341 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4342 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4344 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
4345 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4346 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
4347 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
4348 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
4349 if(FAILED(hr)) shader_20 = NULL;
4350 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
4351 if(FAILED(hr)) shader_20_2 = NULL;
4352 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4353 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4355 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
4356 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4357 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
4358 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
4359 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4360 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4362 hr = IDirect3DDevice9_BeginScene(device);
4363 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4364 if(SUCCEEDED(hr))
4366 hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
4367 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4368 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4369 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4371 hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
4372 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4373 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4374 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4376 if(shader_20) {
4377 hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
4378 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4379 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4380 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4383 if(shader_20_2) {
4384 hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
4385 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4386 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4387 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4390 hr = IDirect3DDevice9_EndScene(device);
4391 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4393 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4394 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4396 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4397 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4398 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4399 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
4401 color = getPixelColor(device, 160, 360);
4402 ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4403 "quad 1 has color %08x, expected 0x00bfbf80\n", color);
4404 color = getPixelColor(device, 480, 360);
4405 ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4406 "quad 2 has color %08x, expected 0x00bfbf80\n", color);
4407 if(shader_20) {
4408 color = getPixelColor(device, 160, 120);
4409 ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4410 "quad 3 has color %08x, expected 0x00bfbf80\n", color);
4412 if(shader_20_2) {
4413 color = getPixelColor(device, 480, 120);
4414 ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4415 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4418 IDirect3DVertexDeclaration9_Release(decl);
4419 if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
4420 if(shader_20) IDirect3DVertexShader9_Release(shader_20);
4421 IDirect3DVertexShader9_Release(shader_11_2);
4422 IDirect3DVertexShader9_Release(shader_11);
4425 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
4427 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
4428 HRESULT hr;
4429 DWORD color;
4430 DWORD shader_code_11[] = {
4431 0xffff0101, /* ps_1_1 */
4432 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4433 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4434 0x0000ffff /* end */
4436 DWORD shader_code_12[] = {
4437 0xffff0102, /* ps_1_2 */
4438 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4439 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4440 0x0000ffff /* end */
4442 /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
4443 * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
4444 * During development of this test, 1.3 shaders were verified too
4446 DWORD shader_code_14[] = {
4447 0xffff0104, /* ps_1_4 */
4448 /* Try to make one constant local. It gets clamped too, although the binary contains
4449 * the bigger numbers
4451 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
4452 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4453 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4454 0x0000ffff /* end */
4456 DWORD shader_code_20[] = {
4457 0xffff0200, /* ps_2_0 */
4458 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4459 0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4460 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4461 0x0000ffff /* end */
4463 float quad1[] = {
4464 -1.0, -1.0, 0.1,
4465 0.0, -1.0, 0.1,
4466 -1.0, 0.0, 0.1,
4467 0.0, 0.0, 0.1
4469 float quad2[] = {
4470 0.0, -1.0, 0.1,
4471 1.0, -1.0, 0.1,
4472 0.0, 0.0, 0.1,
4473 1.0, 0.0, 0.1
4475 float quad3[] = {
4476 0.0, 0.0, 0.1,
4477 1.0, 0.0, 0.1,
4478 0.0, 1.0, 0.1,
4479 1.0, 1.0, 0.1
4481 float quad4[] = {
4482 -1.0, 0.0, 0.1,
4483 0.0, 0.0, 0.1,
4484 -1.0, 1.0, 0.1,
4485 0.0, 1.0, 0.1
4487 float test_data_c1[4] = { 1.25, -0.50, -1.50, 1.0};
4488 float test_data_c2[4] = { -0.50, 1.25, 2.00, 1.0};
4490 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4491 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4493 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4494 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4495 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4496 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4497 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4498 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4499 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
4500 if(FAILED(hr)) shader_20 = NULL;
4502 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4503 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4504 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4505 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4506 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4507 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4509 hr = IDirect3DDevice9_BeginScene(device);
4510 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4511 if(SUCCEEDED(hr))
4513 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4514 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4515 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4516 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4518 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4519 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4520 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4521 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4523 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4524 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4525 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4526 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4528 if(shader_20) {
4529 hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
4530 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4531 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4532 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4535 hr = IDirect3DDevice9_EndScene(device);
4536 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4538 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4539 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4541 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4542 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4544 color = getPixelColor(device, 160, 360);
4545 ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4546 "quad 1 has color %08x, expected 0x00808000\n", color);
4547 color = getPixelColor(device, 480, 360);
4548 ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4549 "quad 2 has color %08x, expected 0x00808000\n", color);
4550 color = getPixelColor(device, 480, 120);
4551 ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4552 "quad 3 has color %08x, expected 0x00808000\n", color);
4553 if(shader_20) {
4554 color = getPixelColor(device, 160, 120);
4555 ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4556 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4559 if(shader_20) IDirect3DPixelShader9_Release(shader_20);
4560 IDirect3DPixelShader9_Release(shader_14);
4561 IDirect3DPixelShader9_Release(shader_12);
4562 IDirect3DPixelShader9_Release(shader_11);
4565 static void dp2add_ps_test(IDirect3DDevice9 *device)
4567 IDirect3DPixelShader9 *shader_dp2add = NULL;
4568 IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
4569 HRESULT hr;
4570 DWORD color;
4572 /* DP2ADD is defined as: (src0.r * src1.r) + (src0.g * src1.g) + src2.
4573 * One D3D restriction of all shader instructions except SINCOS is that no more than 2
4574 * source tokens can be constants. So, for this exercise, we move contents of c0 to
4575 * r0 first.
4576 * The result here for the r,g,b components should be roughly 0.5:
4577 * (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
4578 static const DWORD shader_code_dp2add[] = {
4579 0xffff0200, /* ps_2_0 */
4580 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0 */
4582 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4583 0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add r0.rgb, r0, r0, r0.a */
4585 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
4586 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4587 0x0000ffff /* end */
4590 /* Test the _sat modifier, too. Result here should be:
4591 * DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
4592 * _SAT: ==> 1.0
4593 * ADD: (1.0 + -0.5) = 0.5
4595 static const DWORD shader_code_dp2add_sat[] = {
4596 0xffff0200, /* ps_2_0 */
4597 0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0 */
4599 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4600 0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add_sat r0.rgb, r0, r0, r0.a */
4601 0x03000002, 0x80070000, 0x80e40000, 0xa0000000, /* add r0.rgb, r0, c0.r */
4603 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
4604 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4605 0x0000ffff /* end */
4608 const float quad[] = {
4609 -1.0, -1.0, 0.1,
4610 1.0, -1.0, 0.1,
4611 -1.0, 1.0, 0.1,
4612 1.0, 1.0, 0.1
4616 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
4617 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4619 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
4620 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4622 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
4623 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4625 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4626 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4628 if (shader_dp2add) {
4630 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
4631 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4633 hr = IDirect3DDevice9_BeginScene(device);
4634 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4635 if(SUCCEEDED(hr))
4637 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4638 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4640 hr = IDirect3DDevice9_EndScene(device);
4641 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4643 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4644 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4646 color = getPixelColor(device, 360, 240);
4647 ok(color == 0x007f7f7f || color == 0x00808080, "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4649 IDirect3DPixelShader9_Release(shader_dp2add);
4650 } else {
4651 skip("dp2add shader creation failed\n");
4654 if (shader_dp2add_sat) {
4656 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
4657 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4659 hr = IDirect3DDevice9_BeginScene(device);
4660 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4661 if(SUCCEEDED(hr))
4663 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4664 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4666 hr = IDirect3DDevice9_EndScene(device);
4667 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4669 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4670 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4672 color = getPixelColor(device, 360, 240);
4673 ok(color == 0x007f7f7f || color == 0x00808080, "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4675 IDirect3DPixelShader9_Release(shader_dp2add_sat);
4676 } else {
4677 skip("dp2add shader creation failed\n");
4680 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4681 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4684 static void cnd_test(IDirect3DDevice9 *device)
4686 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
4687 IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
4688 HRESULT hr;
4689 DWORD color;
4690 /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
4691 * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
4692 * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
4694 DWORD shader_code_11[] = {
4695 0xffff0101, /* ps_1_1 */
4696 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4697 0x00000040, 0xb00f0000, /* texcoord t0 */
4698 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, ???(t0) */
4699 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
4700 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4701 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
4702 0x0000ffff /* end */
4704 DWORD shader_code_12[] = {
4705 0xffff0102, /* ps_1_2 */
4706 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4707 0x00000040, 0xb00f0000, /* texcoord t0 */
4708 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4709 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
4710 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4711 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
4712 0x0000ffff /* end */
4714 DWORD shader_code_13[] = {
4715 0xffff0103, /* ps_1_3 */
4716 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4717 0x00000040, 0xb00f0000, /* texcoord t0 */
4718 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4719 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3, r1, r0, c0 */
4720 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4721 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
4722 0x0000ffff /* end */
4724 DWORD shader_code_14[] = {
4725 0xffff0104, /* ps_1_3 */
4726 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
4727 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
4728 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
4729 0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0, c1, c2 */
4730 0x0000ffff /* end */
4733 /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
4734 * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
4735 * set by the compiler, it was added manually after compilation. It isn't always allowed,
4736 * only if there's a mov r0.a, XXXX, and the cnd instruction writes to r0.xyz, otherwise
4737 * native CreatePixelShader returns an error.
4739 * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
4740 * The input from t0 is [0;1]. 0.5 is substracted, then we have to multiply with 2. Since
4741 * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
4742 * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
4744 DWORD shader_code_11_coissue[] = {
4745 0xffff0101, /* ps_1_1 */
4746 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4747 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4748 0x00000040, 0xb00f0000, /* texcoord t0 */
4749 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4750 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
4751 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
4752 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
4753 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4754 /* 0x40000000 = D3DSI_COISSUE */
4755 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
4756 0x0000ffff /* end */
4758 DWORD shader_code_12_coissue[] = {
4759 0xffff0102, /* ps_1_2 */
4760 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4761 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4762 0x00000040, 0xb00f0000, /* texcoord t0 */
4763 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4764 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
4765 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
4766 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
4767 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4768 /* 0x40000000 = D3DSI_COISSUE */
4769 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
4770 0x0000ffff /* end */
4772 DWORD shader_code_13_coissue[] = {
4773 0xffff0103, /* ps_1_3 */
4774 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4775 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4776 0x00000040, 0xb00f0000, /* texcoord t0 */
4777 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4778 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
4779 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
4780 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
4781 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4782 /* 0x40000000 = D3DSI_COISSUE */
4783 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
4784 0x0000ffff /* end */
4786 /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
4787 * compare against 0.5
4789 DWORD shader_code_14_coissue[] = {
4790 0xffff0104, /* ps_1_4 */
4791 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
4792 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
4793 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
4794 /* 0x40000000 = D3DSI_COISSUE */
4795 0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0, c1, c2 */
4796 0x0000ffff /* end */
4798 float quad1[] = {
4799 -1.0, -1.0, 0.1, 0.0, 0.0, 1.0,
4800 0.0, -1.0, 0.1, 1.0, 0.0, 1.0,
4801 -1.0, 0.0, 0.1, 0.0, 1.0, 0.0,
4802 0.0, 0.0, 0.1, 1.0, 1.0, 0.0
4804 float quad2[] = {
4805 0.0, -1.0, 0.1, 0.0, 0.0, 1.0,
4806 1.0, -1.0, 0.1, 1.0, 0.0, 1.0,
4807 0.0, 0.0, 0.1, 0.0, 1.0, 0.0,
4808 1.0, 0.0, 0.1, 1.0, 1.0, 0.0
4810 float quad3[] = {
4811 0.0, 0.0, 0.1, 0.0, 0.0, 1.0,
4812 1.0, 0.0, 0.1, 1.0, 0.0, 1.0,
4813 0.0, 1.0, 0.1, 0.0, 1.0, 0.0,
4814 1.0, 1.0, 0.1, 1.0, 1.0, 0.0
4816 float quad4[] = {
4817 -1.0, 0.0, 0.1, 0.0, 0.0, 1.0,
4818 0.0, 0.0, 0.1, 1.0, 0.0, 1.0,
4819 -1.0, 1.0, 0.1, 0.0, 1.0, 0.0,
4820 0.0, 1.0, 0.1, 1.0, 1.0, 0.0
4822 float test_data_c1[4] = { 0.0, 0.0, 0.0, 0.0};
4823 float test_data_c2[4] = { 1.0, 1.0, 1.0, 1.0};
4824 float test_data_c1_coi[4] = { 0.0, 1.0, 0.0, 0.0};
4825 float test_data_c2_coi[4] = { 1.0, 0.0, 1.0, 1.0};
4827 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4828 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4830 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4831 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4832 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4833 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4834 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
4835 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4836 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4837 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4838 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
4839 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4840 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
4841 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4842 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
4843 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4844 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
4845 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
4847 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4848 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4849 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4850 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4851 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4852 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
4854 hr = IDirect3DDevice9_BeginScene(device);
4855 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4856 if(SUCCEEDED(hr))
4858 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4859 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4860 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4861 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4863 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4864 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4865 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4866 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4868 hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
4869 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4870 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
4871 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4873 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4874 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4875 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4876 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4878 hr = IDirect3DDevice9_EndScene(device);
4879 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4881 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4882 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4884 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4885 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
4887 /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
4888 color = getPixelColor(device, 158, 118);
4889 ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
4890 color = getPixelColor(device, 162, 118);
4891 ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
4892 color = getPixelColor(device, 158, 122);
4893 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
4894 color = getPixelColor(device, 162, 122);
4895 ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
4897 /* 1.1 shader. All 3 components get set, based on the .w comparison */
4898 color = getPixelColor(device, 158, 358);
4899 ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
4900 color = getPixelColor(device, 162, 358);
4901 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4902 "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
4903 color = getPixelColor(device, 158, 362);
4904 ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
4905 color = getPixelColor(device, 162, 362);
4906 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4907 "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
4909 /* 1.2 shader */
4910 color = getPixelColor(device, 478, 358);
4911 ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
4912 color = getPixelColor(device, 482, 358);
4913 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4914 "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
4915 color = getPixelColor(device, 478, 362);
4916 ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
4917 color = getPixelColor(device, 482, 362);
4918 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4919 "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
4921 /* 1.3 shader */
4922 color = getPixelColor(device, 478, 118);
4923 ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
4924 color = getPixelColor(device, 482, 118);
4925 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4926 "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
4927 color = getPixelColor(device, 478, 122);
4928 ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
4929 color = getPixelColor(device, 482, 122);
4930 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4931 "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
4933 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4934 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4935 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
4936 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4937 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
4938 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
4940 hr = IDirect3DDevice9_BeginScene(device);
4941 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
4942 if(SUCCEEDED(hr))
4944 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
4945 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4946 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4947 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4949 hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
4950 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4951 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4952 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4954 hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
4955 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4956 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
4957 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4959 hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
4960 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4961 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4962 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4964 hr = IDirect3DDevice9_EndScene(device);
4965 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
4967 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4968 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4970 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4971 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
4973 /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
4974 * that we swapped the values in c1 and c2 to make the other tests return some color
4976 color = getPixelColor(device, 158, 118);
4977 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
4978 color = getPixelColor(device, 162, 118);
4979 ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
4980 color = getPixelColor(device, 158, 122);
4981 ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
4982 color = getPixelColor(device, 162, 122);
4983 ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
4985 /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected */
4986 color = getPixelColor(device, 158, 358);
4987 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4988 "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
4989 color = getPixelColor(device, 162, 358);
4990 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4991 "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
4992 color = getPixelColor(device, 158, 362);
4993 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4994 "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
4995 color = getPixelColor(device, 162, 362);
4996 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4997 "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
4999 /* 1.2 shader */
5000 color = getPixelColor(device, 478, 358);
5001 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5002 "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
5003 color = getPixelColor(device, 482, 358);
5004 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5005 "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
5006 color = getPixelColor(device, 478, 362);
5007 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5008 "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
5009 color = getPixelColor(device, 482, 362);
5010 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5011 "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
5013 /* 1.3 shader */
5014 color = getPixelColor(device, 478, 118);
5015 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5016 "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
5017 color = getPixelColor(device, 482, 118);
5018 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5019 "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
5020 color = getPixelColor(device, 478, 122);
5021 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5022 "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
5023 color = getPixelColor(device, 482, 122);
5024 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
5025 "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
5027 IDirect3DPixelShader9_Release(shader_14_coissue);
5028 IDirect3DPixelShader9_Release(shader_13_coissue);
5029 IDirect3DPixelShader9_Release(shader_12_coissue);
5030 IDirect3DPixelShader9_Release(shader_11_coissue);
5031 IDirect3DPixelShader9_Release(shader_14);
5032 IDirect3DPixelShader9_Release(shader_13);
5033 IDirect3DPixelShader9_Release(shader_12);
5034 IDirect3DPixelShader9_Release(shader_11);
5037 static void nested_loop_test(IDirect3DDevice9 *device) {
5038 const DWORD shader_code[] = {
5039 0xffff0300, /* ps_3_0 */
5040 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
5041 0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
5042 0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0 */
5043 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5044 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
5045 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
5046 0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001, /* add r0, r0, c1 */
5047 0x0000001d, /* endloop */
5048 0x0000001d, /* endloop */
5049 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5050 0x0000ffff /* end */
5052 IDirect3DPixelShader9 *shader;
5053 HRESULT hr;
5054 DWORD color;
5055 const float quad[] = {
5056 -1.0, -1.0, 0.1,
5057 1.0, -1.0, 0.1,
5058 -1.0, 1.0, 0.1,
5059 1.0, 1.0, 0.1
5062 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5063 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
5064 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5065 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5066 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5067 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5068 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
5069 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5071 hr = IDirect3DDevice9_BeginScene(device);
5072 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5073 if(SUCCEEDED(hr))
5075 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
5076 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5077 hr = IDirect3DDevice9_EndScene(device);
5078 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5080 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5081 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5083 color = getPixelColor(device, 360, 240);
5084 ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
5085 "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
5087 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5088 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
5089 IDirect3DPixelShader9_Release(shader);
5092 struct varying_test_struct
5094 const DWORD *shader_code;
5095 IDirect3DPixelShader9 *shader;
5096 DWORD color, color_rhw;
5097 const char *name;
5098 BOOL todo, todo_rhw;
5101 struct hugeVertex
5103 float pos_x, pos_y, pos_z, rhw;
5104 float weight_1, weight_2, weight_3, weight_4;
5105 float index_1, index_2, index_3, index_4;
5106 float normal_1, normal_2, normal_3, normal_4;
5107 float fog_1, fog_2, fog_3, fog_4;
5108 float texcoord_1, texcoord_2, texcoord_3, texcoord_4;
5109 float tangent_1, tangent_2, tangent_3, tangent_4;
5110 float binormal_1, binormal_2, binormal_3, binormal_4;
5111 float depth_1, depth_2, depth_3, depth_4;
5112 DWORD diffuse, specular;
5115 static void fixed_function_varying_test(IDirect3DDevice9 *device) {
5116 /* dcl_position: fails to compile */
5117 const DWORD blendweight_code[] = {
5118 0xffff0300, /* ps_3_0 */
5119 0x0200001f, 0x80000001, 0x900f0000, /* dcl_blendweight, v0 */
5120 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5121 0x0000ffff /* end */
5123 const DWORD blendindices_code[] = {
5124 0xffff0300, /* ps_3_0 */
5125 0x0200001f, 0x80000002, 0x900f0000, /* dcl_blendindices, v0 */
5126 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5127 0x0000ffff /* end */
5129 const DWORD normal_code[] = {
5130 0xffff0300, /* ps_3_0 */
5131 0x0200001f, 0x80000003, 0x900f0000, /* dcl_normal, v0 */
5132 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5133 0x0000ffff /* end */
5135 /* psize: fails? */
5136 const DWORD texcoord0_code[] = {
5137 0xffff0300, /* ps_3_0 */
5138 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0, v0 */
5139 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5140 0x0000ffff /* end */
5142 const DWORD tangent_code[] = {
5143 0xffff0300, /* ps_3_0 */
5144 0x0200001f, 0x80000006, 0x900f0000, /* dcl_tangent, v0 */
5145 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5146 0x0000ffff /* end */
5148 const DWORD binormal_code[] = {
5149 0xffff0300, /* ps_3_0 */
5150 0x0200001f, 0x80000007, 0x900f0000, /* dcl_binormal, v0 */
5151 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5152 0x0000ffff /* end */
5154 /* tessfactor: fails */
5155 /* positiont: fails */
5156 const DWORD color_code[] = {
5157 0xffff0300, /* ps_3_0 */
5158 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0, v0 */
5159 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5160 0x0000ffff /* end */
5162 const DWORD fog_code[] = {
5163 0xffff0300, /* ps_3_0 */
5164 0x0200001f, 0x8000000b, 0x900f0000, /* dcl_fog, v0 */
5165 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5166 0x0000ffff /* end */
5168 const DWORD depth_code[] = {
5169 0xffff0300, /* ps_3_0 */
5170 0x0200001f, 0x8000000c, 0x900f0000, /* dcl_depth, v0 */
5171 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5172 0x0000ffff /* end */
5174 const DWORD specular_code[] = {
5175 0xffff0300, /* ps_3_0 */
5176 0x0200001f, 0x8001000a, 0x900f0000, /* dcl_color1, v0 */
5177 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5178 0x0000ffff /* end */
5180 /* sample: fails */
5182 struct varying_test_struct tests[] = {
5183 {blendweight_code, NULL, 0x00000000, 0x00191919, "blendweight" , FALSE, TRUE },
5184 {blendindices_code, NULL, 0x00000000, 0x00000000, "blendindices" , FALSE, FALSE },
5185 {normal_code, NULL, 0x00000000, 0x004c4c4c, "normal" , FALSE, TRUE },
5186 /* Why does dx not forward the texcoord? */
5187 {texcoord0_code, NULL, 0x00000000, 0x00808c8c, "texcoord0" , FALSE, FALSE },
5188 {tangent_code, NULL, 0x00000000, 0x00999999, "tangent" , FALSE, TRUE },
5189 {binormal_code, NULL, 0x00000000, 0x00b2b2b2, "binormal" , FALSE, TRUE },
5190 {color_code, NULL, 0x00e6e6e6, 0x00e6e6e6, "color" , FALSE, FALSE },
5191 {fog_code, NULL, 0x00000000, 0x00666666, "fog" , FALSE, TRUE },
5192 {depth_code, NULL, 0x00000000, 0x00cccccc, "depth" , FALSE, TRUE },
5193 {specular_code, NULL, 0x004488ff, 0x004488ff, "specular" , FALSE, FALSE }
5195 /* Declare a monster vertex type :-) */
5196 static const D3DVERTEXELEMENT9 decl_elements[] = {
5197 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5198 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
5199 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
5200 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
5201 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
5202 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5203 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
5204 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
5205 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
5206 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5207 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
5208 D3DDECL_END()
5210 static const D3DVERTEXELEMENT9 decl_elements2[] = {
5211 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
5212 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
5213 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
5214 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
5215 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
5216 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5217 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
5218 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
5219 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
5220 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5221 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
5222 D3DDECL_END()
5224 struct hugeVertex data[4] = {
5226 -1.0, -1.0, 0.1, 1.0,
5227 0.1, 0.1, 0.1, 0.1,
5228 0.2, 0.2, 0.2, 0.2,
5229 0.3, 0.3, 0.3, 0.3,
5230 0.4, 0.4, 0.4, 0.4,
5231 0.50, 0.55, 0.55, 0.55,
5232 0.6, 0.6, 0.6, 0.7,
5233 0.7, 0.7, 0.7, 0.6,
5234 0.8, 0.8, 0.8, 0.8,
5235 0xe6e6e6e6, /* 0.9 * 256 */
5236 0x224488ff /* Nothing special */
5239 1.0, -1.0, 0.1, 1.0,
5240 0.1, 0.1, 0.1, 0.1,
5241 0.2, 0.2, 0.2, 0.2,
5242 0.3, 0.3, 0.3, 0.3,
5243 0.4, 0.4, 0.4, 0.4,
5244 0.50, 0.55, 0.55, 0.55,
5245 0.6, 0.6, 0.6, 0.7,
5246 0.7, 0.7, 0.7, 0.6,
5247 0.8, 0.8, 0.8, 0.8,
5248 0xe6e6e6e6, /* 0.9 * 256 */
5249 0x224488ff /* Nothing special */
5252 -1.0, 1.0, 0.1, 1.0,
5253 0.1, 0.1, 0.1, 0.1,
5254 0.2, 0.2, 0.2, 0.2,
5255 0.3, 0.3, 0.3, 0.3,
5256 0.4, 0.4, 0.4, 0.4,
5257 0.50, 0.55, 0.55, 0.55,
5258 0.6, 0.6, 0.6, 0.7,
5259 0.7, 0.7, 0.7, 0.6,
5260 0.8, 0.8, 0.8, 0.8,
5261 0xe6e6e6e6, /* 0.9 * 256 */
5262 0x224488ff /* Nothing special */
5265 1.0, 1.0, 0.1, 1.0,
5266 0.1, 0.1, 0.1, 0.1,
5267 0.2, 0.2, 0.2, 0.2,
5268 0.3, 0.3, 0.3, 0.3,
5269 0.4, 0.4, 0.4, 0.4,
5270 0.50, 0.55, 0.55, 0.55,
5271 0.6, 0.6, 0.6, 0.7,
5272 0.7, 0.7, 0.7, 0.6,
5273 0.8, 0.8, 0.8, 0.8,
5274 0xe6e6e6e6, /* 0.9 * 256 */
5275 0x224488ff /* Nothing special */
5278 struct hugeVertex data2[4];
5279 IDirect3DVertexDeclaration9 *decl;
5280 IDirect3DVertexDeclaration9 *decl2;
5281 HRESULT hr;
5282 unsigned int i;
5283 DWORD color, r, g, b, r_e, g_e, b_e;
5284 BOOL drawok;
5286 memcpy(data2, data, sizeof(data2));
5287 data2[0].pos_x = 0; data2[0].pos_y = 0;
5288 data2[1].pos_x = 640; data2[1].pos_y = 0;
5289 data2[2].pos_x = 0; data2[2].pos_y = 480;
5290 data2[3].pos_x = 640; data2[3].pos_y = 480;
5292 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5293 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5294 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
5295 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5296 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5297 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5299 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5301 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
5302 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %08x\n",
5303 tests[i].name, hr);
5306 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5308 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5309 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5311 IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5312 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5314 hr = IDirect3DDevice9_BeginScene(device);
5315 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5316 drawok = FALSE;
5317 if(SUCCEEDED(hr))
5319 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(data[0]));
5320 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed (%08x)\n", hr);
5321 drawok = SUCCEEDED(hr);
5322 hr = IDirect3DDevice9_EndScene(device);
5323 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5325 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5326 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5328 /* Some drivers reject the combination of ps_3_0 and fixed function vertex processing. Accept
5329 * the failure and do not check the color if it failed
5331 if(!drawok) {
5332 continue;
5335 color = getPixelColor(device, 360, 240);
5336 r = color & 0x00ff0000 >> 16;
5337 g = color & 0x0000ff00 >> 8;
5338 b = color & 0x000000ff;
5339 r_e = tests[i].color & 0x00ff0000 >> 16;
5340 g_e = tests[i].color & 0x0000ff00 >> 8;
5341 b_e = tests[i].color & 0x000000ff;
5343 if(tests[i].todo) {
5344 todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5345 "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5346 tests[i].name, color, tests[i].color);
5347 } else {
5348 ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5349 "Test %s returned color 0x%08x, expected 0x%08x\n",
5350 tests[i].name, color, tests[i].color);
5354 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
5355 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5356 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5358 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5359 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5361 IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5362 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5364 hr = IDirect3DDevice9_BeginScene(device);
5365 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5366 if(SUCCEEDED(hr))
5368 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
5369 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5370 hr = IDirect3DDevice9_EndScene(device);
5371 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5373 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5374 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5376 color = getPixelColor(device, 360, 240);
5377 r = color & 0x00ff0000 >> 16;
5378 g = color & 0x0000ff00 >> 8;
5379 b = color & 0x000000ff;
5380 r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
5381 g_e = tests[i].color_rhw & 0x0000ff00 >> 8;
5382 b_e = tests[i].color_rhw & 0x000000ff;
5384 if(tests[i].todo_rhw) {
5385 /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
5386 * pipeline
5388 todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5389 "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5390 tests[i].name, color, tests[i].color_rhw);
5391 } else {
5392 ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5393 "Test %s returned color 0x%08x, expected 0x%08x\n",
5394 tests[i].name, color, tests[i].color_rhw);
5398 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5400 IDirect3DPixelShader9_Release(tests[i].shader);
5403 IDirect3DVertexDeclaration9_Release(decl2);
5404 IDirect3DVertexDeclaration9_Release(decl);
5407 static void vshader_version_varying_test(IDirect3DDevice9 *device) {
5408 static const DWORD ps_code[] = {
5409 0xffff0300, /* ps_3_0 */
5410 0x05000030, 0xf00f0000, 0x00000003, 0x00000003, 0x00000001, 0x00000000, /* defi i0, 3, 3, 1, 0 */
5411 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
5412 0x0200001f, 0x8001000a, 0x900f0003, /* dcl_color1 v3 */
5413 0x0200001f, 0x8000000b, 0x900f0004, /* dcl_fog v4 */
5414 0x0200001f, 0x80030005, 0x900f0005, /* dcl_texcoord3 v5 */
5415 0x0200001f, 0x80000003, 0x900f0006, /* dcl_normal v6 */
5416 0x0200001f, 0x80000006, 0x900f0007, /* dcl_tangent v7 */
5417 0x0200001f, 0x80000001, 0x900f0008, /* dcl_blendweight v8 */
5418 0x0200001f, 0x8000000c, 0x900f0009, /* dcl_depth v9 */
5420 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5421 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
5422 0x04000002, 0x800f0000, 0x80e40000, 0x90e42000, 0xf0e40800, /* add r0, r0, v0[aL] */
5423 0x0000001d, /* endloop */
5424 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5425 0x0000ffff /* end */
5427 static const DWORD vs_1_code[] = {
5428 0xfffe0101, /* vs_1_1 */
5429 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5430 0x00000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0 */
5431 0x00000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0 */
5432 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0 */
5433 0x00000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
5434 0x00000001, 0xd00f0000, 0xa0e40002, /* mov oD0, c2 */
5435 0x00000001, 0xd00f0001, 0xa0e40000, /* mov oD1, c0 */
5436 0x00000001, 0xc00f0001, 0xa0550001, /* mov oFog, c1.g */
5437 0x00000001, 0xe00f0000, 0xa0e40003, /* mov oT0, c3 */
5438 0x00000001, 0xe00f0001, 0xa0e40003, /* mov oT1, c3 */
5439 0x00000001, 0xe00f0002, 0xa0e40003, /* mov oT2, c3 */
5440 0x00000001, 0xe00f0003, 0xa0e40002, /* mov oT3, c2 */
5441 0x00000001, 0xe00f0004, 0xa0e40003, /* mov oT4, c3 */
5442 0x00000001, 0xe00f0005, 0xa0e40003, /* mov oT5, c3 */
5443 0x00000001, 0xe00f0006, 0xa0e40003, /* mov oT6, c3 */
5444 0x00000001, 0xe00f0007, 0xa0e40003, /* mov oT7, c3 */
5445 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5446 0x0000ffff
5448 DWORD vs_2_code[] = {
5449 0xfffe0200, /* vs_2_0 */
5450 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5451 0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0 */
5452 0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0 */
5453 0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0 */
5454 0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
5455 0x02000001, 0xd00f0000, 0xa0e40002, /* mov oD0, c2 */
5456 0x02000001, 0xd00f0001, 0xa0e40000, /* mov oD1, c0 */
5457 0x02000001, 0xc00f0001, 0xa0550001, /* mov oFog, c1.g */
5458 0x02000001, 0xe00f0000, 0xa0e40003, /* mov oT0, c3 */
5459 0x02000001, 0xe00f0001, 0xa0e40003, /* mov oT1, c3 */
5460 0x02000001, 0xe00f0002, 0xa0e40003, /* mov oT2, c3 */
5461 0x02000001, 0xe00f0003, 0xa0e40002, /* mov oT3, c2 */
5462 0x02000001, 0xe00f0004, 0xa0e40003, /* mov oT4, c3 */
5463 0x02000001, 0xe00f0005, 0xa0e40003, /* mov oT5, c3 */
5464 0x02000001, 0xe00f0006, 0xa0e40003, /* mov oT6, c3 */
5465 0x02000001, 0xe00f0007, 0xa0e40003, /* mov oT7, c3 */
5466 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5467 0x0000ffff /* end */
5469 /* TODO: Define normal, tangent, blendweight and depth here */
5470 static const DWORD vs_3_code[] = {
5471 0xfffe0300, /* vs_3_0 */
5472 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5473 0x0200001f, 0x8001000a, 0xe00f0009, /* dcl_color1 o9 */
5474 0x0200001f, 0x8000000b, 0xe00f0002, /* dcl_fog o2 */
5475 0x0200001f, 0x80030005, 0xe00f0005, /* dcl_texcoord3 o5 */
5476 0x0200001f, 0x80000000, 0xe00f000b, /* dcl_position o11 */
5477 0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0 */
5478 0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0 */
5479 0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0 */
5480 0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
5481 0x02000001, 0xe00f0009, 0xa0e40000, /* mov o9, c0 */
5482 0x02000001, 0xe00f0002, 0xa0e40001, /* mov o2, c1 */
5483 0x02000001, 0xe00f0005, 0xa0e40002, /* mov o5, c2 */
5484 0x02000001, 0xe00f000b, 0x90e40000, /* mov o11, v0 */
5485 0x0000ffff /* end */
5487 float quad1[] = {
5488 -1.0, -1.0, 0.1,
5489 0.0, -1.0, 0.1,
5490 -1.0, 0.0, 0.1,
5491 0.0, 0.0, 0.1
5493 float quad2[] = {
5494 0.0, -1.0, 0.1,
5495 1.0, -1.0, 0.1,
5496 0.0, 0.0, 0.1,
5497 1.0, 0.0, 0.1
5499 float quad3[] = {
5500 -1.0, 0.0, 0.1,
5501 0.0, 0.0, 0.1,
5502 -1.0, 1.0, 0.1,
5503 0.0, 1.0, 0.1
5506 HRESULT hr;
5507 DWORD color;
5508 IDirect3DPixelShader9 *pixelshader = NULL;
5509 IDirect3DVertexShader9 *vs_1_shader = NULL;
5510 IDirect3DVertexShader9 *vs_2_shader = NULL;
5511 IDirect3DVertexShader9 *vs_3_shader = NULL;
5513 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff110000, 0.0, 0);
5515 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &pixelshader);
5516 ok(hr == D3D_OK, "IDirect3DDevice_CreatePixelShader returned %08x\n", hr);
5517 hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_code, &vs_1_shader);
5518 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5519 hr = IDirect3DDevice9_CreateVertexShader(device, vs_2_code, &vs_2_shader);
5520 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5521 hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_code, &vs_3_shader);
5522 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5523 hr = IDirect3DDevice9_SetPixelShader(device, pixelshader);
5524 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5525 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5527 hr = IDirect3DDevice9_BeginScene(device);
5528 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5529 if(SUCCEEDED(hr))
5531 hr = IDirect3DDevice9_SetVertexShader(device, vs_1_shader);
5532 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5533 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5534 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5536 hr = IDirect3DDevice9_SetVertexShader(device, vs_2_shader);
5537 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5538 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
5539 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5541 hr = IDirect3DDevice9_SetVertexShader(device, vs_3_shader);
5542 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5543 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5544 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5546 hr = IDirect3DDevice9_EndScene(device);
5547 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5549 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5550 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5552 color = getPixelColor(device, 160, 120);
5553 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x1a, 0x34, 0x67), 1),
5554 "vs_3_0 returned color 0x%08x, expected 0x00193366\n", color);
5555 color = getPixelColor(device, 160, 360);
5556 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1),
5557 "vs_1_1 returned color 0x%08x, expected 0x004c0066\n", color);
5558 color = getPixelColor(device, 480, 360);
5559 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x4d, 0x00, 0x67), 1),
5560 "vs_2_0 returned color 0x%08x, expected 0x004c0066\n", color);
5562 /* cleanup */
5563 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5564 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5565 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5566 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5567 if(pixelshader) IDirect3DPixelShader9_Release(pixelshader);
5568 if(vs_1_shader) IDirect3DVertexShader9_Release(vs_1_shader);
5569 if(vs_2_shader) IDirect3DVertexShader9_Release(vs_2_shader);
5570 if(vs_3_shader) IDirect3DVertexShader9_Release(vs_3_shader);
5573 static void pshader_version_varying_test(IDirect3DDevice9 *device) {
5574 static const DWORD vs_code[] = {
5575 0xfffe0300, /* vs_3_0 */
5576 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5577 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5578 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */
5579 0x0200001f, 0x80000005, 0xe00f0002, /* dcl_texcoord0 o2 */
5580 0x0200001f, 0x8000000b, 0xe00f0003, /* dcl_fog o3 */
5581 0x0200001f, 0x80000003, 0xe00f0004, /* dcl_normal o4 */
5582 0x0200001f, 0x8000000c, 0xe00f0005, /* dcl_depth o5 */
5583 0x0200001f, 0x80000006, 0xe00f0006, /* dcl_tangent o6 */
5584 0x0200001f, 0x80000001, 0xe00f0007, /* dcl_blendweight o7 */
5585 0x05000051, 0xa00f0001, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c1, 0.1, 0.0, 0.0, 0.0 */
5586 0x05000051, 0xa00f0002, 0x00000000, 0x3e4ccccd, 0x00000000, 0x3f800000, /* def c2, 0.0, 0.2, 0.0, 1.0 */
5587 0x05000051, 0xa00f0003, 0x3ecccccd, 0x3f59999a, 0x3f666666, 0x00000000, /* def c3, 0.4, 0.85,0.9, 0.0 */
5588 0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0 */
5590 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5591 0x02000001, 0xe00f0001, 0xa0e40001, /* mov o1, c1 */
5592 0x02000001, 0xe00f0002, 0xa0e40002, /* mov o2, c2 */
5593 0x02000001, 0xe00f0003, 0xa0e40003, /* mov o3, c3 */
5594 0x02000001, 0xe00f0004, 0xa0e40000, /* mov o4, c0 */
5595 0x02000001, 0xe00f0005, 0xa0e40000, /* mov o5, c0 */
5596 0x02000001, 0xe00f0006, 0xa0e40000, /* mov o6, c0 */
5597 0x02000001, 0xe00f0007, 0xa0e40000, /* mov o7, c0 */
5598 0x0000ffff /* end */
5600 static const DWORD ps_1_code[] = {
5601 0xffff0104, /* ps_1_4 */
5602 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
5603 0x00000040, 0x80070001, 0xb0e40000, /* texcrd r1.xyz, t0 */
5604 0x00000001, 0x80080001, 0xa0ff0000, /* mov r1.a, c0.a */
5605 0x00000002, 0x800f0000, 0x90e40000, 0x80e40001, /* add r0, v0, r1 */
5606 0x0000ffff /* end */
5608 static const DWORD ps_2_code[] = {
5609 0xffff0200, /* ps_2_0 */
5610 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
5611 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
5612 0x0200001f, 0x80000000, 0x900f0001, /* dcl v1 */
5614 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
5615 0x03000002, 0x800f0000, 0x80e40000,0xb0e40000, /* add r0, r0, t0 */
5616 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5617 0x0000ffff /* end */
5619 static const DWORD ps_3_code[] = {
5620 0xffff0300, /* ps_3_0 */
5621 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
5622 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
5623 0x0200001f, 0x8000000b, 0x900f0002, /* dcl_fog v2 */
5625 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
5626 0x03000002, 0x800f0000, 0x80e40000, 0x90e40001, /* add r0, r0, v1 */
5627 0x03000002, 0x800f0000, 0x80e40000, 0x90e40002, /* mov r0, r0, v2 */
5628 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5629 0x0000ffff /* end */
5632 float quad1[] = {
5633 -1.0, -1.0, 0.1,
5634 0.0, -1.0, 0.1,
5635 -1.0, 0.0, 0.1,
5636 0.0, 0.0, 0.1
5638 float quad2[] = {
5639 0.0, -1.0, 0.1,
5640 1.0, -1.0, 0.1,
5641 0.0, 0.0, 0.1,
5642 1.0, 0.0, 0.1
5644 float quad3[] = {
5645 -1.0, 0.0, 0.1,
5646 0.0, 0.0, 0.1,
5647 -1.0, 1.0, 0.1,
5648 0.0, 1.0, 0.1
5650 float quad4[] = {
5651 0.0, 0.0, 0.1,
5652 1.0, 0.0, 0.1,
5653 0.0, 1.0, 0.1,
5654 1.0, 1.0, 0.1
5657 HRESULT hr;
5658 DWORD color;
5659 IDirect3DVertexShader9 *vertexshader = NULL;
5660 IDirect3DPixelShader9 *ps_1_shader = NULL;
5661 IDirect3DPixelShader9 *ps_2_shader = NULL;
5662 IDirect3DPixelShader9 *ps_3_shader = NULL;
5663 IDirect3DTexture9 *texture = NULL;
5664 D3DLOCKED_RECT lr;
5665 unsigned int x, y;
5667 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5669 hr = IDirect3DDevice9_CreateTexture(device, 512, 512, 1, 0, D3DFMT_A16B16G16R16, D3DPOOL_MANAGED, &texture, NULL);
5670 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
5671 if(FAILED(hr)) {
5672 skip("D3DFMT_A16B16G16R16 textures not supported\n");
5673 return;
5675 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5676 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
5677 for(y = 0; y < 512; y++) {
5678 for(x = 0; x < 512; x++) {
5679 double r_f = (double) x / (double) 512;
5680 double g_f = (double) y / (double) 512;
5681 unsigned short *dst = (unsigned short *) (((unsigned char *) lr.pBits) + y * lr.Pitch + x * 8);
5682 unsigned short r = (unsigned short) (r_f * 65535.0);
5683 unsigned short g = (unsigned short) (g_f * 65535.0);
5684 dst[0] = r;
5685 dst[1] = g;
5686 dst[2] = 0;
5687 dst[3] = 65535;
5690 hr = IDirect3DTexture9_UnlockRect(texture, 0);
5691 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
5693 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vertexshader);
5694 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5695 hr = IDirect3DDevice9_CreatePixelShader(device, ps_1_code, &ps_1_shader);
5696 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5697 hr = IDirect3DDevice9_CreatePixelShader(device, ps_2_code, &ps_2_shader);
5698 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5699 hr = IDirect3DDevice9_CreatePixelShader(device, ps_3_code, &ps_3_shader);
5700 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5701 hr = IDirect3DDevice9_SetVertexShader(device, vertexshader);
5702 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5703 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5705 hr = IDirect3DDevice9_BeginScene(device);
5706 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5707 if(SUCCEEDED(hr))
5709 hr = IDirect3DDevice9_SetPixelShader(device, ps_1_shader);
5710 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5711 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5712 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5714 hr = IDirect3DDevice9_SetPixelShader(device, ps_2_shader);
5715 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5716 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
5717 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5719 hr = IDirect3DDevice9_SetPixelShader(device, ps_3_shader);
5720 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5721 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5722 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5724 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5725 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5726 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5727 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5728 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
5729 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
5730 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
5731 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
5732 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5733 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5735 hr = IDirect3DDevice9_EndScene(device);
5736 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5738 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5739 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5741 color = getPixelColor(device, 160, 120);
5742 ok((color & 0x00ff0000) >= 0x00790000 && (color & 0x00ff0000) <= 0x00810000 &&
5743 (color & 0x0000ff00) == 0x0000ff00 &&
5744 (color & 0x000000ff) >= 0x000000e4 && (color & 0x000000ff) <= 0x000000e6,
5745 "ps_3_0 returned color 0x%08x, expected 0x0080ffe5\n", color);
5746 color = getPixelColor(device, 160, 360);
5747 ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5748 (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003400 &&
5749 (color & 0x000000ff) == 0x00000000,
5750 "ps_1_4 returned color 0x%08x, expected 0x00203300\n", color);
5751 color = getPixelColor(device, 480, 360);
5752 ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5753 (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5754 (color & 0x000000ff) == 0x00000000,
5755 "ps_2_0 returned color 0x%08x, expected 0x00203300\n", color);
5756 color = getPixelColor(device, 480, 160);
5757 ok( color == 0x00ffffff /* Nvidia driver garbage with HW vp */ || (
5758 (color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5759 (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5760 (color & 0x000000ff) == 0x00000000),
5761 "fixed function fragment processing returned color 0x%08x, expected 0x00203300\n", color);
5763 /* cleanup */
5764 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5765 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5766 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5767 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5768 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5769 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5770 if(vertexshader) IDirect3DVertexShader9_Release(vertexshader);
5771 if(ps_1_shader) IDirect3DPixelShader9_Release(ps_1_shader);
5772 if(ps_2_shader) IDirect3DPixelShader9_Release(ps_2_shader);
5773 if(ps_3_shader) IDirect3DPixelShader9_Release(ps_3_shader);
5774 if(texture) IDirect3DTexture9_Release(texture);
5777 static void test_compare_instructions(IDirect3DDevice9 *device)
5779 DWORD shader_sge_vec_code[] = {
5780 0xfffe0101, /* vs_1_1 */
5781 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5782 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5783 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5784 0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001, /* sge oD0, r0, c1 */
5785 0x0000ffff /* end */
5787 DWORD shader_slt_vec_code[] = {
5788 0xfffe0101, /* vs_1_1 */
5789 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5790 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5791 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5792 0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001, /* slt oD0, r0, c1 */
5793 0x0000ffff /* end */
5795 DWORD shader_sge_scalar_code[] = {
5796 0xfffe0101, /* vs_1_1 */
5797 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5798 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5799 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5800 0x0000000d, 0xd0010000, 0x80000000, 0xa0550001, /* slt oD0.r, r0.r, c1.b */
5801 0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001, /* slt oD0.g, r0.g, c1.r */
5802 0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001, /* slt oD0.b, r0.b, c1.g */
5803 0x0000ffff /* end */
5805 DWORD shader_slt_scalar_code[] = {
5806 0xfffe0101, /* vs_1_1 */
5807 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5808 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5809 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5810 0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001, /* slt oD0.r, r0.r, c1.b */
5811 0x0000000c, 0xd0020000, 0x80550000, 0xa0000001, /* slt oD0.g, r0.g, c1.r */
5812 0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001, /* slt oD0.b, r0.b, c1.g */
5813 0x0000ffff /* end */
5815 IDirect3DVertexShader9 *shader_sge_vec;
5816 IDirect3DVertexShader9 *shader_slt_vec;
5817 IDirect3DVertexShader9 *shader_sge_scalar;
5818 IDirect3DVertexShader9 *shader_slt_scalar;
5819 HRESULT hr, color;
5820 float quad1[] = {
5821 -1.0, -1.0, 0.1,
5822 0.0, -1.0, 0.1,
5823 -1.0, 0.0, 0.1,
5824 0.0, 0.0, 0.1
5826 float quad2[] = {
5827 0.0, -1.0, 0.1,
5828 1.0, -1.0, 0.1,
5829 0.0, 0.0, 0.1,
5830 1.0, 0.0, 0.1
5832 float quad3[] = {
5833 -1.0, 0.0, 0.1,
5834 0.0, 0.0, 0.1,
5835 -1.0, 1.0, 0.1,
5836 0.0, 1.0, 0.1
5838 float quad4[] = {
5839 0.0, 0.0, 0.1,
5840 1.0, 0.0, 0.1,
5841 0.0, 1.0, 0.1,
5842 1.0, 1.0, 0.1
5844 const float const0[4] = {0.8, 0.2, 0.2, 0.2};
5845 const float const1[4] = {0.2, 0.8, 0.2, 0.2};
5847 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5849 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
5850 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5851 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
5852 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5853 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
5854 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5855 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
5856 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5857 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5858 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5859 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
5860 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5861 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5862 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
5864 hr = IDirect3DDevice9_BeginScene(device);
5865 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
5866 if(SUCCEEDED(hr))
5868 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
5869 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5870 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5871 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5873 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
5874 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5875 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
5876 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5878 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
5879 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5880 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5881 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5883 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5884 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5886 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
5887 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5888 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5889 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5891 hr = IDirect3DDevice9_EndScene(device);
5892 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
5895 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5896 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5897 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5898 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
5900 color = getPixelColor(device, 160, 360);
5901 ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
5902 color = getPixelColor(device, 480, 360);
5903 ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
5904 color = getPixelColor(device, 160, 120);
5905 ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
5906 color = getPixelColor(device, 480, 160);
5907 ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
5909 IDirect3DVertexShader9_Release(shader_sge_vec);
5910 IDirect3DVertexShader9_Release(shader_slt_vec);
5911 IDirect3DVertexShader9_Release(shader_sge_scalar);
5912 IDirect3DVertexShader9_Release(shader_slt_scalar);
5915 static void test_vshader_input(IDirect3DDevice9 *device)
5917 DWORD swapped_shader_code_3[] = {
5918 0xfffe0300, /* vs_3_0 */
5919 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5920 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
5921 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5922 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
5923 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
5924 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5925 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
5926 0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
5927 0x0000ffff /* end */
5929 DWORD swapped_shader_code_1[] = {
5930 0xfffe0101, /* vs_1_1 */
5931 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5932 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
5933 0x0000001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
5934 0x00000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
5935 0x00000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
5936 0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
5937 0x0000ffff /* end */
5939 DWORD swapped_shader_code_2[] = {
5940 0xfffe0200, /* vs_2_0 */
5941 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5942 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
5943 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
5944 0x02000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
5945 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
5946 0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
5947 0x0000ffff /* end */
5949 DWORD texcoord_color_shader_code_3[] = {
5950 0xfffe0300, /* vs_3_0 */
5951 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5952 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
5953 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5954 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
5955 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5956 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
5957 0x0000ffff /* end */
5959 DWORD texcoord_color_shader_code_2[] = {
5960 0xfffe0200, /* vs_2_0 */
5961 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5962 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
5963 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5964 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
5965 0x0000ffff /* end */
5967 DWORD texcoord_color_shader_code_1[] = {
5968 0xfffe0101, /* vs_1_1 */
5969 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5970 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
5971 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5972 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
5973 0x0000ffff /* end */
5975 DWORD color_color_shader_code_3[] = {
5976 0xfffe0300, /* vs_3_0 */
5977 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5978 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
5979 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5980 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
5981 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5982 0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001, /* mul o1, c0, v1 */
5983 0x0000ffff /* end */
5985 DWORD color_color_shader_code_2[] = {
5986 0xfffe0200, /* vs_2_0 */
5987 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5988 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
5989 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5990 0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
5991 0x0000ffff /* end */
5993 DWORD color_color_shader_code_1[] = {
5994 0xfffe0101, /* vs_1_1 */
5995 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5996 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
5997 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5998 0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
5999 0x0000ffff /* end */
6001 IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
6002 HRESULT hr;
6003 DWORD color;
6004 float quad1[] = {
6005 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6006 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6007 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6008 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6010 float quad2[] = {
6011 0.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6012 1.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6013 0.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6014 1.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6016 float quad3[] = {
6017 -1.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0,
6018 0.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,
6019 -1.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0,
6020 0.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0,
6022 float quad4[] = {
6023 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6024 1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6025 0.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6026 1.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
6028 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
6029 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6030 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6031 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6032 D3DDECL_END()
6034 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
6035 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6036 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6037 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6038 D3DDECL_END()
6040 static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
6041 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6042 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6043 D3DDECL_END()
6045 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
6046 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6047 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6048 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
6049 D3DDECL_END()
6051 static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
6052 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6053 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6054 D3DDECL_END()
6056 static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
6057 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6058 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6059 D3DDECL_END()
6061 static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
6062 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6063 {0, 12, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6064 D3DDECL_END()
6066 static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
6067 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6068 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6069 D3DDECL_END()
6071 IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
6072 IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
6073 unsigned int i;
6074 float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
6075 float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
6077 struct vertex quad1_color[] = {
6078 {-1.0, -1.0, 0.1, 0x00ff8040},
6079 { 0.0, -1.0, 0.1, 0x00ff8040},
6080 {-1.0, 0.0, 0.1, 0x00ff8040},
6081 { 0.0, 0.0, 0.1, 0x00ff8040}
6083 struct vertex quad2_color[] = {
6084 { 0.0, -1.0, 0.1, 0x00ff8040},
6085 { 1.0, -1.0, 0.1, 0x00ff8040},
6086 { 0.0, 0.0, 0.1, 0x00ff8040},
6087 { 1.0, 0.0, 0.1, 0x00ff8040}
6089 struct vertex quad3_color[] = {
6090 {-1.0, 0.0, 0.1, 0x00ff8040},
6091 { 0.0, 0.0, 0.1, 0x00ff8040},
6092 {-1.0, 1.0, 0.1, 0x00ff8040},
6093 { 0.0, 1.0, 0.1, 0x00ff8040}
6095 float quad4_color[] = {
6096 0.0, 0.0, 0.1, 1.0, 1.0, 0.0, 0.0,
6097 1.0, 0.0, 0.1, 1.0, 1.0, 0.0, 1.0,
6098 0.0, 1.0, 0.1, 1.0, 1.0, 0.0, 0.0,
6099 1.0, 1.0, 0.1, 1.0, 1.0, 0.0, 1.0,
6102 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6103 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6104 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6105 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6106 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6107 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6108 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6109 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6111 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6112 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6113 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6114 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6115 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6116 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6117 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6118 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6120 for(i = 1; i <= 3; i++) {
6121 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6122 if(i == 3) {
6123 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6124 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6125 } else if(i == 2){
6126 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6127 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6128 } else if(i == 1) {
6129 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6130 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6133 hr = IDirect3DDevice9_BeginScene(device);
6134 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6135 if(SUCCEEDED(hr))
6137 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6138 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6140 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6141 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6142 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6143 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6145 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6146 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6147 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6148 if(i == 3 || i == 2) {
6149 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6150 } else if(i == 1) {
6151 /* Succeeds or fails, depending on SW or HW vertex processing */
6152 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6155 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6156 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6157 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6158 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6160 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6161 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6162 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6163 if(i == 3 || i == 2) {
6164 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6165 } else if(i == 1) {
6166 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6169 hr = IDirect3DDevice9_EndScene(device);
6170 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6173 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6174 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6176 if(i == 3 || i == 2) {
6177 color = getPixelColor(device, 160, 360);
6178 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6179 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6181 /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6182 color = getPixelColor(device, 480, 360);
6183 ok(color == 0x00FFFF00 || color ==0x00FF0000,
6184 "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6185 color = getPixelColor(device, 160, 120);
6186 /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6187 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6188 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6190 color = getPixelColor(device, 480, 160);
6191 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6192 } else if(i == 1) {
6193 color = getPixelColor(device, 160, 360);
6194 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
6195 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6196 color = getPixelColor(device, 480, 360);
6197 /* Accept the clear color as well in this case, since SW VP returns an error */
6198 ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6199 color = getPixelColor(device, 160, 120);
6200 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
6201 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6202 color = getPixelColor(device, 480, 160);
6203 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6206 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6207 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6209 /* Now find out if the whole streams are re-read, or just the last active value for the
6210 * vertices is used.
6212 hr = IDirect3DDevice9_BeginScene(device);
6213 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6214 if(SUCCEEDED(hr))
6216 float quad1_modified[] = {
6217 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0,
6218 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0,
6219 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0,
6220 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, -1.0, -1.0, 0.0,
6222 float quad2_modified[] = {
6223 0.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6224 1.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6225 0.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6226 1.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6229 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6230 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6232 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6233 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6234 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6235 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6237 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6238 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6239 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6240 if(i == 3 || i == 2) {
6241 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6242 } else if(i == 1) {
6243 /* Succeeds or fails, depending on SW or HW vertex processing */
6244 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6247 hr = IDirect3DDevice9_EndScene(device);
6248 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6250 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6251 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6253 color = getPixelColor(device, 480, 350);
6254 /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6255 * as well.
6257 * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6258 * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6259 * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6260 * refrast's result.
6262 * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6264 ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6265 "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6266 color = getPixelColor(device, 160, 120);
6268 IDirect3DDevice9_SetVertexShader(device, NULL);
6269 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6271 IDirect3DVertexShader9_Release(swapped_shader);
6274 for(i = 1; i <= 3; i++) {
6275 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6276 if(i == 3) {
6277 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6278 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6279 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6280 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6281 } else if(i == 2){
6282 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6283 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6284 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6285 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6286 } else if(i == 1) {
6287 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6288 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6289 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6290 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6293 hr = IDirect3DDevice9_BeginScene(device);
6294 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6295 if(SUCCEEDED(hr))
6297 hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6298 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6299 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6300 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6301 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6302 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6304 hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6305 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6307 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6308 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6309 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6310 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6311 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6312 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6314 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6315 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6316 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6317 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6318 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6319 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6321 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6322 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6323 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6324 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6326 hr = IDirect3DDevice9_EndScene(device);
6327 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6329 IDirect3DDevice9_SetVertexShader(device, NULL);
6330 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6332 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6333 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6335 color = getPixelColor(device, 160, 360);
6336 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6337 "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6338 color = getPixelColor(device, 480, 360);
6339 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
6340 "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6341 color = getPixelColor(device, 160, 120);
6342 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
6343 "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6344 color = getPixelColor(device, 480, 160);
6345 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
6346 "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6348 IDirect3DVertexShader9_Release(texcoord_color_shader);
6349 IDirect3DVertexShader9_Release(color_color_shader);
6352 IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6353 IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6354 IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6355 IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6357 IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6358 IDirect3DVertexDeclaration9_Release(decl_color_color);
6359 IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6360 IDirect3DVertexDeclaration9_Release(decl_color_float);
6363 static void srgbtexture_test(IDirect3DDevice9 *device)
6365 /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6366 * texture stage state to render a quad using that texture. The resulting
6367 * color components should be 0x36 (~ 0.21), per this formula:
6368 * linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6369 * This is true where srgb_color > 0.04045.
6371 IDirect3D9 *d3d = NULL;
6372 HRESULT hr;
6373 LPDIRECT3DTEXTURE9 texture = NULL;
6374 LPDIRECT3DSURFACE9 surface = NULL;
6375 D3DLOCKED_RECT lr;
6376 DWORD color;
6377 float quad[] = {
6378 -1.0, 1.0, 0.0, 0.0, 0.0,
6379 1.0, 1.0, 0.0, 1.0, 0.0,
6380 -1.0, -1.0, 0.0, 0.0, 1.0,
6381 1.0, -1.0, 0.0, 1.0, 1.0,
6385 memset(&lr, 0, sizeof(lr));
6386 IDirect3DDevice9_GetDirect3D(device, &d3d);
6387 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6388 D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6389 D3DFMT_A8R8G8B8) != D3D_OK) {
6390 skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6391 goto out;
6394 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6395 D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6396 &texture, NULL);
6397 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
6398 if(!texture) {
6399 skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6400 goto out;
6402 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6403 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
6405 fill_surface(surface, 0xff7f7f7f);
6406 IDirect3DSurface9_Release(surface);
6408 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6409 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6410 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6411 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6413 hr = IDirect3DDevice9_BeginScene(device);
6414 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6415 if(SUCCEEDED(hr))
6417 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6418 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6420 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6421 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6424 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6425 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %08x\n", hr);
6427 hr = IDirect3DDevice9_EndScene(device);
6428 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6431 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6432 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
6433 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6434 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
6436 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6437 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6439 color = getPixelColor(device, 320, 240);
6440 ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6442 out:
6443 if(texture) IDirect3DTexture9_Release(texture);
6444 IDirect3D9_Release(d3d);
6447 static void shademode_test(IDirect3DDevice9 *device)
6449 /* Render a quad and try all of the different fixed function shading models. */
6450 HRESULT hr;
6451 DWORD color0, color1;
6452 DWORD color0_gouraud = 0, color1_gouraud = 0;
6453 DWORD shademode = D3DSHADE_FLAT;
6454 DWORD primtype = D3DPT_TRIANGLESTRIP;
6455 LPVOID data = NULL;
6456 LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6457 LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6458 UINT i, j;
6459 struct vertex quad_strip[] =
6461 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
6462 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6463 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6464 { 1.0f, 1.0f, 0.0f, 0xffffffff }
6466 struct vertex quad_list[] =
6468 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
6469 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6470 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6472 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6473 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6474 { 1.0f, 1.0f, 0.0f, 0xffffffff }
6477 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6478 0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6479 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6480 if (FAILED(hr)) goto bail;
6482 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6483 0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6484 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
6485 if (FAILED(hr)) goto bail;
6487 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6488 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6490 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6491 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6493 hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), (void **) &data, 0);
6494 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6495 memcpy(data, quad_strip, sizeof(quad_strip));
6496 hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6497 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6499 hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), (void **) &data, 0);
6500 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
6501 memcpy(data, quad_list, sizeof(quad_list));
6502 hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6503 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
6505 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
6506 * the color fixups we have to do for FLAT shading will be dependent on that. */
6507 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6508 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6510 /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6511 for (j=0; j<2; j++) {
6513 /* Inner loop just changes the D3DRS_SHADEMODE */
6514 for (i=0; i<3; i++) {
6515 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6516 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6518 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6519 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6521 hr = IDirect3DDevice9_BeginScene(device);
6522 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
6523 if(SUCCEEDED(hr))
6525 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
6526 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %08x\n", hr);
6528 hr = IDirect3DDevice9_EndScene(device);
6529 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
6532 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6533 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6535 /* Sample two spots from the output */
6536 color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
6537 color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
6538 switch(shademode) {
6539 case D3DSHADE_FLAT:
6540 /* Should take the color of the first vertex of each triangle */
6541 todo_wine ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000 (todo)\n", color0);
6542 todo_wine ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00 (todo)\n", color1);
6543 shademode = D3DSHADE_GOURAUD;
6544 break;
6545 case D3DSHADE_GOURAUD:
6546 /* Should be an interpolated blend */
6548 ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6549 "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
6550 ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6551 "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
6553 color0_gouraud = color0;
6554 color1_gouraud = color1;
6556 shademode = D3DSHADE_PHONG;
6557 break;
6558 case D3DSHADE_PHONG:
6559 /* Should be the same as GOURAUD, since no hardware implements this */
6560 ok(color_match(color0, D3DCOLOR_ARGB(0x00, 0x0d, 0xca, 0x28), 2),
6561 "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
6562 ok(color_match(color1, D3DCOLOR_ARGB(0x00, 0x0d, 0x45, 0xc7), 2),
6563 "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
6565 ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6566 color0_gouraud, color0);
6567 ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6568 color1_gouraud, color1);
6569 break;
6572 /* Now, do it all over again with a TRIANGLELIST */
6573 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
6574 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6575 primtype = D3DPT_TRIANGLELIST;
6576 shademode = D3DSHADE_FLAT;
6579 bail:
6580 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6581 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
6582 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
6583 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6585 if (vb_strip)
6586 IDirect3DVertexBuffer9_Release(vb_strip);
6587 if (vb_list)
6588 IDirect3DVertexBuffer9_Release(vb_list);
6592 static void fog_srgbwrite_test(IDirect3DDevice9 *device)
6594 /* Draw a black quad, half fogged with white fog -> grey color. Enable sRGB writing.
6595 * if sRGB writing is applied before fogging, the 0.0 will be multiplied with ~ 12.92, so still
6596 * stay 0.0. After that the fog gives 0.5. If sRGB writing is applied after fogging, the
6597 * 0.5 will run through the alternative path(0^5 ^ 0.41666 * 1.055 - 0.055), resulting in approx.
6598 * 0.73
6600 * At the time of this writing, wined3d could not apply sRGB correction to fixed function rendering,
6601 * so use shaders for this task
6603 IDirect3DPixelShader9 *pshader;
6604 IDirect3DVertexShader9 *vshader;
6605 IDirect3D9 *d3d;
6606 DWORD vshader_code[] = {
6607 0xfffe0101, /* vs_1_1 */
6608 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6609 0x00000051, 0xa00f0000, 0x3f000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.5, 0.0, 0.0, 0.0 */
6610 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6611 0x00000001, 0xc00f0001, 0xa0000000, /* mov oFog, c0.x */
6612 0x0000ffff /* end */
6614 DWORD pshader_code[] = {
6615 0xffff0101, /* ps_1_1 */
6616 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
6617 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6618 0x0000ffff /* end */
6620 const float quad[] = {
6621 -1.0, -1.0, 0.1,
6622 1.0, -1.0, 0.1,
6623 -1.0, 1.0, 0.1,
6624 1.0, 1.0, 0.1
6626 HRESULT hr;
6627 DWORD color;
6629 IDirect3DDevice9_GetDirect3D(device, &d3d);
6630 /* Ask for srgb writing on D3DRTYPE_TEXTURE. Some Windows drivers do not report it on surfaces.
6631 * For some not entirely understood reasons D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE
6632 * passes on surfaces, while asking for SRGBWRITE alone fails. Textures advertize srgb writing
6633 * alone as well, so use that since it is not the point of this test to show how CheckDeviceFormat
6634 * works
6636 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6637 D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE,
6638 D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8) != D3D_OK) {
6639 skip("No SRGBWRITEENABLE support on D3DFMT_X8R8G8B8\n");
6640 IDirect3D9_Release(d3d);
6641 return;
6643 IDirect3D9_Release(d3d);
6645 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
6646 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6648 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
6649 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6650 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
6651 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6652 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
6653 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6654 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffffffff);
6655 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6656 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
6657 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6659 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
6660 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6661 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code, &pshader);
6662 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6663 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6664 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
6665 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
6666 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6667 hr = IDirect3DDevice9_SetPixelShader(device, pshader);
6668 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6670 hr = IDirect3DDevice9_BeginScene(device);
6671 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
6672 if(SUCCEEDED(hr)) {
6673 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 3);
6674 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6676 hr = IDirect3DDevice9_EndScene(device);
6677 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
6680 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6681 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6682 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6683 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6684 IDirect3DPixelShader9_Release(pshader);
6685 IDirect3DVertexShader9_Release(vshader);
6687 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
6688 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6689 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
6690 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6692 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6693 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6694 color = getPixelColor(device, 160, 360);
6695 ok(color == 0x00808080 || color == 0x007f7f7f || color == 0x00818181,
6696 "Fog with D3DRS_SRGBWRITEENABLE returned color 0x%08x, expected 0x00808080\n", color);
6699 static void alpha_test(IDirect3DDevice9 *device)
6701 HRESULT hr;
6702 IDirect3DTexture9 *offscreenTexture;
6703 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
6704 DWORD color;
6706 struct vertex quad1[] =
6708 {-1.0f, -1.0f, 0.1f, 0x4000ff00},
6709 {-1.0f, 0.0f, 0.1f, 0x4000ff00},
6710 { 1.0f, -1.0f, 0.1f, 0x4000ff00},
6711 { 1.0f, 0.0f, 0.1f, 0x4000ff00},
6713 struct vertex quad2[] =
6715 {-1.0f, 0.0f, 0.1f, 0xc00000ff},
6716 {-1.0f, 1.0f, 0.1f, 0xc00000ff},
6717 { 1.0f, 0.0f, 0.1f, 0xc00000ff},
6718 { 1.0f, 1.0f, 0.1f, 0xc00000ff},
6720 static const float composite_quad[][5] = {
6721 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
6722 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
6723 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
6724 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
6727 /* Clear the render target with alpha = 0.5 */
6728 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6729 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6731 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
6732 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
6734 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6735 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6736 if(!backbuffer) {
6737 goto out;
6740 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
6741 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
6742 if(!offscreen) {
6743 goto out;
6746 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6747 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6749 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6750 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6751 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6752 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
6753 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
6754 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
6755 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
6756 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
6757 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6758 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
6760 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
6761 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6762 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
6764 /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
6765 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6766 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6767 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6768 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6769 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6770 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6772 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6773 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6774 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6775 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6776 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6777 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6779 /* Switch to the offscreen buffer, and redo the testing. The offscreen render target
6780 * doesn't have an alpha channel. DESTALPHA and INVDESTALPHA "don't work" on render
6781 * targets without alpha channel, they give essentially ZERO and ONE blend factors. */
6782 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
6783 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6784 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6785 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6787 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6788 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6789 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6790 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6791 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6792 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6794 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6795 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6796 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6797 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6798 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6799 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6801 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
6802 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6804 /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
6805 * Disable alpha blending for the final composition
6807 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
6808 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6809 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6810 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6812 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
6813 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6814 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
6815 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6816 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6817 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6819 hr = IDirect3DDevice9_EndScene(device);
6820 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
6823 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6825 color = getPixelColor(device, 160, 360);
6826 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6827 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
6829 color = getPixelColor(device, 160, 120);
6830 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
6831 "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
6833 color = getPixelColor(device, 480, 360);
6834 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
6835 "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
6837 color = getPixelColor(device, 480, 120);
6838 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
6839 "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
6841 out:
6842 /* restore things */
6843 if(backbuffer) {
6844 IDirect3DSurface9_Release(backbuffer);
6846 if(offscreenTexture) {
6847 IDirect3DTexture9_Release(offscreenTexture);
6849 if(offscreen) {
6850 IDirect3DSurface9_Release(offscreen);
6854 struct vertex_shortcolor {
6855 float x, y, z;
6856 unsigned short r, g, b, a;
6858 struct vertex_floatcolor {
6859 float x, y, z;
6860 float r, g, b, a;
6863 static void fixed_function_decl_test(IDirect3DDevice9 *device)
6865 HRESULT hr;
6866 BOOL s_ok, ub_ok, f_ok;
6867 DWORD color, size, i;
6868 void *data;
6869 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
6870 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6871 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6872 D3DDECL_END()
6874 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
6875 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6876 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6877 D3DDECL_END()
6879 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
6880 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6881 {0, 12, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6882 D3DDECL_END()
6884 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
6885 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6886 {1, 0, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6887 D3DDECL_END()
6889 static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
6890 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6891 {0, 12, D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6892 D3DDECL_END()
6894 static const D3DVERTEXELEMENT9 decl_elements_float[] = {
6895 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6896 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6897 D3DDECL_END()
6899 static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
6900 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
6901 {0, 16, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6902 D3DDECL_END()
6904 IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
6905 IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
6906 IDirect3DVertexBuffer9 *vb, *vb2;
6907 struct vertex quad1[] = /* D3DCOLOR */
6909 {-1.0f, -1.0f, 0.1f, 0x00ffff00},
6910 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
6911 { 0.0f, -1.0f, 0.1f, 0x00ffff00},
6912 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
6914 struct vertex quad2[] = /* UBYTE4N */
6916 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
6917 {-1.0f, 1.0f, 0.1f, 0x00ffff00},
6918 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
6919 { 0.0f, 1.0f, 0.1f, 0x00ffff00},
6921 struct vertex_shortcolor quad3[] = /* short */
6923 { 0.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6924 { 0.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6925 { 1.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6926 { 1.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6928 struct vertex_floatcolor quad4[] =
6930 { 0.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6931 { 0.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6932 { 1.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6933 { 1.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6935 DWORD colors[] = {
6936 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6937 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6938 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6939 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6940 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6941 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6942 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6943 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6944 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6945 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6946 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6947 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6948 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6949 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6950 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6951 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6953 float quads[] = {
6954 -1.0, -1.0, 0.1,
6955 -1.0, 0.0, 0.1,
6956 0.0, -1.0, 0.1,
6957 0.0, 0.0, 0.1,
6959 0.0, -1.0, 0.1,
6960 0.0, 0.0, 0.1,
6961 1.0, -1.0, 0.1,
6962 1.0, 0.0, 0.1,
6964 0.0, 0.0, 0.1,
6965 0.0, 1.0, 0.1,
6966 1.0, 0.0, 0.1,
6967 1.0, 1.0, 0.1,
6969 -1.0, 0.0, 0.1,
6970 -1.0, 1.0, 0.1,
6971 0.0, 0.0, 0.1,
6972 0.0, 1.0, 0.1
6974 struct tvertex quad_transformed[] = {
6975 { 90, 110, 0.1, 2.0, 0x00ffff00},
6976 { 570, 110, 0.1, 2.0, 0x00ffff00},
6977 { 90, 300, 0.1, 2.0, 0x00ffff00},
6978 { 570, 300, 0.1, 2.0, 0x00ffff00}
6980 D3DCAPS9 caps;
6982 memset(&caps, 0, sizeof(caps));
6983 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6984 ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
6986 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6987 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6989 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
6990 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6991 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
6992 ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
6993 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
6994 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6995 if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
6996 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
6997 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6998 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
6999 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7000 } else {
7001 trace("D3DDTCAPS_UBYTE4N not supported\n");
7002 dcl_ubyte_2 = NULL;
7003 dcl_ubyte = NULL;
7005 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
7006 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7007 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
7008 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
7010 size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
7011 hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
7012 0, 0, D3DPOOL_MANAGED, &vb, NULL);
7013 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7015 hr = IDirect3DDevice9_BeginScene(device);
7016 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7017 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7018 if(SUCCEEDED(hr)) {
7019 if(dcl_color) {
7020 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7021 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7022 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7023 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7026 /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
7027 * accepts them, the nvidia driver accepts them all. All those differences even though we're
7028 * using software vertex processing. Doh!
7030 if(dcl_ubyte) {
7031 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7032 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7033 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
7034 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7035 ub_ok = SUCCEEDED(hr);
7038 if(dcl_short) {
7039 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7040 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7041 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
7042 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7043 s_ok = SUCCEEDED(hr);
7046 if(dcl_float) {
7047 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7048 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7049 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7050 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7051 f_ok = SUCCEEDED(hr);
7054 hr = IDirect3DDevice9_EndScene(device);
7055 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7058 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7059 if(dcl_short) {
7060 color = getPixelColor(device, 480, 360);
7061 ok(color == 0x000000ff || !s_ok,
7062 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7064 if(dcl_ubyte) {
7065 color = getPixelColor(device, 160, 120);
7066 ok(color == 0x0000ffff || !ub_ok,
7067 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7069 if(dcl_color) {
7070 color = getPixelColor(device, 160, 360);
7071 ok(color == 0x00ffff00,
7072 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7074 if(dcl_float) {
7075 color = getPixelColor(device, 480, 120);
7076 ok(color == 0x00ff0000 || !f_ok,
7077 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7080 /* The following test with vertex buffers doesn't serve to find out new information from windows.
7081 * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7082 * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7083 * whether the immediate mode code works
7085 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7086 hr = IDirect3DDevice9_BeginScene(device);
7087 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7088 if(SUCCEEDED(hr)) {
7089 if(dcl_color) {
7090 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), (void **) &data, 0);
7091 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7092 memcpy(data, quad1, sizeof(quad1));
7093 hr = IDirect3DVertexBuffer9_Unlock(vb);
7094 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7095 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7096 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7097 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7098 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7099 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7100 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7103 if(dcl_ubyte) {
7104 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), (void **) &data, 0);
7105 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7106 memcpy(data, quad2, sizeof(quad2));
7107 hr = IDirect3DVertexBuffer9_Unlock(vb);
7108 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7109 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7110 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7111 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7112 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7113 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7114 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7115 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7116 ub_ok = SUCCEEDED(hr);
7119 if(dcl_short) {
7120 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), (void **) &data, 0);
7121 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7122 memcpy(data, quad3, sizeof(quad3));
7123 hr = IDirect3DVertexBuffer9_Unlock(vb);
7124 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7125 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7126 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7127 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7128 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7129 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7130 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7131 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7132 s_ok = SUCCEEDED(hr);
7135 if(dcl_float) {
7136 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), (void **) &data, 0);
7137 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7138 memcpy(data, quad4, sizeof(quad4));
7139 hr = IDirect3DVertexBuffer9_Unlock(vb);
7140 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7141 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7142 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7143 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7144 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7145 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7146 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7147 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7148 f_ok = SUCCEEDED(hr);
7151 hr = IDirect3DDevice9_EndScene(device);
7152 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7155 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7156 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7157 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7158 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7160 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7161 if(dcl_short) {
7162 color = getPixelColor(device, 480, 360);
7163 ok(color == 0x000000ff || !s_ok,
7164 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7166 if(dcl_ubyte) {
7167 color = getPixelColor(device, 160, 120);
7168 ok(color == 0x0000ffff || !ub_ok,
7169 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7171 if(dcl_color) {
7172 color = getPixelColor(device, 160, 360);
7173 ok(color == 0x00ffff00,
7174 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7176 if(dcl_float) {
7177 color = getPixelColor(device, 480, 120);
7178 ok(color == 0x00ff0000 || !f_ok,
7179 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7182 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7183 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7185 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), (void **) &data, 0);
7186 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7187 memcpy(data, quad_transformed, sizeof(quad_transformed));
7188 hr = IDirect3DVertexBuffer9_Unlock(vb);
7189 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7191 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7192 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7194 hr = IDirect3DDevice9_BeginScene(device);
7195 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7196 if(SUCCEEDED(hr)) {
7197 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7198 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7199 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7200 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7202 hr = IDirect3DDevice9_EndScene(device);
7203 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7206 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7207 color = getPixelColor(device, 88, 108);
7208 ok(color == 0x000000ff,
7209 "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7210 color = getPixelColor(device, 92, 108);
7211 ok(color == 0x000000ff,
7212 "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7213 color = getPixelColor(device, 88, 112);
7214 ok(color == 0x000000ff,
7215 "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7216 color = getPixelColor(device, 92, 112);
7217 ok(color == 0x00ffff00,
7218 "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7220 color = getPixelColor(device, 568, 108);
7221 ok(color == 0x000000ff,
7222 "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7223 color = getPixelColor(device, 572, 108);
7224 ok(color == 0x000000ff,
7225 "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7226 color = getPixelColor(device, 568, 112);
7227 ok(color == 0x00ffff00,
7228 "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7229 color = getPixelColor(device, 572, 112);
7230 ok(color == 0x000000ff,
7231 "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7233 color = getPixelColor(device, 88, 298);
7234 ok(color == 0x000000ff,
7235 "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7236 color = getPixelColor(device, 92, 298);
7237 ok(color == 0x00ffff00,
7238 "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7239 color = getPixelColor(device, 88, 302);
7240 ok(color == 0x000000ff,
7241 "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7242 color = getPixelColor(device, 92, 302);
7243 ok(color == 0x000000ff,
7244 "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7246 color = getPixelColor(device, 568, 298);
7247 ok(color == 0x00ffff00,
7248 "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7249 color = getPixelColor(device, 572, 298);
7250 ok(color == 0x000000ff,
7251 "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7252 color = getPixelColor(device, 568, 302);
7253 ok(color == 0x000000ff,
7254 "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7255 color = getPixelColor(device, 572, 302);
7256 ok(color == 0x000000ff,
7257 "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7259 /* This test is pointless without those two declarations: */
7260 if((!dcl_color_2) || (!dcl_ubyte_2)) {
7261 skip("color-ubyte switching test declarations aren't supported\n");
7262 goto out;
7265 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), (void **) &data, 0);
7266 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7267 memcpy(data, quads, sizeof(quads));
7268 hr = IDirect3DVertexBuffer9_Unlock(vb);
7269 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7270 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7271 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7272 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
7273 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), (void **) &data, 0);
7274 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
7275 memcpy(data, colors, sizeof(colors));
7276 hr = IDirect3DVertexBuffer9_Unlock(vb2);
7277 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7279 for(i = 0; i < 2; i++) {
7280 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7281 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
7283 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7284 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7285 if(i == 0) {
7286 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7287 } else {
7288 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7290 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7292 hr = IDirect3DDevice9_BeginScene(device);
7293 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
7294 ub_ok = FALSE;
7295 if(SUCCEEDED(hr)) {
7296 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7297 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7298 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7299 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7300 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7301 ub_ok = SUCCEEDED(hr);
7303 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7304 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7305 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7306 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7308 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7309 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
7310 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7311 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7312 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7313 ub_ok = (SUCCEEDED(hr) && ub_ok);
7315 hr = IDirect3DDevice9_EndScene(device);
7316 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
7319 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7320 if(i == 0) {
7321 color = getPixelColor(device, 480, 360);
7322 ok(color == 0x00ff0000,
7323 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7324 color = getPixelColor(device, 160, 120);
7325 ok(color == 0x00ffffff,
7326 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7327 color = getPixelColor(device, 160, 360);
7328 ok(color == 0x000000ff || !ub_ok,
7329 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7330 color = getPixelColor(device, 480, 120);
7331 ok(color == 0x000000ff || !ub_ok,
7332 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7333 } else {
7334 color = getPixelColor(device, 480, 360);
7335 ok(color == 0x000000ff,
7336 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7337 color = getPixelColor(device, 160, 120);
7338 ok(color == 0x00ffffff,
7339 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7340 color = getPixelColor(device, 160, 360);
7341 ok(color == 0x00ff0000 || !ub_ok,
7342 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7343 color = getPixelColor(device, 480, 120);
7344 ok(color == 0x00ff0000 || !ub_ok,
7345 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7349 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7350 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7351 hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7352 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
7353 IDirect3DVertexBuffer9_Release(vb2);
7355 out:
7356 IDirect3DVertexBuffer9_Release(vb);
7357 if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7358 if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7359 if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7360 if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7361 if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7362 if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7363 if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7366 struct vertex_float16color {
7367 float x, y, z;
7368 DWORD c1, c2;
7371 static void test_vshader_float16(IDirect3DDevice9 *device)
7373 HRESULT hr;
7374 DWORD color;
7375 void *data;
7376 static const D3DVERTEXELEMENT9 decl_elements[] = {
7377 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7378 {0, 12, D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7379 D3DDECL_END()
7381 IDirect3DVertexDeclaration9 *vdecl = NULL;
7382 IDirect3DVertexBuffer9 *buffer = NULL;
7383 IDirect3DVertexShader9 *shader;
7384 DWORD shader_code[] = {
7385 0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7386 0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7387 0x90e40001, 0x0000ffff
7389 struct vertex_float16color quad[] = {
7390 { -1.0, -1.0, 0.1, 0x3c000000, 0x00000000 }, /* green */
7391 { -1.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
7392 { 0.0, -1.0, 0.1, 0x3c000000, 0x00000000 },
7393 { 0.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
7395 { 0.0, -1.0, 0.1, 0x00003c00, 0x00000000 }, /* red */
7396 { 0.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
7397 { 1.0, -1.0, 0.1, 0x00003c00, 0x00000000 },
7398 { 1.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
7400 { 0.0, 0.0, 0.1, 0x00000000, 0x00003c00 }, /* blue */
7401 { 0.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
7402 { 1.0, 0.0, 0.1, 0x00000000, 0x00003c00 },
7403 { 1.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
7405 { -1.0, 0.0, 0.1, 0x00000000, 0x3c000000 }, /* alpha */
7406 { -1.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
7407 { 0.0, 0.0, 0.1, 0x00000000, 0x3c000000 },
7408 { 0.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
7411 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7412 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7414 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7415 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
7416 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7417 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
7418 hr = IDirect3DDevice9_SetVertexShader(device, shader);
7419 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7421 hr = IDirect3DDevice9_BeginScene(device);
7422 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7423 if(SUCCEEDED(hr)) {
7424 hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7425 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7426 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 0, sizeof(quad[0]));
7427 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7428 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 4, sizeof(quad[0]));
7429 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7430 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 8, sizeof(quad[0]));
7431 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7432 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7433 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7435 hr = IDirect3DDevice9_EndScene(device);
7436 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7438 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7439 color = getPixelColor(device, 480, 360);
7440 ok(color == 0x00ff0000,
7441 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7442 color = getPixelColor(device, 160, 120);
7443 ok(color == 0x00000000,
7444 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7445 color = getPixelColor(device, 160, 360);
7446 ok(color == 0x0000ff00,
7447 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7448 color = getPixelColor(device, 480, 120);
7449 ok(color == 0x000000ff,
7450 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7452 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7453 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7455 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7456 D3DPOOL_MANAGED, &buffer, NULL);
7457 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
7458 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), (void **) &data, 0);
7459 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
7460 memcpy(data, quad, sizeof(quad));
7461 hr = IDirect3DVertexBuffer9_Unlock(buffer);
7462 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
7463 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7464 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7466 hr = IDirect3DDevice9_BeginScene(device);
7467 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7468 if(SUCCEEDED(hr)) {
7469 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7470 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7471 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7472 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7473 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7474 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7475 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7476 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7478 hr = IDirect3DDevice9_EndScene(device);
7479 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
7482 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7483 color = getPixelColor(device, 480, 360);
7484 ok(color == 0x00ff0000,
7485 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7486 color = getPixelColor(device, 160, 120);
7487 ok(color == 0x00000000,
7488 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7489 color = getPixelColor(device, 160, 360);
7490 ok(color == 0x0000ff00,
7491 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7492 color = getPixelColor(device, 480, 120);
7493 ok(color == 0x000000ff,
7494 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7496 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7497 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
7498 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7499 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7500 IDirect3DDevice9_SetVertexShader(device, NULL);
7501 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
7503 IDirect3DVertexDeclaration9_Release(vdecl);
7504 IDirect3DVertexShader9_Release(shader);
7505 IDirect3DVertexBuffer9_Release(buffer);
7508 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7510 D3DCAPS9 caps;
7511 IDirect3DTexture9 *texture;
7512 HRESULT hr;
7513 D3DLOCKED_RECT rect;
7514 unsigned int x, y;
7515 DWORD *dst, color;
7516 const float quad[] = {
7517 -1.0, -1.0, 0.1, -0.2, -0.2,
7518 1.0, -1.0, 0.1, 1.2, -0.2,
7519 -1.0, 1.0, 0.1, -0.2, 1.2,
7520 1.0, 1.0, 0.1, 1.2, 1.2
7522 memset(&caps, 0, sizeof(caps));
7524 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7525 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7526 if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7527 /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7528 ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
7529 "Card has conditional NP2 support without power of two restriction set\n");
7530 skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
7531 return;
7532 } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7533 skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7534 return;
7537 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7538 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7540 hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7541 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7543 memset(&rect, 0, sizeof(rect));
7544 hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7545 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
7546 for(y = 0; y < 10; y++) {
7547 for(x = 0; x < 10; x++) {
7548 dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7549 if(x == 0 || x == 9 || y == 0 || y == 9) {
7550 *dst = 0x00ff0000;
7551 } else {
7552 *dst = 0x000000ff;
7556 hr = IDirect3DTexture9_UnlockRect(texture, 0);
7557 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
7559 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7560 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7561 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
7562 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7563 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
7564 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
7565 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7566 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
7568 hr = IDirect3DDevice9_BeginScene(device);
7569 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7570 if(SUCCEEDED(hr)) {
7571 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7572 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7574 hr = IDirect3DDevice9_EndScene(device);
7575 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7578 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7580 color = getPixelColor(device, 1, 1);
7581 ok(color == 0x00ff0000, "NP2: Pixel 1, 1 has color %08x, expected 0x00ff0000\n", color);
7582 color = getPixelColor(device, 639, 479);
7583 ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
7585 color = getPixelColor(device, 135, 101);
7586 ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
7587 color = getPixelColor(device, 140, 101);
7588 ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
7589 color = getPixelColor(device, 135, 105);
7590 ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
7591 color = getPixelColor(device, 140, 105);
7592 ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
7594 color = getPixelColor(device, 135, 376);
7595 ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
7596 color = getPixelColor(device, 140, 376);
7597 ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
7598 color = getPixelColor(device, 135, 379);
7599 ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
7600 color = getPixelColor(device, 140, 379);
7601 ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
7603 color = getPixelColor(device, 500, 101);
7604 ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
7605 color = getPixelColor(device, 504, 101);
7606 ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
7607 color = getPixelColor(device, 500, 105);
7608 ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
7609 color = getPixelColor(device, 504, 105);
7610 ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
7612 color = getPixelColor(device, 500, 376);
7613 ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
7614 color = getPixelColor(device, 504, 376);
7615 ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
7616 color = getPixelColor(device, 500, 380);
7617 ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
7618 color = getPixelColor(device, 504, 380);
7619 ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
7621 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7622 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
7623 IDirect3DTexture9_Release(texture);
7626 static void vFace_register_test(IDirect3DDevice9 *device)
7628 HRESULT hr;
7629 DWORD color;
7630 const DWORD shader_code[] = {
7631 0xffff0300, /* ps_3_0 */
7632 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
7633 0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
7634 0x0200001f, 0x80000000, 0x900f1001, /* dcl vFace */
7635 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
7636 0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001, /* cmp r0, vFace, c0, r1 */
7637 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
7638 0x0000ffff /* END */
7640 IDirect3DPixelShader9 *shader;
7641 IDirect3DTexture9 *texture;
7642 IDirect3DSurface9 *surface, *backbuffer;
7643 const float quad[] = {
7644 -1.0, -1.0, 0.1,
7645 1.0, -1.0, 0.1,
7646 -1.0, 0.0, 0.1,
7648 1.0, -1.0, 0.1,
7649 1.0, 0.0, 0.1,
7650 -1.0, 0.0, 0.1,
7652 -1.0, 0.0, 0.1,
7653 -1.0, 1.0, 0.1,
7654 1.0, 0.0, 0.1,
7656 1.0, 0.0, 0.1,
7657 -1.0, 1.0, 0.1,
7658 1.0, 1.0, 0.1,
7660 const float blit[] = {
7661 0.0, -1.0, 0.1, 0.0, 0.0,
7662 1.0, -1.0, 0.1, 1.0, 0.0,
7663 0.0, 1.0, 0.1, 0.0, 1.0,
7664 1.0, 1.0, 0.1, 1.0, 1.0,
7667 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
7668 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
7669 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
7670 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
7671 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7672 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
7673 hr = IDirect3DDevice9_SetPixelShader(device, shader);
7674 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7675 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7676 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7677 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7678 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
7680 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7681 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7683 hr = IDirect3DDevice9_BeginScene(device);
7684 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
7685 if(SUCCEEDED(hr)) {
7686 /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
7687 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
7688 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7689 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7690 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
7691 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7692 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7693 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7694 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
7695 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7696 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7698 /* Blit the texture onto the back buffer to make it visible */
7699 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7700 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
7701 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7702 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
7703 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7704 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7705 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7706 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%08x\n", hr);
7707 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7708 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
7710 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
7711 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
7713 hr = IDirect3DDevice9_EndScene(device);
7714 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
7717 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7718 color = getPixelColor(device, 160, 360);
7719 ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7720 color = getPixelColor(device, 160, 120);
7721 ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7722 color = getPixelColor(device, 480, 360);
7723 ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7724 color = getPixelColor(device, 480, 120);
7725 ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7727 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
7728 IDirect3DDevice9_SetTexture(device, 0, NULL);
7729 IDirect3DPixelShader9_Release(shader);
7730 IDirect3DSurface9_Release(surface);
7731 IDirect3DSurface9_Release(backbuffer);
7732 IDirect3DTexture9_Release(texture);
7735 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
7737 HRESULT hr;
7738 DWORD color;
7739 int i;
7740 D3DCAPS9 caps;
7741 BOOL L6V5U5_supported = FALSE;
7742 IDirect3DTexture9 *tex1, *tex2;
7743 D3DLOCKED_RECT locked_rect;
7745 static const float quad[][7] = {
7746 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
7747 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
7748 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
7749 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
7752 static const D3DVERTEXELEMENT9 decl_elements[] = {
7753 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7754 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7755 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7756 D3DDECL_END()
7759 /* use asymmetric matrix to test loading */
7760 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
7761 float scale, offset;
7763 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
7764 IDirect3DTexture9 *texture = NULL;
7766 memset(&caps, 0, sizeof(caps));
7767 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7768 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
7769 if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
7770 skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
7771 return;
7772 } else {
7773 /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
7774 * They report that it is not supported, but after that bump mapping works properly. So just test
7775 * if the format is generally supported, and check the BUMPENVMAP flag
7777 IDirect3D9 *d3d9;
7779 IDirect3DDevice9_GetDirect3D(device, &d3d9);
7780 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7781 D3DRTYPE_TEXTURE, D3DFMT_L6V5U5);
7782 L6V5U5_supported = SUCCEEDED(hr);
7783 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7784 D3DRTYPE_TEXTURE, D3DFMT_V8U8);
7785 IDirect3D9_Release(d3d9);
7786 if(FAILED(hr)) {
7787 skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
7788 return;
7792 /* Generate the textures */
7793 generate_bumpmap_textures(device);
7795 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
7796 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7797 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
7798 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7799 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
7800 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7801 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
7802 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7804 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
7805 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7806 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
7807 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7808 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
7809 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7811 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7812 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7813 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7814 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7815 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7816 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7818 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
7819 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7821 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7822 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
7824 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
7825 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
7828 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
7829 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
7830 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
7831 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
7833 hr = IDirect3DDevice9_BeginScene(device);
7834 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7836 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7837 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7839 hr = IDirect3DDevice9_EndScene(device);
7840 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7842 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7843 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7845 /* on MacOS(10.5.4, radeon X1600), the white dots are have color 0x00fbfbfb rather than 0x00ffffff. This is
7846 * kinda strange since no calculations are done on the sampled colors, only on the texture coordinates.
7847 * But since testing the color match is not the purpose of the test don't be too picky
7849 color = getPixelColor(device, 320-32, 240);
7850 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7851 color = getPixelColor(device, 320+32, 240);
7852 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7853 color = getPixelColor(device, 320, 240-32);
7854 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7855 color = getPixelColor(device, 320, 240+32);
7856 ok(color_match(color, 0x00ffffff, 4), "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7857 color = getPixelColor(device, 320, 240);
7858 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7859 color = getPixelColor(device, 320+32, 240+32);
7860 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7861 color = getPixelColor(device, 320-32, 240+32);
7862 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7863 color = getPixelColor(device, 320+32, 240-32);
7864 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7865 color = getPixelColor(device, 320-32, 240-32);
7866 ok(color_match(color, 0x00000000, 4), "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7868 for(i = 0; i < 2; i++) {
7869 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
7870 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
7871 IDirect3DTexture9_Release(texture); /* For the GetTexture */
7872 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
7873 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
7874 IDirect3DTexture9_Release(texture); /* To destroy it */
7877 if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE)) {
7878 skip("D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping\n");
7879 goto cleanup;
7881 if(L6V5U5_supported == FALSE) {
7882 skip("L6V5U5_supported not supported, skipping D3DTOP_BUMPENVMAPLUMINANCE test\n");
7883 goto cleanup;
7886 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 0.0, 0x8);
7887 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7888 /* This test only tests the luminance part. The bumpmapping part was already tested above and
7889 * would only make this test more complicated
7891 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
7892 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
7893 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
7894 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
7896 memset(&locked_rect, 0, sizeof(locked_rect));
7897 hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
7898 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
7899 *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
7900 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
7901 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
7903 memset(&locked_rect, 0, sizeof(locked_rect));
7904 hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
7905 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
7906 *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
7907 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
7908 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
7910 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
7911 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7912 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
7913 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7915 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
7916 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7917 scale = 2.0;
7918 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7919 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7920 offset = 0.1;
7921 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7922 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7924 hr = IDirect3DDevice9_BeginScene(device);
7925 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7926 if(SUCCEEDED(hr)) {
7927 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7928 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7929 hr = IDirect3DDevice9_EndScene(device);
7930 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7933 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7934 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7935 color = getPixelColor(device, 320, 240);
7936 /* red: 1.0 * (0.25 * 2.0 + 0.1) = 1.0 * 0.6 = 0.6 = 0x99
7937 * green: 0.5 * (0.25 * 2.0 + 0.1) = 0.5 * 0.6 = 0.3 = 0x4c
7938 * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
7940 ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
7942 /* Check a result scale factor > 1.0 */
7943 scale = 10;
7944 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7945 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7946 offset = 10;
7947 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7948 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7950 hr = IDirect3DDevice9_BeginScene(device);
7951 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7952 if(SUCCEEDED(hr)) {
7953 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7954 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7955 hr = IDirect3DDevice9_EndScene(device);
7956 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7958 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7959 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7960 color = getPixelColor(device, 320, 240);
7961 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
7963 /* Check clamping in the scale factor calculation */
7964 scale = 1000;
7965 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
7966 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7967 offset = -1;
7968 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
7969 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7971 hr = IDirect3DDevice9_BeginScene(device);
7972 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7973 if(SUCCEEDED(hr)) {
7974 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7975 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7976 hr = IDirect3DDevice9_EndScene(device);
7977 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7979 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7980 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7981 color = getPixelColor(device, 320, 240);
7982 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
7984 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7985 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7986 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
7987 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
7989 IDirect3DTexture9_Release(tex1);
7990 IDirect3DTexture9_Release(tex2);
7992 cleanup:
7993 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
7994 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7995 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
7996 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7998 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7999 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
8000 IDirect3DVertexDeclaration9_Release(vertex_declaration);
8003 static void stencil_cull_test(IDirect3DDevice9 *device) {
8004 HRESULT hr;
8005 IDirect3DSurface9 *depthstencil = NULL;
8006 D3DSURFACE_DESC desc;
8007 float quad1[] = {
8008 -1.0, -1.0, 0.1,
8009 0.0, -1.0, 0.1,
8010 -1.0, 0.0, 0.1,
8011 0.0, 0.0, 0.1,
8013 float quad2[] = {
8014 0.0, -1.0, 0.1,
8015 1.0, -1.0, 0.1,
8016 0.0, 0.0, 0.1,
8017 1.0, 0.0, 0.1,
8019 float quad3[] = {
8020 0.0, 0.0, 0.1,
8021 1.0, 0.0, 0.1,
8022 0.0, 1.0, 0.1,
8023 1.0, 1.0, 0.1,
8025 float quad4[] = {
8026 -1.0, 0.0, 0.1,
8027 0.0, 0.0, 0.1,
8028 -1.0, 1.0, 0.1,
8029 0.0, 1.0, 0.1,
8031 struct vertex painter[] = {
8032 {-1.0, -1.0, 0.0, 0x00000000},
8033 { 1.0, -1.0, 0.0, 0x00000000},
8034 {-1.0, 1.0, 0.0, 0x00000000},
8035 { 1.0, 1.0, 0.0, 0x00000000},
8037 WORD indices_cw[] = {0, 1, 3};
8038 WORD indices_ccw[] = {0, 2, 3};
8039 unsigned int i;
8040 DWORD color;
8042 IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
8043 if(depthstencil == NULL) {
8044 skip("No depth stencil buffer\n");
8045 return;
8047 hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
8048 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
8049 IDirect3DSurface9_Release(depthstencil);
8050 if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
8051 skip("No 4 or 8 bit stencil surface\n");
8052 return;
8055 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
8056 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
8057 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8059 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
8060 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8061 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
8062 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8063 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
8064 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8065 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
8066 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8068 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
8069 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8070 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
8071 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8072 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
8073 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8075 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
8076 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8077 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8078 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8080 /* First pass: Fill the stencil buffer with some values... */
8081 hr = IDirect3DDevice9_BeginScene(device);
8082 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8083 if(SUCCEEDED(hr))
8085 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8086 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8087 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8088 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8089 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8090 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
8092 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
8093 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8094 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8095 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8096 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8097 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8098 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8099 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
8101 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
8102 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8103 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8104 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8105 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8106 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
8108 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
8109 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8110 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8111 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8112 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
8113 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
8115 hr = IDirect3DDevice9_EndScene(device);
8116 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8119 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8120 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
8121 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8122 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
8123 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8124 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
8125 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8126 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
8127 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8128 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8129 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8130 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
8131 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8133 /* 2nd pass: Make the stencil values visible */
8134 hr = IDirect3DDevice9_BeginScene(device);
8135 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %08x\n", hr);
8136 if(SUCCEEDED(hr))
8138 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8139 for(i = 0; i < 16; i++) {
8140 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
8141 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8143 painter[0].diffuse = (i * 16); /* Creates shades of blue */
8144 painter[1].diffuse = (i * 16);
8145 painter[2].diffuse = (i * 16);
8146 painter[3].diffuse = (i * 16);
8147 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
8148 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
8150 hr = IDirect3DDevice9_EndScene(device);
8151 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %08x\n", hr);
8154 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8155 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8157 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8158 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8160 color = getPixelColor(device, 160, 420);
8161 ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8162 color = getPixelColor(device, 160, 300);
8163 ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8165 color = getPixelColor(device, 480, 420);
8166 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8167 color = getPixelColor(device, 480, 300);
8168 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8170 color = getPixelColor(device, 160, 180);
8171 ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8172 color = getPixelColor(device, 160, 60);
8173 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8175 color = getPixelColor(device, 480, 180);
8176 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8177 color = getPixelColor(device, 480, 60);
8178 ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8181 static void vpos_register_test(IDirect3DDevice9 *device)
8183 HRESULT hr;
8184 DWORD color;
8185 const DWORD shader_code[] = {
8186 0xffff0300, /* ps_3_0 */
8187 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8188 0x03000002, 0x80030000, 0x90541000, 0xa1fe0000, /* sub r0.xy, vPos.xy, c0.zw */
8189 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
8190 0x02000001, 0x80080002, 0xa0550000, /* mov r2.a, c0.y */
8191 0x02000001, 0x80010002, 0xa0550000, /* mov r2.r, c0.y */
8192 0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001, /* cmp r2.g, r0.x, r1.x, r1.y */
8193 0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001, /* cmp r2.b, r0.y, r1.x, r1.y */
8194 0x02000001, 0x800f0800, 0x80e40002, /* mov oC0, r2 */
8195 0x0000ffff /* end */
8197 const DWORD shader_frac_code[] = {
8198 0xffff0300, /* ps_3_0 */
8199 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8200 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8201 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
8202 0x02000013, 0x80030000, 0x90541000, /* frc r0.xy, vPos.xy */
8203 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
8204 0x0000ffff /* end */
8206 IDirect3DPixelShader9 *shader, *shader_frac;
8207 IDirect3DSurface9 *surface = NULL, *backbuffer;
8208 const float quad[] = {
8209 -1.0, -1.0, 0.1, 0.0, 0.0,
8210 1.0, -1.0, 0.1, 1.0, 0.0,
8211 -1.0, 1.0, 0.1, 0.0, 1.0,
8212 1.0, 1.0, 0.1, 1.0, 1.0,
8214 D3DLOCKED_RECT lr;
8215 float constant[4] = {1.0, 0.0, 320, 240};
8216 DWORD *pos;
8218 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8219 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8220 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8221 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8222 hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8223 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
8224 hr = IDirect3DDevice9_SetPixelShader(device, shader);
8225 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8226 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8227 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8228 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8229 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
8231 hr = IDirect3DDevice9_BeginScene(device);
8232 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8233 if(SUCCEEDED(hr)) {
8234 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8235 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8236 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8237 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8238 hr = IDirect3DDevice9_EndScene(device);
8239 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8242 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8243 /* This has to be pixel exact */
8244 color = getPixelColor(device, 319, 239);
8245 ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8246 color = getPixelColor(device, 320, 239);
8247 ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8248 color = getPixelColor(device, 319, 240);
8249 ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8250 color = getPixelColor(device, 320, 240);
8251 ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8253 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8254 &surface, NULL);
8255 ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
8256 hr = IDirect3DDevice9_BeginScene(device);
8257 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8258 if(SUCCEEDED(hr)) {
8259 constant[2] = 16; constant[3] = 16;
8260 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8261 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%08x\n", hr);
8262 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8263 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8264 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8265 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8266 hr = IDirect3DDevice9_EndScene(device);
8267 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8269 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8270 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8272 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8273 color = *pos & 0x00ffffff;
8274 ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8275 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8276 color = *pos & 0x00ffffff;
8277 ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8278 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8279 color = *pos & 0x00ffffff;
8280 ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8281 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8282 color = *pos & 0x00ffffff;
8283 ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8285 hr = IDirect3DSurface9_UnlockRect(surface);
8286 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8288 /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8289 * have full control over the multisampling setting inside this test
8291 hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8292 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8293 hr = IDirect3DDevice9_BeginScene(device);
8294 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8295 if(SUCCEEDED(hr)) {
8296 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8297 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8298 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8299 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8300 hr = IDirect3DDevice9_EndScene(device);
8301 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8303 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8304 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8306 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8307 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
8309 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8310 color = *pos & 0x00ffffff;
8311 ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8313 hr = IDirect3DSurface9_UnlockRect(surface);
8314 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
8316 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8317 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
8318 IDirect3DPixelShader9_Release(shader);
8319 IDirect3DPixelShader9_Release(shader_frac);
8320 if(surface) IDirect3DSurface9_Release(surface);
8321 IDirect3DSurface9_Release(backbuffer);
8324 static void pointsize_test(IDirect3DDevice9 *device)
8326 HRESULT hr;
8327 D3DCAPS9 caps;
8328 D3DMATRIX matrix;
8329 D3DMATRIX identity;
8330 float ptsize, ptsize_orig, ptsizemax_orig, ptsizemin_orig;
8331 DWORD color;
8333 const float vertices[] = {
8334 64, 64, 0.1,
8335 128, 64, 0.1,
8336 192, 64, 0.1,
8337 256, 64, 0.1,
8338 320, 64, 0.1,
8339 384, 64, 0.1,
8340 448, 64, 0.1,
8341 512, 64, 0.1,
8342 576, 64, 0.1,
8345 /* Transforms the coordinate system [-1.0;1.0]x[-1.0;1.0] to [0.0;0.0]x[640.0;480.0]. Z is untouched */
8346 U(matrix).m[0][0] = 2.0/640.0; U(matrix).m[1][0] = 0.0; U(matrix).m[2][0] = 0.0; U(matrix).m[3][0] =-1.0;
8347 U(matrix).m[0][1] = 0.0; U(matrix).m[1][1] =-2.0/480.0; U(matrix).m[2][1] = 0.0; U(matrix).m[3][1] = 1.0;
8348 U(matrix).m[0][2] = 0.0; U(matrix).m[1][2] = 0.0; U(matrix).m[2][2] = 1.0; U(matrix).m[3][2] = 0.0;
8349 U(matrix).m[0][3] = 0.0; U(matrix).m[1][3] = 0.0; U(matrix).m[2][3] = 0.0; U(matrix).m[3][3] = 1.0;
8351 U(identity).m[0][0] = 1.0; U(identity).m[1][0] = 0.0; U(identity).m[2][0] = 0.0; U(identity).m[3][0] = 0.0;
8352 U(identity).m[0][1] = 0.0; U(identity).m[1][1] = 1.0; U(identity).m[2][1] = 0.0; U(identity).m[3][1] = 0.0;
8353 U(identity).m[0][2] = 0.0; U(identity).m[1][2] = 0.0; U(identity).m[2][2] = 1.0; U(identity).m[3][2] = 0.0;
8354 U(identity).m[0][3] = 0.0; U(identity).m[1][3] = 0.0; U(identity).m[2][3] = 0.0; U(identity).m[3][3] = 1.0;
8356 memset(&caps, 0, sizeof(caps));
8357 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8358 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
8359 if(caps.MaxPointSize < 32.0) {
8360 skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8361 return;
8364 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8365 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8366 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8367 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8368 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8369 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
8370 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8371 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%08x\n", hr);
8373 hr = IDirect3DDevice9_BeginScene(device);
8374 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%08x\n", hr);
8375 if(SUCCEEDED(hr)) {
8376 ptsize = 16.0;
8377 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8378 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8379 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8380 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8382 ptsize = 32.0;
8383 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8384 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8385 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8386 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8388 ptsize = 31.5;
8389 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8390 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8391 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8392 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8394 if(caps.MaxPointSize >= 64.0) {
8395 ptsize = 64.0;
8396 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8397 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8398 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8399 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8401 ptsize = 63.75;
8402 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8403 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8404 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8405 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8408 ptsize = 1.0;
8409 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8410 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8411 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8412 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8414 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemax_orig));
8415 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8416 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *) (&ptsizemin_orig));
8417 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed, hr=%08x\n", hr);
8419 /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
8420 ptsize = 16.0;
8421 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8422 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8423 ptsize = 1.0;
8424 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsize)));
8425 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8426 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
8427 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8429 /* What happens if POINTSIZE_MAX < POINTSIZE_MIN?
8430 * ptsize = 4.0, ptsize_max = 1.0, ptsize_min = 16.0
8432 ptsize = 4.0;
8433 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8434 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8435 ptsize = 16.0;
8436 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8437 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8438 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
8439 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8441 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *((DWORD *) (&ptsizemax_orig)));
8442 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8444 /* pointsize < pointsize_min < pointsize_max?
8445 * pointsize = 1.0, pointsize_min = 16.0, pointsize_max = default(usually 64.0)
8447 ptsize = 1.0;
8448 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8449 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8450 ptsize = 16.0;
8451 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsize)));
8452 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8453 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[24], sizeof(float) * 3);
8454 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8456 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *((DWORD *) (&ptsizemin_orig)));
8457 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
8459 hr = IDirect3DDevice9_EndScene(device);
8460 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%08x\n", hr);
8462 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8463 color = getPixelColor(device, 64-9, 64-9);
8464 ok(color == 0x000000ff, "pSize: Pixel (64-9),(64-9) has color 0x%08x, expected 0x000000ff\n", color);
8465 color = getPixelColor(device, 64-8, 64-8);
8466 todo_wine ok(color == 0x00ffffff, "pSize: Pixel (64-8),(64-8) has color 0x%08x, expected 0x00ffffff\n", color);
8467 color = getPixelColor(device, 64-7, 64-7);
8468 ok(color == 0x00ffffff, "pSize: Pixel (64-7),(64-7) has color 0x%08x, expected 0x00ffffff\n", color);
8469 color = getPixelColor(device, 64+7, 64+7);
8470 ok(color == 0x00ffffff, "pSize: Pixel (64+7),(64+7) has color 0x%08x, expected 0x00ffffff\n", color);
8471 color = getPixelColor(device, 64+8, 64+8);
8472 ok(color == 0x000000ff, "pSize: Pixel (64+8),(64+8) has color 0x%08x, expected 0x000000ff\n", color);
8473 color = getPixelColor(device, 64+9, 64+9);
8474 ok(color == 0x000000ff, "pSize: Pixel (64+9),(64+9) has color 0x%08x, expected 0x000000ff\n", color);
8476 color = getPixelColor(device, 128-17, 64-17);
8477 ok(color == 0x000000ff, "pSize: Pixel (128-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8478 color = getPixelColor(device, 128-16, 64-16);
8479 todo_wine ok(color == 0x00ffffff, "pSize: Pixel (128-16),(64-16) has color 0x%08x, expected 0x00ffffff\n", color);
8480 color = getPixelColor(device, 128-15, 64-15);
8481 ok(color == 0x00ffffff, "pSize: Pixel (128-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8482 color = getPixelColor(device, 128+15, 64+15);
8483 ok(color == 0x00ffffff, "pSize: Pixel (128+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8484 color = getPixelColor(device, 128+16, 64+16);
8485 ok(color == 0x000000ff, "pSize: Pixel (128+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8486 color = getPixelColor(device, 128+17, 64+17);
8487 ok(color == 0x000000ff, "pSize: Pixel (128+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8489 color = getPixelColor(device, 192-17, 64-17);
8490 ok(color == 0x000000ff, "pSize: Pixel (192-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8491 color = getPixelColor(device, 192-16, 64-16);
8492 ok(color == 0x000000ff, "pSize: Pixel (192-16),(64-16) has color 0x%08x, expected 0x000000ff\n", color);
8493 color = getPixelColor(device, 192-15, 64-15);
8494 ok(color == 0x00ffffff, "pSize: Pixel (192-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8495 color = getPixelColor(device, 192+15, 64+15);
8496 ok(color == 0x00ffffff, "pSize: Pixel (192+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8497 color = getPixelColor(device, 192+16, 64+16);
8498 ok(color == 0x000000ff, "pSize: Pixel (192+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8499 color = getPixelColor(device, 192+17, 64+17);
8500 ok(color == 0x000000ff, "pSize: Pixel (192+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8502 if(caps.MaxPointSize >= 64.0) {
8503 color = getPixelColor(device, 256-33, 64-33);
8504 ok(color == 0x000000ff, "pSize: Pixel (256-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8505 color = getPixelColor(device, 256-32, 64-32);
8506 todo_wine ok(color == 0x00ffffff, "pSize: Pixel (256-32),(64-32) has color 0x%08x, expected 0x00ffffff\n", color);
8507 color = getPixelColor(device, 256-31, 64-31);
8508 ok(color == 0x00ffffff, "pSize: Pixel (256-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8509 color = getPixelColor(device, 256+31, 64+31);
8510 ok(color == 0x00ffffff, "pSize: Pixel (256+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8511 color = getPixelColor(device, 256+32, 64+32);
8512 ok(color == 0x000000ff, "pSize: Pixel (256+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8513 color = getPixelColor(device, 256+33, 64+33);
8514 ok(color == 0x000000ff, "pSize: Pixel (256+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8516 color = getPixelColor(device, 384-33, 64-33);
8517 ok(color == 0x000000ff, "pSize: Pixel (384-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8518 color = getPixelColor(device, 384-32, 64-32);
8519 ok(color == 0x000000ff, "pSize: Pixel (384-32),(64-32) has color 0x%08x, expected 0x000000ff\n", color);
8520 color = getPixelColor(device, 384-31, 64-31);
8521 ok(color == 0x00ffffff, "pSize: Pixel (384-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8522 color = getPixelColor(device, 384+31, 64+31);
8523 ok(color == 0x00ffffff, "pSize: Pixel (384+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8524 color = getPixelColor(device, 384+32, 64+32);
8525 ok(color == 0x000000ff, "pSize: Pixel (384+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8526 color = getPixelColor(device, 384+33, 64+33);
8527 ok(color == 0x000000ff, "pSize: Pixel (384+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8530 color = getPixelColor(device, 320-1, 64-1);
8531 ok(color == 0x000000ff, "pSize: Pixel (320-1),(64-1) has color 0x%08x, expected 0x000000ff\n", color);
8532 color = getPixelColor(device, 320-0, 64-0);
8533 ok(color == 0x00ffffff, "pSize: Pixel (320-0),(64-0) has color 0x%08x, expected 0x00ffffff\n", color);
8534 color = getPixelColor(device, 320+1, 64+1);
8535 ok(color == 0x000000ff, "pSize: Pixel (320+1),(64+1) has color 0x%08x, expected 0x000000ff\n", color);
8537 /* ptsize = 16, ptsize_max = 1 --> point has size 1 */
8538 color = getPixelColor(device, 448-4, 64-4);
8539 ok(color == 0x000000ff, "pSize: Pixel (448-4),(64-4) has color 0x%08x, expected 0x00ffffff\n", color);
8540 color = getPixelColor(device, 448+4, 64+4);
8541 ok(color == 0x000000ff, "pSize: Pixel (448+4),(64+4) has color 0x%08x, expected 0x00ffffff\n", color);
8543 /* ptsize = 4, ptsize_max = 1, ptsize_min = 16 --> point has size 1 */
8544 color = getPixelColor(device, 512-4, 64-4);
8545 ok(color == 0x000000ff, "pSize: Pixel (448-4),(64-4) has color 0x%08x, expected 0x00ffffff\n", color);
8546 color = getPixelColor(device, 512+4, 64+4);
8547 ok(color == 0x000000ff, "pSize: Pixel (448+4),(64+4) has color 0x%08x, expected 0x00ffffff\n", color);
8549 /* ptsize = 1, ptsize_max = default(64), ptsize_min = 16 --> point has size 16
8550 * Don't be overly picky - just show that the point is bigger than 1 pixel
8552 color = getPixelColor(device, 576-4, 64-4);
8553 ok(color == 0x00ffffff, "pSize: Pixel (448-4),(64-4) has color 0x%08x, expected 0x00ffffff\n", color);
8554 color = getPixelColor(device, 576+4, 64+4);
8555 ok(color == 0x00ffffff, "pSize: Pixel (448+4),(64+4) has color 0x%08x, expected 0x00ffffff\n", color);
8557 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
8558 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
8559 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
8560 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
8563 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
8565 HRESULT hr;
8566 IDirect3DPixelShader9 *ps;
8567 IDirect3DTexture9 *tex1, *tex2;
8568 IDirect3DSurface9 *surf1, *surf2, *backbuf;
8569 D3DCAPS9 caps;
8570 DWORD color;
8571 DWORD shader_code[] = {
8572 0xffff0300, /* ps_3_0 */
8573 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0, 1, 0, 0 */
8574 0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0, 0, 1, 0 */
8575 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
8576 0x02000001, 0x800f0801, 0xa0e40001, /* mov oC1, c1 */
8577 0x0000ffff /* END */
8579 float quad[] = {
8580 -1.0, -1.0, 0.1,
8581 1.0, -1.0, 0.1,
8582 -1.0, 1.0, 0.1,
8583 1.0, 1.0, 0.1,
8585 float texquad[] = {
8586 -1.0, -1.0, 0.1, 0.0, 0.0,
8587 0.0, -1.0, 0.1, 1.0, 0.0,
8588 -1.0, 1.0, 0.1, 0.0, 1.0,
8589 0.0, 1.0, 0.1, 1.0, 1.0,
8591 0.0, -1.0, 0.1, 0.0, 0.0,
8592 1.0, -1.0, 0.1, 1.0, 0.0,
8593 0.0, 1.0, 0.1, 0.0, 1.0,
8594 1.0, 1.0, 0.1, 1.0, 1.0,
8597 memset(&caps, 0, sizeof(caps));
8598 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8599 ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%08x\n", hr);
8600 if(caps.NumSimultaneousRTs < 2) {
8601 skip("Only 1 simultaneous render target supported, skipping MRT test\n");
8602 return;
8605 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
8606 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
8608 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
8609 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8610 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
8611 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
8612 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
8613 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed, hr=%08x\n", hr);
8615 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
8616 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
8617 hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
8618 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8619 hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
8620 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
8622 hr = IDirect3DDevice9_SetPixelShader(device, ps);
8623 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8624 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
8625 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8626 hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
8627 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8628 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8629 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8631 hr = IDirect3DDevice9_BeginScene(device);
8632 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%08x\n", hr);
8633 if(SUCCEEDED(hr)) {
8634 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
8635 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8637 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8638 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
8639 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
8640 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8641 hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
8642 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
8643 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8644 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
8646 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8647 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8648 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
8649 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8651 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
8652 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8653 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
8654 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%08x\n", hr);
8656 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8657 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%08x\n", hr);
8659 hr = IDirect3DDevice9_EndScene(device);
8660 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%08x\n", hr);
8663 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8664 color = getPixelColor(device, 160, 240);
8665 ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
8666 color = getPixelColor(device, 480, 240);
8667 ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
8669 IDirect3DPixelShader9_Release(ps);
8670 IDirect3DTexture9_Release(tex1);
8671 IDirect3DTexture9_Release(tex2);
8672 IDirect3DSurface9_Release(surf1);
8673 IDirect3DSurface9_Release(surf2);
8674 IDirect3DSurface9_Release(backbuf);
8677 struct formats {
8678 const char *fmtName;
8679 D3DFORMAT textureFormat;
8680 DWORD resultColorBlending;
8681 DWORD resultColorNoBlending;
8684 const struct formats test_formats[] = {
8685 { "D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
8686 { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
8687 { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
8688 { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
8689 { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
8690 { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
8691 { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
8692 { NULL, 0 }
8695 static void pixelshader_blending_test(IDirect3DDevice9 *device)
8697 HRESULT hr;
8698 IDirect3DTexture9 *offscreenTexture = NULL;
8699 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
8700 IDirect3D9 *d3d = NULL;
8701 DWORD color;
8702 DWORD r0, g0, b0, r1, g1, b1;
8703 int fmt_index;
8705 static const float quad[][5] = {
8706 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
8707 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
8708 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
8709 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
8712 /* Quad with R=0x10, G=0x20 */
8713 static const struct vertex quad1[] = {
8714 {-1.0f, -1.0f, 0.1f, 0x80102000},
8715 {-1.0f, 1.0f, 0.1f, 0x80102000},
8716 { 1.0f, -1.0f, 0.1f, 0x80102000},
8717 { 1.0f, 1.0f, 0.1f, 0x80102000},
8720 /* Quad with R=0x20, G=0x10 */
8721 static const struct vertex quad2[] = {
8722 {-1.0f, -1.0f, 0.1f, 0x80201000},
8723 {-1.0f, 1.0f, 0.1f, 0x80201000},
8724 { 1.0f, -1.0f, 0.1f, 0x80201000},
8725 { 1.0f, 1.0f, 0.1f, 0x80201000},
8728 IDirect3DDevice9_GetDirect3D(device, &d3d);
8730 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8731 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
8732 if(!backbuffer) {
8733 goto out;
8736 for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
8738 D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
8739 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, fmt) != D3D_OK) {
8740 skip("%s textures not supported\n", test_formats[fmt_index].fmtName);
8741 continue;
8744 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8745 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8747 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
8748 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
8749 if(!offscreenTexture) {
8750 continue;
8753 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
8754 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
8755 if(!offscreen) {
8756 continue;
8759 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8760 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
8762 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8763 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8764 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8765 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8766 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
8767 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
8768 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
8769 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
8770 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8771 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8773 /* Below we will draw two quads with different colors and try to blend them together.
8774 * The result color is compared with the expected outcome.
8776 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
8777 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
8778 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
8779 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
8780 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8782 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
8783 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8785 /* Draw a quad using color 0x0010200 */
8786 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
8787 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8788 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
8789 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8790 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8791 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8793 /* Draw a quad using color 0x0020100 */
8794 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
8795 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8796 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
8797 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8798 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8799 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8801 /* We don't want to blend the result on the backbuffer */
8802 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
8803 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8805 /* Prepare rendering the 'blended' texture quad to the backbuffer */
8806 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8807 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %08x\n", hr);
8808 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
8809 ok(hr == D3D_OK, "SetTexture failed, %08x\n", hr);
8811 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8812 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
8814 /* This time with the texture */
8815 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8816 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %08x\n", hr);
8818 IDirect3DDevice9_EndScene(device);
8820 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8823 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
8824 /* Compare the color of the center quad with our expectation */
8825 color = getPixelColor(device, 320, 240);
8826 r0 = (color & 0x00ff0000) >> 16;
8827 g0 = (color & 0x0000ff00) >> 8;
8828 b0 = (color & 0x000000ff) >> 0;
8830 r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
8831 g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >> 8;
8832 b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >> 0;
8834 ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
8835 g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
8836 b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
8837 "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
8838 } else {
8839 /* No pixel shader blending is supported so expected garbage.The type of 'garbage' depends on the driver version and OS.
8840 * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
8841 * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
8842 color = getPixelColor(device, 320, 240);
8843 ok((color == 0x00ffffff) || (color == test_formats[fmt_index].resultColorNoBlending), "Offscreen failed for %s: expected no color blending but received it anyway.\n", test_formats[fmt_index].fmtName);
8846 IDirect3DDevice9_SetTexture(device, 0, NULL);
8847 if(offscreenTexture) {
8848 IDirect3DTexture9_Release(offscreenTexture);
8850 if(offscreen) {
8851 IDirect3DSurface9_Release(offscreen);
8855 out:
8856 /* restore things */
8857 if(backbuffer) {
8858 IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8859 IDirect3DSurface9_Release(backbuffer);
8863 static void tssargtemp_test(IDirect3DDevice9 *device)
8865 HRESULT hr;
8866 DWORD color;
8867 static const struct vertex quad[] = {
8868 {-1.0, -1.0, 0.1, 0x00ff0000},
8869 { 1.0, -1.0, 0.1, 0x00ff0000},
8870 {-1.0, 1.0, 0.1, 0x00ff0000},
8871 { 1.0, 1.0, 0.1, 0x00ff0000}
8873 D3DCAPS9 caps;
8875 memset(&caps, 0, sizeof(caps));
8876 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8877 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
8878 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
8879 skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
8880 return;
8883 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
8884 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
8886 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8887 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8888 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
8889 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8891 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8892 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8893 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
8894 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8895 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
8896 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8898 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
8899 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8900 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
8901 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8902 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
8903 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8905 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
8906 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8908 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
8909 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8910 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8911 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
8913 hr = IDirect3DDevice9_BeginScene(device);
8914 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %08x\n", hr);
8915 if(SUCCEEDED(hr)) {
8917 hr = IDirect3DDevice9_EndScene(device);
8918 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %08x\n", hr);
8919 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8920 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %08x\n", hr);
8922 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8923 color = getPixelColor(device, 320, 240);
8924 ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
8926 /* Set stage 1 back to default */
8927 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
8928 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8929 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
8930 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8931 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8932 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8933 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
8934 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8935 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
8936 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8939 struct testdata
8941 DWORD idxVertex; /* number of instances in the first stream */
8942 DWORD idxColor; /* number of instances in the second stream */
8943 DWORD idxInstance; /* should be 1 ?? */
8944 DWORD color1; /* color 1 instance */
8945 DWORD color2; /* color 2 instance */
8946 DWORD color3; /* color 3 instance */
8947 DWORD color4; /* color 4 instance */
8948 WORD strVertex; /* specify which stream to use 0-2*/
8949 WORD strColor;
8950 WORD strInstance;
8953 static const struct testdata testcases[]=
8955 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 0 */
8956 {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 1 */
8957 {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 2 */
8958 {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 3 */
8959 {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 4 */
8960 {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 5 */
8961 {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 6 */
8962 {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 7 */
8963 {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 8 */
8964 {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 9 */
8965 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 10 */
8966 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 11 */
8967 {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 12 */
8968 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 13 */
8969 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 14 */
8971 This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1)) has to return D3DERR_INVALIDCALL!
8972 {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
8976 /* Drawing Indexed Geometry with instances*/
8977 static void stream_test(IDirect3DDevice9 *device)
8979 IDirect3DVertexBuffer9 *vb = NULL;
8980 IDirect3DVertexBuffer9 *vb2 = NULL;
8981 IDirect3DVertexBuffer9 *vb3 = NULL;
8982 IDirect3DIndexBuffer9 *ib = NULL;
8983 IDirect3DVertexDeclaration9 *pDecl = NULL;
8984 IDirect3DVertexShader9 *shader = NULL;
8985 HRESULT hr;
8986 BYTE *data;
8987 DWORD color;
8988 DWORD ind;
8989 unsigned i;
8991 const DWORD shader_code[] =
8993 0xfffe0101, /* vs_1_1 */
8994 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8995 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
8996 0x0000001f, 0x80000005, 0x900f0002, /* dcl_texcoord v2 */
8997 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
8998 0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
8999 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
9000 0x0000ffff
9003 const float quad[][3] =
9005 {-0.5f, -0.5f, 1.1f}, /*0 */
9006 {-0.5f, 0.5f, 1.1f}, /*1 */
9007 { 0.5f, -0.5f, 1.1f}, /*2 */
9008 { 0.5f, 0.5f, 1.1f}, /*3 */
9011 const float vertcolor[][4] =
9013 {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
9014 {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
9015 {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
9016 {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
9019 /* 4 position for 4 instances */
9020 const float instancepos[][3] =
9022 {-0.6f,-0.6f, 0.0f},
9023 { 0.6f,-0.6f, 0.0f},
9024 { 0.6f, 0.6f, 0.0f},
9025 {-0.6f, 0.6f, 0.0f},
9028 short indices[] = {0, 1, 2, 1, 2, 3};
9030 D3DVERTEXELEMENT9 decl[] =
9032 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9033 {1, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9034 {2, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9035 D3DDECL_END()
9038 /* set the default value because it isn't done in wine? */
9039 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9040 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9042 /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
9043 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
9044 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9046 /* check wrong cases */
9047 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
9048 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9049 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9050 ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9051 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
9052 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9053 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9054 ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9055 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
9056 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9057 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9058 ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9059 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
9060 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9061 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9062 ok(hr == D3D_OK && ind == (0 | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9063 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
9064 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9065 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
9066 ok(hr == D3D_OK && ind == (0 | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
9068 /* set the default value back */
9069 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
9070 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
9072 /* create all VertexBuffers*/
9073 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
9074 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9075 if(!vb) {
9076 skip("Failed to create a vertex buffer\n");
9077 return;
9079 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9080 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9081 if(!vb2) {
9082 skip("Failed to create a vertex buffer\n");
9083 goto out;
9085 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
9086 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9087 if(!vb3) {
9088 skip("Failed to create a vertex buffer\n");
9089 goto out;
9092 /* create IndexBuffer*/
9093 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
9094 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
9095 if(!ib) {
9096 skip("Failed to create a index buffer\n");
9097 goto out;
9100 /* copy all Buffers (Vertex + Index)*/
9101 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
9102 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9103 memcpy(data, quad, sizeof(quad));
9104 hr = IDirect3DVertexBuffer9_Unlock(vb);
9105 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9106 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
9107 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9108 memcpy(data, vertcolor, sizeof(vertcolor));
9109 hr = IDirect3DVertexBuffer9_Unlock(vb2);
9110 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9111 hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
9112 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9113 memcpy(data, instancepos, sizeof(instancepos));
9114 hr = IDirect3DVertexBuffer9_Unlock(vb3);
9115 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
9116 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
9117 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
9118 memcpy(data, indices, sizeof(indices));
9119 hr = IDirect3DIndexBuffer9_Unlock(ib);
9120 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9122 /* create VertexShader */
9123 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9124 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9125 if(!shader) {
9126 skip("Failed to create a vetex shader\n");
9127 goto out;
9130 hr = IDirect3DDevice9_SetVertexShader(device, shader);
9131 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9133 hr = IDirect3DDevice9_SetIndices(device, ib);
9134 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
9136 /* run all tests */
9137 for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
9139 struct testdata act = testcases[i];
9140 decl[0].Stream = act.strVertex;
9141 decl[1].Stream = act.strColor;
9142 decl[2].Stream = act.strInstance;
9143 /* create VertexDeclarations */
9144 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
9145 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
9147 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9148 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
9150 hr = IDirect3DDevice9_BeginScene(device);
9151 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
9152 if(SUCCEEDED(hr))
9154 hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
9155 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
9157 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
9158 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9159 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
9160 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9162 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
9163 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9164 hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
9165 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9167 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
9168 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9169 hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
9170 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x (case %i)\n", hr, i);
9172 /* don't know if this is right (1*3 and 4*1)*/
9173 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 1 * 3 , 0, 4*1);
9174 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
9175 hr = IDirect3DDevice9_EndScene(device);
9176 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
9178 /* set all StreamSource && StreamSourceFreq back to default */
9179 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
9180 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9181 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
9182 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9183 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
9184 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9185 hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
9186 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9187 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
9188 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x (case %i)\n", hr, i);
9189 hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
9190 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
9193 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9194 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
9196 hr = IDirect3DVertexDeclaration9_Release(pDecl);
9197 ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
9199 color = getPixelColor(device, 160, 360);
9200 ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
9201 color = getPixelColor(device, 480, 360);
9202 ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
9203 color = getPixelColor(device, 480, 120);
9204 ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
9205 color = getPixelColor(device, 160, 120);
9206 ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
9209 hr = IDirect3DDevice9_SetIndices(device, NULL);
9210 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
9212 out:
9213 if(vb) IDirect3DVertexBuffer9_Release(vb);
9214 if(vb2)IDirect3DVertexBuffer9_Release(vb2);
9215 if(vb3)IDirect3DVertexBuffer9_Release(vb3);
9216 if(ib)IDirect3DIndexBuffer9_Release(ib);
9217 if(shader)IDirect3DVertexShader9_Release(shader);
9220 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
9221 IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
9222 IDirect3DTexture9 *dsttex = NULL;
9223 HRESULT hr;
9224 DWORD color;
9225 D3DRECT r1 = {0, 0, 50, 50 };
9226 D3DRECT r2 = {50, 0, 100, 50 };
9227 D3DRECT r3 = {50, 50, 100, 100};
9228 D3DRECT r4 = {0, 50, 50, 100};
9229 const float quad[] = {
9230 -1.0, -1.0, 0.1, 0.0, 0.0,
9231 1.0, -1.0, 0.1, 1.0, 0.0,
9232 -1.0, 1.0, 0.1, 0.0, 1.0,
9233 1.0, 1.0, 0.1, 1.0, 1.0,
9236 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9237 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
9239 hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9240 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
9241 hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9242 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
9244 if(!src || !dsttex) {
9245 skip("One or more test resources could not be created\n");
9246 goto cleanup;
9249 hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9250 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
9252 hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9253 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9255 /* Clear the StretchRect destination for debugging */
9256 hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9257 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9258 hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9259 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9261 hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9262 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9264 hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9265 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9266 hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9267 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9268 hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9269 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9270 hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9271 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9273 /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9274 * the target -> texture GL blit path
9276 hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9277 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
9278 IDirect3DSurface9_Release(dst);
9280 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9281 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
9283 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9284 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9285 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9286 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
9287 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9288 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9289 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9290 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9292 hr = IDirect3DDevice9_BeginScene(device);
9293 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
9294 if(SUCCEEDED(hr)) {
9295 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9296 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9297 hr = IDirect3DDevice9_EndScene(device);
9298 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
9301 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9302 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
9303 color = getPixelColor(device, 160, 360);
9304 ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9305 color = getPixelColor(device, 480, 360);
9306 ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9307 color = getPixelColor(device, 480, 120);
9308 ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9309 color = getPixelColor(device, 160, 120);
9310 ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9312 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9313 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9314 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9315 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
9317 cleanup:
9318 if(src) IDirect3DSurface9_Release(src);
9319 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9320 if(dsttex) IDirect3DTexture9_Release(dsttex);
9323 static void texop_test(IDirect3DDevice9 *device)
9325 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
9326 IDirect3DTexture9 *texture = NULL;
9327 D3DLOCKED_RECT locked_rect;
9328 D3DCOLOR color;
9329 D3DCAPS9 caps;
9330 HRESULT hr;
9331 unsigned i;
9333 static const struct {
9334 float x, y, z;
9335 float s, t;
9336 D3DCOLOR diffuse;
9337 } quad[] = {
9338 {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9339 {-1.0f, 1.0f, 0.1f, -1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9340 { 1.0f, -1.0f, 0.1f, 1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
9341 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
9344 static const D3DVERTEXELEMENT9 decl_elements[] = {
9345 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9346 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9347 {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9348 D3DDECL_END()
9351 static const struct {
9352 D3DTEXTUREOP op;
9353 const char *name;
9354 DWORD caps_flag;
9355 D3DCOLOR result;
9356 } test_data[] = {
9357 {D3DTOP_SELECTARG1, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9358 {D3DTOP_SELECTARG2, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
9359 {D3DTOP_MODULATE, "MODULATE", D3DTEXOPCAPS_MODULATE, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
9360 {D3DTOP_MODULATE2X, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
9361 {D3DTOP_MODULATE4X, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9362 {D3DTOP_ADD, "ADD", D3DTEXOPCAPS_ADD, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9363 {D3DTOP_ADDSIGNED, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
9364 {D3DTOP_ADDSIGNED2X, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
9365 {D3DTOP_SUBTRACT, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
9366 {D3DTOP_ADDSMOOTH, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
9367 {D3DTOP_BLENDDIFFUSEALPHA, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9368 {D3DTOP_BLENDTEXTUREALPHA, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
9369 {D3DTOP_BLENDFACTORALPHA, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
9370 {D3DTOP_BLENDTEXTUREALPHAPM, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9371 {D3DTOP_BLENDCURRENTALPHA, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
9372 {D3DTOP_MODULATEALPHA_ADDCOLOR, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
9373 {D3DTOP_MODULATECOLOR_ADDALPHA, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
9374 {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
9375 {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
9376 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
9377 {D3DTOP_DOTPRODUCT3, "DOTPRODUCT2", D3DTEXOPCAPS_DOTPRODUCT3, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
9378 {D3DTOP_MULTIPLYADD, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
9379 {D3DTOP_LERP, "LERP", D3DTEXOPCAPS_LERP, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
9382 memset(&caps, 0, sizeof(caps));
9383 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9384 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9386 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9387 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
9388 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9389 ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
9391 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9392 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9393 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9394 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9395 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
9396 hr = IDirect3DTexture9_UnlockRect(texture, 0);
9397 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9398 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9399 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9401 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
9402 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9403 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9404 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9405 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9406 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9408 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9409 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9411 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9412 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9413 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
9414 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9415 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
9416 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9418 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9419 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9421 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
9423 if (!(caps.TextureOpCaps & test_data[i].caps_flag))
9425 skip("tex operation %s not supported\n", test_data[i].name);
9426 continue;
9429 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
9430 ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
9432 hr = IDirect3DDevice9_BeginScene(device);
9433 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9435 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9436 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9438 hr = IDirect3DDevice9_EndScene(device);
9439 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9441 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9442 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9444 color = getPixelColor(device, 320, 240);
9445 ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
9446 test_data[i].name, color, test_data[i].result);
9449 if (texture) IDirect3DTexture9_Release(texture);
9450 if (vertex_declaration) IDirect3DVertexDeclaration9_Release(vertex_declaration);
9453 static void yuv_color_test(IDirect3DDevice9 *device) {
9454 HRESULT hr;
9455 IDirect3DSurface9 *surface = NULL, *target = NULL;
9456 unsigned int fmt, i;
9457 D3DFORMAT format;
9458 const char *fmt_string;
9459 D3DLOCKED_RECT lr;
9460 IDirect3D9 *d3d;
9461 HRESULT color;
9462 DWORD ref_color_left, ref_color_right;
9464 struct {
9465 DWORD in; /* The input color */
9466 DWORD uyvy_left; /* "in" interpreted as uyvy and transformed to RGB, pixel 1/1*/
9467 DWORD uyvy_right; /* "in" interpreted as uyvy and transformed to RGB, pixel 2/1*/
9468 DWORD yuy2_left; /* "in" interpreted as yuy2 and transformed to RGB, pixel 1/1 */
9469 DWORD yuy2_right; /* "in" interpreted as yuy2 and transformed to RGB, pixel 2/1 */
9470 } test_data[] = {
9471 /* Originally I wanted to avoid being evil, and set Y1 = Y2 to avoid triggering troubles in shader converters,
9472 * but the main difference between YUY2 and UYVY is the swapped ordering of the chroma and luminance
9473 * values. However, handling the two Y's properly could have a big impact on image quality, so be picky about
9474 * that
9476 { 0x00000000, 0x00008700, 0x00008700, 0x00008700, 0x00008700 },
9477 { 0xff000000, 0x00008700, 0x004bff1c, 0x00b30000, 0x00b30000 },
9478 { 0x00ff0000, 0x00b30000, 0x00b30000, 0x00008700, 0x004bff1c },
9479 { 0x0000ff00, 0x004bff1c, 0x00008700, 0x000030e1, 0x000030e1 },
9480 { 0x000000ff, 0x000030e1, 0x000030e1, 0x004bff1c, 0x00008700 },
9481 { 0xffff0000, 0x00b30000, 0x00ffd01c, 0x00b30000, 0x00ffd01c },
9482 { 0xff00ff00, 0x004bff1c, 0x004bff1c, 0x00b300e1, 0x00b300e1 },
9483 { 0xff0000ff, 0x000030e1, 0x004bffff, 0x00ffd01c, 0x00b30000 },
9484 { 0x00ffff00, 0x00ffd01c, 0x00b30000, 0x000030e1, 0x004bffff },
9485 { 0x00ff00ff, 0x00b300e1, 0x00b300e1, 0x004bff1c, 0x004bff1c },
9486 { 0x0000ffff, 0x004bffff, 0x000030e1, 0x004bffff, 0x000030e1 },
9487 { 0xffffff00, 0x00ffd01c, 0x00ffd01c, 0x00b300e1, 0x00ff79ff },
9488 { 0xffff00ff, 0x00b300e1, 0x00ff79ff, 0x00ffd01c, 0x00ffd01c },
9489 { 0xffffffff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff, 0x00ff79ff },
9491 { 0x4cff4c54, 0x00ff0000, 0x00ff0000, 0x000b8b00, 0x00b6ffa3 },
9492 { 0x00800080, 0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00 },
9493 { 0xFF80FF80, 0x00ffffff, 0x00ffffff, 0x00ff00ff, 0x00ff00ff },
9494 { 0x1c6b1cff, 0x000000fd, 0x000000fd, 0x006dff45, 0x0000d500 },
9497 hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
9498 ok(hr == D3D_OK, "IDirect3DDevice9_GetDirect3D failed, hr = %08x\n", hr);
9499 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
9500 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %08x\n", hr);
9502 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX0);
9503 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
9505 for(fmt = 0; fmt < 2; fmt++) {
9506 if(fmt == 0) {
9507 format = D3DFMT_UYVY;
9508 fmt_string = "D3DFMT_UYVY";
9509 } else {
9510 format = D3DFMT_YUY2;
9511 fmt_string = "D3DFMT_YUY2";
9514 /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect. Thus use
9515 * StretchRect to draw the YUV surface onto the screen instead of drawPrimitive
9517 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
9518 D3DRTYPE_SURFACE, format) != D3D_OK) {
9519 skip("%s is not supported\n", fmt_string);
9520 continue;
9523 /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1 */
9524 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 2, 1, format, D3DPOOL_DEFAULT, &surface, NULL);
9525 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %08x\n", hr);
9527 for(i = 0; i < (sizeof(test_data)/sizeof(test_data[0])); i++) {
9528 if(fmt == 0) {
9529 ref_color_left = test_data[i].uyvy_left;
9530 ref_color_right = test_data[i].uyvy_right;
9531 } else {
9532 ref_color_left = test_data[i].yuy2_left;
9533 ref_color_right = test_data[i].yuy2_right;
9536 memset(&lr, 0, sizeof(lr));
9537 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
9538 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %08x\n", hr);
9539 *((DWORD *) lr.pBits) = test_data[i].in;
9540 hr = IDirect3DSurface9_UnlockRect(surface);
9541 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %08x\n", hr);
9543 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9544 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9545 hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
9546 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with 0x%08x\n", hr);
9547 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9548 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9550 /* Native D3D can't resist filtering the YUY surface, even though we asked it not to do so above. To
9551 * prevent running into precision problems, read a far left and far right pixel. In the future we may
9552 * want to add tests for the filtered pixels as well.
9554 * Unfortunately different implementations(Windows-NV and Mac-ATI tested) interpret some colors vastly
9555 * differently, so we need a max diff of 16
9557 color = getPixelColor(device, 40, 240);
9558 ok(color_match(color, ref_color_left, 16),
9559 "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s\n",
9560 test_data[i].in, color, ref_color_left, fmt_string);
9561 color = getPixelColor(device, 600, 240);
9562 ok(color_match(color, ref_color_right, 16),
9563 "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s\n",
9564 test_data[i].in, color, ref_color_left, fmt_string);
9566 IDirect3DSurface9_Release(surface);
9568 IDirect3DSurface9_Release(target);
9569 IDirect3D9_Release(d3d);
9572 static void texop_range_test(IDirect3DDevice9 *device)
9574 static const struct {
9575 float x, y, z;
9576 D3DCOLOR diffuse;
9577 } quad[] = {
9578 {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9579 {-1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9580 { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
9581 { 1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
9583 HRESULT hr;
9584 IDirect3DTexture9 *texture;
9585 D3DLOCKED_RECT locked_rect;
9586 D3DCAPS9 caps;
9587 DWORD color;
9589 /* We need ADD and SUBTRACT operations */
9590 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9591 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9592 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD)) {
9593 skip("D3DTOP_ADD is not supported, skipping value range test\n");
9595 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT)) {
9596 skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test\n");
9599 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9600 ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
9601 /* Stage 1: result = diffuse(=1.0) + diffuse
9602 * stage 2: result = result - tfactor(= 0.5)
9604 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9605 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9606 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9607 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9608 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9609 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9610 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
9611 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9612 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9613 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9614 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9615 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9616 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9617 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9619 hr = IDirect3DDevice9_BeginScene(device);
9620 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9621 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9622 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9623 hr = IDirect3DDevice9_EndScene(device);
9624 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9625 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9626 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9628 color = getPixelColor(device, 320, 240);
9629 ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
9630 color);
9632 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9633 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
9634 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
9635 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9636 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
9637 hr = IDirect3DTexture9_UnlockRect(texture, 0);
9638 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9639 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
9640 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9642 /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
9643 * stage 2: result = result + diffuse(1.0)
9645 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
9646 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
9647 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9648 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9649 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9650 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9651 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
9652 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9653 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
9654 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9655 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
9656 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9657 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
9658 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9660 hr = IDirect3DDevice9_BeginScene(device);
9661 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
9662 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9663 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9664 hr = IDirect3DDevice9_EndScene(device);
9665 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
9666 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9667 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9669 color = getPixelColor(device, 320, 240);
9670 ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
9671 color);
9673 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9674 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9675 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9676 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
9677 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
9678 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
9679 IDirect3DTexture9_Release(texture);
9682 static void alphareplicate_test(IDirect3DDevice9 *device) {
9683 struct vertex quad[] = {
9684 { -1.0, -1.0, 0.1, 0x80ff00ff },
9685 { 1.0, -1.0, 0.1, 0x80ff00ff },
9686 { -1.0, 1.0, 0.1, 0x80ff00ff },
9687 { 1.0, 1.0, 0.1, 0x80ff00ff },
9689 HRESULT hr;
9690 DWORD color;
9692 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9693 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9695 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9696 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9698 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9699 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9700 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
9701 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9703 hr = IDirect3DDevice9_BeginScene(device);
9704 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9705 if(SUCCEEDED(hr)) {
9706 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9707 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9708 hr = IDirect3DDevice9_EndScene(device);
9709 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9712 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9713 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
9715 color = getPixelColor(device, 320, 240);
9716 ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
9717 color);
9719 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9720 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9724 static void dp3_alpha_test(IDirect3DDevice9 *device) {
9725 HRESULT hr;
9726 D3DCAPS9 caps;
9727 DWORD color;
9728 struct vertex quad[] = {
9729 { -1.0, -1.0, 0.1, 0x408080c0 },
9730 { 1.0, -1.0, 0.1, 0x408080c0 },
9731 { -1.0, 1.0, 0.1, 0x408080c0 },
9732 { 1.0, 1.0, 0.1, 0x408080c0 },
9735 memset(&caps, 0, sizeof(caps));
9736 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9737 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
9738 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3)) {
9739 skip("D3DTOP_DOTPRODUCT3 not supported\n");
9740 return;
9743 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9744 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9746 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9747 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9749 /* dp3_x4 r0, diffuse_bias, tfactor_bias
9750 * mov r0.a, diffuse.a
9751 * mov r0, r0.a
9753 * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
9754 * 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
9755 * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
9757 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
9758 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9759 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9760 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9761 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
9762 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9763 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
9764 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9765 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
9766 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9767 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9768 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9769 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
9770 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9771 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
9772 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9773 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
9774 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9776 hr = IDirect3DDevice9_BeginScene(device);
9777 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9778 if(SUCCEEDED(hr)) {
9779 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9780 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9781 hr = IDirect3DDevice9_EndScene(device);
9782 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9785 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9786 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
9788 color = getPixelColor(device, 320, 240);
9789 ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
9790 color);
9792 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9793 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9794 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
9795 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9796 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
9797 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
9800 static void zwriteenable_test(IDirect3DDevice9 *device) {
9801 HRESULT hr;
9802 DWORD color;
9803 struct vertex quad1[] = {
9804 { -1.0, -1.0, 0.1, 0x00ff0000},
9805 { -1.0, 1.0, 0.1, 0x00ff0000},
9806 { 1.0, -1.0, 0.1, 0x00ff0000},
9807 { 1.0, 1.0, 0.1, 0x00ff0000},
9809 struct vertex quad2[] = {
9810 { -1.0, -1.0, 0.9, 0x0000ff00},
9811 { -1.0, 1.0, 0.9, 0x0000ff00},
9812 { 1.0, -1.0, 0.9, 0x0000ff00},
9813 { 1.0, 1.0, 0.9, 0x0000ff00},
9816 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
9817 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
9819 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9820 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
9821 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
9822 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9823 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
9824 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9825 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
9826 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9828 hr = IDirect3DDevice9_BeginScene(device);
9829 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9830 if(SUCCEEDED(hr)) {
9831 /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1, zenable = D3DZB_FALSE, zwriteenable = TRUE.
9832 * The red color is written because the z test is disabled. The question is whether the z = 0.1 values
9833 * are written into the Z buffer. After the draw, set zenable = TRUE and draw a green quad at z = 0.9.
9834 * If the values are written, the z test will fail(0.9 > 0.1) and the red color remains. If the values
9835 * are not written, the z test succeeds(0.9 < 1.0) and the green color is written. It turns out that
9836 * the screen is green, so zenable = D3DZB_FALSE and zwriteenable = TRUE does NOT write to the z buffer.
9838 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
9839 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9840 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
9841 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9842 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
9843 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
9845 hr = IDirect3DDevice9_EndScene(device);
9846 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with 0x%08x\n", hr);
9849 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9850 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
9851 color = getPixelColor(device, 320, 240);
9852 ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
9853 color);
9855 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
9856 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
9859 START_TEST(visual)
9861 IDirect3DDevice9 *device_ptr;
9862 D3DCAPS9 caps;
9863 HRESULT hr;
9864 DWORD color;
9866 d3d9_handle = LoadLibraryA("d3d9.dll");
9867 if (!d3d9_handle)
9869 skip("Could not load d3d9.dll\n");
9870 return;
9873 device_ptr = init_d3d9();
9874 if (!device_ptr)
9876 skip("Creating the device failed\n");
9877 return;
9880 IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
9882 /* Check for the reliability of the returned data */
9883 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9884 if(FAILED(hr))
9886 skip("Clear failed, can't assure correctness of the test results, skipping\n");
9887 goto cleanup;
9889 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
9891 color = getPixelColor(device_ptr, 1, 1);
9892 if(color !=0x00ff0000)
9894 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
9895 goto cleanup;
9898 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
9899 if(FAILED(hr))
9901 skip("Clear failed, can't assure correctness of the test results, skipping\n");
9902 goto cleanup;
9904 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
9906 color = getPixelColor(device_ptr, 639, 479);
9907 if(color != 0x0000ddee)
9909 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
9910 goto cleanup;
9913 /* Now execute the real tests */
9914 stretchrect_test(device_ptr);
9915 lighting_test(device_ptr);
9916 clear_test(device_ptr);
9917 fog_test(device_ptr);
9918 if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
9920 test_cube_wrap(device_ptr);
9921 } else {
9922 skip("No cube texture support\n");
9924 z_range_test(device_ptr);
9925 if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
9927 maxmip_test(device_ptr);
9929 else
9931 skip("No mipmap support\n");
9933 offscreen_test(device_ptr);
9934 alpha_test(device_ptr);
9935 shademode_test(device_ptr);
9936 srgbtexture_test(device_ptr);
9937 release_buffer_test(device_ptr);
9938 float_texture_test(device_ptr);
9939 g16r16_texture_test(device_ptr);
9940 pixelshader_blending_test(device_ptr);
9941 texture_transform_flags_test(device_ptr);
9942 autogen_mipmap_test(device_ptr);
9943 fixed_function_decl_test(device_ptr);
9944 conditional_np2_repeat_test(device_ptr);
9945 fixed_function_bumpmap_test(device_ptr);
9946 if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
9947 stencil_cull_test(device_ptr);
9948 } else {
9949 skip("No two sided stencil support\n");
9951 pointsize_test(device_ptr);
9952 tssargtemp_test(device_ptr);
9953 np2_stretch_rect_test(device_ptr);
9954 yuv_color_test(device_ptr);
9955 zwriteenable_test(device_ptr);
9957 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
9959 test_constant_clamp_vs(device_ptr);
9960 test_compare_instructions(device_ptr);
9962 else skip("No vs_1_1 support\n");
9964 if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
9966 test_mova(device_ptr);
9967 if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
9968 test_vshader_input(device_ptr);
9969 test_vshader_float16(device_ptr);
9970 stream_test(device_ptr);
9971 } else {
9972 skip("No vs_3_0 support\n");
9975 else skip("No vs_2_0 support\n");
9977 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
9979 fog_with_shader_test(device_ptr);
9980 fog_srgbwrite_test(device_ptr);
9982 else skip("No vs_1_1 and ps_1_1 support\n");
9984 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
9986 texbem_test(device_ptr);
9987 texdepth_test(device_ptr);
9988 texkill_test(device_ptr);
9989 x8l8v8u8_test(device_ptr);
9990 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
9991 constant_clamp_ps_test(device_ptr);
9992 cnd_test(device_ptr);
9993 if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
9994 dp2add_ps_test(device_ptr);
9995 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) {
9996 nested_loop_test(device_ptr);
9997 fixed_function_varying_test(device_ptr);
9998 vFace_register_test(device_ptr);
9999 vpos_register_test(device_ptr);
10000 multiple_rendertargets_test(device_ptr);
10001 if(caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
10002 vshader_version_varying_test(device_ptr);
10003 pshader_version_varying_test(device_ptr);
10004 } else {
10005 skip("No vs_3_0 support\n");
10007 } else {
10008 skip("No ps_3_0 support\n");
10010 } else {
10011 skip("No ps_2_0 support\n");
10015 else skip("No ps_1_1 support\n");
10017 texop_test(device_ptr);
10018 texop_range_test(device_ptr);
10019 alphareplicate_test(device_ptr);
10020 dp3_alpha_test(device_ptr);
10022 cleanup:
10023 if(device_ptr) {
10024 ULONG ref;
10026 D3DPRESENT_PARAMETERS present_parameters;
10027 IDirect3DSwapChain9 *swapchain;
10028 IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
10029 IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
10030 IDirect3DSwapChain9_Release(swapchain);
10031 ref = IDirect3DDevice9_Release(device_ptr);
10032 DestroyWindow(present_parameters.hDeviceWindow);
10033 ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);