d3d9/tests: Add missing skip().
[wine.git] / dlls / d3d9 / tests / visual.c
blob2add48e63dda852490ac0e779d4816c2c81ddab2
1 /*
2 * Copyright 2005, 2007 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 <dxerr9.h>
34 #include "wine/test.h"
36 static HMODULE d3d9_handle = 0;
38 static HWND create_window(void)
40 WNDCLASS wc = {0};
41 HWND ret;
42 wc.lpfnWndProc = &DefWindowProc;
43 wc.lpszClassName = "d3d9_test_wc";
44 RegisterClass(&wc);
46 ret = CreateWindow("d3d9_test_wc", "d3d9_test",
47 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
48 return ret;
51 /* Locks a given surface and returns the color at (x,y). It's the caller's
52 * responsibility to only pass in lockable surfaces and valid x,y coordinates */
53 static DWORD getPixelColorFromSurface(IDirect3DSurface9 *surface, UINT x, UINT y)
55 DWORD color;
56 HRESULT hr;
57 D3DSURFACE_DESC desc;
58 RECT rectToLock = {x, y, x+1, y+1};
59 D3DLOCKED_RECT lockedRect;
61 hr = IDirect3DSurface9_GetDesc(surface, &desc);
62 if(FAILED(hr)) /* This is not a test */
64 trace("Can't get the surface description, hr=%s\n", DXGetErrorString9(hr));
65 return 0xdeadbeef;
68 hr = IDirect3DSurface9_LockRect(surface, &lockedRect, &rectToLock, D3DLOCK_READONLY);
69 if(FAILED(hr)) /* This is not a test */
71 trace("Can't lock the surface, hr=%s\n", DXGetErrorString9(hr));
72 return 0xdeadbeef;
74 switch(desc.Format) {
75 case D3DFMT_A8R8G8B8:
77 color = ((DWORD *) lockedRect.pBits)[0] & 0xffffffff;
78 break;
80 default:
81 trace("Error: unknown surface format: %d\n", desc.Format);
82 color = 0xdeadbeef;
83 break;
85 hr = IDirect3DSurface9_UnlockRect(surface);
86 if(FAILED(hr))
88 trace("Can't unlock the surface, hr=%s\n", DXGetErrorString9(hr));
90 return color;
93 static DWORD getPixelColor(IDirect3DDevice9 *device, UINT x, UINT y)
95 DWORD ret;
96 IDirect3DSurface9 *surf;
97 HRESULT hr;
98 D3DLOCKED_RECT lockedRect;
99 RECT rectToLock = {x, y, x+1, y+1};
101 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 640, 480, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf, NULL);
102 if(FAILED(hr) || !surf ) /* This is not a test */
104 trace("Can't create an offscreen plain surface to read the render target data, hr=%s\n", DXGetErrorString9(hr));
105 return 0xdeadbeef;
108 hr = IDirect3DDevice9_GetFrontBufferData(device, 0, surf);
109 if(FAILED(hr))
111 trace("Can't read the front buffer data, hr=%s\n", DXGetErrorString9(hr));
112 ret = 0xdeadbeed;
113 goto out;
116 hr = IDirect3DSurface9_LockRect(surf, &lockedRect, &rectToLock, D3DLOCK_READONLY);
117 if(FAILED(hr))
119 trace("Can't lock the offscreen surface, hr=%s\n", DXGetErrorString9(hr));
120 ret = 0xdeadbeec;
121 goto out;
124 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
125 * really important for these tests
127 ret = ((DWORD *) lockedRect.pBits)[0] & 0x00ffffff;
128 hr = IDirect3DSurface9_UnlockRect(surf);
129 if(FAILED(hr))
131 trace("Can't unlock the offscreen surface, hr=%s\n", DXGetErrorString9(hr));
134 out:
135 if(surf) IDirect3DSurface9_Release(surf);
136 return ret;
139 static IDirect3DDevice9 *init_d3d9(void)
141 IDirect3D9 * (__stdcall * d3d9_create)(UINT SDKVersion) = 0;
142 IDirect3D9 *d3d9_ptr = 0;
143 IDirect3DDevice9 *device_ptr = 0;
144 D3DPRESENT_PARAMETERS present_parameters;
145 HRESULT hr;
146 D3DADAPTER_IDENTIFIER9 identifier;
148 d3d9_create = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9");
149 ok(d3d9_create != NULL, "Failed to get address of Direct3DCreate9\n");
150 if (!d3d9_create) return NULL;
152 d3d9_ptr = d3d9_create(D3D_SDK_VERSION);
153 ok(d3d9_ptr != NULL, "Failed to create IDirect3D9 object\n");
154 if (!d3d9_ptr) return NULL;
156 ZeroMemory(&present_parameters, sizeof(present_parameters));
157 present_parameters.Windowed = FALSE;
158 present_parameters.hDeviceWindow = create_window();
159 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
160 present_parameters.BackBufferWidth = 640;
161 present_parameters.BackBufferHeight = 480;
162 present_parameters.BackBufferFormat = D3DFMT_X8R8G8B8;
163 present_parameters.EnableAutoDepthStencil = TRUE;
164 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
166 memset(&identifier, 0, sizeof(identifier));
167 hr = IDirect3D9_GetAdapterIdentifier(d3d9_ptr, 0, 0, &identifier);
168 ok(hr == D3D_OK, "Failed to get adapter identifier description\n");
169 trace("Driver string: \"%s\"\n", identifier.Driver);
170 trace("Description string: \"%s\"\n", identifier.Description);
171 trace("Device name string: \"%s\"\n", identifier.DeviceName);
172 trace("Driver version %d.%d.%d.%d\n",
173 HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
174 HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
176 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
177 if(FAILED(hr)) {
178 present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
179 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
180 if(FAILED(hr)) {
181 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
184 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D_CreateDevice returned: %s\n", DXGetErrorString9(hr));
186 return device_ptr;
189 struct vertex
191 float x, y, z;
192 DWORD diffuse;
195 struct tvertex
197 float x, y, z, rhw;
198 DWORD diffuse;
201 struct nvertex
203 float x, y, z;
204 float nx, ny, nz;
205 DWORD diffuse;
208 static void lighting_test(IDirect3DDevice9 *device)
210 HRESULT hr;
211 DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
212 DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
213 DWORD color;
215 float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
216 0.0f, 1.0f, 0.0f, 0.0f,
217 0.0f, 0.0f, 1.0f, 0.0f,
218 0.0f, 0.0f, 0.0f, 1.0f };
220 struct vertex unlitquad[] =
222 {-1.0f, -1.0f, 0.1f, 0xffff0000},
223 {-1.0f, 0.0f, 0.1f, 0xffff0000},
224 { 0.0f, 0.0f, 0.1f, 0xffff0000},
225 { 0.0f, -1.0f, 0.1f, 0xffff0000},
227 struct vertex litquad[] =
229 {-1.0f, 0.0f, 0.1f, 0xff00ff00},
230 {-1.0f, 1.0f, 0.1f, 0xff00ff00},
231 { 0.0f, 1.0f, 0.1f, 0xff00ff00},
232 { 0.0f, 0.0f, 0.1f, 0xff00ff00},
234 struct nvertex unlitnquad[] =
236 { 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
237 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
238 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
239 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
241 struct nvertex litnquad[] =
243 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
244 { 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
245 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
246 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
248 WORD Indices[] = {0, 1, 2, 2, 3, 0};
250 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
251 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
253 /* Setup some states that may cause issues */
254 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
255 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %s\n", DXGetErrorString9(hr));
256 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
257 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %s\n", DXGetErrorString9(hr));
258 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
259 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %s\n", DXGetErrorString9(hr));
260 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
261 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
262 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
263 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
264 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
265 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
266 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
267 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
268 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
269 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
270 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
271 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
272 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
273 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
274 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
275 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %s\n", DXGetErrorString9(hr));
276 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
277 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %s\n", DXGetErrorString9(hr));
279 hr = IDirect3DDevice9_SetFVF(device, fvf);
280 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
282 hr = IDirect3DDevice9_BeginScene(device);
283 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
284 if(hr == D3D_OK)
286 /* No lights are defined... That means, lit vertices should be entirely black */
287 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
288 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
289 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
290 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
291 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
293 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
294 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
295 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
296 2 /*PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
297 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
299 hr = IDirect3DDevice9_SetFVF(device, nfvf);
300 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
302 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
303 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
304 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
305 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
306 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
308 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
309 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
310 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
311 2 /*PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
312 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
314 IDirect3DDevice9_EndScene(device);
315 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
318 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
320 color = getPixelColor(device, 160, 360); /* lower left quad - unlit without normals */
321 ok(color == 0x00ff0000, "Unlit quad without normals has color %08x\n", color);
322 color = getPixelColor(device, 160, 120); /* upper left quad - lit without normals */
323 ok(color == 0x00000000, "Lit quad without normals has color %08x\n", color);
324 color = getPixelColor(device, 480, 360); /* lower left quad - unlit with normals */
325 ok(color == 0x000000ff, "Unlit quad with normals has color %08x\n", color);
326 color = getPixelColor(device, 480, 120); /* upper left quad - lit with normals */
327 ok(color == 0x00000000, "Lit quad with normals has color %08x\n", color);
329 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
330 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
333 static void clear_test(IDirect3DDevice9 *device)
335 /* Tests the correctness of clearing parameters */
336 HRESULT hr;
337 D3DRECT rect[2];
338 D3DRECT rect_negneg;
339 DWORD color;
340 D3DVIEWPORT9 old_vp, vp;
341 RECT scissor;
342 DWORD oldColorWrite;
343 BOOL invalid_clear_failed = FALSE;
345 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
346 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
348 /* Positive x, negative y */
349 rect[0].x1 = 0;
350 rect[0].y1 = 480;
351 rect[0].x2 = 320;
352 rect[0].y2 = 240;
354 /* Positive x, positive y */
355 rect[1].x1 = 0;
356 rect[1].y1 = 0;
357 rect[1].x2 = 320;
358 rect[1].y2 = 240;
359 /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
360 * returns D3D_OK, but ignores the rectangle silently
362 hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
363 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
364 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
366 /* negative x, negative y */
367 rect_negneg.x1 = 640;
368 rect_negneg.y1 = 240;
369 rect_negneg.x2 = 320;
370 rect_negneg.y2 = 0;
371 hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
372 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
373 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
375 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
377 color = getPixelColor(device, 160, 360); /* lower left quad */
378 ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
379 color = getPixelColor(device, 160, 120); /* upper left quad */
380 if(invalid_clear_failed) {
381 /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
382 ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
383 } else {
384 /* If the negative rectangle was dropped silently, the correct ones are cleared */
385 ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
387 color = getPixelColor(device, 480, 360); /* lower right quad */
388 ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
389 color = getPixelColor(device, 480, 120); /* upper right quad */
390 ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
392 /* Test how the viewport affects clears */
393 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
394 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
395 hr = IDirect3DDevice9_GetViewport(device, &old_vp);
396 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %s\n", DXGetErrorString9(hr));
398 vp.X = 160;
399 vp.Y = 120;
400 vp.Width = 160;
401 vp.Height = 120;
402 vp.MinZ = 0.0;
403 vp.MaxZ = 1.0;
404 hr = IDirect3DDevice9_SetViewport(device, &vp);
405 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %s\n", DXGetErrorString9(hr));
406 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
407 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
409 vp.X = 320;
410 vp.Y = 240;
411 vp.Width = 320;
412 vp.Height = 240;
413 vp.MinZ = 0.0;
414 vp.MaxZ = 1.0;
415 hr = IDirect3DDevice9_SetViewport(device, &vp);
416 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %s\n", DXGetErrorString9(hr));
417 rect[0].x1 = 160;
418 rect[0].y1 = 120;
419 rect[0].x2 = 480;
420 rect[0].y2 = 360;
421 hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
422 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
424 hr = IDirect3DDevice9_SetViewport(device, &old_vp);
425 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %s\n", DXGetErrorString9(hr));
427 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
428 color = getPixelColor(device, 158, 118);
429 ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
430 color = getPixelColor(device, 162, 118);
431 ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
432 color = getPixelColor(device, 158, 122);
433 ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
434 color = getPixelColor(device, 162, 122);
435 ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
437 color = getPixelColor(device, 318, 238);
438 ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
439 color = getPixelColor(device, 322, 238);
440 ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
441 color = getPixelColor(device, 318, 242);
442 ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
443 color = getPixelColor(device, 322, 242);
444 ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
446 color = getPixelColor(device, 478, 358);
447 ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
448 color = getPixelColor(device, 482, 358);
449 ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
450 color = getPixelColor(device, 478, 362);
451 ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
452 color = getPixelColor(device, 482, 362);
453 ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
455 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
456 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
458 scissor.left = 160;
459 scissor.right = 480;
460 scissor.top = 120;
461 scissor.bottom = 360;
462 hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
463 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %s\n", DXGetErrorString9(hr));
464 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
465 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %s\n", DXGetErrorString9(hr));
467 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
468 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
469 hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
470 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
472 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
473 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %s\n", DXGetErrorString9(hr));
475 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
476 color = getPixelColor(device, 158, 118);
477 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
478 color = getPixelColor(device, 162, 118);
479 ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
480 color = getPixelColor(device, 158, 122);
481 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
482 color = getPixelColor(device, 162, 122);
483 ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
485 color = getPixelColor(device, 158, 358);
486 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
487 color = getPixelColor(device, 162, 358);
488 ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
489 color = getPixelColor(device, 158, 358);
490 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
491 color = getPixelColor(device, 162, 362);
492 ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
494 color = getPixelColor(device, 478, 118);
495 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
496 color = getPixelColor(device, 478, 122);
497 ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
498 color = getPixelColor(device, 482, 122);
499 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
500 color = getPixelColor(device, 482, 358);
501 ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
503 color = getPixelColor(device, 478, 358);
504 ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
505 color = getPixelColor(device, 478, 362);
506 ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
507 color = getPixelColor(device, 482, 358);
508 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
509 color = getPixelColor(device, 482, 362);
510 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
512 color = getPixelColor(device, 318, 238);
513 ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
514 color = getPixelColor(device, 318, 242);
515 ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
516 color = getPixelColor(device, 322, 238);
517 ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
518 color = getPixelColor(device, 322, 242);
519 ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
521 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
522 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %s\n", DXGetErrorString9(hr));
523 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
524 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %s\n", DXGetErrorString9(hr));
526 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
527 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
529 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
530 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %s\n", DXGetErrorString9(hr));
532 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
534 /* Colorwriteenable does not affect the clear */
535 color = getPixelColor(device, 320, 240);
536 ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
539 typedef struct {
540 float in[4];
541 DWORD out;
542 } test_data_t;
545 * c7 mova ARGB mov ARGB
546 * -2.4 -2 0x00ffff00 -3 0x00ff0000
547 * -1.6 -2 0x00ffff00 -2 0x00ffff00
548 * -0.4 0 0x0000ffff -1 0x0000ff00
549 * 0.4 0 0x0000ffff 0 0x0000ffff
550 * 1.6 2 0x00ff00ff 1 0x000000ff
551 * 2.4 2 0x00ff00ff 2 0x00ff00ff
553 static void test_mova(IDirect3DDevice9 *device)
555 static const DWORD mova_test[] = {
556 0xfffe0200, /* vs_2_0 */
557 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
558 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
559 0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
560 0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
561 0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
562 0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
563 0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
564 0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
565 0x0200002e, 0xb0010000, 0xa0000007, /* mova a0.x, c7.x */
566 0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000, /* mov oD0, c[a0.x + 3] */
567 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
568 0x0000ffff /* END */
570 static const DWORD mov_test[] = {
571 0xfffe0101, /* vs_1_1 */
572 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
573 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
574 0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
575 0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
576 0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
577 0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
578 0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
579 0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
580 0x00000001, 0xb0010000, 0xa0000007, /* mov a0.x, c7.x */
581 0x00000001, 0xd00f0000, 0xa0e42003, /* mov oD0, c[a0.x + 3] */
582 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
583 0x0000ffff /* END */
586 static const test_data_t test_data[2][6] = {
588 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
589 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
590 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
591 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
592 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
593 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
596 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
597 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
598 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
599 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
600 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
601 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
605 static const float quad[][3] = {
606 {-1.0f, -1.0f, 0.0f},
607 {-1.0f, 1.0f, 0.0f},
608 { 1.0f, -1.0f, 0.0f},
609 { 1.0f, 1.0f, 0.0f},
612 static const D3DVERTEXELEMENT9 decl_elements[] = {
613 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
614 D3DDECL_END()
617 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
618 IDirect3DVertexShader9 *mova_shader = NULL;
619 IDirect3DVertexShader9 *mov_shader = NULL;
620 HRESULT hr;
621 UINT i, j;
623 hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
624 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
625 hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
626 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
627 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
628 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
629 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
630 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
632 hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
633 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
634 for(j = 0; j < 2; ++j)
636 for (i = 0; i < (sizeof(test_data[0]) / sizeof(test_data_t)); ++i)
638 DWORD color;
640 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
641 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
643 hr = IDirect3DDevice9_BeginScene(device);
644 ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
646 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
647 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
649 hr = IDirect3DDevice9_EndScene(device);
650 ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
652 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
653 ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
655 color = getPixelColor(device, 320, 240);
656 ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
657 test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
659 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
660 ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
662 hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
663 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
666 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
667 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
669 IDirect3DVertexDeclaration9_Release(vertex_declaration);
670 IDirect3DVertexShader9_Release(mova_shader);
671 IDirect3DVertexShader9_Release(mov_shader);
674 struct sVertex {
675 float x, y, z;
676 DWORD diffuse;
677 DWORD specular;
680 struct sVertexT {
681 float x, y, z, rhw;
682 DWORD diffuse;
683 DWORD specular;
686 static void fog_test(IDirect3DDevice9 *device)
688 HRESULT hr;
689 DWORD color;
690 BYTE r, g, b;
691 float start = 0.0f, end = 1.0f;
692 D3DCAPS9 caps;
693 int i;
695 /* Gets full z based fog with linear fog, no fog with specular color */
696 struct sVertex unstransformed_1[] = {
697 {-1, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
698 {-1, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
699 { 0, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
700 { 0, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
702 /* Ok, I am too lazy to deal with transform matrices */
703 struct sVertex unstransformed_2[] = {
704 {-1, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
705 {-1, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
706 { 0, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
707 { 0, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
709 /* Untransformed ones. Give them a different diffuse color to make the test look
710 * nicer. It also makes making sure that they are drawn correctly easier.
712 struct sVertexT transformed_1[] = {
713 {320, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
714 {640, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
715 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
716 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
718 struct sVertexT transformed_2[] = {
719 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
720 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
721 {640, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
722 {320, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
724 struct vertex rev_fog_quads[] = {
725 {-1.0, -1.0, 0.1, 0x000000ff},
726 {-1.0, 0.0, 0.1, 0x000000ff},
727 { 0.0, 0.0, 0.1, 0x000000ff},
728 { 0.0, -1.0, 0.1, 0x000000ff},
730 { 0.0, -1.0, 0.9, 0x000000ff},
731 { 0.0, 0.0, 0.9, 0x000000ff},
732 { 1.0, 0.0, 0.9, 0x000000ff},
733 { 1.0, -1.0, 0.9, 0x000000ff},
735 { 0.0, 0.0, 0.4, 0x000000ff},
736 { 0.0, 1.0, 0.4, 0x000000ff},
737 { 1.0, 1.0, 0.4, 0x000000ff},
738 { 1.0, 0.0, 0.4, 0x000000ff},
740 {-1.0, 0.0, 0.7, 0x000000ff},
741 {-1.0, 1.0, 0.7, 0x000000ff},
742 { 0.0, 1.0, 0.7, 0x000000ff},
743 { 0.0, 0.0, 0.7, 0x000000ff},
745 WORD Indices[] = {0, 1, 2, 2, 3, 0};
747 memset(&caps, 0, sizeof(caps));
748 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
749 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %s\n", DXGetErrorString9(hr));
750 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
751 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
753 /* Setup initial states: No lighting, fog on, fog color */
754 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
755 ok(hr == D3D_OK, "Turning off lighting returned %s\n", DXGetErrorString9(hr));
756 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
757 ok(hr == D3D_OK, "Turning on fog calculations returned %s\n", DXGetErrorString9(hr));
758 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
759 ok(hr == D3D_OK, "Turning on fog calculations returned %s\n", DXGetErrorString9(hr));
761 /* First test: Both table fog and vertex fog off */
762 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
763 ok(hr == D3D_OK, "Turning off table fog returned %s\n", DXGetErrorString9(hr));
764 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
765 ok(hr == D3D_OK, "Turning off table fog returned %s\n", DXGetErrorString9(hr));
767 /* Start = 0, end = 1. Should be default, but set them */
768 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
769 ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
770 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
771 ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
773 if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
775 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
776 ok( hr == D3D_OK, "SetFVF returned %s\n", DXGetErrorString9(hr));
777 /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
778 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
779 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
780 sizeof(unstransformed_1[0]));
781 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
783 /* That makes it use the Z value */
784 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
785 ok(hr == D3D_OK, "Turning off table fog returned %s\n", DXGetErrorString9(hr));
786 /* Untransformed, vertex fog != none (or table fog != none):
787 * Use the Z value as input into the equation
789 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
790 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
791 sizeof(unstransformed_1[0]));
792 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
794 /* transformed verts */
795 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
796 ok( hr == D3D_OK, "SetFVF returned %s\n", DXGetErrorString9(hr));
797 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
798 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
799 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
800 sizeof(transformed_1[0]));
801 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
803 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
804 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %s\n", DXGetErrorString9(hr));
805 /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
806 * equation
808 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
809 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
810 sizeof(transformed_2[0]));
812 hr = IDirect3DDevice9_EndScene(device);
813 ok(hr == D3D_OK, "EndScene returned %s\n", DXGetErrorString9(hr));
815 else
817 ok(FALSE, "BeginScene failed\n");
820 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
821 color = getPixelColor(device, 160, 360);
822 ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
823 color = getPixelColor(device, 160, 120);
824 ok(color == 0x0000FF00 || color == 0x0000FE00, "Untransformed vertex with linear vertex fog has color %08x\n", color);
825 color = getPixelColor(device, 480, 120);
826 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
827 if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
829 color = getPixelColor(device, 480, 360);
830 ok(color == 0x0000FF00 || color == 0x0000FE00, "Transformed vertex with linear table fog has color %08x\n", color);
832 else
834 /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
835 * The settings above result in no fogging with vertex fog
837 color = getPixelColor(device, 480, 120);
838 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
839 trace("Info: Table fog not supported by this device\n");
842 /* Now test the special case fogstart == fogend */
843 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
844 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
846 if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
848 start = 512;
849 end = 512;
850 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
851 ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
852 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
853 ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
855 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
856 ok( hr == D3D_OK, "SetFVF returned %s\n", DXGetErrorString9(hr));
857 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
858 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %s\n", DXGetErrorString9(hr));
859 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
860 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %s\n", DXGetErrorString9(hr));
862 /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
863 * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
864 * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
865 * The third transformed quad remains unfogged because the fogcoords are read from the specular
866 * color and has fixed fogstart and fogend.
868 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
869 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
870 sizeof(unstransformed_1[0]));
871 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
872 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
873 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
874 sizeof(unstransformed_1[0]));
875 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
877 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
878 ok( hr == D3D_OK, "SetFVF returned %s\n", DXGetErrorString9(hr));
879 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
880 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
881 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
882 sizeof(transformed_1[0]));
883 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
885 hr = IDirect3DDevice9_EndScene(device);
886 ok(hr == D3D_OK, "EndScene returned %s\n", DXGetErrorString9(hr));
888 else
890 ok(FALSE, "BeginScene failed\n");
892 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
893 color = getPixelColor(device, 160, 360);
894 ok(color == 0x0000FF00 || color == 0x0000FE00, "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
895 color = getPixelColor(device, 160, 120);
896 ok(color == 0x0000FF00 || color == 0x0000FE00, "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
897 color = getPixelColor(device, 480, 120);
898 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
900 /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
901 * but without shaders it seems to work everywhere
903 end = 0.2;
904 start = 0.8;
905 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
906 ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
907 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
908 ok(hr == D3D_OK, "Setting fog end returned %s\n", DXGetErrorString9(hr));
909 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
910 ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
912 /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
913 * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
914 * so skip this for now
916 for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
917 const char *mode = (i ? "table" : "vertex");
918 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
919 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
920 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
921 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
922 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
923 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
924 hr = IDirect3DDevice9_BeginScene(device);
925 ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
926 if(SUCCEEDED(hr)) {
927 WORD Indices2[] = { 0, 1, 2, 2, 3, 0,
928 4, 5, 6, 6, 7, 4,
929 8, 9, 10, 10, 11, 8,
930 12, 13, 14, 14, 15, 12};
932 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
933 16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
934 sizeof(rev_fog_quads[0]));
936 hr = IDirect3DDevice9_EndScene(device);
937 ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
939 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
940 color = getPixelColor(device, 160, 360);
941 ok(color == 0x0000FF00 || color == 0x0000FE00, "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00\n", mode, color);
943 color = getPixelColor(device, 160, 120);
944 r = (color & 0x00ff0000) >> 16;
945 g = (color & 0x0000ff00) >> 8;
946 b = (color & 0x000000ff);
947 ok(r == 0x00 && g >= 0x29 && g <= 0x2d && b >= 0xd2 && b <= 0xd6,
948 "Reversed %s fog: z=0.7 has color 0x%08x, expected\n", mode, color);
950 color = getPixelColor(device, 480, 120);
951 r = (color & 0x00ff0000) >> 16;
952 g = (color & 0x0000ff00) >> 8;
953 b = (color & 0x000000ff);
954 ok(r == 0x00 && g >= 0xa8 && g <= 0xac && b >= 0x53 && b <= 0x57,
955 "Reversed %s fog: z=0.4 has color 0x%08x, expected\n", mode, color);
957 color = getPixelColor(device, 480, 360);
958 ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
960 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
961 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
962 break;
965 /* Turn off the fog master switch to avoid confusing other tests */
966 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
967 ok(hr == D3D_OK, "Turning off fog calculations returned %s\n", DXGetErrorString9(hr));
968 start = 0.0;
969 end = 1.0;
970 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
971 ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
972 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
973 ok(hr == D3D_OK, "Setting fog end returned %s\n", DXGetErrorString9(hr));
974 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
975 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %s\n", DXGetErrorString9(hr));
976 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
977 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %s\n", DXGetErrorString9(hr));
980 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
981 * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
982 * regardless of the actual addressing mode set. */
983 static void test_cube_wrap(IDirect3DDevice9 *device)
985 static const float quad[][6] = {
986 {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
987 {-1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
988 { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
989 { 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
992 static const D3DVERTEXELEMENT9 decl_elements[] = {
993 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
994 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
995 D3DDECL_END()
998 static const struct {
999 D3DTEXTUREADDRESS mode;
1000 const char *name;
1001 } address_modes[] = {
1002 {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
1003 {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
1004 {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
1005 {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
1006 {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
1009 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1010 IDirect3DCubeTexture9 *texture = NULL;
1011 IDirect3DSurface9 *surface = NULL;
1012 D3DLOCKED_RECT locked_rect;
1013 HRESULT hr;
1014 UINT x;
1015 INT y, face;
1017 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1018 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1019 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1020 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1022 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1023 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1024 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1026 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1027 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1029 for (y = 0; y < 128; ++y)
1031 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1032 for (x = 0; x < 64; ++x)
1034 *ptr++ = 0xffff0000;
1036 for (x = 64; x < 128; ++x)
1038 *ptr++ = 0xff0000ff;
1042 hr = IDirect3DSurface9_UnlockRect(surface);
1043 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1045 hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1046 D3DPOOL_DEFAULT, &texture, NULL);
1047 ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1049 /* Create cube faces */
1050 for (face = 0; face < 6; ++face)
1052 IDirect3DSurface9 *face_surface = NULL;
1054 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1055 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1057 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1058 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1060 IDirect3DSurface9_Release(face_surface);
1063 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1064 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1066 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1067 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1068 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1069 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1070 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1071 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1073 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1074 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1076 for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1078 DWORD color;
1080 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1081 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1082 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1083 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1085 hr = IDirect3DDevice9_BeginScene(device);
1086 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1088 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1089 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1091 hr = IDirect3DDevice9_EndScene(device);
1092 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1094 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1095 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1097 /* Due to the nature of this test, we sample essentially at the edge
1098 * between two faces. Because of this it's undefined from which face
1099 * the driver will sample. Fortunately that's not important for this
1100 * test, since all we care about is that it doesn't sample from the
1101 * other side of the surface or from the border. */
1102 color = getPixelColor(device, 320, 240);
1103 ok(color == 0x00ff0000 || color == 0x000000ff,
1104 "Got color 0x%08x for addressing mode %s, expected 0x00ff0000 or 0x000000ff.\n",
1105 color, address_modes[x].name);
1107 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1108 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1111 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1112 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1114 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1115 IDirect3DCubeTexture9_Release(texture);
1116 IDirect3DSurface9_Release(surface);
1119 static void offscreen_test(IDirect3DDevice9 *device)
1121 HRESULT hr;
1122 IDirect3DTexture9 *offscreenTexture = NULL;
1123 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1124 DWORD color;
1126 static const float quad[][5] = {
1127 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1128 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
1129 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1130 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
1133 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1134 ok(hr == D3D_OK, "Clear failed, hr = %s\n", DXGetErrorString9(hr));
1136 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1137 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %s\n", DXGetErrorString9(hr));
1138 if(!offscreenTexture) {
1139 trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1140 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1141 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %s\n", DXGetErrorString9(hr));
1142 if(!offscreenTexture) {
1143 skip("Cannot create an offscreen render target\n");
1144 goto out;
1148 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1149 ok(hr == D3D_OK, "Can't get back buffer, hr = %s\n", DXGetErrorString9(hr));
1150 if(!backbuffer) {
1151 goto out;
1154 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1155 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %s\n", DXGetErrorString9(hr));
1156 if(!offscreen) {
1157 goto out;
1160 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1161 ok(hr == D3D_OK, "SetFVF failed, hr = %s\n", DXGetErrorString9(hr));
1163 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1164 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
1165 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1166 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
1167 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1168 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1169 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1170 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1171 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1172 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1174 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1175 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1176 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %s\n", DXGetErrorString9(hr));
1177 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1178 ok(hr == D3D_OK, "Clear failed, hr = %s\n", DXGetErrorString9(hr));
1180 /* Draw without textures - Should result in a white quad */
1181 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1182 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %s\n", DXGetErrorString9(hr));
1184 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1185 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %s\n", DXGetErrorString9(hr));
1186 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1187 ok(hr == D3D_OK, "SetTexture failed, %s\n", DXGetErrorString9(hr));
1189 /* This time with the texture */
1190 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1191 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %s\n", DXGetErrorString9(hr));
1193 IDirect3DDevice9_EndScene(device);
1196 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1198 /* Center quad - should be white */
1199 color = getPixelColor(device, 320, 240);
1200 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1201 /* Some quad in the cleared part of the texture */
1202 color = getPixelColor(device, 170, 240);
1203 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1204 /* Part of the originally cleared back buffer */
1205 color = getPixelColor(device, 10, 10);
1206 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1207 if(0) {
1208 /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1209 * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1210 * the offscreen rendering mode this test would succeed or fail
1212 color = getPixelColor(device, 10, 470);
1213 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1216 out:
1217 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1219 /* restore things */
1220 if(backbuffer) {
1221 IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1222 IDirect3DSurface9_Release(backbuffer);
1224 if(offscreenTexture) {
1225 IDirect3DTexture9_Release(offscreenTexture);
1227 if(offscreen) {
1228 IDirect3DSurface9_Release(offscreen);
1232 /* This test tests fog in combination with shaders.
1233 * What's tested: linear fog (vertex and table) with pixel shader
1234 * linear table fog with non foggy vertex shader
1235 * vertex fog with foggy vertex shader
1236 * What's not tested: non linear fog with shader
1237 * table fog with foggy vertex shader
1239 static void fog_with_shader_test(IDirect3DDevice9 *device)
1241 HRESULT hr;
1242 DWORD color;
1243 union {
1244 float f;
1245 DWORD i;
1246 } start, end;
1247 unsigned int i, j;
1249 /* basic vertex shader without fog computation ("non foggy") */
1250 static const DWORD vertex_shader_code1[] = {
1251 0xfffe0101, /* vs_1_1 */
1252 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1253 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1254 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1255 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1256 0x0000ffff
1258 /* basic vertex shader with reversed fog computation ("foggy") */
1259 static const DWORD vertex_shader_code2[] = {
1260 0xfffe0101, /* vs_1_1 */
1261 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1262 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1263 0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1264 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1265 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1266 0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
1267 0x00000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
1268 0x0000ffff
1270 /* basic pixel shader */
1271 static const DWORD pixel_shader_code[] = {
1272 0xffff0101, /* ps_1_1 */
1273 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, vo */
1274 0x0000ffff
1277 static struct vertex quad[] = {
1278 {-1.0f, -1.0f, 0.0f, 0xFFFF0000 },
1279 {-1.0f, 1.0f, 0.0f, 0xFFFF0000 },
1280 { 1.0f, -1.0f, 0.0f, 0xFFFF0000 },
1281 { 1.0f, 1.0f, 0.0f, 0xFFFF0000 },
1284 static const D3DVERTEXELEMENT9 decl_elements[] = {
1285 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1286 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
1287 D3DDECL_END()
1290 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1291 IDirect3DVertexShader9 *vertex_shader[3] = {NULL, NULL, NULL};
1292 IDirect3DPixelShader9 *pixel_shader[2] = {NULL, NULL};
1294 /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1295 static const struct test_data_t {
1296 int vshader;
1297 int pshader;
1298 D3DFOGMODE vfog;
1299 D3DFOGMODE tfog;
1300 unsigned int color[11];
1301 } test_data[] = {
1302 /* only pixel shader: */
1303 {0, 1, 0, 3,
1304 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1305 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1306 {0, 1, 1, 3,
1307 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1308 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1309 {0, 1, 2, 3,
1310 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1311 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1312 {0, 1, 3, 0,
1313 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1314 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1315 {0, 1, 3, 3,
1316 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1317 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1319 /* vertex shader */
1320 {1, 0, 0, 0,
1321 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1322 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1323 {1, 0, 0, 3,
1324 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1325 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1326 {1, 0, 1, 3,
1327 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1328 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1330 {1, 0, 2, 3,
1331 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1332 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1333 {1, 0, 3, 3,
1334 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1335 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1337 /* vertex shader and pixel shader */
1338 {1, 1, 0, 3,
1339 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1340 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1341 {1, 1, 1, 3,
1342 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1343 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1344 {1, 1, 2, 3,
1345 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1346 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1348 {1, 1, 3, 3,
1349 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1350 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1353 #if 0 /* FIXME: these fail on GeForce 8500 */
1354 /* foggy vertex shader */
1355 {2, 0, 0, 0,
1356 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1357 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1358 {2, 0, 1, 0,
1359 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1360 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1361 {2, 0, 2, 0,
1362 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1363 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1364 {2, 0, 3, 0,
1365 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1366 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1367 #endif
1369 /* foggy vertex shader and pixel shader */
1370 {2, 1, 0, 0,
1371 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1372 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1373 {2, 1, 1, 0,
1374 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1375 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1376 {2, 1, 2, 0,
1377 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1378 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1379 {2, 1, 3, 0,
1380 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1381 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1385 /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1386 start.f=0.1f;
1387 end.f=0.9f;
1389 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1390 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1391 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1392 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1393 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1394 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1395 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1396 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1398 /* Setup initial states: No lighting, fog on, fog color */
1399 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1400 ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1401 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1402 ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1403 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1404 ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1405 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1406 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1408 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1409 ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1410 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1411 ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1413 /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1414 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1415 ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1416 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1417 ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1419 for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1421 hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1422 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1423 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1424 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1425 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1426 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1427 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1428 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1430 for(j=0; j < 11; j++)
1432 /* Don't use the whole zrange to prevent rounding errors */
1433 quad[0].z = 0.001f + (float)j / 10.02f;
1434 quad[1].z = 0.001f + (float)j / 10.02f;
1435 quad[2].z = 0.001f + (float)j / 10.02f;
1436 quad[3].z = 0.001f + (float)j / 10.02f;
1438 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1439 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1441 hr = IDirect3DDevice9_BeginScene(device);
1442 ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1444 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1445 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1447 hr = IDirect3DDevice9_EndScene(device);
1448 ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1450 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1452 /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1453 color = getPixelColor(device, 128, 240);
1454 ok((unsigned char)(color) == ((unsigned char)test_data[i].color[j])
1455 && abs( ((unsigned char)(color>>8)) - (unsigned char)(test_data[i].color[j]>>8) ) < 13
1456 && abs( ((unsigned char)(color>>16)) - (unsigned char)(test_data[i].color[j]>>16) ) < 13,
1457 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1458 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1462 /* reset states */
1463 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1464 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1465 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1466 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1467 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1468 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1469 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1470 ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1472 IDirect3DVertexShader9_Release(vertex_shader[1]);
1473 IDirect3DVertexShader9_Release(vertex_shader[2]);
1474 IDirect3DPixelShader9_Release(pixel_shader[1]);
1475 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1478 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
1479 unsigned int i, x, y;
1480 HRESULT hr;
1481 IDirect3DTexture9 *texture[2] = {NULL, NULL};
1482 D3DLOCKED_RECT locked_rect;
1484 /* Generate the textures */
1485 for(i=0; i<2; i++)
1487 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1488 D3DPOOL_MANAGED, &texture[i], NULL);
1489 ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1491 hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
1492 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1493 for (y = 0; y < 128; ++y)
1495 if(i)
1496 { /* Set up black texture with 2x2 texel white spot in the middle */
1497 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1498 for (x = 0; x < 128; ++x)
1500 if(y>62 && y<66 && x>62 && x<66)
1501 *ptr++ = 0xffffffff;
1502 else
1503 *ptr++ = 0xff000000;
1506 else
1507 { /* Set up a displacement map which points away from the center parallel to the closest axis.
1508 * (if multiplied with bumpenvmat)
1510 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1511 for (x = 0; x < 128; ++x)
1513 if(abs(x-64)>abs(y-64))
1515 if(x < 64)
1516 *ptr++ = 0xc000;
1517 else
1518 *ptr++ = 0x4000;
1520 else
1522 if(y < 64)
1523 *ptr++ = 0x0040;
1524 else
1525 *ptr++ = 0x00c0;
1530 hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
1531 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1533 hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
1534 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1536 /* Disable texture filtering */
1537 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1538 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1539 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1540 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1542 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1543 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
1544 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1545 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
1549 /* test the behavior of the texbem instruction
1550 * with normal 2D and projective 2D textures
1552 static void texbem_test(IDirect3DDevice9 *device)
1554 HRESULT hr;
1555 DWORD color;
1556 int i;
1558 static const DWORD pixel_shader_code[] = {
1559 0xffff0101, /* ps_1_1*/
1560 0x00000042, 0xb00f0000, /* tex t0*/
1561 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
1562 0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
1563 0x0000ffff
1565 static const DWORD double_texbem_code[] = {
1566 0xffff0103, /* ps_1_3 */
1567 0x00000042, 0xb00f0000, /* tex t0 */
1568 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0 */
1569 0x00000042, 0xb00f0002, /* tex t2 */
1570 0x00000043, 0xb00f0003, 0xb0e40002, /* texbem t3, t2 */
1571 0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003, /* add r0, t1, t3 */
1572 0x0000ffff /* end */
1576 static const float quad[][7] = {
1577 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
1578 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
1579 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
1580 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
1582 static const float quad_proj[][9] = {
1583 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 128.0f},
1584 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 128.0f, 0.0f, 128.0f},
1585 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f, 0.0f, 0.0f, 128.0f},
1586 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
1589 static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
1590 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1591 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1592 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1593 D3DDECL_END()
1595 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1596 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1597 {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1598 D3DDECL_END()
1599 } };
1601 /* use asymmetric matrix to test loading */
1602 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
1604 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1605 IDirect3DPixelShader9 *pixel_shader = NULL;
1606 IDirect3DTexture9 *texture = NULL, *texture1, *texture2;
1607 D3DLOCKED_RECT locked_rect;
1609 generate_bumpmap_textures(device);
1611 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1612 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1613 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1614 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1615 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
1617 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1618 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1620 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1621 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1623 for(i=0; i<2; i++)
1625 if(i)
1627 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
1628 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1631 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
1632 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1633 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1634 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1636 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
1637 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1638 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1639 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1641 hr = IDirect3DDevice9_BeginScene(device);
1642 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1644 if(!i)
1645 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1646 else
1647 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
1648 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1650 hr = IDirect3DDevice9_EndScene(device);
1651 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1653 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1654 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1656 color = getPixelColor(device, 320-32, 240);
1657 ok(color == 0x00ffffff, "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1658 color = getPixelColor(device, 320+32, 240);
1659 ok(color == 0x00ffffff, "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1660 color = getPixelColor(device, 320, 240-32);
1661 ok(color == 0x00ffffff, "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1662 color = getPixelColor(device, 320, 240+32);
1663 ok(color == 0x00ffffff, "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1665 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1666 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1667 IDirect3DPixelShader9_Release(pixel_shader);
1669 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1670 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1671 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1674 /* clean up */
1675 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1676 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1678 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
1679 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1681 for(i=0; i<2; i++)
1683 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
1684 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
1685 IDirect3DTexture9_Release(texture); /* For the GetTexture */
1686 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
1687 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1688 IDirect3DTexture9_Release(texture);
1691 /* Test double texbem */
1692 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
1693 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1694 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
1695 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1696 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
1697 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1698 hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
1699 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1701 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
1702 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1703 ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
1704 ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
1706 hr = IDirect3DTexture9_UnlockRect(texture, 0);
1707 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1709 hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
1710 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1711 ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
1712 ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
1713 hr = IDirect3DTexture9_UnlockRect(texture1, 0);
1714 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1717 /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
1718 #define tex 0x00ff0000
1719 #define tex1 0x0000ff00
1720 #define origin 0x000000ff
1721 static const DWORD pixel_data[] = {
1722 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1723 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1724 0x000000ff, tex1 , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1725 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1726 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin, 0x000000ff, tex , 0x000000ff,
1727 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1728 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1729 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1731 #undef tex1
1732 #undef tex2
1733 #undef origin
1735 hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
1736 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1737 for(i = 0; i < 8; i++) {
1738 memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
1740 hr = IDirect3DTexture9_UnlockRect(texture2, 0);
1741 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1744 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
1745 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1746 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
1747 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1748 hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
1749 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1750 hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
1751 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1752 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1753 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1754 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
1755 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1757 bumpenvmat[0] =-1.0; bumpenvmat[2] = 2.0;
1758 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.0;
1759 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1760 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1761 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1762 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1764 bumpenvmat[0] = 1.5; bumpenvmat[2] = 0.0;
1765 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.5;
1766 IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1767 IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1768 IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1769 IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1771 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1772 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1773 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1774 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1775 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1776 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1777 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1778 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1780 hr = IDirect3DDevice9_BeginScene(device);
1781 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1782 if(SUCCEEDED(hr)) {
1783 static const float double_quad[] = {
1784 -1.0, -1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
1785 1.0, -1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
1786 -1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
1787 1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
1790 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
1791 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1792 hr = IDirect3DDevice9_EndScene(device);
1793 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1795 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1796 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1797 color = getPixelColor(device, 320, 240);
1798 ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1800 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1801 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1802 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
1803 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1804 hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
1805 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1806 hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
1807 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1808 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1809 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1811 IDirect3DPixelShader9_Release(pixel_shader);
1812 IDirect3DTexture9_Release(texture);
1813 IDirect3DTexture9_Release(texture1);
1814 IDirect3DTexture9_Release(texture2);
1817 static void z_range_test(IDirect3DDevice9 *device)
1819 const struct vertex quad[] =
1821 {-1.0f, 0.0f, 1.1f, 0xffff0000},
1822 {-1.0f, 1.0f, 1.1f, 0xffff0000},
1823 { 1.0f, 0.0f, -1.1f, 0xffff0000},
1824 { 1.0f, 1.0f, -1.1f, 0xffff0000},
1826 const struct vertex quad2[] =
1828 {-1.0f, 0.0f, 1.1f, 0xff0000ff},
1829 {-1.0f, 1.0f, 1.1f, 0xff0000ff},
1830 { 1.0f, 0.0f, -1.1f, 0xff0000ff},
1831 { 1.0f, 1.0f, -1.1f, 0xff0000ff},
1834 const struct tvertex quad3[] =
1836 { 0, 240, 1.1f, 1.0, 0xffffff00},
1837 { 0, 480, 1.1f, 1.0, 0xffffff00},
1838 { 640, 240, -1.1f, 1.0, 0xffffff00},
1839 { 640, 480, -1.1f, 1.0, 0xffffff00},
1841 const struct tvertex quad4[] =
1843 { 0, 240, 1.1f, 1.0, 0xff00ff00},
1844 { 0, 480, 1.1f, 1.0, 0xff00ff00},
1845 { 640, 240, -1.1f, 1.0, 0xff00ff00},
1846 { 640, 480, -1.1f, 1.0, 0xff00ff00},
1848 HRESULT hr;
1849 DWORD color;
1850 IDirect3DVertexShader9 *shader;
1851 IDirect3DVertexDeclaration9 *decl;
1852 D3DCAPS9 caps;
1853 const DWORD shader_code[] = {
1854 0xfffe0101, /* vs_1_1 */
1855 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1856 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1857 0x00000001, 0xd00f0000, 0xa0e40000, /* mov oD0, c0 */
1858 0x0000ffff /* end */
1860 static const D3DVERTEXELEMENT9 decl_elements[] = {
1861 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1862 D3DDECL_END()
1864 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
1865 * then call Present. Then clear the color buffer to make sure it has some defined content
1866 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
1867 * by the depth value.
1869 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
1870 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
1871 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1872 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
1874 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
1875 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1876 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
1877 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1878 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
1879 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1880 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
1881 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1882 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1883 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
1885 hr = IDirect3DDevice9_BeginScene(device);
1886 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
1887 if(hr == D3D_OK)
1889 /* Test the untransformed vertex path */
1890 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
1891 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1892 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
1893 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1894 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
1895 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1897 /* Test the transformed vertex path */
1898 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
1899 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
1901 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
1902 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1903 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
1904 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1905 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
1906 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1908 hr = IDirect3DDevice9_EndScene(device);
1909 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
1912 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1913 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1915 /* Do not test the exact corner pixels, but go pretty close to them */
1917 /* Clipped because z > 1.0 */
1918 color = getPixelColor(device, 28, 238);
1919 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1920 color = getPixelColor(device, 28, 241);
1921 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1923 /* Not clipped, > z buffer clear value(0.75) */
1924 color = getPixelColor(device, 31, 238);
1925 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1926 color = getPixelColor(device, 31, 241);
1927 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1928 color = getPixelColor(device, 100, 238);
1929 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1930 color = getPixelColor(device, 100, 241);
1931 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1933 /* Not clipped, < z buffer clear value */
1934 color = getPixelColor(device, 104, 238);
1935 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
1936 color = getPixelColor(device, 104, 241);
1937 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
1938 color = getPixelColor(device, 318, 238);
1939 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
1940 color = getPixelColor(device, 318, 241);
1941 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
1943 /* Clipped because z < 0.0 */
1944 color = getPixelColor(device, 321, 238);
1945 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1946 color = getPixelColor(device, 321, 241);
1947 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1949 /* Test the shader path */
1950 IDirect3DDevice9_GetDeviceCaps(device, &caps);
1951 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
1952 skip("Vertex shaders not supported\n");
1953 goto out;
1955 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
1956 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
1957 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
1958 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
1960 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
1962 IDirect3DDevice9_SetVertexDeclaration(device, decl);
1963 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
1964 IDirect3DDevice9_SetVertexShader(device, shader);
1965 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
1967 hr = IDirect3DDevice9_BeginScene(device);
1968 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
1969 if(hr == D3D_OK)
1971 float colorf[] = {1.0, 0.0, 0.0, 1.0};
1972 float colorf2[] = {0.0, 0.0, 1.0, 1.0};
1973 IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
1974 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
1975 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1976 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
1977 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1978 IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
1979 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
1980 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1982 hr = IDirect3DDevice9_EndScene(device);
1983 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
1986 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1987 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
1988 IDirect3DDevice9_SetVertexShader(device, NULL);
1989 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
1991 IDirect3DVertexDeclaration9_Release(decl);
1992 IDirect3DVertexShader9_Release(shader);
1994 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1995 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1996 /* Z < 1.0 */
1997 color = getPixelColor(device, 28, 238);
1998 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2000 /* 1.0 < z < 0.75 */
2001 color = getPixelColor(device, 31, 238);
2002 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2003 color = getPixelColor(device, 100, 238);
2004 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2006 /* 0.75 < z < 0.0 */
2007 color = getPixelColor(device, 104, 238);
2008 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2009 color = getPixelColor(device, 318, 238);
2010 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2012 /* 0.0 < z */
2013 color = getPixelColor(device, 321, 238);
2014 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2016 out:
2017 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2018 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
2019 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2020 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
2021 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2022 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
2025 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2027 D3DSURFACE_DESC desc;
2028 D3DLOCKED_RECT l;
2029 HRESULT hr;
2030 unsigned int x, y;
2031 DWORD *mem;
2033 memset(&desc, 0, sizeof(desc));
2034 memset(&l, 0, sizeof(l));
2035 hr = IDirect3DSurface9_GetDesc(surface, &desc);
2036 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %s\n", DXGetErrorString9(hr));
2037 hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2038 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %s\n", DXGetErrorString9(hr));
2039 if(FAILED(hr)) return;
2041 for(y = 0; y < desc.Height; y++)
2043 mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2044 for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2046 mem[x] = color;
2049 hr = IDirect3DSurface9_UnlockRect(surface);
2050 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %s\n", DXGetErrorString9(hr));
2053 /* This tests a variety of possible StretchRect() situations */
2054 static void stretchrect_test(IDirect3DDevice9 *device)
2056 HRESULT hr;
2057 IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64 = NULL;
2058 IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL;
2059 IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2060 IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2061 IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2062 IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2063 IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2064 IDirect3DSurface9 *orig_rt = NULL;
2065 DWORD color;
2067 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2068 ok(hr == D3D_OK, "Can't get render target, hr = %s\n", DXGetErrorString9(hr));
2069 if(!orig_rt) {
2070 goto out;
2073 /* Create our temporary surfaces in system memory */
2074 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2075 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %s\n", DXGetErrorString9(hr));
2076 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2077 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %s\n", DXGetErrorString9(hr));
2079 /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2080 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2081 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %s\n", DXGetErrorString9(hr));
2082 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2083 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %s\n", DXGetErrorString9(hr));
2084 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2085 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %s\n", DXGetErrorString9(hr));
2087 /* Create render target surfaces */
2088 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2089 ok(hr == D3D_OK, "Creating the render target surface failed with %s\n", DXGetErrorString9(hr));
2090 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2091 ok(hr == D3D_OK, "Creating the render target surface failed with %s\n", DXGetErrorString9(hr));
2092 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2093 ok(hr == D3D_OK, "Creating the render target surface failed with %s\n", DXGetErrorString9(hr));
2095 /* Create render target textures */
2096 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2097 ok(hr == D3D_OK, "Creating the render target texture failed with %s\n", DXGetErrorString9(hr));
2098 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2099 ok(hr == D3D_OK, "Creating the render target texture failed with %s\n", DXGetErrorString9(hr));
2100 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2101 ok(hr == D3D_OK, "Creating the render target texture failed with %s\n", DXGetErrorString9(hr));
2102 if (tex_rt32) {
2103 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2104 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
2106 if (tex_rt64) {
2107 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2108 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
2110 if (tex_rt_dest64) {
2111 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2112 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
2115 /* Create regular textures in D3DPOOL_DEFAULT */
2116 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2117 ok(hr == D3D_OK, "Creating the regular texture failed with %s\n", DXGetErrorString9(hr));
2118 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2119 ok(hr == D3D_OK, "Creating the regular texture failed with %s\n", DXGetErrorString9(hr));
2120 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2121 ok(hr == D3D_OK, "Creating the regular texture failed with %s\n", DXGetErrorString9(hr));
2122 if (tex32) {
2123 hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2124 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
2126 if (tex64) {
2127 hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2128 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
2130 if (tex_dest64) {
2131 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2132 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
2135 /*********************************************************************
2136 * Tests for when the source parameter is an offscreen plain surface *
2137 *********************************************************************/
2139 /* Fill the offscreen 64x64 surface with green */
2140 if (surf_offscreen64)
2141 fill_surface(surf_offscreen64, 0xff00ff00);
2143 /* offscreenplain ==> offscreenplain, same size */
2144 if(surf_offscreen64 && surf_offscreen_dest64) {
2145 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2146 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2148 if (hr == D3D_OK) {
2149 color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2150 ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2154 /* offscreenplain ==> rendertarget texture, same size */
2155 if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2156 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2157 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2159 /* We can't lock rendertarget textures, so copy to our temp surface first */
2160 if (hr == D3D_OK) {
2161 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2162 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2165 if (hr == D3D_OK) {
2166 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2167 ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2171 /* offscreenplain ==> rendertarget surface, same size */
2172 if(surf_offscreen64 && surf_rt_dest64) {
2173 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2174 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2176 if (hr == D3D_OK) {
2177 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2178 ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2182 /* offscreenplain ==> texture, same size (should fail) */
2183 if(surf_offscreen64 && surf_tex_dest64) {
2184 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2185 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2188 /* Fill the smaller offscreen surface with red */
2189 fill_surface(surf_offscreen32, 0xffff0000);
2191 /* offscreenplain ==> offscreenplain, scaling (should fail) */
2192 if(surf_offscreen32 && surf_offscreen64) {
2193 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2194 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2197 /* offscreenplain ==> rendertarget texture, scaling */
2198 if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2199 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2200 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2202 /* We can't lock rendertarget textures, so copy to our temp surface first */
2203 if (hr == D3D_OK) {
2204 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2205 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2208 if (hr == D3D_OK) {
2209 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2210 ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2214 /* offscreenplain ==> rendertarget surface, scaling */
2215 if(surf_offscreen32 && surf_rt_dest64) {
2216 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2217 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2219 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2220 ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2223 /* offscreenplain ==> texture, scaling (should fail) */
2224 if(surf_offscreen32 && surf_tex_dest64) {
2225 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2226 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2229 /************************************************************
2230 * Tests for when the source parameter is a regular texture *
2231 ************************************************************/
2233 /* Fill the surface of the regular texture with blue */
2234 if (surf_tex64 && surf_temp64) {
2235 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2236 fill_surface(surf_temp64, 0xff0000ff);
2237 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2238 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %s\n", DXGetErrorString9(hr));
2241 /* texture ==> offscreenplain, same size */
2242 if(surf_tex64 && surf_offscreen64) {
2243 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2244 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2247 /* texture ==> rendertarget texture, same size */
2248 if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2249 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2250 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2252 /* We can't lock rendertarget textures, so copy to our temp surface first */
2253 if (hr == D3D_OK) {
2254 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2255 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2258 if (hr == D3D_OK) {
2259 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2260 ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2264 /* texture ==> rendertarget surface, same size */
2265 if(surf_tex64 && surf_rt_dest64) {
2266 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2267 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2269 if (hr == D3D_OK) {
2270 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2271 ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2275 /* texture ==> texture, same size (should fail) */
2276 if(surf_tex64 && surf_tex_dest64) {
2277 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2278 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2281 /* Fill the surface of the smaller regular texture with red */
2282 if (surf_tex32 && surf_temp32) {
2283 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2284 fill_surface(surf_temp32, 0xffff0000);
2285 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2286 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %s\n", DXGetErrorString9(hr));
2289 /* texture ==> offscreenplain, scaling (should fail) */
2290 if(surf_tex32 && surf_offscreen64) {
2291 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2292 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2295 /* texture ==> rendertarget texture, scaling */
2296 if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
2297 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
2298 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2300 /* We can't lock rendertarget textures, so copy to our temp surface first */
2301 if (hr == D3D_OK) {
2302 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2303 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2306 if (hr == D3D_OK) {
2307 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2308 ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2312 /* texture ==> rendertarget surface, scaling */
2313 if(surf_tex32 && surf_rt_dest64) {
2314 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
2315 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2317 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2318 ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2321 /* texture ==> texture, scaling (should fail) */
2322 if(surf_tex32 && surf_tex_dest64) {
2323 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
2324 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2327 /*****************************************************************
2328 * Tests for when the source parameter is a rendertarget texture *
2329 *****************************************************************/
2331 /* Fill the surface of the rendertarget texture with white */
2332 if (surf_tex_rt64 && surf_temp64) {
2333 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2334 fill_surface(surf_temp64, 0xffffffff);
2335 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
2336 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %s\n", DXGetErrorString9(hr));
2339 /* rendertarget texture ==> offscreenplain, same size */
2340 if(surf_tex_rt64 && surf_offscreen64) {
2341 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
2342 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2345 /* rendertarget texture ==> rendertarget texture, same size */
2346 if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2347 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2348 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2350 /* We can't lock rendertarget textures, so copy to our temp surface first */
2351 if (hr == D3D_OK) {
2352 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2353 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2356 if (hr == D3D_OK) {
2357 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2358 ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2362 /* rendertarget texture ==> rendertarget surface, same size */
2363 if(surf_tex_rt64 && surf_rt_dest64) {
2364 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
2365 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2367 if (hr == D3D_OK) {
2368 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2369 ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2373 /* rendertarget texture ==> texture, same size (should fail) */
2374 if(surf_tex_rt64 && surf_tex_dest64) {
2375 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
2376 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2379 /* Fill the surface of the smaller rendertarget texture with red */
2380 if (surf_tex_rt32 && surf_temp32) {
2381 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2382 fill_surface(surf_temp32, 0xffff0000);
2383 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
2384 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %s\n", DXGetErrorString9(hr));
2387 /* rendertarget texture ==> offscreenplain, scaling (should fail) */
2388 if(surf_tex_rt32 && surf_offscreen64) {
2389 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
2390 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2393 /* rendertarget texture ==> rendertarget texture, scaling */
2394 if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2395 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2396 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2398 /* We can't lock rendertarget textures, so copy to our temp surface first */
2399 if (hr == D3D_OK) {
2400 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2401 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2404 if (hr == D3D_OK) {
2405 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2406 ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2410 /* rendertarget texture ==> rendertarget surface, scaling */
2411 if(surf_tex_rt32 && surf_rt_dest64) {
2412 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
2413 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2415 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2416 ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2419 /* rendertarget texture ==> texture, scaling (should fail) */
2420 if(surf_tex_rt32 && surf_tex_dest64) {
2421 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
2422 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2425 /*****************************************************************
2426 * Tests for when the source parameter is a rendertarget surface *
2427 *****************************************************************/
2429 /* Fill the surface of the rendertarget surface with black */
2430 if (surf_rt64)
2431 fill_surface(surf_rt64, 0xff000000);
2433 /* rendertarget texture ==> offscreenplain, same size */
2434 if(surf_rt64 && surf_offscreen64) {
2435 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
2436 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2439 /* rendertarget surface ==> rendertarget texture, same size */
2440 if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2441 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2442 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2444 /* We can't lock rendertarget textures, so copy to our temp surface first */
2445 if (hr == D3D_OK) {
2446 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2447 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2450 if (hr == D3D_OK) {
2451 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2452 ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2456 /* rendertarget surface ==> rendertarget surface, same size */
2457 if(surf_rt64 && surf_rt_dest64) {
2458 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
2459 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2461 if (hr == D3D_OK) {
2462 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2463 ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2467 /* rendertarget surface ==> texture, same size (should fail) */
2468 if(surf_rt64 && surf_tex_dest64) {
2469 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
2470 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2473 /* Fill the surface of the smaller rendertarget texture with red */
2474 if (surf_rt32)
2475 fill_surface(surf_rt32, 0xffff0000);
2477 /* rendertarget surface ==> offscreenplain, scaling (should fail) */
2478 if(surf_rt32 && surf_offscreen64) {
2479 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
2480 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2483 /* rendertarget surface ==> rendertarget texture, scaling */
2484 if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2485 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2486 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2488 /* We can't lock rendertarget textures, so copy to our temp surface first */
2489 if (hr == D3D_OK) {
2490 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2491 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2494 if (hr == D3D_OK) {
2495 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2496 ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2500 /* rendertarget surface ==> rendertarget surface, scaling */
2501 if(surf_rt32 && surf_rt_dest64) {
2502 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
2503 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2505 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2506 ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2509 /* rendertarget surface ==> texture, scaling (should fail) */
2510 if(surf_rt32 && surf_tex_dest64) {
2511 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
2512 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2515 /* TODO: Test when source and destination RECT parameters are given... */
2516 /* TODO: Test format conversions */
2519 out:
2520 /* Clean up */
2521 if (surf_rt32)
2522 IDirect3DSurface9_Release(surf_rt32);
2523 if (surf_rt64)
2524 IDirect3DSurface9_Release(surf_rt64);
2525 if (surf_rt_dest64)
2526 IDirect3DSurface9_Release(surf_rt_dest64);
2527 if (surf_temp32)
2528 IDirect3DSurface9_Release(surf_temp32);
2529 if (surf_temp64)
2530 IDirect3DSurface9_Release(surf_temp64);
2531 if (surf_offscreen32)
2532 IDirect3DSurface9_Release(surf_offscreen32);
2533 if (surf_offscreen64)
2534 IDirect3DSurface9_Release(surf_offscreen64);
2535 if (surf_offscreen_dest64)
2536 IDirect3DSurface9_Release(surf_offscreen_dest64);
2538 if (tex_rt32) {
2539 if (surf_tex_rt32)
2540 IDirect3DSurface9_Release(surf_tex_rt32);
2541 IDirect3DTexture9_Release(tex_rt32);
2543 if (tex_rt64) {
2544 if (surf_tex_rt64)
2545 IDirect3DSurface9_Release(surf_tex_rt64);
2546 IDirect3DTexture9_Release(tex_rt64);
2548 if (tex_rt_dest64) {
2549 if (surf_tex_rt_dest64)
2550 IDirect3DSurface9_Release(surf_tex_rt_dest64);
2551 IDirect3DTexture9_Release(tex_rt_dest64);
2553 if (tex32) {
2554 if (surf_tex32)
2555 IDirect3DSurface9_Release(surf_tex32);
2556 IDirect3DTexture9_Release(tex32);
2558 if (tex64) {
2559 if (surf_tex64)
2560 IDirect3DSurface9_Release(surf_tex64);
2561 IDirect3DTexture9_Release(tex64);
2563 if (tex_dest64) {
2564 if (surf_tex_dest64)
2565 IDirect3DSurface9_Release(surf_tex_dest64);
2566 IDirect3DTexture9_Release(tex_dest64);
2569 if (orig_rt) {
2570 hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
2571 ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %s\n", DXGetErrorString9(hr));
2572 IDirect3DSurface9_Release(orig_rt);
2576 static void maxmip_test(IDirect3DDevice9 *device)
2578 IDirect3DTexture9 *texture = NULL;
2579 IDirect3DSurface9 *surface = NULL;
2580 HRESULT hr;
2581 DWORD color;
2582 const float quads[] = {
2583 -1.0, -1.0, 0.0, 0.0, 0.0,
2584 -1.0, 0.0, 0.0, 0.0, 1.0,
2585 0.0, -1.0, 0.0, 1.0, 0.0,
2586 0.0, 0.0, 0.0, 1.0, 1.0,
2588 0.0, -1.0, 0.0, 0.0, 0.0,
2589 0.0, 0.0, 0.0, 0.0, 1.0,
2590 1.0, -1.0, 0.0, 1.0, 0.0,
2591 1.0, 0.0, 0.0, 1.0, 1.0,
2593 0.0, 0.0, 0.0, 0.0, 0.0,
2594 0.0, 1.0, 0.0, 0.0, 1.0,
2595 1.0, 0.0, 0.0, 1.0, 0.0,
2596 1.0, 1.0, 0.0, 1.0, 1.0,
2598 -1.0, 0.0, 0.0, 0.0, 0.0,
2599 -1.0, 1.0, 0.0, 0.0, 1.0,
2600 0.0, 0.0, 0.0, 1.0, 0.0,
2601 0.0, 1.0, 0.0, 1.0, 1.0,
2604 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2605 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
2607 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
2608 &texture, NULL);
2609 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
2610 if(!texture)
2612 skip("Failed to create test texture\n");
2613 return;
2616 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
2617 fill_surface(surface, 0xffff0000);
2618 IDirect3DSurface9_Release(surface);
2619 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
2620 fill_surface(surface, 0xff00ff00);
2621 IDirect3DSurface9_Release(surface);
2622 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
2623 fill_surface(surface, 0xff0000ff);
2624 IDirect3DSurface9_Release(surface);
2626 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2627 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2628 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2629 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2631 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2632 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2634 hr = IDirect3DDevice9_BeginScene(device);
2635 if(SUCCEEDED(hr))
2637 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2638 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2639 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2640 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2642 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2643 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2644 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2645 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2647 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2648 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2649 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2650 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2652 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2653 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2654 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2655 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2656 hr = IDirect3DDevice9_EndScene(device);
2659 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2660 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2661 /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
2662 color = getPixelColor(device, 160, 360);
2663 ok(color == 0x00FF0000, "MapMip 0, no mipfilter has color %08x\n", color);
2664 color = getPixelColor(device, 160, 120);
2665 ok(color == 0x00FF0000, "MapMip 3, no mipfilter has color %08x\n", color);
2666 color = getPixelColor(device, 480, 120);
2667 ok(color == 0x00FF0000, "MapMip 2, no mipfilter has color %08x\n", color);
2668 color = getPixelColor(device, 480, 360);
2669 ok(color == 0x00FF0000, "MapMip 1, no mipfilter has color %08x\n", color);
2671 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2672 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
2674 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
2675 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2677 hr = IDirect3DDevice9_BeginScene(device);
2678 if(SUCCEEDED(hr))
2680 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2681 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2682 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2683 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2685 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2686 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2687 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2688 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2690 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2691 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2692 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2693 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2695 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2696 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2697 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2698 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2699 hr = IDirect3DDevice9_EndScene(device);
2702 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2703 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2704 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2705 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2707 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2708 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2709 /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
2710 * samples from the highest level in the texture(level 2)
2712 color = getPixelColor(device, 160, 360);
2713 ok(color == 0x00FF0000, "MapMip 0, point mipfilter has color %08x\n", color);
2714 color = getPixelColor(device, 160, 120);
2715 ok(color == 0x000000FF, "MapMip 3, point mipfilter has color %08x\n", color);
2716 color = getPixelColor(device, 480, 120);
2717 ok(color == 0x000000FF, "MapMip 2, point mipfilter has color %08x\n", color);
2718 color = getPixelColor(device, 480, 360);
2719 ok(color == 0x0000FF00, "MapMip 1, point mipfilter has color %08x\n", color);
2721 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2722 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2723 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2724 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2725 IDirect3DTexture9_Release(texture);
2728 static void release_buffer_test(IDirect3DDevice9 *device)
2730 IDirect3DVertexBuffer9 *vb = NULL;
2731 IDirect3DIndexBuffer9 *ib = NULL;
2732 HRESULT hr;
2733 BYTE *data;
2734 long ref;
2736 static const struct vertex quad[] = {
2737 {-1.0, -1.0, 0.1, 0xffff0000},
2738 {-1.0, 1.0, 0.1, 0xffff0000},
2739 { 1.0, 1.0, 0.1, 0xffff0000},
2741 {-1.0, -1.0, 0.1, 0xff00ff00},
2742 {-1.0, 1.0, 0.1, 0xff00ff00},
2743 { 1.0, 1.0, 0.1, 0xff00ff00}
2745 short indices[] = {3, 4, 5};
2747 /* Index and vertex buffers should always be creatable */
2748 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
2749 D3DPOOL_MANAGED, &vb, NULL);
2750 ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
2751 if(!vb) {
2752 skip("Failed to create a vertex buffer\n");
2753 return;
2755 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
2756 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %s\n", DXGetErrorString9(hr));
2757 if(!ib) {
2758 skip("Failed to create an index buffer\n");
2759 return;
2762 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
2763 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
2764 memcpy(data, quad, sizeof(quad));
2765 hr = IDirect3DVertexBuffer9_Unlock(vb);
2766 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
2768 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
2769 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
2770 memcpy(data, indices, sizeof(indices));
2771 hr = IDirect3DIndexBuffer9_Unlock(ib);
2772 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
2774 hr = IDirect3DDevice9_SetIndices(device, ib);
2775 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %s\n", DXGetErrorString9(hr));
2776 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
2777 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
2778 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2779 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2781 /* Now destroy the bound index buffer and draw again */
2782 ref = IDirect3DIndexBuffer9_Release(ib);
2783 ok(ref == 0, "Index Buffer reference count is %08ld\n", ref);
2785 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
2786 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
2788 hr = IDirect3DDevice9_BeginScene(device);
2789 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2790 if(SUCCEEDED(hr))
2792 /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
2793 * making assumptions about the indices or vertices
2795 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
2796 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
2797 hr = IDirect3DDevice9_EndScene(device);
2798 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2801 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2802 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
2804 hr = IDirect3DDevice9_SetIndices(device, NULL);
2805 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2806 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
2807 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2809 /* Index buffer was already destroyed as part of the test */
2810 IDirect3DVertexBuffer9_Release(vb);
2813 static void float_texture_test(IDirect3DDevice9 *device)
2815 IDirect3D9 *d3d = NULL;
2816 HRESULT hr;
2817 IDirect3DTexture9 *texture = NULL;
2818 D3DLOCKED_RECT lr;
2819 float *data;
2820 DWORD color;
2821 float quad[] = {
2822 -1.0, -1.0, 0.1, 0.0, 0.0,
2823 -1.0, 1.0, 0.1, 0.0, 1.0,
2824 1.0, -1.0, 0.1, 1.0, 0.0,
2825 1.0, 1.0, 0.1, 1.0, 1.0,
2828 memset(&lr, 0, sizeof(lr));
2829 IDirect3DDevice9_GetDirect3D(device, &d3d);
2830 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
2831 D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
2832 skip("D3DFMT_R32F textures not supported\n");
2833 goto out;
2836 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
2837 D3DPOOL_MANAGED, &texture, NULL);
2838 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
2839 if(!texture) {
2840 skip("Failed to create R32F texture\n");
2841 goto out;
2844 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
2845 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %s\n", DXGetErrorString9(hr));
2846 data = lr.pBits;
2847 *data = 0.0;
2848 hr = IDirect3DTexture9_UnlockRect(texture, 0);
2849 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %s\n", DXGetErrorString9(hr));
2851 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2852 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2854 hr = IDirect3DDevice9_BeginScene(device);
2855 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
2856 if(SUCCEEDED(hr))
2858 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2859 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2861 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2862 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2864 hr = IDirect3DDevice9_EndScene(device);
2865 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
2867 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2868 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2870 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2871 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2873 color = getPixelColor(device, 240, 320);
2874 ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
2876 out:
2877 if(texture) IDirect3DTexture9_Release(texture);
2878 IDirect3D9_Release(d3d);
2881 static void g16r16_texture_test(IDirect3DDevice9 *device)
2883 IDirect3D9 *d3d = NULL;
2884 HRESULT hr;
2885 IDirect3DTexture9 *texture = NULL;
2886 D3DLOCKED_RECT lr;
2887 DWORD *data;
2888 DWORD color, red, green, blue;
2889 float quad[] = {
2890 -1.0, -1.0, 0.1, 0.0, 0.0,
2891 -1.0, 1.0, 0.1, 0.0, 1.0,
2892 1.0, -1.0, 0.1, 1.0, 0.0,
2893 1.0, 1.0, 0.1, 1.0, 1.0,
2896 memset(&lr, 0, sizeof(lr));
2897 IDirect3DDevice9_GetDirect3D(device, &d3d);
2898 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
2899 D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
2900 skip("D3DFMT_G16R16 textures not supported\n");
2901 goto out;
2904 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
2905 D3DPOOL_MANAGED, &texture, NULL);
2906 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
2907 if(!texture) {
2908 skip("Failed to create D3DFMT_G16R16 texture\n");
2909 goto out;
2912 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
2913 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %s\n", DXGetErrorString9(hr));
2914 data = lr.pBits;
2915 *data = 0x0f00f000;
2916 hr = IDirect3DTexture9_UnlockRect(texture, 0);
2917 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %s\n", DXGetErrorString9(hr));
2919 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2920 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2922 hr = IDirect3DDevice9_BeginScene(device);
2923 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
2924 if(SUCCEEDED(hr))
2926 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2927 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2929 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2930 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2932 hr = IDirect3DDevice9_EndScene(device);
2933 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
2935 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2936 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2938 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2939 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2941 color = getPixelColor(device, 240, 320);
2942 red = (color & 0x00ff0000) >> 16;
2943 green = (color & 0x0000ff00) >> 8;
2944 blue = (color & 0x000000ff) >> 0;
2945 ok(blue == 0xff && red >= 0xef && red <= 0xf1 && green >= 0x0e && green <= 0x10,
2946 "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00F00FFF\n", color);
2948 out:
2949 if(texture) IDirect3DTexture9_Release(texture);
2950 IDirect3D9_Release(d3d);
2953 static void texture_transform_flags_test(IDirect3DDevice9 *device)
2955 HRESULT hr;
2956 IDirect3D9 *d3d;
2957 D3DFORMAT fmt = D3DFMT_X8R8G8B8;
2958 D3DCAPS9 caps;
2959 IDirect3DTexture9 *texture = NULL;
2960 IDirect3DVolumeTexture9 *volume = NULL;
2961 unsigned int x, y, z;
2962 D3DLOCKED_RECT lr;
2963 D3DLOCKED_BOX lb;
2964 DWORD color;
2965 IDirect3DVertexDeclaration9 *decl, *decl2, *decl3;
2966 float identity[16] = {1.0, 0.0, 0.0, 0.0,
2967 0.0, 1.0, 0.0, 0.0,
2968 0.0, 0.0, 1.0, 0.0,
2969 0.0, 0.0, 0.0, 1.0};
2970 static const D3DVERTEXELEMENT9 decl_elements[] = {
2971 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2972 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2973 D3DDECL_END()
2975 static const D3DVERTEXELEMENT9 decl_elements2[] = {
2976 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2977 {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2978 D3DDECL_END()
2980 static const D3DVERTEXELEMENT9 decl_elements3[] = {
2981 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2982 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2983 D3DDECL_END()
2985 static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
2986 0x00, 0xff, 0x00, 0x00,
2987 0x00, 0x00, 0x00, 0x00,
2988 0x00, 0x00, 0x00, 0x00};
2990 memset(&lr, 0, sizeof(lr));
2991 memset(&lb, 0, sizeof(lb));
2992 IDirect3DDevice9_GetDirect3D(device, &d3d);
2993 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
2994 D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
2995 fmt = D3DFMT_A16B16G16R16;
2997 IDirect3D9_Release(d3d);
2999 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3000 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
3001 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
3002 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
3003 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
3004 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
3005 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
3006 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %s\n", DXGetErrorString9(hr));
3007 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
3008 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %s\n", DXGetErrorString9(hr));
3009 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
3010 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %s\n", DXGetErrorString9(hr));
3011 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3012 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %s\n", DXGetErrorString9(hr));
3013 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3014 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %s\n", DXGetErrorString9(hr));
3015 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3016 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %s\n", DXGetErrorString9(hr));
3017 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
3018 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %s\n", DXGetErrorString9(hr));
3019 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3020 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %s\n", DXGetErrorString9(hr));
3021 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3022 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3024 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3025 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %s\n", DXGetErrorString9(hr));
3026 hr = IDirect3DDevice9_CreateTexture(device, caps.MaxTextureWidth, caps.MaxTextureHeight, 1,
3027 0, fmt, D3DPOOL_MANAGED, &texture, NULL);
3028 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %s\n", DXGetErrorString9(hr));
3029 if(!texture) {
3030 skip("Failed to create the test texture\n");
3031 return;
3034 /* Unfortunately there is no easy way to set up a texture coordinate passthrough
3035 * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
3036 * 1.0 in red and green for the x and y coords
3038 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3039 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %s\n", DXGetErrorString9(hr));
3040 for(y = 0; y < caps.MaxTextureHeight; y++) {
3041 for(x = 0; x < caps.MaxTextureWidth; x++) {
3042 double r_f = (double) y / (double) caps.MaxTextureHeight;
3043 double g_f = (double) x / (double) caps.MaxTextureWidth;
3044 if(fmt == D3DFMT_A16B16G16R16) {
3045 unsigned short r, g;
3046 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
3047 r = (unsigned short) (r_f * 65536.0);
3048 g = (unsigned short) (g_f * 65536.0);
3049 dst[0] = r;
3050 dst[1] = g;
3051 dst[2] = 0;
3052 dst[3] = 65535;
3053 } else {
3054 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
3055 unsigned char r = (unsigned char) (r_f * 255.0);
3056 unsigned char g = (unsigned char) (g_f * 255.0);
3057 dst[0] = 0;
3058 dst[1] = g;
3059 dst[2] = r;
3060 dst[3] = 255;
3064 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3065 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %s\n", DXGetErrorString9(hr));
3066 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3067 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
3069 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3070 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
3071 hr = IDirect3DDevice9_BeginScene(device);
3072 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
3073 if(SUCCEEDED(hr))
3075 float quad1[] = {
3076 -1.0, -1.0, 0.1, 1.0, 1.0,
3077 -1.0, 0.0, 0.1, 1.0, 1.0,
3078 0.0, -1.0, 0.1, 1.0, 1.0,
3079 0.0, 0.0, 0.1, 1.0, 1.0,
3081 float quad2[] = {
3082 -1.0, 0.0, 0.1, 1.0, 1.0,
3083 -1.0, 1.0, 0.1, 1.0, 1.0,
3084 0.0, 0.0, 0.1, 1.0, 1.0,
3085 0.0, 1.0, 0.1, 1.0, 1.0,
3087 float quad3[] = {
3088 0.0, 0.0, 0.1, 0.5, 0.5,
3089 0.0, 1.0, 0.1, 0.5, 0.5,
3090 1.0, 0.0, 0.1, 0.5, 0.5,
3091 1.0, 1.0, 0.1, 0.5, 0.5,
3093 float quad4[] = {
3094 320, 480, 0.1, 1.0, 0.0, 1.0,
3095 320, 240, 0.1, 1.0, 0.0, 1.0,
3096 640, 480, 0.1, 1.0, 0.0, 1.0,
3097 640, 240, 0.1, 1.0, 0.0, 1.0,
3099 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3100 0.0, 0.0, 0.0, 0.0,
3101 0.0, 0.0, 0.0, 0.0,
3102 0.0, 0.0, 0.0, 0.0};
3104 /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
3105 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3106 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3107 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3108 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3110 /* What happens with transforms enabled? */
3111 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3112 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3113 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3114 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3116 /* What happens if 4 coords are used, but only 2 given ?*/
3117 mat[8] = 1.0;
3118 mat[13] = 1.0;
3119 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3120 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3121 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3122 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3123 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3124 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3126 /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
3127 * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
3128 * due to the coords in the vertices. (turns out red, indeed)
3130 memset(mat, 0, sizeof(mat));
3131 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3132 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3133 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
3134 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3135 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3136 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
3137 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3138 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3140 hr = IDirect3DDevice9_EndScene(device);
3141 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
3143 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3144 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3145 color = getPixelColor(device, 160, 360);
3146 ok(color == 0x00FFFF00 || color == 0x00FEFE00, "quad 1 has color %08x, expected 0x00FFFF00\n", color);
3147 color = getPixelColor(device, 160, 120);
3148 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3149 color = getPixelColor(device, 480, 120);
3150 ok(color == 0x0000FF00 || color == 0x0000FE00, "quad 3 has color %08x, expected 0x0000FF00\n", color);
3151 color = getPixelColor(device, 480, 360);
3152 ok(color == 0x00FF0000 || 0x00FE0000, "quad 4 has color %08x, expected 0x00FF0000\n", color);
3154 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3155 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3157 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3158 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
3159 hr = IDirect3DDevice9_BeginScene(device);
3160 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
3161 if(SUCCEEDED(hr))
3163 float quad1[] = {
3164 -1.0, -1.0, 0.1, 0.8, 0.2,
3165 -1.0, 0.0, 0.1, 0.8, 0.2,
3166 0.0, -1.0, 0.1, 0.8, 0.2,
3167 0.0, 0.0, 0.1, 0.8, 0.2,
3169 float quad2[] = {
3170 -1.0, 0.0, 0.1, 0.5, 1.0,
3171 -1.0, 1.0, 0.1, 0.5, 1.0,
3172 0.0, 0.0, 0.1, 0.5, 1.0,
3173 0.0, 1.0, 0.1, 0.5, 1.0,
3175 float quad3[] = {
3176 0.0, 0.0, 0.1, 0.5, 1.0,
3177 0.0, 1.0, 0.1, 0.5, 1.0,
3178 1.0, 0.0, 0.1, 0.5, 1.0,
3179 1.0, 1.0, 0.1, 0.5, 1.0,
3181 float quad4[] = {
3182 0.0, -1.0, 0.1, 0.8, 0.2,
3183 0.0, 0.0, 0.1, 0.8, 0.2,
3184 1.0, -1.0, 0.1, 0.8, 0.2,
3185 1.0, 0.0, 0.1, 0.8, 0.2,
3187 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3188 0.0, 0.0, 0.0, 0.0,
3189 0.0, 1.0, 0.0, 0.0,
3190 0.0, 0.0, 0.0, 0.0};
3192 /* What happens to the default 1 in the 3rd coordinate if it is disabled?
3194 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3195 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3196 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3197 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3199 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3200 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3202 /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
3203 * it behaves like COUNT2 because normal textures require 2 coords
3205 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3206 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3207 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
3208 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3210 /* Just to be sure, the same as quad2 above */
3211 memset(mat, 0, sizeof(mat));
3212 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3213 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3214 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3215 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3216 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3217 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3219 /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
3220 * used? And what happens to the first?
3222 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3223 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3224 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3225 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3227 hr = IDirect3DDevice9_EndScene(device);
3228 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
3230 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3231 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3232 color = getPixelColor(device, 160, 360);
3233 ok(color == 0x00FF0000 || color == 0x00FE0000, "quad 1 has color %08x, expected 0x00FF0000\n", color);
3234 color = getPixelColor(device, 160, 120);
3235 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3236 color = getPixelColor(device, 480, 120);
3237 ok(color == 0x00ff8000 || color == 0x00fe7f00 || color == 0x00000000,
3238 "quad 3 has color %08x, expected 0x00ff8000\n", color);
3239 color = getPixelColor(device, 480, 360);
3240 ok(color == 0x0033cc00 || color == 0x0032cb00 || color == 0x00FF0000 || color == 0x00FE0000,
3241 "quad 4 has color %08x, expected 0x0033cc00\n", color);
3243 IDirect3DTexture9_Release(texture);
3245 /* Test projected textures, without any fancy matrices */
3246 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3247 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3248 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
3249 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %s\n", DXGetErrorString9(hr));
3250 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3251 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3252 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl3);
3253 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
3255 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3256 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %s\n", DXGetErrorString9(hr));
3257 for(x = 0; x < 4; x++) {
3258 memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
3260 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3261 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %s\n", DXGetErrorString9(hr));
3262 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3263 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
3265 hr = IDirect3DDevice9_BeginScene(device);
3266 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
3267 if(SUCCEEDED(hr))
3269 const float proj_quads[] = {
3270 -1.0, -1.0, 0.1, 0.0, 0.0, 4.0, 6.0,
3271 1.0, -1.0, 0.1, 4.0, 0.0, 4.0, 6.0,
3272 -1.0, 0.0, 0.1, 0.0, 4.0, 4.0, 6.0,
3273 1.0, 0.0, 0.1, 4.0, 4.0, 4.0, 6.0,
3274 -1.0, 0.0, 0.1, 0.0, 0.0, 4.0, 6.0,
3275 1.0, 0.0, 0.1, 4.0, 0.0, 4.0, 6.0,
3276 -1.0, 1.0, 0.1, 0.0, 4.0, 4.0, 6.0,
3277 1.0, 1.0, 0.1, 4.0, 4.0, 4.0, 6.0,
3280 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3281 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3282 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[0*7], 7 * sizeof(float));
3283 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3285 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED);
3286 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3287 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[4*7], 7 * sizeof(float));
3288 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3290 hr = IDirect3DDevice9_EndScene(device);
3291 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
3294 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3295 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
3296 IDirect3DTexture9_Release(texture);
3298 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3299 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3300 color = getPixelColor(device, 158, 118);
3301 ok(color == 0x00000000, "proj: Pixel 158/118 has color 0x%08x, expected 0x00000000\n", color);
3302 color = getPixelColor(device, 162, 118);
3303 ok(color == 0x00000000, "proj: Pixel 162/118 has color 0x%08x, expected 0x00000000\n", color);
3304 color = getPixelColor(device, 158, 122);
3305 ok(color == 0x00000000, "proj: Pixel 158/122 has color 0x%08x, expected 0x00000000\n", color);
3306 color = getPixelColor(device, 162, 122);
3307 ok(color == 0x00FFFFFF, "proj: Pixel 162/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3309 color = getPixelColor(device, 158, 178);
3310 ok(color == 0x00000000, "proj: Pixel 158/178 has color 0x%08x, expected 0x00000000\n", color);
3311 color = getPixelColor(device, 162, 178);
3312 ok(color == 0x00FFFFFF, "proj: Pixel 158/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3313 color = getPixelColor(device, 158, 182);
3314 ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3315 color = getPixelColor(device, 162, 182);
3316 ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3318 color = getPixelColor(device, 318, 118);
3319 ok(color == 0x00000000, "proj: Pixel 318/118 has color 0x%08x, expected 0x00000000\n", color);
3320 color = getPixelColor(device, 322, 118);
3321 ok(color == 0x00000000, "proj: Pixel 322/118 has color 0x%08x, expected 0x00000000\n", color);
3322 color = getPixelColor(device, 318, 122);
3323 ok(color == 0x00FFFFFF, "proj: Pixel 318/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3324 color = getPixelColor(device, 322, 122);
3325 ok(color == 0x00000000, "proj: Pixel 322/122 has color 0x%08x, expected 0x00000000\n", color);
3327 color = getPixelColor(device, 318, 178);
3328 ok(color == 0x00FFFFFF, "proj: Pixel 318/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3329 color = getPixelColor(device, 322, 178);
3330 ok(color == 0x00000000, "proj: Pixel 322/178 has color 0x%08x, expected 0x00000000\n", color);
3331 color = getPixelColor(device, 318, 182);
3332 ok(color == 0x00000000, "proj: Pixel 318/182 has color 0x%08x, expected 0x00000000\n", color);
3333 color = getPixelColor(device, 322, 182);
3334 ok(color == 0x00000000, "proj: Pixel 322/182 has color 0x%08x, expected 0x00000000\n", color);
3336 color = getPixelColor(device, 238, 298);
3337 ok(color == 0x00000000, "proj: Pixel 238/298 has color 0x%08x, expected 0x00000000\n", color);
3338 color = getPixelColor(device, 242, 298);
3339 ok(color == 0x00000000, "proj: Pixel 242/298 has color 0x%08x, expected 0x00000000\n", color);
3340 color = getPixelColor(device, 238, 302);
3341 ok(color == 0x00000000, "proj: Pixel 238/302 has color 0x%08x, expected 0x00000000\n", color);
3342 color = getPixelColor(device, 242, 302);
3343 ok(color == 0x00FFFFFF, "proj: Pixel 242/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3345 color = getPixelColor(device, 238, 388);
3346 ok(color == 0x00000000, "proj: Pixel 238/388 has color 0x%08x, expected 0x00000000\n", color);
3347 color = getPixelColor(device, 242, 388);
3348 ok(color == 0x00FFFFFF, "proj: Pixel 242/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3349 color = getPixelColor(device, 238, 392);
3350 ok(color == 0x00000000, "proj: Pixel 238/392 has color 0x%08x, expected 0x00000000\n", color);
3351 color = getPixelColor(device, 242, 392);
3352 ok(color == 0x00000000, "proj: Pixel 242/392 has color 0x%08x, expected 0x00000000\n", color);
3354 color = getPixelColor(device, 478, 298);
3355 ok(color == 0x00000000, "proj: Pixel 478/298 has color 0x%08x, expected 0x00000000\n", color);
3356 color = getPixelColor(device, 482, 298);
3357 ok(color == 0x00000000, "proj: Pixel 482/298 has color 0x%08x, expected 0x00000000\n", color);
3358 color = getPixelColor(device, 478, 302);
3359 ok(color == 0x00FFFFFF, "proj: Pixel 478/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3360 color = getPixelColor(device, 482, 302);
3361 ok(color == 0x00000000, "proj: Pixel 482/302 has color 0x%08x, expected 0x00000000\n", color);
3363 color = getPixelColor(device, 478, 388);
3364 ok(color == 0x00FFFFFF, "proj: Pixel 478/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3365 color = getPixelColor(device, 482, 388);
3366 ok(color == 0x00000000, "proj: Pixel 482/388 has color 0x%08x, expected 0x00000000\n", color);
3367 color = getPixelColor(device, 478, 392);
3368 ok(color == 0x00000000, "proj: Pixel 478/392 has color 0x%08x, expected 0x00000000\n", color);
3369 color = getPixelColor(device, 482, 392);
3370 ok(color == 0x00000000, "proj: Pixel 482/392 has color 0x%08x, expected 0x00000000\n", color);
3372 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3373 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3374 /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
3375 * Thus watch out if sampling from texels between 0 and 1.
3377 hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
3378 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
3379 "IDirect3DDevice9_CreateVolumeTexture failed with %s\n", DXGetErrorString9(hr));
3380 if(!volume) {
3381 skip("Failed to create a volume texture\n");
3382 goto out;
3385 hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
3386 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %s\n", DXGetErrorString9(hr));
3387 for(z = 0; z < 32; z++) {
3388 for(y = 0; y < 32; y++) {
3389 for(x = 0; x < 32; x++) {
3390 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
3391 void *mem = ((char *) lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
3392 float r_f = (float) x / 31.0;
3393 float g_f = (float) y / 31.0;
3394 float b_f = (float) z / 31.0;
3396 if(fmt == D3DFMT_A16B16G16R16) {
3397 unsigned short *mem_s = mem;
3398 mem_s[0] = r_f * 65535.0;
3399 mem_s[1] = g_f * 65535.0;
3400 mem_s[2] = b_f * 65535.0;
3401 mem_s[3] = 65535;
3402 } else {
3403 unsigned char *mem_c = mem;
3404 mem_c[0] = b_f * 255.0;
3405 mem_c[1] = g_f * 255.0;
3406 mem_c[2] = r_f * 255.0;
3407 mem_c[3] = 255;
3412 hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
3413 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %s\n", DXGetErrorString9(hr));
3415 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
3416 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %s\n", DXGetErrorString9(hr));
3418 hr = IDirect3DDevice9_BeginScene(device);
3419 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
3420 if(SUCCEEDED(hr))
3422 float quad1[] = {
3423 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3424 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3425 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3426 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
3428 float quad2[] = {
3429 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3430 -1.0, 1.0, 0.1, 1.0, 1.0, 1.0,
3431 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3432 0.0, 1.0, 0.1, 1.0, 1.0, 1.0
3434 float quad3[] = {
3435 0.0, 0.0, 0.1, 0.0, 0.0,
3436 0.0, 1.0, 0.1, 0.0, 0.0,
3437 1.0, 0.0, 0.1, 0.0, 0.0,
3438 1.0, 1.0, 0.1, 0.0, 0.0
3440 float quad4[] = {
3441 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3442 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3443 1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3444 1.0, 0.0, 0.1, 1.0, 1.0, 1.0
3446 float mat[16] = {1.0, 0.0, 0.0, 0.0,
3447 0.0, 0.0, 1.0, 0.0,
3448 0.0, 1.0, 0.0, 0.0,
3449 0.0, 0.0, 0.0, 1.0};
3450 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3451 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
3453 /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
3454 * values
3456 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3457 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3458 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3459 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3460 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3461 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3463 /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
3464 * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
3465 * otherwise the w will be missing(blue).
3466 * turns out that on nvidia cards the blue color is missing, so it is an output modification.
3467 * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
3469 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3470 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3471 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
3472 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3474 /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 4 */
3475 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3476 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3477 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3478 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3479 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3480 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
3481 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3482 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3484 /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
3485 * disable. ATI extends it up to the amount of values needed for the volume texture
3487 memset(mat, 0, sizeof(mat));
3488 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3489 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3490 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3491 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3492 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3493 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
3494 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3495 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3497 hr = IDirect3DDevice9_EndScene(device);
3498 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
3500 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3501 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3503 color = getPixelColor(device, 160, 360);
3504 ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
3505 color = getPixelColor(device, 160, 120);
3506 ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
3507 "quad 2 has color %08x, expected 0x00ffff00\n", color);
3508 color = getPixelColor(device, 480, 120);
3509 ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
3510 color = getPixelColor(device, 480, 360);
3511 ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
3513 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
3514 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3515 hr = IDirect3DDevice9_BeginScene(device);
3516 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
3517 if(SUCCEEDED(hr))
3519 float quad1[] = {
3520 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3521 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3522 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3523 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
3525 float quad2[] = {
3526 -1.0, 0.0, 0.1,
3527 -1.0, 1.0, 0.1,
3528 0.0, 0.0, 0.1,
3529 0.0, 1.0, 0.1,
3531 float quad3[] = {
3532 0.0, 0.0, 0.1, 1.0,
3533 0.0, 1.0, 0.1, 1.0,
3534 1.0, 0.0, 0.1, 1.0,
3535 1.0, 1.0, 0.1, 1.0
3537 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3538 0.0, 0.0, 0.0, 0.0,
3539 0.0, 0.0, 0.0, 0.0,
3540 0.0, 1.0, 0.0, 0.0};
3541 float mat2[16] = {0.0, 0.0, 0.0, 1.0,
3542 1.0, 0.0, 0.0, 0.0,
3543 0.0, 1.0, 0.0, 0.0,
3544 0.0, 0.0, 1.0, 0.0};
3545 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3546 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
3548 /* Default values? 4 coords used, 3 passed. What happens to the 4th?
3550 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3551 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3552 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3553 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3554 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3555 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3557 /* None passed */
3558 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3559 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3560 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3561 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
3562 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
3563 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3565 /* 4 used, 1 passed */
3566 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
3567 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
3568 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
3569 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3570 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
3571 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3573 hr = IDirect3DDevice9_EndScene(device);
3574 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
3576 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3577 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3578 color = getPixelColor(device, 160, 360);
3579 ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
3580 color = getPixelColor(device, 160, 120);
3581 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
3582 color = getPixelColor(device, 480, 120);
3583 ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
3584 /* Quad4: unused */
3586 IDirect3DVolumeTexture9_Release(volume);
3588 out:
3589 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
3590 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
3591 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
3592 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3593 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3594 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3595 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3596 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
3597 IDirect3DVertexDeclaration9_Release(decl);
3598 IDirect3DVertexDeclaration9_Release(decl2);
3599 IDirect3DVertexDeclaration9_Release(decl3);
3602 static void texdepth_test(IDirect3DDevice9 *device)
3604 IDirect3DPixelShader9 *shader;
3605 HRESULT hr;
3606 const float texdepth_test_data1[] = { 0.25, 2.0, 0.0, 0.0};
3607 const float texdepth_test_data2[] = { 0.25, 0.5, 0.0, 0.0};
3608 const float texdepth_test_data3[] = {-1.00, 0.1, 0.0, 0.0};
3609 const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
3610 const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
3611 const float texdepth_test_data6[] = { 1.00, 0.5, 0.0, 0.0};
3612 const float texdepth_test_data7[] = { 0.50, 0.0, 0.0, 0.0};
3613 DWORD shader_code[] = {
3614 0xffff0104, /* ps_1_4 */
3615 0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c1, 0, 0, 1, 1 */
3616 0x00000001, 0x800f0005, 0xa0e40000, /* mov r5, c0 */
3617 0x0000fffd, /* phase */
3618 0x00000057, 0x800f0005, /* texdepth r5 */
3619 0x00000001, 0x800f0000, 0xa0e40001, /* mov r0, c1 */
3620 0x0000ffff /* end */
3622 DWORD color;
3623 float vertex[] = {
3624 -1.0, -1.0, 0.0,
3625 1.0, -1.0, 1.0,
3626 -1.0, 1.0, 0.0,
3627 1.0, 1.0, 1.0
3630 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
3631 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3633 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
3634 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3635 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3636 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3637 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3638 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3639 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
3640 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3641 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3643 /* Fill the depth buffer with a gradient */
3644 hr = IDirect3DDevice9_BeginScene(device);
3645 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3646 if(SUCCEEDED(hr))
3648 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3649 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3650 hr = IDirect3DDevice9_EndScene(device);
3651 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3654 /* Now perform the actual tests. Same geometry, but with the shader */
3655 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
3656 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3657 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3658 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3659 hr = IDirect3DDevice9_SetPixelShader(device, shader);
3660 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3662 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
3663 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3664 hr = IDirect3DDevice9_BeginScene(device);
3665 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3666 if(SUCCEEDED(hr))
3668 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3669 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3671 hr = IDirect3DDevice9_EndScene(device);
3672 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3675 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3676 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3677 color = getPixelColor(device, 158, 240);
3678 ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3679 color = getPixelColor(device, 162, 240);
3680 ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
3682 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3684 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
3685 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3686 hr = IDirect3DDevice9_BeginScene(device);
3687 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3688 if(SUCCEEDED(hr))
3690 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3691 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3693 hr = IDirect3DDevice9_EndScene(device);
3694 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3697 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3698 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3699 color = getPixelColor(device, 318, 240);
3700 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3701 color = getPixelColor(device, 322, 240);
3702 ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3704 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3706 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
3707 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3708 hr = IDirect3DDevice9_BeginScene(device);
3709 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3710 if(SUCCEEDED(hr))
3712 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3713 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3715 hr = IDirect3DDevice9_EndScene(device);
3716 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3718 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3719 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3721 color = getPixelColor(device, 1, 240);
3722 ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
3724 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3726 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
3727 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3728 hr = IDirect3DDevice9_BeginScene(device);
3729 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3730 if(SUCCEEDED(hr))
3732 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3733 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3735 hr = IDirect3DDevice9_EndScene(device);
3736 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3738 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3739 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3740 color = getPixelColor(device, 318, 240);
3741 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3742 color = getPixelColor(device, 322, 240);
3743 ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
3745 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3747 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
3748 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3749 hr = IDirect3DDevice9_BeginScene(device);
3750 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3751 if(SUCCEEDED(hr))
3753 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3754 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3756 hr = IDirect3DDevice9_EndScene(device);
3757 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3759 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3760 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3762 color = getPixelColor(device, 1, 240);
3763 ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3765 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3767 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
3768 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3769 hr = IDirect3DDevice9_BeginScene(device);
3770 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3771 if(SUCCEEDED(hr))
3773 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3774 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3776 hr = IDirect3DDevice9_EndScene(device);
3777 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3779 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3780 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3782 color = getPixelColor(device, 638, 240);
3783 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
3785 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3787 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
3788 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3789 hr = IDirect3DDevice9_BeginScene(device);
3790 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3791 if(SUCCEEDED(hr))
3793 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3794 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3796 hr = IDirect3DDevice9_EndScene(device);
3797 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3799 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3800 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3802 color = getPixelColor(device, 638, 240);
3803 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
3805 /* Cleanup */
3806 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3807 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3808 IDirect3DPixelShader9_Release(shader);
3810 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
3811 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3812 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3813 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3816 static void texkill_test(IDirect3DDevice9 *device)
3818 IDirect3DPixelShader9 *shader;
3819 HRESULT hr;
3820 DWORD color;
3822 const float vertex[] = {
3823 /* bottom top right left */
3824 -1.0, -1.0, 1.0, -0.1, 0.9, 0.9, -0.1,
3825 1.0, -1.0, 0.0, 0.9, -0.1, 0.9, -0.1,
3826 -1.0, 1.0, 1.0, -0.1, 0.9, -0.1, 0.9,
3827 1.0, 1.0, 0.0, 0.9, -0.1, -0.1, 0.9,
3830 DWORD shader_code_11[] = {
3831 0xffff0101, /* ps_1_1 */
3832 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
3833 0x00000041, 0xb00f0000, /* texkill t0 */
3834 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
3835 0x0000ffff /* end */
3837 DWORD shader_code_20[] = {
3838 0xffff0200, /* ps_2_0 */
3839 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
3840 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
3841 0x01000041, 0xb00f0000, /* texkill t0 */
3842 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
3843 0x0000ffff /* end */
3846 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3847 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3848 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
3849 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3851 hr = IDirect3DDevice9_SetPixelShader(device, shader);
3852 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3853 hr = IDirect3DDevice9_BeginScene(device);
3854 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3855 if(SUCCEEDED(hr))
3857 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
3858 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
3859 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
3860 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3861 hr = IDirect3DDevice9_EndScene(device);
3862 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3864 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3865 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3866 color = getPixelColor(device, 63, 46);
3867 ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
3868 color = getPixelColor(device, 66, 46);
3869 ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
3870 color = getPixelColor(device, 63, 49);
3871 ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
3872 color = getPixelColor(device, 66, 49);
3873 ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
3875 color = getPixelColor(device, 578, 46);
3876 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3877 color = getPixelColor(device, 575, 46);
3878 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3879 color = getPixelColor(device, 578, 49);
3880 ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
3881 color = getPixelColor(device, 575, 49);
3882 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3884 color = getPixelColor(device, 63, 430);
3885 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3886 color = getPixelColor(device, 63, 433);
3887 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3888 color = getPixelColor(device, 66, 433);
3889 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
3890 color = getPixelColor(device, 66, 430);
3891 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3893 color = getPixelColor(device, 578, 430);
3894 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3895 color = getPixelColor(device, 578, 433);
3896 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3897 color = getPixelColor(device, 575, 433);
3898 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
3899 color = getPixelColor(device, 575, 430);
3900 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3902 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3903 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3904 IDirect3DPixelShader9_Release(shader);
3906 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3907 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3908 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
3909 if(FAILED(hr)) {
3910 skip("Failed to create 2.0 test shader, most likely not supported\n");
3911 return;
3914 hr = IDirect3DDevice9_SetPixelShader(device, shader);
3915 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3916 hr = IDirect3DDevice9_BeginScene(device);
3917 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3918 if(SUCCEEDED(hr))
3920 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
3921 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3922 hr = IDirect3DDevice9_EndScene(device);
3923 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3925 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3927 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3928 color = getPixelColor(device, 63, 46);
3929 ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
3930 color = getPixelColor(device, 66, 46);
3931 ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
3932 color = getPixelColor(device, 63, 49);
3933 ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
3934 color = getPixelColor(device, 66, 49);
3935 ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
3937 color = getPixelColor(device, 578, 46);
3938 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
3939 color = getPixelColor(device, 575, 46);
3940 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
3941 color = getPixelColor(device, 578, 49);
3942 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
3943 color = getPixelColor(device, 575, 49);
3944 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
3946 color = getPixelColor(device, 63, 430);
3947 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
3948 color = getPixelColor(device, 63, 433);
3949 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
3950 color = getPixelColor(device, 66, 433);
3951 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
3952 color = getPixelColor(device, 66, 430);
3953 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
3955 color = getPixelColor(device, 578, 430);
3956 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
3957 color = getPixelColor(device, 578, 433);
3958 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
3959 color = getPixelColor(device, 575, 433);
3960 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
3961 color = getPixelColor(device, 575, 430);
3962 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
3964 /* Cleanup */
3965 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3966 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
3967 IDirect3DPixelShader9_Release(shader);
3970 static void x8l8v8u8_test(IDirect3DDevice9 *device)
3972 IDirect3D9 *d3d9;
3973 HRESULT hr;
3974 IDirect3DTexture9 *texture;
3975 IDirect3DPixelShader9 *shader;
3976 IDirect3DPixelShader9 *shader2;
3977 D3DLOCKED_RECT lr;
3978 DWORD color;
3979 DWORD shader_code[] = {
3980 0xffff0101, /* ps_1_1 */
3981 0x00000042, 0xb00f0000, /* tex t0 */
3982 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
3983 0x0000ffff /* end */
3985 DWORD shader_code2[] = {
3986 0xffff0101, /* ps_1_1 */
3987 0x00000042, 0xb00f0000, /* tex t0 */
3988 0x00000001, 0x800f0000, 0xb0ff0000, /* mov r0, t0.w */
3989 0x0000ffff /* end */
3992 float quad[] = {
3993 -1.0, -1.0, 0.1, 0.5, 0.5,
3994 1.0, -1.0, 0.1, 0.5, 0.5,
3995 -1.0, 1.0, 0.1, 0.5, 0.5,
3996 1.0, 1.0, 0.1, 0.5, 0.5,
3999 memset(&lr, 0, sizeof(lr));
4000 IDirect3DDevice9_GetDirect3D(device, &d3d9);
4001 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4002 0, D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
4003 IDirect3D9_Release(d3d9);
4004 if(FAILED(hr)) {
4005 skip("No D3DFMT_X8L8V8U8 support\n");
4008 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4009 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4011 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
4012 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
4013 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4014 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
4015 *((DWORD *) lr.pBits) = 0x11ca3141;
4016 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4017 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
4019 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4020 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4021 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
4022 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4024 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4025 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4026 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4027 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4028 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4029 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4031 hr = IDirect3DDevice9_BeginScene(device);
4032 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4033 if(SUCCEEDED(hr))
4035 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4036 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4038 hr = IDirect3DDevice9_EndScene(device);
4039 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4041 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4042 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4043 color = getPixelColor(device, 578, 430);
4044 ok(color == 0x008262ca || color == 0x008363ca || color == 0x008362ca,
4045 "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
4047 hr = IDirect3DDevice9_SetPixelShader(device, shader2);
4048 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4049 hr = IDirect3DDevice9_BeginScene(device);
4050 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4051 if(SUCCEEDED(hr))
4053 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4054 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4056 hr = IDirect3DDevice9_EndScene(device);
4057 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4059 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4060 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4061 color = getPixelColor(device, 578, 430);
4062 ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
4064 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4065 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4066 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4067 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4068 IDirect3DPixelShader9_Release(shader);
4069 IDirect3DPixelShader9_Release(shader2);
4070 IDirect3DTexture9_Release(texture);
4073 static void autogen_mipmap_test(IDirect3DDevice9 *device)
4075 HRESULT hr;
4076 IDirect3D9 *d3d;
4077 IDirect3DTexture9 *texture = NULL;
4078 IDirect3DSurface9 *surface;
4079 DWORD color;
4080 const RECT r1 = {256, 256, 512, 512};
4081 const RECT r2 = {512, 256, 768, 512};
4082 const RECT r3 = {256, 512, 512, 768};
4083 const RECT r4 = {512, 512, 768, 768};
4084 unsigned int x, y;
4085 D3DLOCKED_RECT lr;
4086 memset(&lr, 0, sizeof(lr));
4088 IDirect3DDevice9_GetDirect3D(device, &d3d);
4089 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4090 D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
4091 skip("No autogenmipmap support\n");
4092 IDirect3D9_Release(d3d);
4093 return;
4095 IDirect3D9_Release(d3d);
4097 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4098 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4100 /* Make the mipmap big, so that a smaller mipmap is used
4102 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
4103 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4104 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %s\n", DXGetErrorString9(hr));
4106 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4107 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %s\n", DXGetErrorString9(hr));
4108 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
4109 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %s\n", DXGetErrorString9(hr));
4110 for(y = 0; y < 1024; y++) {
4111 for(x = 0; x < 1024; x++) {
4112 DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
4113 POINT pt;
4115 pt.x = x;
4116 pt.y = y;
4117 if(PtInRect(&r1, pt)) {
4118 *dst = 0xffff0000;
4119 } else if(PtInRect(&r2, pt)) {
4120 *dst = 0xff00ff00;
4121 } else if(PtInRect(&r3, pt)) {
4122 *dst = 0xff0000ff;
4123 } else if(PtInRect(&r4, pt)) {
4124 *dst = 0xff000000;
4125 } else {
4126 *dst = 0xffffffff;
4130 hr = IDirect3DSurface9_UnlockRect(surface);
4131 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %s\n", DXGetErrorString9(hr));
4132 IDirect3DSurface9_Release(surface);
4134 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4135 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
4136 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4137 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
4139 hr = IDirect3DDevice9_BeginScene(device);
4140 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4141 if(SUCCEEDED(hr)) {
4142 const float quad[] = {
4143 -0.5, -0.5, 0.1, 0.0, 0.0,
4144 -0.5, 0.5, 0.1, 0.0, 1.0,
4145 0.5, -0.5, 0.1, 1.0, 0.0,
4146 0.5, 0.5, 0.1, 1.0, 1.0
4149 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4150 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
4151 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4152 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4153 hr = IDirect3DDevice9_EndScene(device);
4154 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4156 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4157 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
4158 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4159 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
4160 IDirect3DTexture9_Release(texture);
4162 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4163 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4164 color = getPixelColor(device, 200, 200);
4165 ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
4166 color = getPixelColor(device, 280, 200);
4167 ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
4168 color = getPixelColor(device, 360, 200);
4169 ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
4170 color = getPixelColor(device, 440, 200);
4171 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4172 color = getPixelColor(device, 200, 270);
4173 ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
4174 color = getPixelColor(device, 280, 270);
4175 ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
4176 color = getPixelColor(device, 360, 270);
4177 ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
4178 color = getPixelColor(device, 440, 270);
4179 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4182 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
4184 IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
4185 IDirect3DVertexDeclaration9 *decl;
4186 HRESULT hr;
4187 DWORD color;
4188 DWORD shader_code_11[] = {
4189 0xfffe0101, /* vs_1_1 */
4190 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4191 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4192 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4193 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4194 0x0000ffff /* end */
4196 DWORD shader_code_11_2[] = {
4197 0xfffe0101, /* vs_1_1 */
4198 0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
4199 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
4200 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4201 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4202 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4203 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4204 0x0000ffff /* end */
4206 DWORD shader_code_20[] = {
4207 0xfffe0200, /* vs_2_0 */
4208 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4209 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4210 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4211 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4212 0x0000ffff /* end */
4214 DWORD shader_code_20_2[] = {
4215 0xfffe0200, /* vs_2_0 */
4216 0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
4217 0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
4218 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4219 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4220 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4221 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4222 0x0000ffff /* end */
4224 static const D3DVERTEXELEMENT9 decl_elements[] = {
4225 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4226 D3DDECL_END()
4228 float quad1[] = {
4229 -1.0, -1.0, 0.1,
4230 0.0, -1.0, 0.1,
4231 -1.0, 0.0, 0.1,
4232 0.0, 0.0, 0.1
4234 float quad2[] = {
4235 0.0, -1.0, 0.1,
4236 1.0, -1.0, 0.1,
4237 0.0, 0.0, 0.1,
4238 1.0, 0.0, 0.1
4240 float quad3[] = {
4241 0.0, 0.0, 0.1,
4242 1.0, 0.0, 0.1,
4243 0.0, 1.0, 0.1,
4244 1.0, 1.0, 0.1
4246 float quad4[] = {
4247 -1.0, 0.0, 0.1,
4248 0.0, 0.0, 0.1,
4249 -1.0, 1.0, 0.1,
4250 0.0, 1.0, 0.1
4252 float test_data_c1[4] = { 1.25, -0.50, -1.50, 1.0};
4253 float test_data_c2[4] = { -0.50, 1.25, 2.00, 1.0};
4255 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4256 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4258 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
4259 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
4260 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
4261 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
4262 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
4263 if(FAILED(hr)) shader_20 = NULL;
4264 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
4265 if(FAILED(hr)) shader_20_2 = NULL;
4266 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4267 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
4269 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
4270 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %s\n", DXGetErrorString9(hr));
4271 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
4272 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %s\n", DXGetErrorString9(hr));
4273 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4274 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
4276 hr = IDirect3DDevice9_BeginScene(device);
4277 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4278 if(SUCCEEDED(hr))
4280 hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
4281 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4282 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4283 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4285 hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
4286 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4287 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4288 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4290 if(shader_20) {
4291 hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
4292 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4293 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4294 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4297 if(shader_20_2) {
4298 hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
4299 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4300 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4301 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4304 hr = IDirect3DDevice9_EndScene(device);
4305 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4307 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4308 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4310 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4311 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4312 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4313 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
4315 color = getPixelColor(device, 160, 360);
4316 ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4317 "quad 1 has color %08x, expected 0x00bfbf80\n", color);
4318 color = getPixelColor(device, 480, 360);
4319 ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4320 "quad 2 has color %08x, expected 0x00bfbf80\n", color);
4321 if(shader_20) {
4322 color = getPixelColor(device, 160, 120);
4323 ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4324 "quad 3 has color %08x, expected 0x00bfbf80\n", color);
4326 if(shader_20_2) {
4327 color = getPixelColor(device, 480, 120);
4328 ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4329 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4332 IDirect3DVertexDeclaration9_Release(decl);
4333 if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
4334 if(shader_20) IDirect3DVertexShader9_Release(shader_20);
4335 IDirect3DVertexShader9_Release(shader_11_2);
4336 IDirect3DVertexShader9_Release(shader_11);
4339 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
4341 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
4342 HRESULT hr;
4343 DWORD color;
4344 DWORD shader_code_11[] = {
4345 0xffff0101, /* ps_1_1 */
4346 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4347 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4348 0x0000ffff /* end */
4350 DWORD shader_code_12[] = {
4351 0xffff0102, /* ps_1_2 */
4352 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4353 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4354 0x0000ffff /* end */
4356 /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
4357 * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
4358 * During development of this test, 1.3 shaders were verified too
4360 DWORD shader_code_14[] = {
4361 0xffff0104, /* ps_1_4 */
4362 /* Try to make one constant local. It gets clamped too, although the binary contains
4363 * the bigger numbers
4365 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
4366 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4367 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4368 0x0000ffff /* end */
4370 DWORD shader_code_20[] = {
4371 0xffff0200, /* ps_2_0 */
4372 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4373 0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4374 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4375 0x0000ffff /* end */
4377 float quad1[] = {
4378 -1.0, -1.0, 0.1,
4379 0.0, -1.0, 0.1,
4380 -1.0, 0.0, 0.1,
4381 0.0, 0.0, 0.1
4383 float quad2[] = {
4384 0.0, -1.0, 0.1,
4385 1.0, -1.0, 0.1,
4386 0.0, 0.0, 0.1,
4387 1.0, 0.0, 0.1
4389 float quad3[] = {
4390 0.0, 0.0, 0.1,
4391 1.0, 0.0, 0.1,
4392 0.0, 1.0, 0.1,
4393 1.0, 1.0, 0.1
4395 float quad4[] = {
4396 -1.0, 0.0, 0.1,
4397 0.0, 0.0, 0.1,
4398 -1.0, 1.0, 0.1,
4399 0.0, 1.0, 0.1
4401 float test_data_c1[4] = { 1.25, -0.50, -1.50, 1.0};
4402 float test_data_c2[4] = { -0.50, 1.25, 2.00, 1.0};
4404 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4405 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4407 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4408 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4409 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4410 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4411 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4412 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4413 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
4414 if(FAILED(hr)) shader_20 = NULL;
4416 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4417 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
4418 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4419 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
4420 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4421 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
4423 hr = IDirect3DDevice9_BeginScene(device);
4424 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4425 if(SUCCEEDED(hr))
4427 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4428 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4429 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4430 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4432 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4433 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4434 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4435 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4437 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4438 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4439 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4440 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4442 if(shader_20) {
4443 hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
4444 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4445 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4446 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4449 hr = IDirect3DDevice9_EndScene(device);
4450 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4452 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4453 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4455 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4456 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4458 color = getPixelColor(device, 160, 360);
4459 ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4460 "quad 1 has color %08x, expected 0x00808000\n", color);
4461 color = getPixelColor(device, 480, 360);
4462 ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4463 "quad 2 has color %08x, expected 0x00808000\n", color);
4464 color = getPixelColor(device, 480, 120);
4465 ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4466 "quad 3 has color %08x, expected 0x00808000\n", color);
4467 if(shader_20) {
4468 color = getPixelColor(device, 160, 120);
4469 ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4470 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4473 if(shader_20) IDirect3DPixelShader9_Release(shader_20);
4474 IDirect3DPixelShader9_Release(shader_14);
4475 IDirect3DPixelShader9_Release(shader_12);
4476 IDirect3DPixelShader9_Release(shader_11);
4479 static void dp2add_ps_test(IDirect3DDevice9 *device)
4481 IDirect3DPixelShader9 *shader_dp2add = NULL;
4482 IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
4483 HRESULT hr;
4484 DWORD color;
4486 /* DP2ADD is defined as: (src0.r * src1.r) + (src0.g * src1.g) + src2.
4487 * One D3D restriction of all shader instructions except SINCOS is that no more than 2
4488 * source tokens can be constants. So, for this exercise, we move contents of c0 to
4489 * r0 first.
4490 * The result here for the r,g,b components should be roughly 0.5:
4491 * (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
4492 static const DWORD shader_code_dp2add[] = {
4493 0xffff0200, /* ps_2_0 */
4494 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0 */
4496 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4497 0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add r0.rgb, r0, r0, r0.a */
4499 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
4500 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4501 0x0000ffff /* end */
4504 /* Test the _sat modifier, too. Result here should be:
4505 * DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
4506 * _SAT: ==> 1.0
4507 * ADD: (1.0 + -0.5) = 0.5
4509 static const DWORD shader_code_dp2add_sat[] = {
4510 0xffff0200, /* ps_2_0 */
4511 0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0 */
4513 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4514 0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add_sat r0.rgb, r0, r0, r0.a */
4515 0x03000002, 0x80070000, 0x80e40000, 0xa0000000, /* add r0.rgb, r0, c0.r */
4517 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
4518 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4519 0x0000ffff /* end */
4522 const float quad[] = {
4523 -1.0, -1.0, 0.1,
4524 1.0, -1.0, 0.1,
4525 -1.0, 1.0, 0.1,
4526 1.0, 1.0, 0.1
4530 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
4531 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4533 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
4534 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4536 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
4537 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4539 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4540 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
4542 if (shader_dp2add) {
4544 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
4545 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4547 hr = IDirect3DDevice9_BeginScene(device);
4548 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4549 if(SUCCEEDED(hr))
4551 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4552 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4554 hr = IDirect3DDevice9_EndScene(device);
4555 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4557 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4558 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4560 color = getPixelColor(device, 360, 240);
4561 ok(color == 0x007f7f7f || color == 0x00808080, "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4563 IDirect3DPixelShader9_Release(shader_dp2add);
4564 } else {
4565 skip("dp2add shader creation failed\n");
4568 if (shader_dp2add_sat) {
4570 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
4571 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4573 hr = IDirect3DDevice9_BeginScene(device);
4574 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4575 if(SUCCEEDED(hr))
4577 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4578 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4580 hr = IDirect3DDevice9_EndScene(device);
4581 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4583 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4584 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4586 color = getPixelColor(device, 360, 240);
4587 ok(color == 0x007f7f7f || color == 0x00808080, "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4589 IDirect3DPixelShader9_Release(shader_dp2add_sat);
4590 } else {
4591 skip("dp2add shader creation failed\n");
4594 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4595 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4598 static void cnd_test(IDirect3DDevice9 *device)
4600 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
4601 IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
4602 HRESULT hr;
4603 DWORD color;
4604 /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
4605 * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
4606 * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
4608 DWORD shader_code_11[] = {
4609 0xffff0101, /* ps_1_1 */
4610 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4611 0x00000040, 0xb00f0000, /* texcoord t0 */
4612 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, ???(t0) */
4613 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
4614 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4615 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
4616 0x0000ffff /* end */
4618 DWORD shader_code_12[] = {
4619 0xffff0102, /* ps_1_2 */
4620 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4621 0x00000040, 0xb00f0000, /* texcoord t0 */
4622 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4623 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
4624 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4625 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
4626 0x0000ffff /* end */
4628 DWORD shader_code_13[] = {
4629 0xffff0103, /* ps_1_3 */
4630 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4631 0x00000040, 0xb00f0000, /* texcoord t0 */
4632 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4633 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3, r1, r0, c0 */
4634 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4635 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
4636 0x0000ffff /* end */
4638 DWORD shader_code_14[] = {
4639 0xffff0104, /* ps_1_3 */
4640 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
4641 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
4642 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
4643 0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0, c1, c2 */
4644 0x0000ffff /* end */
4647 /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
4648 * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
4649 * set by the compiler, it was added manually after compilation. It isn't always allowed,
4650 * only if there's a mov r0.a, XXXX, and the cnd instruction writes to r0.xyz, otherwise
4651 * native CreatePixelShader returns an error.
4653 * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
4654 * The input from t0 is [0;1]. 0.5 is substracted, then we have to multiply with 2. Since
4655 * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
4656 * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
4658 DWORD shader_code_11_coissue[] = {
4659 0xffff0101, /* ps_1_1 */
4660 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4661 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4662 0x00000040, 0xb00f0000, /* texcoord t0 */
4663 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4664 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
4665 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
4666 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
4667 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4668 /* 0x40000000 = D3DSI_COISSUE */
4669 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
4670 0x0000ffff /* end */
4672 DWORD shader_code_12_coissue[] = {
4673 0xffff0102, /* ps_1_2 */
4674 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4675 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4676 0x00000040, 0xb00f0000, /* texcoord t0 */
4677 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4678 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
4679 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
4680 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
4681 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4682 /* 0x40000000 = D3DSI_COISSUE */
4683 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
4684 0x0000ffff /* end */
4686 DWORD shader_code_13_coissue[] = {
4687 0xffff0103, /* ps_1_3 */
4688 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4689 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4690 0x00000040, 0xb00f0000, /* texcoord t0 */
4691 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4692 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
4693 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
4694 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
4695 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4696 /* 0x40000000 = D3DSI_COISSUE */
4697 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
4698 0x0000ffff /* end */
4700 /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
4701 * compare against 0.5
4703 DWORD shader_code_14_coissue[] = {
4704 0xffff0104, /* ps_1_4 */
4705 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
4706 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
4707 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
4708 /* 0x40000000 = D3DSI_COISSUE */
4709 0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0, c1, c2 */
4710 0x0000ffff /* end */
4712 float quad1[] = {
4713 -1.0, -1.0, 0.1, 0.0, 0.0, 1.0,
4714 0.0, -1.0, 0.1, 1.0, 0.0, 1.0,
4715 -1.0, 0.0, 0.1, 0.0, 1.0, 0.0,
4716 0.0, 0.0, 0.1, 1.0, 1.0, 0.0
4718 float quad2[] = {
4719 0.0, -1.0, 0.1, 0.0, 0.0, 1.0,
4720 1.0, -1.0, 0.1, 1.0, 0.0, 1.0,
4721 0.0, 0.0, 0.1, 0.0, 1.0, 0.0,
4722 1.0, 0.0, 0.1, 1.0, 1.0, 0.0
4724 float quad3[] = {
4725 0.0, 0.0, 0.1, 0.0, 0.0, 1.0,
4726 1.0, 0.0, 0.1, 1.0, 0.0, 1.0,
4727 0.0, 1.0, 0.1, 0.0, 1.0, 0.0,
4728 1.0, 1.0, 0.1, 1.0, 1.0, 0.0
4730 float quad4[] = {
4731 -1.0, 0.0, 0.1, 0.0, 0.0, 1.0,
4732 0.0, 0.0, 0.1, 1.0, 0.0, 1.0,
4733 -1.0, 1.0, 0.1, 0.0, 1.0, 0.0,
4734 0.0, 1.0, 0.1, 1.0, 1.0, 0.0
4736 float test_data_c1[4] = { 0.0, 0.0, 0.0, 0.0};
4737 float test_data_c2[4] = { 1.0, 1.0, 1.0, 1.0};
4738 float test_data_c1_coi[4] = { 0.0, 1.0, 0.0, 0.0};
4739 float test_data_c2_coi[4] = { 1.0, 0.0, 1.0, 1.0};
4741 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4742 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4744 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4745 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4746 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4747 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4748 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
4749 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4750 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4751 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4752 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
4753 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4754 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
4755 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4756 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
4757 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4758 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
4759 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4761 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4762 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
4763 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4764 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
4765 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4766 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
4768 hr = IDirect3DDevice9_BeginScene(device);
4769 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4770 if(SUCCEEDED(hr))
4772 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4773 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4774 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4775 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4777 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4778 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4779 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4780 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4782 hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
4783 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4784 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
4785 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4787 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4788 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4789 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4790 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4792 hr = IDirect3DDevice9_EndScene(device);
4793 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4795 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4796 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4798 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4799 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4801 /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
4802 color = getPixelColor(device, 158, 118);
4803 ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
4804 color = getPixelColor(device, 162, 118);
4805 ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
4806 color = getPixelColor(device, 158, 122);
4807 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
4808 color = getPixelColor(device, 162, 122);
4809 ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
4811 /* 1.1 shader. All 3 components get set, based on the .w comparison */
4812 color = getPixelColor(device, 158, 358);
4813 ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
4814 color = getPixelColor(device, 162, 358);
4815 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4816 "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
4817 color = getPixelColor(device, 158, 362);
4818 ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
4819 color = getPixelColor(device, 162, 362);
4820 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4821 "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
4823 /* 1.2 shader */
4824 color = getPixelColor(device, 478, 358);
4825 ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
4826 color = getPixelColor(device, 482, 358);
4827 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4828 "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
4829 color = getPixelColor(device, 478, 362);
4830 ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
4831 color = getPixelColor(device, 482, 362);
4832 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4833 "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
4835 /* 1.3 shader */
4836 color = getPixelColor(device, 478, 118);
4837 ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
4838 color = getPixelColor(device, 482, 118);
4839 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4840 "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
4841 color = getPixelColor(device, 478, 122);
4842 ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
4843 color = getPixelColor(device, 482, 122);
4844 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4845 "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
4847 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4848 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4849 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
4850 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
4851 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
4852 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
4854 hr = IDirect3DDevice9_BeginScene(device);
4855 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4856 if(SUCCEEDED(hr))
4858 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
4859 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(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_coissue);
4864 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(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_coissue);
4869 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(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_coissue);
4874 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(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 %s\n", DXGetErrorString9(hr));
4881 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4882 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4884 /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
4885 * that we swapped the values in c1 and c2 to make the other tests return some color
4887 color = getPixelColor(device, 158, 118);
4888 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
4889 color = getPixelColor(device, 162, 118);
4890 ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
4891 color = getPixelColor(device, 158, 122);
4892 ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
4893 color = getPixelColor(device, 162, 122);
4894 ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
4896 /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected */
4897 color = getPixelColor(device, 158, 358);
4898 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4899 "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
4900 color = getPixelColor(device, 162, 358);
4901 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4902 "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
4903 color = getPixelColor(device, 158, 362);
4904 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4905 "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
4906 color = getPixelColor(device, 162, 362);
4907 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4908 "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
4910 /* 1.2 shader */
4911 color = getPixelColor(device, 478, 358);
4912 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4913 "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
4914 color = getPixelColor(device, 482, 358);
4915 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4916 "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
4917 color = getPixelColor(device, 478, 362);
4918 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4919 "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
4920 color = getPixelColor(device, 482, 362);
4921 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4922 "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
4924 /* 1.3 shader */
4925 color = getPixelColor(device, 478, 118);
4926 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4927 "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
4928 color = getPixelColor(device, 482, 118);
4929 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4930 "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
4931 color = getPixelColor(device, 478, 122);
4932 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4933 "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
4934 color = getPixelColor(device, 482, 122);
4935 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4936 "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
4938 IDirect3DPixelShader9_Release(shader_14_coissue);
4939 IDirect3DPixelShader9_Release(shader_13_coissue);
4940 IDirect3DPixelShader9_Release(shader_12_coissue);
4941 IDirect3DPixelShader9_Release(shader_11_coissue);
4942 IDirect3DPixelShader9_Release(shader_14);
4943 IDirect3DPixelShader9_Release(shader_13);
4944 IDirect3DPixelShader9_Release(shader_12);
4945 IDirect3DPixelShader9_Release(shader_11);
4948 static void nested_loop_test(IDirect3DDevice9 *device) {
4949 const DWORD shader_code[] = {
4950 0xffff0300, /* ps_3_0 */
4951 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
4952 0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
4953 0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0 */
4954 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4955 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
4956 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
4957 0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001, /* add r0, r0, c1 */
4958 0x0000001d, /* endloop */
4959 0x0000001d, /* endloop */
4960 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4961 0x0000ffff /* end */
4963 IDirect3DPixelShader9 *shader;
4964 HRESULT hr;
4965 DWORD color;
4966 const float quad[] = {
4967 -1.0, -1.0, 0.1,
4968 1.0, -1.0, 0.1,
4969 -1.0, 1.0, 0.1,
4970 1.0, 1.0, 0.1
4973 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4974 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %s\n", DXGetErrorString9(hr));
4975 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4976 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %s\n", DXGetErrorString9(hr));
4977 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4978 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
4979 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
4980 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4982 hr = IDirect3DDevice9_BeginScene(device);
4983 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4984 if(SUCCEEDED(hr))
4986 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4987 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4988 hr = IDirect3DDevice9_EndScene(device);
4989 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4991 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4992 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4994 color = getPixelColor(device, 360, 240);
4995 ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
4996 "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
4998 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4999 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %s\n", DXGetErrorString9(hr));
5000 IDirect3DPixelShader9_Release(shader);
5003 struct varying_test_struct
5005 const DWORD *shader_code;
5006 IDirect3DPixelShader9 *shader;
5007 DWORD color, color_rhw;
5008 const char *name;
5009 BOOL todo, todo_rhw;
5012 struct hugeVertex
5014 float pos_x, pos_y, pos_z, rhw;
5015 float weight_1, weight_2, weight_3, weight_4;
5016 float index_1, index_2, index_3, index_4;
5017 float normal_1, normal_2, normal_3, normal_4;
5018 float fog_1, fog_2, fog_3, fog_4;
5019 float texcoord_1, texcoord_2, texcoord_3, texcoord_4;
5020 float tangent_1, tangent_2, tangent_3, tangent_4;
5021 float binormal_1, binormal_2, binormal_3, binormal_4;
5022 float depth_1, depth_2, depth_3, depth_4;
5023 DWORD diffuse, specular;
5026 static void fixed_function_varying_test(IDirect3DDevice9 *device) {
5027 /* dcl_position: fails to compile */
5028 const DWORD blendweight_code[] = {
5029 0xffff0300, /* ps_3_0 */
5030 0x0200001f, 0x80000001, 0x900f0000, /* dcl_blendweight, v0 */
5031 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5032 0x0000ffff /* end */
5034 const DWORD blendindices_code[] = {
5035 0xffff0300, /* ps_3_0 */
5036 0x0200001f, 0x80000002, 0x900f0000, /* dcl_blendindices, v0 */
5037 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5038 0x0000ffff /* end */
5040 const DWORD normal_code[] = {
5041 0xffff0300, /* ps_3_0 */
5042 0x0200001f, 0x80000003, 0x900f0000, /* dcl_normal, v0 */
5043 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5044 0x0000ffff /* end */
5046 /* psize: fails? */
5047 const DWORD texcoord0_code[] = {
5048 0xffff0300, /* ps_3_0 */
5049 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0, v0 */
5050 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5051 0x0000ffff /* end */
5053 const DWORD tangent_code[] = {
5054 0xffff0300, /* ps_3_0 */
5055 0x0200001f, 0x80000006, 0x900f0000, /* dcl_tangent, v0 */
5056 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5057 0x0000ffff /* end */
5059 const DWORD binormal_code[] = {
5060 0xffff0300, /* ps_3_0 */
5061 0x0200001f, 0x80000007, 0x900f0000, /* dcl_binormal, v0 */
5062 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5063 0x0000ffff /* end */
5065 /* tessfactor: fails */
5066 /* positiont: fails */
5067 const DWORD color_code[] = {
5068 0xffff0300, /* ps_3_0 */
5069 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0, v0 */
5070 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5071 0x0000ffff /* end */
5073 const DWORD fog_code[] = {
5074 0xffff0300, /* ps_3_0 */
5075 0x0200001f, 0x8000000b, 0x900f0000, /* dcl_fog, v0 */
5076 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5077 0x0000ffff /* end */
5079 const DWORD depth_code[] = {
5080 0xffff0300, /* ps_3_0 */
5081 0x0200001f, 0x8000000c, 0x900f0000, /* dcl_depth, v0 */
5082 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5083 0x0000ffff /* end */
5085 const DWORD specular_code[] = {
5086 0xffff0300, /* ps_3_0 */
5087 0x0200001f, 0x8001000a, 0x900f0000, /* dcl_color1, v0 */
5088 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5089 0x0000ffff /* end */
5091 /* sample: fails */
5093 struct varying_test_struct tests[] = {
5094 {blendweight_code, NULL, 0x00000000, 0x00191919, "blendweight" , FALSE, TRUE },
5095 {blendindices_code, NULL, 0x00000000, 0x00000000, "blendindices" , FALSE, FALSE },
5096 {normal_code, NULL, 0x00000000, 0x004c4c4c, "normal" , FALSE, TRUE },
5097 /* Why does dx not forward the texcoord? */
5098 {texcoord0_code, NULL, 0x00000000, 0x00808c8c, "texcoord0" , FALSE, FALSE },
5099 {tangent_code, NULL, 0x00000000, 0x00999999, "tangent" , FALSE, TRUE },
5100 {binormal_code, NULL, 0x00000000, 0x00b2b2b2, "binormal" , FALSE, TRUE },
5101 {color_code, NULL, 0x00e6e6e6, 0x00e6e6e6, "color" , FALSE, FALSE },
5102 {fog_code, NULL, 0x00000000, 0x00666666, "fog" , FALSE, TRUE },
5103 {depth_code, NULL, 0x00000000, 0x00cccccc, "depth" , FALSE, TRUE },
5104 {specular_code, NULL, 0x004488ff, 0x004488ff, "specular" , FALSE, FALSE }
5106 /* Declare a monster vertex type :-) */
5107 static const D3DVERTEXELEMENT9 decl_elements[] = {
5108 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5109 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
5110 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
5111 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
5112 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
5113 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5114 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
5115 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
5116 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
5117 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5118 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
5119 D3DDECL_END()
5121 static const D3DVERTEXELEMENT9 decl_elements2[] = {
5122 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
5123 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
5124 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
5125 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
5126 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
5127 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5128 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
5129 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
5130 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
5131 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5132 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
5133 D3DDECL_END()
5135 struct hugeVertex data[4] = {
5137 -1.0, -1.0, 0.1, 1.0,
5138 0.1, 0.1, 0.1, 0.1,
5139 0.2, 0.2, 0.2, 0.2,
5140 0.3, 0.3, 0.3, 0.3,
5141 0.4, 0.4, 0.4, 0.4,
5142 0.50, 0.55, 0.55, 0.55,
5143 0.6, 0.6, 0.6, 0.7,
5144 0.7, 0.7, 0.7, 0.6,
5145 0.8, 0.8, 0.8, 0.8,
5146 0xe6e6e6e6, /* 0.9 * 256 */
5147 0x224488ff /* Nothing special */
5150 1.0, -1.0, 0.1, 1.0,
5151 0.1, 0.1, 0.1, 0.1,
5152 0.2, 0.2, 0.2, 0.2,
5153 0.3, 0.3, 0.3, 0.3,
5154 0.4, 0.4, 0.4, 0.4,
5155 0.50, 0.55, 0.55, 0.55,
5156 0.6, 0.6, 0.6, 0.7,
5157 0.7, 0.7, 0.7, 0.6,
5158 0.8, 0.8, 0.8, 0.8,
5159 0xe6e6e6e6, /* 0.9 * 256 */
5160 0x224488ff /* Nothing special */
5163 -1.0, 1.0, 0.1, 1.0,
5164 0.1, 0.1, 0.1, 0.1,
5165 0.2, 0.2, 0.2, 0.2,
5166 0.3, 0.3, 0.3, 0.3,
5167 0.4, 0.4, 0.4, 0.4,
5168 0.50, 0.55, 0.55, 0.55,
5169 0.6, 0.6, 0.6, 0.7,
5170 0.7, 0.7, 0.7, 0.6,
5171 0.8, 0.8, 0.8, 0.8,
5172 0xe6e6e6e6, /* 0.9 * 256 */
5173 0x224488ff /* Nothing special */
5176 1.0, 1.0, 0.1, 1.0,
5177 0.1, 0.1, 0.1, 0.1,
5178 0.2, 0.2, 0.2, 0.2,
5179 0.3, 0.3, 0.3, 0.3,
5180 0.4, 0.4, 0.4, 0.4,
5181 0.50, 0.55, 0.55, 0.55,
5182 0.6, 0.6, 0.6, 0.7,
5183 0.7, 0.7, 0.7, 0.6,
5184 0.8, 0.8, 0.8, 0.8,
5185 0xe6e6e6e6, /* 0.9 * 256 */
5186 0x224488ff /* Nothing special */
5189 struct hugeVertex data2[4];
5190 IDirect3DVertexDeclaration9 *decl;
5191 IDirect3DVertexDeclaration9 *decl2;
5192 HRESULT hr;
5193 unsigned int i;
5194 DWORD color, r, g, b, r_e, g_e, b_e;
5195 BOOL drawok;
5197 memcpy(data2, data, sizeof(data2));
5198 data2[0].pos_x = 0; data2[0].pos_y = 0;
5199 data2[1].pos_x = 640; data2[1].pos_y = 0;
5200 data2[2].pos_x = 0; data2[2].pos_y = 480;
5201 data2[3].pos_x = 640; data2[3].pos_y = 480;
5203 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5204 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5205 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
5206 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5207 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5208 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5210 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5212 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
5213 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %s\n",
5214 tests[i].name, DXGetErrorString9(hr));
5217 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5219 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5220 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
5222 IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5223 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5225 hr = IDirect3DDevice9_BeginScene(device);
5226 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5227 drawok = FALSE;
5228 if(SUCCEEDED(hr))
5230 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(data[0]));
5231 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed (%08x)\n", hr);
5232 drawok = SUCCEEDED(hr);
5233 hr = IDirect3DDevice9_EndScene(device);
5234 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5236 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5237 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5239 /* Some drivers reject the combination of ps_3_0 and fixed function vertex processing. Accept
5240 * the failure and do not check the color if it failed
5242 if(!drawok) {
5243 continue;
5246 color = getPixelColor(device, 360, 240);
5247 r = color & 0x00ff0000 >> 16;
5248 g = color & 0x0000ff00 >> 8;
5249 b = color & 0x000000ff;
5250 r_e = tests[i].color & 0x00ff0000 >> 16;
5251 g_e = tests[i].color & 0x0000ff00 >> 8;
5252 b_e = tests[i].color & 0x000000ff;
5254 if(tests[i].todo) {
5255 todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5256 "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5257 tests[i].name, color, tests[i].color);
5258 } else {
5259 ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5260 "Test %s returned color 0x%08x, expected 0x%08x\n",
5261 tests[i].name, color, tests[i].color);
5265 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
5266 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5267 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5269 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5270 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
5272 IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5273 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5275 hr = IDirect3DDevice9_BeginScene(device);
5276 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5277 if(SUCCEEDED(hr))
5279 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
5280 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5281 hr = IDirect3DDevice9_EndScene(device);
5282 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5284 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5285 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5287 color = getPixelColor(device, 360, 240);
5288 r = color & 0x00ff0000 >> 16;
5289 g = color & 0x0000ff00 >> 8;
5290 b = color & 0x000000ff;
5291 r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
5292 g_e = tests[i].color_rhw & 0x0000ff00 >> 8;
5293 b_e = tests[i].color_rhw & 0x000000ff;
5295 if(tests[i].todo_rhw) {
5296 /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
5297 * pipeline
5299 todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5300 "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5301 tests[i].name, color, tests[i].color_rhw);
5302 } else {
5303 ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5304 "Test %s returned color 0x%08x, expected 0x%08x\n",
5305 tests[i].name, color, tests[i].color_rhw);
5309 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5311 IDirect3DPixelShader9_Release(tests[i].shader);
5314 IDirect3DVertexDeclaration9_Release(decl2);
5315 IDirect3DVertexDeclaration9_Release(decl);
5318 static void vshader_version_varying_test(IDirect3DDevice9 *device) {
5319 static const DWORD ps_code[] = {
5320 0xffff0300, /* ps_3_0 */
5321 0x05000030, 0xf00f0000, 0x00000003, 0x00000003, 0x00000001, 0x00000000, /* defi i0, 3, 3, 1, 0 */
5322 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
5323 0x0200001f, 0x8001000a, 0x900f0003, /* dcl_color1 v3 */
5324 0x0200001f, 0x8000000b, 0x900f0004, /* dcl_fog v4 */
5325 0x0200001f, 0x80030005, 0x900f0005, /* dcl_texcoord3 v5 */
5326 0x0200001f, 0x80000003, 0x900f0006,
5327 0x0200001f, 0x80000006, 0x900f0007,
5328 0x0200001f, 0x80000001, 0x900f0008,
5329 0x0200001f, 0x8000000c, 0x900f0009,
5331 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5332 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
5333 0x04000002, 0x800f0000, 0x80e40000, 0x90e42000, 0xf0e40800, /* add r0, r0, v0[aL] */
5334 0x0000001d, /* endloop */
5335 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5336 0x0000ffff /* end */
5338 static const DWORD vs_1_code[] = {
5339 0xfffe0101, /* vs_1_1 */
5340 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5341 0x00000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0 */
5342 0x00000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0 */
5343 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0 */
5344 0x00000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
5345 0x00000001, 0xd00f0000, 0xa0e40002, /* mov oD0, c2 */
5346 0x00000001, 0xd00f0001, 0xa0e40000, /* mov oD1, c0 */
5347 0x00000001, 0xc00f0001, 0xa0550001, /* mov oFog, c1.g */
5348 0x00000001, 0xe00f0000, 0xa0e40003, /* mov oT0, c3 */
5349 0x00000001, 0xe00f0001, 0xa0e40003, /* mov oT1, c3 */
5350 0x00000001, 0xe00f0002, 0xa0e40003, /* mov oT2, c3 */
5351 0x00000001, 0xe00f0003, 0xa0e40002, /* mov oT3, c2 */
5352 0x00000001, 0xe00f0004, 0xa0e40003, /* mov oT4, c3 */
5353 0x00000001, 0xe00f0005, 0xa0e40003, /* mov oT5, c3 */
5354 0x00000001, 0xe00f0006, 0xa0e40003, /* mov oT6, c3 */
5355 0x00000001, 0xe00f0007, 0xa0e40003, /* mov oT7, c3 */
5356 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5357 0x0000ffff
5359 DWORD vs_2_code[] = {
5360 0xfffe0200, /* vs_2_0 */
5361 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5362 0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.5, 0.0, 0.0, 0.0 */
5363 0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.5, 0.0, 0.0 */
5364 0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.5, 0.0 */
5365 0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
5366 0x02000001, 0xd00f0000, 0xa0e40002, /* mov oD0, c2 */
5367 0x02000001, 0xd00f0001, 0xa0e40000, /* mov oD1, c0 */
5368 0x02000001, 0xc00f0001, 0xa0550001, /* mov oFog, c1.g */
5369 0x02000001, 0xe00f0000, 0xa0e40003, /* mov oT0, c3 */
5370 0x02000001, 0xe00f0001, 0xa0e40003, /* mov oT1, c3 */
5371 0x02000001, 0xe00f0002, 0xa0e40003, /* mov oT2, c3 */
5372 0x02000001, 0xe00f0003, 0xa0e40002, /* mov oT3, c2 */
5373 0x02000001, 0xe00f0004, 0xa0e40003, /* mov oT4, c3 */
5374 0x02000001, 0xe00f0005, 0xa0e40003, /* mov oT5, c3 */
5375 0x02000001, 0xe00f0006, 0xa0e40003, /* mov oT6, c3 */
5376 0x02000001, 0xe00f0007, 0xa0e40003, /* mov oT7, c3 */
5377 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5378 0x0000ffff /* end */
5380 /* TODO: Define normal, tangent, blendweight and depth here */
5381 static const DWORD vs_3_code[] = {
5382 0xfffe0300, /* vs_3_0 */
5383 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5384 0x0200001f, 0x8001000a, 0xe00f0009, /* dcl_color1 o9 */
5385 0x0200001f, 0x8000000b, 0xe00f0002, /* dcl_fog o2 */
5386 0x0200001f, 0x80030005, 0xe00f0005, /* dcl_texcoord3 o5 */
5387 0x0200001f, 0x80000000, 0xe00f000b, /* dcl_position o11 */
5388 0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0 */
5389 0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0 */
5390 0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0 */
5391 0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
5392 0x02000001, 0xe00f0009, 0xa0e40000, /* mov o9, c0 */
5393 0x02000001, 0xe00f0002, 0xa0e40001, /* mov o2, c1 */
5394 0x02000001, 0xe00f0005, 0xa0e40002, /* mov o5, c2 */
5395 0x02000001, 0xe00f000b, 0x90e40000, /* mov o11, v0 */
5396 0x0000ffff /* end */
5398 float quad1[] = {
5399 -1.0, -1.0, 0.1,
5400 0.0, -1.0, 0.1,
5401 -1.0, 0.0, 0.1,
5402 0.0, 0.0, 0.1
5404 float quad2[] = {
5405 0.0, -1.0, 0.1,
5406 1.0, -1.0, 0.1,
5407 0.0, 0.0, 0.1,
5408 1.0, 0.0, 0.1
5410 float quad3[] = {
5411 -1.0, 0.0, 0.1,
5412 0.0, 0.0, 0.1,
5413 -1.0, 1.0, 0.1,
5414 0.0, 1.0, 0.1
5417 HRESULT hr;
5418 DWORD color;
5419 IDirect3DPixelShader9 *pixelshader = NULL;
5420 IDirect3DVertexShader9 *vs_1_shader = NULL;
5421 IDirect3DVertexShader9 *vs_2_shader = NULL;
5422 IDirect3DVertexShader9 *vs_3_shader = NULL;
5424 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff110000, 0.0, 0);
5426 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &pixelshader);
5427 ok(hr == D3D_OK, "IDirect3DDevice_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
5428 hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_code, &vs_1_shader);
5429 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5430 hr = IDirect3DDevice9_CreateVertexShader(device, vs_2_code, &vs_2_shader);
5431 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5432 hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_code, &vs_3_shader);
5433 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5434 hr = IDirect3DDevice9_SetPixelShader(device, pixelshader);
5435 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5436 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5438 hr = IDirect3DDevice9_BeginScene(device);
5439 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5440 if(SUCCEEDED(hr))
5442 hr = IDirect3DDevice9_SetVertexShader(device, vs_1_shader);
5443 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5444 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5445 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5447 hr = IDirect3DDevice9_SetVertexShader(device, vs_2_shader);
5448 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5449 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
5450 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5452 hr = IDirect3DDevice9_SetVertexShader(device, vs_3_shader);
5453 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5454 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5455 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5457 hr = IDirect3DDevice9_EndScene(device);
5458 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5460 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5461 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5463 color = getPixelColor(device, 160, 120);
5464 ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5465 (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003500 &&
5466 (color & 0x000000ff) >= 0x00000066 && (color & 0x000000ff) <= 0x00000068,
5467 "vs_3_0 returned color 0x%08x, expected 0x00203366\n", color);
5468 color = getPixelColor(device, 160, 360);
5469 ok((color & 0x00ff0000) >= 0x003c0000 && (color & 0x00ff0000) <= 0x004e0000 &&
5470 (color & 0x0000ff00) >= 0x00000000 && (color & 0x0000ff00) <= 0x00000000 &&
5471 (color & 0x000000ff) >= 0x00000066 && (color & 0x000000ff) <= 0x00000068,
5472 "vs_1_1 returned color 0x%08x, expected 0x004c0066\n", color);
5473 color = getPixelColor(device, 480, 360);
5474 ok((color & 0x00ff0000) >= 0x003c0000 && (color & 0x00ff0000) <= 0x004e0000 &&
5475 (color & 0x0000ff00) >= 0x00000000 && (color & 0x0000ff00) <= 0x00000000 &&
5476 (color & 0x000000ff) >= 0x00000066 && (color & 0x000000ff) <= 0x00000068,
5477 "vs_2_0 returned color 0x%08x, expected 0x004c0066\n", color);
5479 /* cleanup */
5480 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5481 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5482 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5483 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5484 if(pixelshader) IDirect3DPixelShader9_Release(pixelshader);
5485 if(vs_1_shader) IDirect3DVertexShader9_Release(vs_1_shader);
5486 if(vs_2_shader) IDirect3DVertexShader9_Release(vs_2_shader);
5487 if(vs_3_shader) IDirect3DVertexShader9_Release(vs_3_shader);
5490 static void pshader_version_varying_test(IDirect3DDevice9 *device) {
5491 static const DWORD vs_code[] = {
5492 0xfffe0300, /* vs_3_0 */
5493 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5494 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5495 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */
5496 0x0200001f, 0x80000005, 0xe00f0002, /* dcl_texcoord0 o2 */
5497 0x0200001f, 0x8000000b, 0xe00f0003, /* dcl_fog o3 */
5498 0x0200001f, 0x80000003, 0xe00f0004, /* dcl_normal o4 */
5499 0x0200001f, 0x8000000c, 0xe00f0005, /* dcl_depth o5 */
5500 0x0200001f, 0x80000006, 0xe00f0006, /* dcl_tangent o6 */
5501 0x0200001f, 0x80000001, 0xe00f0007, /* dcl_blendweight o7 */
5502 0x05000051, 0xa00f0001, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c1, 0.1, 0.0, 0.0, 0.0 */
5503 0x05000051, 0xa00f0002, 0x00000000, 0x3e4ccccd, 0x00000000, 0x3f800000, /* def c2, 0.0, 0.2, 0.0, 1.0 */
5504 0x05000051, 0xa00f0003, 0x3ecccccd, 0x3f59999a, 0x3f666666, 0x00000000, /* def c3, 0.4, 0.85,0.9, 0.0 */
5505 0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0 */
5507 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5508 0x02000001, 0xe00f0001, 0xa0e40001, /* mov o1, c1 */
5509 0x02000001, 0xe00f0002, 0xa0e40002, /* mov o2, c2 */
5510 0x02000001, 0xe00f0003, 0xa0e40003, /* mov o3, c3 */
5511 0x02000001, 0xe00f0004, 0xa0e40000, /* mov o4, c0 */
5512 0x02000001, 0xe00f0005, 0xa0e40000, /* mov o5, c0 */
5513 0x02000001, 0xe00f0006, 0xa0e40000, /* mov o6, c0 */
5514 0x02000001, 0xe00f0007, 0xa0e40000, /* mov o7, c0 */
5515 0x0000ffff /* end */
5517 static const DWORD ps_1_code[] = {
5518 0xffff0104, /* ps_1_4 */
5519 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
5520 0x00000040, 0x80070001, 0xb0e40000, /* texcrd r1.xyz, t0 */
5521 0x00000001, 0x80080001, 0xa0ff0000, /* mov r1.a, c0.a */
5522 0x00000002, 0x800f0000, 0x90e40000, 0x80e40001, /* add r0, v0, r1 */
5523 0x0000ffff /* end */
5525 static const DWORD ps_2_code[] = {
5526 0xffff0200, /* ps_2_0 */
5527 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
5528 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
5529 0x0200001f, 0x80000000, 0x900f0001, /* dcl v1 */
5531 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
5532 0x03000002, 0x800f0000, 0x80e40000,0xb0e40000, /* add r0, r0, t0 */
5533 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5534 0x0000ffff /* end */
5536 static const DWORD ps_3_code[] = {
5537 0xffff0300, /* ps_3_0 */
5538 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
5539 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
5540 0x0200001f, 0x8000000b, 0x900f0002, /* dcl_fog v2 */
5542 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
5543 0x03000002, 0x800f0000, 0x80e40000, 0x90e40001, /* add r0, r0, v1 */
5544 0x03000002, 0x800f0000, 0x80e40000, 0x90e40002, /* mov r0, r0, v2 */
5545 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5546 0x0000ffff /* end */
5549 float quad1[] = {
5550 -1.0, -1.0, 0.1,
5551 0.0, -1.0, 0.1,
5552 -1.0, 0.0, 0.1,
5553 0.0, 0.0, 0.1
5555 float quad2[] = {
5556 0.0, -1.0, 0.1,
5557 1.0, -1.0, 0.1,
5558 0.0, 0.0, 0.1,
5559 1.0, 0.0, 0.1
5561 float quad3[] = {
5562 -1.0, 0.0, 0.1,
5563 0.0, 0.0, 0.1,
5564 -1.0, 1.0, 0.1,
5565 0.0, 1.0, 0.1
5567 float quad4[] = {
5568 0.0, 0.0, 0.1,
5569 1.0, 0.0, 0.1,
5570 0.0, 1.0, 0.1,
5571 1.0, 1.0, 0.1
5574 HRESULT hr;
5575 DWORD color;
5576 IDirect3DVertexShader9 *vertexshader = NULL;
5577 IDirect3DPixelShader9 *ps_1_shader = NULL;
5578 IDirect3DPixelShader9 *ps_2_shader = NULL;
5579 IDirect3DPixelShader9 *ps_3_shader = NULL;
5580 IDirect3DTexture9 *texture = NULL;
5581 D3DLOCKED_RECT lr;
5582 unsigned int x, y;
5584 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5586 hr = IDirect3DDevice9_CreateTexture(device, 512, 512, 1, 0, D3DFMT_A16B16G16R16, D3DPOOL_MANAGED, &texture, NULL);
5587 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %s\n", DXGetErrorString9(hr));
5588 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5589 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %s\n", DXGetErrorString9(hr));
5590 for(y = 0; y < 512; y++) {
5591 for(x = 0; x < 512; x++) {
5592 double r_f = (double) x / (double) 512;
5593 double g_f = (double) y / (double) 512;
5594 unsigned short *dst = (unsigned short *) (((unsigned char *) lr.pBits) + y * lr.Pitch + x * 8);
5595 unsigned short r = (unsigned short) (r_f * 65535.0);
5596 unsigned short g = (unsigned short) (g_f * 65535.0);
5597 dst[0] = r;
5598 dst[1] = g;
5599 dst[2] = 0;
5600 dst[3] = 65535;
5603 hr = IDirect3DTexture9_UnlockRect(texture, 0);
5604 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %s\n", DXGetErrorString9(hr));
5606 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vertexshader);
5607 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5608 hr = IDirect3DDevice9_CreatePixelShader(device, ps_1_code, &ps_1_shader);
5609 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
5610 hr = IDirect3DDevice9_CreatePixelShader(device, ps_2_code, &ps_2_shader);
5611 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
5612 hr = IDirect3DDevice9_CreatePixelShader(device, ps_3_code, &ps_3_shader);
5613 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
5614 hr = IDirect3DDevice9_SetVertexShader(device, vertexshader);
5615 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5616 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5618 hr = IDirect3DDevice9_BeginScene(device);
5619 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5620 if(SUCCEEDED(hr))
5622 hr = IDirect3DDevice9_SetPixelShader(device, ps_1_shader);
5623 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5624 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5625 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5627 hr = IDirect3DDevice9_SetPixelShader(device, ps_2_shader);
5628 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5629 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
5630 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5632 hr = IDirect3DDevice9_SetPixelShader(device, ps_3_shader);
5633 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5634 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5635 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5637 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5638 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5639 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5640 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
5641 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
5642 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
5643 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
5644 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
5645 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5646 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5648 hr = IDirect3DDevice9_EndScene(device);
5649 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5651 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5652 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5654 color = getPixelColor(device, 160, 120);
5655 ok((color & 0x00ff0000) >= 0x00790000 && (color & 0x00ff0000) <= 0x00810000 &&
5656 (color & 0x0000ff00) == 0x0000ff00 &&
5657 (color & 0x000000ff) >= 0x000000e4 && (color & 0x000000ff) <= 0x000000e6,
5658 "ps_3_0 returned color 0x%08x, expected 0x0080ffe5\n", color);
5659 color = getPixelColor(device, 160, 360);
5660 ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5661 (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003400 &&
5662 (color & 0x000000ff) == 0x00000000,
5663 "ps_1_4 returned color 0x%08x, expected 0x00203300\n", color);
5664 color = getPixelColor(device, 480, 360);
5665 ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5666 (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5667 (color & 0x000000ff) == 0x00000000,
5668 "ps_2_0 returned color 0x%08x, expected 0x00203300\n", color);
5669 color = getPixelColor(device, 480, 160);
5670 ok( color == 0x00ffffff /* Nvidia driver garbage with HW vp */ || (
5671 (color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5672 (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5673 (color & 0x000000ff) == 0x00000000),
5674 "fixed function fragment processing returned color 0x%08x, expected 0x00203300\n", color);
5676 /* cleanup */
5677 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5678 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
5679 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5680 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5681 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5682 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5683 if(vertexshader) IDirect3DVertexShader9_Release(vertexshader);
5684 if(ps_1_shader) IDirect3DPixelShader9_Release(ps_1_shader);
5685 if(ps_2_shader) IDirect3DPixelShader9_Release(ps_2_shader);
5686 if(ps_3_shader) IDirect3DPixelShader9_Release(ps_3_shader);
5687 if(texture) IDirect3DTexture9_Release(texture);
5690 void test_compare_instructions(IDirect3DDevice9 *device)
5692 DWORD shader_sge_vec_code[] = {
5693 0xfffe0101, /* vs_1_1 */
5694 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5695 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5696 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5697 0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001, /* sge oD0, r0, c1 */
5698 0x0000ffff /* end */
5700 DWORD shader_slt_vec_code[] = {
5701 0xfffe0101, /* vs_1_1 */
5702 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5703 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5704 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5705 0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001, /* slt oD0, r0, c1 */
5706 0x0000ffff /* end */
5708 DWORD shader_sge_scalar_code[] = {
5709 0xfffe0101, /* vs_1_1 */
5710 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5711 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5712 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5713 0x0000000d, 0xd0010000, 0x80000000, 0xa0550001, /* slt oD0.r, r0.r, c1.b */
5714 0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001, /* slt oD0.g, r0.g, c1.r */
5715 0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001, /* slt oD0.b, r0.b, c1.g */
5716 0x0000ffff /* end */
5718 DWORD shader_slt_scalar_code[] = {
5719 0xfffe0101, /* vs_1_1 */
5720 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5721 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5722 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5723 0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001, /* slt oD0.r, r0.r, c1.b */
5724 0x0000000c, 0xd0020000, 0x80550000, 0xa0000001, /* slt oD0.g, r0.g, c1.r */
5725 0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001, /* slt oD0.b, r0.b, c1.g */
5726 0x0000ffff /* end */
5728 IDirect3DVertexShader9 *shader_sge_vec;
5729 IDirect3DVertexShader9 *shader_slt_vec;
5730 IDirect3DVertexShader9 *shader_sge_scalar;
5731 IDirect3DVertexShader9 *shader_slt_scalar;
5732 HRESULT hr, color;
5733 float quad1[] = {
5734 -1.0, -1.0, 0.1,
5735 0.0, -1.0, 0.1,
5736 -1.0, 0.0, 0.1,
5737 0.0, 0.0, 0.1
5739 float quad2[] = {
5740 0.0, -1.0, 0.1,
5741 1.0, -1.0, 0.1,
5742 0.0, 0.0, 0.1,
5743 1.0, 0.0, 0.1
5745 float quad3[] = {
5746 -1.0, 0.0, 0.1,
5747 0.0, 0.0, 0.1,
5748 -1.0, 1.0, 0.1,
5749 0.0, 1.0, 0.1
5751 float quad4[] = {
5752 0.0, 0.0, 0.1,
5753 1.0, 0.0, 0.1,
5754 0.0, 1.0, 0.1,
5755 1.0, 1.0, 0.1
5757 const float const0[4] = {0.8, 0.2, 0.2, 0.2};
5758 const float const1[4] = {0.2, 0.8, 0.2, 0.2};
5760 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5762 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
5763 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5764 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
5765 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5766 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
5767 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5768 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
5769 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5770 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5771 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5772 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
5773 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5774 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5775 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
5777 hr = IDirect3DDevice9_BeginScene(device);
5778 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5779 if(SUCCEEDED(hr))
5781 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
5782 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5783 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5784 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5786 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
5787 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5788 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
5789 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5791 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
5792 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5793 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5794 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5796 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5797 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5799 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
5800 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5801 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5802 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5804 hr = IDirect3DDevice9_EndScene(device);
5805 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5808 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5809 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5811 color = getPixelColor(device, 160, 360);
5812 ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
5813 color = getPixelColor(device, 480, 360);
5814 ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
5815 color = getPixelColor(device, 160, 120);
5816 ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
5817 color = getPixelColor(device, 480, 160);
5818 ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
5820 IDirect3DVertexShader9_Release(shader_sge_vec);
5821 IDirect3DVertexShader9_Release(shader_slt_vec);
5822 IDirect3DVertexShader9_Release(shader_sge_scalar);
5823 IDirect3DVertexShader9_Release(shader_slt_scalar);
5826 void test_vshader_input(IDirect3DDevice9 *device)
5828 DWORD swapped_shader_code_3[] = {
5829 0xfffe0300, /* vs_3_0 */
5830 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5831 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
5832 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5833 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
5834 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
5835 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5836 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
5837 0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
5838 0x0000ffff /* end */
5840 DWORD swapped_shader_code_1[] = {
5841 0xfffe0101, /* vs_1_1 */
5842 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5843 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
5844 0x0000001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
5845 0x00000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
5846 0x00000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
5847 0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
5848 0x0000ffff /* end */
5850 DWORD swapped_shader_code_2[] = {
5851 0xfffe0200, /* vs_2_0 */
5852 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5853 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
5854 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
5855 0x02000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
5856 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
5857 0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
5858 0x0000ffff /* end */
5860 DWORD texcoord_color_shader_code_3[] = {
5861 0xfffe0300, /* vs_3_0 */
5862 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5863 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
5864 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5865 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
5866 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5867 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
5868 0x0000ffff /* end */
5870 DWORD texcoord_color_shader_code_2[] = {
5871 0xfffe0200, /* vs_2_0 */
5872 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5873 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
5874 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5875 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
5876 0x0000ffff /* end */
5878 DWORD texcoord_color_shader_code_1[] = {
5879 0xfffe0101, /* vs_1_1 */
5880 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5881 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
5882 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5883 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
5884 0x0000ffff /* end */
5886 DWORD color_color_shader_code_3[] = {
5887 0xfffe0300, /* vs_3_0 */
5888 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5889 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
5890 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5891 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
5892 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5893 0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001, /* mul o1, c0, v1 */
5894 0x0000ffff /* end */
5896 DWORD color_color_shader_code_2[] = {
5897 0xfffe0200, /* vs_2_0 */
5898 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5899 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
5900 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5901 0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
5902 0x0000ffff /* end */
5904 DWORD color_color_shader_code_1[] = {
5905 0xfffe0101, /* vs_1_1 */
5906 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5907 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
5908 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5909 0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
5910 0x0000ffff /* end */
5912 IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
5913 HRESULT hr;
5914 DWORD color, r, g, b;
5915 float quad1[] = {
5916 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
5917 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
5918 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
5919 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
5921 float quad2[] = {
5922 0.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
5923 1.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
5924 0.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
5925 1.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
5927 float quad3[] = {
5928 -1.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0,
5929 0.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,
5930 -1.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0,
5931 0.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0,
5933 float quad4[] = {
5934 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
5935 1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
5936 0.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
5937 1.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
5939 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
5940 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5941 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5942 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
5943 D3DDECL_END()
5945 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
5946 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5947 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
5948 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5949 D3DDECL_END()
5951 static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
5952 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5953 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5954 D3DDECL_END()
5956 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
5957 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5958 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
5959 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
5960 D3DDECL_END()
5962 static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
5963 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5964 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5965 D3DDECL_END()
5967 static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
5968 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5969 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5970 D3DDECL_END()
5972 static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
5973 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5974 {0, 12, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5975 D3DDECL_END()
5977 static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
5978 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5979 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5980 D3DDECL_END()
5982 IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
5983 IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
5984 unsigned int i;
5985 float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
5986 float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
5988 struct vertex quad1_color[] = {
5989 {-1.0, -1.0, 0.1, 0x00ff8040},
5990 { 0.0, -1.0, 0.1, 0x00ff8040},
5991 {-1.0, 0.0, 0.1, 0x00ff8040},
5992 { 0.0, 0.0, 0.1, 0x00ff8040}
5994 struct vertex quad2_color[] = {
5995 { 0.0, -1.0, 0.1, 0x00ff8040},
5996 { 1.0, -1.0, 0.1, 0x00ff8040},
5997 { 0.0, 0.0, 0.1, 0x00ff8040},
5998 { 1.0, 0.0, 0.1, 0x00ff8040}
6000 struct vertex quad3_color[] = {
6001 {-1.0, 0.0, 0.1, 0x00ff8040},
6002 { 0.0, 0.0, 0.1, 0x00ff8040},
6003 {-1.0, 1.0, 0.1, 0x00ff8040},
6004 { 0.0, 1.0, 0.1, 0x00ff8040}
6006 float quad4_color[] = {
6007 0.0, 0.0, 0.1, 1.0, 1.0, 0.0, 0.0,
6008 1.0, 0.0, 0.1, 1.0, 1.0, 0.0, 1.0,
6009 0.0, 1.0, 0.1, 1.0, 1.0, 0.0, 0.0,
6010 1.0, 1.0, 0.1, 1.0, 1.0, 0.0, 1.0,
6013 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6014 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6015 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6016 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6017 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6018 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6019 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6020 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6022 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6023 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6024 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6025 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6026 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6027 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6028 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6029 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6031 for(i = 1; i <= 3; i++) {
6032 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6033 if(i == 3) {
6034 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6035 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6036 } else if(i == 2){
6037 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6038 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6039 } else if(i == 1) {
6040 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6041 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6044 hr = IDirect3DDevice9_BeginScene(device);
6045 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
6046 if(SUCCEEDED(hr))
6048 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6049 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6051 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6052 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6053 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6054 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6056 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6057 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6058 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6059 if(i == 3 || i == 2) {
6060 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6061 } else if(i == 1) {
6062 /* Succeeds or fails, depending on SW or HW vertex processing */
6063 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6066 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6067 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6068 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6069 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6071 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6072 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6073 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6074 if(i == 3 || i == 2) {
6075 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6076 } else if(i == 1) {
6077 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6080 hr = IDirect3DDevice9_EndScene(device);
6081 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
6084 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6085 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6087 if(i == 3 || i == 2) {
6088 color = getPixelColor(device, 160, 360);
6089 ok(color == 0x00FFFF80 || color == 0x00FFFF7f || color == 0x00FFFF81,
6090 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6092 /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6093 color = getPixelColor(device, 480, 360);
6094 ok(color == 0x00FFFF00 || color ==0x00FF0000,
6095 "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6096 color = getPixelColor(device, 160, 120);
6097 /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6098 ok(color == 0x00FF0080 || color == 0x00FF007f || color == 0x00FF0081 || color == 0x00FF0000,
6099 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6101 color = getPixelColor(device, 480, 160);
6102 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6103 } else if(i == 1) {
6104 color = getPixelColor(device, 160, 360);
6105 ok(color == 0x00FFFF80 || color == 0x00FFFF7f || color == 0x00FFFF81,
6106 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6107 color = getPixelColor(device, 480, 360);
6108 /* Accept the clear color as well in this case, since SW VP returns an error */
6109 ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6110 color = getPixelColor(device, 160, 120);
6111 ok(color == 0x00FF0080 || color == 0x00FF0000 || color == 0x00FF007f || color == 0x00FF0081,
6112 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6113 color = getPixelColor(device, 480, 160);
6114 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6117 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6118 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
6120 /* Now find out if the whole streams are re-read, or just the last active value for the
6121 * vertices is used.
6123 hr = IDirect3DDevice9_BeginScene(device);
6124 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
6125 if(SUCCEEDED(hr))
6127 float quad1_modified[] = {
6128 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0,
6129 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0,
6130 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0,
6131 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, -1.0, -1.0, 0.0,
6133 float quad2_modified[] = {
6134 0.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6135 1.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6136 0.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6137 1.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6140 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6141 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6143 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6144 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6145 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6146 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6148 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6149 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6150 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6151 if(i == 3 || i == 2) {
6152 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6153 } else if(i == 1) {
6154 /* Succeeds or fails, depending on SW or HW vertex processing */
6155 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6158 hr = IDirect3DDevice9_EndScene(device);
6159 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
6161 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6162 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6164 color = getPixelColor(device, 480, 350);
6165 /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6166 * as well.
6168 * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6169 * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6170 * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6171 * refrast's result.
6173 * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6175 ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6176 "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6177 color = getPixelColor(device, 160, 120);
6179 IDirect3DDevice9_SetVertexShader(device, NULL);
6180 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6182 IDirect3DVertexShader9_Release(swapped_shader);
6185 for(i = 1; i <= 3; i++) {
6186 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6187 if(i == 3) {
6188 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6189 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6190 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6191 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6192 } else if(i == 2){
6193 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6194 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6195 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6196 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6197 } else if(i == 1) {
6198 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6199 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6200 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6201 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6204 hr = IDirect3DDevice9_BeginScene(device);
6205 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
6206 if(SUCCEEDED(hr))
6208 hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6209 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6210 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6211 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6212 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6213 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6215 hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6216 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6218 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6219 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6220 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6221 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6222 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6223 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6225 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6226 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6227 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6228 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6229 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6230 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6232 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6233 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6234 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6235 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6237 hr = IDirect3DDevice9_EndScene(device);
6238 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
6240 IDirect3DDevice9_SetVertexShader(device, NULL);
6241 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6243 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6244 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6246 color = getPixelColor(device, 160, 360);
6247 r = (color & 0x00ff0000) >> 16;
6248 g = (color & 0x0000ff00) >> 8;
6249 b = (color & 0x000000ff) >> 0;
6250 ok(r >= 0xfe && r <= 0xff && g >= 0x7f && g <= 0x81 && b >= 0x3f && b <= 0x41,
6251 "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6252 color = getPixelColor(device, 480, 360);
6253 r = (color & 0x00ff0000) >> 16;
6254 g = (color & 0x0000ff00) >> 8;
6255 b = (color & 0x000000ff) >> 0;
6256 ok(r >= 0x3f && r <= 0x41 && g >= 0x7f && g <= 0x81 && b >= 0xfe && b <= 0xff,
6257 "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6258 color = getPixelColor(device, 160, 120);
6259 r = (color & 0x00ff0000) >> 16;
6260 g = (color & 0x0000ff00) >> 8;
6261 b = (color & 0x000000ff) >> 0;
6262 ok(r >= 0xfe && r <= 0xff && g >= 0x7f && g <= 0x81 && b >= 0x3f && b <= 0x41,
6263 "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6264 color = getPixelColor(device, 480, 160);
6265 r = (color & 0x00ff0000) >> 16;
6266 g = (color & 0x0000ff00) >> 8;
6267 b = (color & 0x000000ff) >> 0;
6268 ok(r >= 0xfe && r <= 0xff && g >= 0xfe && g <= 0xff && b <= 0x01,
6269 "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6271 IDirect3DVertexShader9_Release(texcoord_color_shader);
6272 IDirect3DVertexShader9_Release(color_color_shader);
6275 IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6276 IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6277 IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6278 IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6280 IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6281 IDirect3DVertexDeclaration9_Release(decl_color_color);
6282 IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6283 IDirect3DVertexDeclaration9_Release(decl_color_float);
6286 static void srgbtexture_test(IDirect3DDevice9 *device)
6288 /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6289 * texture stage state to render a quad using that texture. The resulting
6290 * color components should be 0x36 (~ 0.21), per this formula:
6291 * linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6292 * This is true where srgb_color > 0.04045.
6294 IDirect3D9 *d3d = NULL;
6295 HRESULT hr;
6296 LPDIRECT3DTEXTURE9 texture = NULL;
6297 LPDIRECT3DSURFACE9 surface = NULL;
6298 D3DLOCKED_RECT lr;
6299 DWORD color;
6300 float quad[] = {
6301 -1.0, 1.0, 0.0, 0.0, 0.0,
6302 1.0, 1.0, 0.0, 1.0, 0.0,
6303 -1.0, -1.0, 0.0, 0.0, 1.0,
6304 1.0, -1.0, 0.0, 1.0, 1.0,
6308 memset(&lr, 0, sizeof(lr));
6309 IDirect3DDevice9_GetDirect3D(device, &d3d);
6310 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6311 D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6312 D3DFMT_A8R8G8B8) != D3D_OK) {
6313 skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6314 goto out;
6317 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6318 D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6319 &texture, NULL);
6320 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
6321 if(!texture) {
6322 skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6323 goto out;
6325 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6326 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
6328 fill_surface(surface, 0xff7f7f7f);
6329 IDirect3DSurface9_Release(surface);
6331 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6332 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6333 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6334 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
6336 hr = IDirect3DDevice9_BeginScene(device);
6337 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
6338 if(SUCCEEDED(hr))
6340 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6341 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
6343 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6344 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
6347 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6348 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
6350 hr = IDirect3DDevice9_EndScene(device);
6351 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
6354 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6355 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
6356 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6357 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
6359 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6360 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6362 color = getPixelColor(device, 320, 240);
6363 ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6365 out:
6366 if(texture) IDirect3DTexture9_Release(texture);
6367 IDirect3D9_Release(d3d);
6370 /* Return true if color is near the expected value */
6371 static int color_near(DWORD color, DWORD expected)
6373 const BYTE slop = 1;
6375 BYTE r, g, b;
6376 BYTE rx, gx, bx;
6377 r = (color & 0x00ff0000) >> 16;
6378 g = (color & 0x0000ff00) >> 8;
6379 b = (color & 0x000000ff);
6380 rx = (expected & 0x00ff0000) >> 16;
6381 gx = (expected & 0x0000ff00) >> 8;
6382 bx = (expected & 0x000000ff);
6384 return
6385 ((r >= (rx - slop)) && (r <= (rx + slop))) &&
6386 ((g >= (gx - slop)) && (g <= (gx + slop))) &&
6387 ((b >= (bx - slop)) && (b <= (bx + slop)));
6390 static void shademode_test(IDirect3DDevice9 *device)
6392 /* Render a quad and try all of the different fixed function shading models. */
6393 HRESULT hr;
6394 DWORD color0, color1;
6395 DWORD color0_gouraud = 0, color1_gouraud = 0;
6396 DWORD shademode = D3DSHADE_FLAT;
6397 DWORD primtype = D3DPT_TRIANGLESTRIP;
6398 LPVOID data = NULL;
6399 LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6400 LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6401 UINT i, j;
6402 struct vertex quad_strip[] =
6404 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
6405 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6406 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6407 { 1.0f, 1.0f, 0.0f, 0xffffffff }
6409 struct vertex quad_list[] =
6411 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
6412 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6413 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6415 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6416 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6417 { 1.0f, 1.0f, 0.0f, 0xffffffff }
6420 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6421 0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6422 ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
6423 if (FAILED(hr)) goto bail;
6425 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6426 0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6427 ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
6428 if (FAILED(hr)) goto bail;
6430 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6431 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6433 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6434 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
6436 hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), (void **) &data, 0);
6437 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
6438 memcpy(data, quad_strip, sizeof(quad_strip));
6439 hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6440 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
6442 hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), (void **) &data, 0);
6443 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
6444 memcpy(data, quad_list, sizeof(quad_list));
6445 hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6446 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
6448 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
6449 * the color fixups we have to do for FLAT shading will be dependent on that. */
6450 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6451 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6453 /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6454 for (j=0; j<2; j++) {
6456 /* Inner loop just changes the D3DRS_SHADEMODE */
6457 for (i=0; i<3; i++) {
6458 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6459 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
6461 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6462 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6464 hr = IDirect3DDevice9_BeginScene(device);
6465 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
6466 if(SUCCEEDED(hr))
6468 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
6469 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %s\n", DXGetErrorString9(hr));
6471 hr = IDirect3DDevice9_EndScene(device);
6472 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
6475 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6476 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6478 /* Sample two spots from the output */
6479 color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
6480 color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
6481 switch(shademode) {
6482 case D3DSHADE_FLAT:
6483 /* Should take the color of the first vertex of each triangle */
6484 todo_wine ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000 (todo)\n", color0);
6485 todo_wine ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00 (todo)\n", color1);
6486 shademode = D3DSHADE_GOURAUD;
6487 break;
6488 case D3DSHADE_GOURAUD:
6489 /* Should be an interpolated blend */
6491 ok(color_near(color0, 0x000dca28),
6492 "GOURAUD shading has color0 %08x, expected 0x00dca28\n", color0);
6493 ok(color_near(color1, 0x000d45c7),
6494 "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
6496 color0_gouraud = color0;
6497 color1_gouraud = color1;
6499 shademode = D3DSHADE_PHONG;
6500 break;
6501 case D3DSHADE_PHONG:
6502 /* Should be the same as GOURAUD, since no hardware implements this */
6503 ok(color_near(color0, 0x000dca28),
6504 "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
6505 ok(color_near(color1, 0x000d45c7),
6506 "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
6508 ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6509 color0_gouraud, color0);
6510 ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6511 color1_gouraud, color1);
6512 break;
6515 /* Now, do it all over again with a TRIANGLELIST */
6516 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
6517 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6518 primtype = D3DPT_TRIANGLELIST;
6519 shademode = D3DSHADE_FLAT;
6522 bail:
6523 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6524 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6525 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
6526 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6528 if (vb_strip)
6529 IDirect3DVertexBuffer9_Release(vb_strip);
6530 if (vb_list)
6531 IDirect3DVertexBuffer9_Release(vb_list);
6535 static void fog_srgbwrite_test(IDirect3DDevice9 *device)
6537 /* Draw a black quad, half fogged with white fog -> grey color. Enable sRGB writing.
6538 * if sRGB writing is applied before fogging, the 0.0 will be multiplied with ~ 12.92, so still
6539 * stay 0.0. After that the fog gives 0.5. If sRGB writing is applied after fogging, the
6540 * 0.5 will run through the alternative path(0^5 ^ 0.41666 * 1.055 - 0.055), resulting in approx.
6541 * 0.73
6543 * At the time of this writing, wined3d could not apply sRGB correction to fixed function rendering,
6544 * so use shaders for this task
6546 IDirect3DPixelShader9 *pshader;
6547 IDirect3DVertexShader9 *vshader;
6548 IDirect3D9 *d3d;
6549 DWORD vshader_code[] = {
6550 0xfffe0101, /* vs_1_1 */
6551 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6552 0x00000051, 0xa00f0000, 0x3f000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.5, 0.0, 0.0, 0.0 */
6553 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6554 0x00000001, 0xc00f0001, 0xa0000000, /* mov oFog, c0.x */
6555 0x0000ffff /* end */
6557 DWORD pshader_code[] = {
6558 0xffff0101, /* ps_1_1 */
6559 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
6560 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6561 0x0000ffff /* end */
6563 const float quad[] = {
6564 -1.0, -1.0, 0.1,
6565 1.0, -1.0, 0.1,
6566 -1.0, 1.0, 0.1,
6567 1.0, 1.0, 0.1
6569 HRESULT hr;
6570 DWORD color;
6572 IDirect3DDevice9_GetDirect3D(device, &d3d);
6573 /* Ask for srgb writing on D3DRTYPE_TEXTURE. Some Windows drivers do not report it on surfaces.
6574 * For some not entirely understood reasons D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE
6575 * passes on surfaces, while asking for SRGBWRITE alone fails. Textures advertize srgb writing
6576 * alone as well, so use that since it is not the point of this test to show how CheckDeviceFormat
6577 * works
6579 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6580 D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE,
6581 D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8) != D3D_OK) {
6582 skip("No SRGBWRITEENABLE support on D3DFMT_X8R8G8B8\n");
6583 IDirect3D9_Release(d3d);
6584 return;
6586 IDirect3D9_Release(d3d);
6588 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
6589 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
6591 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
6592 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6593 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
6594 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6595 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
6596 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6597 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffffffff);
6598 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6599 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
6600 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6602 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
6603 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6604 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code, &pshader);
6605 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
6606 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6607 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
6608 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
6609 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6610 hr = IDirect3DDevice9_SetPixelShader(device, pshader);
6611 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
6613 hr = IDirect3DDevice9_BeginScene(device);
6614 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
6615 if(SUCCEEDED(hr)) {
6616 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 3);
6617 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6619 hr = IDirect3DDevice9_EndScene(device);
6620 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
6623 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6624 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6625 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6626 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
6627 IDirect3DPixelShader9_Release(pshader);
6628 IDirect3DVertexShader9_Release(vshader);
6630 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
6631 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6632 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
6633 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6635 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6636 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6637 color = getPixelColor(device, 160, 360);
6638 ok(color == 0x00808080 || color == 0x007f7f7f || color == 0x00818181,
6639 "Fog with D3DRS_SRGBWRITEENABLE returned color 0x%08x, expected 0x00808080\n", color);
6642 static void alpha_test(IDirect3DDevice9 *device)
6644 HRESULT hr;
6645 IDirect3DTexture9 *offscreenTexture;
6646 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
6647 DWORD color, red, green, blue;
6649 struct vertex quad1[] =
6651 {-1.0f, -1.0f, 0.1f, 0x4000ff00},
6652 {-1.0f, 0.0f, 0.1f, 0x4000ff00},
6653 { 1.0f, -1.0f, 0.1f, 0x4000ff00},
6654 { 1.0f, 0.0f, 0.1f, 0x4000ff00},
6656 struct vertex quad2[] =
6658 {-1.0f, 0.0f, 0.1f, 0xc00000ff},
6659 {-1.0f, 1.0f, 0.1f, 0xc00000ff},
6660 { 1.0f, 0.0f, 0.1f, 0xc00000ff},
6661 { 1.0f, 1.0f, 0.1f, 0xc00000ff},
6663 static const float composite_quad[][5] = {
6664 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
6665 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
6666 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
6667 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
6670 /* Clear the render target with alpha = 0.5 */
6671 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6672 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6674 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
6675 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
6677 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6678 ok(hr == D3D_OK, "Can't get back buffer, hr = %s\n", DXGetErrorString9(hr));
6679 if(!backbuffer) {
6680 goto out;
6683 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
6684 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %s\n", DXGetErrorString9(hr));
6685 if(!offscreen) {
6686 goto out;
6689 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6690 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6692 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6693 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
6694 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6695 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
6696 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
6697 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
6698 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
6699 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
6700 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6701 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6703 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
6704 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6705 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
6707 /* Draw two quads, one with src alpha blending, one with dest alpha blending. The
6708 * SRCALPHA / INVSRCALPHA blend doesn't give any surprises. Colors are blended based on
6709 * the input alpha
6711 * The DESTALPHA / INVDESTALPHA do not "work" on the regular buffer because there is no alpha.
6712 * They give essentially ZERO and ONE blend factors
6714 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6715 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6716 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6717 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6718 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6719 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6721 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6722 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6723 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6724 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6725 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6726 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6728 /* Switch to the offscreen buffer, and redo the testing. SRCALPHA and DESTALPHA. The offscreen buffer
6729 * has a alpha channel on its own. Clear the offscreen buffer with alpha = 0.5 again, then draw the
6730 * quads again. The SRCALPHA/INVSRCALPHA doesn't give any surprises, but the DESTALPHA/INVDESTALPHA
6731 * blending works as supposed now - blend factor is 0.5 in both cases, not 0.75 as from the input
6732 * vertices
6734 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
6735 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6736 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6737 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6739 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6740 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6741 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6742 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6743 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6744 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6746 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6747 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6748 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6749 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6750 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6751 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6753 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
6754 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6756 /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
6757 * Disable alpha blending for the final composition
6759 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
6760 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6761 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6762 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6764 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
6765 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6766 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
6767 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6768 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6769 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6771 hr = IDirect3DDevice9_EndScene(device);
6772 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
6775 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6777 color = getPixelColor(device, 160, 360);
6778 red = (color & 0x00ff0000) >> 16;
6779 green = (color & 0x0000ff00) >> 8;
6780 blue = (color & 0x000000ff);
6781 ok(red >= 0xbe && red <= 0xc0 && green >= 0x39 && green <= 0x41 && blue == 0x00,
6782 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
6784 color = getPixelColor(device, 160, 120);
6785 red = (color & 0x00ff0000) >> 16;
6786 green = (color & 0x0000ff00) >> 8;
6787 blue = (color & 0x000000ff);
6788 ok(red == 0x00 && green == 0x00 && blue >= 0xfe && blue <= 0xff ,
6789 "DSTALPHA on frame buffer returned color %08x, expected 0x00ff0000\n", color);
6791 color = getPixelColor(device, 480, 360);
6792 red = (color & 0x00ff0000) >> 16;
6793 green = (color & 0x0000ff00) >> 8;
6794 blue = (color & 0x000000ff);
6795 ok(red >= 0xbe && red <= 0xc0 && green >= 0x39 && green <= 0x41 && blue == 0x00,
6796 "SRCALPHA on texture returned color %08x, expected bar\n", color);
6798 color = getPixelColor(device, 480, 120);
6799 red = (color & 0x00ff0000) >> 16;
6800 green = (color & 0x0000ff00) >> 8;
6801 blue = (color & 0x000000ff);
6802 ok(red >= 0x7e && red <= 0x81 && green == 0x00 && blue >= 0x7e && blue <= 0x81,
6803 "DSTALPHA on texture returned color %08x, expected 0x00800080\n", color);
6805 out:
6806 /* restore things */
6807 if(backbuffer) {
6808 IDirect3DSurface9_Release(backbuffer);
6810 if(offscreenTexture) {
6811 IDirect3DTexture9_Release(offscreenTexture);
6813 if(offscreen) {
6814 IDirect3DSurface9_Release(offscreen);
6818 struct vertex_shortcolor {
6819 float x, y, z;
6820 unsigned short r, g, b, a;
6822 struct vertex_floatcolor {
6823 float x, y, z;
6824 float r, g, b, a;
6827 static void fixed_function_decl_test(IDirect3DDevice9 *device)
6829 HRESULT hr;
6830 BOOL s_ok, ub_ok, f_ok;
6831 DWORD color, size, i;
6832 void *data;
6833 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
6834 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6835 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6836 D3DDECL_END()
6838 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
6839 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6840 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6841 D3DDECL_END()
6843 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
6844 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6845 {0, 12, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6846 D3DDECL_END()
6848 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
6849 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6850 {1, 0, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6851 D3DDECL_END()
6853 static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
6854 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6855 {0, 12, D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6856 D3DDECL_END()
6858 static const D3DVERTEXELEMENT9 decl_elements_float[] = {
6859 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6860 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6861 D3DDECL_END()
6863 static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
6864 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
6865 {0, 16, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6866 D3DDECL_END()
6868 IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
6869 IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
6870 IDirect3DVertexBuffer9 *vb, *vb2;
6871 struct vertex quad1[] = /* D3DCOLOR */
6873 {-1.0f, -1.0f, 0.1f, 0x00ffff00},
6874 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
6875 { 0.0f, -1.0f, 0.1f, 0x00ffff00},
6876 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
6878 struct vertex quad2[] = /* UBYTE4N */
6880 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
6881 {-1.0f, 1.0f, 0.1f, 0x00ffff00},
6882 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
6883 { 0.0f, 1.0f, 0.1f, 0x00ffff00},
6885 struct vertex_shortcolor quad3[] = /* short */
6887 { 0.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6888 { 0.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6889 { 1.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6890 { 1.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6892 struct vertex_floatcolor quad4[] =
6894 { 0.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6895 { 0.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6896 { 1.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6897 { 1.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6899 DWORD colors[] = {
6900 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6901 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6902 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6903 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6904 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6905 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6906 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6907 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6908 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6909 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6910 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6911 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6912 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6913 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6914 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6915 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6917 float quads[] = {
6918 -1.0, -1.0, 0.1,
6919 -1.0, 0.0, 0.1,
6920 0.0, -1.0, 0.1,
6921 0.0, 0.0, 0.1,
6923 0.0, -1.0, 0.1,
6924 0.0, 0.0, 0.1,
6925 1.0, -1.0, 0.1,
6926 1.0, 0.0, 0.1,
6928 0.0, 0.0, 0.1,
6929 0.0, 1.0, 0.1,
6930 1.0, 0.0, 0.1,
6931 1.0, 1.0, 0.1,
6933 -1.0, 0.0, 0.1,
6934 -1.0, 1.0, 0.1,
6935 0.0, 0.0, 0.1,
6936 0.0, 1.0, 0.1
6938 struct tvertex quad_transformed[] = {
6939 { 90, 110, 0.1, 2.0, 0x00ffff00},
6940 { 570, 110, 0.1, 2.0, 0x00ffff00},
6941 { 90, 300, 0.1, 2.0, 0x00ffff00},
6942 { 570, 300, 0.1, 2.0, 0x00ffff00}
6944 D3DCAPS9 caps;
6946 memset(&caps, 0, sizeof(caps));
6947 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6948 ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
6950 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6951 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6953 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
6954 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6955 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
6956 ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
6957 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
6958 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6959 if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
6960 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
6961 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6962 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
6963 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6964 } else {
6965 trace("D3DDTCAPS_UBYTE4N not supported\n");
6966 dcl_ubyte_2 = NULL;
6967 dcl_ubyte = NULL;
6969 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
6970 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6971 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
6972 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6974 size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
6975 hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
6976 0, 0, D3DPOOL_MANAGED, &vb, NULL);
6977 ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
6979 hr = IDirect3DDevice9_BeginScene(device);
6980 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
6981 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
6982 if(SUCCEEDED(hr)) {
6983 if(dcl_color) {
6984 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
6985 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6986 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6987 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6990 /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
6991 * accepts them, the nvidia driver accepts them all. All those differences even though we're
6992 * using software vertex processing. Doh!
6994 if(dcl_ubyte) {
6995 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
6996 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6997 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6998 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6999 ub_ok = SUCCEEDED(hr);
7002 if(dcl_short) {
7003 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7004 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7005 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
7006 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7007 s_ok = SUCCEEDED(hr);
7010 if(dcl_float) {
7011 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7012 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7013 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
7014 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
7015 f_ok = SUCCEEDED(hr);
7018 hr = IDirect3DDevice9_EndScene(device);
7019 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7022 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7023 if(dcl_short) {
7024 color = getPixelColor(device, 480, 360);
7025 ok(color == 0x000000ff || !s_ok,
7026 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7028 if(dcl_ubyte) {
7029 color = getPixelColor(device, 160, 120);
7030 ok(color == 0x0000ffff || !ub_ok,
7031 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7033 if(dcl_color) {
7034 color = getPixelColor(device, 160, 360);
7035 ok(color == 0x00ffff00,
7036 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7038 if(dcl_float) {
7039 color = getPixelColor(device, 480, 120);
7040 ok(color == 0x00ff0000 || !f_ok,
7041 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7044 /* The following test with vertex buffers doesn't serve to find out new information from windows.
7045 * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7046 * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7047 * whether the immediate mode code works
7049 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7050 hr = IDirect3DDevice9_BeginScene(device);
7051 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7052 if(SUCCEEDED(hr)) {
7053 if(dcl_color) {
7054 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), (void **) &data, 0);
7055 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7056 memcpy(data, quad1, sizeof(quad1));
7057 hr = IDirect3DVertexBuffer9_Unlock(vb);
7058 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7059 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7060 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7061 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7062 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7063 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7064 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7067 if(dcl_ubyte) {
7068 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), (void **) &data, 0);
7069 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7070 memcpy(data, quad2, sizeof(quad2));
7071 hr = IDirect3DVertexBuffer9_Unlock(vb);
7072 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7073 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7074 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7075 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7076 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7077 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7078 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7079 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7080 ub_ok = SUCCEEDED(hr);
7083 if(dcl_short) {
7084 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), (void **) &data, 0);
7085 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7086 memcpy(data, quad3, sizeof(quad3));
7087 hr = IDirect3DVertexBuffer9_Unlock(vb);
7088 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7089 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7090 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7091 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7092 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7093 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7094 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7095 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7096 s_ok = SUCCEEDED(hr);
7099 if(dcl_float) {
7100 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), (void **) &data, 0);
7101 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7102 memcpy(data, quad4, sizeof(quad4));
7103 hr = IDirect3DVertexBuffer9_Unlock(vb);
7104 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7105 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7106 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7107 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7108 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7109 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7110 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7111 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7112 f_ok = SUCCEEDED(hr);
7115 hr = IDirect3DDevice9_EndScene(device);
7116 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7119 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7120 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7121 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7122 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7124 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7125 if(dcl_short) {
7126 color = getPixelColor(device, 480, 360);
7127 ok(color == 0x000000ff || !s_ok,
7128 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7130 if(dcl_ubyte) {
7131 color = getPixelColor(device, 160, 120);
7132 ok(color == 0x0000ffff || !ub_ok,
7133 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7135 if(dcl_color) {
7136 color = getPixelColor(device, 160, 360);
7137 ok(color == 0x00ffff00,
7138 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7140 if(dcl_float) {
7141 color = getPixelColor(device, 480, 120);
7142 ok(color == 0x00ff0000 || !f_ok,
7143 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7146 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7147 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
7149 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), (void **) &data, 0);
7150 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7151 memcpy(data, quad_transformed, sizeof(quad_transformed));
7152 hr = IDirect3DVertexBuffer9_Unlock(vb);
7153 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7155 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7156 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7158 hr = IDirect3DDevice9_BeginScene(device);
7159 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7160 if(SUCCEEDED(hr)) {
7161 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7162 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7163 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7164 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7166 hr = IDirect3DDevice9_EndScene(device);
7167 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7170 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7171 color = getPixelColor(device, 88, 108);
7172 ok(color == 0x000000ff,
7173 "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7174 color = getPixelColor(device, 92, 108);
7175 ok(color == 0x000000ff,
7176 "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7177 color = getPixelColor(device, 88, 112);
7178 ok(color == 0x000000ff,
7179 "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7180 color = getPixelColor(device, 92, 112);
7181 ok(color == 0x00ffff00,
7182 "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7184 color = getPixelColor(device, 568, 108);
7185 ok(color == 0x000000ff,
7186 "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7187 color = getPixelColor(device, 572, 108);
7188 ok(color == 0x000000ff,
7189 "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7190 color = getPixelColor(device, 568, 112);
7191 ok(color == 0x00ffff00,
7192 "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7193 color = getPixelColor(device, 572, 112);
7194 ok(color == 0x000000ff,
7195 "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7197 color = getPixelColor(device, 88, 298);
7198 ok(color == 0x000000ff,
7199 "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7200 color = getPixelColor(device, 92, 298);
7201 ok(color == 0x00ffff00,
7202 "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7203 color = getPixelColor(device, 88, 302);
7204 ok(color == 0x000000ff,
7205 "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7206 color = getPixelColor(device, 92, 302);
7207 ok(color == 0x000000ff,
7208 "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7210 color = getPixelColor(device, 568, 298);
7211 ok(color == 0x00ffff00,
7212 "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7213 color = getPixelColor(device, 572, 298);
7214 ok(color == 0x000000ff,
7215 "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7216 color = getPixelColor(device, 568, 302);
7217 ok(color == 0x000000ff,
7218 "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7219 color = getPixelColor(device, 572, 302);
7220 ok(color == 0x000000ff,
7221 "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7223 /* This test is pointless without those two declarations: */
7224 if((!dcl_color_2) || (!dcl_ubyte_2)) {
7225 skip("color-ubyte switching test declarations aren't supported\n");
7226 goto out;
7229 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), (void **) &data, 0);
7230 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7231 memcpy(data, quads, sizeof(quads));
7232 hr = IDirect3DVertexBuffer9_Unlock(vb);
7233 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7234 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7235 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7236 ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
7237 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), (void **) &data, 0);
7238 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7239 memcpy(data, colors, sizeof(colors));
7240 hr = IDirect3DVertexBuffer9_Unlock(vb2);
7241 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7243 for(i = 0; i < 2; i++) {
7244 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7245 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
7247 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7248 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7249 if(i == 0) {
7250 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7251 } else {
7252 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7254 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7256 hr = IDirect3DDevice9_BeginScene(device);
7257 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
7258 ub_ok = FALSE;
7259 if(SUCCEEDED(hr)) {
7260 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7261 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7262 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7263 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7264 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7265 ub_ok = SUCCEEDED(hr);
7267 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7268 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7269 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7270 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7272 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7273 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7274 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7275 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7276 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7277 ub_ok = (SUCCEEDED(hr) && ub_ok);
7279 hr = IDirect3DDevice9_EndScene(device);
7280 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
7283 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7284 if(i == 0) {
7285 color = getPixelColor(device, 480, 360);
7286 ok(color == 0x00ff0000,
7287 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7288 color = getPixelColor(device, 160, 120);
7289 ok(color == 0x00ffffff,
7290 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7291 color = getPixelColor(device, 160, 360);
7292 ok(color == 0x000000ff || !ub_ok,
7293 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7294 color = getPixelColor(device, 480, 120);
7295 ok(color == 0x000000ff || !ub_ok,
7296 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7297 } else {
7298 color = getPixelColor(device, 480, 360);
7299 ok(color == 0x000000ff,
7300 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7301 color = getPixelColor(device, 160, 120);
7302 ok(color == 0x00ffffff,
7303 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7304 color = getPixelColor(device, 160, 360);
7305 ok(color == 0x00ff0000 || !ub_ok,
7306 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7307 color = getPixelColor(device, 480, 120);
7308 ok(color == 0x00ff0000 || !ub_ok,
7309 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7313 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7314 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7315 hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7316 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7317 IDirect3DVertexBuffer9_Release(vb2);
7319 out:
7320 IDirect3DVertexBuffer9_Release(vb);
7321 if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7322 if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7323 if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7324 if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7325 if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7326 if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7327 if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7330 struct vertex_float16color {
7331 float x, y, z;
7332 DWORD c1, c2;
7335 static void test_vshader_float16(IDirect3DDevice9 *device)
7337 HRESULT hr;
7338 DWORD color;
7339 void *data;
7340 static const D3DVERTEXELEMENT9 decl_elements[] = {
7341 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7342 {0, 12, D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7343 D3DDECL_END()
7345 IDirect3DVertexDeclaration9 *vdecl = NULL;
7346 IDirect3DVertexBuffer9 *buffer = NULL;
7347 IDirect3DVertexShader9 *shader;
7348 DWORD shader_code[] = {
7349 0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7350 0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7351 0x90e40001, 0x0000ffff
7353 struct vertex_float16color quad[] = {
7354 { -1.0, -1.0, 0.1, 0x3c000000, 0x00000000 }, /* green */
7355 { -1.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
7356 { 0.0, -1.0, 0.1, 0x3c000000, 0x00000000 },
7357 { 0.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
7359 { 0.0, -1.0, 0.1, 0x00003c00, 0x00000000 }, /* red */
7360 { 0.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
7361 { 1.0, -1.0, 0.1, 0x00003c00, 0x00000000 },
7362 { 1.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
7364 { 0.0, 0.0, 0.1, 0x00000000, 0x00003c00 }, /* blue */
7365 { 0.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
7366 { 1.0, 0.0, 0.1, 0x00000000, 0x00003c00 },
7367 { 1.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
7369 { -1.0, 0.0, 0.1, 0x00000000, 0x3c000000 }, /* alpha */
7370 { -1.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
7371 { 0.0, 0.0, 0.1, 0x00000000, 0x3c000000 },
7372 { 0.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
7375 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7376 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7378 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7379 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%s\n", DXGetErrorString9(hr));
7380 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7381 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%s\n", DXGetErrorString9(hr));
7382 hr = IDirect3DDevice9_SetVertexShader(device, shader);
7383 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%s\n", DXGetErrorString9(hr));
7385 hr = IDirect3DDevice9_BeginScene(device);
7386 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
7387 if(SUCCEEDED(hr)) {
7388 hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7389 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%s\n", DXGetErrorString9(hr));
7390 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 0, sizeof(quad[0]));
7391 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7392 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 4, sizeof(quad[0]));
7393 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7394 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 8, sizeof(quad[0]));
7395 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7396 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7397 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7399 hr = IDirect3DDevice9_EndScene(device);
7400 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%s\n", DXGetErrorString9(hr));
7402 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7403 color = getPixelColor(device, 480, 360);
7404 ok(color == 0x00ff0000,
7405 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7406 color = getPixelColor(device, 160, 120);
7407 ok(color == 0x00000000,
7408 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7409 color = getPixelColor(device, 160, 360);
7410 ok(color == 0x0000ff00,
7411 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7412 color = getPixelColor(device, 480, 120);
7413 ok(color == 0x000000ff,
7414 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7416 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7417 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7419 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7420 D3DPOOL_MANAGED, &buffer, NULL);
7421 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%s\n", DXGetErrorString9(hr));
7422 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), (void **) &data, 0);
7423 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%s\n", DXGetErrorString9(hr));
7424 memcpy(data, quad, sizeof(quad));
7425 hr = IDirect3DVertexBuffer9_Unlock(buffer);
7426 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%s\n", DXGetErrorString9(hr));
7427 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7428 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%s\n", DXGetErrorString9(hr));
7430 hr = IDirect3DDevice9_BeginScene(device);
7431 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7432 if(SUCCEEDED(hr)) {
7433 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7434 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7435 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7436 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7437 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7438 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7439 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7440 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7442 hr = IDirect3DDevice9_EndScene(device);
7443 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%s\n", DXGetErrorString9(hr));
7446 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7447 color = getPixelColor(device, 480, 360);
7448 ok(color == 0x00ff0000,
7449 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7450 color = getPixelColor(device, 160, 120);
7451 ok(color == 0x00000000,
7452 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7453 color = getPixelColor(device, 160, 360);
7454 ok(color == 0x0000ff00,
7455 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7456 color = getPixelColor(device, 480, 120);
7457 ok(color == 0x000000ff,
7458 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7460 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7461 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%s\n", DXGetErrorString9(hr));
7462 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7463 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%s\n", DXGetErrorString9(hr));
7464 IDirect3DDevice9_SetVertexShader(device, NULL);
7465 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%s\n", DXGetErrorString9(hr));
7467 IDirect3DVertexDeclaration9_Release(vdecl);
7468 IDirect3DVertexShader9_Release(shader);
7469 IDirect3DVertexBuffer9_Release(buffer);
7472 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7474 D3DCAPS9 caps;
7475 IDirect3DTexture9 *texture;
7476 HRESULT hr;
7477 D3DLOCKED_RECT rect;
7478 unsigned int x, y;
7479 DWORD *dst, color;
7480 const float quad[] = {
7481 -1.0, -1.0, 0.1, -0.2, -0.2,
7482 1.0, -1.0, 0.1, 1.2, -0.2,
7483 -1.0, 1.0, 0.1, -0.2, 1.2,
7484 1.0, 1.0, 0.1, 1.2, 1.2
7486 memset(&caps, 0, sizeof(caps));
7488 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7489 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%s\n", DXGetErrorString9(hr));
7490 if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7491 /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7492 ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
7493 "Card has conditional NP2 support without power of two restriction set\n");
7494 skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
7495 return;
7496 } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7497 skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7498 return;
7501 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7502 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7504 hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7505 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%s\n", DXGetErrorString9(hr));
7507 memset(&rect, 0, sizeof(rect));
7508 hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7509 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%s\n", DXGetErrorString9(hr));
7510 for(y = 0; y < 10; y++) {
7511 for(x = 0; x < 10; x++) {
7512 dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7513 if(x == 0 || x == 9 || y == 0 || y == 9) {
7514 *dst = 0x00ff0000;
7515 } else {
7516 *dst = 0x000000ff;
7520 hr = IDirect3DTexture9_UnlockRect(texture, 0);
7521 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%s\n", DXGetErrorString9(hr));
7523 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7524 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%s\n", DXGetErrorString9(hr));
7525 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
7526 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%s\n", DXGetErrorString9(hr));
7527 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
7528 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%s\n", DXGetErrorString9(hr));
7529 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7530 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%s\n", DXGetErrorString9(hr));
7532 hr = IDirect3DDevice9_BeginScene(device);
7533 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
7534 if(SUCCEEDED(hr)) {
7535 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7536 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7538 hr = IDirect3DDevice9_EndScene(device);
7539 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
7542 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7544 color = getPixelColor(device, 1, 1);
7545 ok(color == 0x00ff0000, "NP2: Pixel 1, 1 has color %08x, expected 0x00ff0000\n", color);
7546 color = getPixelColor(device, 639, 479);
7547 ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
7549 color = getPixelColor(device, 135, 101);
7550 ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
7551 color = getPixelColor(device, 140, 101);
7552 ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
7553 color = getPixelColor(device, 135, 105);
7554 ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
7555 color = getPixelColor(device, 140, 105);
7556 ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
7558 color = getPixelColor(device, 135, 376);
7559 ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
7560 color = getPixelColor(device, 140, 376);
7561 ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
7562 color = getPixelColor(device, 135, 379);
7563 ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
7564 color = getPixelColor(device, 140, 379);
7565 ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
7567 color = getPixelColor(device, 500, 101);
7568 ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
7569 color = getPixelColor(device, 504, 101);
7570 ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
7571 color = getPixelColor(device, 500, 105);
7572 ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
7573 color = getPixelColor(device, 504, 105);
7574 ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
7576 color = getPixelColor(device, 500, 376);
7577 ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
7578 color = getPixelColor(device, 504, 376);
7579 ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
7580 color = getPixelColor(device, 500, 380);
7581 ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
7582 color = getPixelColor(device, 504, 380);
7583 ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
7585 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7586 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%s\n", DXGetErrorString9(hr));
7587 IDirect3DTexture9_Release(texture);
7590 static void vFace_register_test(IDirect3DDevice9 *device)
7592 HRESULT hr;
7593 DWORD color;
7594 const DWORD shader_code[] = {
7595 0xffff0300, /* ps_3_0 */
7596 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
7597 0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
7598 0x0200001f, 0x80000000, 0x900f1001, /* dcl vFace */
7599 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
7600 0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001, /* cmp r0, vFace, c0, r1 */
7601 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
7602 0x0000ffff /* END */
7604 IDirect3DPixelShader9 *shader;
7605 IDirect3DTexture9 *texture;
7606 IDirect3DSurface9 *surface, *backbuffer;
7607 const float quad[] = {
7608 -1.0, -1.0, 0.1,
7609 1.0, -1.0, 0.1,
7610 -1.0, 0.0, 0.1,
7612 1.0, -1.0, 0.1,
7613 1.0, 0.0, 0.1,
7614 -1.0, 0.0, 0.1,
7616 -1.0, 0.0, 0.1,
7617 -1.0, 1.0, 0.1,
7618 1.0, 0.0, 0.1,
7620 1.0, 0.0, 0.1,
7621 -1.0, 1.0, 0.1,
7622 1.0, 1.0, 0.1,
7624 const float blit[] = {
7625 0.0, -1.0, 0.1, 0.0, 0.0,
7626 1.0, -1.0, 0.1, 1.0, 0.0,
7627 0.0, 1.0, 0.1, 0.0, 1.0,
7628 1.0, 1.0, 0.1, 1.0, 1.0,
7631 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
7632 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%s\n", DXGetErrorString9(hr));
7633 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
7634 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%s\n", DXGetErrorString9(hr));
7635 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7636 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%s\n", DXGetErrorString9(hr));
7637 hr = IDirect3DDevice9_SetPixelShader(device, shader);
7638 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
7639 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7640 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%s\n", DXGetErrorString9(hr));
7641 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7642 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%s\n", DXGetErrorString9(hr));
7644 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7645 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7647 hr = IDirect3DDevice9_BeginScene(device);
7648 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
7649 if(SUCCEEDED(hr)) {
7650 /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
7651 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
7652 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
7653 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7654 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7655 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7656 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7657 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7658 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
7659 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7660 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7662 /* Blit the texture onto the back buffer to make it visible */
7663 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7664 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%s\n", DXGetErrorString9(hr));
7665 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7666 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%s\n", DXGetErrorString9(hr));
7667 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7668 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%s\n", DXGetErrorString9(hr));
7669 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7670 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%s\n", DXGetErrorString9(hr));
7671 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7672 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%s\n", DXGetErrorString9(hr));
7674 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
7675 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7677 hr = IDirect3DDevice9_EndScene(device);
7678 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
7681 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7682 color = getPixelColor(device, 160, 360);
7683 ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7684 color = getPixelColor(device, 160, 120);
7685 ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7686 color = getPixelColor(device, 480, 360);
7687 ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7688 color = getPixelColor(device, 480, 120);
7689 ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7691 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
7692 IDirect3DDevice9_SetTexture(device, 0, NULL);
7693 IDirect3DPixelShader9_Release(shader);
7694 IDirect3DSurface9_Release(surface);
7695 IDirect3DSurface9_Release(backbuffer);
7696 IDirect3DTexture9_Release(texture);
7699 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
7701 HRESULT hr;
7702 DWORD color;
7703 int i;
7704 D3DCAPS9 caps;
7706 static const float quad[][7] = {
7707 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
7708 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
7709 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
7710 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
7713 static const D3DVERTEXELEMENT9 decl_elements[] = {
7714 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7715 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7716 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7717 D3DDECL_END()
7720 /* use asymmetric matrix to test loading */
7721 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
7723 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
7724 IDirect3DTexture9 *texture = NULL;
7726 memset(&caps, 0, sizeof(caps));
7727 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7728 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%s\n", DXGetErrorString9(hr));
7729 if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
7730 skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
7731 return;
7732 } else {
7733 /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
7734 * They report that it is not supported, but after that bump mapping works properly. So just test
7735 * if the format is generally supported, and check the BUMPENVMAP flag
7737 IDirect3D9 *d3d9;
7739 IDirect3DDevice9_GetDirect3D(device, &d3d9);
7740 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7741 D3DRTYPE_TEXTURE, D3DFMT_V8U8);
7742 IDirect3D9_Release(d3d9);
7743 if(FAILED(hr)) {
7744 skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
7745 return;
7749 /* Generate the textures */
7750 generate_bumpmap_textures(device);
7752 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
7753 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7754 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
7755 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7756 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
7757 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7758 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
7759 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7761 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
7762 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7763 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
7764 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7765 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
7766 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7768 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7769 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7770 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7771 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7772 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7773 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7775 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
7776 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7778 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7779 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
7781 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
7782 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
7785 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
7786 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
7787 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
7788 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
7790 hr = IDirect3DDevice9_BeginScene(device);
7791 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7793 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7794 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7796 hr = IDirect3DDevice9_EndScene(device);
7797 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7799 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7800 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7802 color = getPixelColor(device, 320-32, 240);
7803 ok(color == 0x00ffffff, "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7804 color = getPixelColor(device, 320+32, 240);
7805 ok(color == 0x00ffffff, "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7806 color = getPixelColor(device, 320, 240-32);
7807 ok(color == 0x00ffffff, "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7808 color = getPixelColor(device, 320, 240+32);
7809 ok(color == 0x00ffffff, "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7810 color = getPixelColor(device, 320, 240);
7811 ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7812 color = getPixelColor(device, 320+32, 240+32);
7813 ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7814 color = getPixelColor(device, 320-32, 240+32);
7815 ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7816 color = getPixelColor(device, 320+32, 240-32);
7817 ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7818 color = getPixelColor(device, 320-32, 240-32);
7819 ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7821 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7822 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
7823 IDirect3DVertexDeclaration9_Release(vertex_declaration);
7825 for(i = 0; i < 2; i++) {
7826 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
7827 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
7828 IDirect3DTexture9_Release(texture); /* For the GetTexture */
7829 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
7830 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
7831 IDirect3DTexture9_Release(texture); /* To destroy it */
7834 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
7835 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7836 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
7837 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7841 static void stencil_cull_test(IDirect3DDevice9 *device) {
7842 HRESULT hr;
7843 IDirect3DSurface9 *depthstencil = NULL;
7844 D3DSURFACE_DESC desc;
7845 float quad1[] = {
7846 -1.0, -1.0, 0.1,
7847 0.0, -1.0, 0.1,
7848 -1.0, 0.0, 0.1,
7849 0.0, 0.0, 0.1,
7851 float quad2[] = {
7852 0.0, -1.0, 0.1,
7853 1.0, -1.0, 0.1,
7854 0.0, 0.0, 0.1,
7855 1.0, 0.0, 0.1,
7857 float quad3[] = {
7858 0.0, 0.0, 0.1,
7859 1.0, 0.0, 0.1,
7860 0.0, 1.0, 0.1,
7861 1.0, 1.0, 0.1,
7863 float quad4[] = {
7864 -1.0, 0.0, 0.1,
7865 0.0, 0.0, 0.1,
7866 -1.0, 1.0, 0.1,
7867 0.0, 1.0, 0.1,
7869 struct vertex painter[] = {
7870 {-1.0, -1.0, 0.0, 0x00000000},
7871 { 1.0, -1.0, 0.0, 0x00000000},
7872 {-1.0, 1.0, 0.0, 0x00000000},
7873 { 1.0, 1.0, 0.0, 0x00000000},
7875 WORD indices_cw[] = {0, 1, 3};
7876 WORD indices_ccw[] = {0, 2, 3};
7877 unsigned int i;
7878 DWORD color;
7880 IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
7881 if(depthstencil == NULL) {
7882 skip("No depth stencil buffer\n");
7883 return;
7885 hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
7886 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %s\n", DXGetErrorString9(hr));
7887 IDirect3DSurface9_Release(depthstencil);
7888 if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
7889 skip("No 4 or 8 bit stencil surface\n");
7890 return;
7893 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
7894 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
7895 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7897 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
7898 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7899 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
7900 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7901 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
7902 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7903 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
7904 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7906 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
7907 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7908 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
7909 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7910 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
7911 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7913 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
7914 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7915 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
7916 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7918 /* First pass: Fill the stencil buffer with some values... */
7919 hr = IDirect3DDevice9_BeginScene(device);
7920 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
7921 if(SUCCEEDED(hr))
7923 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
7924 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7925 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7926 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
7927 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7928 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
7930 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
7931 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7932 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
7933 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7934 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7935 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
7936 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7937 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
7939 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
7940 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7941 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7942 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
7943 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7944 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
7946 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
7947 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7948 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7949 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
7950 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7951 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
7953 hr = IDirect3DDevice9_EndScene(device);
7954 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
7957 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7958 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
7959 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7960 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
7961 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7962 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
7963 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7964 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
7965 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7966 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
7967 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7968 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
7969 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7971 /* 2nd pass: Make the stencil values visible */
7972 hr = IDirect3DDevice9_BeginScene(device);
7973 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
7974 if(SUCCEEDED(hr))
7976 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
7977 for(i = 0; i < 16; i++) {
7978 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
7979 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7981 painter[0].diffuse = (i * 16); /* Creates shades of blue */
7982 painter[1].diffuse = (i * 16);
7983 painter[2].diffuse = (i * 16);
7984 painter[3].diffuse = (i * 16);
7985 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
7986 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
7988 hr = IDirect3DDevice9_EndScene(device);
7989 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
7992 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7993 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
7995 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
7996 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7998 color = getPixelColor(device, 160, 420);
7999 ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
8000 color = getPixelColor(device, 160, 300);
8001 ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8003 color = getPixelColor(device, 480, 420);
8004 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
8005 color = getPixelColor(device, 480, 300);
8006 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
8008 color = getPixelColor(device, 160, 180);
8009 ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
8010 color = getPixelColor(device, 160, 60);
8011 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
8013 color = getPixelColor(device, 480, 180);
8014 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
8015 color = getPixelColor(device, 480, 60);
8016 ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
8019 static void vpos_register_test(IDirect3DDevice9 *device)
8021 HRESULT hr;
8022 DWORD color;
8023 const DWORD shader_code[] = {
8024 0xffff0300, /* ps_3_0 */
8025 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8026 0x03000002, 0x80030000, 0x90541000, 0xa1fe0000, /* sub r0.xy, vPos.xy, c0.zw */
8027 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
8028 0x02000001, 0x80080002, 0xa0550000, /* mov r2.a, c0.y */
8029 0x02000001, 0x80010002, 0xa0550000, /* mov r2.r, c0.y */
8030 0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001, /* cmp r2.g, r0.x, r1.x, r1.y */
8031 0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001, /* cmp r2.b, r0.y, r1.x, r1.y */
8032 0x02000001, 0x800f0800, 0x80e40002, /* mov oC0, r2 */
8033 0x0000ffff /* end */
8035 const DWORD shader_frac_code[] = {
8036 0xffff0300, /* ps_3_0 */
8037 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8038 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8039 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
8040 0x02000013, 0x80030000, 0x90541000, /* frc r0.xy, vPos.xy */
8041 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
8042 0x0000ffff /* end */
8044 IDirect3DPixelShader9 *shader, *shader_frac;
8045 IDirect3DSurface9 *surface = NULL, *backbuffer;
8046 const float quad[] = {
8047 -1.0, -1.0, 0.1, 0.0, 0.0,
8048 1.0, -1.0, 0.1, 1.0, 0.0,
8049 -1.0, 1.0, 0.1, 0.0, 1.0,
8050 1.0, 1.0, 0.1, 1.0, 1.0,
8052 D3DLOCKED_RECT lr;
8053 float constant[4] = {1.0, 0.0, 320, 240};
8054 DWORD *pos;
8056 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8057 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
8058 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8059 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%s\n", DXGetErrorString9(hr));
8060 hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8061 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%s\n", DXGetErrorString9(hr));
8062 hr = IDirect3DDevice9_SetPixelShader(device, shader);
8063 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
8064 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8065 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%s\n", DXGetErrorString9(hr));
8066 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8067 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%s\n", DXGetErrorString9(hr));
8069 hr = IDirect3DDevice9_BeginScene(device);
8070 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
8071 if(SUCCEEDED(hr)) {
8072 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8073 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%s\n", DXGetErrorString9(hr));
8074 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8075 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8076 hr = IDirect3DDevice9_EndScene(device);
8077 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
8080 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8081 /* This has to be pixel exact */
8082 color = getPixelColor(device, 319, 239);
8083 ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8084 color = getPixelColor(device, 320, 239);
8085 ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8086 color = getPixelColor(device, 319, 240);
8087 ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8088 color = getPixelColor(device, 320, 240);
8089 ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8091 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8092 &surface, NULL);
8093 ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%s\n", DXGetErrorString9(hr));
8094 hr = IDirect3DDevice9_BeginScene(device);
8095 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
8096 if(SUCCEEDED(hr)) {
8097 constant[2] = 16; constant[3] = 16;
8098 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8099 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%s\n", DXGetErrorString9(hr));
8100 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8101 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8102 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8103 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8104 hr = IDirect3DDevice9_EndScene(device);
8105 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
8107 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8108 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%s\n", DXGetErrorString9(hr));
8110 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8111 color = *pos & 0x00ffffff;
8112 ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8113 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8114 color = *pos & 0x00ffffff;
8115 ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8116 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8117 color = *pos & 0x00ffffff;
8118 ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8119 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8120 color = *pos & 0x00ffffff;
8121 ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8123 hr = IDirect3DSurface9_UnlockRect(surface);
8124 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%s\n", DXGetErrorString9(hr));
8126 /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8127 * have full control over the multisampling setting inside this test
8129 hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8130 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
8131 hr = IDirect3DDevice9_BeginScene(device);
8132 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
8133 if(SUCCEEDED(hr)) {
8134 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8135 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
8136 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8137 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8138 hr = IDirect3DDevice9_EndScene(device);
8139 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
8141 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8142 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8144 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8145 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%s\n", DXGetErrorString9(hr));
8147 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8148 color = *pos & 0x00ffffff;
8149 ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8151 hr = IDirect3DSurface9_UnlockRect(surface);
8152 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%s\n", DXGetErrorString9(hr));
8154 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8155 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
8156 IDirect3DPixelShader9_Release(shader);
8157 IDirect3DPixelShader9_Release(shader_frac);
8158 if(surface) IDirect3DSurface9_Release(surface);
8159 IDirect3DSurface9_Release(backbuffer);
8162 static void pointsize_test(IDirect3DDevice9 *device)
8164 HRESULT hr;
8165 D3DCAPS9 caps;
8166 D3DMATRIX matrix;
8167 D3DMATRIX identity;
8168 float ptsize, ptsize_orig;
8169 DWORD color;
8171 const float vertices[] = {
8172 64, 64, 0.1,
8173 128, 64, 0.1,
8174 192, 64, 0.1,
8175 256, 64, 0.1,
8176 320, 64, 0.1,
8177 384, 64, 0.1
8180 /* 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 */
8181 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;
8182 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;
8183 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;
8184 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;
8186 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;
8187 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;
8188 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;
8189 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;
8191 memset(&caps, 0, sizeof(caps));
8192 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8193 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%s\n", DXGetErrorString9(hr));
8194 if(caps.MaxPointSize < 32.0) {
8195 skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8196 return;
8199 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8200 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
8201 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8202 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%s\n", DXGetErrorString9(hr));
8203 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8204 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%s\n", DXGetErrorString9(hr));
8205 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8206 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%s\n", DXGetErrorString9(hr));
8208 hr = IDirect3DDevice9_BeginScene(device);
8209 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
8210 if(SUCCEEDED(hr)) {
8211 ptsize = 16.0;
8212 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8213 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8214 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8215 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8217 ptsize = 32.0;
8218 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8219 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8220 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8221 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8223 ptsize = 31.5;
8224 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8225 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8226 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8227 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8229 if(caps.MaxPointSize >= 64.0) {
8230 ptsize = 64.0;
8231 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8232 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8233 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8234 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8236 ptsize = 63.75;
8237 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8238 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8239 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8240 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8243 ptsize = 1.0;
8244 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8245 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8246 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8247 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8249 hr = IDirect3DDevice9_EndScene(device);
8250 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
8252 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8253 color = getPixelColor(device, 64-9, 64-9);
8254 ok(color == 0x000000ff, "pSize: Pixel (64-9),(64-9) has color 0x%08x, expected 0x000000ff\n", color);
8255 color = getPixelColor(device, 64-8, 64-8);
8256 todo_wine ok(color == 0x00ffffff, "pSize: Pixel (64-8),(64-8) has color 0x%08x, expected 0x00ffffff\n", color);
8257 color = getPixelColor(device, 64-7, 64-7);
8258 ok(color == 0x00ffffff, "pSize: Pixel (64-7),(64-7) has color 0x%08x, expected 0x00ffffff\n", color);
8259 color = getPixelColor(device, 64+7, 64+7);
8260 ok(color == 0x00ffffff, "pSize: Pixel (64+7),(64+7) has color 0x%08x, expected 0x00ffffff\n", color);
8261 color = getPixelColor(device, 64+8, 64+8);
8262 ok(color == 0x000000ff, "pSize: Pixel (64+8),(64+8) has color 0x%08x, expected 0x000000ff\n", color);
8263 color = getPixelColor(device, 64+9, 64+9);
8264 ok(color == 0x000000ff, "pSize: Pixel (64+9),(64+9) has color 0x%08x, expected 0x000000ff\n", color);
8266 color = getPixelColor(device, 128-17, 64-17);
8267 ok(color == 0x000000ff, "pSize: Pixel (128-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8268 color = getPixelColor(device, 128-16, 64-16);
8269 todo_wine ok(color == 0x00ffffff, "pSize: Pixel (128-16),(64-16) has color 0x%08x, expected 0x00ffffff\n", color);
8270 color = getPixelColor(device, 128-15, 64-15);
8271 ok(color == 0x00ffffff, "pSize: Pixel (128-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8272 color = getPixelColor(device, 128+15, 64+15);
8273 ok(color == 0x00ffffff, "pSize: Pixel (128+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8274 color = getPixelColor(device, 128+16, 64+16);
8275 ok(color == 0x000000ff, "pSize: Pixel (128+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8276 color = getPixelColor(device, 128+17, 64+17);
8277 ok(color == 0x000000ff, "pSize: Pixel (128+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8279 color = getPixelColor(device, 192-17, 64-17);
8280 ok(color == 0x000000ff, "pSize: Pixel (192-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8281 color = getPixelColor(device, 192-16, 64-16);
8282 ok(color == 0x000000ff, "pSize: Pixel (192-16),(64-16) has color 0x%08x, expected 0x000000ff\n", color);
8283 color = getPixelColor(device, 192-15, 64-15);
8284 ok(color == 0x00ffffff, "pSize: Pixel (192-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8285 color = getPixelColor(device, 192+15, 64+15);
8286 ok(color == 0x00ffffff, "pSize: Pixel (192+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8287 color = getPixelColor(device, 192+16, 64+16);
8288 ok(color == 0x000000ff, "pSize: Pixel (192+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8289 color = getPixelColor(device, 192+17, 64+17);
8290 ok(color == 0x000000ff, "pSize: Pixel (192+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8292 if(caps.MaxPointSize >= 64.0) {
8293 color = getPixelColor(device, 256-33, 64-33);
8294 ok(color == 0x000000ff, "pSize: Pixel (256-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8295 color = getPixelColor(device, 256-32, 64-32);
8296 todo_wine ok(color == 0x00ffffff, "pSize: Pixel (256-32),(64-32) has color 0x%08x, expected 0x00ffffff\n", color);
8297 color = getPixelColor(device, 256-31, 64-31);
8298 ok(color == 0x00ffffff, "pSize: Pixel (256-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8299 color = getPixelColor(device, 256+31, 64+31);
8300 ok(color == 0x00ffffff, "pSize: Pixel (256+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8301 color = getPixelColor(device, 256+32, 64+32);
8302 ok(color == 0x000000ff, "pSize: Pixel (256+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8303 color = getPixelColor(device, 256+33, 64+33);
8304 ok(color == 0x000000ff, "pSize: Pixel (256+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8306 color = getPixelColor(device, 384-33, 64-33);
8307 ok(color == 0x000000ff, "pSize: Pixel (384-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8308 color = getPixelColor(device, 384-32, 64-32);
8309 ok(color == 0x000000ff, "pSize: Pixel (384-32),(64-32) has color 0x%08x, expected 0x000000ff\n", color);
8310 color = getPixelColor(device, 384-31, 64-31);
8311 ok(color == 0x00ffffff, "pSize: Pixel (384-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8312 color = getPixelColor(device, 384+31, 64+31);
8313 ok(color == 0x00ffffff, "pSize: Pixel (384+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8314 color = getPixelColor(device, 384+32, 64+32);
8315 ok(color == 0x000000ff, "pSize: Pixel (384+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8316 color = getPixelColor(device, 384+33, 64+33);
8317 ok(color == 0x000000ff, "pSize: Pixel (384+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8320 color = getPixelColor(device, 320-1, 64-1);
8321 ok(color == 0x000000ff, "pSize: Pixel (320-1),(64-1) has color 0x%08x, expected 0x000000ff\n", color);
8322 color = getPixelColor(device, 320-0, 64-0);
8323 ok(color == 0x00ffffff, "pSize: Pixel (320-0),(64-0) has color 0x%08x, expected 0x00ffffff\n", color);
8324 color = getPixelColor(device, 320+1, 64+1);
8325 ok(color == 0x000000ff, "pSize: Pixel (320+1),(64+1) has color 0x%08x, expected 0x000000ff\n", color);
8327 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
8328 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%s\n", DXGetErrorString9(hr));
8329 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
8330 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%s\n", DXGetErrorString9(hr));
8333 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
8335 HRESULT hr;
8336 IDirect3DPixelShader9 *ps;
8337 IDirect3DTexture9 *tex1, *tex2;
8338 IDirect3DSurface9 *surf1, *surf2, *backbuf;
8339 D3DCAPS9 caps;
8340 DWORD color;
8341 DWORD shader_code[] = {
8342 0xffff0300, /* ps_3_0 */
8343 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0, 1, 0, 0 */
8344 0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0, 0, 1, 0 */
8345 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
8346 0x02000001, 0x800f0801, 0xa0e40001, /* mov oC1, c1 */
8347 0x0000ffff /* END */
8349 float quad[] = {
8350 -1.0, -1.0, 0.1,
8351 1.0, -1.0, 0.1,
8352 -1.0, 1.0, 0.1,
8353 1.0, 1.0, 0.1,
8355 float texquad[] = {
8356 -1.0, -1.0, 0.1, 0.0, 0.0,
8357 0.0, -1.0, 0.1, 1.0, 0.0,
8358 -1.0, 1.0, 0.1, 0.0, 1.0,
8359 0.0, 1.0, 0.1, 1.0, 1.0,
8361 0.0, -1.0, 0.1, 0.0, 0.0,
8362 1.0, -1.0, 0.1, 1.0, 0.0,
8363 0.0, 1.0, 0.1, 0.0, 1.0,
8364 1.0, 1.0, 0.1, 1.0, 1.0,
8367 memset(&caps, 0, sizeof(caps));
8368 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8369 ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%s\n", DXGetErrorString9(hr));
8370 if(caps.NumSimultaneousRTs < 2) {
8371 skip("Only 1 simultaneous render target supported, skipping MRT test\n");
8372 return;
8375 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
8376 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
8378 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
8379 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%s\n", DXGetErrorString9(hr));
8380 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
8381 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%s\n", DXGetErrorString9(hr));
8382 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
8383 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed, hr=%s\n", DXGetErrorString9(hr));
8385 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
8386 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8387 hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
8388 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%s\n", DXGetErrorString9(hr));
8389 hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
8390 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%s\n", DXGetErrorString9(hr));
8392 hr = IDirect3DDevice9_SetPixelShader(device, ps);
8393 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%s\n", DXGetErrorString9(hr));
8394 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
8395 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8396 hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
8397 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8398 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8399 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%s\n", DXGetErrorString9(hr));
8401 hr = IDirect3DDevice9_BeginScene(device);
8402 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%s\n", DXGetErrorString9(hr));
8403 if(SUCCEEDED(hr)) {
8404 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
8405 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8407 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8408 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%s\n", DXGetErrorString9(hr));
8409 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
8410 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8411 hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
8412 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8413 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8414 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%s\n", DXGetErrorString9(hr));
8416 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8417 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%s\n", DXGetErrorString9(hr));
8418 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
8419 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8421 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
8422 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%s\n", DXGetErrorString9(hr));
8423 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
8424 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8426 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8427 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%s\n", DXGetErrorString9(hr));
8429 hr = IDirect3DDevice9_EndScene(device);
8430 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%s\n", DXGetErrorString9(hr));
8433 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8434 color = getPixelColor(device, 160, 240);
8435 ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
8436 color = getPixelColor(device, 480, 240);
8437 ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
8439 IDirect3DPixelShader9_Release(ps);
8440 IDirect3DTexture9_Release(tex1);
8441 IDirect3DTexture9_Release(tex2);
8442 IDirect3DSurface9_Release(surf1);
8443 IDirect3DSurface9_Release(surf2);
8444 IDirect3DSurface9_Release(backbuf);
8447 struct formats {
8448 const char *fmtName;
8449 D3DFORMAT textureFormat;
8450 DWORD resultColorBlending;
8451 DWORD resultColorNoBlending;
8454 const struct formats test_formats[] = {
8455 { "D3DFMT_G16R16", D3DFMT_G16R16, 0x00181800, 0x002010ff},
8456 { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
8457 { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
8458 { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
8459 { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
8460 { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
8461 { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
8462 { NULL, 0 }
8465 static void pixelshader_blending_test(IDirect3DDevice9 *device)
8467 HRESULT hr;
8468 IDirect3DTexture9 *offscreenTexture = NULL;
8469 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
8470 IDirect3D9 *d3d = NULL;
8471 DWORD color;
8472 DWORD r0, g0, b0, r1, g1, b1;
8473 int fmt_index;
8475 static const float quad[][5] = {
8476 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
8477 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
8478 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
8479 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
8482 /* Quad with R=0x10, G=0x20 */
8483 static const struct vertex quad1[] = {
8484 {-1.0f, -1.0f, 0.1f, 0x80102000},
8485 {-1.0f, 1.0f, 0.1f, 0x80102000},
8486 { 1.0f, -1.0f, 0.1f, 0x80102000},
8487 { 1.0f, 1.0f, 0.1f, 0x80102000},
8490 /* Quad with R=0x20, G=0x10 */
8491 static const struct vertex quad2[] = {
8492 {-1.0f, -1.0f, 0.1f, 0x80201000},
8493 {-1.0f, 1.0f, 0.1f, 0x80201000},
8494 { 1.0f, -1.0f, 0.1f, 0x80201000},
8495 { 1.0f, 1.0f, 0.1f, 0x80201000},
8498 IDirect3DDevice9_GetDirect3D(device, &d3d);
8500 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8501 ok(hr == D3D_OK, "Can't get back buffer, hr = %s\n", DXGetErrorString9(hr));
8502 if(!backbuffer) {
8503 goto out;
8506 for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
8508 D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
8509 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, fmt) != D3D_OK) {
8510 skip("%s textures not supported\n", test_formats[fmt_index].fmtName);
8511 continue;
8514 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8515 ok(hr == D3D_OK, "Clear failed, hr = %s\n", DXGetErrorString9(hr));
8517 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
8518 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %s\n", DXGetErrorString9(hr));
8519 if(!offscreenTexture) {
8520 continue;
8523 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
8524 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %s\n", DXGetErrorString9(hr));
8525 if(!offscreen) {
8526 continue;
8529 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8530 ok(hr == D3D_OK, "SetFVF failed, hr = %s\n", DXGetErrorString9(hr));
8532 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8533 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8534 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8535 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8536 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
8537 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
8538 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
8539 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
8540 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8541 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
8543 /* Below we will draw two quads with different colors and try to blend them together.
8544 * The result color is compared with the expected outcome.
8546 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
8547 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
8548 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %s\n", DXGetErrorString9(hr));
8549 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
8550 ok(hr == D3D_OK, "Clear failed, hr = %s\n", DXGetErrorString9(hr));
8552 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
8553 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8555 /* Draw a quad using color 0x0010200 */
8556 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
8557 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8558 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
8559 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8560 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8561 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8563 /* Draw a quad using color 0x0020100 */
8564 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
8565 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8566 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
8567 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8568 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8569 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8571 /* We don't want to blend the result on the backbuffer */
8572 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
8573 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8575 /* Prepare rendering the 'blended' texture quad to the backbuffer */
8576 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8577 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %s\n", DXGetErrorString9(hr));
8578 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
8579 ok(hr == D3D_OK, "SetTexture failed, %s\n", DXGetErrorString9(hr));
8581 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8582 ok(hr == D3D_OK, "SetFVF failed, hr = %s\n", DXGetErrorString9(hr));
8584 /* This time with the texture */
8585 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8586 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %s\n", DXGetErrorString9(hr));
8588 IDirect3DDevice9_EndScene(device);
8590 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8593 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
8594 /* Compare the color of the center quad with our expectation */
8595 color = getPixelColor(device, 320, 240);
8596 r0 = (color & 0x00ff0000) >> 16;
8597 g0 = (color & 0x0000ff00) >> 8;
8598 b0 = (color & 0x000000ff) >> 0;
8600 r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
8601 g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >> 8;
8602 b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >> 0;
8604 ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
8605 g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
8606 b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
8607 "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
8608 } else {
8609 /* No pixel shader blending is supported so expected garbage.The type of 'garbage' depends on the driver version and OS.
8610 * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
8611 * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
8612 color = getPixelColor(device, 320, 240);
8613 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);
8616 IDirect3DDevice9_SetTexture(device, 0, NULL);
8617 if(offscreenTexture) {
8618 IDirect3DTexture9_Release(offscreenTexture);
8620 if(offscreen) {
8621 IDirect3DSurface9_Release(offscreen);
8625 out:
8626 /* restore things */
8627 if(backbuffer) {
8628 IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8629 IDirect3DSurface9_Release(backbuffer);
8633 static void tssargtemp_test(IDirect3DDevice9 *device)
8635 HRESULT hr;
8636 DWORD color;
8637 static const struct vertex quad[] = {
8638 {-1.0, -1.0, 0.1, 0x00ff0000},
8639 { 1.0, -1.0, 0.1, 0x00ff0000},
8640 {-1.0, 1.0, 0.1, 0x00ff0000},
8641 { 1.0, 1.0, 0.1, 0x00ff0000}
8643 D3DCAPS9 caps;
8645 memset(&caps, 0, sizeof(caps));
8646 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8647 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %s\n", DXGetErrorString9(hr));
8648 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
8649 skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
8650 return;
8653 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
8654 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
8656 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8657 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8658 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
8659 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8661 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8662 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8663 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
8664 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8665 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
8666 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8668 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
8669 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8670 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
8671 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8672 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
8673 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8675 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
8676 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8678 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
8679 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %s\n", DXGetErrorString9(hr));
8680 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8681 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %s\n", DXGetErrorString9(hr));
8683 hr = IDirect3DDevice9_BeginScene(device);
8684 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %s\n", DXGetErrorString9(hr));
8685 if(SUCCEEDED(hr)) {
8687 hr = IDirect3DDevice9_EndScene(device);
8688 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %s\n", DXGetErrorString9(hr));
8689 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8690 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
8692 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8693 color = getPixelColor(device, 320, 240);
8694 ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
8696 /* Set stage 1 back to default */
8697 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
8698 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8699 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
8700 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8701 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8702 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8703 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
8704 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8705 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
8706 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8709 struct testdata
8711 DWORD idxVertex; /* number of instances in the first stream */
8712 DWORD idxColor; /* number of instances in the second stream */
8713 DWORD idxInstance; /* should be 1 ?? */
8714 DWORD color1; /* color 1 instance */
8715 DWORD color2; /* color 2 instance */
8716 DWORD color3; /* color 3 instance */
8717 DWORD color4; /* color 4 instance */
8718 WORD strVertex; /* specify which stream to use 0-2*/
8719 WORD strColor;
8720 WORD strInstance;
8723 static const struct testdata testcases[]=
8725 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 0 */
8726 {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 1 */
8727 {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 2 */
8728 {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 3 */
8729 {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 4 */
8730 {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 5 */
8731 {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 6 */
8732 {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 7 */
8733 {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 8 */
8734 {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 9 */
8735 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 10 */
8736 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 11 */
8737 {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 12 */
8738 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 13 */
8739 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 14 */
8741 This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1)) has to return D3DERR_INVALIDCALL!
8742 {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
8746 /* Drawing Indexed Geometry with instances*/
8747 static void stream_test(IDirect3DDevice9 *device)
8749 IDirect3DVertexBuffer9 *vb = NULL;
8750 IDirect3DVertexBuffer9 *vb2 = NULL;
8751 IDirect3DVertexBuffer9 *vb3 = NULL;
8752 IDirect3DIndexBuffer9 *ib = NULL;
8753 IDirect3DVertexDeclaration9 *pDecl = NULL;
8754 IDirect3DVertexShader9 *shader = NULL;
8755 HRESULT hr;
8756 BYTE *data;
8757 DWORD color;
8758 DWORD ind;
8759 int i;
8761 const DWORD shader_code[] =
8763 0xfffe0101, /* vs_1_1 */
8764 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8765 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
8766 0x0000001f, 0x80000005, 0x900f0002, /* dcl_texcoord v2 */
8767 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
8768 0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
8769 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
8770 0x0000ffff
8773 const float quad[][3] =
8775 {-0.5f, -0.5f, 1.1f}, /*0 */
8776 {-0.5f, 0.5f, 1.1f}, /*1 */
8777 { 0.5f, -0.5f, 1.1f}, /*2 */
8778 { 0.5f, 0.5f, 1.1f}, /*3 */
8781 const float vertcolor[][4] =
8783 {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
8784 {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
8785 {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
8786 {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
8789 /* 4 position for 4 instances */
8790 const float instancepos[][3] =
8792 {-0.6f,-0.6f, 0.0f},
8793 { 0.6f,-0.6f, 0.0f},
8794 { 0.6f, 0.6f, 0.0f},
8795 {-0.6f, 0.6f, 0.0f},
8798 short indices[] = {0, 1, 2, 1, 2, 3};
8800 D3DVERTEXELEMENT9 decl[] =
8802 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8803 {1, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8804 {2, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
8805 D3DDECL_END()
8808 /* set the default value because it isn't done in wine? */
8809 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
8810 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8812 /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
8813 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
8814 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8816 /* check wrong cases */
8817 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
8818 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8819 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8820 ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8821 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
8822 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8823 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8824 ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8825 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
8826 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8827 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8828 ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8829 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
8830 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8831 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8832 ok(hr == D3D_OK && ind == (0 | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8833 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
8834 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8835 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8836 ok(hr == D3D_OK && ind == (0 | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8838 /* set the default value back */
8839 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
8840 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8842 /* create all VertexBuffers*/
8843 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
8844 ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
8845 if(!vb) {
8846 skip("Failed to create a vertex buffer\n");
8847 return;
8849 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
8850 ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
8851 if(!vb2) {
8852 skip("Failed to create a vertex buffer\n");
8853 goto out;
8855 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
8856 ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
8857 if(!vb3) {
8858 skip("Failed to create a vertex buffer\n");
8859 goto out;
8862 /* create IndexBuffer*/
8863 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
8864 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %s\n", DXGetErrorString9(hr));
8865 if(!ib) {
8866 skip("Failed to create a index buffer\n");
8867 goto out;
8870 /* copy all Buffers (Vertex + Index)*/
8871 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
8872 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
8873 memcpy(data, quad, sizeof(quad));
8874 hr = IDirect3DVertexBuffer9_Unlock(vb);
8875 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
8876 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
8877 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
8878 memcpy(data, vertcolor, sizeof(vertcolor));
8879 hr = IDirect3DVertexBuffer9_Unlock(vb2);
8880 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
8881 hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
8882 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
8883 memcpy(data, instancepos, sizeof(instancepos));
8884 hr = IDirect3DVertexBuffer9_Unlock(vb3);
8885 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
8886 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
8887 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
8888 memcpy(data, indices, sizeof(indices));
8889 hr = IDirect3DIndexBuffer9_Unlock(ib);
8890 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
8892 /* create VertexShader */
8893 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
8894 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%s\n", DXGetErrorString9(hr));
8895 if(!shader) {
8896 skip("Failed to create a vetex shader\n");
8897 goto out;
8900 hr = IDirect3DDevice9_SetVertexShader(device, shader);
8901 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%s\n", DXGetErrorString9(hr));
8903 hr = IDirect3DDevice9_SetIndices(device, ib);
8904 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
8906 /* run all tests */
8907 for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
8909 struct testdata act = testcases[i];
8910 decl[0].Stream = act.strVertex;
8911 decl[1].Stream = act.strColor;
8912 decl[2].Stream = act.strInstance;
8913 /* create VertexDeclarations */
8914 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
8915 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%s (case %i)\n", DXGetErrorString9(hr), i);
8917 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8918 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
8920 hr = IDirect3DDevice9_BeginScene(device);
8921 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
8922 if(SUCCEEDED(hr))
8924 hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
8925 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
8927 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
8928 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8929 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
8930 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8932 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
8933 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8934 hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
8935 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8937 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
8938 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8939 hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
8940 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8942 /* don't know if this is right (1*3 and 4*1)*/
8943 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 1 * 3 , 0, 4*1);
8944 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
8945 hr = IDirect3DDevice9_EndScene(device);
8946 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
8948 /* set all StreamSource && StreamSourceFreq back to default */
8949 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
8950 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8951 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
8952 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
8953 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
8954 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8955 hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
8956 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
8957 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
8958 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8959 hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
8960 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
8963 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8964 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
8966 hr = IDirect3DVertexDeclaration9_Release(pDecl);
8967 ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
8969 color = getPixelColor(device, 160, 360);
8970 ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
8971 color = getPixelColor(device, 480, 360);
8972 ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
8973 color = getPixelColor(device, 480, 120);
8974 ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
8975 color = getPixelColor(device, 160, 120);
8976 ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
8979 hr = IDirect3DDevice9_SetIndices(device, NULL);
8980 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
8982 out:
8983 if(vb) IDirect3DVertexBuffer9_Release(vb);
8984 if(vb2)IDirect3DVertexBuffer9_Release(vb2);
8985 if(vb3)IDirect3DVertexBuffer9_Release(vb3);
8986 if(ib)IDirect3DIndexBuffer9_Release(ib);
8987 if(shader)IDirect3DVertexShader9_Release(shader);
8990 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
8991 IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
8992 IDirect3DTexture9 *dsttex = NULL;
8993 HRESULT hr;
8994 DWORD color;
8995 D3DRECT r1 = {0, 0, 50, 50 };
8996 D3DRECT r2 = {50, 0, 100, 50 };
8997 D3DRECT r3 = {50, 50, 100, 100};
8998 D3DRECT r4 = {0, 50, 50, 100};
8999 const float quad[] = {
9000 -1.0, -1.0, 0.1, 0.0, 0.0,
9001 1.0, -1.0, 0.1, 1.0, 0.0,
9002 -1.0, 1.0, 0.1, 0.0, 1.0,
9003 1.0, 1.0, 0.1, 1.0, 1.0,
9006 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9007 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %s\n", DXGetErrorString9(hr));
9009 hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
9010 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %s\n", DXGetErrorString9(hr));
9011 hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
9012 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
9014 if(!src || !dsttex) {
9015 skip("One or more test resources could not be created\n");
9016 goto cleanup;
9019 hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
9020 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
9022 hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
9023 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
9025 /* Clear the StretchRect destination for debugging */
9026 hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9027 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %s\n", DXGetErrorString9(hr));
9028 hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9029 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
9031 hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9032 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %s\n", DXGetErrorString9(hr));
9034 hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9035 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
9036 hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9037 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
9038 hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9039 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
9040 hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9041 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
9043 /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9044 * the target -> texture GL blit path
9046 hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9047 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
9048 IDirect3DSurface9_Release(dst);
9050 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9051 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %s\n", DXGetErrorString9(hr));
9053 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9054 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
9055 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9056 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
9057 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9058 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
9059 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9060 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
9062 hr = IDirect3DDevice9_BeginScene(device);
9063 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
9064 if(SUCCEEDED(hr)) {
9065 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9066 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9067 hr = IDirect3DDevice9_EndScene(device);
9068 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
9071 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9072 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
9073 color = getPixelColor(device, 160, 360);
9074 ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9075 color = getPixelColor(device, 480, 360);
9076 ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9077 color = getPixelColor(device, 480, 120);
9078 ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9079 color = getPixelColor(device, 160, 120);
9080 ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9082 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9083 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
9084 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9085 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
9087 cleanup:
9088 if(src) IDirect3DSurface9_Release(src);
9089 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9090 if(dsttex) IDirect3DTexture9_Release(dsttex);
9093 START_TEST(visual)
9095 IDirect3DDevice9 *device_ptr;
9096 D3DCAPS9 caps;
9097 HRESULT hr;
9098 DWORD color;
9100 d3d9_handle = LoadLibraryA("d3d9.dll");
9101 if (!d3d9_handle)
9103 skip("Could not load d3d9.dll\n");
9104 return;
9107 device_ptr = init_d3d9();
9108 if (!device_ptr)
9110 skip("Creating the device failed\n");
9111 return;
9114 IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
9116 /* Check for the reliability of the returned data */
9117 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9118 if(FAILED(hr))
9120 skip("Clear failed, can't assure correctness of the test results, skipping\n");
9121 goto cleanup;
9123 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
9125 color = getPixelColor(device_ptr, 1, 1);
9126 if(color !=0x00ff0000)
9128 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
9129 goto cleanup;
9132 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
9133 if(FAILED(hr))
9135 skip("Clear failed, can't assure correctness of the test results, skipping\n");
9136 goto cleanup;
9138 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
9140 color = getPixelColor(device_ptr, 639, 479);
9141 if(color != 0x0000ddee)
9143 skip("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
9144 goto cleanup;
9147 /* Now execute the real tests */
9148 stretchrect_test(device_ptr);
9149 lighting_test(device_ptr);
9150 clear_test(device_ptr);
9151 fog_test(device_ptr);
9152 if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
9154 test_cube_wrap(device_ptr);
9155 } else {
9156 skip("No cube texture support\n");
9158 z_range_test(device_ptr);
9159 if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
9161 maxmip_test(device_ptr);
9163 else
9165 skip("No mipmap support\n");
9167 offscreen_test(device_ptr);
9168 alpha_test(device_ptr);
9169 shademode_test(device_ptr);
9170 srgbtexture_test(device_ptr);
9171 release_buffer_test(device_ptr);
9172 float_texture_test(device_ptr);
9173 g16r16_texture_test(device_ptr);
9174 pixelshader_blending_test(device_ptr);
9175 texture_transform_flags_test(device_ptr);
9176 autogen_mipmap_test(device_ptr);
9177 fixed_function_decl_test(device_ptr);
9178 conditional_np2_repeat_test(device_ptr);
9179 fixed_function_bumpmap_test(device_ptr);
9180 if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
9181 stencil_cull_test(device_ptr);
9182 } else {
9183 skip("No two sided stencil support\n");
9185 pointsize_test(device_ptr);
9186 tssargtemp_test(device_ptr);
9187 np2_stretch_rect_test(device_ptr);
9189 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
9191 test_constant_clamp_vs(device_ptr);
9192 test_compare_instructions(device_ptr);
9194 else skip("No vs_1_1 support\n");
9196 if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
9198 test_mova(device_ptr);
9199 if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
9200 test_vshader_input(device_ptr);
9201 test_vshader_float16(device_ptr);
9202 stream_test(device_ptr);
9203 } else {
9204 skip("No vs_3_0 support\n");
9207 else skip("No vs_2_0 support\n");
9209 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
9211 fog_with_shader_test(device_ptr);
9212 fog_srgbwrite_test(device_ptr);
9214 else skip("No vs_1_1 and ps_1_1 support\n");
9216 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
9218 texbem_test(device_ptr);
9219 texdepth_test(device_ptr);
9220 texkill_test(device_ptr);
9221 x8l8v8u8_test(device_ptr);
9222 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
9223 constant_clamp_ps_test(device_ptr);
9224 cnd_test(device_ptr);
9225 if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
9226 dp2add_ps_test(device_ptr);
9227 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) {
9228 nested_loop_test(device_ptr);
9229 fixed_function_varying_test(device_ptr);
9230 vFace_register_test(device_ptr);
9231 vpos_register_test(device_ptr);
9232 multiple_rendertargets_test(device_ptr);
9233 if(caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
9234 vshader_version_varying_test(device_ptr);
9235 pshader_version_varying_test(device_ptr);
9236 } else {
9237 skip("No vs_3_0 support\n");
9239 } else {
9240 skip("No ps_3_0 support\n");
9242 } else {
9243 skip("No ps_2_0 support\n");
9247 else skip("No ps_1_1 support\n");
9249 cleanup:
9250 if(device_ptr) {
9251 ULONG ref;
9253 D3DPRESENT_PARAMETERS present_parameters;
9254 IDirect3DSwapChain9 *swapchain;
9255 IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
9256 IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
9257 IDirect3DSwapChain9_Release(swapchain);
9258 ref = IDirect3DDevice9_Release(device_ptr);
9259 DestroyWindow(present_parameters.hDeviceWindow);
9260 ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);