d3d9: Add a non-shader reversed fog test.
[wine/multimedia.git] / dlls / d3d9 / tests / visual.c
blobf799af80d02c781345485abfb055ca4b3a1973c9
1 /*
2 * Copyright 2005, 2007 Henri Verbeet
3 * Copyright (C) 2007 Stefan Dösinger(for CodeWeavers)
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 /* This test framework allows limited testing of rendering results. Things are rendered, shown on
21 * the framebuffer, read back from there and compared to expected colors.
23 * However, neither d3d nor opengl is guaranteed to be pixel exact, and thus the capability of this test
24 * is rather limited. As a general guideline for adding tests, do not rely on corner pixels. Draw a big enough
25 * area which shows specific behavior(like a quad on the whole screen), and try to get resulting colors with
26 * all bits set or unset in all channels(like pure red, green, blue, white, black). Hopefully everything that
27 * causes visible results in games can be tested in a way that does not depend on pixel exactness
30 #define COBJMACROS
31 #include <d3d9.h>
32 #include <dxerr9.h>
33 #include "wine/test.h"
35 static HMODULE d3d9_handle = 0;
37 static HWND create_window(void)
39 WNDCLASS wc = {0};
40 HWND ret;
41 wc.lpfnWndProc = &DefWindowProc;
42 wc.lpszClassName = "d3d9_test_wc";
43 RegisterClass(&wc);
45 ret = CreateWindow("d3d9_test_wc", "d3d9_test",
46 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
47 return ret;
50 static DWORD getPixelColor(IDirect3DDevice9 *device, UINT x, UINT y)
52 DWORD ret;
53 IDirect3DSurface9 *surf;
54 HRESULT hr;
55 D3DLOCKED_RECT lockedRect;
56 RECT rectToLock = {x, y, x+1, y+1};
58 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 640, 480, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf, NULL);
59 if(FAILED(hr) || !surf ) /* This is not a test */
61 trace("Can't create an offscreen plain surface to read the render target data, hr=%s\n", DXGetErrorString9(hr));
62 return 0xdeadbeef;
65 hr = IDirect3DDevice9_GetFrontBufferData(device, 0, surf);
66 if(FAILED(hr))
68 trace("Can't read the front buffer data, hr=%s\n", DXGetErrorString9(hr));
69 ret = 0xdeadbeed;
70 goto out;
73 hr = IDirect3DSurface9_LockRect(surf, &lockedRect, &rectToLock, D3DLOCK_READONLY);
74 if(FAILED(hr))
76 trace("Can't lock the offscreen surface, hr=%s\n", DXGetErrorString9(hr));
77 ret = 0xdeadbeec;
78 goto out;
81 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
82 * really important for these tests
84 ret = ((DWORD *) lockedRect.pBits)[0] & 0x00ffffff;
85 hr = IDirect3DSurface9_UnlockRect(surf);
86 if(FAILED(hr))
88 trace("Can't unlock the offscreen surface, hr=%s\n", DXGetErrorString9(hr));
91 out:
92 if(surf) IDirect3DSurface9_Release(surf);
93 return ret;
96 static IDirect3DDevice9 *init_d3d9(void)
98 IDirect3D9 * (__stdcall * d3d9_create)(UINT SDKVersion) = 0;
99 IDirect3D9 *d3d9_ptr = 0;
100 IDirect3DDevice9 *device_ptr = 0;
101 D3DPRESENT_PARAMETERS present_parameters;
102 HRESULT hr;
104 d3d9_create = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9");
105 ok(d3d9_create != NULL, "Failed to get address of Direct3DCreate9\n");
106 if (!d3d9_create) return NULL;
108 d3d9_ptr = d3d9_create(D3D_SDK_VERSION);
109 ok(d3d9_ptr != NULL, "Failed to create IDirect3D9 object\n");
110 if (!d3d9_ptr) return NULL;
112 ZeroMemory(&present_parameters, sizeof(present_parameters));
113 present_parameters.Windowed = FALSE;
114 present_parameters.hDeviceWindow = create_window();
115 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
116 present_parameters.BackBufferWidth = 640;
117 present_parameters.BackBufferHeight = 480;
118 present_parameters.BackBufferFormat = D3DFMT_X8R8G8B8;
119 present_parameters.EnableAutoDepthStencil = TRUE;
120 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
122 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
123 if(FAILED(hr)) {
124 present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
125 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
127 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D_CreateDevice returned: %s\n", DXGetErrorString9(hr));
129 return device_ptr;
132 struct vertex
134 float x, y, z;
135 DWORD diffuse;
138 struct tvertex
140 float x, y, z, rhw;
141 DWORD diffuse;
144 struct nvertex
146 float x, y, z;
147 float nx, ny, nz;
148 DWORD diffuse;
151 static void lighting_test(IDirect3DDevice9 *device)
153 HRESULT hr;
154 DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
155 DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
156 DWORD color;
158 float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
159 0.0f, 1.0f, 0.0f, 0.0f,
160 0.0f, 0.0f, 1.0f, 0.0f,
161 0.0f, 0.0f, 0.0f, 1.0f };
163 struct vertex unlitquad[] =
165 {-1.0f, -1.0f, 0.1f, 0xffff0000},
166 {-1.0f, 0.0f, 0.1f, 0xffff0000},
167 { 0.0f, 0.0f, 0.1f, 0xffff0000},
168 { 0.0f, -1.0f, 0.1f, 0xffff0000},
170 struct vertex litquad[] =
172 {-1.0f, 0.0f, 0.1f, 0xff00ff00},
173 {-1.0f, 1.0f, 0.1f, 0xff00ff00},
174 { 0.0f, 1.0f, 0.1f, 0xff00ff00},
175 { 0.0f, 0.0f, 0.1f, 0xff00ff00},
177 struct nvertex unlitnquad[] =
179 { 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
180 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
181 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
182 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
184 struct nvertex litnquad[] =
186 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
187 { 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
188 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
189 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
191 WORD Indices[] = {0, 1, 2, 2, 3, 0};
193 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
194 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
196 /* Setup some states that may cause issues */
197 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
198 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %s\n", DXGetErrorString9(hr));
199 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
200 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %s\n", DXGetErrorString9(hr));
201 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
202 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %s\n", DXGetErrorString9(hr));
203 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
204 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
205 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
206 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
207 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
208 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
209 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
210 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
211 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
212 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
213 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
214 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
215 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
216 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
217 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
218 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %s\n", DXGetErrorString9(hr));
219 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
220 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %s\n", DXGetErrorString9(hr));
222 hr = IDirect3DDevice9_SetFVF(device, fvf);
223 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
225 hr = IDirect3DDevice9_BeginScene(device);
226 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
227 if(hr == D3D_OK)
229 /* No lights are defined... That means, lit vertices should be entirely black */
230 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
231 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
232 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
233 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
234 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
236 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
237 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
238 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
239 2 /*PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
240 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
242 hr = IDirect3DDevice9_SetFVF(device, nfvf);
243 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
245 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
246 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
247 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
248 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
249 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
251 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
252 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
253 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
254 2 /*PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
255 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
257 IDirect3DDevice9_EndScene(device);
258 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
261 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
263 color = getPixelColor(device, 160, 360); /* lower left quad - unlit without normals */
264 ok(color == 0x00ff0000, "Unlit quad without normals has color %08x\n", color);
265 color = getPixelColor(device, 160, 120); /* upper left quad - lit without normals */
266 ok(color == 0x00000000, "Lit quad without normals has color %08x\n", color);
267 color = getPixelColor(device, 480, 360); /* lower left quad - unlit with normals */
268 ok(color == 0x000000ff, "Unlit quad with normals has color %08x\n", color);
269 color = getPixelColor(device, 480, 120); /* upper left quad - lit with normals */
270 ok(color == 0x00000000, "Lit quad with normals has color %08x\n", color);
272 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
273 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
276 static void clear_test(IDirect3DDevice9 *device)
278 /* Tests the correctness of clearing parameters */
279 HRESULT hr;
280 D3DRECT rect[2];
281 D3DRECT rect_negneg;
282 DWORD color;
283 D3DVIEWPORT9 old_vp, vp;
284 RECT scissor;
285 DWORD oldColorWrite;
286 BOOL invalid_clear_failed = FALSE;
288 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
289 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
291 /* Positive x, negative y */
292 rect[0].x1 = 0;
293 rect[0].y1 = 480;
294 rect[0].x2 = 320;
295 rect[0].y2 = 240;
297 /* Positive x, positive y */
298 rect[1].x1 = 0;
299 rect[1].y1 = 0;
300 rect[1].x2 = 320;
301 rect[1].y2 = 240;
302 /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
303 * returns D3D_OK, but ignores the rectangle silently
305 hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
306 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
307 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
309 /* negative x, negative y */
310 rect_negneg.x1 = 640;
311 rect_negneg.y1 = 240;
312 rect_negneg.x2 = 320;
313 rect_negneg.y2 = 0;
314 hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
315 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
316 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
318 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
320 color = getPixelColor(device, 160, 360); /* lower left quad */
321 ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
322 color = getPixelColor(device, 160, 120); /* upper left quad */
323 if(invalid_clear_failed) {
324 /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
325 ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
326 } else {
327 /* If the negative rectangle was dropped silently, the correct ones are cleared */
328 ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
330 color = getPixelColor(device, 480, 360); /* lower right quad */
331 ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
332 color = getPixelColor(device, 480, 120); /* upper right quad */
333 ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
335 /* Test how the viewport affects clears */
336 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
337 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
338 hr = IDirect3DDevice9_GetViewport(device, &old_vp);
339 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %s\n", DXGetErrorString9(hr));
341 vp.X = 160;
342 vp.Y = 120;
343 vp.Width = 160;
344 vp.Height = 120;
345 vp.MinZ = 0.0;
346 vp.MaxZ = 1.0;
347 hr = IDirect3DDevice9_SetViewport(device, &vp);
348 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %s\n", DXGetErrorString9(hr));
349 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
350 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
352 vp.X = 320;
353 vp.Y = 240;
354 vp.Width = 320;
355 vp.Height = 240;
356 vp.MinZ = 0.0;
357 vp.MaxZ = 1.0;
358 hr = IDirect3DDevice9_SetViewport(device, &vp);
359 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %s\n", DXGetErrorString9(hr));
360 rect[0].x1 = 160;
361 rect[0].y1 = 120;
362 rect[0].x2 = 480;
363 rect[0].y2 = 360;
364 hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
365 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
367 hr = IDirect3DDevice9_SetViewport(device, &old_vp);
368 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %s\n", DXGetErrorString9(hr));
370 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
371 color = getPixelColor(device, 158, 118);
372 ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
373 color = getPixelColor(device, 162, 118);
374 ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
375 color = getPixelColor(device, 158, 122);
376 ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
377 color = getPixelColor(device, 162, 122);
378 ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
380 color = getPixelColor(device, 318, 238);
381 ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
382 color = getPixelColor(device, 322, 238);
383 ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
384 color = getPixelColor(device, 318, 242);
385 ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
386 color = getPixelColor(device, 322, 242);
387 ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
389 color = getPixelColor(device, 478, 358);
390 ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
391 color = getPixelColor(device, 482, 358);
392 ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
393 color = getPixelColor(device, 478, 362);
394 ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
395 color = getPixelColor(device, 482, 362);
396 ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
398 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
399 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
401 scissor.left = 160;
402 scissor.right = 480;
403 scissor.top = 120;
404 scissor.bottom = 360;
405 hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
406 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %s\n", DXGetErrorString9(hr));
407 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
408 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %s\n", DXGetErrorString9(hr));
410 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
411 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
412 hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
413 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
415 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
416 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %s\n", DXGetErrorString9(hr));
418 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
419 color = getPixelColor(device, 158, 118);
420 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
421 color = getPixelColor(device, 162, 118);
422 ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
423 color = getPixelColor(device, 158, 122);
424 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
425 color = getPixelColor(device, 162, 122);
426 ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
428 color = getPixelColor(device, 158, 358);
429 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
430 color = getPixelColor(device, 162, 358);
431 ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
432 color = getPixelColor(device, 158, 358);
433 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
434 color = getPixelColor(device, 162, 362);
435 ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
437 color = getPixelColor(device, 478, 118);
438 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
439 color = getPixelColor(device, 478, 122);
440 ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
441 color = getPixelColor(device, 482, 122);
442 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
443 color = getPixelColor(device, 482, 358);
444 ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
446 color = getPixelColor(device, 478, 358);
447 ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
448 color = getPixelColor(device, 478, 362);
449 ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
450 color = getPixelColor(device, 482, 358);
451 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
452 color = getPixelColor(device, 482, 362);
453 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
455 color = getPixelColor(device, 318, 238);
456 ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
457 color = getPixelColor(device, 318, 242);
458 ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
459 color = getPixelColor(device, 322, 238);
460 ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
461 color = getPixelColor(device, 322, 242);
462 ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
464 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
465 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %s\n", DXGetErrorString9(hr));
466 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
467 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %s\n", DXGetErrorString9(hr));
469 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
470 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
472 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
473 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %s\n", DXGetErrorString9(hr));
475 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
477 /* Colorwriteenable does not affect the clear */
478 color = getPixelColor(device, 320, 240);
479 ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
482 typedef struct {
483 float in[4];
484 DWORD out;
485 } test_data_t;
488 * c7 mova ARGB mov ARGB
489 * -2.4 -2 0x00ffff00 -3 0x00ff0000
490 * -1.6 -2 0x00ffff00 -2 0x00ffff00
491 * -0.4 0 0x0000ffff -1 0x0000ff00
492 * 0.4 0 0x0000ffff 0 0x0000ffff
493 * 1.6 2 0x00ff00ff 1 0x000000ff
494 * 2.4 2 0x00ff00ff 2 0x00ff00ff
496 static void test_mova(IDirect3DDevice9 *device)
498 static const DWORD mova_test[] = {
499 0xfffe0200, /* vs_2_0 */
500 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
501 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
502 0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
503 0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
504 0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
505 0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
506 0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
507 0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
508 0x0200002e, 0xb0010000, 0xa0000007, /* mova a0.x, c7.x */
509 0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000, /* mov oD0, c[a0.x + 3] */
510 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
511 0x0000ffff /* END */
513 static const DWORD mov_test[] = {
514 0xfffe0101, /* vs_1_1 */
515 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
516 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
517 0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
518 0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
519 0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
520 0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
521 0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
522 0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
523 0x00000001, 0xb0010000, 0xa0000007, /* mov a0.x, c7.x */
524 0x00000001, 0xd00f0000, 0xa0e42003, /* mov oD0, c[a0.x + 3] */
525 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
526 0x0000ffff /* END */
529 static const test_data_t test_data[2][6] = {
531 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
532 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
533 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
534 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
535 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
536 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
539 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
540 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
541 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
542 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
543 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
544 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
548 static const float quad[][3] = {
549 {-1.0f, -1.0f, 0.0f},
550 {-1.0f, 1.0f, 0.0f},
551 { 1.0f, -1.0f, 0.0f},
552 { 1.0f, 1.0f, 0.0f},
555 static const D3DVERTEXELEMENT9 decl_elements[] = {
556 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
557 D3DDECL_END()
560 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
561 IDirect3DVertexShader9 *mova_shader = NULL;
562 IDirect3DVertexShader9 *mov_shader = NULL;
563 HRESULT hr;
564 UINT i, j;
566 hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
567 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
568 hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
569 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
570 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
571 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
572 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
573 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
575 hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
576 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
577 for(j = 0; j < 2; ++j)
579 for (i = 0; i < (sizeof(test_data[0]) / sizeof(test_data_t)); ++i)
581 DWORD color;
583 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
584 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
586 hr = IDirect3DDevice9_BeginScene(device);
587 ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
589 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
590 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
592 hr = IDirect3DDevice9_EndScene(device);
593 ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
595 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
596 ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
598 color = getPixelColor(device, 320, 240);
599 ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
600 test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
602 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
603 ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
605 hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
606 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
609 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
610 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
612 IDirect3DVertexDeclaration9_Release(vertex_declaration);
613 IDirect3DVertexShader9_Release(mova_shader);
614 IDirect3DVertexShader9_Release(mov_shader);
617 struct sVertex {
618 float x, y, z;
619 DWORD diffuse;
620 DWORD specular;
623 struct sVertexT {
624 float x, y, z, rhw;
625 DWORD diffuse;
626 DWORD specular;
629 static void fog_test(IDirect3DDevice9 *device)
631 HRESULT hr;
632 DWORD color;
633 BYTE r, g, b;
634 float start = 0.0f, end = 1.0f;
635 D3DCAPS9 caps;
636 int i;
638 /* Gets full z based fog with linear fog, no fog with specular color */
639 struct sVertex unstransformed_1[] = {
640 {-1, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
641 {-1, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
642 { 0, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
643 { 0, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
645 /* Ok, I am too lazy to deal with transform matrices */
646 struct sVertex unstransformed_2[] = {
647 {-1, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
648 {-1, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
649 { 0, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
650 { 0, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
652 /* Untransformed ones. Give them a different diffuse color to make the test look
653 * nicer. It also makes making sure that they are drawn correctly easier.
655 struct sVertexT transformed_1[] = {
656 {320, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
657 {640, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
658 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
659 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
661 struct sVertexT transformed_2[] = {
662 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
663 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
664 {640, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
665 {320, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
667 struct vertex rev_fog_quads[] = {
668 {-1.0, -1.0, 0.1, 0x000000ff},
669 {-1.0, 0.0, 0.1, 0x000000ff},
670 { 0.0, 0.0, 0.1, 0x000000ff},
671 { 0.0, -1.0, 0.1, 0x000000ff},
673 { 0.0, -1.0, 0.9, 0x000000ff},
674 { 0.0, 0.0, 0.9, 0x000000ff},
675 { 1.0, 0.0, 0.9, 0x000000ff},
676 { 1.0, -1.0, 0.9, 0x000000ff},
678 { 0.0, 0.0, 0.4, 0x000000ff},
679 { 0.0, 1.0, 0.4, 0x000000ff},
680 { 1.0, 1.0, 0.4, 0x000000ff},
681 { 1.0, 0.0, 0.4, 0x000000ff},
683 {-1.0, 0.0, 0.7, 0x000000ff},
684 {-1.0, 1.0, 0.7, 0x000000ff},
685 { 0.0, 1.0, 0.7, 0x000000ff},
686 { 0.0, 0.0, 0.7, 0x000000ff},
688 WORD Indices[] = {0, 1, 2, 2, 3, 0};
690 memset(&caps, 0, sizeof(caps));
691 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
692 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %s\n", DXGetErrorString9(hr));
693 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
694 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
696 /* Setup initial states: No lighting, fog on, fog color */
697 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
698 ok(hr == D3D_OK, "Turning off lighting returned %s\n", DXGetErrorString9(hr));
699 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
700 ok(hr == D3D_OK, "Turning on fog calculations returned %s\n", DXGetErrorString9(hr));
701 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
702 ok(hr == D3D_OK, "Turning on fog calculations returned %s\n", DXGetErrorString9(hr));
704 /* First test: Both table fog and vertex fog off */
705 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
706 ok(hr == D3D_OK, "Turning off table fog returned %s\n", DXGetErrorString9(hr));
707 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
708 ok(hr == D3D_OK, "Turning off table fog returned %s\n", DXGetErrorString9(hr));
710 /* Start = 0, end = 1. Should be default, but set them */
711 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
712 ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
713 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
714 ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
716 if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
718 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
719 ok( hr == D3D_OK, "SetFVF returned %s\n", DXGetErrorString9(hr));
720 /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
721 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
722 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
723 sizeof(unstransformed_1[0]));
724 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
726 /* That makes it use the Z value */
727 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
728 ok(hr == D3D_OK, "Turning off table fog returned %s\n", DXGetErrorString9(hr));
729 /* Untransformed, vertex fog != none (or table fog != none):
730 * Use the Z value as input into the equation
732 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
733 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
734 sizeof(unstransformed_1[0]));
735 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
737 /* transformed verts */
738 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
739 ok( hr == D3D_OK, "SetFVF returned %s\n", DXGetErrorString9(hr));
740 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
741 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
742 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
743 sizeof(transformed_1[0]));
744 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
746 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
747 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %s\n", DXGetErrorString9(hr));
748 /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
749 * equation
751 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
752 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
753 sizeof(transformed_2[0]));
755 hr = IDirect3DDevice9_EndScene(device);
756 ok(hr == D3D_OK, "EndScene returned %s\n", DXGetErrorString9(hr));
758 else
760 ok(FALSE, "BeginScene failed\n");
763 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
764 color = getPixelColor(device, 160, 360);
765 ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
766 color = getPixelColor(device, 160, 120);
767 ok(color == 0x0000FF00, "Untransformed vertex with linear vertex fog has color %08x\n", color);
768 color = getPixelColor(device, 480, 120);
769 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
770 if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
772 color = getPixelColor(device, 480, 360);
773 ok(color == 0x0000FF00, "Transformed vertex with linear table fog has color %08x\n", color);
775 else
777 /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
778 * The settings above result in no fogging with vertex fog
780 color = getPixelColor(device, 480, 120);
781 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
782 trace("Info: Table fog not supported by this device\n");
785 /* Now test the special case fogstart == fogend */
786 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
787 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
789 if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
791 start = 512;
792 end = 512;
793 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
794 ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
795 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
796 ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
798 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
799 ok( hr == D3D_OK, "SetFVF returned %s\n", DXGetErrorString9(hr));
800 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
801 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %s\n", DXGetErrorString9(hr));
802 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
803 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %s\n", DXGetErrorString9(hr));
805 /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
806 * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
807 * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
808 * The third transformed quad remains unfogged because the fogcoords are read from the specular
809 * color and has fixed fogstart and fogend.
811 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
812 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
813 sizeof(unstransformed_1[0]));
814 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
815 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
816 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
817 sizeof(unstransformed_1[0]));
818 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
820 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
821 ok( hr == D3D_OK, "SetFVF returned %s\n", DXGetErrorString9(hr));
822 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
823 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
824 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
825 sizeof(transformed_1[0]));
826 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
828 hr = IDirect3DDevice9_EndScene(device);
829 ok(hr == D3D_OK, "EndScene returned %s\n", DXGetErrorString9(hr));
831 else
833 ok(FALSE, "BeginScene failed\n");
835 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
836 color = getPixelColor(device, 160, 360);
837 ok(color == 0x0000FF00, "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
838 color = getPixelColor(device, 160, 120);
839 ok(color == 0x0000FF00, "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
840 color = getPixelColor(device, 480, 120);
841 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
843 /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
844 * but without shaders it seems to work everywhere
846 end = 0.2;
847 start = 0.8;
848 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
849 ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
850 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
851 ok(hr == D3D_OK, "Setting fog end returned %s\n", DXGetErrorString9(hr));
852 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
853 ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
855 /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
856 * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
857 * so skip this for now
859 for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
860 const char *mode = (i ? "table" : "vertex");
861 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
862 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
863 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
864 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
865 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
866 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
867 hr = IDirect3DDevice9_BeginScene(device);
868 ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
869 if(SUCCEEDED(hr)) {
870 WORD Indices2[] = { 0, 1, 2, 2, 3, 0,
871 4, 5, 6, 6, 7, 4,
872 8, 9, 10, 10, 11, 8,
873 12, 13, 14, 14, 15, 12};
875 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
876 16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
877 sizeof(rev_fog_quads[0]));
879 hr = IDirect3DDevice9_EndScene(device);
880 ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
882 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
883 color = getPixelColor(device, 160, 360);
884 ok(color == 0x0000FF00, "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00\n", mode, color);
886 color = getPixelColor(device, 160, 120);
887 r = (color & 0x00ff0000) >> 16;
888 g = (color & 0x0000ff00) >> 8;
889 b = (color & 0x000000ff);
890 ok(r == 0x00 && g >= 0x29 && g <= 0x2d && b >= 0xd2 && b <= 0xd6,
891 "Reversed %s fog: z=0.7 has color 0x%08x, expected\n", mode, color);
893 color = getPixelColor(device, 480, 120);
894 r = (color & 0x00ff0000) >> 16;
895 g = (color & 0x0000ff00) >> 8;
896 b = (color & 0x000000ff);
897 ok(r == 0x00 && g >= 0xa8 && g <= 0xac && b >= 0x53 && b <= 0x57,
898 "Reversed %s fog: z=0.4 has color 0x%08x, expected\n", mode, color);
900 color = getPixelColor(device, 480, 360);
901 ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
903 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
904 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
905 break;
908 /* Turn off the fog master switch to avoid confusing other tests */
909 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
910 ok(hr == D3D_OK, "Turning off fog calculations returned %s\n", DXGetErrorString9(hr));
911 start = 0.0;
912 end = 1.0;
913 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
914 ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
915 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
916 ok(hr == D3D_OK, "Setting fog end returned %s\n", DXGetErrorString9(hr));
917 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
918 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %s\n", DXGetErrorString9(hr));
919 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
920 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %s\n", DXGetErrorString9(hr));
923 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
924 * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
925 * regardless of the actual addressing mode set. */
926 static void test_cube_wrap(IDirect3DDevice9 *device)
928 static const float quad[][6] = {
929 {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
930 {-1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
931 { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
932 { 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
935 static const D3DVERTEXELEMENT9 decl_elements[] = {
936 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
937 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
938 D3DDECL_END()
941 static const struct {
942 D3DTEXTUREADDRESS mode;
943 const char *name;
944 } address_modes[] = {
945 {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
946 {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
947 {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
948 {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
949 {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
952 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
953 IDirect3DCubeTexture9 *texture = NULL;
954 IDirect3DSurface9 *surface = NULL;
955 D3DLOCKED_RECT locked_rect;
956 HRESULT hr;
957 UINT x;
958 INT y, face;
960 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
961 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
962 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
963 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
965 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
966 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
967 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
969 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
970 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
972 for (y = 0; y < 128; ++y)
974 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
975 for (x = 0; x < 64; ++x)
977 *ptr++ = 0xffff0000;
979 for (x = 64; x < 128; ++x)
981 *ptr++ = 0xff0000ff;
985 hr = IDirect3DSurface9_UnlockRect(surface);
986 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
988 hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
989 D3DPOOL_DEFAULT, &texture, NULL);
990 ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
992 /* Create cube faces */
993 for (face = 0; face < 6; ++face)
995 IDirect3DSurface9 *face_surface = NULL;
997 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
998 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1000 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1001 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1003 IDirect3DSurface9_Release(face_surface);
1006 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1007 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1009 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1010 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1011 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1012 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1013 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1014 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1016 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1017 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1019 for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1021 DWORD color;
1023 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1024 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1025 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1026 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1028 hr = IDirect3DDevice9_BeginScene(device);
1029 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1031 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1032 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1034 hr = IDirect3DDevice9_EndScene(device);
1035 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1037 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1038 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1040 /* Due to the nature of this test, we sample essentially at the edge
1041 * between two faces. Because of this it's undefined from which face
1042 * the driver will sample. Furtunately that's not important for this
1043 * test, since all we care about is that it doesn't sample from the
1044 * other side of the surface or from the border. */
1045 color = getPixelColor(device, 320, 240);
1046 ok(color == 0x00ff0000 || color == 0x000000ff,
1047 "Got color 0x%08x for addressing mode %s, expected 0x00ff0000 or 0x000000ff.\n",
1048 color, address_modes[x].name);
1050 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1051 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1054 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1055 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1057 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1058 IDirect3DCubeTexture9_Release(texture);
1059 IDirect3DSurface9_Release(surface);
1062 static void offscreen_test(IDirect3DDevice9 *device)
1064 HRESULT hr;
1065 IDirect3DTexture9 *offscreenTexture = NULL;
1066 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1067 DWORD color;
1069 static const float quad[][5] = {
1070 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1071 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
1072 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1073 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
1076 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1077 ok(hr == D3D_OK, "Clear failed, hr = %s\n", DXGetErrorString9(hr));
1079 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1080 ok(hr == D3D_OK || D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %s\n", DXGetErrorString9(hr));
1081 if(!offscreenTexture) {
1082 trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1083 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1084 ok(hr == D3D_OK || D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %s\n", DXGetErrorString9(hr));
1085 if(!offscreenTexture) {
1086 skip("Cannot create an offscreen render target\n");
1087 goto out;
1091 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1092 ok(hr == D3D_OK, "Can't get back buffer, hr = %s\n", DXGetErrorString9(hr));
1093 if(!backbuffer) {
1094 goto out;
1097 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1098 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %s\n", DXGetErrorString9(hr));
1099 if(!offscreen) {
1100 goto out;
1103 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1104 ok(hr == D3D_OK, "SetFVF failed, hr = %s\n", DXGetErrorString9(hr));
1106 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1107 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
1108 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1109 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
1110 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1111 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1112 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1113 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1114 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1115 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1117 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1118 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1119 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %s\n", DXGetErrorString9(hr));
1120 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1121 ok(hr == D3D_OK, "Clear failed, hr = %s\n", DXGetErrorString9(hr));
1123 /* Draw without textures - Should resut in a white quad */
1124 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1125 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %s\n", DXGetErrorString9(hr));
1127 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1128 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %s\n", DXGetErrorString9(hr));
1129 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1130 ok(hr == D3D_OK, "SetTexture failed, %s\n", DXGetErrorString9(hr));
1132 /* This time with the texture */
1133 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1134 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %s\n", DXGetErrorString9(hr));
1136 IDirect3DDevice9_EndScene(device);
1139 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1141 /* Center quad - should be white */
1142 color = getPixelColor(device, 320, 240);
1143 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1144 /* Some quad in the cleared part of the texture */
1145 color = getPixelColor(device, 170, 240);
1146 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1147 /* Part of the originally cleared back buffer */
1148 color = getPixelColor(device, 10, 10);
1149 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1150 if(0) {
1151 /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1152 * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1153 * the offscreen rendering mode this test would succeed or fail
1155 color = getPixelColor(device, 10, 470);
1156 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1159 out:
1160 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1162 /* restore things */
1163 if(backbuffer) {
1164 IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1165 IDirect3DSurface9_Release(backbuffer);
1167 if(offscreenTexture) {
1168 IDirect3DTexture9_Release(offscreenTexture);
1170 if(offscreen) {
1171 IDirect3DSurface9_Release(offscreen);
1175 /* This test tests fog in combination with shaders.
1176 * What's tested: linear fog (vertex and table) with pixel shader
1177 * linear table fog with non foggy vertex shader
1178 * vertex fog with foggy vertex shader
1179 * What's not tested: non linear fog with shader
1180 * table fog with foggy vertex shader
1182 static void fog_with_shader_test(IDirect3DDevice9 *device)
1184 HRESULT hr;
1185 DWORD color;
1186 union {
1187 float f;
1188 DWORD i;
1189 } start, end;
1190 unsigned int i, j;
1192 /* basic vertex shader without fog computation ("non foggy") */
1193 static const DWORD vertex_shader_code1[] = {
1194 0xfffe0101, /* vs_1_1 */
1195 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1196 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1197 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1198 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1199 0x0000ffff
1201 /* basic vertex shader with reversed fog computation ("foggy") */
1202 static const DWORD vertex_shader_code2[] = {
1203 0xfffe0101, /* vs_1_1 */
1204 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1205 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1206 0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1207 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1208 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1209 0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
1210 0x00000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
1211 0x0000ffff
1213 /* basic pixel shader */
1214 static const DWORD pixel_shader_code[] = {
1215 0xffff0101, /* ps_1_1 */
1216 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, vo */
1217 0x0000ffff
1220 static struct vertex quad[] = {
1221 {-1.0f, -1.0f, 0.0f, 0xFFFF0000 },
1222 {-1.0f, 1.0f, 0.0f, 0xFFFF0000 },
1223 { 1.0f, -1.0f, 0.0f, 0xFFFF0000 },
1224 { 1.0f, 1.0f, 0.0f, 0xFFFF0000 },
1227 static const D3DVERTEXELEMENT9 decl_elements[] = {
1228 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1229 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
1230 D3DDECL_END()
1233 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1234 IDirect3DVertexShader9 *vertex_shader[3] = {NULL, NULL, NULL};
1235 IDirect3DPixelShader9 *pixel_shader[2] = {NULL, NULL};
1237 /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1238 static const struct test_data_t {
1239 int vshader;
1240 int pshader;
1241 D3DFOGMODE vfog;
1242 D3DFOGMODE tfog;
1243 unsigned int color[11];
1244 } test_data[] = {
1245 /* only pixel shader: */
1246 {0, 1, 0, 3,
1247 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1248 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1249 {0, 1, 1, 3,
1250 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1251 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1252 {0, 1, 2, 3,
1253 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1254 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1255 {0, 1, 3, 0,
1256 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1257 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1258 {0, 1, 3, 3,
1259 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1260 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1262 /* vertex shader */
1263 {1, 0, 0, 0,
1264 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1265 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1266 {1, 0, 0, 3,
1267 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1268 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1269 {1, 0, 1, 3,
1270 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1271 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1273 {1, 0, 2, 3,
1274 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1275 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1276 {1, 0, 3, 3,
1277 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1278 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1280 /* vertex shader and pixel shader */
1281 {1, 1, 0, 3,
1282 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1283 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1284 {1, 1, 1, 3,
1285 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1286 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1287 {1, 1, 2, 3,
1288 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1289 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1291 {1, 1, 3, 3,
1292 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1293 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1296 #if 0 /* FIXME: these fail on GeForce 8500 */
1297 /* foggy vertex shader */
1298 {2, 0, 0, 0,
1299 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1300 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1301 {2, 0, 1, 0,
1302 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1303 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1304 {2, 0, 2, 0,
1305 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1306 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1307 {2, 0, 3, 0,
1308 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1309 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1310 #endif
1312 /* foggy vertex shader and pixel shader */
1313 {2, 1, 0, 0,
1314 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1315 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1316 {2, 1, 1, 0,
1317 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1318 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1319 {2, 1, 2, 0,
1320 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1321 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1322 {2, 1, 3, 0,
1323 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1324 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1328 /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1329 start.f=0.1f;
1330 end.f=0.9f;
1332 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1333 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1334 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1335 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1336 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1337 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1338 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1339 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1341 /* Setup initial states: No lighting, fog on, fog color */
1342 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1343 ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1344 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1345 ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1346 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1347 ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1348 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1349 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1351 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1352 ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1353 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1354 ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1356 /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1357 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1358 ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1359 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1360 ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1362 for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1364 hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1365 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1366 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1367 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1368 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1369 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1370 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1371 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1373 for(j=0; j < 11; j++)
1375 /* Don't use the whole zrange to prevent rounding errors */
1376 quad[0].z = 0.001f + (float)j / 10.02f;
1377 quad[1].z = 0.001f + (float)j / 10.02f;
1378 quad[2].z = 0.001f + (float)j / 10.02f;
1379 quad[3].z = 0.001f + (float)j / 10.02f;
1381 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1382 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1384 hr = IDirect3DDevice9_BeginScene(device);
1385 ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1387 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1388 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1390 hr = IDirect3DDevice9_EndScene(device);
1391 ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1393 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1395 /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1396 color = getPixelColor(device, 128, 240);
1397 ok((unsigned char)(color) == ((unsigned char)test_data[i].color[j])
1398 && abs( ((unsigned char)(color>>8)) - (unsigned char)(test_data[i].color[j]>>8) ) < 13
1399 && abs( ((unsigned char)(color>>16)) - (unsigned char)(test_data[i].color[j]>>16) ) < 13,
1400 "fog ps%i vs%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n", test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1404 /* reset states */
1405 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1406 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1407 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1408 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1409 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1410 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1411 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1412 ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1414 IDirect3DVertexShader9_Release(vertex_shader[1]);
1415 IDirect3DVertexShader9_Release(vertex_shader[2]);
1416 IDirect3DPixelShader9_Release(pixel_shader[1]);
1417 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1420 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
1421 unsigned int i, x, y;
1422 HRESULT hr;
1423 IDirect3DTexture9 *texture[2] = {NULL, NULL};
1424 D3DLOCKED_RECT locked_rect;
1426 /* Generate the textures */
1427 for(i=0; i<2; i++)
1429 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1430 D3DPOOL_MANAGED, &texture[i], NULL);
1431 ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1433 hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
1434 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1435 for (y = 0; y < 128; ++y)
1437 if(i)
1438 { /* Set up black texture with 2x2 texel white spot in the middle */
1439 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1440 for (x = 0; x < 128; ++x)
1442 if(y>62 && y<66 && x>62 && x<66)
1443 *ptr++ = 0xffffffff;
1444 else
1445 *ptr++ = 0xff000000;
1448 else
1449 { /* Set up a displacement map which points away from the center parallel to the closest axis.
1450 * (if multiplied with bumpenvmat)
1452 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1453 for (x = 0; x < 128; ++x)
1455 if(abs(x-64)>abs(y-64))
1457 if(x < 64)
1458 *ptr++ = 0xc000;
1459 else
1460 *ptr++ = 0x4000;
1462 else
1464 if(y < 64)
1465 *ptr++ = 0x0040;
1466 else
1467 *ptr++ = 0x00c0;
1472 hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
1473 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1475 hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
1476 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1478 /* Disable texture filtering */
1479 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1480 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1481 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1482 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1484 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1485 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
1486 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1487 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
1491 /* test the behavior of the texbem instruction
1492 * with normal 2D and projective 2D textures
1494 static void texbem_test(IDirect3DDevice9 *device)
1496 HRESULT hr;
1497 DWORD color;
1498 int i;
1500 static const DWORD pixel_shader_code[] = {
1501 0xffff0101, /* ps_1_1*/
1502 0x00000042, 0xb00f0000, /* tex t0*/
1503 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
1504 0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
1505 0x0000ffff
1508 static const float quad[][7] = {
1509 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
1510 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
1511 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
1512 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
1514 static const float quad_proj[][9] = {
1515 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 128.0f},
1516 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 128.0f, 0.0f, 128.0f},
1517 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f, 0.0f, 0.0f, 128.0f},
1518 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
1521 static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
1522 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1523 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1524 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1525 D3DDECL_END()
1527 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1528 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1529 {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1530 D3DDECL_END()
1531 } };
1533 /* use assymetric matrix to test loading */
1534 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
1536 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1537 IDirect3DPixelShader9 *pixel_shader = NULL;
1538 IDirect3DTexture9 *texture = NULL;
1540 generate_bumpmap_textures(device);
1542 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1543 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1544 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1545 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1546 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
1548 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1549 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1551 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1552 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1554 for(i=0; i<2; i++)
1556 if(i)
1558 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
1559 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1562 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
1563 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1564 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1565 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1567 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
1568 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1569 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1570 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1572 hr = IDirect3DDevice9_BeginScene(device);
1573 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1575 if(!i)
1576 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1577 else
1578 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
1579 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1581 hr = IDirect3DDevice9_EndScene(device);
1582 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1584 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1585 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1587 color = getPixelColor(device, 320-32, 240);
1588 ok(color == 0x00ffffff, "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1589 color = getPixelColor(device, 320+32, 240);
1590 ok(color == 0x00ffffff, "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1591 color = getPixelColor(device, 320, 240-32);
1592 ok(color == 0x00ffffff, "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1593 color = getPixelColor(device, 320, 240+32);
1594 ok(color == 0x00ffffff, "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1596 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1597 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1598 IDirect3DPixelShader9_Release(pixel_shader);
1600 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1601 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1602 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1605 /* clean up */
1606 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1607 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1609 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
1610 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1612 for(i=0; i<2; i++)
1614 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
1615 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
1616 IDirect3DTexture9_Release(texture); /* For the GetTexture */
1617 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
1618 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1619 IDirect3DTexture9_Release(texture);
1623 static void z_range_test(IDirect3DDevice9 *device)
1625 const struct vertex quad[] =
1627 {-1.0f, 0.0f, 1.1f, 0xffff0000},
1628 {-1.0f, 1.0f, 1.1f, 0xffff0000},
1629 { 1.0f, 0.0f, -1.1f, 0xffff0000},
1630 { 1.0f, 1.0f, -1.1f, 0xffff0000},
1632 const struct vertex quad2[] =
1634 {-1.0f, 0.0f, 1.1f, 0xff0000ff},
1635 {-1.0f, 1.0f, 1.1f, 0xff0000ff},
1636 { 1.0f, 0.0f, -1.1f, 0xff0000ff},
1637 { 1.0f, 1.0f, -1.1f, 0xff0000ff},
1640 const struct tvertex quad3[] =
1642 { 0, 240, 1.1f, 1.0, 0xffffff00},
1643 { 0, 480, 1.1f, 1.0, 0xffffff00},
1644 { 640, 240, -1.1f, 1.0, 0xffffff00},
1645 { 640, 480, -1.1f, 1.0, 0xffffff00},
1647 const struct tvertex quad4[] =
1649 { 0, 240, 1.1f, 1.0, 0xff00ff00},
1650 { 0, 480, 1.1f, 1.0, 0xff00ff00},
1651 { 640, 240, -1.1f, 1.0, 0xff00ff00},
1652 { 640, 480, -1.1f, 1.0, 0xff00ff00},
1654 HRESULT hr;
1655 DWORD color;
1656 IDirect3DVertexShader9 *shader;
1657 IDirect3DVertexDeclaration9 *decl;
1658 D3DCAPS9 caps;
1659 const DWORD shader_code[] = {
1660 0xfffe0101, /* vs_1_1 */
1661 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1662 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1663 0x00000001, 0xd00f0000, 0xa0e40000, /* mov oD0, c0 */
1664 0x0000ffff /* end */
1666 static const D3DVERTEXELEMENT9 decl_elements[] = {
1667 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1668 D3DDECL_END()
1670 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
1671 * then call Present. Then clear the color buffer to make sure it has some defined content
1672 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
1673 * by the depth value.
1675 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
1676 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
1677 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1678 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
1680 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
1681 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1682 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
1683 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1684 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
1685 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1686 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
1687 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1688 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1689 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
1691 hr = IDirect3DDevice9_BeginScene(device);
1692 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
1693 if(hr == D3D_OK)
1695 /* Test the untransformed vertex path */
1696 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
1697 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1698 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
1699 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1700 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
1701 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1703 /* Test the transformed vertex path */
1704 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
1705 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
1707 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
1708 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1709 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
1710 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1711 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
1712 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1714 hr = IDirect3DDevice9_EndScene(device);
1715 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
1718 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1719 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1721 /* Do not test the exact corner pixels, but go pretty close to them */
1723 /* Clipped because z > 1.0 */
1724 color = getPixelColor(device, 28, 238);
1725 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1726 color = getPixelColor(device, 28, 241);
1727 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1729 /* Not clipped, > z buffer clear value(0.75) */
1730 color = getPixelColor(device, 31, 238);
1731 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1732 color = getPixelColor(device, 31, 241);
1733 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1734 color = getPixelColor(device, 100, 238);
1735 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1736 color = getPixelColor(device, 100, 241);
1737 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1739 /* Not clipped, < z buffer clear value */
1740 color = getPixelColor(device, 104, 238);
1741 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
1742 color = getPixelColor(device, 104, 241);
1743 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
1744 color = getPixelColor(device, 318, 238);
1745 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
1746 color = getPixelColor(device, 318, 241);
1747 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
1749 /* Clipped because z < 0.0 */
1750 color = getPixelColor(device, 321, 238);
1751 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1752 color = getPixelColor(device, 321, 241);
1753 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1755 /* Test the shader path */
1756 IDirect3DDevice9_GetDeviceCaps(device, &caps);
1757 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
1758 skip("Vertex shaders not supported\n");
1759 goto out;
1761 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
1762 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
1763 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
1764 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
1766 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
1768 IDirect3DDevice9_SetVertexDeclaration(device, decl);
1769 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
1770 IDirect3DDevice9_SetVertexShader(device, shader);
1771 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
1773 hr = IDirect3DDevice9_BeginScene(device);
1774 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
1775 if(hr == D3D_OK)
1777 float colorf[] = {1.0, 0.0, 0.0, 1.0};
1778 float colorf2[] = {0.0, 0.0, 1.0, 1.0};
1779 IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
1780 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
1781 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1782 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
1783 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1784 IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
1785 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
1786 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1788 hr = IDirect3DDevice9_EndScene(device);
1789 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
1792 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1793 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
1794 IDirect3DDevice9_SetVertexShader(device, NULL);
1795 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
1797 IDirect3DVertexDeclaration9_Release(decl);
1798 IDirect3DVertexShader9_Release(shader);
1800 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1801 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1802 /* Z < 1.0 */
1803 color = getPixelColor(device, 28, 238);
1804 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1806 /* 1.0 < z < 0.75 */
1807 color = getPixelColor(device, 31, 238);
1808 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1809 color = getPixelColor(device, 100, 238);
1810 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1812 /* 0.75 < z < 0.0 */
1813 color = getPixelColor(device, 104, 238);
1814 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
1815 color = getPixelColor(device, 318, 238);
1816 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
1818 /* 0.0 < z */
1819 color = getPixelColor(device, 321, 238);
1820 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1822 out:
1823 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
1824 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1825 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
1826 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1827 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
1828 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1831 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
1833 D3DSURFACE_DESC desc;
1834 D3DLOCKED_RECT l;
1835 HRESULT hr;
1836 unsigned int x, y;
1837 DWORD *mem;
1839 memset(&desc, 0, sizeof(desc));
1840 memset(&l, 0, sizeof(l));
1841 hr = IDirect3DSurface9_GetDesc(surface, &desc);
1842 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %s\n", DXGetErrorString9(hr));
1843 hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
1844 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %s\n", DXGetErrorString9(hr));
1845 if(FAILED(hr)) return;
1847 for(y = 0; y < desc.Height; y++)
1849 mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
1850 for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
1852 mem[x] = color;
1855 hr = IDirect3DSurface9_UnlockRect(surface);
1856 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %s\n", DXGetErrorString9(hr));
1859 static void maxmip_test(IDirect3DDevice9 *device)
1861 IDirect3DTexture9 *texture = NULL;
1862 IDirect3DSurface9 *surface = NULL;
1863 HRESULT hr;
1864 DWORD color;
1865 const float quads[] = {
1866 -1.0, -1.0, 0.0, 0.0, 0.0,
1867 -1.0, 0.0, 0.0, 0.0, 1.0,
1868 0.0, -1.0, 0.0, 1.0, 0.0,
1869 0.0, 0.0, 0.0, 1.0, 1.0,
1871 0.0, -1.0, 0.0, 0.0, 0.0,
1872 0.0, 0.0, 0.0, 0.0, 1.0,
1873 1.0, -1.0, 0.0, 1.0, 0.0,
1874 1.0, 0.0, 0.0, 1.0, 1.0,
1876 0.0, 0.0, 0.0, 0.0, 0.0,
1877 0.0, 1.0, 0.0, 0.0, 1.0,
1878 1.0, 0.0, 0.0, 1.0, 0.0,
1879 1.0, 1.0, 0.0, 1.0, 1.0,
1881 -1.0, 0.0, 0.0, 0.0, 0.0,
1882 -1.0, 1.0, 0.0, 0.0, 1.0,
1883 0.0, 0.0, 0.0, 1.0, 0.0,
1884 0.0, 1.0, 0.0, 1.0, 1.0,
1887 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
1888 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
1890 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
1891 &texture, NULL);
1892 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
1893 if(!texture)
1895 skip("Failed to create test texture\n");
1896 return;
1899 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
1900 fill_surface(surface, 0xffff0000);
1901 IDirect3DSurface9_Release(surface);
1902 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
1903 fill_surface(surface, 0xff00ff00);
1904 IDirect3DSurface9_Release(surface);
1905 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
1906 fill_surface(surface, 0xff0000ff);
1907 IDirect3DSurface9_Release(surface);
1909 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
1910 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
1911 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1912 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
1914 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
1915 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
1917 hr = IDirect3DDevice9_BeginScene(device);
1918 if(SUCCEEDED(hr))
1920 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
1921 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
1922 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
1923 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1925 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
1926 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
1927 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
1928 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1930 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
1931 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
1932 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
1933 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1935 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
1936 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
1937 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
1938 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1939 hr = IDirect3DDevice9_EndScene(device);
1942 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1943 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1944 /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
1945 color = getPixelColor(device, 160, 360);
1946 ok(color == 0x00FF0000, "MapMip 0, no mipfilter has color %08x\n", color);
1947 color = getPixelColor(device, 160, 120);
1948 ok(color == 0x00FF0000, "MapMip 3, no mipfilter has color %08x\n", color);
1949 color = getPixelColor(device, 480, 120);
1950 ok(color == 0x00FF0000, "MapMip 2, no mipfilter has color %08x\n", color);
1951 color = getPixelColor(device, 480, 360);
1952 ok(color == 0x00FF0000, "MapMip 1, no mipfilter has color %08x\n", color);
1954 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
1955 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
1957 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
1958 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
1960 hr = IDirect3DDevice9_BeginScene(device);
1961 if(SUCCEEDED(hr))
1963 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
1964 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
1965 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
1966 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1968 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
1969 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
1970 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
1971 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1973 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
1974 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
1975 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
1976 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1978 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
1979 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
1980 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
1981 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1982 hr = IDirect3DDevice9_EndScene(device);
1985 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
1986 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
1987 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
1988 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
1990 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1991 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1992 /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
1993 * samples from the highest level in the texture(level 2)
1995 color = getPixelColor(device, 160, 360);
1996 ok(color == 0x00FF0000, "MapMip 0, point mipfilter has color %08x\n", color);
1997 color = getPixelColor(device, 160, 120);
1998 ok(color == 0x000000FF, "MapMip 3, point mipfilter has color %08x\n", color);
1999 color = getPixelColor(device, 480, 120);
2000 ok(color == 0x000000FF, "MapMip 2, point mipfilter has color %08x\n", color);
2001 color = getPixelColor(device, 480, 360);
2002 ok(color == 0x0000FF00, "MapMip 1, point mipfilter has color %08x\n", color);
2004 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2005 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2006 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2007 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2008 IDirect3DTexture9_Release(texture);
2011 static void release_buffer_test(IDirect3DDevice9 *device)
2013 IDirect3DVertexBuffer9 *vb = NULL;
2014 IDirect3DIndexBuffer9 *ib = NULL;
2015 HRESULT hr;
2016 BYTE *data;
2017 long ref;
2019 static const struct vertex quad[] = {
2020 {-1.0, -1.0, 0.1, 0xffff0000},
2021 {-1.0, 1.0, 0.1, 0xffff0000},
2022 { 1.0, 1.0, 0.1, 0xffff0000},
2024 {-1.0, -1.0, 0.1, 0xff00ff00},
2025 {-1.0, 1.0, 0.1, 0xff00ff00},
2026 { 1.0, 1.0, 0.1, 0xff00ff00}
2028 short indices[] = {3, 4, 5};
2030 /* Index and vertex buffers should always be creatable */
2031 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
2032 D3DPOOL_MANAGED, &vb, NULL);
2033 ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
2034 if(!vb) {
2035 skip("Failed to create a vertex buffer\n");
2036 return;
2038 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
2039 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %s\n", DXGetErrorString9(hr));
2040 if(!ib) {
2041 skip("Failed to create an index buffer\n");
2042 return;
2045 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
2046 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
2047 memcpy(data, quad, sizeof(quad));
2048 hr = IDirect3DVertexBuffer9_Unlock(vb);
2049 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
2051 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
2052 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
2053 memcpy(data, indices, sizeof(indices));
2054 hr = IDirect3DIndexBuffer9_Unlock(ib);
2055 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
2057 hr = IDirect3DDevice9_SetIndices(device, ib);
2058 ok(hr == D3D_OK, "IDirect3DIndexBuffer8_Unlock failed with %s\n", DXGetErrorString9(hr));
2059 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
2060 ok(hr == D3D_OK, "IDirect3DIndexBuffer8_Unlock failed with %s\n", DXGetErrorString9(hr));
2061 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2062 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2064 /* Now destroy the bound index buffer and draw again */
2065 ref = IDirect3DIndexBuffer9_Release(ib);
2066 ok(ref == 0, "Index Buffer reference count is %08ld\n", ref);
2068 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
2069 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
2071 hr = IDirect3DDevice9_BeginScene(device);
2072 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2073 if(SUCCEEDED(hr))
2075 /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
2076 * making assumptions about the indices or vertices
2078 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
2079 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
2080 hr = IDirect3DDevice9_EndScene(device);
2081 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2084 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2085 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
2087 hr = IDirect3DDevice9_SetIndices(device, NULL);
2088 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2089 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
2090 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2092 /* Index buffer was already destroyed as part of the test */
2093 IDirect3DVertexBuffer9_Release(vb);
2096 static void float_texture_test(IDirect3DDevice9 *device)
2098 IDirect3D9 *d3d = NULL;
2099 HRESULT hr;
2100 IDirect3DTexture9 *texture = NULL;
2101 D3DLOCKED_RECT lr;
2102 float *data;
2103 DWORD color;
2104 float quad[] = {
2105 -1.0, -1.0, 0.1, 0.0, 0.0,
2106 -1.0, 1.0, 0.1, 0.0, 1.0,
2107 1.0, -1.0, 0.1, 1.0, 0.0,
2108 1.0, 1.0, 0.1, 1.0, 1.0,
2111 memset(&lr, 0, sizeof(lr));
2112 IDirect3DDevice9_GetDirect3D(device, &d3d);
2113 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
2114 D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
2115 skip("D3DFMT_R32F textures not supported\n");
2116 goto out;
2119 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
2120 D3DPOOL_MANAGED, &texture, NULL);
2121 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
2122 if(!texture) {
2123 skip("Failed to create R32F texture\n");
2124 goto out;
2127 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
2128 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %s\n", DXGetErrorString9(hr));
2129 data = lr.pBits;
2130 *data = 0.0;
2131 hr = IDirect3DTexture9_UnlockRect(texture, 0);
2132 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %s\n", DXGetErrorString9(hr));
2134 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2135 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2137 hr = IDirect3DDevice9_BeginScene(device);
2138 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
2139 if(SUCCEEDED(hr))
2141 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2142 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2144 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2145 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2147 hr = IDirect3DDevice9_EndScene(device);
2148 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
2150 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2151 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2153 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2154 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2156 color = getPixelColor(device, 240, 320);
2157 ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
2159 out:
2160 if(texture) IDirect3DTexture9_Release(texture);
2161 IDirect3D9_Release(d3d);
2164 static void g16r16_texture_test(IDirect3DDevice9 *device)
2166 IDirect3D9 *d3d = NULL;
2167 HRESULT hr;
2168 IDirect3DTexture9 *texture = NULL;
2169 D3DLOCKED_RECT lr;
2170 DWORD *data;
2171 DWORD color, red, green, blue;
2172 float quad[] = {
2173 -1.0, -1.0, 0.1, 0.0, 0.0,
2174 -1.0, 1.0, 0.1, 0.0, 1.0,
2175 1.0, -1.0, 0.1, 1.0, 0.0,
2176 1.0, 1.0, 0.1, 1.0, 1.0,
2179 memset(&lr, 0, sizeof(lr));
2180 IDirect3DDevice9_GetDirect3D(device, &d3d);
2181 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
2182 D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
2183 skip("D3DFMT_G16R16 textures not supported\n");
2184 goto out;
2187 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
2188 D3DPOOL_MANAGED, &texture, NULL);
2189 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
2190 if(!texture) {
2191 skip("Failed to create D3DFMT_G16R16 texture\n");
2192 goto out;
2195 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
2196 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %s\n", DXGetErrorString9(hr));
2197 data = lr.pBits;
2198 *data = 0x0f00f000;
2199 hr = IDirect3DTexture9_UnlockRect(texture, 0);
2200 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %s\n", DXGetErrorString9(hr));
2202 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2203 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2205 hr = IDirect3DDevice9_BeginScene(device);
2206 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
2207 if(SUCCEEDED(hr))
2209 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2210 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2212 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2213 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2215 hr = IDirect3DDevice9_EndScene(device);
2216 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
2218 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2219 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2221 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2222 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2224 color = getPixelColor(device, 240, 320);
2225 red = (color & 0x00ff0000) >> 16;
2226 green = (color & 0x0000ff00) >> 8;
2227 blue = (color & 0x000000ff) >> 0;
2228 ok(blue == 0xff && red >= 0xef && red <= 0xf1 && green >= 0x0e && green <= 0x10,
2229 "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00F00FFF\n", color);
2231 out:
2232 if(texture) IDirect3DTexture9_Release(texture);
2233 IDirect3D9_Release(d3d);
2236 static void texture_transform_flags_test(IDirect3DDevice9 *device)
2238 HRESULT hr;
2239 IDirect3D9 *d3d;
2240 D3DFORMAT fmt = D3DFMT_X8R8G8B8;
2241 D3DCAPS9 caps;
2242 IDirect3DTexture9 *texture = NULL;
2243 IDirect3DVolumeTexture9 *volume = NULL;
2244 unsigned int x, y, z;
2245 D3DLOCKED_RECT lr;
2246 D3DLOCKED_BOX lb;
2247 DWORD color;
2248 IDirect3DVertexDeclaration9 *decl, *decl2;
2249 float identity[16] = {1.0, 0.0, 0.0, 0.0,
2250 0.0, 1.0, 0.0, 0.0,
2251 0.0, 0.0, 1.0, 0.0,
2252 0.0, 0.0, 0.0, 1.0};
2253 static const D3DVERTEXELEMENT9 decl_elements[] = {
2254 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2255 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2256 D3DDECL_END()
2258 static const D3DVERTEXELEMENT9 decl_elements2[] = {
2259 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2260 {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2261 D3DDECL_END()
2264 memset(&lr, 0, sizeof(lr));
2265 memset(&lb, 0, sizeof(lb));
2266 IDirect3DDevice9_GetDirect3D(device, &d3d);
2267 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
2268 D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
2269 fmt = D3DFMT_A16B16G16R16;
2271 IDirect3D9_Release(d3d);
2273 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2274 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
2275 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
2276 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
2277 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
2278 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %s\n", DXGetErrorString9(hr));
2279 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
2280 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %s\n", DXGetErrorString9(hr));
2281 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
2282 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %s\n", DXGetErrorString9(hr));
2283 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2284 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %s\n", DXGetErrorString9(hr));
2285 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2286 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %s\n", DXGetErrorString9(hr));
2287 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2288 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %s\n", DXGetErrorString9(hr));
2289 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
2290 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %s\n", DXGetErrorString9(hr));
2291 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2292 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %s\n", DXGetErrorString9(hr));
2293 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
2294 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
2296 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2297 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %s\n", DXGetErrorString9(hr));
2298 hr = IDirect3DDevice9_CreateTexture(device, caps.MaxTextureWidth, caps.MaxTextureHeight, 1,
2299 0, fmt, D3DPOOL_MANAGED, &texture, NULL);
2300 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %s\n", DXGetErrorString9(hr));
2301 if(!texture) {
2302 skip("Failed to create the test texture\n");
2303 return;
2306 /* Unfortunately there is no easy way to set up a texture coordinate passthrough
2307 * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
2308 * 1.0 in red and green for the x and y coords
2310 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
2311 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %s\n", DXGetErrorString9(hr));
2312 for(y = 0; y < caps.MaxTextureHeight; y++) {
2313 for(x = 0; x < caps.MaxTextureWidth; x++) {
2314 double r_f = (double) y / (double) caps.MaxTextureHeight;
2315 double g_f = (double) x / (double) caps.MaxTextureWidth;
2316 if(fmt == D3DFMT_A16B16G16R16) {
2317 unsigned short r, g;
2318 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
2319 r = (unsigned short) (r_f * 65536.0);
2320 g = (unsigned short) (g_f * 65536.0);
2321 dst[0] = r;
2322 dst[1] = g;
2323 dst[2] = 0;
2324 dst[3] = 65535;
2325 } else {
2326 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
2327 unsigned char r = (unsigned char) (r_f * 255.0);
2328 unsigned char g = (unsigned char) (g_f * 255.0);
2329 dst[0] = 0;
2330 dst[1] = g;
2331 dst[2] = r;
2332 dst[3] = 255;
2336 hr = IDirect3DTexture9_UnlockRect(texture, 0);
2337 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %s\n", DXGetErrorString9(hr));
2338 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2339 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
2341 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2342 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2343 hr = IDirect3DDevice9_BeginScene(device);
2344 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
2345 if(SUCCEEDED(hr))
2347 float quad1[] = {
2348 -1.0, -1.0, 0.1, 1.0, 1.0,
2349 -1.0, 0.0, 0.1, 1.0, 1.0,
2350 0.0, -1.0, 0.1, 1.0, 1.0,
2351 0.0, 0.0, 0.1, 1.0, 1.0,
2353 float quad2[] = {
2354 -1.0, 0.0, 0.1, 1.0, 1.0,
2355 -1.0, 1.0, 0.1, 1.0, 1.0,
2356 0.0, 0.0, 0.1, 1.0, 1.0,
2357 0.0, 1.0, 0.1, 1.0, 1.0,
2359 float quad3[] = {
2360 0.0, 0.0, 0.1, 0.5, 0.5,
2361 0.0, 1.0, 0.1, 0.5, 0.5,
2362 1.0, 0.0, 0.1, 0.5, 0.5,
2363 1.0, 1.0, 0.1, 0.5, 0.5,
2365 float quad4[] = {
2366 320, 480, 0.1, 1.0, 0.0, 1.0,
2367 320, 240, 0.1, 1.0, 0.0, 1.0,
2368 640, 480, 0.1, 1.0, 0.0, 1.0,
2369 640, 240, 0.1, 1.0, 0.0, 1.0,
2371 float mat[16] = {0.0, 0.0, 0.0, 0.0,
2372 0.0, 0.0, 0.0, 0.0,
2373 0.0, 0.0, 0.0, 0.0,
2374 0.0, 0.0, 0.0, 0.0};
2376 /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
2377 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
2378 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2379 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
2380 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2382 /* What happens with transforms enabled? */
2383 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
2384 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2385 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
2386 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2388 /* What happens if 4 coords are used, but only 2 given ?*/
2389 mat[8] = 1.0;
2390 mat[13] = 1.0;
2391 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
2392 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2393 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
2394 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2395 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
2396 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2398 /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
2399 * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
2400 * due to the coords in the vertices. (turns out red, indeed)
2402 memset(mat, 0, sizeof(mat));
2403 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
2404 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2405 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
2406 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
2407 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2408 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2409 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
2410 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2412 hr = IDirect3DDevice9_EndScene(device);
2413 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
2415 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2416 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2417 color = getPixelColor(device, 160, 360);
2418 ok(color == 0x00FFFF00 || color == 0x00FEFE00, "quad 1 has color %08x, expected 0x00FFFF00\n", color);
2419 color = getPixelColor(device, 160, 120);
2420 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
2421 color = getPixelColor(device, 480, 120);
2422 ok(color == 0x0000FF00 || color == 0x0000FE00, "quad 3 has color %08x, expected 0x0000FF00\n", color);
2423 color = getPixelColor(device, 480, 360);
2424 ok(color == 0x00FF0000 || 0x00FE0000, "quad 4 has color %08x, expected 0x00FF0000\n", color);
2426 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
2427 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
2429 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2430 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2431 hr = IDirect3DDevice9_BeginScene(device);
2432 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
2433 if(SUCCEEDED(hr))
2435 float quad1[] = {
2436 -1.0, -1.0, 0.1, 0.8, 0.2,
2437 -1.0, 0.0, 0.1, 0.8, 0.2,
2438 0.0, -1.0, 0.1, 0.8, 0.2,
2439 0.0, 0.0, 0.1, 0.8, 0.2,
2441 float quad2[] = {
2442 -1.0, 0.0, 0.1, 0.5, 1.0,
2443 -1.0, 1.0, 0.1, 0.5, 1.0,
2444 0.0, 0.0, 0.1, 0.5, 1.0,
2445 0.0, 1.0, 0.1, 0.5, 1.0,
2447 float quad3[] = {
2448 0.0, 0.0, 0.1, 0.5, 1.0,
2449 0.0, 1.0, 0.1, 0.5, 1.0,
2450 1.0, 0.0, 0.1, 0.5, 1.0,
2451 1.0, 1.0, 0.1, 0.5, 1.0,
2453 float quad4[] = {
2454 0.0, -1.0, 0.1, 0.8, 0.2,
2455 0.0, 0.0, 0.1, 0.8, 0.2,
2456 1.0, -1.0, 0.1, 0.8, 0.2,
2457 1.0, 0.0, 0.1, 0.8, 0.2,
2459 float mat[16] = {0.0, 0.0, 0.0, 0.0,
2460 0.0, 0.0, 0.0, 0.0,
2461 0.0, 1.0, 0.0, 0.0,
2462 0.0, 0.0, 0.0, 0.0};
2464 /* What happens to the default 1 in the 3rd coordinate if it is disabled?
2466 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
2467 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2468 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
2469 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2471 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
2472 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2474 /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
2475 * it behaves like COUNT2 because normal textures require 2 coords
2477 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
2478 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2479 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
2480 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2482 /* Just to be sure, the same as quad2 above */
2483 memset(mat, 0, sizeof(mat));
2484 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
2485 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2486 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
2487 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2488 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
2489 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2491 /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
2492 * used? And what happens to the first?
2494 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
2495 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2496 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
2497 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2499 hr = IDirect3DDevice9_EndScene(device);
2500 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
2502 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2503 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2504 color = getPixelColor(device, 160, 360);
2505 ok(color == 0x00FF0000 || color == 0x00FE0000, "quad 1 has color %08x, expected 0x00FF0000\n", color);
2506 color = getPixelColor(device, 160, 120);
2507 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
2508 color = getPixelColor(device, 480, 120);
2509 ok(color == 0x00ff8000 || color == 0x00fe7f00 || color == 0x00000000,
2510 "quad 3 has color %08x, expected 0x00ff8000\n", color);
2511 color = getPixelColor(device, 480, 360);
2512 ok(color == 0x0033cc00 || color == 0x0032cb00 || color == 0x00FF0000 || color == 0x00FE0000,
2513 "quad 4 has color %08x, expected 0x0033cc00\n", color);
2515 IDirect3DTexture9_Release(texture);
2517 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
2518 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
2519 /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
2520 * Thus watch out if sampling from texels between 0 and 1.
2522 hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
2523 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
2524 "IDirect3DDevice9_CreateVolumeTexture failed with %s\n", DXGetErrorString9(hr));
2525 if(!volume) {
2526 skip("Failed to create a volume texture\n");
2527 goto out;
2530 hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
2531 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %s\n", DXGetErrorString9(hr));
2532 for(z = 0; z < 32; z++) {
2533 for(y = 0; y < 32; y++) {
2534 for(x = 0; x < 32; x++) {
2535 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
2536 void *mem = ((char *) lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
2537 float r_f = (float) x / 31.0;
2538 float g_f = (float) y / 31.0;
2539 float b_f = (float) z / 31.0;
2541 if(fmt == D3DFMT_A16B16G16R16) {
2542 unsigned short *mem_s = mem;
2543 mem_s[0] = r_f * 65535.0;
2544 mem_s[1] = g_f * 65535.0;
2545 mem_s[2] = b_f * 65535.0;
2546 mem_s[3] = 65535;
2547 } else {
2548 unsigned char *mem_c = mem;
2549 mem_c[0] = b_f * 255.0;
2550 mem_c[1] = g_f * 255.0;
2551 mem_c[2] = r_f * 255.0;
2552 mem_c[3] = 255;
2557 hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
2558 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %s\n", DXGetErrorString9(hr));
2560 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
2561 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %s\n", DXGetErrorString9(hr));
2563 hr = IDirect3DDevice9_BeginScene(device);
2564 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
2565 if(SUCCEEDED(hr))
2567 float quad1[] = {
2568 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
2569 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
2570 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
2571 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
2573 float quad2[] = {
2574 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
2575 -1.0, 1.0, 0.1, 1.0, 1.0, 1.0,
2576 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
2577 0.0, 1.0, 0.1, 1.0, 1.0, 1.0
2579 float quad3[] = {
2580 0.0, 0.0, 0.1, 0.0, 0.0,
2581 0.0, 1.0, 0.1, 0.0, 0.0,
2582 1.0, 0.0, 0.1, 0.0, 0.0,
2583 1.0, 1.0, 0.1, 0.0, 0.0
2585 float quad4[] = {
2586 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
2587 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
2588 1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
2589 1.0, 0.0, 0.1, 1.0, 1.0, 1.0
2591 float mat[16] = {1.0, 0.0, 0.0, 0.0,
2592 0.0, 0.0, 1.0, 0.0,
2593 0.0, 1.0, 0.0, 0.0,
2594 0.0, 0.0, 0.0, 1.0};
2595 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
2596 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
2598 /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
2599 * values
2601 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
2602 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2603 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
2604 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2605 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
2606 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2608 /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
2609 * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
2610 * otherwise the w will be missing(blue).
2611 * turns out that on nvidia cards the blue color is missing, so it is an output modification.
2612 * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
2614 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
2615 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2616 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
2617 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2619 /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 4 */
2620 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
2621 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2622 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
2623 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2624 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2625 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2626 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
2627 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2629 /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
2630 * disable. ATI extends it up to the amount of values needed for the volume texture
2632 memset(mat, 0, sizeof(mat));
2633 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
2634 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2635 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
2636 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2637 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
2638 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
2639 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
2640 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2642 hr = IDirect3DDevice9_EndScene(device);
2643 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
2645 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2646 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2648 color = getPixelColor(device, 160, 360);
2649 ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
2650 color = getPixelColor(device, 160, 120);
2651 ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
2652 "quad 2 has color %08x, expected 0x00ffff00\n", color);
2653 color = getPixelColor(device, 480, 120);
2654 ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
2655 color = getPixelColor(device, 480, 360);
2656 ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
2658 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
2659 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
2660 hr = IDirect3DDevice9_BeginScene(device);
2661 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
2662 if(SUCCEEDED(hr))
2664 float quad1[] = {
2665 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
2666 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
2667 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
2668 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
2670 float quad2[] = {
2671 -1.0, 0.0, 0.1,
2672 -1.0, 1.0, 0.1,
2673 0.0, 0.0, 0.1,
2674 0.0, 1.0, 0.1,
2676 float quad3[] = {
2677 0.0, 0.0, 0.1, 1.0,
2678 0.0, 1.0, 0.1, 1.0,
2679 1.0, 0.0, 0.1, 1.0,
2680 1.0, 1.0, 0.1, 1.0
2682 float mat[16] = {0.0, 0.0, 0.0, 0.0,
2683 0.0, 0.0, 0.0, 0.0,
2684 0.0, 0.0, 0.0, 0.0,
2685 0.0, 1.0, 0.0, 0.0};
2686 float mat2[16] = {0.0, 0.0, 0.0, 1.0,
2687 1.0, 0.0, 0.0, 0.0,
2688 0.0, 1.0, 0.0, 0.0,
2689 0.0, 0.0, 1.0, 0.0};
2690 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
2691 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
2693 /* Default values? 4 coords used, 3 passed. What happens to the 4th?
2695 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
2696 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2697 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
2698 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2699 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
2700 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2702 /* None passed */
2703 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
2704 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2705 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
2706 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2707 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
2708 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2710 /* 4 used, 1 passed */
2711 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
2712 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
2713 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
2714 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2715 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
2716 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2718 hr = IDirect3DDevice9_EndScene(device);
2719 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
2721 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2722 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2723 color = getPixelColor(device, 160, 360);
2724 ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
2725 color = getPixelColor(device, 160, 120);
2726 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
2727 color = getPixelColor(device, 480, 120);
2728 ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
2729 /* Quad4: unused */
2731 IDirect3DVolumeTexture9_Release(volume);
2733 out:
2734 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2735 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
2736 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
2737 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2738 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
2739 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2740 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2741 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
2742 IDirect3DVertexDeclaration9_Release(decl);
2743 IDirect3DVertexDeclaration9_Release(decl2);
2746 static void texdepth_test(IDirect3DDevice9 *device)
2748 IDirect3DPixelShader9 *shader;
2749 HRESULT hr;
2750 const float texdepth_test_data1[] = { 0.25, 2.0, 0.0, 0.0};
2751 const float texdepth_test_data2[] = { 0.25, 0.5, 0.0, 0.0};
2752 const float texdepth_test_data3[] = {-1.00, 0.1, 0.0, 0.0};
2753 const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
2754 const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
2755 const float texdepth_test_data6[] = { 1.00, 0.5, 0.0, 0.0};
2756 const float texdepth_test_data7[] = { 0.50, 0.0, 0.0, 0.0};
2757 DWORD shader_code[] = {
2758 0xffff0104, /* ps_1_4 */
2759 0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c1, 0, 0, 1, 1 */
2760 0x00000001, 0x800f0005, 0xa0e40000, /* mov r5, c0 */
2761 0x0000fffd, /* phase */
2762 0x00000057, 0x800f0005, /* texdepth r5 */
2763 0x00000001, 0x800f0000, 0xa0e40001, /* mov r0, c1 */
2764 0x0000ffff /* end */
2766 DWORD color;
2767 float vertex[] = {
2768 -1.0, -1.0, 0.0,
2769 1.0, -1.0, 1.0,
2770 -1.0, 1.0, 0.0,
2771 1.0, 1.0, 1.0
2774 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
2775 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
2777 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
2778 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
2779 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2780 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
2781 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2782 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
2783 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
2784 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
2785 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
2787 /* Fill the depth buffer with a gradient */
2788 hr = IDirect3DDevice9_BeginScene(device);
2789 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
2790 if(SUCCEEDED(hr))
2792 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
2793 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2794 hr = IDirect3DDevice9_EndScene(device);
2795 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
2798 /* Now perform the actual tests. Same geometry, but with the shader */
2799 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2800 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
2801 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2802 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
2803 hr = IDirect3DDevice9_SetPixelShader(device, shader);
2804 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
2806 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
2807 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
2808 hr = IDirect3DDevice9_BeginScene(device);
2809 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
2810 if(SUCCEEDED(hr))
2812 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
2813 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2815 hr = IDirect3DDevice9_EndScene(device);
2816 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
2819 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2820 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2821 color = getPixelColor(device, 158, 240);
2822 ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
2823 color = getPixelColor(device, 162, 240);
2824 ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
2826 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
2828 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
2829 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
2830 hr = IDirect3DDevice9_BeginScene(device);
2831 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
2832 if(SUCCEEDED(hr))
2834 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
2835 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2837 hr = IDirect3DDevice9_EndScene(device);
2838 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
2841 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2842 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2843 color = getPixelColor(device, 318, 240);
2844 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
2845 color = getPixelColor(device, 322, 240);
2846 ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
2848 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
2850 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
2851 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
2852 hr = IDirect3DDevice9_BeginScene(device);
2853 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
2854 if(SUCCEEDED(hr))
2856 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
2857 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2859 hr = IDirect3DDevice9_EndScene(device);
2860 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
2862 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2863 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2865 color = getPixelColor(device, 1, 240);
2866 ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
2868 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
2870 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
2871 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
2872 hr = IDirect3DDevice9_BeginScene(device);
2873 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
2874 if(SUCCEEDED(hr))
2876 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
2877 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2879 hr = IDirect3DDevice9_EndScene(device);
2880 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
2882 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2883 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2884 color = getPixelColor(device, 318, 240);
2885 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
2886 color = getPixelColor(device, 322, 240);
2887 ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
2889 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
2891 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
2892 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
2893 hr = IDirect3DDevice9_BeginScene(device);
2894 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
2895 if(SUCCEEDED(hr))
2897 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
2898 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2900 hr = IDirect3DDevice9_EndScene(device);
2901 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
2903 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2904 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2906 color = getPixelColor(device, 1, 240);
2907 ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
2909 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
2911 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
2912 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
2913 hr = IDirect3DDevice9_BeginScene(device);
2914 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
2915 if(SUCCEEDED(hr))
2917 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
2918 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2920 hr = IDirect3DDevice9_EndScene(device);
2921 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
2923 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2924 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2926 color = getPixelColor(device, 638, 240);
2927 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
2929 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
2931 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
2932 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
2933 hr = IDirect3DDevice9_BeginScene(device);
2934 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
2935 if(SUCCEEDED(hr))
2937 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
2938 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2940 hr = IDirect3DDevice9_EndScene(device);
2941 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
2943 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2944 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2946 color = getPixelColor(device, 638, 240);
2947 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
2949 /* Cleanup */
2950 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2951 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
2952 IDirect3DPixelShader9_Release(shader);
2954 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2955 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
2956 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2957 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
2960 static void texkill_test(IDirect3DDevice9 *device)
2962 IDirect3DPixelShader9 *shader;
2963 HRESULT hr;
2964 DWORD color;
2966 const float vertex[] = {
2967 /* bottom top right left */
2968 -1.0, -1.0, 1.0, -0.1, 0.9, 0.9, -0.1,
2969 1.0, -1.0, 0.0, 0.9, -0.1, 0.9, -0.1,
2970 -1.0, 1.0, 1.0, -0.1, 0.9, -0.1, 0.9,
2971 1.0, 1.0, 0.0, 0.9, -0.1, -0.1, 0.9,
2974 DWORD shader_code_11[] = {
2975 0xffff0101, /* ps_1_1 */
2976 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
2977 0x00000041, 0xb00f0000, /* texkill t0 */
2978 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
2979 0x0000ffff /* end */
2981 DWORD shader_code_20[] = {
2982 0xffff0200, /* ps_2_0 */
2983 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
2984 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
2985 0x01000041, 0xb00f0000, /* texkill t0 */
2986 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
2987 0x0000ffff /* end */
2990 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
2991 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
2992 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
2993 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
2995 hr = IDirect3DDevice9_SetPixelShader(device, shader);
2996 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
2997 hr = IDirect3DDevice9_BeginScene(device);
2998 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
2999 if(SUCCEEDED(hr))
3001 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
3002 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
3003 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
3004 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3005 hr = IDirect3DDevice9_EndScene(device);
3006 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3008 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3009 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3010 color = getPixelColor(device, 63, 46);
3011 ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
3012 color = getPixelColor(device, 66, 46);
3013 ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
3014 color = getPixelColor(device, 63, 49);
3015 ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
3016 color = getPixelColor(device, 66, 49);
3017 ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
3019 color = getPixelColor(device, 578, 46);
3020 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3021 color = getPixelColor(device, 575, 46);
3022 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3023 color = getPixelColor(device, 578, 49);
3024 ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
3025 color = getPixelColor(device, 575, 49);
3026 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3028 color = getPixelColor(device, 63, 430);
3029 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3030 color = getPixelColor(device, 63, 433);
3031 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3032 color = getPixelColor(device, 66, 433);
3033 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
3034 color = getPixelColor(device, 66, 430);
3035 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3037 color = getPixelColor(device, 578, 430);
3038 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3039 color = getPixelColor(device, 578, 433);
3040 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3041 color = getPixelColor(device, 575, 433);
3042 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
3043 color = getPixelColor(device, 575, 430);
3044 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3046 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3047 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3048 IDirect3DPixelShader9_Release(shader);
3050 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3051 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3052 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
3053 if(FAILED(hr)) {
3054 skip("Failed to create 2.0 test shader, most likely not supported\n");
3055 return;
3058 hr = IDirect3DDevice9_SetPixelShader(device, shader);
3059 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3060 hr = IDirect3DDevice9_BeginScene(device);
3061 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3062 if(SUCCEEDED(hr))
3064 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
3065 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3066 hr = IDirect3DDevice9_EndScene(device);
3067 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3069 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3071 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3072 color = getPixelColor(device, 63, 46);
3073 ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
3074 color = getPixelColor(device, 66, 46);
3075 ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
3076 color = getPixelColor(device, 63, 49);
3077 ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
3078 color = getPixelColor(device, 66, 49);
3079 ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
3081 color = getPixelColor(device, 578, 46);
3082 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
3083 color = getPixelColor(device, 575, 46);
3084 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
3085 color = getPixelColor(device, 578, 49);
3086 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
3087 color = getPixelColor(device, 575, 49);
3088 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
3090 color = getPixelColor(device, 63, 430);
3091 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
3092 color = getPixelColor(device, 63, 433);
3093 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
3094 color = getPixelColor(device, 66, 433);
3095 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
3096 color = getPixelColor(device, 66, 430);
3097 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
3099 color = getPixelColor(device, 578, 430);
3100 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
3101 color = getPixelColor(device, 578, 433);
3102 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
3103 color = getPixelColor(device, 575, 433);
3104 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
3105 color = getPixelColor(device, 575, 430);
3106 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
3108 /* Cleanup */
3109 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3110 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
3111 IDirect3DPixelShader9_Release(shader);
3114 static void x8l8v8u8_test(IDirect3DDevice9 *device)
3116 IDirect3D9 *d3d9;
3117 HRESULT hr;
3118 IDirect3DTexture9 *texture;
3119 IDirect3DPixelShader9 *shader;
3120 IDirect3DPixelShader9 *shader2;
3121 D3DLOCKED_RECT lr;
3122 DWORD color;
3123 DWORD shader_code[] = {
3124 0xffff0101, /* ps_1_1 */
3125 0x00000042, 0xb00f0000, /* tex t0 */
3126 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
3127 0x0000ffff /* end */
3129 DWORD shader_code2[] = {
3130 0xffff0101, /* ps_1_1 */
3131 0x00000042, 0xb00f0000, /* tex t0 */
3132 0x00000001, 0x800f0000, 0xb0ff0000, /* mov r0, t0.w */
3133 0x0000ffff /* end */
3136 float quad[] = {
3137 -1.0, -1.0, 0.1, 0.5, 0.5,
3138 1.0, -1.0, 0.1, 0.5, 0.5,
3139 -1.0, 1.0, 0.1, 0.5, 0.5,
3140 1.0, 1.0, 0.1, 0.5, 0.5,
3143 memset(&lr, 0, sizeof(lr));
3144 IDirect3DDevice9_GetDirect3D(device, &d3d9);
3145 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
3146 0, D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
3147 IDirect3D9_Release(d3d9);
3148 if(FAILED(hr)) {
3149 skip("No D3DFMT_X8L8V8U8 support\n");
3152 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3153 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3155 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
3156 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
3157 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3158 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
3159 *((DWORD *) lr.pBits) = 0x11ca3141;
3160 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3161 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
3163 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
3164 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
3165 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
3166 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
3168 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3169 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
3170 hr = IDirect3DDevice9_SetPixelShader(device, shader);
3171 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3172 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3173 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
3175 hr = IDirect3DDevice9_BeginScene(device);
3176 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
3177 if(SUCCEEDED(hr))
3179 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3180 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3182 hr = IDirect3DDevice9_EndScene(device);
3183 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
3185 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3186 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3187 color = getPixelColor(device, 578, 430);
3188 ok(color == 0x008262ca || color == 0x008363ca || color == 0x008362ca,
3189 "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
3191 hr = IDirect3DDevice9_SetPixelShader(device, shader2);
3192 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3193 hr = IDirect3DDevice9_BeginScene(device);
3194 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
3195 if(SUCCEEDED(hr))
3197 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3198 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3200 hr = IDirect3DDevice9_EndScene(device);
3201 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
3203 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3204 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3205 color = getPixelColor(device, 578, 430);
3206 ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
3208 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3209 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3210 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3211 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
3212 IDirect3DPixelShader9_Release(shader);
3213 IDirect3DPixelShader9_Release(shader2);
3214 IDirect3DTexture9_Release(texture);
3217 static void autogen_mipmap_test(IDirect3DDevice9 *device)
3219 HRESULT hr;
3220 IDirect3D9 *d3d;
3221 IDirect3DTexture9 *texture = NULL;
3222 IDirect3DSurface9 *surface;
3223 DWORD color;
3224 const RECT r1 = {256, 256, 512, 512};
3225 const RECT r2 = {512, 256, 768, 512};
3226 const RECT r3 = {256, 512, 512, 768};
3227 const RECT r4 = {512, 512, 768, 768};
3228 unsigned int x, y;
3229 D3DLOCKED_RECT lr;
3230 memset(&lr, 0, sizeof(lr));
3232 IDirect3DDevice9_GetDirect3D(device, &d3d);
3233 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
3234 D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
3235 skip("No autogenmipmap support\n");
3236 IDirect3D9_Release(d3d);
3237 return;
3239 IDirect3D9_Release(d3d);
3241 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3242 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3244 /* Make the mipmap big, so that a smaller mipmap is used
3246 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
3247 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
3248 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %s\n", DXGetErrorString9(hr));
3250 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
3251 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %s\n", DXGetErrorString9(hr));
3252 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
3253 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %s\n", DXGetErrorString9(hr));
3254 for(y = 0; y < 1024; y++) {
3255 for(x = 0; x < 1024; x++) {
3256 DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
3257 POINT pt;
3259 pt.x = x;
3260 pt.y = y;
3261 if(PtInRect(&r1, pt)) {
3262 *dst = 0xffff0000;
3263 } else if(PtInRect(&r2, pt)) {
3264 *dst = 0xff00ff00;
3265 } else if(PtInRect(&r3, pt)) {
3266 *dst = 0xff0000ff;
3267 } else if(PtInRect(&r4, pt)) {
3268 *dst = 0xff000000;
3269 } else {
3270 *dst = 0xffffffff;
3274 hr = IDirect3DSurface9_UnlockRect(surface);
3275 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %s\n", DXGetErrorString9(hr));
3276 IDirect3DSurface9_Release(surface);
3278 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3279 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
3280 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
3281 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
3283 hr = IDirect3DDevice9_BeginScene(device);
3284 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3285 if(SUCCEEDED(hr)) {
3286 const float quad[] = {
3287 -0.5, -0.5, 0.1, 0.0, 0.0,
3288 -0.5, 0.5, 0.1, 0.0, 1.0,
3289 0.5, -0.5, 0.1, 1.0, 0.0,
3290 0.5, 0.5, 0.1, 1.0, 1.0
3293 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3294 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
3295 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3296 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3297 hr = IDirect3DDevice9_EndScene(device);
3298 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3300 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3301 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
3302 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3303 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
3304 IDirect3DTexture9_Release(texture);
3306 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3307 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3308 color = getPixelColor(device, 200, 200);
3309 ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
3310 color = getPixelColor(device, 280, 200);
3311 ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
3312 color = getPixelColor(device, 360, 200);
3313 ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
3314 color = getPixelColor(device, 440, 200);
3315 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
3316 color = getPixelColor(device, 200, 270);
3317 ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
3318 color = getPixelColor(device, 280, 270);
3319 ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
3320 color = getPixelColor(device, 360, 270);
3321 ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
3322 color = getPixelColor(device, 440, 270);
3323 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
3326 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
3328 IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
3329 IDirect3DVertexDeclaration9 *decl;
3330 HRESULT hr;
3331 DWORD color;
3332 DWORD shader_code_11[] = {
3333 0xfffe0101, /* vs_1_1 */
3334 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
3335 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
3336 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
3337 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
3338 0x0000ffff /* end */
3340 DWORD shader_code_11_2[] = {
3341 0xfffe0101, /* vs_1_1 */
3342 0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
3343 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
3344 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
3345 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
3346 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
3347 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
3348 0x0000ffff /* end */
3350 DWORD shader_code_20[] = {
3351 0xfffe0200, /* vs_2_0 */
3352 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
3353 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
3354 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
3355 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
3356 0x0000ffff /* end */
3358 DWORD shader_code_20_2[] = {
3359 0xfffe0200, /* vs_2_0 */
3360 0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
3361 0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
3362 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
3363 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
3364 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
3365 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
3366 0x0000ffff /* end */
3368 static const D3DVERTEXELEMENT9 decl_elements[] = {
3369 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3370 D3DDECL_END()
3372 float quad1[] = {
3373 -1.0, -1.0, 0.1,
3374 0.0, -1.0, 0.1,
3375 -1.0, 0.0, 0.1,
3376 0.0, 0.0, 0.1
3378 float quad2[] = {
3379 0.0, -1.0, 0.1,
3380 1.0, -1.0, 0.1,
3381 0.0, 0.0, 0.1,
3382 1.0, 0.0, 0.1
3384 float quad3[] = {
3385 0.0, 0.0, 0.1,
3386 1.0, 0.0, 0.1,
3387 0.0, 1.0, 0.1,
3388 1.0, 1.0, 0.1
3390 float quad4[] = {
3391 -1.0, 0.0, 0.1,
3392 0.0, 0.0, 0.1,
3393 -1.0, 1.0, 0.1,
3394 0.0, 1.0, 0.1
3396 float test_data_c1[4] = { 1.25, -0.50, -1.50, 1.0};
3397 float test_data_c2[4] = { -0.50, 1.25, 2.00, 1.0};
3399 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
3400 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3402 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
3403 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
3404 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
3405 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
3406 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
3407 if(FAILED(hr)) shader_20 = NULL;
3408 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
3409 if(FAILED(hr)) shader_20_2 = NULL;
3410 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
3411 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
3413 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
3414 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %s\n", DXGetErrorString9(hr));
3415 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
3416 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %s\n", DXGetErrorString9(hr));
3417 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3418 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
3420 hr = IDirect3DDevice9_BeginScene(device);
3421 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3422 if(SUCCEEDED(hr))
3424 hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
3425 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
3426 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
3427 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3429 hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
3430 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
3431 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
3432 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3434 if(shader_20) {
3435 hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
3436 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
3437 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
3438 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3441 if(shader_20_2) {
3442 hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
3443 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
3444 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
3445 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3448 hr = IDirect3DDevice9_EndScene(device);
3449 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3451 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3452 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3454 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
3455 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
3456 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
3457 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
3459 color = getPixelColor(device, 160, 360);
3460 ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
3461 "quad 1 has color %08x, expected 0x00bfbf80\n", color);
3462 color = getPixelColor(device, 480, 360);
3463 ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
3464 "quad 2 has color %08x, expected 0x00bfbf80\n", color);
3465 if(shader_20) {
3466 color = getPixelColor(device, 160, 120);
3467 ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
3468 "quad 3 has color %08x, expected 0x00bfbf80\n", color);
3470 if(shader_20_2) {
3471 color = getPixelColor(device, 480, 120);
3472 ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
3473 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
3476 IDirect3DVertexDeclaration9_Release(decl);
3477 if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
3478 if(shader_20) IDirect3DVertexShader9_Release(shader_20);
3479 IDirect3DVertexShader9_Release(shader_11_2);
3480 IDirect3DVertexShader9_Release(shader_11);
3483 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
3485 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
3486 HRESULT hr;
3487 DWORD color;
3488 DWORD shader_code_11[] = {
3489 0xffff0101, /* ps_1_1 */
3490 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
3491 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
3492 0x0000ffff /* end */
3494 DWORD shader_code_12[] = {
3495 0xffff0102, /* ps_1_2 */
3496 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
3497 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
3498 0x0000ffff /* end */
3500 /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
3501 * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
3502 * During development of this test, 1.3 shaders were verified too
3504 DWORD shader_code_14[] = {
3505 0xffff0104, /* ps_1_4 */
3506 /* Try to make one constant local. It gets clamped too, although the binary contains
3507 * the bigger numbers
3509 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
3510 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
3511 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
3512 0x0000ffff /* end */
3514 DWORD shader_code_20[] = {
3515 0xffff0200, /* ps_2_0 */
3516 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
3517 0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
3518 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
3519 0x0000ffff /* end */
3521 float quad1[] = {
3522 -1.0, -1.0, 0.1,
3523 0.0, -1.0, 0.1,
3524 -1.0, 0.0, 0.1,
3525 0.0, 0.0, 0.1
3527 float quad2[] = {
3528 0.0, -1.0, 0.1,
3529 1.0, -1.0, 0.1,
3530 0.0, 0.0, 0.1,
3531 1.0, 0.0, 0.1
3533 float quad3[] = {
3534 0.0, 0.0, 0.1,
3535 1.0, 0.0, 0.1,
3536 0.0, 1.0, 0.1,
3537 1.0, 1.0, 0.1
3539 float quad4[] = {
3540 -1.0, 0.0, 0.1,
3541 0.0, 0.0, 0.1,
3542 -1.0, 1.0, 0.1,
3543 0.0, 1.0, 0.1
3545 float test_data_c1[4] = { 1.25, -0.50, -1.50, 1.0};
3546 float test_data_c2[4] = { -0.50, 1.25, 2.00, 1.0};
3548 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
3549 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3551 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
3552 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3553 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
3554 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3555 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
3556 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3557 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
3558 if(FAILED(hr)) shader_20 = NULL;
3560 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
3561 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3562 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
3563 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3564 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3565 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
3567 hr = IDirect3DDevice9_BeginScene(device);
3568 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3569 if(SUCCEEDED(hr))
3571 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
3572 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3573 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
3574 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3576 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
3577 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3578 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
3579 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3581 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
3582 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3583 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
3584 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3586 if(shader_20) {
3587 hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
3588 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3589 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
3590 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3593 hr = IDirect3DDevice9_EndScene(device);
3594 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3596 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3597 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3599 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3600 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
3602 color = getPixelColor(device, 160, 360);
3603 ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
3604 "quad 1 has color %08x, expected 0x00808000\n", color);
3605 color = getPixelColor(device, 480, 360);
3606 ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
3607 "quad 2 has color %08x, expected 0x00808000\n", color);
3608 color = getPixelColor(device, 480, 120);
3609 ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
3610 "quad 3 has color %08x, expected 0x00808000\n", color);
3611 if(shader_20) {
3612 color = getPixelColor(device, 160, 120);
3613 ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
3614 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
3617 if(shader_20) IDirect3DPixelShader9_Release(shader_20);
3618 IDirect3DPixelShader9_Release(shader_14);
3619 IDirect3DPixelShader9_Release(shader_12);
3620 IDirect3DPixelShader9_Release(shader_11);
3623 static void cnd_test(IDirect3DDevice9 *device)
3625 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
3626 IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
3627 HRESULT hr;
3628 DWORD color;
3629 /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
3630 * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
3631 * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
3633 DWORD shader_code_11[] = {
3634 0xffff0101, /* ps_1_1 */
3635 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
3636 0x00000040, 0xb00f0000, /* texcoord t0 */
3637 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, ???(t0) */
3638 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
3639 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
3640 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
3641 0x0000ffff /* end */
3643 DWORD shader_code_12[] = {
3644 0xffff0102, /* ps_1_2 */
3645 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
3646 0x00000040, 0xb00f0000, /* texcoord t0 */
3647 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
3648 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
3649 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
3650 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
3651 0x0000ffff /* end */
3653 DWORD shader_code_13[] = {
3654 0xffff0103, /* ps_1_3 */
3655 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
3656 0x00000040, 0xb00f0000, /* texcoord t0 */
3657 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
3658 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3, r1, r0, c0 */
3659 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
3660 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
3661 0x0000ffff /* end */
3663 DWORD shader_code_14[] = {
3664 0xffff0104, /* ps_1_3 */
3665 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
3666 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
3667 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
3668 0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0, c1, c2 */
3669 0x0000ffff /* end */
3672 /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
3673 * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
3674 * set by the compiler, it was added manually after compilation. It isn't always allowed,
3675 * only if there's a mov r0.a, XXXX, and the cnd instruction writes to r0.xyz, otherwise
3676 * native CreatePixelShader returns an error.
3678 * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
3679 * The input from t0 is [0;1]. 0.5 is substracted, then we have to multiply with 2. Since
3680 * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
3681 * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
3683 DWORD shader_code_11_coissue[] = {
3684 0xffff0101, /* ps_1_1 */
3685 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
3686 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
3687 0x00000040, 0xb00f0000, /* texcoord t0 */
3688 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
3689 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
3690 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
3691 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
3692 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
3693 /* 0x40000000 = D3DSI_COISSUE */
3694 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
3695 0x0000ffff /* end */
3697 DWORD shader_code_12_coissue[] = {
3698 0xffff0102, /* ps_1_2 */
3699 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
3700 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
3701 0x00000040, 0xb00f0000, /* texcoord t0 */
3702 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
3703 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
3704 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
3705 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
3706 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
3707 /* 0x40000000 = D3DSI_COISSUE */
3708 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
3709 0x0000ffff /* end */
3711 DWORD shader_code_13_coissue[] = {
3712 0xffff0103, /* ps_1_3 */
3713 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
3714 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
3715 0x00000040, 0xb00f0000, /* texcoord t0 */
3716 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
3717 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
3718 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
3719 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
3720 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
3721 /* 0x40000000 = D3DSI_COISSUE */
3722 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
3723 0x0000ffff /* end */
3725 /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
3726 * compare against 0.5
3728 DWORD shader_code_14_coissue[] = {
3729 0xffff0104, /* ps_1_4 */
3730 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
3731 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
3732 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
3733 /* 0x40000000 = D3DSI_COISSUE */
3734 0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0, c1, c2 */
3735 0x0000ffff /* end */
3737 float quad1[] = {
3738 -1.0, -1.0, 0.1, 0.0, 0.0, 1.0,
3739 0.0, -1.0, 0.1, 1.0, 0.0, 1.0,
3740 -1.0, 0.0, 0.1, 0.0, 1.0, 0.0,
3741 0.0, 0.0, 0.1, 1.0, 1.0, 0.0
3743 float quad2[] = {
3744 0.0, -1.0, 0.1, 0.0, 0.0, 1.0,
3745 1.0, -1.0, 0.1, 1.0, 0.0, 1.0,
3746 0.0, 0.0, 0.1, 0.0, 1.0, 0.0,
3747 1.0, 0.0, 0.1, 1.0, 1.0, 0.0
3749 float quad3[] = {
3750 0.0, 0.0, 0.1, 0.0, 0.0, 1.0,
3751 1.0, 0.0, 0.1, 1.0, 0.0, 1.0,
3752 0.0, 1.0, 0.1, 0.0, 1.0, 0.0,
3753 1.0, 1.0, 0.1, 1.0, 1.0, 0.0
3755 float quad4[] = {
3756 -1.0, 0.0, 0.1, 0.0, 0.0, 1.0,
3757 0.0, 0.0, 0.1, 1.0, 0.0, 1.0,
3758 -1.0, 1.0, 0.1, 0.0, 1.0, 0.0,
3759 0.0, 1.0, 0.1, 1.0, 1.0, 0.0
3761 float test_data_c1[4] = { 0.0, 0.0, 0.0, 0.0};
3762 float test_data_c2[4] = { 1.0, 1.0, 1.0, 1.0};
3763 float test_data_c1_coi[4] = { 0.0, 1.0, 0.0, 0.0};
3764 float test_data_c2_coi[4] = { 1.0, 0.0, 1.0, 1.0};
3766 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
3767 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3769 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
3770 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3771 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
3772 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3773 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
3774 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3775 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
3776 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3777 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
3778 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3779 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
3780 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3781 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
3782 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3783 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
3784 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3786 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
3787 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3788 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
3789 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3790 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3791 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
3793 hr = IDirect3DDevice9_BeginScene(device);
3794 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3795 if(SUCCEEDED(hr))
3797 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
3798 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3799 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3800 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3802 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
3803 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3804 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
3805 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3807 hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
3808 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3809 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
3810 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3812 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
3813 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3814 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3815 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3817 hr = IDirect3DDevice9_EndScene(device);
3818 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3820 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3821 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3823 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3824 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
3826 /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
3827 color = getPixelColor(device, 158, 118);
3828 ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
3829 color = getPixelColor(device, 162, 118);
3830 ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
3831 color = getPixelColor(device, 158, 122);
3832 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
3833 color = getPixelColor(device, 162, 122);
3834 ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
3836 /* 1.1 shader. All 3 components get set, based on the .w comparison */
3837 color = getPixelColor(device, 158, 358);
3838 ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
3839 color = getPixelColor(device, 162, 358);
3840 ok(color == 0x00000000, "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
3841 color = getPixelColor(device, 158, 362);
3842 ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
3843 color = getPixelColor(device, 162, 362);
3844 ok(color == 0x00000000, "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
3846 /* 1.2 shader */
3847 color = getPixelColor(device, 478, 358);
3848 ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
3849 color = getPixelColor(device, 482, 358);
3850 ok(color == 0x00000000, "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
3851 color = getPixelColor(device, 478, 362);
3852 ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
3853 color = getPixelColor(device, 482, 362);
3854 ok(color == 0x00000000, "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
3856 /* 1.3 shader */
3857 color = getPixelColor(device, 478, 118);
3858 ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
3859 color = getPixelColor(device, 482, 118);
3860 ok(color == 0x00000000, "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
3861 color = getPixelColor(device, 478, 122);
3862 ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
3863 color = getPixelColor(device, 482, 122);
3864 ok(color == 0x00000000, "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
3866 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
3867 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3868 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
3869 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3870 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
3871 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3873 hr = IDirect3DDevice9_BeginScene(device);
3874 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3875 if(SUCCEEDED(hr))
3877 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
3878 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3879 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3880 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3882 hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
3883 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3884 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
3885 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3887 hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
3888 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3889 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
3890 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3892 hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
3893 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3894 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3895 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3897 hr = IDirect3DDevice9_EndScene(device);
3898 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3900 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3901 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3903 /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
3904 * that we swapped the values in c1 and c2 to make the other tests return some color
3906 color = getPixelColor(device, 158, 118);
3907 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
3908 color = getPixelColor(device, 162, 118);
3909 ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
3910 color = getPixelColor(device, 158, 122);
3911 ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
3912 color = getPixelColor(device, 162, 122);
3913 ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
3915 /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected */
3916 color = getPixelColor(device, 158, 358);
3917 ok(color == 0x0000ff00, "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
3918 color = getPixelColor(device, 162, 358);
3919 ok(color == 0x0000ff00, "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
3920 color = getPixelColor(device, 158, 362);
3921 ok(color == 0x0000ff00, "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
3922 color = getPixelColor(device, 162, 362);
3923 ok(color == 0x0000ff00, "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
3925 /* 1.2 shader */
3926 color = getPixelColor(device, 478, 358);
3927 ok(color == 0x0000ff00, "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
3928 color = getPixelColor(device, 482, 358);
3929 ok(color == 0x0000ff00, "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
3930 color = getPixelColor(device, 478, 362);
3931 ok(color == 0x0000ff00, "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
3932 color = getPixelColor(device, 482, 362);
3933 ok(color == 0x0000ff00, "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
3935 /* 1.3 shader */
3936 color = getPixelColor(device, 478, 118);
3937 ok(color == 0x0000ff00, "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
3938 color = getPixelColor(device, 482, 118);
3939 ok(color == 0x0000ff00, "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
3940 color = getPixelColor(device, 478, 122);
3941 ok(color == 0x0000ff00, "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
3942 color = getPixelColor(device, 482, 122);
3943 ok(color == 0x0000ff00, "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
3945 IDirect3DPixelShader9_Release(shader_14_coissue);
3946 IDirect3DPixelShader9_Release(shader_13_coissue);
3947 IDirect3DPixelShader9_Release(shader_12_coissue);
3948 IDirect3DPixelShader9_Release(shader_11_coissue);
3949 IDirect3DPixelShader9_Release(shader_14);
3950 IDirect3DPixelShader9_Release(shader_13);
3951 IDirect3DPixelShader9_Release(shader_12);
3952 IDirect3DPixelShader9_Release(shader_11);
3955 static void nested_loop_test(IDirect3DDevice9 *device) {
3956 const DWORD shader_code[] = {
3957 0xffff0300, /* ps_3_0 */
3958 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
3959 0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
3960 0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0 */
3961 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
3962 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
3963 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
3964 0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001, /* add r0, r0, c1 */
3965 0x0000001d, /* endloop */
3966 0x0000001d, /* endloop */
3967 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
3968 0x0000ffff /* end */
3970 IDirect3DPixelShader9 *shader;
3971 HRESULT hr;
3972 DWORD color;
3973 const float quad[] = {
3974 -1.0, -1.0, 0.1,
3975 1.0, -1.0, 0.1,
3976 -1.0, 1.0, 0.1,
3977 1.0, 1.0, 0.1
3980 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
3981 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %s\n", DXGetErrorString9(hr));
3982 hr = IDirect3DDevice9_SetPixelShader(device, shader);
3983 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %s\n", DXGetErrorString9(hr));
3984 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3985 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
3986 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
3987 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3989 hr = IDirect3DDevice9_BeginScene(device);
3990 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3991 if(SUCCEEDED(hr))
3993 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
3994 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3995 hr = IDirect3DDevice9_EndScene(device);
3996 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3998 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3999 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4001 color = getPixelColor(device, 360, 240);
4002 ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
4003 "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
4005 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4006 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %s\n", DXGetErrorString9(hr));
4007 IDirect3DPixelShader9_Release(shader);
4010 struct varying_test_struct
4012 const DWORD *shader_code;
4013 IDirect3DPixelShader9 *shader;
4014 DWORD color, color_rhw;
4015 const char *name;
4016 BOOL todo, todo_rhw;
4019 struct hugeVertex
4021 float pos_x, pos_y, pos_z, rhw;
4022 float weight_1, weight_2, weight_3, weight_4;
4023 float index_1, index_2, index_3, index_4;
4024 float normal_1, normal_2, normal_3, normal_4;
4025 float fog_1, fog_2, fog_3, fog_4;
4026 float texcoord_1, texcoord_2, texcoord_3, texcoord_4;
4027 float tangent_1, tangent_2, tangent_3, tangent_4;
4028 float binormal_1, binormal_2, binormal_3, binormal_4;
4029 float depth_1, depth_2, depth_3, depth_4;
4030 DWORD diffuse, specular;
4033 static void fixed_function_varying_test(IDirect3DDevice9 *device) {
4034 /* dcl_position: fails to compile */
4035 const DWORD blendweight_code[] = {
4036 0xffff0300, /* ps_3_0 */
4037 0x0200001f, 0x80000001, 0x900f0000, /* dcl_blendweight, v0 */
4038 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
4039 0x0000ffff /* end */
4041 const DWORD blendindices_code[] = {
4042 0xffff0300, /* ps_3_0 */
4043 0x0200001f, 0x80000002, 0x900f0000, /* dcl_blendindices, v0 */
4044 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
4045 0x0000ffff /* end */
4047 const DWORD normal_code[] = {
4048 0xffff0300, /* ps_3_0 */
4049 0x0200001f, 0x80000003, 0x900f0000, /* dcl_normal, v0 */
4050 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
4051 0x0000ffff /* end */
4053 /* psize: fails? */
4054 const DWORD texcoord0_code[] = {
4055 0xffff0300, /* ps_3_0 */
4056 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0, v0 */
4057 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
4058 0x0000ffff /* end */
4060 const DWORD tangent_code[] = {
4061 0xffff0300, /* ps_3_0 */
4062 0x0200001f, 0x80000006, 0x900f0000, /* dcl_tangent, v0 */
4063 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
4064 0x0000ffff /* end */
4066 const DWORD binormal_code[] = {
4067 0xffff0300, /* ps_3_0 */
4068 0x0200001f, 0x80000007, 0x900f0000, /* dcl_binormal, v0 */
4069 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
4070 0x0000ffff /* end */
4072 /* tessfactor: fails */
4073 /* positiont: fails */
4074 const DWORD color_code[] = {
4075 0xffff0300, /* ps_3_0 */
4076 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0, v0 */
4077 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
4078 0x0000ffff /* end */
4080 const DWORD fog_code[] = {
4081 0xffff0300, /* ps_3_0 */
4082 0x0200001f, 0x8000000b, 0x900f0000, /* dcl_fog, v0 */
4083 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
4084 0x0000ffff /* end */
4086 const DWORD depth_code[] = {
4087 0xffff0300, /* ps_3_0 */
4088 0x0200001f, 0x8000000c, 0x900f0000, /* dcl_depth, v0 */
4089 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
4090 0x0000ffff /* end */
4092 const DWORD specular_code[] = {
4093 0xffff0300, /* ps_3_0 */
4094 0x0200001f, 0x8001000a, 0x900f0000, /* dcl_color1, v0 */
4095 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
4096 0x0000ffff /* end */
4098 /* sample: fails */
4100 struct varying_test_struct tests[] = {
4101 {blendweight_code, NULL, 0x00000000, 0x00191919, "blendweight" , FALSE, TRUE },
4102 {blendindices_code, NULL, 0x00000000, 0x00000000, "blendindices" , FALSE, FALSE },
4103 {normal_code, NULL, 0x00000000, 0x004c4c4c, "normal" , FALSE, TRUE },
4104 /* Why does dx not forward the texcoord? */
4105 {texcoord0_code, NULL, 0x00000000, 0x00808c8c, "texcoord0" , FALSE, FALSE },
4106 {tangent_code, NULL, 0x00000000, 0x00999999, "tangent" , FALSE, TRUE },
4107 {binormal_code, NULL, 0x00000000, 0x00b2b2b2, "binormal" , FALSE, TRUE },
4108 {color_code, NULL, 0x00e6e6e6, 0x00e6e6e6, "color" , FALSE, FALSE },
4109 {fog_code, NULL, 0x00000000, 0x00666666, "fog" , FALSE, TRUE },
4110 {depth_code, NULL, 0x00000000, 0x00cccccc, "depth" , FALSE, TRUE },
4111 {specular_code, NULL, 0x004488ff, 0x004488ff, "specular" , FALSE, FALSE }
4113 /* Declare a monster vertex type :-) */
4114 static const D3DVERTEXELEMENT9 decl_elements[] = {
4115 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4116 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
4117 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
4118 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
4119 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
4120 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4121 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
4122 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
4123 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
4124 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
4125 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
4126 D3DDECL_END()
4128 static const D3DVERTEXELEMENT9 decl_elements2[] = {
4129 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
4130 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
4131 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
4132 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
4133 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
4134 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4135 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
4136 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
4137 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
4138 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
4139 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
4140 D3DDECL_END()
4142 struct hugeVertex data[4] = {
4144 -1.0, -1.0, 0.1, 1.0,
4145 0.1, 0.1, 0.1, 0.1,
4146 0.2, 0.2, 0.2, 0.2,
4147 0.3, 0.3, 0.3, 0.3,
4148 0.4, 0.4, 0.4, 0.4,
4149 0.50, 0.55, 0.55, 0.55,
4150 0.6, 0.6, 0.6, 0.7,
4151 0.7, 0.7, 0.7, 0.6,
4152 0.8, 0.8, 0.8, 0.8,
4153 0xe6e6e6e6, /* 0.9 * 256 */
4154 0x224488ff /* Nothing special */
4157 1.0, -1.0, 0.1, 1.0,
4158 0.1, 0.1, 0.1, 0.1,
4159 0.2, 0.2, 0.2, 0.2,
4160 0.3, 0.3, 0.3, 0.3,
4161 0.4, 0.4, 0.4, 0.4,
4162 0.50, 0.55, 0.55, 0.55,
4163 0.6, 0.6, 0.6, 0.7,
4164 0.7, 0.7, 0.7, 0.6,
4165 0.8, 0.8, 0.8, 0.8,
4166 0xe6e6e6e6, /* 0.9 * 256 */
4167 0x224488ff /* Nothing special */
4170 -1.0, 1.0, 0.1, 1.0,
4171 0.1, 0.1, 0.1, 0.1,
4172 0.2, 0.2, 0.2, 0.2,
4173 0.3, 0.3, 0.3, 0.3,
4174 0.4, 0.4, 0.4, 0.4,
4175 0.50, 0.55, 0.55, 0.55,
4176 0.6, 0.6, 0.6, 0.7,
4177 0.7, 0.7, 0.7, 0.6,
4178 0.8, 0.8, 0.8, 0.8,
4179 0xe6e6e6e6, /* 0.9 * 256 */
4180 0x224488ff /* Nothing special */
4183 1.0, 1.0, 0.1, 1.0,
4184 0.1, 0.1, 0.1, 0.1,
4185 0.2, 0.2, 0.2, 0.2,
4186 0.3, 0.3, 0.3, 0.3,
4187 0.4, 0.4, 0.4, 0.4,
4188 0.50, 0.55, 0.55, 0.55,
4189 0.6, 0.6, 0.6, 0.7,
4190 0.7, 0.7, 0.7, 0.6,
4191 0.8, 0.8, 0.8, 0.8,
4192 0xe6e6e6e6, /* 0.9 * 256 */
4193 0x224488ff /* Nothing special */
4196 struct hugeVertex data2[4];
4197 IDirect3DVertexDeclaration9 *decl;
4198 IDirect3DVertexDeclaration9 *decl2;
4199 HRESULT hr;
4200 unsigned int i;
4201 DWORD color, r, g, b, r_e, g_e, b_e;
4203 memcpy(data2, data, sizeof(data2));
4204 data2[0].pos_x = 0; data2[0].pos_y = 0;
4205 data2[1].pos_x = 640; data2[1].pos_y = 0;
4206 data2[2].pos_x = 0; data2[2].pos_y = 480;
4207 data2[3].pos_x = 640; data2[3].pos_y = 480;
4209 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4210 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
4211 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
4212 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
4213 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4214 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
4216 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
4218 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
4219 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %s\n",
4220 tests[i].name, DXGetErrorString9(hr));
4223 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
4225 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
4226 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4228 IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
4229 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4231 hr = IDirect3DDevice9_BeginScene(device);
4232 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4233 if(SUCCEEDED(hr))
4235 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(data[0]));
4236 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4237 hr = IDirect3DDevice9_EndScene(device);
4238 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4240 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4241 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4243 color = getPixelColor(device, 360, 240);
4244 r = color & 0x00ff0000 >> 16;
4245 g = color & 0x0000ff00 >> 8;
4246 b = color & 0x000000ff;
4247 r_e = tests[i].color & 0x00ff0000 >> 16;
4248 g_e = tests[i].color & 0x0000ff00 >> 8;
4249 b_e = tests[i].color & 0x000000ff;
4251 if(tests[i].todo) {
4252 todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
4253 "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
4254 tests[i].name, color, tests[i].color);
4255 } else {
4256 ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
4257 "Test %s returned color 0x%08x, expected 0x%08x\n",
4258 tests[i].name, color, tests[i].color);
4262 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
4263 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
4264 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
4266 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
4267 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4269 IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
4270 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4272 hr = IDirect3DDevice9_BeginScene(device);
4273 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4274 if(SUCCEEDED(hr))
4276 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
4277 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4278 hr = IDirect3DDevice9_EndScene(device);
4279 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4281 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4282 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4284 color = getPixelColor(device, 360, 240);
4285 r = color & 0x00ff0000 >> 16;
4286 g = color & 0x0000ff00 >> 8;
4287 b = color & 0x000000ff;
4288 r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
4289 g_e = tests[i].color_rhw & 0x0000ff00 >> 8;
4290 b_e = tests[i].color_rhw & 0x000000ff;
4292 if(tests[i].todo_rhw) {
4293 /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
4294 * pipeline
4296 todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
4297 "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
4298 tests[i].name, color, tests[i].color_rhw);
4299 } else {
4300 ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
4301 "Test %s returned color 0x%08x, expected 0x%08x\n",
4302 tests[i].name, color, tests[i].color_rhw);
4306 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
4308 IDirect3DPixelShader9_Release(tests[i].shader);
4311 IDirect3DVertexDeclaration9_Release(decl2);
4312 IDirect3DVertexDeclaration9_Release(decl);
4315 static void vshader_version_varying_test(IDirect3DDevice9 *device) {
4316 static const DWORD ps_code[] = {
4317 0xffff0300, /* ps_3_0 */
4318 0x05000030, 0xf00f0000, 0x00000003, 0x00000003, 0x00000001, 0x00000000, /* defi i0, 3, 3, 1, 0 */
4319 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
4320 0x0200001f, 0x8001000a, 0x900f0003, /* dcl_color1 v3 */
4321 0x0200001f, 0x8000000b, 0x900f0004, /* dcl_fog v4 */
4322 0x0200001f, 0x80030005, 0x900f0005, /* dcl_texcoord3 v5 */
4323 0x0200001f, 0x80000003, 0x900f0006,
4324 0x0200001f, 0x80000006, 0x900f0007,
4325 0x0200001f, 0x80000001, 0x900f0008,
4326 0x0200001f, 0x8000000c, 0x900f0009,
4328 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4329 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
4330 0x04000002, 0x800f0000, 0x80e40000, 0x90e42000, 0xf0e40800, /* add r0, r0, v0[aL] */
4331 0x0000001d, /* endloop */
4332 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4333 0x0000ffff /* end */
4335 static const DWORD vs_1_code[] = {
4336 0xfffe0101, /* vs_1_1 */
4337 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4338 0x00000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0 */
4339 0x00000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0 */
4340 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0 */
4341 0x00000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
4342 0x00000001, 0xd00f0000, 0xa0e40002, /* mov oD0, c2 */
4343 0x00000001, 0xd00f0001, 0xa0e40000, /* mov oD1, c0 */
4344 0x00000001, 0xc00f0001, 0xa0550001, /* mov oFog, c1.g */
4345 0x00000001, 0xe00f0000, 0xa0e40003, /* mov oT0, c3 */
4346 0x00000001, 0xe00f0001, 0xa0e40003, /* mov oT1, c3 */
4347 0x00000001, 0xe00f0002, 0xa0e40003, /* mov oT2, c3 */
4348 0x00000001, 0xe00f0003, 0xa0e40002, /* mov oT3, c2 */
4349 0x00000001, 0xe00f0004, 0xa0e40003, /* mov oT4, c3 */
4350 0x00000001, 0xe00f0005, 0xa0e40003, /* mov oT5, c3 */
4351 0x00000001, 0xe00f0006, 0xa0e40003, /* mov oT6, c3 */
4352 0x00000001, 0xe00f0007, 0xa0e40003, /* mov oT7, c3 */
4353 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4354 0x0000ffff
4356 DWORD vs_2_code[] = {
4357 0xfffe0200, /* vs_2_0 */
4358 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4359 0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.5, 0.0, 0.0, 0.0 */
4360 0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.5, 0.0, 0.0 */
4361 0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.5, 0.0 */
4362 0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
4363 0x02000001, 0xd00f0000, 0xa0e40002, /* mov oD0, c2 */
4364 0x02000001, 0xd00f0001, 0xa0e40000, /* mov oD1, c0 */
4365 0x02000001, 0xc00f0001, 0xa0550001, /* mov oFog, c1.g */
4366 0x02000001, 0xe00f0000, 0xa0e40003, /* mov oT0, c3 */
4367 0x02000001, 0xe00f0001, 0xa0e40003, /* mov oT1, c3 */
4368 0x02000001, 0xe00f0002, 0xa0e40003, /* mov oT2, c3 */
4369 0x02000001, 0xe00f0003, 0xa0e40002, /* mov oT3, c2 */
4370 0x02000001, 0xe00f0004, 0xa0e40003, /* mov oT4, c3 */
4371 0x02000001, 0xe00f0005, 0xa0e40003, /* mov oT5, c3 */
4372 0x02000001, 0xe00f0006, 0xa0e40003, /* mov oT6, c3 */
4373 0x02000001, 0xe00f0007, 0xa0e40003, /* mov oT7, c3 */
4374 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4375 0x0000ffff /* end */
4377 /* TODO: Define normal, tangent, blendweight and depth here */
4378 static const DWORD vs_3_code[] = {
4379 0xfffe0300, /* vs_3_0 */
4380 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4381 0x0200001f, 0x8001000a, 0xe00f0009, /* dcl_color1 o9 */
4382 0x0200001f, 0x8000000b, 0xe00f0002, /* dcl_fog o2 */
4383 0x0200001f, 0x80030005, 0xe00f0005, /* dcl_texcoord3 o5 */
4384 0x0200001f, 0x80000000, 0xe00f000b, /* dcl_position o11 */
4385 0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0 */
4386 0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0 */
4387 0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0 */
4388 0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
4389 0x02000001, 0xe00f0009, 0xa0e40000, /* mov o9, c0 */
4390 0x02000001, 0xe00f0002, 0xa0e40001, /* mov o2, c1 */
4391 0x02000001, 0xe00f0005, 0xa0e40002, /* mov o5, c2 */
4392 0x02000001, 0xe00f000b, 0x90e40000, /* mov o11, v0 */
4393 0x0000ffff /* end */
4395 float quad1[] = {
4396 -1.0, -1.0, 0.1,
4397 0.0, -1.0, 0.1,
4398 -1.0, 0.0, 0.1,
4399 0.0, 0.0, 0.1
4401 float quad2[] = {
4402 0.0, -1.0, 0.1,
4403 1.0, -1.0, 0.1,
4404 0.0, 0.0, 0.1,
4405 1.0, 0.0, 0.1
4407 float quad3[] = {
4408 -1.0, 0.0, 0.1,
4409 0.0, 0.0, 0.1,
4410 -1.0, 1.0, 0.1,
4411 0.0, 1.0, 0.1
4414 HRESULT hr;
4415 DWORD color;
4416 IDirect3DPixelShader9 *pixelshader = NULL;
4417 IDirect3DVertexShader9 *vs_1_shader = NULL;
4418 IDirect3DVertexShader9 *vs_2_shader = NULL;
4419 IDirect3DVertexShader9 *vs_3_shader = NULL;
4421 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff110000, 0.0, 0);
4423 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &pixelshader);
4424 ok(hr == D3D_OK, "IDirect3DDevice_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4425 hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_code, &vs_1_shader);
4426 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
4427 hr = IDirect3DDevice9_CreateVertexShader(device, vs_2_code, &vs_2_shader);
4428 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
4429 hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_code, &vs_3_shader);
4430 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
4431 hr = IDirect3DDevice9_SetPixelShader(device, pixelshader);
4432 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4433 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4435 hr = IDirect3DDevice9_BeginScene(device);
4436 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4437 if(SUCCEEDED(hr))
4439 hr = IDirect3DDevice9_SetVertexShader(device, vs_1_shader);
4440 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4441 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
4442 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4444 hr = IDirect3DDevice9_SetVertexShader(device, vs_2_shader);
4445 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4446 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
4447 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4449 hr = IDirect3DDevice9_SetVertexShader(device, vs_3_shader);
4450 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4451 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
4452 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4454 hr = IDirect3DDevice9_EndScene(device);
4455 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4457 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4458 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4460 color = getPixelColor(device, 160, 120);
4461 ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
4462 (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003500 &&
4463 (color & 0x000000ff) >= 0x00000066 && (color & 0x000000ff) <= 0x00210068,
4464 "vs_3_0 returned color 0x%08x, expected 0x00203366\n", color);
4465 color = getPixelColor(device, 160, 360);
4466 ok((color & 0x00ff0000) >= 0x003c0000 && (color & 0x00ff0000) <= 0x004e0000 &&
4467 (color & 0x0000ff00) >= 0x00000000 && (color & 0x0000ff00) <= 0x00000000 &&
4468 (color & 0x000000ff) >= 0x00000066 && (color & 0x000000ff) <= 0x00210068,
4469 "vs_1_1 returned color 0x%08x, expected 0x00808080\n", color);
4470 color = getPixelColor(device, 480, 360);
4471 ok((color & 0x00ff0000) >= 0x003c0000 && (color & 0x00ff0000) <= 0x004e0000 &&
4472 (color & 0x0000ff00) >= 0x00000000 && (color & 0x0000ff00) <= 0x00000000 &&
4473 (color & 0x000000ff) >= 0x00000066 && (color & 0x000000ff) <= 0x00210068,
4474 "vs_2_0 returned color 0x%08x, expected 0x00000000\n", color);
4476 /* cleanup */
4477 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4478 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4479 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4480 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4481 if(pixelshader) IDirect3DPixelShader9_Release(pixelshader);
4482 if(vs_1_shader) IDirect3DVertexShader9_Release(vs_1_shader);
4483 if(vs_2_shader) IDirect3DVertexShader9_Release(vs_2_shader);
4484 if(vs_3_shader) IDirect3DVertexShader9_Release(vs_3_shader);
4487 static void pshader_version_varying_test(IDirect3DDevice9 *device) {
4488 static const DWORD vs_code[] = {
4489 0xfffe0300, /* vs_3_0 */
4490 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4491 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
4492 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */
4493 0x0200001f, 0x80000005, 0xe00f0002, /* dcl_texcoord0 o2 */
4494 0x0200001f, 0x8000000b, 0xe00f0003, /* dcl_fog o3 */
4495 0x0200001f, 0x80000003, 0xe00f0004, /* dcl_normal o4 */
4496 0x0200001f, 0x8000000c, 0xe00f0005, /* dcl_depth o5 */
4497 0x0200001f, 0x80000006, 0xe00f0006, /* dcl_tangent o6 */
4498 0x0200001f, 0x80000001, 0xe00f0007, /* dcl_blendweight o7 */
4499 0x05000051, 0xa00f0001, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c1, 0.1, 0.0, 0.0, 0.0 */
4500 0x05000051, 0xa00f0002, 0x00000000, 0x3e4ccccd, 0x00000000, 0x3f800000, /* def c2, 0.0, 0.2, 0.0, 1.0 */
4501 0x05000051, 0xa00f0003, 0x3ecccccd, 0x3f59999a, 0x3f666666, 0x00000000, /* def c3, 0.4, 0.85,0.9, 0.0 */
4502 0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0 */
4504 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
4505 0x02000001, 0xe00f0001, 0xa0e40001, /* mov o1, c1 */
4506 0x02000001, 0xe00f0002, 0xa0e40002, /* mov o2, c2 */
4507 0x02000001, 0xe00f0003, 0xa0e40003, /* mov o3, c3 */
4508 0x02000001, 0xe00f0004, 0xa0e40000, /* mov o4, c0 */
4509 0x02000001, 0xe00f0005, 0xa0e40000, /* mov o5, c0 */
4510 0x02000001, 0xe00f0006, 0xa0e40000, /* mov o6, c0 */
4511 0x02000001, 0xe00f0007, 0xa0e40000, /* mov o7, c0 */
4512 0x0000ffff /* end */
4514 static const DWORD ps_1_code[] = {
4515 0xffff0104, /* ps_1_4 */
4516 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
4517 0x00000040, 0x80070001, 0xb0e40000, /* texcrd r1.xyz, t0 */
4518 0x00000001, 0x80080001, 0xa0ff0000, /* mov r1.a, c0.a */
4519 0x00000002, 0x800f0000, 0x90e40000, 0x80e40001, /* add r0, v0, r1 */
4520 0x0000ffff /* end */
4522 static const DWORD ps_2_code[] = {
4523 0xffff0200, /* ps_2_0 */
4524 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
4525 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
4526 0x0200001f, 0x80000000, 0x900f0001, /* dcl v1 */
4528 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
4529 0x03000002, 0x800f0000, 0x80e40000,0xb0e40000, /* add r0, r0, t0 */
4530 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4531 0x0000ffff /* end */
4533 static const DWORD ps_3_code[] = {
4534 0xffff0300, /* ps_3_0 */
4535 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
4536 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
4537 0x0200001f, 0x8000000b, 0x900f0002, /* dcl_fog v2 */
4539 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
4540 0x03000002, 0x800f0000, 0x80e40000, 0x90e40001, /* add r0, r0, v1 */
4541 0x03000002, 0x800f0000, 0x80e40000, 0x90e40002, /* mov r0, r0, v2 */
4542 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4543 0x0000ffff /* end */
4546 float quad1[] = {
4547 -1.0, -1.0, 0.1,
4548 0.0, -1.0, 0.1,
4549 -1.0, 0.0, 0.1,
4550 0.0, 0.0, 0.1
4552 float quad2[] = {
4553 0.0, -1.0, 0.1,
4554 1.0, -1.0, 0.1,
4555 0.0, 0.0, 0.1,
4556 1.0, 0.0, 0.1
4558 float quad3[] = {
4559 -1.0, 0.0, 0.1,
4560 0.0, 0.0, 0.1,
4561 -1.0, 1.0, 0.1,
4562 0.0, 1.0, 0.1
4564 float quad4[] = {
4565 0.0, 0.0, 0.1,
4566 1.0, 0.0, 0.1,
4567 0.0, 1.0, 0.1,
4568 1.0, 1.0, 0.1
4571 HRESULT hr;
4572 DWORD color;
4573 IDirect3DVertexShader9 *vertexshader = NULL;
4574 IDirect3DPixelShader9 *ps_1_shader = NULL;
4575 IDirect3DPixelShader9 *ps_2_shader = NULL;
4576 IDirect3DPixelShader9 *ps_3_shader = NULL;
4577 IDirect3DTexture9 *texture = NULL;
4578 D3DLOCKED_RECT lr;
4579 unsigned int x, y;
4581 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4583 hr = IDirect3DDevice9_CreateTexture(device, 512, 512, 1, 0, D3DFMT_A16B16G16R16, D3DPOOL_MANAGED, &texture, NULL);
4584 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %s\n", DXGetErrorString9(hr));
4585 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4586 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %s\n", DXGetErrorString9(hr));
4587 for(y = 0; y < 512; y++) {
4588 for(x = 0; x < 512; x++) {
4589 double r_f = (double) x / (double) 512;
4590 double g_f = (double) y / (double) 512;
4591 unsigned short *dst = (unsigned short *) (((unsigned char *) lr.pBits) + y * lr.Pitch + x * 8);
4592 unsigned short r = (unsigned short) (r_f * 65535.0);
4593 unsigned short g = (unsigned short) (g_f * 65535.0);
4594 dst[0] = r;
4595 dst[1] = g;
4596 dst[2] = 0;
4597 dst[3] = 65535;
4600 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4601 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %s\n", DXGetErrorString9(hr));
4603 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vertexshader);
4604 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
4605 hr = IDirect3DDevice9_CreatePixelShader(device, ps_1_code, &ps_1_shader);
4606 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4607 hr = IDirect3DDevice9_CreatePixelShader(device, ps_2_code, &ps_2_shader);
4608 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4609 hr = IDirect3DDevice9_CreatePixelShader(device, ps_3_code, &ps_3_shader);
4610 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4611 hr = IDirect3DDevice9_SetVertexShader(device, vertexshader);
4612 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4613 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4615 hr = IDirect3DDevice9_BeginScene(device);
4616 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4617 if(SUCCEEDED(hr))
4619 hr = IDirect3DDevice9_SetPixelShader(device, ps_1_shader);
4620 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4621 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
4622 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4624 hr = IDirect3DDevice9_SetPixelShader(device, ps_2_shader);
4625 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4626 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
4627 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4629 hr = IDirect3DDevice9_SetPixelShader(device, ps_3_shader);
4630 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4631 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
4632 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4634 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4635 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4636 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4637 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
4638 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
4639 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
4640 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
4641 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
4642 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
4643 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4645 hr = IDirect3DDevice9_EndScene(device);
4646 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4648 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4649 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4651 color = getPixelColor(device, 160, 120);
4652 ok((color & 0x00ff0000) >= 0x00790000 && (color & 0x00ff0000) <= 0x00810000 &&
4653 (color & 0x0000ff00) == 0x0000ff00 &&
4654 (color & 0x000000ff) >= 0x000000e4 && (color & 0x000000ff) <= 0x000000e6,
4655 "ps_3_0 returned color 0x%08x, expected 0x0080ffe5\n", color);
4656 color = getPixelColor(device, 160, 360);
4657 ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
4658 (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003400 &&
4659 (color & 0x000000ff) == 0x00000000,
4660 "ps_1_4 returned color 0x%08x, expected 0x00203300\n", color);
4661 color = getPixelColor(device, 480, 360);
4662 ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
4663 (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
4664 (color & 0x000000ff) == 0x00000000,
4665 "ps_2_0 returned color 0x%08x, expected 0x00203300\n", color);
4666 color = getPixelColor(device, 480, 160);
4667 ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
4668 (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
4669 (color & 0x000000ff) == 0x00000000,
4670 "fixed function fragment processing returned color 0x%08x, expected 0x00203300\n", color);
4672 /* cleanup */
4673 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4674 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
4675 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4676 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4677 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4678 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4679 if(vertexshader) IDirect3DVertexShader9_Release(vertexshader);
4680 if(ps_1_shader) IDirect3DPixelShader9_Release(ps_1_shader);
4681 if(ps_2_shader) IDirect3DPixelShader9_Release(ps_2_shader);
4682 if(ps_3_shader) IDirect3DPixelShader9_Release(ps_3_shader);
4683 if(texture) IDirect3DTexture9_Release(texture);
4686 void test_compare_instructions(IDirect3DDevice9 *device)
4688 DWORD shader_sge_vec_code[] = {
4689 0xfffe0101, /* vs_1_1 */
4690 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4691 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4692 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4693 0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001, /* sge oD0, r0, c1 */
4694 0x0000ffff /* end */
4696 DWORD shader_slt_vec_code[] = {
4697 0xfffe0101, /* vs_1_1 */
4698 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4699 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4700 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4701 0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001, /* slt oD0, r0, c1 */
4702 0x0000ffff /* end */
4704 DWORD shader_sge_scalar_code[] = {
4705 0xfffe0101, /* vs_1_1 */
4706 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4707 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4708 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4709 0x0000000d, 0xd0010000, 0x80000000, 0xa0550001, /* slt oD0.r, r0.r, c1.b */
4710 0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001, /* slt oD0.g, r0.g, c1.r */
4711 0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001, /* slt oD0.b, r0.b, c1.g */
4712 0x0000ffff /* end */
4714 DWORD shader_slt_scalar_code[] = {
4715 0xfffe0101, /* vs_1_1 */
4716 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4717 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4718 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4719 0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001, /* slt oD0.r, r0.r, c1.b */
4720 0x0000000c, 0xd0020000, 0x80550000, 0xa0000001, /* slt oD0.g, r0.g, c1.r */
4721 0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001, /* slt oD0.b, r0.b, c1.g */
4722 0x0000ffff /* end */
4724 IDirect3DVertexShader9 *shader_sge_vec;
4725 IDirect3DVertexShader9 *shader_slt_vec;
4726 IDirect3DVertexShader9 *shader_sge_scalar;
4727 IDirect3DVertexShader9 *shader_slt_scalar;
4728 HRESULT hr, color;
4729 float quad1[] = {
4730 -1.0, -1.0, 0.1,
4731 0.0, -1.0, 0.1,
4732 -1.0, 0.0, 0.1,
4733 0.0, 0.0, 0.1
4735 float quad2[] = {
4736 0.0, -1.0, 0.1,
4737 1.0, -1.0, 0.1,
4738 0.0, 0.0, 0.1,
4739 1.0, 0.0, 0.1
4741 float quad3[] = {
4742 -1.0, 0.0, 0.1,
4743 0.0, 0.0, 0.1,
4744 -1.0, 1.0, 0.1,
4745 0.0, 1.0, 0.1
4747 float quad4[] = {
4748 0.0, 0.0, 0.1,
4749 1.0, 0.0, 0.1,
4750 0.0, 1.0, 0.1,
4751 1.0, 1.0, 0.1
4753 const float const0[4] = {0.8, 0.2, 0.2, 0.2};
4754 const float const1[4] = {0.2, 0.8, 0.2, 0.2};
4756 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
4758 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
4759 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
4760 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
4761 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
4762 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
4763 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
4764 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
4765 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
4766 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
4767 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
4768 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
4769 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
4770 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4771 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4773 hr = IDirect3DDevice9_BeginScene(device);
4774 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4775 if(SUCCEEDED(hr))
4777 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
4778 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4779 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
4780 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4782 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
4783 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4784 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
4785 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4787 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
4788 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4789 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
4790 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4792 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
4793 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
4795 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
4796 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4797 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
4798 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4800 hr = IDirect3DDevice9_EndScene(device);
4801 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4804 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4805 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4807 color = getPixelColor(device, 160, 360);
4808 ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
4809 color = getPixelColor(device, 480, 360);
4810 ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
4811 color = getPixelColor(device, 160, 120);
4812 ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
4813 color = getPixelColor(device, 480, 160);
4814 ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
4816 IDirect3DVertexShader9_Release(shader_sge_vec);
4817 IDirect3DVertexShader9_Release(shader_slt_vec);
4818 IDirect3DVertexShader9_Release(shader_sge_scalar);
4819 IDirect3DVertexShader9_Release(shader_slt_scalar);
4822 void test_vshader_input(IDirect3DDevice9 *device)
4824 DWORD swapped_shader_code_3[] = {
4825 0xfffe0300, /* vs_3_0 */
4826 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
4827 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
4828 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4829 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
4830 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
4831 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
4832 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
4833 0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
4834 0x0000ffff /* end */
4836 DWORD swapped_shader_code_1[] = {
4837 0xfffe0101, /* vs_1_1 */
4838 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4839 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
4840 0x0000001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
4841 0x00000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
4842 0x00000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
4843 0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
4844 0x0000ffff /* end */
4846 DWORD swapped_shader_code_2[] = {
4847 0xfffe0200, /* vs_2_0 */
4848 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4849 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
4850 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
4851 0x02000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
4852 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
4853 0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
4854 0x0000ffff /* end */
4856 DWORD texcoord_color_shader_code_3[] = {
4857 0xfffe0300, /* vs_3_0 */
4858 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
4859 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
4860 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4861 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
4862 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
4863 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
4864 0x0000ffff /* end */
4866 DWORD texcoord_color_shader_code_2[] = {
4867 0xfffe0200, /* vs_2_0 */
4868 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4869 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
4870 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4871 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
4872 0x0000ffff /* end */
4874 DWORD texcoord_color_shader_code_1[] = {
4875 0xfffe0101, /* vs_1_1 */
4876 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4877 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
4878 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4879 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
4880 0x0000ffff /* end */
4882 DWORD color_color_shader_code_3[] = {
4883 0xfffe0300, /* vs_3_0 */
4884 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
4885 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
4886 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4887 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
4888 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
4889 0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001, /* mul o1, c0, v1 */
4890 0x0000ffff /* end */
4892 DWORD color_color_shader_code_2[] = {
4893 0xfffe0200, /* vs_2_0 */
4894 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4895 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
4896 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4897 0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
4898 0x0000ffff /* end */
4900 DWORD color_color_shader_code_1[] = {
4901 0xfffe0101, /* vs_1_1 */
4902 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4903 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
4904 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4905 0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
4906 0x0000ffff /* end */
4908 IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
4909 HRESULT hr;
4910 DWORD color, r, g, b;
4911 float quad1[] = {
4912 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
4913 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
4914 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
4915 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
4917 float quad2[] = {
4918 0.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
4919 1.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
4920 0.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
4921 1.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
4923 float quad3[] = {
4924 -1.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0,
4925 0.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,
4926 -1.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0,
4927 0.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0,
4929 float quad4[] = {
4930 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
4931 1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
4932 0.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
4933 1.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
4935 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
4936 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4937 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4938 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
4939 D3DDECL_END()
4941 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
4942 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4943 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
4944 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4945 D3DDECL_END()
4947 static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
4948 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4949 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4950 D3DDECL_END()
4952 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
4953 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4954 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
4955 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
4956 D3DDECL_END()
4958 static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
4959 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4960 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4961 D3DDECL_END()
4963 static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
4964 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4965 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
4966 D3DDECL_END()
4968 static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
4969 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4970 {0, 12, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
4971 D3DDECL_END()
4973 static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
4974 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4975 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
4976 D3DDECL_END()
4978 IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
4979 IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
4980 unsigned int i;
4981 float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
4982 float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
4984 struct vertex quad1_color[] = {
4985 {-1.0, -1.0, 0.1, 0x00ff8040},
4986 { 0.0, -1.0, 0.1, 0x00ff8040},
4987 {-1.0, 0.0, 0.1, 0x00ff8040},
4988 { 0.0, 0.0, 0.1, 0x00ff8040}
4990 struct vertex quad2_color[] = {
4991 { 0.0, -1.0, 0.1, 0x00ff8040},
4992 { 1.0, -1.0, 0.1, 0x00ff8040},
4993 { 0.0, 0.0, 0.1, 0x00ff8040},
4994 { 1.0, 0.0, 0.1, 0x00ff8040}
4996 struct vertex quad3_color[] = {
4997 {-1.0, 0.0, 0.1, 0x00ff8040},
4998 { 0.0, 0.0, 0.1, 0x00ff8040},
4999 {-1.0, 1.0, 0.1, 0x00ff8040},
5000 { 0.0, 1.0, 0.1, 0x00ff8040}
5002 float quad4_color[] = {
5003 0.0, 0.0, 0.1, 1.0, 1.0, 0.0, 0.0,
5004 1.0, 0.0, 0.1, 1.0, 1.0, 0.0, 1.0,
5005 0.0, 1.0, 0.1, 1.0, 1.0, 0.0, 0.0,
5006 1.0, 1.0, 0.1, 1.0, 1.0, 0.0, 1.0,
5009 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
5010 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5011 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
5012 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5013 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
5014 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5015 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
5016 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5018 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
5019 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5020 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
5021 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5022 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
5023 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5024 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
5025 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5027 for(i = 1; i <= 3; i++) {
5028 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
5029 if(i == 3) {
5030 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
5031 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5032 } else if(i == 2){
5033 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
5034 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5035 } else if(i == 1) {
5036 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
5037 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5040 hr = IDirect3DDevice9_BeginScene(device);
5041 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5042 if(SUCCEEDED(hr))
5044 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
5045 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5047 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
5048 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5049 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
5050 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5052 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
5053 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5054 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
5055 if(i == 3 || i == 2) {
5056 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
5057 } else if(i == 1) {
5058 /* Succeeds or fails, depending on SW or HW vertex processing */
5059 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
5062 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
5063 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5064 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
5065 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5067 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
5068 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5069 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
5070 if(i == 3 || i == 2) {
5071 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
5072 } else if(i == 1) {
5073 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
5076 hr = IDirect3DDevice9_EndScene(device);
5077 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5080 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5081 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5083 if(i == 3 || i == 2) {
5084 color = getPixelColor(device, 160, 360);
5085 ok(color == 0x00FFFF80 || color == 0x00FFFF7f || color == 0x00FFFF81,
5086 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
5088 /* The last value of the read but undefined stream is used */
5089 color = getPixelColor(device, 480, 360);
5090 ok(color == 0x00FFFF00, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
5091 color = getPixelColor(device, 160, 120);
5092 ok(color == 0x00FF0080 || color == 0x00FF007f || color == 0x00FF0081,
5093 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
5095 color = getPixelColor(device, 480, 160);
5096 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
5097 } else if(i == 1) {
5098 color = getPixelColor(device, 160, 360);
5099 ok(color == 0x00FFFF80 || color == 0x00FFFF7f || color == 0x00FFFF81,
5100 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
5101 color = getPixelColor(device, 480, 360);
5102 /* Accept the clear color as well in this case, since SW VP returns an error */
5103 ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
5104 color = getPixelColor(device, 160, 120);
5105 ok(color == 0x00FF0080 || color == 0x00FF0000 || color == 0x00FF007f || color == 0x00FF0081,
5106 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
5107 color = getPixelColor(device, 480, 160);
5108 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
5111 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
5112 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
5114 /* Now find out if the whole streams are re-read, or just the last active value for the
5115 * vertices is used.
5117 hr = IDirect3DDevice9_BeginScene(device);
5118 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5119 if(SUCCEEDED(hr))
5121 float quad1_modified[] = {
5122 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0,
5123 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0,
5124 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0,
5125 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, -1.0, -1.0, 0.0,
5127 float quad2_modified[] = {
5128 0.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
5129 1.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
5130 0.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
5131 1.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
5134 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
5135 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5137 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
5138 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5139 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
5140 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5142 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
5143 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5144 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
5145 if(i == 3 || i == 2) {
5146 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
5147 } else if(i == 1) {
5148 /* Succeeds or fails, depending on SW or HW vertex processing */
5149 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
5152 hr = IDirect3DDevice9_EndScene(device);
5153 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5155 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5156 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5158 color = getPixelColor(device, 480, 360);
5159 /* vs_1_1 may fail, accept the clear color
5161 * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
5162 * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
5163 * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
5164 * refrast's result.
5166 * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
5168 ok(color == 0x000000FF || color == 0x00808080,
5169 "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF\n", color);
5170 color = getPixelColor(device, 160, 120);
5172 IDirect3DDevice9_SetVertexShader(device, NULL);
5173 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
5175 IDirect3DVertexShader9_Release(swapped_shader);
5178 for(i = 1; i <= 3; i++) {
5179 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
5180 if(i == 3) {
5181 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
5182 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5183 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
5184 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5185 } else if(i == 2){
5186 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
5187 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5188 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
5189 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5190 } else if(i == 1) {
5191 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
5192 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5193 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
5194 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5197 hr = IDirect3DDevice9_BeginScene(device);
5198 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5199 if(SUCCEEDED(hr))
5201 hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
5202 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5203 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
5204 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5205 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
5206 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5208 hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
5209 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5211 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
5212 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5213 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
5214 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5215 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
5216 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5218 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
5219 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5220 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
5221 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5222 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
5223 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5225 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
5226 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5227 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
5228 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5230 hr = IDirect3DDevice9_EndScene(device);
5231 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5233 IDirect3DDevice9_SetVertexShader(device, NULL);
5234 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
5236 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5237 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5239 color = getPixelColor(device, 160, 360);
5240 r = (color & 0x00ff0000) >> 16;
5241 g = (color & 0x0000ff00) >> 8;
5242 b = (color & 0x000000ff) >> 0;
5243 ok(r >= 0xfe && r <= 0xff && g >= 0x7f && g <= 0x81 && b >= 0x3f && b <= 0x41,
5244 "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
5245 color = getPixelColor(device, 480, 360);
5246 r = (color & 0x00ff0000) >> 16;
5247 g = (color & 0x0000ff00) >> 8;
5248 b = (color & 0x000000ff) >> 0;
5249 ok(r >= 0x3f && r <= 0x41 && g >= 0x7f && g <= 0x81 && b >= 0xfe && b <= 0xff,
5250 "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
5251 color = getPixelColor(device, 160, 120);
5252 r = (color & 0x00ff0000) >> 16;
5253 g = (color & 0x0000ff00) >> 8;
5254 b = (color & 0x000000ff) >> 0;
5255 ok(r >= 0xfe && r <= 0xff && g >= 0x7f && g <= 0x81 && b >= 0x3f && b <= 0x41,
5256 "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
5257 color = getPixelColor(device, 480, 160);
5258 r = (color & 0x00ff0000) >> 16;
5259 g = (color & 0x0000ff00) >> 8;
5260 b = (color & 0x000000ff) >> 0;
5261 ok(r >= 0xfe && r <= 0xff && g >= 0xfe && g <= 0xff && b <= 0x01,
5262 "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
5264 IDirect3DVertexShader9_Release(texcoord_color_shader);
5265 IDirect3DVertexShader9_Release(color_color_shader);
5268 IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
5269 IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
5270 IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
5271 IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
5273 IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
5274 IDirect3DVertexDeclaration9_Release(decl_color_color);
5275 IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
5276 IDirect3DVertexDeclaration9_Release(decl_color_float);
5279 static void fog_srgbwrite_test(IDirect3DDevice9 *device)
5281 /* Draw a black quad, half fogged with white fog -> grey color. Enable sRGB writing.
5282 * if sRGB writing is applied before fogging, the 0.0 will be multiplied with ~ 12.92, so still
5283 * stay 0.0. After that the fog gives 0.5. If sRGB writing is applied after fogging, the
5284 * 0.5 will run through the alternative path(0^5 ^ 0.41666 * 1.055 - 0.055), resulting in approx.
5285 * 0.73
5287 * At the time of this writing, wined3d could not apply sRGB correction to fixed function rendering,
5288 * so use shaders for this task
5290 IDirect3DPixelShader9 *pshader;
5291 IDirect3DVertexShader9 *vshader;
5292 IDirect3D9 *d3d;
5293 DWORD vshader_code[] = {
5294 0xfffe0101, /* vs_1_1 */
5295 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5296 0x00000051, 0xa00f0000, 0x3f000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.5, 0.0, 0.0, 0.0 */
5297 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5298 0x00000001, 0xc00f0001, 0xa0000000, /* mov oFog, c0.x */
5299 0x0000ffff /* end */
5301 DWORD pshader_code[] = {
5302 0xffff0101, /* ps_1_1 */
5303 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
5304 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5305 0x0000ffff /* end */
5307 const float quad[] = {
5308 -1.0, -1.0, 0.1,
5309 1.0, -1.0, 0.1,
5310 -1.0, 1.0, 0.1,
5311 1.0, 1.0, 0.1
5313 HRESULT hr;
5314 DWORD color;
5316 IDirect3DDevice9_GetDirect3D(device, &d3d);
5317 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
5318 D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE,
5319 D3DRTYPE_SURFACE, D3DFMT_A8R8G8B8) != D3D_OK) {
5320 skip("No SRGBWRITEENABLE support on D3DFMT_X8R8G8B8\n");
5321 IDirect3D9_Release(d3d);
5322 return;
5324 IDirect3D9_Release(d3d);
5326 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5327 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
5329 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
5330 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
5331 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
5332 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
5333 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
5334 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
5335 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffffffff);
5336 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
5337 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
5338 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
5340 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
5341 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5342 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code, &pshader);
5343 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
5344 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5345 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
5346 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
5347 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5348 hr = IDirect3DDevice9_SetPixelShader(device, pshader);
5349 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5351 hr = IDirect3DDevice9_BeginScene(device);
5352 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5353 if(SUCCEEDED(hr)) {
5354 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 3);
5355 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5357 hr = IDirect3DDevice9_EndScene(device);
5358 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5361 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5362 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5363 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5364 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5365 IDirect3DPixelShader9_Release(pshader);
5366 IDirect3DVertexShader9_Release(vshader);
5368 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
5369 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
5370 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
5371 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
5373 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5374 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5375 color = getPixelColor(device, 160, 360);
5376 ok(color == 0x00808080 || color == 0x007f7f7f || color == 0x00818181,
5377 "Fog with D3DRS_SRGBWRITEENABLE returned color 0x%08x, expected 0x00808080\n", color);
5380 static void alpha_test(IDirect3DDevice9 *device)
5382 HRESULT hr;
5383 IDirect3DTexture9 *offscreenTexture;
5384 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
5385 DWORD color, red, green, blue;
5387 struct vertex quad1[] =
5389 {-1.0f, -1.0f, 0.1f, 0x4000ff00},
5390 {-1.0f, 0.0f, 0.1f, 0x4000ff00},
5391 { 1.0f, -1.0f, 0.1f, 0x4000ff00},
5392 { 1.0f, 0.0f, 0.1f, 0x4000ff00},
5394 struct vertex quad2[] =
5396 {-1.0f, 0.0f, 0.1f, 0xc00000ff},
5397 {-1.0f, 1.0f, 0.1f, 0xc00000ff},
5398 { 1.0f, 0.0f, 0.1f, 0xc00000ff},
5399 { 1.0f, 1.0f, 0.1f, 0xc00000ff},
5401 static const float composite_quad[][5] = {
5402 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
5403 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
5404 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
5405 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
5408 /* Clear the render target with alpha = 0.5 */
5409 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
5410 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
5412 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
5413 ok(hr == D3D_OK || D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
5415 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
5416 ok(hr == D3D_OK, "Can't get back buffer, hr = %s\n", DXGetErrorString9(hr));
5417 if(!backbuffer) {
5418 goto out;
5421 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
5422 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %s\n", DXGetErrorString9(hr));
5423 if(!offscreen) {
5424 goto out;
5427 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
5428 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
5430 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
5431 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
5432 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
5433 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
5434 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
5435 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
5436 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
5437 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
5438 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
5439 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
5441 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
5442 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
5443 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
5445 /* Draw two quads, one with src alpha blending, one with dest alpha blending. The
5446 * SRCALPHA / INVSRCALPHA blend doesn't give any surprises. Colors are blended based on
5447 * the input alpha
5449 * The DESTALPHA / INVDESTALPHA do not "work" on the regular buffer because there is no alpha.
5450 * They give essentially ZERO and ONE blend factors
5452 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
5453 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
5454 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
5455 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
5456 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
5457 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
5459 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
5460 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
5461 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
5462 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
5463 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
5464 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
5466 /* Switch to the offscreen buffer, and redo the testing. SRCALPHA and DESTALPHA. The offscreen buffer
5467 * has a alpha channel on its own. Clear the offscreen buffer with alpha = 0.5 again, then draw the
5468 * quads again. The SRCALPHA/INVSRCALPHA doesn't give any surprises, but the DESTALPHA/INVDESTALPHA
5469 * blending works as supposed now - blend factor is 0.5 in both cases, not 0.75 as from the input
5470 * vertices
5472 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
5473 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
5474 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
5475 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
5477 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
5478 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
5479 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
5480 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
5481 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
5482 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
5484 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
5485 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
5486 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
5487 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
5488 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
5489 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
5491 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
5492 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
5494 /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
5495 * Disable alpha blending for the final composition
5497 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
5498 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
5499 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5500 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
5502 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
5503 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
5504 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
5505 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
5506 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5507 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
5509 hr = IDirect3DDevice9_EndScene(device);
5510 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
5513 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5515 color = getPixelColor(device, 160, 360);
5516 red = (color & 0x00ff0000) >> 16;
5517 green = (color & 0x0000ff00) >> 8;
5518 blue = (color & 0x000000ff);
5519 ok(red >= 0xbe && red <= 0xc0 && green >= 0x39 && green <= 0x41 && blue == 0x00,
5520 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
5522 color = getPixelColor(device, 160, 120);
5523 red = (color & 0x00ff0000) >> 16;
5524 green = (color & 0x0000ff00) >> 8;
5525 blue = (color & 0x000000ff);
5526 ok(red == 0x00 && green == 0x00 && blue >= 0xfe && blue <= 0xff ,
5527 "DSTALPHA on frame buffer returned color %08x, expected 0x00ff0000\n", color);
5529 color = getPixelColor(device, 480, 360);
5530 red = (color & 0x00ff0000) >> 16;
5531 green = (color & 0x0000ff00) >> 8;
5532 blue = (color & 0x000000ff);
5533 ok(red >= 0xbe && red <= 0xc0 && green >= 0x39 && green <= 0x41 && blue == 0x00,
5534 "SRCALPHA on texture returned color %08x, expected bar\n", color);
5536 color = getPixelColor(device, 480, 120);
5537 red = (color & 0x00ff0000) >> 16;
5538 green = (color & 0x0000ff00) >> 8;
5539 blue = (color & 0x000000ff);
5540 ok(red >= 0x7e && red <= 0x81 && green == 0x00 && blue >= 0x7e && blue <= 0x81,
5541 "DSTALPHA on texture returned color %08x, expected foo\n", color);
5543 out:
5544 /* restore things */
5545 if(backbuffer) {
5546 IDirect3DSurface9_Release(backbuffer);
5548 if(offscreenTexture) {
5549 IDirect3DTexture9_Release(offscreenTexture);
5551 if(offscreen) {
5552 IDirect3DSurface9_Release(offscreen);
5556 struct vertex_shortcolor {
5557 float x, y, z;
5558 unsigned short r, g, b, a;
5560 struct vertex_floatcolor {
5561 float x, y, z;
5562 float r, g, b, a;
5565 static void fixed_function_decl_test(IDirect3DDevice9 *device)
5567 HRESULT hr;
5568 BOOL s_ok, ub_ok, f_ok;
5569 DWORD color, size, i;
5570 void *data;
5571 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
5572 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5573 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5574 D3DDECL_END()
5576 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
5577 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5578 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5579 D3DDECL_END()
5581 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
5582 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5583 {0, 12, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5584 D3DDECL_END()
5586 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
5587 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5588 {1, 0, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5589 D3DDECL_END()
5591 static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
5592 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5593 {0, 12, D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5594 D3DDECL_END()
5596 static const D3DVERTEXELEMENT9 decl_elements_float[] = {
5597 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5598 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5599 D3DDECL_END()
5601 static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
5602 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
5603 {0, 16, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5604 D3DDECL_END()
5606 IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
5607 IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
5608 IDirect3DVertexBuffer9 *vb, *vb2;
5609 struct vertex quad1[] = /* D3DCOLOR */
5611 {-1.0f, -1.0f, 0.1f, 0x00ffff00},
5612 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
5613 { 0.0f, -1.0f, 0.1f, 0x00ffff00},
5614 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
5616 struct vertex quad2[] = /* UBYTE4N */
5618 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
5619 {-1.0f, 1.0f, 0.1f, 0x00ffff00},
5620 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
5621 { 0.0f, 1.0f, 0.1f, 0x00ffff00},
5623 struct vertex_shortcolor quad3[] = /* short */
5625 { 0.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
5626 { 0.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
5627 { 1.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
5628 { 1.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
5630 struct vertex_floatcolor quad4[] =
5632 { 0.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
5633 { 0.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
5634 { 1.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
5635 { 1.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
5637 DWORD colors[] = {
5638 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
5639 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
5640 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
5641 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
5642 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
5643 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
5644 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
5645 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
5646 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
5647 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
5648 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
5649 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
5650 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
5651 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
5652 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
5653 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
5655 float quads[] = {
5656 -1.0, -1.0, 0.1,
5657 -1.0, 0.0, 0.1,
5658 0.0, -1.0, 0.1,
5659 0.0, 0.0, 0.1,
5661 0.0, -1.0, 0.1,
5662 0.0, 0.0, 0.1,
5663 1.0, -1.0, 0.1,
5664 1.0, 0.0, 0.1,
5666 0.0, 0.0, 0.1,
5667 0.0, 1.0, 0.1,
5668 1.0, 0.0, 0.1,
5669 1.0, 1.0, 0.1,
5671 -1.0, 0.0, 0.1,
5672 -1.0, 1.0, 0.1,
5673 0.0, 0.0, 0.1,
5674 0.0, 1.0, 0.1
5676 struct tvertex quad_transformed[] = {
5677 { 90, 110, 0.1, 2.0, 0x00ffff00},
5678 { 570, 110, 0.1, 2.0, 0x00ffff00},
5679 { 90, 300, 0.1, 2.0, 0x00ffff00},
5680 { 570, 300, 0.1, 2.0, 0x00ffff00}
5682 D3DCAPS9 caps;
5684 memset(&caps, 0, sizeof(caps));
5685 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5686 ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
5688 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5689 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
5691 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
5692 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
5693 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
5694 ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
5695 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
5696 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
5697 if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
5698 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
5699 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
5700 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
5701 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
5702 } else {
5703 trace("D3DDTCAPS_UBYTE4N not supported\n");
5704 dcl_ubyte_2 = NULL;
5705 dcl_ubyte = NULL;
5707 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
5708 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
5709 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
5710 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
5712 size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
5713 hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
5714 0, 0, D3DPOOL_MANAGED, &vb, NULL);
5715 ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
5717 hr = IDirect3DDevice9_BeginScene(device);
5718 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
5719 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
5720 if(SUCCEEDED(hr)) {
5721 if(dcl_color) {
5722 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
5723 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
5724 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
5725 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
5728 /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
5729 * accepts them, the nvidia driver accepts them all. All those differences even though we're
5730 * using software vertex processing. Doh!
5732 if(dcl_ubyte) {
5733 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
5734 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
5735 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
5736 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
5737 ub_ok = SUCCEEDED(hr);
5740 if(dcl_short) {
5741 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
5742 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
5743 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
5744 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
5745 s_ok = SUCCEEDED(hr);
5748 if(dcl_float) {
5749 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
5750 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
5751 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
5752 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
5753 f_ok = SUCCEEDED(hr);
5756 hr = IDirect3DDevice9_EndScene(device);
5757 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
5760 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5761 if(dcl_short) {
5762 color = getPixelColor(device, 480, 360);
5763 ok(color == 0x000000ff || !s_ok,
5764 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
5766 if(dcl_ubyte) {
5767 color = getPixelColor(device, 160, 120);
5768 ok(color == 0x0000ffff || !ub_ok,
5769 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
5771 if(dcl_color) {
5772 color = getPixelColor(device, 160, 360);
5773 ok(color == 0x00ffff00,
5774 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
5776 if(dcl_float) {
5777 color = getPixelColor(device, 480, 120);
5778 ok(color == 0x00ff0000 || !f_ok,
5779 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
5782 /* The following test with vertex buffers doesn't serve to find out new information from windows.
5783 * It is a plain regression test because wined3d uses different codepaths for attribute conversion
5784 * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
5785 * whether the immediate mode code works
5787 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
5788 hr = IDirect3DDevice9_BeginScene(device);
5789 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
5790 if(SUCCEEDED(hr)) {
5791 if(dcl_color) {
5792 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), (void **) &data, 0);
5793 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
5794 memcpy(data, quad1, sizeof(quad1));
5795 hr = IDirect3DVertexBuffer9_Unlock(vb);
5796 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
5797 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
5798 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
5799 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
5800 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
5801 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
5802 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
5805 if(dcl_ubyte) {
5806 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), (void **) &data, 0);
5807 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
5808 memcpy(data, quad2, sizeof(quad2));
5809 hr = IDirect3DVertexBuffer9_Unlock(vb);
5810 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
5811 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
5812 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
5813 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
5814 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
5815 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
5816 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
5817 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
5818 ub_ok = SUCCEEDED(hr);
5821 if(dcl_short) {
5822 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), (void **) &data, 0);
5823 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
5824 memcpy(data, quad3, sizeof(quad3));
5825 hr = IDirect3DVertexBuffer9_Unlock(vb);
5826 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
5827 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
5828 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
5829 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
5830 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
5831 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
5832 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
5833 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
5834 s_ok = SUCCEEDED(hr);
5837 if(dcl_float) {
5838 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), (void **) &data, 0);
5839 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
5840 memcpy(data, quad4, sizeof(quad4));
5841 hr = IDirect3DVertexBuffer9_Unlock(vb);
5842 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
5843 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
5844 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
5845 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
5846 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
5847 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
5848 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
5849 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
5850 f_ok = SUCCEEDED(hr);
5853 hr = IDirect3DDevice9_EndScene(device);
5854 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
5857 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
5858 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
5859 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
5860 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
5862 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5863 if(dcl_short) {
5864 color = getPixelColor(device, 480, 360);
5865 ok(color == 0x000000ff || !s_ok,
5866 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
5868 if(dcl_ubyte) {
5869 color = getPixelColor(device, 160, 120);
5870 ok(color == 0x0000ffff || !ub_ok,
5871 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
5873 if(dcl_color) {
5874 color = getPixelColor(device, 160, 360);
5875 ok(color == 0x00ffff00,
5876 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
5878 if(dcl_float) {
5879 color = getPixelColor(device, 480, 120);
5880 ok(color == 0x00ff0000 || !f_ok,
5881 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
5884 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
5885 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
5887 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), (void **) &data, 0);
5888 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
5889 memcpy(data, quad_transformed, sizeof(quad_transformed));
5890 hr = IDirect3DVertexBuffer9_Unlock(vb);
5891 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
5893 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
5894 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
5896 hr = IDirect3DDevice9_BeginScene(device);
5897 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
5898 if(SUCCEEDED(hr)) {
5899 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
5900 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
5901 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
5902 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
5904 hr = IDirect3DDevice9_EndScene(device);
5905 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
5908 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5909 color = getPixelColor(device, 88, 108);
5910 ok(color == 0x000000ff,
5911 "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
5912 color = getPixelColor(device, 92, 108);
5913 ok(color == 0x000000ff,
5914 "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
5915 color = getPixelColor(device, 88, 112);
5916 ok(color == 0x000000ff,
5917 "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
5918 color = getPixelColor(device, 92, 112);
5919 ok(color == 0x00ffff00,
5920 "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
5922 color = getPixelColor(device, 568, 108);
5923 ok(color == 0x000000ff,
5924 "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
5925 color = getPixelColor(device, 572, 108);
5926 ok(color == 0x000000ff,
5927 "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
5928 color = getPixelColor(device, 568, 112);
5929 ok(color == 0x00ffff00,
5930 "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
5931 color = getPixelColor(device, 572, 112);
5932 ok(color == 0x000000ff,
5933 "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
5935 color = getPixelColor(device, 88, 298);
5936 ok(color == 0x000000ff,
5937 "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
5938 color = getPixelColor(device, 92, 298);
5939 ok(color == 0x00ffff00,
5940 "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
5941 color = getPixelColor(device, 88, 302);
5942 ok(color == 0x000000ff,
5943 "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
5944 color = getPixelColor(device, 92, 302);
5945 ok(color == 0x000000ff,
5946 "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
5948 color = getPixelColor(device, 568, 298);
5949 ok(color == 0x00ffff00,
5950 "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
5951 color = getPixelColor(device, 572, 298);
5952 ok(color == 0x000000ff,
5953 "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
5954 color = getPixelColor(device, 568, 302);
5955 ok(color == 0x000000ff,
5956 "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
5957 color = getPixelColor(device, 572, 302);
5958 ok(color == 0x000000ff,
5959 "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
5961 /* This test is pointless without those two declarations: */
5962 if((!dcl_color_2) || (!dcl_ubyte_2)) {
5963 skip("color-ubyte switching test declarations aren't supported\n");
5964 goto out;
5967 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), (void **) &data, 0);
5968 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
5969 memcpy(data, quads, sizeof(quads));
5970 hr = IDirect3DVertexBuffer9_Unlock(vb);
5971 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
5972 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
5973 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
5974 ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
5975 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), (void **) &data, 0);
5976 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
5977 memcpy(data, colors, sizeof(colors));
5978 hr = IDirect3DVertexBuffer9_Unlock(vb2);
5979 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
5981 for(i = 0; i < 2; i++) {
5982 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5983 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
5985 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
5986 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
5987 if(i == 0) {
5988 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
5989 } else {
5990 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
5992 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
5994 hr = IDirect3DDevice9_BeginScene(device);
5995 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
5996 ub_ok = FALSE;
5997 if(SUCCEEDED(hr)) {
5998 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
5999 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
6000 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
6001 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
6002 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
6003 ub_ok = SUCCEEDED(hr);
6005 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
6006 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
6007 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
6008 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
6010 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
6011 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
6012 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
6013 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
6014 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
6015 ub_ok = (SUCCEEDED(hr) && ub_ok);
6017 hr = IDirect3DDevice9_EndScene(device);
6018 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
6021 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6022 if(i == 0) {
6023 color = getPixelColor(device, 480, 360);
6024 ok(color == 0x00ff0000,
6025 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
6026 color = getPixelColor(device, 160, 120);
6027 ok(color == 0x00ffffff,
6028 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
6029 color = getPixelColor(device, 160, 360);
6030 ok(color == 0x000000ff || !ub_ok,
6031 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
6032 color = getPixelColor(device, 480, 120);
6033 ok(color == 0x000000ff || !ub_ok,
6034 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
6035 } else {
6036 color = getPixelColor(device, 480, 360);
6037 ok(color == 0x000000ff,
6038 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
6039 color = getPixelColor(device, 160, 120);
6040 ok(color == 0x00ffffff,
6041 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
6042 color = getPixelColor(device, 160, 360);
6043 ok(color == 0x00ff0000 || !ub_ok,
6044 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
6045 color = getPixelColor(device, 480, 120);
6046 ok(color == 0x00ff0000 || !ub_ok,
6047 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
6051 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6052 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6053 hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
6054 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6055 IDirect3DVertexBuffer9_Release(vb2);
6057 out:
6058 IDirect3DVertexBuffer9_Release(vb);
6059 if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
6060 if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
6061 if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
6062 if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
6063 if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
6064 if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
6065 if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
6068 struct vertex_float16color {
6069 float x, y, z;
6070 DWORD c1, c2;
6073 static void test_vshader_float16(IDirect3DDevice9 *device)
6075 HRESULT hr;
6076 DWORD color;
6077 void *data;
6078 static const D3DVERTEXELEMENT9 decl_elements[] = {
6079 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6080 {0, 12, D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6081 D3DDECL_END()
6083 IDirect3DVertexDeclaration9 *vdecl = NULL;
6084 IDirect3DVertexBuffer9 *buffer = NULL;
6085 IDirect3DVertexShader9 *shader;
6086 DWORD shader_code[] = {
6087 0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
6088 0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
6089 0x90e40001, 0x0000ffff
6091 struct vertex_float16color quad[] = {
6092 { -1.0, -1.0, 0.1, 0x3c000000, 0x00000000 }, /* green */
6093 { -1.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
6094 { 0.0, -1.0, 0.1, 0x3c000000, 0x00000000 },
6095 { 0.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
6097 { 0.0, -1.0, 0.1, 0x00003c00, 0x00000000 }, /* red */
6098 { 0.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
6099 { 1.0, -1.0, 0.1, 0x00003c00, 0x00000000 },
6100 { 1.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
6102 { 0.0, 0.0, 0.1, 0x00000000, 0x00003c00 }, /* blue */
6103 { 0.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
6104 { 1.0, 0.0, 0.1, 0x00000000, 0x00003c00 },
6105 { 1.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
6107 { -1.0, 0.0, 0.1, 0x00000000, 0x3c000000 }, /* alpha */
6108 { -1.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
6109 { 0.0, 0.0, 0.1, 0x00000000, 0x3c000000 },
6110 { 0.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
6113 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
6114 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
6116 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
6117 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%s\n", DXGetErrorString9(hr));
6118 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
6119 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%s\n", DXGetErrorString9(hr));
6120 IDirect3DDevice9_SetVertexShader(device, shader);
6121 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%s\n", DXGetErrorString9(hr));
6123 hr = IDirect3DDevice9_BeginScene(device);
6124 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
6125 if(SUCCEEDED(hr)) {
6126 hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
6127 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%s\n", DXGetErrorString9(hr));
6128 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 0, sizeof(quad[0]));
6129 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
6130 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 4, sizeof(quad[0]));
6131 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
6132 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 8, sizeof(quad[0]));
6133 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
6134 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
6135 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
6137 hr = IDirect3DDevice9_EndScene(device);
6138 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%s\n", DXGetErrorString9(hr));
6140 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6141 color = getPixelColor(device, 480, 360);
6142 ok(color == 0x00ff0000,
6143 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
6144 color = getPixelColor(device, 160, 120);
6145 ok(color == 0x00000000,
6146 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
6147 color = getPixelColor(device, 160, 360);
6148 ok(color == 0x0000ff00,
6149 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
6150 color = getPixelColor(device, 480, 120);
6151 ok(color == 0x000000ff,
6152 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
6154 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
6155 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
6157 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
6158 D3DPOOL_MANAGED, &buffer, NULL);
6159 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%s\n", DXGetErrorString9(hr));
6160 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), (void **) &data, 0);
6161 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%s\n", DXGetErrorString9(hr));
6162 memcpy(data, quad, sizeof(quad));
6163 hr = IDirect3DVertexBuffer9_Unlock(buffer);
6164 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%s\n", DXGetErrorString9(hr));
6165 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
6166 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%s\n", DXGetErrorString9(hr));
6168 hr = IDirect3DDevice9_BeginScene(device);
6169 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
6170 if(SUCCEEDED(hr)) {
6171 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
6172 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
6173 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
6174 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
6175 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
6176 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
6177 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
6178 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
6180 hr = IDirect3DDevice9_EndScene(device);
6181 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%s\n", DXGetErrorString9(hr));
6184 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6185 color = getPixelColor(device, 480, 360);
6186 ok(color == 0x00ff0000,
6187 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
6188 color = getPixelColor(device, 160, 120);
6189 ok(color == 0x00000000,
6190 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
6191 color = getPixelColor(device, 160, 360);
6192 ok(color == 0x0000ff00,
6193 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
6194 color = getPixelColor(device, 480, 120);
6195 ok(color == 0x000000ff,
6196 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
6198 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6199 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%s\n", DXGetErrorString9(hr));
6200 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6201 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%s\n", DXGetErrorString9(hr));
6202 IDirect3DDevice9_SetVertexShader(device, NULL);
6203 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%s\n", DXGetErrorString9(hr));
6205 IDirect3DVertexDeclaration9_Release(vdecl);
6206 IDirect3DVertexShader9_Release(shader);
6207 IDirect3DVertexBuffer9_Release(buffer);
6210 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
6212 D3DCAPS9 caps;
6213 IDirect3DTexture9 *texture;
6214 HRESULT hr;
6215 D3DLOCKED_RECT rect;
6216 unsigned int x, y;
6217 DWORD *dst, color;
6218 const float quad[] = {
6219 -1.0, -1.0, 0.1, -0.2, -0.2,
6220 1.0, -1.0, 0.1, 1.2, -0.2,
6221 -1.0, 1.0, 0.1, -0.2, 1.2,
6222 1.0, 1.0, 0.1, 1.2, 1.2
6224 memset(&caps, 0, sizeof(caps));
6226 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6227 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%s\n", DXGetErrorString9(hr));
6228 if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
6229 /* NP2 conditional requires the POW2 flag. Check that while we're at it */
6230 ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
6231 "Card has conditional NP2 support without power of two restriction set\n");
6232 skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
6233 return;
6234 } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
6235 skip("No conditional NP2 support, skipping conditional NP2 tests\n");
6236 return;
6239 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
6240 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
6242 hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
6243 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%s\n", DXGetErrorString9(hr));
6245 memset(&rect, 0, sizeof(rect));
6246 hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
6247 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%s\n", DXGetErrorString9(hr));
6248 for(y = 0; y < 10; y++) {
6249 for(x = 0; x < 10; x++) {
6250 dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
6251 if(x == 0 || x == 9 || y == 0 || y == 9) {
6252 *dst = 0x00ff0000;
6253 } else {
6254 *dst = 0x000000ff;
6258 hr = IDirect3DTexture9_UnlockRect(texture, 0);
6259 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%s\n", DXGetErrorString9(hr));
6261 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6262 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%s\n", DXGetErrorString9(hr));
6263 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
6264 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%s\n", DXGetErrorString9(hr));
6265 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
6266 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%s\n", DXGetErrorString9(hr));
6267 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6268 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%s\n", DXGetErrorString9(hr));
6270 hr = IDirect3DDevice9_BeginScene(device);
6271 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
6272 if(SUCCEEDED(hr)) {
6273 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
6274 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
6276 hr = IDirect3DDevice9_EndScene(device);
6277 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
6280 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6282 color = getPixelColor(device, 1, 1);
6283 ok(color == 0x00ff0000, "NP2: Pixel 1, 1 has color %08x, expected 0x00ff0000\n", color);
6284 color = getPixelColor(device, 639, 479);
6285 ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
6287 color = getPixelColor(device, 135, 101);
6288 ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
6289 color = getPixelColor(device, 140, 101);
6290 ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
6291 color = getPixelColor(device, 135, 105);
6292 ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
6293 color = getPixelColor(device, 140, 105);
6294 ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
6296 color = getPixelColor(device, 135, 376);
6297 ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
6298 color = getPixelColor(device, 140, 376);
6299 ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
6300 color = getPixelColor(device, 135, 379);
6301 ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
6302 color = getPixelColor(device, 140, 379);
6303 ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
6305 color = getPixelColor(device, 500, 101);
6306 ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
6307 color = getPixelColor(device, 504, 101);
6308 ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
6309 color = getPixelColor(device, 500, 105);
6310 ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
6311 color = getPixelColor(device, 504, 105);
6312 ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
6314 color = getPixelColor(device, 500, 376);
6315 ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
6316 color = getPixelColor(device, 504, 376);
6317 ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
6318 color = getPixelColor(device, 500, 380);
6319 ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
6320 color = getPixelColor(device, 504, 380);
6321 ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
6323 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6324 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%s\n", DXGetErrorString9(hr));
6325 IDirect3DTexture9_Release(texture);
6328 static void vFace_register_test(IDirect3DDevice9 *device)
6330 HRESULT hr;
6331 DWORD color;
6332 const DWORD shader_code[] = {
6333 0xffff0300, /* ps_3_0 */
6334 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
6335 0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
6336 0x0200001f, 0x80000000, 0x900f1001, /* dcl vFace */
6337 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6338 0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001, /* cmp r0, vFace, c0, r1 */
6339 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
6340 0x0000ffff /* END */
6342 IDirect3DPixelShader9 *shader;
6343 IDirect3DTexture9 *texture;
6344 IDirect3DSurface9 *surface, *backbuffer;
6345 const float quad[] = {
6346 -1.0, -1.0, 0.1,
6347 1.0, -1.0, 0.1,
6348 -1.0, 0.0, 0.1,
6350 1.0, -1.0, 0.1,
6351 1.0, 0.0, 0.1,
6352 -1.0, 0.0, 0.1,
6354 -1.0, 0.0, 0.1,
6355 -1.0, 1.0, 0.1,
6356 1.0, 0.0, 0.1,
6358 1.0, 0.0, 0.1,
6359 -1.0, 1.0, 0.1,
6360 1.0, 1.0, 0.1,
6362 const float blit[] = {
6363 0.0, -1.0, 0.1, 0.0, 0.0,
6364 1.0, -1.0, 0.1, 1.0, 0.0,
6365 0.0, 1.0, 0.1, 0.0, 1.0,
6366 1.0, 1.0, 0.1, 1.0, 1.0,
6369 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
6370 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%s\n", DXGetErrorString9(hr));
6371 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
6372 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%s\n", DXGetErrorString9(hr));
6373 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6374 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%s\n", DXGetErrorString9(hr));
6375 hr = IDirect3DDevice9_SetPixelShader(device, shader);
6376 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
6377 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6378 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%s\n", DXGetErrorString9(hr));
6379 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6380 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%s\n", DXGetErrorString9(hr));
6382 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6383 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
6385 hr = IDirect3DDevice9_BeginScene(device);
6386 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
6387 if(SUCCEEDED(hr)) {
6388 /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
6389 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
6390 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
6391 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6392 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
6393 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
6394 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
6395 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
6396 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
6397 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
6398 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
6400 /* Blit the texture ontp the back buffer to make it visible */
6401 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6402 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%s\n", DXGetErrorString9(hr));
6403 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6404 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%s\n", DXGetErrorString9(hr));
6405 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6406 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%s\n", DXGetErrorString9(hr));
6407 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6408 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%s\n", DXGetErrorString9(hr));
6409 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6410 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%s\n", DXGetErrorString9(hr));
6412 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
6413 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
6415 hr = IDirect3DDevice9_EndScene(device);
6416 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
6419 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6420 color = getPixelColor(device, 160, 360);
6421 ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
6422 color = getPixelColor(device, 160, 120);
6423 ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
6424 color = getPixelColor(device, 480, 360);
6425 ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
6426 color = getPixelColor(device, 480, 120);
6427 ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
6429 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
6430 IDirect3DDevice9_SetTexture(device, 0, NULL);
6431 IDirect3DPixelShader9_Release(shader);
6432 IDirect3DSurface9_Release(surface);
6433 IDirect3DSurface9_Release(backbuffer);
6434 IDirect3DTexture9_Release(texture);
6437 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
6439 HRESULT hr;
6440 DWORD color;
6441 int i;
6442 D3DCAPS9 caps;
6444 static const float quad[][7] = {
6445 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
6446 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
6447 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
6448 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
6451 static const D3DVERTEXELEMENT9 decl_elements[] = {
6452 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6453 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
6454 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
6455 D3DDECL_END()
6458 /* use assymetric matrix to test loading */
6459 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
6461 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
6462 IDirect3DTexture9 *texture = NULL;
6464 memset(&caps, 0, sizeof(caps));
6465 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6466 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%s\n", DXGetErrorString9(hr));
6467 if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
6468 skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
6469 return;
6470 } else {
6471 IDirect3D9 *d3d9;
6473 IDirect3DDevice9_GetDirect3D(device, &d3d9);
6474 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_LEGACYBUMPMAP,
6475 D3DRTYPE_TEXTURE, D3DFMT_V8U8);
6476 IDirect3D9_Release(d3d9);
6477 if(FAILED(hr)) {
6478 skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
6479 return;
6483 /* Generate the textures */
6484 generate_bumpmap_textures(device);
6486 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
6487 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
6488 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
6489 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
6490 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
6491 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
6492 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
6493 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
6495 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
6496 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
6497 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
6498 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
6499 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
6500 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
6502 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6503 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
6504 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6505 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
6506 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
6507 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
6509 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
6510 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
6512 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6513 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
6515 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
6516 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
6519 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
6520 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
6521 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
6522 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
6524 hr = IDirect3DDevice9_BeginScene(device);
6525 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
6527 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
6528 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
6530 hr = IDirect3DDevice9_EndScene(device);
6531 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
6533 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6534 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
6536 color = getPixelColor(device, 320-32, 240);
6537 ok(color == 0x00ffffff, "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
6538 color = getPixelColor(device, 320+32, 240);
6539 ok(color == 0x00ffffff, "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
6540 color = getPixelColor(device, 320, 240-32);
6541 ok(color == 0x00ffffff, "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
6542 color = getPixelColor(device, 320, 240+32);
6543 ok(color == 0x00ffffff, "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
6544 color = getPixelColor(device, 320, 240);
6545 ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
6546 color = getPixelColor(device, 320+32, 240+32);
6547 ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
6548 color = getPixelColor(device, 320-32, 240+32);
6549 ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
6550 color = getPixelColor(device, 320+32, 240-32);
6551 ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
6552 color = getPixelColor(device, 320-32, 240-32);
6553 ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
6555 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6556 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
6557 IDirect3DVertexDeclaration9_Release(vertex_declaration);
6559 for(i = 0; i < 2; i++) {
6560 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
6561 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
6562 IDirect3DTexture9_Release(texture); /* For the GetTexture */
6563 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
6564 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
6565 IDirect3DTexture9_Release(texture); /* To destroy it */
6568 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
6569 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
6570 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
6571 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
6575 static void stencil_cull_test(IDirect3DDevice9 *device) {
6576 HRESULT hr;
6577 IDirect3DSurface9 *depthstencil = NULL;
6578 D3DSURFACE_DESC desc;
6579 float quad1[] = {
6580 -1.0, -1.0, 0.1,
6581 0.0, -1.0, 0.1,
6582 -1.0, 0.0, 0.1,
6583 0.0, 0.0, 0.1,
6585 float quad2[] = {
6586 0.0, -1.0, 0.1,
6587 1.0, -1.0, 0.1,
6588 0.0, 0.0, 0.1,
6589 1.0, 0.0, 0.1,
6591 float quad3[] = {
6592 0.0, 0.0, 0.1,
6593 1.0, 0.0, 0.1,
6594 0.0, 1.0, 0.1,
6595 1.0, 1.0, 0.1,
6597 float quad4[] = {
6598 -1.0, 0.0, 0.1,
6599 0.0, 0.0, 0.1,
6600 -1.0, 1.0, 0.1,
6601 0.0, 1.0, 0.1,
6603 struct vertex painter[] = {
6604 {-1.0, -1.0, 0.0, 0x00000000},
6605 { 1.0, -1.0, 0.0, 0x00000000},
6606 {-1.0, 1.0, 0.0, 0x00000000},
6607 { 1.0, 1.0, 0.0, 0x00000000},
6609 WORD indices_cw[] = {0, 1, 3};
6610 WORD indices_ccw[] = {0, 2, 3};
6611 unsigned int i;
6612 DWORD color;
6614 IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
6615 if(depthstencil == NULL) {
6616 skip("No depth stencil buffer\n");
6617 return;
6619 hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
6620 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %s\n", DXGetErrorString9(hr));
6621 IDirect3DSurface9_Release(depthstencil);
6622 if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
6623 skip("No 4 or 8 bit stencil surface\n");
6624 return;
6627 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
6628 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
6629 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6631 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
6632 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6633 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
6634 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6635 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
6636 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6637 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
6638 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6640 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
6641 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6642 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
6643 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6644 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
6645 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6647 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
6648 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6649 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
6650 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6652 /* First pass: Fill the stencil buffer with some values... */
6653 hr = IDirect3DDevice9_BeginScene(device);
6654 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
6655 if(SUCCEEDED(hr))
6657 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
6658 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6659 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
6660 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
6661 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
6662 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
6664 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
6665 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6666 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
6667 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6668 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
6669 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
6670 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
6671 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
6673 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
6674 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6675 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
6676 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
6677 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
6678 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
6680 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
6681 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6682 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
6683 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
6684 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
6685 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
6687 hr = IDirect3DDevice9_EndScene(device);
6688 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
6691 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6692 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
6693 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6694 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
6695 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6696 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
6697 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6698 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
6699 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6700 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
6701 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6702 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
6703 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6705 /* 2nd pass: Make the stencil values visible */
6706 hr = IDirect3DDevice9_BeginScene(device);
6707 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
6708 if(SUCCEEDED(hr))
6710 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6711 for(i = 0; i < 16; i++) {
6712 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
6713 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6715 painter[0].diffuse = (i * 16); /* Creates shades of blue */
6716 painter[1].diffuse = (i * 16);
6717 painter[2].diffuse = (i * 16);
6718 painter[3].diffuse = (i * 16);
6719 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
6720 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6722 hr = IDirect3DDevice9_EndScene(device);
6723 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
6726 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6727 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6729 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
6730 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6732 color = getPixelColor(device, 160, 420);
6733 ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
6734 color = getPixelColor(device, 160, 300);
6735 ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
6737 color = getPixelColor(device, 480, 420);
6738 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
6739 color = getPixelColor(device, 480, 300);
6740 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
6742 color = getPixelColor(device, 160, 180);
6743 ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
6744 color = getPixelColor(device, 160, 60);
6745 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
6747 color = getPixelColor(device, 480, 180);
6748 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
6749 color = getPixelColor(device, 480, 60);
6750 ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
6753 START_TEST(visual)
6755 IDirect3DDevice9 *device_ptr;
6756 D3DCAPS9 caps;
6757 HRESULT hr;
6758 DWORD color;
6760 d3d9_handle = LoadLibraryA("d3d9.dll");
6761 if (!d3d9_handle)
6763 skip("Could not load d3d9.dll\n");
6764 return;
6767 device_ptr = init_d3d9();
6768 if (!device_ptr)
6770 skip("Creating the device failed\n");
6771 return;
6774 IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
6776 /* Check for the reliability of the returned data */
6777 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6778 if(FAILED(hr))
6780 trace("Clear failed, can't assure correctness of the test results, skipping\n");
6781 goto cleanup;
6783 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
6785 color = getPixelColor(device_ptr, 1, 1);
6786 if(color !=0x00ff0000)
6788 trace("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
6789 goto cleanup;
6792 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
6793 if(FAILED(hr))
6795 trace("Clear failed, can't assure correctness of the test results, skipping\n");
6796 goto cleanup;
6798 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
6800 color = getPixelColor(device_ptr, 639, 479);
6801 if(color != 0x0000ddee)
6803 trace("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
6804 goto cleanup;
6807 /* Now execute the real tests */
6808 lighting_test(device_ptr);
6809 clear_test(device_ptr);
6810 fog_test(device_ptr);
6811 if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
6813 test_cube_wrap(device_ptr);
6814 } else {
6815 skip("No cube texture support\n");
6817 z_range_test(device_ptr);
6818 if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
6820 maxmip_test(device_ptr);
6822 else
6824 skip("No mipmap support\n");
6826 offscreen_test(device_ptr);
6827 alpha_test(device_ptr);
6828 release_buffer_test(device_ptr);
6829 float_texture_test(device_ptr);
6830 g16r16_texture_test(device_ptr);
6831 texture_transform_flags_test(device_ptr);
6832 autogen_mipmap_test(device_ptr);
6833 fixed_function_decl_test(device_ptr);
6834 conditional_np2_repeat_test(device_ptr);
6835 fixed_function_bumpmap_test(device_ptr);
6836 if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
6837 stencil_cull_test(device_ptr);
6838 } else {
6839 skip("No two sided stencil support\n");
6842 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
6844 test_constant_clamp_vs(device_ptr);
6845 test_compare_instructions(device_ptr);
6847 else skip("No vs_1_1 support\n");
6849 if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
6851 test_mova(device_ptr);
6852 if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
6853 test_vshader_input(device_ptr);
6854 test_vshader_float16(device_ptr);
6855 } else {
6856 skip("No vs_3_0 support\n");
6859 else skip("No vs_2_0 support\n");
6861 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
6863 fog_with_shader_test(device_ptr);
6864 fog_srgbwrite_test(device_ptr);
6866 else skip("No vs_1_1 and ps_1_1 support\n");
6868 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
6870 texbem_test(device_ptr);
6871 texdepth_test(device_ptr);
6872 texkill_test(device_ptr);
6873 x8l8v8u8_test(device_ptr);
6874 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
6875 constant_clamp_ps_test(device_ptr);
6876 cnd_test(device_ptr);
6877 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) {
6878 nested_loop_test(device_ptr);
6879 fixed_function_varying_test(device_ptr);
6880 vFace_register_test(device_ptr);
6881 if(caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
6882 vshader_version_varying_test(device_ptr);
6883 pshader_version_varying_test(device_ptr);
6884 } else {
6885 skip("No vs_3_0 support\n");
6887 } else {
6888 skip("No ps_3_0 support\n");
6892 else skip("No ps_1_1 support\n");
6894 cleanup:
6895 if(device_ptr) {
6896 ULONG ref;
6898 D3DPRESENT_PARAMETERS present_parameters;
6899 IDirect3DSwapChain9 *swapchain;
6900 IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
6901 IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
6902 IDirect3DSwapChain9_Release(swapchain);
6903 ref = IDirect3DDevice9_Release(device_ptr);
6904 DestroyWindow(present_parameters.hDeviceWindow);
6905 ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);