d3d9: Add stream_test with instancing.
[wine/wine64.git] / dlls / d3d9 / tests / visual.c
blobfc78f7a24866d00ece9a42cf43a9845eaa55dc16
1 /*
2 * Copyright 2005, 2007 Henri Verbeet
3 * Copyright (C) 2007-2008 Stefan Dösinger(for CodeWeavers)
4 * Copyright (C) 2008 Jason Green(for TransGaming)
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 /* This test framework allows limited testing of rendering results. Things are rendered, shown on
22 * the framebuffer, read back from there and compared to expected colors.
24 * However, neither d3d nor opengl is guaranteed to be pixel exact, and thus the capability of this test
25 * is rather limited. As a general guideline for adding tests, do not rely on corner pixels. Draw a big enough
26 * area which shows specific behavior(like a quad on the whole screen), and try to get resulting colors with
27 * all bits set or unset in all channels(like pure red, green, blue, white, black). Hopefully everything that
28 * causes visible results in games can be tested in a way that does not depend on pixel exactness
31 #define COBJMACROS
32 #include <d3d9.h>
33 #include <dxerr9.h>
34 #include "wine/test.h"
36 static HMODULE d3d9_handle = 0;
38 static HWND create_window(void)
40 WNDCLASS wc = {0};
41 HWND ret;
42 wc.lpfnWndProc = &DefWindowProc;
43 wc.lpszClassName = "d3d9_test_wc";
44 RegisterClass(&wc);
46 ret = CreateWindow("d3d9_test_wc", "d3d9_test",
47 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
48 return ret;
51 /* Locks a given surface and returns the color at (x,y). It's the caller's
52 * responsibility to only pass in lockable surfaces and valid x,y coordinates */
53 static DWORD getPixelColorFromSurface(IDirect3DSurface9 *surface, UINT x, UINT y)
55 DWORD color;
56 HRESULT hr;
57 D3DSURFACE_DESC desc;
58 RECT rectToLock = {x, y, x+1, y+1};
59 D3DLOCKED_RECT lockedRect;
61 hr = IDirect3DSurface9_GetDesc(surface, &desc);
62 if(FAILED(hr)) /* This is not a test */
64 trace("Can't get the surface description, hr=%s\n", DXGetErrorString9(hr));
65 return 0xdeadbeef;
68 hr = IDirect3DSurface9_LockRect(surface, &lockedRect, &rectToLock, D3DLOCK_READONLY);
69 if(FAILED(hr)) /* This is not a test */
71 trace("Can't lock the surface, hr=%s\n", DXGetErrorString9(hr));
72 return 0xdeadbeef;
74 switch(desc.Format) {
75 case D3DFMT_A8R8G8B8:
77 color = ((DWORD *) lockedRect.pBits)[0] & 0xffffffff;
78 break;
80 default:
81 trace("Error: unknown surface format: %d\n", desc.Format);
82 color = 0xdeadbeef;
83 break;
85 hr = IDirect3DSurface9_UnlockRect(surface);
86 if(FAILED(hr))
88 trace("Can't unlock the surface, hr=%s\n", DXGetErrorString9(hr));
90 return color;
93 static DWORD getPixelColor(IDirect3DDevice9 *device, UINT x, UINT y)
95 DWORD ret;
96 IDirect3DSurface9 *surf;
97 HRESULT hr;
98 D3DLOCKED_RECT lockedRect;
99 RECT rectToLock = {x, y, x+1, y+1};
101 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 640, 480, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf, NULL);
102 if(FAILED(hr) || !surf ) /* This is not a test */
104 trace("Can't create an offscreen plain surface to read the render target data, hr=%s\n", DXGetErrorString9(hr));
105 return 0xdeadbeef;
108 hr = IDirect3DDevice9_GetFrontBufferData(device, 0, surf);
109 if(FAILED(hr))
111 trace("Can't read the front buffer data, hr=%s\n", DXGetErrorString9(hr));
112 ret = 0xdeadbeed;
113 goto out;
116 hr = IDirect3DSurface9_LockRect(surf, &lockedRect, &rectToLock, D3DLOCK_READONLY);
117 if(FAILED(hr))
119 trace("Can't lock the offscreen surface, hr=%s\n", DXGetErrorString9(hr));
120 ret = 0xdeadbeec;
121 goto out;
124 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
125 * really important for these tests
127 ret = ((DWORD *) lockedRect.pBits)[0] & 0x00ffffff;
128 hr = IDirect3DSurface9_UnlockRect(surf);
129 if(FAILED(hr))
131 trace("Can't unlock the offscreen surface, hr=%s\n", DXGetErrorString9(hr));
134 out:
135 if(surf) IDirect3DSurface9_Release(surf);
136 return ret;
139 static IDirect3DDevice9 *init_d3d9(void)
141 IDirect3D9 * (__stdcall * d3d9_create)(UINT SDKVersion) = 0;
142 IDirect3D9 *d3d9_ptr = 0;
143 IDirect3DDevice9 *device_ptr = 0;
144 D3DPRESENT_PARAMETERS present_parameters;
145 HRESULT hr;
147 d3d9_create = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9");
148 ok(d3d9_create != NULL, "Failed to get address of Direct3DCreate9\n");
149 if (!d3d9_create) return NULL;
151 d3d9_ptr = d3d9_create(D3D_SDK_VERSION);
152 ok(d3d9_ptr != NULL, "Failed to create IDirect3D9 object\n");
153 if (!d3d9_ptr) return NULL;
155 ZeroMemory(&present_parameters, sizeof(present_parameters));
156 present_parameters.Windowed = FALSE;
157 present_parameters.hDeviceWindow = create_window();
158 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
159 present_parameters.BackBufferWidth = 640;
160 present_parameters.BackBufferHeight = 480;
161 present_parameters.BackBufferFormat = D3DFMT_X8R8G8B8;
162 present_parameters.EnableAutoDepthStencil = TRUE;
163 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
165 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
166 if(FAILED(hr)) {
167 present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
168 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
169 if(FAILED(hr)) {
170 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
173 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D_CreateDevice returned: %s\n", DXGetErrorString9(hr));
175 return device_ptr;
178 struct vertex
180 float x, y, z;
181 DWORD diffuse;
184 struct tvertex
186 float x, y, z, rhw;
187 DWORD diffuse;
190 struct nvertex
192 float x, y, z;
193 float nx, ny, nz;
194 DWORD diffuse;
197 static void lighting_test(IDirect3DDevice9 *device)
199 HRESULT hr;
200 DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
201 DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
202 DWORD color;
204 float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
205 0.0f, 1.0f, 0.0f, 0.0f,
206 0.0f, 0.0f, 1.0f, 0.0f,
207 0.0f, 0.0f, 0.0f, 1.0f };
209 struct vertex unlitquad[] =
211 {-1.0f, -1.0f, 0.1f, 0xffff0000},
212 {-1.0f, 0.0f, 0.1f, 0xffff0000},
213 { 0.0f, 0.0f, 0.1f, 0xffff0000},
214 { 0.0f, -1.0f, 0.1f, 0xffff0000},
216 struct vertex litquad[] =
218 {-1.0f, 0.0f, 0.1f, 0xff00ff00},
219 {-1.0f, 1.0f, 0.1f, 0xff00ff00},
220 { 0.0f, 1.0f, 0.1f, 0xff00ff00},
221 { 0.0f, 0.0f, 0.1f, 0xff00ff00},
223 struct nvertex unlitnquad[] =
225 { 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
226 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
227 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
228 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
230 struct nvertex litnquad[] =
232 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
233 { 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
234 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
235 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
237 WORD Indices[] = {0, 1, 2, 2, 3, 0};
239 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
240 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
242 /* Setup some states that may cause issues */
243 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
244 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %s\n", DXGetErrorString9(hr));
245 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
246 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %s\n", DXGetErrorString9(hr));
247 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
248 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %s\n", DXGetErrorString9(hr));
249 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
250 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
251 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
252 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
253 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
254 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
255 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
256 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
257 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
258 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
259 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
260 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
261 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
262 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
263 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
264 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %s\n", DXGetErrorString9(hr));
265 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
266 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %s\n", DXGetErrorString9(hr));
268 hr = IDirect3DDevice9_SetFVF(device, fvf);
269 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
271 hr = IDirect3DDevice9_BeginScene(device);
272 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
273 if(hr == D3D_OK)
275 /* No lights are defined... That means, lit vertices should be entirely black */
276 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
277 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
278 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
279 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
280 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
282 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
283 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
284 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
285 2 /*PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
286 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
288 hr = IDirect3DDevice9_SetFVF(device, nfvf);
289 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
291 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
292 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
293 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
294 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
295 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
297 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
298 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
299 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
300 2 /*PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
301 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
303 IDirect3DDevice9_EndScene(device);
304 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
307 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
309 color = getPixelColor(device, 160, 360); /* lower left quad - unlit without normals */
310 ok(color == 0x00ff0000, "Unlit quad without normals has color %08x\n", color);
311 color = getPixelColor(device, 160, 120); /* upper left quad - lit without normals */
312 ok(color == 0x00000000, "Lit quad without normals has color %08x\n", color);
313 color = getPixelColor(device, 480, 360); /* lower left quad - unlit with normals */
314 ok(color == 0x000000ff, "Unlit quad with normals has color %08x\n", color);
315 color = getPixelColor(device, 480, 120); /* upper left quad - lit with normals */
316 ok(color == 0x00000000, "Lit quad with normals has color %08x\n", color);
318 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
319 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
322 static void clear_test(IDirect3DDevice9 *device)
324 /* Tests the correctness of clearing parameters */
325 HRESULT hr;
326 D3DRECT rect[2];
327 D3DRECT rect_negneg;
328 DWORD color;
329 D3DVIEWPORT9 old_vp, vp;
330 RECT scissor;
331 DWORD oldColorWrite;
332 BOOL invalid_clear_failed = FALSE;
334 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
335 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
337 /* Positive x, negative y */
338 rect[0].x1 = 0;
339 rect[0].y1 = 480;
340 rect[0].x2 = 320;
341 rect[0].y2 = 240;
343 /* Positive x, positive y */
344 rect[1].x1 = 0;
345 rect[1].y1 = 0;
346 rect[1].x2 = 320;
347 rect[1].y2 = 240;
348 /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
349 * returns D3D_OK, but ignores the rectangle silently
351 hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
352 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
353 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
355 /* negative x, negative y */
356 rect_negneg.x1 = 640;
357 rect_negneg.y1 = 240;
358 rect_negneg.x2 = 320;
359 rect_negneg.y2 = 0;
360 hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
361 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
362 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
364 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
366 color = getPixelColor(device, 160, 360); /* lower left quad */
367 ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
368 color = getPixelColor(device, 160, 120); /* upper left quad */
369 if(invalid_clear_failed) {
370 /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
371 ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
372 } else {
373 /* If the negative rectangle was dropped silently, the correct ones are cleared */
374 ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
376 color = getPixelColor(device, 480, 360); /* lower right quad */
377 ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
378 color = getPixelColor(device, 480, 120); /* upper right quad */
379 ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
381 /* Test how the viewport affects clears */
382 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
383 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
384 hr = IDirect3DDevice9_GetViewport(device, &old_vp);
385 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %s\n", DXGetErrorString9(hr));
387 vp.X = 160;
388 vp.Y = 120;
389 vp.Width = 160;
390 vp.Height = 120;
391 vp.MinZ = 0.0;
392 vp.MaxZ = 1.0;
393 hr = IDirect3DDevice9_SetViewport(device, &vp);
394 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %s\n", DXGetErrorString9(hr));
395 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
396 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
398 vp.X = 320;
399 vp.Y = 240;
400 vp.Width = 320;
401 vp.Height = 240;
402 vp.MinZ = 0.0;
403 vp.MaxZ = 1.0;
404 hr = IDirect3DDevice9_SetViewport(device, &vp);
405 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %s\n", DXGetErrorString9(hr));
406 rect[0].x1 = 160;
407 rect[0].y1 = 120;
408 rect[0].x2 = 480;
409 rect[0].y2 = 360;
410 hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
411 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
413 hr = IDirect3DDevice9_SetViewport(device, &old_vp);
414 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %s\n", DXGetErrorString9(hr));
416 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
417 color = getPixelColor(device, 158, 118);
418 ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
419 color = getPixelColor(device, 162, 118);
420 ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
421 color = getPixelColor(device, 158, 122);
422 ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
423 color = getPixelColor(device, 162, 122);
424 ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
426 color = getPixelColor(device, 318, 238);
427 ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
428 color = getPixelColor(device, 322, 238);
429 ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
430 color = getPixelColor(device, 318, 242);
431 ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
432 color = getPixelColor(device, 322, 242);
433 ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
435 color = getPixelColor(device, 478, 358);
436 ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
437 color = getPixelColor(device, 482, 358);
438 ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
439 color = getPixelColor(device, 478, 362);
440 ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
441 color = getPixelColor(device, 482, 362);
442 ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
444 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
445 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
447 scissor.left = 160;
448 scissor.right = 480;
449 scissor.top = 120;
450 scissor.bottom = 360;
451 hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
452 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %s\n", DXGetErrorString9(hr));
453 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
454 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %s\n", DXGetErrorString9(hr));
456 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
457 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
458 hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
459 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
461 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
462 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %s\n", DXGetErrorString9(hr));
464 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
465 color = getPixelColor(device, 158, 118);
466 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
467 color = getPixelColor(device, 162, 118);
468 ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
469 color = getPixelColor(device, 158, 122);
470 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
471 color = getPixelColor(device, 162, 122);
472 ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
474 color = getPixelColor(device, 158, 358);
475 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
476 color = getPixelColor(device, 162, 358);
477 ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
478 color = getPixelColor(device, 158, 358);
479 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
480 color = getPixelColor(device, 162, 362);
481 ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
483 color = getPixelColor(device, 478, 118);
484 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
485 color = getPixelColor(device, 478, 122);
486 ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
487 color = getPixelColor(device, 482, 122);
488 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
489 color = getPixelColor(device, 482, 358);
490 ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
492 color = getPixelColor(device, 478, 358);
493 ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
494 color = getPixelColor(device, 478, 362);
495 ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
496 color = getPixelColor(device, 482, 358);
497 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
498 color = getPixelColor(device, 482, 362);
499 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
501 color = getPixelColor(device, 318, 238);
502 ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
503 color = getPixelColor(device, 318, 242);
504 ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
505 color = getPixelColor(device, 322, 238);
506 ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
507 color = getPixelColor(device, 322, 242);
508 ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
510 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
511 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %s\n", DXGetErrorString9(hr));
512 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
513 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %s\n", DXGetErrorString9(hr));
515 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
516 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
518 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
519 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %s\n", DXGetErrorString9(hr));
521 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
523 /* Colorwriteenable does not affect the clear */
524 color = getPixelColor(device, 320, 240);
525 ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
528 typedef struct {
529 float in[4];
530 DWORD out;
531 } test_data_t;
534 * c7 mova ARGB mov ARGB
535 * -2.4 -2 0x00ffff00 -3 0x00ff0000
536 * -1.6 -2 0x00ffff00 -2 0x00ffff00
537 * -0.4 0 0x0000ffff -1 0x0000ff00
538 * 0.4 0 0x0000ffff 0 0x0000ffff
539 * 1.6 2 0x00ff00ff 1 0x000000ff
540 * 2.4 2 0x00ff00ff 2 0x00ff00ff
542 static void test_mova(IDirect3DDevice9 *device)
544 static const DWORD mova_test[] = {
545 0xfffe0200, /* vs_2_0 */
546 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
547 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
548 0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
549 0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
550 0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
551 0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
552 0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
553 0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
554 0x0200002e, 0xb0010000, 0xa0000007, /* mova a0.x, c7.x */
555 0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000, /* mov oD0, c[a0.x + 3] */
556 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
557 0x0000ffff /* END */
559 static const DWORD mov_test[] = {
560 0xfffe0101, /* vs_1_1 */
561 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
562 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
563 0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
564 0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
565 0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
566 0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
567 0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
568 0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
569 0x00000001, 0xb0010000, 0xa0000007, /* mov a0.x, c7.x */
570 0x00000001, 0xd00f0000, 0xa0e42003, /* mov oD0, c[a0.x + 3] */
571 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
572 0x0000ffff /* END */
575 static const test_data_t test_data[2][6] = {
577 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
578 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
579 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
580 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
581 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
582 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
585 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
586 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
587 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
588 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
589 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
590 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
594 static const float quad[][3] = {
595 {-1.0f, -1.0f, 0.0f},
596 {-1.0f, 1.0f, 0.0f},
597 { 1.0f, -1.0f, 0.0f},
598 { 1.0f, 1.0f, 0.0f},
601 static const D3DVERTEXELEMENT9 decl_elements[] = {
602 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
603 D3DDECL_END()
606 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
607 IDirect3DVertexShader9 *mova_shader = NULL;
608 IDirect3DVertexShader9 *mov_shader = NULL;
609 HRESULT hr;
610 UINT i, j;
612 hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
613 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
614 hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
615 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
616 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
617 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
618 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
619 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
621 hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
622 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
623 for(j = 0; j < 2; ++j)
625 for (i = 0; i < (sizeof(test_data[0]) / sizeof(test_data_t)); ++i)
627 DWORD color;
629 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
630 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
632 hr = IDirect3DDevice9_BeginScene(device);
633 ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
635 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
636 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
638 hr = IDirect3DDevice9_EndScene(device);
639 ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
641 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
642 ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
644 color = getPixelColor(device, 320, 240);
645 ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
646 test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
648 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
649 ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
651 hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
652 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
655 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
656 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
658 IDirect3DVertexDeclaration9_Release(vertex_declaration);
659 IDirect3DVertexShader9_Release(mova_shader);
660 IDirect3DVertexShader9_Release(mov_shader);
663 struct sVertex {
664 float x, y, z;
665 DWORD diffuse;
666 DWORD specular;
669 struct sVertexT {
670 float x, y, z, rhw;
671 DWORD diffuse;
672 DWORD specular;
675 static void fog_test(IDirect3DDevice9 *device)
677 HRESULT hr;
678 DWORD color;
679 BYTE r, g, b;
680 float start = 0.0f, end = 1.0f;
681 D3DCAPS9 caps;
682 int i;
684 /* Gets full z based fog with linear fog, no fog with specular color */
685 struct sVertex unstransformed_1[] = {
686 {-1, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
687 {-1, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
688 { 0, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
689 { 0, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
691 /* Ok, I am too lazy to deal with transform matrices */
692 struct sVertex unstransformed_2[] = {
693 {-1, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
694 {-1, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
695 { 0, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
696 { 0, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
698 /* Untransformed ones. Give them a different diffuse color to make the test look
699 * nicer. It also makes making sure that they are drawn correctly easier.
701 struct sVertexT transformed_1[] = {
702 {320, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
703 {640, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
704 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
705 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
707 struct sVertexT transformed_2[] = {
708 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
709 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
710 {640, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
711 {320, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
713 struct vertex rev_fog_quads[] = {
714 {-1.0, -1.0, 0.1, 0x000000ff},
715 {-1.0, 0.0, 0.1, 0x000000ff},
716 { 0.0, 0.0, 0.1, 0x000000ff},
717 { 0.0, -1.0, 0.1, 0x000000ff},
719 { 0.0, -1.0, 0.9, 0x000000ff},
720 { 0.0, 0.0, 0.9, 0x000000ff},
721 { 1.0, 0.0, 0.9, 0x000000ff},
722 { 1.0, -1.0, 0.9, 0x000000ff},
724 { 0.0, 0.0, 0.4, 0x000000ff},
725 { 0.0, 1.0, 0.4, 0x000000ff},
726 { 1.0, 1.0, 0.4, 0x000000ff},
727 { 1.0, 0.0, 0.4, 0x000000ff},
729 {-1.0, 0.0, 0.7, 0x000000ff},
730 {-1.0, 1.0, 0.7, 0x000000ff},
731 { 0.0, 1.0, 0.7, 0x000000ff},
732 { 0.0, 0.0, 0.7, 0x000000ff},
734 WORD Indices[] = {0, 1, 2, 2, 3, 0};
736 memset(&caps, 0, sizeof(caps));
737 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
738 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %s\n", DXGetErrorString9(hr));
739 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
740 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
742 /* Setup initial states: No lighting, fog on, fog color */
743 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
744 ok(hr == D3D_OK, "Turning off lighting returned %s\n", DXGetErrorString9(hr));
745 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
746 ok(hr == D3D_OK, "Turning on fog calculations returned %s\n", DXGetErrorString9(hr));
747 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
748 ok(hr == D3D_OK, "Turning on fog calculations returned %s\n", DXGetErrorString9(hr));
750 /* First test: Both table fog and vertex fog off */
751 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
752 ok(hr == D3D_OK, "Turning off table fog returned %s\n", DXGetErrorString9(hr));
753 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
754 ok(hr == D3D_OK, "Turning off table fog returned %s\n", DXGetErrorString9(hr));
756 /* Start = 0, end = 1. Should be default, but set them */
757 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
758 ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
759 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
760 ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
762 if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
764 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
765 ok( hr == D3D_OK, "SetFVF returned %s\n", DXGetErrorString9(hr));
766 /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
767 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
768 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
769 sizeof(unstransformed_1[0]));
770 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
772 /* That makes it use the Z value */
773 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
774 ok(hr == D3D_OK, "Turning off table fog returned %s\n", DXGetErrorString9(hr));
775 /* Untransformed, vertex fog != none (or table fog != none):
776 * Use the Z value as input into the equation
778 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
779 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
780 sizeof(unstransformed_1[0]));
781 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
783 /* transformed verts */
784 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
785 ok( hr == D3D_OK, "SetFVF returned %s\n", DXGetErrorString9(hr));
786 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
787 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
788 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
789 sizeof(transformed_1[0]));
790 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
792 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
793 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %s\n", DXGetErrorString9(hr));
794 /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
795 * equation
797 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
798 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
799 sizeof(transformed_2[0]));
801 hr = IDirect3DDevice9_EndScene(device);
802 ok(hr == D3D_OK, "EndScene returned %s\n", DXGetErrorString9(hr));
804 else
806 ok(FALSE, "BeginScene failed\n");
809 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
810 color = getPixelColor(device, 160, 360);
811 ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
812 color = getPixelColor(device, 160, 120);
813 ok(color == 0x0000FF00 || color == 0x0000FE00, "Untransformed vertex with linear vertex fog has color %08x\n", color);
814 color = getPixelColor(device, 480, 120);
815 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
816 if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
818 color = getPixelColor(device, 480, 360);
819 ok(color == 0x0000FF00 || color == 0x0000FE00, "Transformed vertex with linear table fog has color %08x\n", color);
821 else
823 /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
824 * The settings above result in no fogging with vertex fog
826 color = getPixelColor(device, 480, 120);
827 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
828 trace("Info: Table fog not supported by this device\n");
831 /* Now test the special case fogstart == fogend */
832 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
833 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
835 if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
837 start = 512;
838 end = 512;
839 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
840 ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
841 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
842 ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
844 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
845 ok( hr == D3D_OK, "SetFVF returned %s\n", DXGetErrorString9(hr));
846 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
847 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %s\n", DXGetErrorString9(hr));
848 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
849 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %s\n", DXGetErrorString9(hr));
851 /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
852 * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
853 * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
854 * The third transformed quad remains unfogged because the fogcoords are read from the specular
855 * color and has fixed fogstart and fogend.
857 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
858 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
859 sizeof(unstransformed_1[0]));
860 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
861 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
862 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
863 sizeof(unstransformed_1[0]));
864 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
866 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
867 ok( hr == D3D_OK, "SetFVF returned %s\n", DXGetErrorString9(hr));
868 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
869 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
870 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
871 sizeof(transformed_1[0]));
872 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
874 hr = IDirect3DDevice9_EndScene(device);
875 ok(hr == D3D_OK, "EndScene returned %s\n", DXGetErrorString9(hr));
877 else
879 ok(FALSE, "BeginScene failed\n");
881 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
882 color = getPixelColor(device, 160, 360);
883 ok(color == 0x0000FF00 || color == 0x0000FE00, "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
884 color = getPixelColor(device, 160, 120);
885 ok(color == 0x0000FF00 || color == 0x0000FE00, "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
886 color = getPixelColor(device, 480, 120);
887 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
889 /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
890 * but without shaders it seems to work everywhere
892 end = 0.2;
893 start = 0.8;
894 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
895 ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
896 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
897 ok(hr == D3D_OK, "Setting fog end returned %s\n", DXGetErrorString9(hr));
898 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
899 ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
901 /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
902 * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
903 * so skip this for now
905 for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
906 const char *mode = (i ? "table" : "vertex");
907 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
908 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
909 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
910 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
911 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
912 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
913 hr = IDirect3DDevice9_BeginScene(device);
914 ok( hr == D3D_OK, "IDirect3DDDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
915 if(SUCCEEDED(hr)) {
916 WORD Indices2[] = { 0, 1, 2, 2, 3, 0,
917 4, 5, 6, 6, 7, 4,
918 8, 9, 10, 10, 11, 8,
919 12, 13, 14, 14, 15, 12};
921 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */,
922 16 /* NumVerts */, 8 /*PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads,
923 sizeof(rev_fog_quads[0]));
925 hr = IDirect3DDevice9_EndScene(device);
926 ok( hr == D3D_OK, "IDirect3DDDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
928 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
929 color = getPixelColor(device, 160, 360);
930 ok(color == 0x0000FF00 || color == 0x0000FE00, "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00\n", mode, color);
932 color = getPixelColor(device, 160, 120);
933 r = (color & 0x00ff0000) >> 16;
934 g = (color & 0x0000ff00) >> 8;
935 b = (color & 0x000000ff);
936 ok(r == 0x00 && g >= 0x29 && g <= 0x2d && b >= 0xd2 && b <= 0xd6,
937 "Reversed %s fog: z=0.7 has color 0x%08x, expected\n", mode, color);
939 color = getPixelColor(device, 480, 120);
940 r = (color & 0x00ff0000) >> 16;
941 g = (color & 0x0000ff00) >> 8;
942 b = (color & 0x000000ff);
943 ok(r == 0x00 && g >= 0xa8 && g <= 0xac && b >= 0x53 && b <= 0x57,
944 "Reversed %s fog: z=0.4 has color 0x%08x, expected\n", mode, color);
946 color = getPixelColor(device, 480, 360);
947 ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
949 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
950 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
951 break;
954 /* Turn off the fog master switch to avoid confusing other tests */
955 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
956 ok(hr == D3D_OK, "Turning off fog calculations returned %s\n", DXGetErrorString9(hr));
957 start = 0.0;
958 end = 1.0;
959 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
960 ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
961 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
962 ok(hr == D3D_OK, "Setting fog end returned %s\n", DXGetErrorString9(hr));
963 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
964 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %s\n", DXGetErrorString9(hr));
965 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
966 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %s\n", DXGetErrorString9(hr));
969 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
970 * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
971 * regardless of the actual addressing mode set. */
972 static void test_cube_wrap(IDirect3DDevice9 *device)
974 static const float quad[][6] = {
975 {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
976 {-1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
977 { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
978 { 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
981 static const D3DVERTEXELEMENT9 decl_elements[] = {
982 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
983 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
984 D3DDECL_END()
987 static const struct {
988 D3DTEXTUREADDRESS mode;
989 const char *name;
990 } address_modes[] = {
991 {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
992 {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
993 {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
994 {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
995 {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
998 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
999 IDirect3DCubeTexture9 *texture = NULL;
1000 IDirect3DSurface9 *surface = NULL;
1001 D3DLOCKED_RECT locked_rect;
1002 HRESULT hr;
1003 UINT x;
1004 INT y, face;
1006 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1007 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1008 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1009 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1011 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
1012 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1013 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
1015 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
1016 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1018 for (y = 0; y < 128; ++y)
1020 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1021 for (x = 0; x < 64; ++x)
1023 *ptr++ = 0xffff0000;
1025 for (x = 64; x < 128; ++x)
1027 *ptr++ = 0xff0000ff;
1031 hr = IDirect3DSurface9_UnlockRect(surface);
1032 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1034 hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
1035 D3DPOOL_DEFAULT, &texture, NULL);
1036 ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
1038 /* Create cube faces */
1039 for (face = 0; face < 6; ++face)
1041 IDirect3DSurface9 *face_surface = NULL;
1043 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
1044 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
1046 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
1047 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
1049 IDirect3DSurface9_Release(face_surface);
1052 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
1053 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1055 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
1056 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1057 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
1058 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1059 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
1060 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
1062 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1063 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1065 for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
1067 DWORD color;
1069 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
1070 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1071 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
1072 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
1074 hr = IDirect3DDevice9_BeginScene(device);
1075 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1077 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1078 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1080 hr = IDirect3DDevice9_EndScene(device);
1081 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1083 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1084 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1086 /* Due to the nature of this test, we sample essentially at the edge
1087 * between two faces. Because of this it's undefined from which face
1088 * the driver will sample. Fortunately that's not important for this
1089 * test, since all we care about is that it doesn't sample from the
1090 * other side of the surface or from the border. */
1091 color = getPixelColor(device, 320, 240);
1092 ok(color == 0x00ff0000 || color == 0x000000ff,
1093 "Got color 0x%08x for addressing mode %s, expected 0x00ff0000 or 0x000000ff.\n",
1094 color, address_modes[x].name);
1096 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1097 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1100 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1101 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1103 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1104 IDirect3DCubeTexture9_Release(texture);
1105 IDirect3DSurface9_Release(surface);
1108 static void offscreen_test(IDirect3DDevice9 *device)
1110 HRESULT hr;
1111 IDirect3DTexture9 *offscreenTexture = NULL;
1112 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
1113 DWORD color;
1115 static const float quad[][5] = {
1116 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
1117 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
1118 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
1119 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
1122 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1123 ok(hr == D3D_OK, "Clear failed, hr = %s\n", DXGetErrorString9(hr));
1125 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1126 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %s\n", DXGetErrorString9(hr));
1127 if(!offscreenTexture) {
1128 trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
1129 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
1130 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %s\n", DXGetErrorString9(hr));
1131 if(!offscreenTexture) {
1132 skip("Cannot create an offscreen render target\n");
1133 goto out;
1137 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1138 ok(hr == D3D_OK, "Can't get back buffer, hr = %s\n", DXGetErrorString9(hr));
1139 if(!backbuffer) {
1140 goto out;
1143 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
1144 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %s\n", DXGetErrorString9(hr));
1145 if(!offscreen) {
1146 goto out;
1149 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1150 ok(hr == D3D_OK, "SetFVF failed, hr = %s\n", DXGetErrorString9(hr));
1152 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
1153 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
1154 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
1155 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
1156 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1157 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1158 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1159 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1160 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1161 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1163 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
1164 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
1165 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %s\n", DXGetErrorString9(hr));
1166 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1167 ok(hr == D3D_OK, "Clear failed, hr = %s\n", DXGetErrorString9(hr));
1169 /* Draw without textures - Should result in a white quad */
1170 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1171 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %s\n", DXGetErrorString9(hr));
1173 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1174 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %s\n", DXGetErrorString9(hr));
1175 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
1176 ok(hr == D3D_OK, "SetTexture failed, %s\n", DXGetErrorString9(hr));
1178 /* This time with the texture */
1179 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
1180 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %s\n", DXGetErrorString9(hr));
1182 IDirect3DDevice9_EndScene(device);
1185 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1187 /* Center quad - should be white */
1188 color = getPixelColor(device, 320, 240);
1189 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1190 /* Some quad in the cleared part of the texture */
1191 color = getPixelColor(device, 170, 240);
1192 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
1193 /* Part of the originally cleared back buffer */
1194 color = getPixelColor(device, 10, 10);
1195 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1196 if(0) {
1197 /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
1198 * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
1199 * the offscreen rendering mode this test would succeed or fail
1201 color = getPixelColor(device, 10, 470);
1202 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1205 out:
1206 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1208 /* restore things */
1209 if(backbuffer) {
1210 IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1211 IDirect3DSurface9_Release(backbuffer);
1213 if(offscreenTexture) {
1214 IDirect3DTexture9_Release(offscreenTexture);
1216 if(offscreen) {
1217 IDirect3DSurface9_Release(offscreen);
1221 /* This test tests fog in combination with shaders.
1222 * What's tested: linear fog (vertex and table) with pixel shader
1223 * linear table fog with non foggy vertex shader
1224 * vertex fog with foggy vertex shader
1225 * What's not tested: non linear fog with shader
1226 * table fog with foggy vertex shader
1228 static void fog_with_shader_test(IDirect3DDevice9 *device)
1230 HRESULT hr;
1231 DWORD color;
1232 union {
1233 float f;
1234 DWORD i;
1235 } start, end;
1236 unsigned int i, j;
1238 /* basic vertex shader without fog computation ("non foggy") */
1239 static const DWORD vertex_shader_code1[] = {
1240 0xfffe0101, /* vs_1_1 */
1241 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1242 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1243 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1244 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1245 0x0000ffff
1247 /* basic vertex shader with reversed fog computation ("foggy") */
1248 static const DWORD vertex_shader_code2[] = {
1249 0xfffe0101, /* vs_1_1 */
1250 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1251 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
1252 0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
1253 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1254 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1255 0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
1256 0x00000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
1257 0x0000ffff
1259 /* basic pixel shader */
1260 static const DWORD pixel_shader_code[] = {
1261 0xffff0101, /* ps_1_1 */
1262 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, vo */
1263 0x0000ffff
1266 static struct vertex quad[] = {
1267 {-1.0f, -1.0f, 0.0f, 0xFFFF0000 },
1268 {-1.0f, 1.0f, 0.0f, 0xFFFF0000 },
1269 { 1.0f, -1.0f, 0.0f, 0xFFFF0000 },
1270 { 1.0f, 1.0f, 0.0f, 0xFFFF0000 },
1273 static const D3DVERTEXELEMENT9 decl_elements[] = {
1274 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1275 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
1276 D3DDECL_END()
1279 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1280 IDirect3DVertexShader9 *vertex_shader[3] = {NULL, NULL, NULL};
1281 IDirect3DPixelShader9 *pixel_shader[2] = {NULL, NULL};
1283 /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
1284 static const struct test_data_t {
1285 int vshader;
1286 int pshader;
1287 D3DFOGMODE vfog;
1288 D3DFOGMODE tfog;
1289 unsigned int color[11];
1290 } test_data[] = {
1291 /* only pixel shader: */
1292 {0, 1, 0, 3,
1293 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1294 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1295 {0, 1, 1, 3,
1296 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1297 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1298 {0, 1, 2, 3,
1299 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1300 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1301 {0, 1, 3, 0,
1302 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1303 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1304 {0, 1, 3, 3,
1305 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1306 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1308 /* vertex shader */
1309 {1, 0, 0, 0,
1310 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1311 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1312 {1, 0, 0, 3,
1313 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1314 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1315 {1, 0, 1, 3,
1316 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1317 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1319 {1, 0, 2, 3,
1320 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1321 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1322 {1, 0, 3, 3,
1323 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1324 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1326 /* vertex shader and pixel shader */
1327 {1, 1, 0, 3,
1328 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1329 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1330 {1, 1, 1, 3,
1331 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1332 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1333 {1, 1, 2, 3,
1334 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1335 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1337 {1, 1, 3, 3,
1338 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1339 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1342 #if 0 /* FIXME: these fail on GeForce 8500 */
1343 /* foggy vertex shader */
1344 {2, 0, 0, 0,
1345 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1346 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1347 {2, 0, 1, 0,
1348 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1349 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1350 {2, 0, 2, 0,
1351 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1352 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1353 {2, 0, 3, 0,
1354 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1355 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1356 #endif
1358 /* foggy vertex shader and pixel shader */
1359 {2, 1, 0, 0,
1360 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1361 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1362 {2, 1, 1, 0,
1363 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1364 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1365 {2, 1, 2, 0,
1366 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1367 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1368 {2, 1, 3, 0,
1369 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1370 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1374 /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1375 start.f=0.1f;
1376 end.f=0.9f;
1378 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1379 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1380 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1381 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1382 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1383 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1384 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1385 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1387 /* Setup initial states: No lighting, fog on, fog color */
1388 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1389 ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1390 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1391 ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1392 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1393 ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1394 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1395 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1397 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1398 ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1399 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1400 ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1402 /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1403 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1404 ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1405 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1406 ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1408 for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1410 hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1411 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1412 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1413 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1414 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1415 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1416 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1417 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1419 for(j=0; j < 11; j++)
1421 /* Don't use the whole zrange to prevent rounding errors */
1422 quad[0].z = 0.001f + (float)j / 10.02f;
1423 quad[1].z = 0.001f + (float)j / 10.02f;
1424 quad[2].z = 0.001f + (float)j / 10.02f;
1425 quad[3].z = 0.001f + (float)j / 10.02f;
1427 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1428 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1430 hr = IDirect3DDevice9_BeginScene(device);
1431 ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1433 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1434 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1436 hr = IDirect3DDevice9_EndScene(device);
1437 ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1439 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1441 /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1442 color = getPixelColor(device, 128, 240);
1443 ok((unsigned char)(color) == ((unsigned char)test_data[i].color[j])
1444 && abs( ((unsigned char)(color>>8)) - (unsigned char)(test_data[i].color[j]>>8) ) < 13
1445 && abs( ((unsigned char)(color>>16)) - (unsigned char)(test_data[i].color[j]>>16) ) < 13,
1446 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1447 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1451 /* reset states */
1452 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1453 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1454 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1455 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1456 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1457 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1458 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1459 ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1461 IDirect3DVertexShader9_Release(vertex_shader[1]);
1462 IDirect3DVertexShader9_Release(vertex_shader[2]);
1463 IDirect3DPixelShader9_Release(pixel_shader[1]);
1464 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1467 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
1468 unsigned int i, x, y;
1469 HRESULT hr;
1470 IDirect3DTexture9 *texture[2] = {NULL, NULL};
1471 D3DLOCKED_RECT locked_rect;
1473 /* Generate the textures */
1474 for(i=0; i<2; i++)
1476 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1477 D3DPOOL_MANAGED, &texture[i], NULL);
1478 ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1480 hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
1481 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1482 for (y = 0; y < 128; ++y)
1484 if(i)
1485 { /* Set up black texture with 2x2 texel white spot in the middle */
1486 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1487 for (x = 0; x < 128; ++x)
1489 if(y>62 && y<66 && x>62 && x<66)
1490 *ptr++ = 0xffffffff;
1491 else
1492 *ptr++ = 0xff000000;
1495 else
1496 { /* Set up a displacement map which points away from the center parallel to the closest axis.
1497 * (if multiplied with bumpenvmat)
1499 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1500 for (x = 0; x < 128; ++x)
1502 if(abs(x-64)>abs(y-64))
1504 if(x < 64)
1505 *ptr++ = 0xc000;
1506 else
1507 *ptr++ = 0x4000;
1509 else
1511 if(y < 64)
1512 *ptr++ = 0x0040;
1513 else
1514 *ptr++ = 0x00c0;
1519 hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
1520 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1522 hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
1523 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1525 /* Disable texture filtering */
1526 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1527 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1528 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1529 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1531 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1532 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
1533 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1534 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
1538 /* test the behavior of the texbem instruction
1539 * with normal 2D and projective 2D textures
1541 static void texbem_test(IDirect3DDevice9 *device)
1543 HRESULT hr;
1544 DWORD color;
1545 int i;
1547 static const DWORD pixel_shader_code[] = {
1548 0xffff0101, /* ps_1_1*/
1549 0x00000042, 0xb00f0000, /* tex t0*/
1550 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
1551 0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
1552 0x0000ffff
1554 static const DWORD double_texbem_code[] = {
1555 0xffff0103, /* ps_1_3 */
1556 0x00000042, 0xb00f0000, /* tex t0 */
1557 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0 */
1558 0x00000042, 0xb00f0002, /* tex t2 */
1559 0x00000043, 0xb00f0003, 0xb0e40002, /* texbem t3, t2 */
1560 0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003, /* add r0, t1, t3 */
1561 0x0000ffff /* end */
1565 static const float quad[][7] = {
1566 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
1567 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
1568 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
1569 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
1571 static const float quad_proj[][9] = {
1572 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 128.0f},
1573 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 128.0f, 0.0f, 128.0f},
1574 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f, 0.0f, 0.0f, 128.0f},
1575 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
1578 static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
1579 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1580 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1581 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1582 D3DDECL_END()
1584 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1585 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1586 {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1587 D3DDECL_END()
1588 } };
1590 /* use asymmetric matrix to test loading */
1591 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
1593 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1594 IDirect3DPixelShader9 *pixel_shader = NULL;
1595 IDirect3DTexture9 *texture = NULL, *texture1, *texture2;
1596 D3DLOCKED_RECT locked_rect;
1598 generate_bumpmap_textures(device);
1600 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1601 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1602 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1603 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1604 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
1606 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1607 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1609 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1610 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1612 for(i=0; i<2; i++)
1614 if(i)
1616 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
1617 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1620 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
1621 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1622 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1623 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1625 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
1626 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1627 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1628 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1630 hr = IDirect3DDevice9_BeginScene(device);
1631 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1633 if(!i)
1634 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1635 else
1636 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
1637 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1639 hr = IDirect3DDevice9_EndScene(device);
1640 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1642 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1643 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1645 color = getPixelColor(device, 320-32, 240);
1646 ok(color == 0x00ffffff, "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1647 color = getPixelColor(device, 320+32, 240);
1648 ok(color == 0x00ffffff, "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1649 color = getPixelColor(device, 320, 240-32);
1650 ok(color == 0x00ffffff, "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1651 color = getPixelColor(device, 320, 240+32);
1652 ok(color == 0x00ffffff, "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1654 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1655 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1656 IDirect3DPixelShader9_Release(pixel_shader);
1658 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1659 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1660 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1663 /* clean up */
1664 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1665 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1667 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
1668 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1670 for(i=0; i<2; i++)
1672 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
1673 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
1674 IDirect3DTexture9_Release(texture); /* For the GetTexture */
1675 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
1676 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1677 IDirect3DTexture9_Release(texture);
1680 /* Test double texbem */
1681 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
1682 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1683 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
1684 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1685 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
1686 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
1687 hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
1688 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1690 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
1691 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1692 ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
1693 ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
1695 hr = IDirect3DTexture9_UnlockRect(texture, 0);
1696 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1698 hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
1699 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1700 ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
1701 ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
1702 hr = IDirect3DTexture9_UnlockRect(texture1, 0);
1703 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1706 /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
1707 #define tex 0x00ff0000
1708 #define tex1 0x0000ff00
1709 #define origin 0x000000ff
1710 static const DWORD pixel_data[] = {
1711 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1712 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1713 0x000000ff, tex1 , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1714 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1715 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin, 0x000000ff, tex , 0x000000ff,
1716 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1717 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1718 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
1720 #undef tex1
1721 #undef tex2
1722 #undef origin
1724 hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
1725 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1726 for(i = 0; i < 8; i++) {
1727 memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
1729 hr = IDirect3DTexture9_UnlockRect(texture2, 0);
1730 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1733 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
1734 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1735 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
1736 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1737 hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
1738 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1739 hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
1740 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1741 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1742 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1743 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
1744 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1746 bumpenvmat[0] =-1.0; bumpenvmat[2] = 2.0;
1747 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.0;
1748 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1749 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1750 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1751 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1753 bumpenvmat[0] = 1.5; bumpenvmat[2] = 0.0;
1754 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.5;
1755 IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1756 IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1757 IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1758 IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1760 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1761 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1762 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1763 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1764 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1765 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1766 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1767 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1769 hr = IDirect3DDevice9_BeginScene(device);
1770 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1771 if(SUCCEEDED(hr)) {
1772 static const float double_quad[] = {
1773 -1.0, -1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
1774 1.0, -1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
1775 -1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
1776 1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5,
1779 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
1780 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1781 hr = IDirect3DDevice9_EndScene(device);
1782 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1784 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1785 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1786 color = getPixelColor(device, 320, 240);
1787 ok(color == 0x00ffff00, "double texbem failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1789 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1790 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1791 hr = IDirect3DDevice9_SetTexture(device, 1, NULL);
1792 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1793 hr = IDirect3DDevice9_SetTexture(device, 2, NULL);
1794 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1795 hr = IDirect3DDevice9_SetTexture(device, 3, NULL);
1796 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
1797 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1798 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
1800 IDirect3DPixelShader9_Release(pixel_shader);
1801 IDirect3DTexture9_Release(texture);
1802 IDirect3DTexture9_Release(texture1);
1803 IDirect3DTexture9_Release(texture2);
1806 static void z_range_test(IDirect3DDevice9 *device)
1808 const struct vertex quad[] =
1810 {-1.0f, 0.0f, 1.1f, 0xffff0000},
1811 {-1.0f, 1.0f, 1.1f, 0xffff0000},
1812 { 1.0f, 0.0f, -1.1f, 0xffff0000},
1813 { 1.0f, 1.0f, -1.1f, 0xffff0000},
1815 const struct vertex quad2[] =
1817 {-1.0f, 0.0f, 1.1f, 0xff0000ff},
1818 {-1.0f, 1.0f, 1.1f, 0xff0000ff},
1819 { 1.0f, 0.0f, -1.1f, 0xff0000ff},
1820 { 1.0f, 1.0f, -1.1f, 0xff0000ff},
1823 const struct tvertex quad3[] =
1825 { 0, 240, 1.1f, 1.0, 0xffffff00},
1826 { 0, 480, 1.1f, 1.0, 0xffffff00},
1827 { 640, 240, -1.1f, 1.0, 0xffffff00},
1828 { 640, 480, -1.1f, 1.0, 0xffffff00},
1830 const struct tvertex quad4[] =
1832 { 0, 240, 1.1f, 1.0, 0xff00ff00},
1833 { 0, 480, 1.1f, 1.0, 0xff00ff00},
1834 { 640, 240, -1.1f, 1.0, 0xff00ff00},
1835 { 640, 480, -1.1f, 1.0, 0xff00ff00},
1837 HRESULT hr;
1838 DWORD color;
1839 IDirect3DVertexShader9 *shader;
1840 IDirect3DVertexDeclaration9 *decl;
1841 D3DCAPS9 caps;
1842 const DWORD shader_code[] = {
1843 0xfffe0101, /* vs_1_1 */
1844 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1845 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1846 0x00000001, 0xd00f0000, 0xa0e40000, /* mov oD0, c0 */
1847 0x0000ffff /* end */
1849 static const D3DVERTEXELEMENT9 decl_elements[] = {
1850 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1851 D3DDECL_END()
1853 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
1854 * then call Present. Then clear the color buffer to make sure it has some defined content
1855 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
1856 * by the depth value.
1858 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
1859 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
1860 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1861 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
1863 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
1864 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1865 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
1866 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1867 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
1868 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1869 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
1870 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1871 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1872 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
1874 hr = IDirect3DDevice9_BeginScene(device);
1875 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
1876 if(hr == D3D_OK)
1878 /* Test the untransformed vertex path */
1879 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
1880 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1881 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
1882 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1883 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
1884 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1886 /* Test the transformed vertex path */
1887 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
1888 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
1890 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
1891 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1892 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
1893 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1894 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
1895 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1897 hr = IDirect3DDevice9_EndScene(device);
1898 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
1901 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1902 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1904 /* Do not test the exact corner pixels, but go pretty close to them */
1906 /* Clipped because z > 1.0 */
1907 color = getPixelColor(device, 28, 238);
1908 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1909 color = getPixelColor(device, 28, 241);
1910 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1912 /* Not clipped, > z buffer clear value(0.75) */
1913 color = getPixelColor(device, 31, 238);
1914 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1915 color = getPixelColor(device, 31, 241);
1916 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1917 color = getPixelColor(device, 100, 238);
1918 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1919 color = getPixelColor(device, 100, 241);
1920 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1922 /* Not clipped, < z buffer clear value */
1923 color = getPixelColor(device, 104, 238);
1924 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
1925 color = getPixelColor(device, 104, 241);
1926 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
1927 color = getPixelColor(device, 318, 238);
1928 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
1929 color = getPixelColor(device, 318, 241);
1930 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
1932 /* Clipped because z < 0.0 */
1933 color = getPixelColor(device, 321, 238);
1934 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1935 color = getPixelColor(device, 321, 241);
1936 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1938 /* Test the shader path */
1939 IDirect3DDevice9_GetDeviceCaps(device, &caps);
1940 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) {
1941 skip("Vertex shaders not supported\n");
1942 goto out;
1944 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
1945 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
1946 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
1947 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
1949 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
1951 IDirect3DDevice9_SetVertexDeclaration(device, decl);
1952 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
1953 IDirect3DDevice9_SetVertexShader(device, shader);
1954 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
1956 hr = IDirect3DDevice9_BeginScene(device);
1957 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
1958 if(hr == D3D_OK)
1960 float colorf[] = {1.0, 0.0, 0.0, 1.0};
1961 float colorf2[] = {0.0, 0.0, 1.0, 1.0};
1962 IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
1963 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
1964 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1965 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
1966 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1967 IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
1968 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
1969 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1971 hr = IDirect3DDevice9_EndScene(device);
1972 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
1975 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1976 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
1977 IDirect3DDevice9_SetVertexShader(device, NULL);
1978 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
1980 IDirect3DVertexDeclaration9_Release(decl);
1981 IDirect3DVertexShader9_Release(shader);
1983 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1984 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1985 /* Z < 1.0 */
1986 color = getPixelColor(device, 28, 238);
1987 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1989 /* 1.0 < z < 0.75 */
1990 color = getPixelColor(device, 31, 238);
1991 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1992 color = getPixelColor(device, 100, 238);
1993 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1995 /* 0.75 < z < 0.0 */
1996 color = getPixelColor(device, 104, 238);
1997 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
1998 color = getPixelColor(device, 318, 238);
1999 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2001 /* 0.0 < z */
2002 color = getPixelColor(device, 321, 238);
2003 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2005 out:
2006 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2007 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
2008 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
2009 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
2010 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2011 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
2014 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
2016 D3DSURFACE_DESC desc;
2017 D3DLOCKED_RECT l;
2018 HRESULT hr;
2019 unsigned int x, y;
2020 DWORD *mem;
2022 memset(&desc, 0, sizeof(desc));
2023 memset(&l, 0, sizeof(l));
2024 hr = IDirect3DSurface9_GetDesc(surface, &desc);
2025 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %s\n", DXGetErrorString9(hr));
2026 hr = IDirect3DSurface9_LockRect(surface, &l, NULL, 0);
2027 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %s\n", DXGetErrorString9(hr));
2028 if(FAILED(hr)) return;
2030 for(y = 0; y < desc.Height; y++)
2032 mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
2033 for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
2035 mem[x] = color;
2038 hr = IDirect3DSurface9_UnlockRect(surface);
2039 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %s\n", DXGetErrorString9(hr));
2042 /* This tests a variety of possible StretchRect() situations */
2043 static void stretchrect_test(IDirect3DDevice9 *device)
2045 HRESULT hr;
2046 IDirect3DTexture9 *tex_rt32 = NULL, *tex_rt64 = NULL, *tex_rt_dest64;
2047 IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64;
2048 IDirect3DTexture9 *tex32 = NULL, *tex64 = NULL, *tex_dest64 = NULL;
2049 IDirect3DSurface9 *surf_tex32 = NULL, *surf_tex64 = NULL, *surf_tex_dest64 = NULL;
2050 IDirect3DSurface9 *surf_rt32 = NULL, *surf_rt64 = NULL, *surf_rt_dest64 = NULL;
2051 IDirect3DSurface9 *surf_offscreen32 = NULL, *surf_offscreen64 = NULL, *surf_offscreen_dest64 = NULL;
2052 IDirect3DSurface9 *surf_temp32 = NULL, *surf_temp64 = NULL;
2053 IDirect3DSurface9 *orig_rt = NULL;
2054 DWORD color;
2056 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &orig_rt);
2057 ok(hr == D3D_OK, "Can't get render target, hr = %s\n", DXGetErrorString9(hr));
2058 if(!orig_rt) {
2059 goto out;
2062 /* Create our temporary surfaces in system memory */
2063 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
2064 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %s\n", DXGetErrorString9(hr));
2065 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
2066 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %s\n", DXGetErrorString9(hr));
2068 /* Create offscreen plain surfaces in D3DPOOL_DEFAULT */
2069 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
2070 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %s\n", DXGetErrorString9(hr));
2071 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
2072 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %s\n", DXGetErrorString9(hr));
2073 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
2074 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed with %s\n", DXGetErrorString9(hr));
2076 /* Create render target surfaces */
2077 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
2078 ok(hr == D3D_OK, "Creating the render target surface failed with %s\n", DXGetErrorString9(hr));
2079 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
2080 ok(hr == D3D_OK, "Creating the render target surface failed with %s\n", DXGetErrorString9(hr));
2081 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
2082 ok(hr == D3D_OK, "Creating the render target surface failed with %s\n", DXGetErrorString9(hr));
2084 /* Create render target textures */
2085 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
2086 ok(hr == D3D_OK, "Creating the render target texture failed with %s\n", DXGetErrorString9(hr));
2087 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
2088 ok(hr == D3D_OK, "Creating the render target texture failed with %s\n", DXGetErrorString9(hr));
2089 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
2090 ok(hr == D3D_OK, "Creating the render target texture failed with %s\n", DXGetErrorString9(hr));
2091 if (tex_rt32) {
2092 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
2093 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
2095 if (tex_rt64) {
2096 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
2097 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
2099 if (tex_rt_dest64) {
2100 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
2101 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
2104 /* Create regular textures in D3DPOOL_DEFAULT */
2105 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
2106 ok(hr == D3D_OK, "Creating the regular texture failed with %s\n", DXGetErrorString9(hr));
2107 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
2108 ok(hr == D3D_OK, "Creating the regular texture failed with %s\n", DXGetErrorString9(hr));
2109 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
2110 ok(hr == D3D_OK, "Creating the regular texture failed with %s\n", DXGetErrorString9(hr));
2111 if (tex32) {
2112 hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
2113 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
2115 if (tex64) {
2116 hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
2117 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
2119 if (tex_dest64) {
2120 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
2121 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
2124 /*********************************************************************
2125 * Tests for when the source parameter is an offscreen plain surface *
2126 *********************************************************************/
2128 /* Fill the offscreen 64x64 surface with green */
2129 if (surf_offscreen64)
2130 fill_surface(surf_offscreen64, 0xff00ff00);
2132 /* offscreenplain ==> offscreenplain, same size */
2133 if(surf_offscreen64 && surf_offscreen_dest64) {
2134 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, 0);
2135 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2137 if (hr == D3D_OK) {
2138 color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
2139 ok(color == 0xff00ff00, "StretchRect offscreen ==> offscreen same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2143 /* offscreenplain ==> rendertarget texture, same size */
2144 if(surf_offscreen64 && surf_tex_rt_dest64 && surf_temp64) {
2145 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, 0);
2146 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2148 /* We can't lock rendertarget textures, so copy to our temp surface first */
2149 if (hr == D3D_OK) {
2150 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2151 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2154 if (hr == D3D_OK) {
2155 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2156 ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2160 /* offscreenplain ==> rendertarget surface, same size */
2161 if(surf_offscreen64 && surf_rt_dest64) {
2162 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, 0);
2163 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2165 if (hr == D3D_OK) {
2166 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2167 ok(color == 0xff00ff00, "StretchRect offscreen ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff00ff00.\n", color);
2171 /* offscreenplain ==> texture, same size (should fail) */
2172 if(surf_offscreen64 && surf_tex_dest64) {
2173 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, 0);
2174 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2177 /* Fill the smaller offscreen surface with red */
2178 fill_surface(surf_offscreen32, 0xffff0000);
2180 /* offscreenplain ==> offscreenplain, scaling (should fail) */
2181 if(surf_offscreen32 && surf_offscreen64) {
2182 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, 0);
2183 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2186 /* offscreenplain ==> rendertarget texture, scaling */
2187 if(surf_offscreen32 && surf_tex_rt_dest64 && surf_temp64) {
2188 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, 0);
2189 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2191 /* We can't lock rendertarget textures, so copy to our temp surface first */
2192 if (hr == D3D_OK) {
2193 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2194 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2197 if (hr == D3D_OK) {
2198 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2199 ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2203 /* offscreenplain ==> rendertarget surface, scaling */
2204 if(surf_offscreen32 && surf_rt_dest64) {
2205 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, 0);
2206 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2208 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2209 ok(color == 0xffff0000, "StretchRect offscreen ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2212 /* offscreenplain ==> texture, scaling (should fail) */
2213 if(surf_offscreen32 && surf_tex_dest64) {
2214 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, 0);
2215 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2218 /************************************************************
2219 * Tests for when the source parameter is a regular texture *
2220 ************************************************************/
2222 /* Fill the surface of the regular texture with blue */
2223 if (surf_tex64 && surf_temp64) {
2224 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2225 fill_surface(surf_temp64, 0xff0000ff);
2226 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
2227 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %s\n", DXGetErrorString9(hr));
2230 /* texture ==> offscreenplain, same size */
2231 if(surf_tex64 && surf_offscreen64) {
2232 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, 0);
2233 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2236 /* texture ==> rendertarget texture, same size */
2237 if(surf_tex64 && surf_tex_rt_dest64 && surf_temp64) {
2238 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, 0);
2239 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2241 /* We can't lock rendertarget textures, so copy to our temp surface first */
2242 if (hr == D3D_OK) {
2243 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2244 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2247 if (hr == D3D_OK) {
2248 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2249 ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2253 /* texture ==> rendertarget surface, same size */
2254 if(surf_tex64 && surf_rt_dest64) {
2255 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, 0);
2256 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2258 if (hr == D3D_OK) {
2259 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2260 ok(color == 0xff0000ff, "StretchRect texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff0000ff.\n", color);
2264 /* texture ==> texture, same size (should fail) */
2265 if(surf_tex64 && surf_tex_dest64) {
2266 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, 0);
2267 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2270 /* Fill the surface of the smaller regular texture with red */
2271 if (surf_tex32 && surf_temp32) {
2272 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT */
2273 fill_surface(surf_temp32, 0xffff0000);
2274 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
2275 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %s\n", DXGetErrorString9(hr));
2278 /* texture ==> offscreenplain, scaling (should fail) */
2279 if(surf_tex32 && surf_offscreen64) {
2280 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, 0);
2281 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2284 /* texture ==> rendertarget texture, scaling */
2285 if(surf_tex32 && surf_tex_rt_dest64 && surf_temp64) {
2286 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, 0);
2287 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2289 /* We can't lock rendertarget textures, so copy to our temp surface first */
2290 if (hr == D3D_OK) {
2291 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2292 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2295 if (hr == D3D_OK) {
2296 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2297 ok(color == 0xffff0000, "StretchRect texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2301 /* texture ==> rendertarget surface, scaling */
2302 if(surf_tex32 && surf_rt_dest64) {
2303 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, 0);
2304 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2306 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2307 ok(color == 0xffff0000, "StretchRect texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2310 /* texture ==> texture, scaling (should fail) */
2311 if(surf_tex32 && surf_tex_dest64) {
2312 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, 0);
2313 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2316 /*****************************************************************
2317 * Tests for when the source parameter is a rendertarget texture *
2318 *****************************************************************/
2320 /* Fill the surface of the rendertarget texture with white */
2321 if (surf_tex_rt64 && surf_temp64) {
2322 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2323 fill_surface(surf_temp64, 0xffffffff);
2324 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
2325 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %s\n", DXGetErrorString9(hr));
2328 /* rendertarget texture ==> offscreenplain, same size */
2329 if(surf_tex_rt64 && surf_offscreen64) {
2330 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, 0);
2331 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2334 /* rendertarget texture ==> rendertarget texture, same size */
2335 if(surf_tex_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2336 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2337 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2339 /* We can't lock rendertarget textures, so copy to our temp surface first */
2340 if (hr == D3D_OK) {
2341 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2342 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2345 if (hr == D3D_OK) {
2346 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2347 ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2351 /* rendertarget texture ==> rendertarget surface, same size */
2352 if(surf_tex_rt64 && surf_rt_dest64) {
2353 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, 0);
2354 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2356 if (hr == D3D_OK) {
2357 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2358 ok(color == 0xffffffff, "StretchRect rendertarget texture ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xffffffff.\n", color);
2362 /* rendertarget texture ==> texture, same size (should fail) */
2363 if(surf_tex_rt64 && surf_tex_dest64) {
2364 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, 0);
2365 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2368 /* Fill the surface of the smaller rendertarget texture with red */
2369 if (surf_tex_rt32 && surf_temp32) {
2370 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT */
2371 fill_surface(surf_temp32, 0xffff0000);
2372 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
2373 ok( hr == D3D_OK, "IDirect3DDevice9_UpdateSurface failed with %s\n", DXGetErrorString9(hr));
2376 /* rendertarget texture ==> offscreenplain, scaling (should fail) */
2377 if(surf_tex_rt32 && surf_offscreen64) {
2378 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, 0);
2379 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2382 /* rendertarget texture ==> rendertarget texture, scaling */
2383 if(surf_tex_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2384 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2385 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2387 /* We can't lock rendertarget textures, so copy to our temp surface first */
2388 if (hr == D3D_OK) {
2389 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2390 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2393 if (hr == D3D_OK) {
2394 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2395 ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2399 /* rendertarget texture ==> rendertarget surface, scaling */
2400 if(surf_tex_rt32 && surf_rt_dest64) {
2401 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, 0);
2402 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2404 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2405 ok(color == 0xffff0000, "StretchRect rendertarget texture ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2408 /* rendertarget texture ==> texture, scaling (should fail) */
2409 if(surf_tex_rt32 && surf_tex_dest64) {
2410 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, 0);
2411 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2414 /*****************************************************************
2415 * Tests for when the source parameter is a rendertarget surface *
2416 *****************************************************************/
2418 /* Fill the surface of the rendertarget surface with black */
2419 if (surf_rt64)
2420 fill_surface(surf_rt64, 0xff000000);
2422 /* rendertarget texture ==> offscreenplain, same size */
2423 if(surf_rt64 && surf_offscreen64) {
2424 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, 0);
2425 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2428 /* rendertarget surface ==> rendertarget texture, same size */
2429 if(surf_rt64 && surf_tex_rt_dest64 && surf_temp64) {
2430 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, 0);
2431 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2433 /* We can't lock rendertarget textures, so copy to our temp surface first */
2434 if (hr == D3D_OK) {
2435 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2436 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2439 if (hr == D3D_OK) {
2440 color = getPixelColorFromSurface(surf_temp64, 32, 32);
2441 ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget texture same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2445 /* rendertarget surface ==> rendertarget surface, same size */
2446 if(surf_rt64 && surf_rt_dest64) {
2447 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, 0);
2448 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2450 if (hr == D3D_OK) {
2451 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
2452 ok(color == 0xff000000, "StretchRect rendertarget surface ==> rendertarget surface same size failed: Got color 0x%08x, expected 0xff000000.\n", color);
2456 /* rendertarget surface ==> texture, same size (should fail) */
2457 if(surf_rt64 && surf_tex_dest64) {
2458 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, 0);
2459 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2462 /* Fill the surface of the smaller rendertarget texture with red */
2463 if (surf_rt32)
2464 fill_surface(surf_rt32, 0xffff0000);
2466 /* rendertarget surface ==> offscreenplain, scaling (should fail) */
2467 if(surf_rt32 && surf_offscreen64) {
2468 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, 0);
2469 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2472 /* rendertarget surface ==> rendertarget texture, scaling */
2473 if(surf_rt32 && surf_tex_rt_dest64 && surf_temp64) {
2474 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, 0);
2475 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2477 /* We can't lock rendertarget textures, so copy to our temp surface first */
2478 if (hr == D3D_OK) {
2479 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
2480 ok( hr == D3D_OK, "IDirect3DDevice9_GetRenderTargetData failed with %s\n", DXGetErrorString9(hr));
2483 if (hr == D3D_OK) {
2484 color = getPixelColorFromSurface(surf_temp64, 48, 48);
2485 ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget texture scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2489 /* rendertarget surface ==> rendertarget surface, scaling */
2490 if(surf_rt32 && surf_rt_dest64) {
2491 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, 0);
2492 ok( hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
2494 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
2495 ok(color == 0xffff0000, "StretchRect rendertarget surface ==> rendertarget surface scaling failed: Got color 0x%08x, expected 0xffff0000.\n", color);
2498 /* rendertarget surface ==> texture, scaling (should fail) */
2499 if(surf_rt32 && surf_tex_dest64) {
2500 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, 0);
2501 todo_wine ok( hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_StretchRect succeeded, shouldn't happen (todo)\n");
2504 /* TODO: Test when source and destination RECT parameters are given... */
2505 /* TODO: Test format conversions */
2508 out:
2509 /* Clean up */
2510 if (surf_rt32)
2511 IDirect3DSurface9_Release(surf_rt32);
2512 if (surf_rt64)
2513 IDirect3DSurface9_Release(surf_rt64);
2514 if (surf_rt_dest64)
2515 IDirect3DSurface9_Release(surf_rt_dest64);
2516 if (surf_temp32)
2517 IDirect3DSurface9_Release(surf_temp32);
2518 if (surf_temp64)
2519 IDirect3DSurface9_Release(surf_temp64);
2520 if (surf_offscreen32)
2521 IDirect3DSurface9_Release(surf_offscreen32);
2522 if (surf_offscreen64)
2523 IDirect3DSurface9_Release(surf_offscreen64);
2524 if (surf_offscreen_dest64)
2525 IDirect3DSurface9_Release(surf_offscreen_dest64);
2527 if (tex_rt32) {
2528 if (surf_tex_rt32)
2529 IDirect3DSurface9_Release(surf_tex_rt32);
2530 IDirect3DTexture9_Release(tex_rt32);
2532 if (tex_rt64) {
2533 if (surf_tex_rt64)
2534 IDirect3DSurface9_Release(surf_tex_rt64);
2535 IDirect3DTexture9_Release(tex_rt64);
2537 if (tex_rt_dest64) {
2538 if (surf_tex_rt_dest64)
2539 IDirect3DSurface9_Release(surf_tex_rt_dest64);
2540 IDirect3DTexture9_Release(tex_rt_dest64);
2542 if (tex32) {
2543 if (surf_tex32)
2544 IDirect3DSurface9_Release(surf_tex32);
2545 IDirect3DTexture9_Release(tex32);
2547 if (tex64) {
2548 if (surf_tex64)
2549 IDirect3DSurface9_Release(surf_tex64);
2550 IDirect3DTexture9_Release(tex64);
2552 if (tex_dest64) {
2553 if (surf_tex_dest64)
2554 IDirect3DSurface9_Release(surf_tex_dest64);
2555 IDirect3DTexture9_Release(tex_dest64);
2558 if (orig_rt) {
2559 hr = IDirect3DDevice9_SetRenderTarget(device, 0, orig_rt);
2560 ok(hr == D3D_OK, "IDirect3DSetRenderTarget failed with %s\n", DXGetErrorString9(hr));
2561 IDirect3DSurface9_Release(orig_rt);
2565 static void maxmip_test(IDirect3DDevice9 *device)
2567 IDirect3DTexture9 *texture = NULL;
2568 IDirect3DSurface9 *surface = NULL;
2569 HRESULT hr;
2570 DWORD color;
2571 const float quads[] = {
2572 -1.0, -1.0, 0.0, 0.0, 0.0,
2573 -1.0, 0.0, 0.0, 0.0, 1.0,
2574 0.0, -1.0, 0.0, 1.0, 0.0,
2575 0.0, 0.0, 0.0, 1.0, 1.0,
2577 0.0, -1.0, 0.0, 0.0, 0.0,
2578 0.0, 0.0, 0.0, 0.0, 1.0,
2579 1.0, -1.0, 0.0, 1.0, 0.0,
2580 1.0, 0.0, 0.0, 1.0, 1.0,
2582 0.0, 0.0, 0.0, 0.0, 0.0,
2583 0.0, 1.0, 0.0, 0.0, 1.0,
2584 1.0, 0.0, 0.0, 1.0, 0.0,
2585 1.0, 1.0, 0.0, 1.0, 1.0,
2587 -1.0, 0.0, 0.0, 0.0, 0.0,
2588 -1.0, 1.0, 0.0, 0.0, 1.0,
2589 0.0, 0.0, 0.0, 1.0, 0.0,
2590 0.0, 1.0, 0.0, 1.0, 1.0,
2593 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2594 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
2596 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
2597 &texture, NULL);
2598 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
2599 if(!texture)
2601 skip("Failed to create test texture\n");
2602 return;
2605 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
2606 fill_surface(surface, 0xffff0000);
2607 IDirect3DSurface9_Release(surface);
2608 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
2609 fill_surface(surface, 0xff00ff00);
2610 IDirect3DSurface9_Release(surface);
2611 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
2612 fill_surface(surface, 0xff0000ff);
2613 IDirect3DSurface9_Release(surface);
2615 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2616 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2617 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2618 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2620 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2621 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2623 hr = IDirect3DDevice9_BeginScene(device);
2624 if(SUCCEEDED(hr))
2626 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2627 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2628 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2629 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2631 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2632 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2633 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2634 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2636 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2637 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2638 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2639 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2641 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2642 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2643 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2644 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2645 hr = IDirect3DDevice9_EndScene(device);
2648 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2649 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2650 /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
2651 color = getPixelColor(device, 160, 360);
2652 ok(color == 0x00FF0000, "MapMip 0, no mipfilter has color %08x\n", color);
2653 color = getPixelColor(device, 160, 120);
2654 ok(color == 0x00FF0000, "MapMip 3, no mipfilter has color %08x\n", color);
2655 color = getPixelColor(device, 480, 120);
2656 ok(color == 0x00FF0000, "MapMip 2, no mipfilter has color %08x\n", color);
2657 color = getPixelColor(device, 480, 360);
2658 ok(color == 0x00FF0000, "MapMip 1, no mipfilter has color %08x\n", color);
2660 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
2661 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
2663 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
2664 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2666 hr = IDirect3DDevice9_BeginScene(device);
2667 if(SUCCEEDED(hr))
2669 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2670 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2671 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
2672 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2674 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
2675 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2676 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
2677 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2679 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
2680 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2681 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
2682 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2684 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
2685 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2686 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
2687 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2688 hr = IDirect3DDevice9_EndScene(device);
2691 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2692 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2693 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2694 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2696 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2697 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2698 /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
2699 * samples from the highest level in the texture(level 2)
2701 color = getPixelColor(device, 160, 360);
2702 ok(color == 0x00FF0000, "MapMip 0, point mipfilter has color %08x\n", color);
2703 color = getPixelColor(device, 160, 120);
2704 ok(color == 0x000000FF, "MapMip 3, point mipfilter has color %08x\n", color);
2705 color = getPixelColor(device, 480, 120);
2706 ok(color == 0x000000FF, "MapMip 2, point mipfilter has color %08x\n", color);
2707 color = getPixelColor(device, 480, 360);
2708 ok(color == 0x0000FF00, "MapMip 1, point mipfilter has color %08x\n", color);
2710 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2711 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2712 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
2713 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
2714 IDirect3DTexture9_Release(texture);
2717 static void release_buffer_test(IDirect3DDevice9 *device)
2719 IDirect3DVertexBuffer9 *vb = NULL;
2720 IDirect3DIndexBuffer9 *ib = NULL;
2721 HRESULT hr;
2722 BYTE *data;
2723 long ref;
2725 static const struct vertex quad[] = {
2726 {-1.0, -1.0, 0.1, 0xffff0000},
2727 {-1.0, 1.0, 0.1, 0xffff0000},
2728 { 1.0, 1.0, 0.1, 0xffff0000},
2730 {-1.0, -1.0, 0.1, 0xff00ff00},
2731 {-1.0, 1.0, 0.1, 0xff00ff00},
2732 { 1.0, 1.0, 0.1, 0xff00ff00}
2734 short indices[] = {3, 4, 5};
2736 /* Index and vertex buffers should always be creatable */
2737 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
2738 D3DPOOL_MANAGED, &vb, NULL);
2739 ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
2740 if(!vb) {
2741 skip("Failed to create a vertex buffer\n");
2742 return;
2744 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
2745 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %s\n", DXGetErrorString9(hr));
2746 if(!ib) {
2747 skip("Failed to create an index buffer\n");
2748 return;
2751 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
2752 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
2753 memcpy(data, quad, sizeof(quad));
2754 hr = IDirect3DVertexBuffer9_Unlock(vb);
2755 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
2757 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
2758 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
2759 memcpy(data, indices, sizeof(indices));
2760 hr = IDirect3DIndexBuffer9_Unlock(ib);
2761 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
2763 hr = IDirect3DDevice9_SetIndices(device, ib);
2764 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %s\n", DXGetErrorString9(hr));
2765 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
2766 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
2767 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2768 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2770 /* Now destroy the bound index buffer and draw again */
2771 ref = IDirect3DIndexBuffer9_Release(ib);
2772 ok(ref == 0, "Index Buffer reference count is %08ld\n", ref);
2774 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
2775 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
2777 hr = IDirect3DDevice9_BeginScene(device);
2778 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
2779 if(SUCCEEDED(hr))
2781 /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
2782 * making assumptions about the indices or vertices
2784 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
2785 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
2786 hr = IDirect3DDevice9_EndScene(device);
2787 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
2790 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2791 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
2793 hr = IDirect3DDevice9_SetIndices(device, NULL);
2794 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2795 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
2796 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
2798 /* Index buffer was already destroyed as part of the test */
2799 IDirect3DVertexBuffer9_Release(vb);
2802 static void float_texture_test(IDirect3DDevice9 *device)
2804 IDirect3D9 *d3d = NULL;
2805 HRESULT hr;
2806 IDirect3DTexture9 *texture = NULL;
2807 D3DLOCKED_RECT lr;
2808 float *data;
2809 DWORD color;
2810 float quad[] = {
2811 -1.0, -1.0, 0.1, 0.0, 0.0,
2812 -1.0, 1.0, 0.1, 0.0, 1.0,
2813 1.0, -1.0, 0.1, 1.0, 0.0,
2814 1.0, 1.0, 0.1, 1.0, 1.0,
2817 memset(&lr, 0, sizeof(lr));
2818 IDirect3DDevice9_GetDirect3D(device, &d3d);
2819 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
2820 D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
2821 skip("D3DFMT_R32F textures not supported\n");
2822 goto out;
2825 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
2826 D3DPOOL_MANAGED, &texture, NULL);
2827 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
2828 if(!texture) {
2829 skip("Failed to create R32F texture\n");
2830 goto out;
2833 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
2834 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %s\n", DXGetErrorString9(hr));
2835 data = lr.pBits;
2836 *data = 0.0;
2837 hr = IDirect3DTexture9_UnlockRect(texture, 0);
2838 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %s\n", DXGetErrorString9(hr));
2840 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2841 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2843 hr = IDirect3DDevice9_BeginScene(device);
2844 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
2845 if(SUCCEEDED(hr))
2847 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2848 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2850 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2851 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2853 hr = IDirect3DDevice9_EndScene(device);
2854 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
2856 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2857 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2859 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2860 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2862 color = getPixelColor(device, 240, 320);
2863 ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
2865 out:
2866 if(texture) IDirect3DTexture9_Release(texture);
2867 IDirect3D9_Release(d3d);
2870 static void g16r16_texture_test(IDirect3DDevice9 *device)
2872 IDirect3D9 *d3d = NULL;
2873 HRESULT hr;
2874 IDirect3DTexture9 *texture = NULL;
2875 D3DLOCKED_RECT lr;
2876 DWORD *data;
2877 DWORD color, red, green, blue;
2878 float quad[] = {
2879 -1.0, -1.0, 0.1, 0.0, 0.0,
2880 -1.0, 1.0, 0.1, 0.0, 1.0,
2881 1.0, -1.0, 0.1, 1.0, 0.0,
2882 1.0, 1.0, 0.1, 1.0, 1.0,
2885 memset(&lr, 0, sizeof(lr));
2886 IDirect3DDevice9_GetDirect3D(device, &d3d);
2887 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
2888 D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK) {
2889 skip("D3DFMT_G16R16 textures not supported\n");
2890 goto out;
2893 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16,
2894 D3DPOOL_MANAGED, &texture, NULL);
2895 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
2896 if(!texture) {
2897 skip("Failed to create D3DFMT_G16R16 texture\n");
2898 goto out;
2901 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
2902 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %s\n", DXGetErrorString9(hr));
2903 data = lr.pBits;
2904 *data = 0x0f00f000;
2905 hr = IDirect3DTexture9_UnlockRect(texture, 0);
2906 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %s\n", DXGetErrorString9(hr));
2908 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
2909 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2911 hr = IDirect3DDevice9_BeginScene(device);
2912 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
2913 if(SUCCEEDED(hr))
2915 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2916 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2918 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2919 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2921 hr = IDirect3DDevice9_EndScene(device);
2922 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
2924 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2925 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
2927 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2928 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2930 color = getPixelColor(device, 240, 320);
2931 red = (color & 0x00ff0000) >> 16;
2932 green = (color & 0x0000ff00) >> 8;
2933 blue = (color & 0x000000ff) >> 0;
2934 ok(blue == 0xff && red >= 0xef && red <= 0xf1 && green >= 0x0e && green <= 0x10,
2935 "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00F00FFF\n", color);
2937 out:
2938 if(texture) IDirect3DTexture9_Release(texture);
2939 IDirect3D9_Release(d3d);
2942 static void texture_transform_flags_test(IDirect3DDevice9 *device)
2944 HRESULT hr;
2945 IDirect3D9 *d3d;
2946 D3DFORMAT fmt = D3DFMT_X8R8G8B8;
2947 D3DCAPS9 caps;
2948 IDirect3DTexture9 *texture = NULL;
2949 IDirect3DVolumeTexture9 *volume = NULL;
2950 unsigned int x, y, z;
2951 D3DLOCKED_RECT lr;
2952 D3DLOCKED_BOX lb;
2953 DWORD color;
2954 IDirect3DVertexDeclaration9 *decl, *decl2, *decl3;
2955 float identity[16] = {1.0, 0.0, 0.0, 0.0,
2956 0.0, 1.0, 0.0, 0.0,
2957 0.0, 0.0, 1.0, 0.0,
2958 0.0, 0.0, 0.0, 1.0};
2959 static const D3DVERTEXELEMENT9 decl_elements[] = {
2960 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2961 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2962 D3DDECL_END()
2964 static const D3DVERTEXELEMENT9 decl_elements2[] = {
2965 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2966 {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2967 D3DDECL_END()
2969 static const D3DVERTEXELEMENT9 decl_elements3[] = {
2970 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2971 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2972 D3DDECL_END()
2974 static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
2975 0x00, 0xff, 0x00, 0x00,
2976 0x00, 0x00, 0x00, 0x00,
2977 0x00, 0x00, 0x00, 0x00};
2979 memset(&lr, 0, sizeof(lr));
2980 memset(&lb, 0, sizeof(lb));
2981 IDirect3DDevice9_GetDirect3D(device, &d3d);
2982 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
2983 D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
2984 fmt = D3DFMT_A16B16G16R16;
2986 IDirect3D9_Release(d3d);
2988 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
2989 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
2990 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
2991 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
2992 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
2993 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
2994 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
2995 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %s\n", DXGetErrorString9(hr));
2996 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
2997 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %s\n", DXGetErrorString9(hr));
2998 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
2999 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %s\n", DXGetErrorString9(hr));
3000 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
3001 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %s\n", DXGetErrorString9(hr));
3002 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3003 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %s\n", DXGetErrorString9(hr));
3004 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3005 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %s\n", DXGetErrorString9(hr));
3006 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
3007 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %s\n", DXGetErrorString9(hr));
3008 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3009 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %s\n", DXGetErrorString9(hr));
3010 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3011 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3013 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3014 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %s\n", DXGetErrorString9(hr));
3015 hr = IDirect3DDevice9_CreateTexture(device, caps.MaxTextureWidth, caps.MaxTextureHeight, 1,
3016 0, fmt, D3DPOOL_MANAGED, &texture, NULL);
3017 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %s\n", DXGetErrorString9(hr));
3018 if(!texture) {
3019 skip("Failed to create the test texture\n");
3020 return;
3023 /* Unfortunately there is no easy way to set up a texture coordinate passthrough
3024 * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
3025 * 1.0 in red and green for the x and y coords
3027 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3028 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %s\n", DXGetErrorString9(hr));
3029 for(y = 0; y < caps.MaxTextureHeight; y++) {
3030 for(x = 0; x < caps.MaxTextureWidth; x++) {
3031 double r_f = (double) y / (double) caps.MaxTextureHeight;
3032 double g_f = (double) x / (double) caps.MaxTextureWidth;
3033 if(fmt == D3DFMT_A16B16G16R16) {
3034 unsigned short r, g;
3035 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
3036 r = (unsigned short) (r_f * 65536.0);
3037 g = (unsigned short) (g_f * 65536.0);
3038 dst[0] = r;
3039 dst[1] = g;
3040 dst[2] = 0;
3041 dst[3] = 65535;
3042 } else {
3043 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
3044 unsigned char r = (unsigned char) (r_f * 255.0);
3045 unsigned char g = (unsigned char) (g_f * 255.0);
3046 dst[0] = 0;
3047 dst[1] = g;
3048 dst[2] = r;
3049 dst[3] = 255;
3053 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3054 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %s\n", DXGetErrorString9(hr));
3055 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3056 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
3058 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3059 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
3060 hr = IDirect3DDevice9_BeginScene(device);
3061 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
3062 if(SUCCEEDED(hr))
3064 float quad1[] = {
3065 -1.0, -1.0, 0.1, 1.0, 1.0,
3066 -1.0, 0.0, 0.1, 1.0, 1.0,
3067 0.0, -1.0, 0.1, 1.0, 1.0,
3068 0.0, 0.0, 0.1, 1.0, 1.0,
3070 float quad2[] = {
3071 -1.0, 0.0, 0.1, 1.0, 1.0,
3072 -1.0, 1.0, 0.1, 1.0, 1.0,
3073 0.0, 0.0, 0.1, 1.0, 1.0,
3074 0.0, 1.0, 0.1, 1.0, 1.0,
3076 float quad3[] = {
3077 0.0, 0.0, 0.1, 0.5, 0.5,
3078 0.0, 1.0, 0.1, 0.5, 0.5,
3079 1.0, 0.0, 0.1, 0.5, 0.5,
3080 1.0, 1.0, 0.1, 0.5, 0.5,
3082 float quad4[] = {
3083 320, 480, 0.1, 1.0, 0.0, 1.0,
3084 320, 240, 0.1, 1.0, 0.0, 1.0,
3085 640, 480, 0.1, 1.0, 0.0, 1.0,
3086 640, 240, 0.1, 1.0, 0.0, 1.0,
3088 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3089 0.0, 0.0, 0.0, 0.0,
3090 0.0, 0.0, 0.0, 0.0,
3091 0.0, 0.0, 0.0, 0.0};
3093 /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
3094 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3095 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3096 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3097 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3099 /* What happens with transforms enabled? */
3100 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3101 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3102 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3103 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3105 /* What happens if 4 coords are used, but only 2 given ?*/
3106 mat[8] = 1.0;
3107 mat[13] = 1.0;
3108 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3109 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3110 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3111 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3112 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3113 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3115 /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
3116 * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
3117 * due to the coords in the vertices. (turns out red, indeed)
3119 memset(mat, 0, sizeof(mat));
3120 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3121 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3122 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
3123 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3124 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3125 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
3126 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3127 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3129 hr = IDirect3DDevice9_EndScene(device);
3130 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
3132 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3133 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3134 color = getPixelColor(device, 160, 360);
3135 ok(color == 0x00FFFF00 || color == 0x00FEFE00, "quad 1 has color %08x, expected 0x00FFFF00\n", color);
3136 color = getPixelColor(device, 160, 120);
3137 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3138 color = getPixelColor(device, 480, 120);
3139 ok(color == 0x0000FF00 || color == 0x0000FE00, "quad 3 has color %08x, expected 0x0000FF00\n", color);
3140 color = getPixelColor(device, 480, 360);
3141 ok(color == 0x00FF0000 || 0x00FE0000, "quad 4 has color %08x, expected 0x00FF0000\n", color);
3143 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
3144 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3146 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3147 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
3148 hr = IDirect3DDevice9_BeginScene(device);
3149 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
3150 if(SUCCEEDED(hr))
3152 float quad1[] = {
3153 -1.0, -1.0, 0.1, 0.8, 0.2,
3154 -1.0, 0.0, 0.1, 0.8, 0.2,
3155 0.0, -1.0, 0.1, 0.8, 0.2,
3156 0.0, 0.0, 0.1, 0.8, 0.2,
3158 float quad2[] = {
3159 -1.0, 0.0, 0.1, 0.5, 1.0,
3160 -1.0, 1.0, 0.1, 0.5, 1.0,
3161 0.0, 0.0, 0.1, 0.5, 1.0,
3162 0.0, 1.0, 0.1, 0.5, 1.0,
3164 float quad3[] = {
3165 0.0, 0.0, 0.1, 0.5, 1.0,
3166 0.0, 1.0, 0.1, 0.5, 1.0,
3167 1.0, 0.0, 0.1, 0.5, 1.0,
3168 1.0, 1.0, 0.1, 0.5, 1.0,
3170 float quad4[] = {
3171 0.0, -1.0, 0.1, 0.8, 0.2,
3172 0.0, 0.0, 0.1, 0.8, 0.2,
3173 1.0, -1.0, 0.1, 0.8, 0.2,
3174 1.0, 0.0, 0.1, 0.8, 0.2,
3176 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3177 0.0, 0.0, 0.0, 0.0,
3178 0.0, 1.0, 0.0, 0.0,
3179 0.0, 0.0, 0.0, 0.0};
3181 /* What happens to the default 1 in the 3rd coordinate if it is disabled?
3183 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3184 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3185 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3186 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3188 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
3189 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3191 /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
3192 * it behaves like COUNT2 because normal textures require 2 coords
3194 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3195 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3196 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
3197 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3199 /* Just to be sure, the same as quad2 above */
3200 memset(mat, 0, sizeof(mat));
3201 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
3202 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3203 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3204 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3205 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3206 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3208 /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
3209 * used? And what happens to the first?
3211 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3212 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3213 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3214 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3216 hr = IDirect3DDevice9_EndScene(device);
3217 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
3219 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3220 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3221 color = getPixelColor(device, 160, 360);
3222 ok(color == 0x00FF0000 || color == 0x00FE0000, "quad 1 has color %08x, expected 0x00FF0000\n", color);
3223 color = getPixelColor(device, 160, 120);
3224 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
3225 color = getPixelColor(device, 480, 120);
3226 ok(color == 0x00ff8000 || color == 0x00fe7f00 || color == 0x00000000,
3227 "quad 3 has color %08x, expected 0x00ff8000\n", color);
3228 color = getPixelColor(device, 480, 360);
3229 ok(color == 0x0033cc00 || color == 0x0032cb00 || color == 0x00FF0000 || color == 0x00FE0000,
3230 "quad 4 has color %08x, expected 0x0033cc00\n", color);
3232 IDirect3DTexture9_Release(texture);
3234 /* Test projected textures, without any fancy matrices */
3235 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3236 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3237 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
3238 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %s\n", DXGetErrorString9(hr));
3239 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3240 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3241 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl3);
3242 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
3244 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
3245 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %s\n", DXGetErrorString9(hr));
3246 for(x = 0; x < 4; x++) {
3247 memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
3249 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3250 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %s\n", DXGetErrorString9(hr));
3251 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3252 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
3254 hr = IDirect3DDevice9_BeginScene(device);
3255 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
3256 if(SUCCEEDED(hr))
3258 const float proj_quads[] = {
3259 -1.0, -1.0, 0.1, 0.0, 0.0, 4.0, 6.0,
3260 1.0, -1.0, 0.1, 4.0, 0.0, 4.0, 6.0,
3261 -1.0, 0.0, 0.1, 0.0, 4.0, 4.0, 6.0,
3262 1.0, 0.0, 0.1, 4.0, 4.0, 4.0, 6.0,
3263 -1.0, 0.0, 0.1, 0.0, 0.0, 4.0, 6.0,
3264 1.0, 0.0, 0.1, 4.0, 0.0, 4.0, 6.0,
3265 -1.0, 1.0, 0.1, 0.0, 4.0, 4.0, 6.0,
3266 1.0, 1.0, 0.1, 4.0, 4.0, 4.0, 6.0,
3269 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3270 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3271 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[0*7], 7 * sizeof(float));
3272 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3274 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED);
3275 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3276 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &proj_quads[4*7], 7 * sizeof(float));
3277 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
3279 hr = IDirect3DDevice9_EndScene(device);
3280 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
3283 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3284 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
3285 IDirect3DTexture9_Release(texture);
3287 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3288 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3289 color = getPixelColor(device, 158, 118);
3290 ok(color == 0x00000000, "proj: Pixel 158/118 has color 0x%08x, expected 0x00000000\n", color);
3291 color = getPixelColor(device, 162, 118);
3292 ok(color == 0x00000000, "proj: Pixel 162/118 has color 0x%08x, expected 0x00000000\n", color);
3293 color = getPixelColor(device, 158, 122);
3294 ok(color == 0x00000000, "proj: Pixel 158/122 has color 0x%08x, expected 0x00000000\n", color);
3295 color = getPixelColor(device, 162, 122);
3296 ok(color == 0x00FFFFFF, "proj: Pixel 162/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3298 color = getPixelColor(device, 158, 178);
3299 ok(color == 0x00000000, "proj: Pixel 158/178 has color 0x%08x, expected 0x00000000\n", color);
3300 color = getPixelColor(device, 162, 178);
3301 ok(color == 0x00FFFFFF, "proj: Pixel 158/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3302 color = getPixelColor(device, 158, 182);
3303 ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3304 color = getPixelColor(device, 162, 182);
3305 ok(color == 0x00000000, "proj: Pixel 158/182 has color 0x%08x, expected 0x00000000\n", color);
3307 color = getPixelColor(device, 318, 118);
3308 ok(color == 0x00000000, "proj: Pixel 318/118 has color 0x%08x, expected 0x00000000\n", color);
3309 color = getPixelColor(device, 322, 118);
3310 ok(color == 0x00000000, "proj: Pixel 322/118 has color 0x%08x, expected 0x00000000\n", color);
3311 color = getPixelColor(device, 318, 122);
3312 ok(color == 0x00FFFFFF, "proj: Pixel 318/122 has color 0x%08x, expected 0x00FFFFFF\n", color);
3313 color = getPixelColor(device, 322, 122);
3314 ok(color == 0x00000000, "proj: Pixel 322/122 has color 0x%08x, expected 0x00000000\n", color);
3316 color = getPixelColor(device, 318, 178);
3317 ok(color == 0x00FFFFFF, "proj: Pixel 318/178 has color 0x%08x, expected 0x00FFFFFF\n", color);
3318 color = getPixelColor(device, 322, 178);
3319 ok(color == 0x00000000, "proj: Pixel 322/178 has color 0x%08x, expected 0x00000000\n", color);
3320 color = getPixelColor(device, 318, 182);
3321 ok(color == 0x00000000, "proj: Pixel 318/182 has color 0x%08x, expected 0x00000000\n", color);
3322 color = getPixelColor(device, 322, 182);
3323 ok(color == 0x00000000, "proj: Pixel 322/182 has color 0x%08x, expected 0x00000000\n", color);
3325 color = getPixelColor(device, 238, 298);
3326 ok(color == 0x00000000, "proj: Pixel 238/298 has color 0x%08x, expected 0x00000000\n", color);
3327 color = getPixelColor(device, 242, 298);
3328 ok(color == 0x00000000, "proj: Pixel 242/298 has color 0x%08x, expected 0x00000000\n", color);
3329 color = getPixelColor(device, 238, 302);
3330 ok(color == 0x00000000, "proj: Pixel 238/302 has color 0x%08x, expected 0x00000000\n", color);
3331 color = getPixelColor(device, 242, 302);
3332 ok(color == 0x00FFFFFF, "proj: Pixel 242/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3334 color = getPixelColor(device, 238, 388);
3335 ok(color == 0x00000000, "proj: Pixel 238/388 has color 0x%08x, expected 0x00000000\n", color);
3336 color = getPixelColor(device, 242, 388);
3337 ok(color == 0x00FFFFFF, "proj: Pixel 242/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3338 color = getPixelColor(device, 238, 392);
3339 ok(color == 0x00000000, "proj: Pixel 238/392 has color 0x%08x, expected 0x00000000\n", color);
3340 color = getPixelColor(device, 242, 392);
3341 ok(color == 0x00000000, "proj: Pixel 242/392 has color 0x%08x, expected 0x00000000\n", color);
3343 color = getPixelColor(device, 478, 298);
3344 ok(color == 0x00000000, "proj: Pixel 478/298 has color 0x%08x, expected 0x00000000\n", color);
3345 color = getPixelColor(device, 482, 298);
3346 ok(color == 0x00000000, "proj: Pixel 482/298 has color 0x%08x, expected 0x00000000\n", color);
3347 color = getPixelColor(device, 478, 302);
3348 ok(color == 0x00FFFFFF, "proj: Pixel 478/302 has color 0x%08x, expected 0x00FFFFFF\n", color);
3349 color = getPixelColor(device, 482, 302);
3350 ok(color == 0x00000000, "proj: Pixel 482/302 has color 0x%08x, expected 0x00000000\n", color);
3352 color = getPixelColor(device, 478, 388);
3353 ok(color == 0x00FFFFFF, "proj: Pixel 478/388 has color 0x%08x, expected 0x00FFFFFF\n", color);
3354 color = getPixelColor(device, 482, 388);
3355 ok(color == 0x00000000, "proj: Pixel 482/388 has color 0x%08x, expected 0x00000000\n", color);
3356 color = getPixelColor(device, 478, 392);
3357 ok(color == 0x00000000, "proj: Pixel 478/392 has color 0x%08x, expected 0x00000000\n", color);
3358 color = getPixelColor(device, 482, 392);
3359 ok(color == 0x00000000, "proj: Pixel 482/392 has color 0x%08x, expected 0x00000000\n", color);
3361 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
3362 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3363 /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
3364 * Thus watch out if sampling from texels between 0 and 1.
3366 hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
3367 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
3368 "IDirect3DDevice9_CreateVolumeTexture failed with %s\n", DXGetErrorString9(hr));
3369 if(!volume) {
3370 skip("Failed to create a volume texture\n");
3371 goto out;
3374 hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
3375 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %s\n", DXGetErrorString9(hr));
3376 for(z = 0; z < 32; z++) {
3377 for(y = 0; y < 32; y++) {
3378 for(x = 0; x < 32; x++) {
3379 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
3380 void *mem = ((char *) lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
3381 float r_f = (float) x / 31.0;
3382 float g_f = (float) y / 31.0;
3383 float b_f = (float) z / 31.0;
3385 if(fmt == D3DFMT_A16B16G16R16) {
3386 unsigned short *mem_s = mem;
3387 mem_s[0] = r_f * 65535.0;
3388 mem_s[1] = g_f * 65535.0;
3389 mem_s[2] = b_f * 65535.0;
3390 mem_s[3] = 65535;
3391 } else {
3392 unsigned char *mem_c = mem;
3393 mem_c[0] = b_f * 255.0;
3394 mem_c[1] = g_f * 255.0;
3395 mem_c[2] = r_f * 255.0;
3396 mem_c[3] = 255;
3401 hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
3402 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %s\n", DXGetErrorString9(hr));
3404 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
3405 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %s\n", DXGetErrorString9(hr));
3407 hr = IDirect3DDevice9_BeginScene(device);
3408 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
3409 if(SUCCEEDED(hr))
3411 float quad1[] = {
3412 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3413 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3414 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3415 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
3417 float quad2[] = {
3418 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3419 -1.0, 1.0, 0.1, 1.0, 1.0, 1.0,
3420 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3421 0.0, 1.0, 0.1, 1.0, 1.0, 1.0
3423 float quad3[] = {
3424 0.0, 0.0, 0.1, 0.0, 0.0,
3425 0.0, 1.0, 0.1, 0.0, 0.0,
3426 1.0, 0.0, 0.1, 0.0, 0.0,
3427 1.0, 1.0, 0.1, 0.0, 0.0
3429 float quad4[] = {
3430 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3431 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3432 1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3433 1.0, 0.0, 0.1, 1.0, 1.0, 1.0
3435 float mat[16] = {1.0, 0.0, 0.0, 0.0,
3436 0.0, 0.0, 1.0, 0.0,
3437 0.0, 1.0, 0.0, 0.0,
3438 0.0, 0.0, 0.0, 1.0};
3439 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3440 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
3442 /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
3443 * values
3445 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3446 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3447 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3448 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3449 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3450 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3452 /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
3453 * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
3454 * otherwise the w will be missing(blue).
3455 * turns out that on nvidia cards the blue color is missing, so it is an output modification.
3456 * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3.
3458 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3459 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3460 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
3461 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3463 /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 4 */
3464 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3465 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3466 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3467 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3468 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
3469 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
3470 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
3471 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3473 /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
3474 * disable. ATI extends it up to the amount of values needed for the volume texture
3476 memset(mat, 0, sizeof(mat));
3477 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3478 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3479 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
3480 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3481 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3482 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
3483 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
3484 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3486 hr = IDirect3DDevice9_EndScene(device);
3487 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
3489 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3490 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3492 color = getPixelColor(device, 160, 360);
3493 ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
3494 color = getPixelColor(device, 160, 120);
3495 ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
3496 "quad 2 has color %08x, expected 0x00ffff00\n", color);
3497 color = getPixelColor(device, 480, 120);
3498 ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
3499 color = getPixelColor(device, 480, 360);
3500 ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
3502 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
3503 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3504 hr = IDirect3DDevice9_BeginScene(device);
3505 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
3506 if(SUCCEEDED(hr))
3508 float quad1[] = {
3509 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3510 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
3511 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
3512 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
3514 float quad2[] = {
3515 -1.0, 0.0, 0.1,
3516 -1.0, 1.0, 0.1,
3517 0.0, 0.0, 0.1,
3518 0.0, 1.0, 0.1,
3520 float quad3[] = {
3521 0.0, 0.0, 0.1, 1.0,
3522 0.0, 1.0, 0.1, 1.0,
3523 1.0, 0.0, 0.1, 1.0,
3524 1.0, 1.0, 0.1, 1.0
3526 float mat[16] = {0.0, 0.0, 0.0, 0.0,
3527 0.0, 0.0, 0.0, 0.0,
3528 0.0, 0.0, 0.0, 0.0,
3529 0.0, 1.0, 0.0, 0.0};
3530 float mat2[16] = {0.0, 0.0, 0.0, 1.0,
3531 1.0, 0.0, 0.0, 0.0,
3532 0.0, 1.0, 0.0, 0.0,
3533 0.0, 0.0, 1.0, 0.0};
3534 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
3535 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
3537 /* Default values? 4 coords used, 3 passed. What happens to the 4th?
3539 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
3540 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3541 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
3542 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3543 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
3544 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3546 /* None passed */
3547 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
3548 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3549 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3550 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
3551 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
3552 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3554 /* 4 used, 1 passed */
3555 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
3556 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
3557 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
3558 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3559 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
3560 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3562 hr = IDirect3DDevice9_EndScene(device);
3563 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
3565 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3566 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3567 color = getPixelColor(device, 160, 360);
3568 ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
3569 color = getPixelColor(device, 160, 120);
3570 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
3571 color = getPixelColor(device, 480, 120);
3572 ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
3573 /* Quad4: unused */
3575 IDirect3DVolumeTexture9_Release(volume);
3577 out:
3578 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
3579 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
3580 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
3581 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
3582 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
3583 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
3584 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
3585 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
3586 IDirect3DVertexDeclaration9_Release(decl);
3587 IDirect3DVertexDeclaration9_Release(decl2);
3588 IDirect3DVertexDeclaration9_Release(decl3);
3591 static void texdepth_test(IDirect3DDevice9 *device)
3593 IDirect3DPixelShader9 *shader;
3594 HRESULT hr;
3595 const float texdepth_test_data1[] = { 0.25, 2.0, 0.0, 0.0};
3596 const float texdepth_test_data2[] = { 0.25, 0.5, 0.0, 0.0};
3597 const float texdepth_test_data3[] = {-1.00, 0.1, 0.0, 0.0};
3598 const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
3599 const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
3600 const float texdepth_test_data6[] = { 1.00, 0.5, 0.0, 0.0};
3601 const float texdepth_test_data7[] = { 0.50, 0.0, 0.0, 0.0};
3602 DWORD shader_code[] = {
3603 0xffff0104, /* ps_1_4 */
3604 0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c1, 0, 0, 1, 1 */
3605 0x00000001, 0x800f0005, 0xa0e40000, /* mov r5, c0 */
3606 0x0000fffd, /* phase */
3607 0x00000057, 0x800f0005, /* texdepth r5 */
3608 0x00000001, 0x800f0000, 0xa0e40001, /* mov r0, c1 */
3609 0x0000ffff /* end */
3611 DWORD color;
3612 float vertex[] = {
3613 -1.0, -1.0, 0.0,
3614 1.0, -1.0, 1.0,
3615 -1.0, 1.0, 0.0,
3616 1.0, 1.0, 1.0
3619 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
3620 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3622 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
3623 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
3624 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3625 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3626 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3627 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3628 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
3629 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3630 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3632 /* Fill the depth buffer with a gradient */
3633 hr = IDirect3DDevice9_BeginScene(device);
3634 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3635 if(SUCCEEDED(hr))
3637 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3638 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3639 hr = IDirect3DDevice9_EndScene(device);
3640 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3643 /* Now perform the actual tests. Same geometry, but with the shader */
3644 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
3645 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3646 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3647 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3648 hr = IDirect3DDevice9_SetPixelShader(device, shader);
3649 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3651 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
3652 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3653 hr = IDirect3DDevice9_BeginScene(device);
3654 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3655 if(SUCCEEDED(hr))
3657 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3658 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3660 hr = IDirect3DDevice9_EndScene(device);
3661 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3664 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3665 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3666 color = getPixelColor(device, 158, 240);
3667 ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3668 color = getPixelColor(device, 162, 240);
3669 ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
3671 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3673 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
3674 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3675 hr = IDirect3DDevice9_BeginScene(device);
3676 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3677 if(SUCCEEDED(hr))
3679 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3680 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3682 hr = IDirect3DDevice9_EndScene(device);
3683 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3686 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3687 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3688 color = getPixelColor(device, 318, 240);
3689 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3690 color = getPixelColor(device, 322, 240);
3691 ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3693 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3695 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
3696 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3697 hr = IDirect3DDevice9_BeginScene(device);
3698 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3699 if(SUCCEEDED(hr))
3701 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3702 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3704 hr = IDirect3DDevice9_EndScene(device);
3705 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3707 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3708 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3710 color = getPixelColor(device, 1, 240);
3711 ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
3713 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3715 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
3716 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3717 hr = IDirect3DDevice9_BeginScene(device);
3718 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3719 if(SUCCEEDED(hr))
3721 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3722 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3724 hr = IDirect3DDevice9_EndScene(device);
3725 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3727 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3728 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3729 color = getPixelColor(device, 318, 240);
3730 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
3731 color = getPixelColor(device, 322, 240);
3732 ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
3734 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3736 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
3737 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3738 hr = IDirect3DDevice9_BeginScene(device);
3739 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3740 if(SUCCEEDED(hr))
3742 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3743 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3745 hr = IDirect3DDevice9_EndScene(device);
3746 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3748 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3749 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3751 color = getPixelColor(device, 1, 240);
3752 ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
3754 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3756 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
3757 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3758 hr = IDirect3DDevice9_BeginScene(device);
3759 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3760 if(SUCCEEDED(hr))
3762 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3763 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3765 hr = IDirect3DDevice9_EndScene(device);
3766 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3768 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3769 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3771 color = getPixelColor(device, 638, 240);
3772 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
3774 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3776 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
3777 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
3778 hr = IDirect3DDevice9_BeginScene(device);
3779 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3780 if(SUCCEEDED(hr))
3782 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
3783 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3785 hr = IDirect3DDevice9_EndScene(device);
3786 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3788 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3789 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3791 color = getPixelColor(device, 638, 240);
3792 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
3794 /* Cleanup */
3795 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3796 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
3797 IDirect3DPixelShader9_Release(shader);
3799 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
3800 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3801 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3802 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
3805 static void texkill_test(IDirect3DDevice9 *device)
3807 IDirect3DPixelShader9 *shader;
3808 HRESULT hr;
3809 DWORD color;
3811 const float vertex[] = {
3812 /* bottom top right left */
3813 -1.0, -1.0, 1.0, -0.1, 0.9, 0.9, -0.1,
3814 1.0, -1.0, 0.0, 0.9, -0.1, 0.9, -0.1,
3815 -1.0, 1.0, 1.0, -0.1, 0.9, -0.1, 0.9,
3816 1.0, 1.0, 0.0, 0.9, -0.1, -0.1, 0.9,
3819 DWORD shader_code_11[] = {
3820 0xffff0101, /* ps_1_1 */
3821 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
3822 0x00000041, 0xb00f0000, /* texkill t0 */
3823 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
3824 0x0000ffff /* end */
3826 DWORD shader_code_20[] = {
3827 0xffff0200, /* ps_2_0 */
3828 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
3829 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
3830 0x01000041, 0xb00f0000, /* texkill t0 */
3831 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
3832 0x0000ffff /* end */
3835 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
3836 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3837 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
3838 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3840 hr = IDirect3DDevice9_SetPixelShader(device, shader);
3841 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3842 hr = IDirect3DDevice9_BeginScene(device);
3843 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3844 if(SUCCEEDED(hr))
3846 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
3847 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
3848 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
3849 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3850 hr = IDirect3DDevice9_EndScene(device);
3851 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3853 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3854 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3855 color = getPixelColor(device, 63, 46);
3856 ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
3857 color = getPixelColor(device, 66, 46);
3858 ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
3859 color = getPixelColor(device, 63, 49);
3860 ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
3861 color = getPixelColor(device, 66, 49);
3862 ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
3864 color = getPixelColor(device, 578, 46);
3865 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3866 color = getPixelColor(device, 575, 46);
3867 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3868 color = getPixelColor(device, 578, 49);
3869 ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
3870 color = getPixelColor(device, 575, 49);
3871 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3873 color = getPixelColor(device, 63, 430);
3874 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3875 color = getPixelColor(device, 63, 433);
3876 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3877 color = getPixelColor(device, 66, 433);
3878 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
3879 color = getPixelColor(device, 66, 430);
3880 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3882 color = getPixelColor(device, 578, 430);
3883 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
3884 color = getPixelColor(device, 578, 433);
3885 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
3886 color = getPixelColor(device, 575, 433);
3887 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
3888 color = getPixelColor(device, 575, 430);
3889 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
3891 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3892 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3893 IDirect3DPixelShader9_Release(shader);
3895 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
3896 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
3897 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader);
3898 if(FAILED(hr)) {
3899 skip("Failed to create 2.0 test shader, most likely not supported\n");
3900 return;
3903 hr = IDirect3DDevice9_SetPixelShader(device, shader);
3904 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
3905 hr = IDirect3DDevice9_BeginScene(device);
3906 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
3907 if(SUCCEEDED(hr))
3909 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
3910 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
3911 hr = IDirect3DDevice9_EndScene(device);
3912 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
3914 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3916 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
3917 color = getPixelColor(device, 63, 46);
3918 ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
3919 color = getPixelColor(device, 66, 46);
3920 ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
3921 color = getPixelColor(device, 63, 49);
3922 ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
3923 color = getPixelColor(device, 66, 49);
3924 ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
3926 color = getPixelColor(device, 578, 46);
3927 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
3928 color = getPixelColor(device, 575, 46);
3929 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
3930 color = getPixelColor(device, 578, 49);
3931 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
3932 color = getPixelColor(device, 575, 49);
3933 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
3935 color = getPixelColor(device, 63, 430);
3936 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
3937 color = getPixelColor(device, 63, 433);
3938 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
3939 color = getPixelColor(device, 66, 433);
3940 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
3941 color = getPixelColor(device, 66, 430);
3942 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
3944 color = getPixelColor(device, 578, 430);
3945 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
3946 color = getPixelColor(device, 578, 433);
3947 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
3948 color = getPixelColor(device, 575, 433);
3949 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
3950 color = getPixelColor(device, 575, 430);
3951 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
3953 /* Cleanup */
3954 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3955 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
3956 IDirect3DPixelShader9_Release(shader);
3959 static void x8l8v8u8_test(IDirect3DDevice9 *device)
3961 IDirect3D9 *d3d9;
3962 HRESULT hr;
3963 IDirect3DTexture9 *texture;
3964 IDirect3DPixelShader9 *shader;
3965 IDirect3DPixelShader9 *shader2;
3966 D3DLOCKED_RECT lr;
3967 DWORD color;
3968 DWORD shader_code[] = {
3969 0xffff0101, /* ps_1_1 */
3970 0x00000042, 0xb00f0000, /* tex t0 */
3971 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
3972 0x0000ffff /* end */
3974 DWORD shader_code2[] = {
3975 0xffff0101, /* ps_1_1 */
3976 0x00000042, 0xb00f0000, /* tex t0 */
3977 0x00000001, 0x800f0000, 0xb0ff0000, /* mov r0, t0.w */
3978 0x0000ffff /* end */
3981 float quad[] = {
3982 -1.0, -1.0, 0.1, 0.5, 0.5,
3983 1.0, -1.0, 0.1, 0.5, 0.5,
3984 -1.0, 1.0, 0.1, 0.5, 0.5,
3985 1.0, 1.0, 0.1, 0.5, 0.5,
3988 memset(&lr, 0, sizeof(lr));
3989 IDirect3DDevice9_GetDirect3D(device, &d3d9);
3990 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
3991 0, D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8);
3992 IDirect3D9_Release(d3d9);
3993 if(FAILED(hr)) {
3994 skip("No D3DFMT_X8L8V8U8 support\n");
3997 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
3998 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4000 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8L8V8U8, D3DPOOL_MANAGED, &texture, NULL);
4001 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed (%08x)\n", hr);
4002 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4003 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed (%08x)\n", hr);
4004 *((DWORD *) lr.pBits) = 0x11ca3141;
4005 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4006 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed (%08x)\n", hr);
4008 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4009 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4010 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code2, &shader2);
4011 ok(hr == D3D_OK, "IDirect3DDevice9_CreateShader failed (%08x)\n", hr);
4013 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4014 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
4015 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4016 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4017 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4018 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4020 hr = IDirect3DDevice9_BeginScene(device);
4021 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4022 if(SUCCEEDED(hr))
4024 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4025 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4027 hr = IDirect3DDevice9_EndScene(device);
4028 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4030 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4031 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4032 color = getPixelColor(device, 578, 430);
4033 ok(color == 0x008262ca || color == 0x008363ca || color == 0x008362ca,
4034 "D3DFMT_X8L8V8U8 = 0x112131ca returns color %08x, expected 0x008262ca\n", color);
4036 hr = IDirect3DDevice9_SetPixelShader(device, shader2);
4037 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4038 hr = IDirect3DDevice9_BeginScene(device);
4039 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4040 if(SUCCEEDED(hr))
4042 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4043 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4045 hr = IDirect3DDevice9_EndScene(device);
4046 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
4048 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4049 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4050 color = getPixelColor(device, 578, 430);
4051 ok(color == 0x00ffffff, "w component of D3DFMT_X8L8V8U8 = 0x11ca3141 returns color %08x\n", color);
4053 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4054 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
4055 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4056 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
4057 IDirect3DPixelShader9_Release(shader);
4058 IDirect3DPixelShader9_Release(shader2);
4059 IDirect3DTexture9_Release(texture);
4062 static void autogen_mipmap_test(IDirect3DDevice9 *device)
4064 HRESULT hr;
4065 IDirect3D9 *d3d;
4066 IDirect3DTexture9 *texture = NULL;
4067 IDirect3DSurface9 *surface;
4068 DWORD color;
4069 const RECT r1 = {256, 256, 512, 512};
4070 const RECT r2 = {512, 256, 768, 512};
4071 const RECT r3 = {256, 512, 512, 768};
4072 const RECT r4 = {512, 512, 768, 768};
4073 unsigned int x, y;
4074 D3DLOCKED_RECT lr;
4075 memset(&lr, 0, sizeof(lr));
4077 IDirect3DDevice9_GetDirect3D(device, &d3d);
4078 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
4079 D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK) {
4080 skip("No autogenmipmap support\n");
4081 IDirect3D9_Release(d3d);
4082 return;
4084 IDirect3D9_Release(d3d);
4086 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
4087 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4089 /* Make the mipmap big, so that a smaller mipmap is used
4091 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
4092 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
4093 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %s\n", DXGetErrorString9(hr));
4095 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4096 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %s\n", DXGetErrorString9(hr));
4097 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
4098 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %s\n", DXGetErrorString9(hr));
4099 for(y = 0; y < 1024; y++) {
4100 for(x = 0; x < 1024; x++) {
4101 DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
4102 POINT pt;
4104 pt.x = x;
4105 pt.y = y;
4106 if(PtInRect(&r1, pt)) {
4107 *dst = 0xffff0000;
4108 } else if(PtInRect(&r2, pt)) {
4109 *dst = 0xff00ff00;
4110 } else if(PtInRect(&r3, pt)) {
4111 *dst = 0xff0000ff;
4112 } else if(PtInRect(&r4, pt)) {
4113 *dst = 0xff000000;
4114 } else {
4115 *dst = 0xffffffff;
4119 hr = IDirect3DSurface9_UnlockRect(surface);
4120 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %s\n", DXGetErrorString9(hr));
4121 IDirect3DSurface9_Release(surface);
4123 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4124 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
4125 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4126 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
4128 hr = IDirect3DDevice9_BeginScene(device);
4129 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4130 if(SUCCEEDED(hr)) {
4131 const float quad[] = {
4132 -0.5, -0.5, 0.1, 0.0, 0.0,
4133 -0.5, 0.5, 0.1, 0.0, 1.0,
4134 0.5, -0.5, 0.1, 1.0, 0.0,
4135 0.5, 0.5, 0.1, 1.0, 1.0
4138 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4139 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
4140 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4141 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4142 hr = IDirect3DDevice9_EndScene(device);
4143 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4145 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
4146 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
4147 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4148 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
4149 IDirect3DTexture9_Release(texture);
4151 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4152 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4153 color = getPixelColor(device, 200, 200);
4154 ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
4155 color = getPixelColor(device, 280, 200);
4156 ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
4157 color = getPixelColor(device, 360, 200);
4158 ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
4159 color = getPixelColor(device, 440, 200);
4160 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4161 color = getPixelColor(device, 200, 270);
4162 ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
4163 color = getPixelColor(device, 280, 270);
4164 ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
4165 color = getPixelColor(device, 360, 270);
4166 ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
4167 color = getPixelColor(device, 440, 270);
4168 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
4171 static void test_constant_clamp_vs(IDirect3DDevice9 *device)
4173 IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
4174 IDirect3DVertexDeclaration9 *decl;
4175 HRESULT hr;
4176 DWORD color;
4177 DWORD shader_code_11[] = {
4178 0xfffe0101, /* vs_1_1 */
4179 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4180 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4181 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4182 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4183 0x0000ffff /* end */
4185 DWORD shader_code_11_2[] = {
4186 0xfffe0101, /* vs_1_1 */
4187 0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
4188 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
4189 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4190 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4191 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4192 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4193 0x0000ffff /* end */
4195 DWORD shader_code_20[] = {
4196 0xfffe0200, /* vs_2_0 */
4197 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4198 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4199 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4200 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4201 0x0000ffff /* end */
4203 DWORD shader_code_20_2[] = {
4204 0xfffe0200, /* vs_2_0 */
4205 0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
4206 0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
4207 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4208 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4209 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4210 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4211 0x0000ffff /* end */
4213 static const D3DVERTEXELEMENT9 decl_elements[] = {
4214 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4215 D3DDECL_END()
4217 float quad1[] = {
4218 -1.0, -1.0, 0.1,
4219 0.0, -1.0, 0.1,
4220 -1.0, 0.0, 0.1,
4221 0.0, 0.0, 0.1
4223 float quad2[] = {
4224 0.0, -1.0, 0.1,
4225 1.0, -1.0, 0.1,
4226 0.0, 0.0, 0.1,
4227 1.0, 0.0, 0.1
4229 float quad3[] = {
4230 0.0, 0.0, 0.1,
4231 1.0, 0.0, 0.1,
4232 0.0, 1.0, 0.1,
4233 1.0, 1.0, 0.1
4235 float quad4[] = {
4236 -1.0, 0.0, 0.1,
4237 0.0, 0.0, 0.1,
4238 -1.0, 1.0, 0.1,
4239 0.0, 1.0, 0.1
4241 float test_data_c1[4] = { 1.25, -0.50, -1.50, 1.0};
4242 float test_data_c2[4] = { -0.50, 1.25, 2.00, 1.0};
4244 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4245 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4247 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
4248 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
4249 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
4250 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
4251 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
4252 if(FAILED(hr)) shader_20 = NULL;
4253 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
4254 if(FAILED(hr)) shader_20_2 = NULL;
4255 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4256 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
4258 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
4259 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %s\n", DXGetErrorString9(hr));
4260 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
4261 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %s\n", DXGetErrorString9(hr));
4262 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
4263 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
4265 hr = IDirect3DDevice9_BeginScene(device);
4266 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4267 if(SUCCEEDED(hr))
4269 hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
4270 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4271 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4272 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4274 hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
4275 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4276 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4277 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4279 if(shader_20) {
4280 hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
4281 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4282 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4283 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4286 if(shader_20_2) {
4287 hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
4288 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4289 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4290 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4293 hr = IDirect3DDevice9_EndScene(device);
4294 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4296 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4297 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4299 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4300 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4301 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
4302 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
4304 color = getPixelColor(device, 160, 360);
4305 ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4306 "quad 1 has color %08x, expected 0x00bfbf80\n", color);
4307 color = getPixelColor(device, 480, 360);
4308 ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4309 "quad 2 has color %08x, expected 0x00bfbf80\n", color);
4310 if(shader_20) {
4311 color = getPixelColor(device, 160, 120);
4312 ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4313 "quad 3 has color %08x, expected 0x00bfbf80\n", color);
4315 if(shader_20_2) {
4316 color = getPixelColor(device, 480, 120);
4317 ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4318 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4321 IDirect3DVertexDeclaration9_Release(decl);
4322 if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
4323 if(shader_20) IDirect3DVertexShader9_Release(shader_20);
4324 IDirect3DVertexShader9_Release(shader_11_2);
4325 IDirect3DVertexShader9_Release(shader_11);
4328 static void constant_clamp_ps_test(IDirect3DDevice9 *device)
4330 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
4331 HRESULT hr;
4332 DWORD color;
4333 DWORD shader_code_11[] = {
4334 0xffff0101, /* ps_1_1 */
4335 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4336 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4337 0x0000ffff /* end */
4339 DWORD shader_code_12[] = {
4340 0xffff0102, /* ps_1_2 */
4341 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4342 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4343 0x0000ffff /* end */
4345 /* Skip 1.3 shaders because we have only 4 quads(ok, could make them smaller if needed).
4346 * 1.2 and 1.4 shaders behave the same, so it's unlikely that 1.3 shaders are different.
4347 * During development of this test, 1.3 shaders were verified too
4349 DWORD shader_code_14[] = {
4350 0xffff0104, /* ps_1_4 */
4351 /* Try to make one constant local. It gets clamped too, although the binary contains
4352 * the bigger numbers
4354 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
4355 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4356 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4357 0x0000ffff /* end */
4359 DWORD shader_code_20[] = {
4360 0xffff0200, /* ps_2_0 */
4361 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4362 0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4363 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4364 0x0000ffff /* end */
4366 float quad1[] = {
4367 -1.0, -1.0, 0.1,
4368 0.0, -1.0, 0.1,
4369 -1.0, 0.0, 0.1,
4370 0.0, 0.0, 0.1
4372 float quad2[] = {
4373 0.0, -1.0, 0.1,
4374 1.0, -1.0, 0.1,
4375 0.0, 0.0, 0.1,
4376 1.0, 0.0, 0.1
4378 float quad3[] = {
4379 0.0, 0.0, 0.1,
4380 1.0, 0.0, 0.1,
4381 0.0, 1.0, 0.1,
4382 1.0, 1.0, 0.1
4384 float quad4[] = {
4385 -1.0, 0.0, 0.1,
4386 0.0, 0.0, 0.1,
4387 -1.0, 1.0, 0.1,
4388 0.0, 1.0, 0.1
4390 float test_data_c1[4] = { 1.25, -0.50, -1.50, 1.0};
4391 float test_data_c2[4] = { -0.50, 1.25, 2.00, 1.0};
4393 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4394 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4396 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4397 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4398 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4399 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4400 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4401 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4402 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
4403 if(FAILED(hr)) shader_20 = NULL;
4405 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4406 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
4407 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4408 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
4409 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4410 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
4412 hr = IDirect3DDevice9_BeginScene(device);
4413 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4414 if(SUCCEEDED(hr))
4416 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4417 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4418 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
4419 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4421 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4422 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4423 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
4424 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4426 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4427 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4428 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
4429 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4431 if(shader_20) {
4432 hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
4433 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4434 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
4435 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4438 hr = IDirect3DDevice9_EndScene(device);
4439 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4441 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4442 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4444 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4445 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4447 color = getPixelColor(device, 160, 360);
4448 ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4449 "quad 1 has color %08x, expected 0x00808000\n", color);
4450 color = getPixelColor(device, 480, 360);
4451 ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4452 "quad 2 has color %08x, expected 0x00808000\n", color);
4453 color = getPixelColor(device, 480, 120);
4454 ok(color == 0x00808000 || color == 0x007f7f00 || color == 0x00818100,
4455 "quad 3 has color %08x, expected 0x00808000\n", color);
4456 if(shader_20) {
4457 color = getPixelColor(device, 160, 120);
4458 ok(color == 0x00bfbf80 || color == 0x00bfbf7f || color == 0x00bfbf81,
4459 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
4462 if(shader_20) IDirect3DPixelShader9_Release(shader_20);
4463 IDirect3DPixelShader9_Release(shader_14);
4464 IDirect3DPixelShader9_Release(shader_12);
4465 IDirect3DPixelShader9_Release(shader_11);
4468 static void dp2add_ps_test(IDirect3DDevice9 *device)
4470 IDirect3DPixelShader9 *shader_dp2add = NULL;
4471 IDirect3DPixelShader9 *shader_dp2add_sat = NULL;
4472 HRESULT hr;
4473 DWORD color;
4475 /* DP2ADD is defined as: (src0.r * src1.r) + (src0.g * src1.g) + src2.
4476 * One D3D restriction of all shader instructions except SINCOS is that no more than 2
4477 * source tokens can be constants. So, for this exercise, we move contents of c0 to
4478 * r0 first.
4479 * The result here for the r,g,b components should be roughly 0.5:
4480 * (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
4481 static const DWORD shader_code_dp2add[] = {
4482 0xffff0200, /* ps_2_0 */
4483 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0 */
4485 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4486 0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add r0.rgb, r0, r0, r0.a */
4488 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
4489 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4490 0x0000ffff /* end */
4493 /* Test the _sat modifier, too. Result here should be:
4494 * DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
4495 * _SAT: ==> 1.0
4496 * ADD: (1.0 + -0.5) = 0.5
4498 static const DWORD shader_code_dp2add_sat[] = {
4499 0xffff0200, /* ps_2_0 */
4500 0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0 */
4502 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4503 0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add_sat r0.rgb, r0, r0, r0.a */
4504 0x03000002, 0x80070000, 0x80e40000, 0xa0000000, /* add r0.rgb, r0, c0.r */
4506 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
4507 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4508 0x0000ffff /* end */
4511 const float quad[] = {
4512 -1.0, -1.0, 0.1,
4513 1.0, -1.0, 0.1,
4514 -1.0, 1.0, 0.1,
4515 1.0, 1.0, 0.1
4519 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
4520 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4522 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
4523 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4525 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
4526 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4528 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4529 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
4531 if (shader_dp2add) {
4533 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
4534 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4536 hr = IDirect3DDevice9_BeginScene(device);
4537 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4538 if(SUCCEEDED(hr))
4540 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4541 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4543 hr = IDirect3DDevice9_EndScene(device);
4544 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4546 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4547 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4549 color = getPixelColor(device, 360, 240);
4550 ok(color == 0x007f7f7f || color == 0x00808080, "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4552 IDirect3DPixelShader9_Release(shader_dp2add);
4553 } else {
4554 skip("dp2add shader creation failed\n");
4557 if (shader_dp2add_sat) {
4559 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
4560 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4562 hr = IDirect3DDevice9_BeginScene(device);
4563 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4564 if(SUCCEEDED(hr))
4566 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4567 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4569 hr = IDirect3DDevice9_EndScene(device);
4570 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4572 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4573 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4575 color = getPixelColor(device, 360, 240);
4576 ok(color == 0x007f7f7f || color == 0x00808080, "dp2add pixel has color %08x, expected ~0x007f7f7f\n", color);
4578 IDirect3DPixelShader9_Release(shader_dp2add_sat);
4579 } else {
4580 skip("dp2add shader creation failed\n");
4583 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4584 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4587 static void cnd_test(IDirect3DDevice9 *device)
4589 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
4590 IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
4591 HRESULT hr;
4592 DWORD color;
4593 /* ps 1.x shaders are rather picky with writemasks and source swizzles. The dp3 is
4594 * used to copy r0.r to all components of r1, then copy r1.a to c0.a. Essentially it
4595 * does a mov r0.a, r0.r, which isn't allowed as-is in 1.x pixel shaders.
4597 DWORD shader_code_11[] = {
4598 0xffff0101, /* ps_1_1 */
4599 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4600 0x00000040, 0xb00f0000, /* texcoord t0 */
4601 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, ???(t0) */
4602 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
4603 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4604 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
4605 0x0000ffff /* end */
4607 DWORD shader_code_12[] = {
4608 0xffff0102, /* ps_1_2 */
4609 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4610 0x00000040, 0xb00f0000, /* texcoord t0 */
4611 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4612 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
4613 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4614 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
4615 0x0000ffff /* end */
4617 DWORD shader_code_13[] = {
4618 0xffff0103, /* ps_1_3 */
4619 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4620 0x00000040, 0xb00f0000, /* texcoord t0 */
4621 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4622 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3, r1, r0, c0 */
4623 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4624 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
4625 0x0000ffff /* end */
4627 DWORD shader_code_14[] = {
4628 0xffff0104, /* ps_1_3 */
4629 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
4630 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
4631 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
4632 0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0, c1, c2 */
4633 0x0000ffff /* end */
4636 /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
4637 * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
4638 * set by the compiler, it was added manually after compilation. It isn't always allowed,
4639 * only if there's a mov r0.a, XXXX, and the cnd instruction writes to r0.xyz, otherwise
4640 * native CreatePixelShader returns an error.
4642 * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
4643 * The input from t0 is [0;1]. 0.5 is substracted, then we have to multiply with 2. Since
4644 * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
4645 * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
4647 DWORD shader_code_11_coissue[] = {
4648 0xffff0101, /* ps_1_1 */
4649 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4650 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4651 0x00000040, 0xb00f0000, /* texcoord t0 */
4652 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4653 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
4654 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
4655 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
4656 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4657 /* 0x40000000 = D3DSI_COISSUE */
4658 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
4659 0x0000ffff /* end */
4661 DWORD shader_code_12_coissue[] = {
4662 0xffff0102, /* ps_1_2 */
4663 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4664 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4665 0x00000040, 0xb00f0000, /* texcoord t0 */
4666 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4667 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
4668 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
4669 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
4670 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4671 /* 0x40000000 = D3DSI_COISSUE */
4672 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
4673 0x0000ffff /* end */
4675 DWORD shader_code_13_coissue[] = {
4676 0xffff0103, /* ps_1_3 */
4677 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
4678 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
4679 0x00000040, 0xb00f0000, /* texcoord t0 */
4680 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4681 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
4682 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
4683 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3, r1, r0, r1 */
4684 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
4685 /* 0x40000000 = D3DSI_COISSUE */
4686 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0.a, c1, c2 */
4687 0x0000ffff /* end */
4689 /* ps_1_4 does not have a different cnd behavior, just pass the [0;1] texcrd result to cnd, it will
4690 * compare against 0.5
4692 DWORD shader_code_14_coissue[] = {
4693 0xffff0104, /* ps_1_4 */
4694 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
4695 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
4696 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
4697 /* 0x40000000 = D3DSI_COISSUE */
4698 0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0.xyz, r0, c1, c2 */
4699 0x0000ffff /* end */
4701 float quad1[] = {
4702 -1.0, -1.0, 0.1, 0.0, 0.0, 1.0,
4703 0.0, -1.0, 0.1, 1.0, 0.0, 1.0,
4704 -1.0, 0.0, 0.1, 0.0, 1.0, 0.0,
4705 0.0, 0.0, 0.1, 1.0, 1.0, 0.0
4707 float quad2[] = {
4708 0.0, -1.0, 0.1, 0.0, 0.0, 1.0,
4709 1.0, -1.0, 0.1, 1.0, 0.0, 1.0,
4710 0.0, 0.0, 0.1, 0.0, 1.0, 0.0,
4711 1.0, 0.0, 0.1, 1.0, 1.0, 0.0
4713 float quad3[] = {
4714 0.0, 0.0, 0.1, 0.0, 0.0, 1.0,
4715 1.0, 0.0, 0.1, 1.0, 0.0, 1.0,
4716 0.0, 1.0, 0.1, 0.0, 1.0, 0.0,
4717 1.0, 1.0, 0.1, 1.0, 1.0, 0.0
4719 float quad4[] = {
4720 -1.0, 0.0, 0.1, 0.0, 0.0, 1.0,
4721 0.0, 0.0, 0.1, 1.0, 0.0, 1.0,
4722 -1.0, 1.0, 0.1, 0.0, 1.0, 0.0,
4723 0.0, 1.0, 0.1, 1.0, 1.0, 0.0
4725 float test_data_c1[4] = { 0.0, 0.0, 0.0, 0.0};
4726 float test_data_c2[4] = { 1.0, 1.0, 1.0, 1.0};
4727 float test_data_c1_coi[4] = { 0.0, 1.0, 0.0, 0.0};
4728 float test_data_c2_coi[4] = { 1.0, 0.0, 1.0, 1.0};
4730 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4731 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4733 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
4734 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4735 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
4736 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4737 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
4738 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4739 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
4740 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4741 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
4742 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4743 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
4744 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4745 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
4746 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4747 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
4748 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
4750 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
4751 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
4752 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
4753 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
4754 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4755 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
4757 hr = IDirect3DDevice9_BeginScene(device);
4758 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4759 if(SUCCEEDED(hr))
4761 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
4762 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4763 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4764 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4766 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
4767 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4768 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4769 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4771 hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
4772 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4773 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
4774 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4776 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
4777 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4778 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4779 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4781 hr = IDirect3DDevice9_EndScene(device);
4782 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4784 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4785 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4787 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4788 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
4790 /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
4791 color = getPixelColor(device, 158, 118);
4792 ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
4793 color = getPixelColor(device, 162, 118);
4794 ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
4795 color = getPixelColor(device, 158, 122);
4796 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
4797 color = getPixelColor(device, 162, 122);
4798 ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
4800 /* 1.1 shader. All 3 components get set, based on the .w comparison */
4801 color = getPixelColor(device, 158, 358);
4802 ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
4803 color = getPixelColor(device, 162, 358);
4804 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4805 "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
4806 color = getPixelColor(device, 158, 362);
4807 ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
4808 color = getPixelColor(device, 162, 362);
4809 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4810 "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
4812 /* 1.2 shader */
4813 color = getPixelColor(device, 478, 358);
4814 ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
4815 color = getPixelColor(device, 482, 358);
4816 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4817 "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
4818 color = getPixelColor(device, 478, 362);
4819 ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
4820 color = getPixelColor(device, 482, 362);
4821 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4822 "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
4824 /* 1.3 shader */
4825 color = getPixelColor(device, 478, 118);
4826 ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
4827 color = getPixelColor(device, 482, 118);
4828 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4829 "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
4830 color = getPixelColor(device, 478, 122);
4831 ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
4832 color = getPixelColor(device, 482, 122);
4833 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) <= 0x01) && ((color & 0x000000ff) <= 0x01),
4834 "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
4836 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
4837 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4838 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
4839 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
4840 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
4841 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
4843 hr = IDirect3DDevice9_BeginScene(device);
4844 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4845 if(SUCCEEDED(hr))
4847 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
4848 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4849 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
4850 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4852 hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
4853 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4854 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
4855 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4857 hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
4858 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4859 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
4860 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4862 hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
4863 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
4864 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4865 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4867 hr = IDirect3DDevice9_EndScene(device);
4868 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4870 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4871 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4873 /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
4874 * that we swapped the values in c1 and c2 to make the other tests return some color
4876 color = getPixelColor(device, 158, 118);
4877 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
4878 color = getPixelColor(device, 162, 118);
4879 ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
4880 color = getPixelColor(device, 158, 122);
4881 ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
4882 color = getPixelColor(device, 162, 122);
4883 ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
4885 /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected */
4886 color = getPixelColor(device, 158, 358);
4887 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4888 "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
4889 color = getPixelColor(device, 162, 358);
4890 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4891 "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
4892 color = getPixelColor(device, 158, 362);
4893 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4894 "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
4895 color = getPixelColor(device, 162, 362);
4896 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4897 "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
4899 /* 1.2 shader */
4900 color = getPixelColor(device, 478, 358);
4901 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4902 "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
4903 color = getPixelColor(device, 482, 358);
4904 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4905 "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
4906 color = getPixelColor(device, 478, 362);
4907 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4908 "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
4909 color = getPixelColor(device, 482, 362);
4910 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4911 "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
4913 /* 1.3 shader */
4914 color = getPixelColor(device, 478, 118);
4915 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4916 "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
4917 color = getPixelColor(device, 482, 118);
4918 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4919 "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
4920 color = getPixelColor(device, 478, 122);
4921 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4922 "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
4923 color = getPixelColor(device, 482, 122);
4924 ok( (((color & 0x00ff0000) >> 16) <= 0x01) && (((color & 0x0000ff00) >> 8) == 0xff) && ((color & 0x000000ff) <= 0x01),
4925 "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
4927 IDirect3DPixelShader9_Release(shader_14_coissue);
4928 IDirect3DPixelShader9_Release(shader_13_coissue);
4929 IDirect3DPixelShader9_Release(shader_12_coissue);
4930 IDirect3DPixelShader9_Release(shader_11_coissue);
4931 IDirect3DPixelShader9_Release(shader_14);
4932 IDirect3DPixelShader9_Release(shader_13);
4933 IDirect3DPixelShader9_Release(shader_12);
4934 IDirect3DPixelShader9_Release(shader_11);
4937 static void nested_loop_test(IDirect3DDevice9 *device) {
4938 const DWORD shader_code[] = {
4939 0xffff0300, /* ps_3_0 */
4940 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
4941 0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
4942 0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0 */
4943 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
4944 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
4945 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
4946 0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001, /* add r0, r0, c1 */
4947 0x0000001d, /* endloop */
4948 0x0000001d, /* endloop */
4949 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4950 0x0000ffff /* end */
4952 IDirect3DPixelShader9 *shader;
4953 HRESULT hr;
4954 DWORD color;
4955 const float quad[] = {
4956 -1.0, -1.0, 0.1,
4957 1.0, -1.0, 0.1,
4958 -1.0, 1.0, 0.1,
4959 1.0, 1.0, 0.1
4962 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
4963 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %s\n", DXGetErrorString9(hr));
4964 hr = IDirect3DDevice9_SetPixelShader(device, shader);
4965 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %s\n", DXGetErrorString9(hr));
4966 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
4967 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
4968 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x0000ff00, 0.0, 0);
4969 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
4971 hr = IDirect3DDevice9_BeginScene(device);
4972 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
4973 if(SUCCEEDED(hr))
4975 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
4976 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
4977 hr = IDirect3DDevice9_EndScene(device);
4978 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
4980 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4981 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
4983 color = getPixelColor(device, 360, 240);
4984 ok(color == 0x007f0000 || color == 0x00800000 || color == 0x00810000,
4985 "Nested loop test returned color 0x%08x, expected 0x00800000\n", color);
4987 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4988 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %s\n", DXGetErrorString9(hr));
4989 IDirect3DPixelShader9_Release(shader);
4992 struct varying_test_struct
4994 const DWORD *shader_code;
4995 IDirect3DPixelShader9 *shader;
4996 DWORD color, color_rhw;
4997 const char *name;
4998 BOOL todo, todo_rhw;
5001 struct hugeVertex
5003 float pos_x, pos_y, pos_z, rhw;
5004 float weight_1, weight_2, weight_3, weight_4;
5005 float index_1, index_2, index_3, index_4;
5006 float normal_1, normal_2, normal_3, normal_4;
5007 float fog_1, fog_2, fog_3, fog_4;
5008 float texcoord_1, texcoord_2, texcoord_3, texcoord_4;
5009 float tangent_1, tangent_2, tangent_3, tangent_4;
5010 float binormal_1, binormal_2, binormal_3, binormal_4;
5011 float depth_1, depth_2, depth_3, depth_4;
5012 DWORD diffuse, specular;
5015 static void fixed_function_varying_test(IDirect3DDevice9 *device) {
5016 /* dcl_position: fails to compile */
5017 const DWORD blendweight_code[] = {
5018 0xffff0300, /* ps_3_0 */
5019 0x0200001f, 0x80000001, 0x900f0000, /* dcl_blendweight, v0 */
5020 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5021 0x0000ffff /* end */
5023 const DWORD blendindices_code[] = {
5024 0xffff0300, /* ps_3_0 */
5025 0x0200001f, 0x80000002, 0x900f0000, /* dcl_blendindices, v0 */
5026 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5027 0x0000ffff /* end */
5029 const DWORD normal_code[] = {
5030 0xffff0300, /* ps_3_0 */
5031 0x0200001f, 0x80000003, 0x900f0000, /* dcl_normal, v0 */
5032 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5033 0x0000ffff /* end */
5035 /* psize: fails? */
5036 const DWORD texcoord0_code[] = {
5037 0xffff0300, /* ps_3_0 */
5038 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0, v0 */
5039 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5040 0x0000ffff /* end */
5042 const DWORD tangent_code[] = {
5043 0xffff0300, /* ps_3_0 */
5044 0x0200001f, 0x80000006, 0x900f0000, /* dcl_tangent, v0 */
5045 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5046 0x0000ffff /* end */
5048 const DWORD binormal_code[] = {
5049 0xffff0300, /* ps_3_0 */
5050 0x0200001f, 0x80000007, 0x900f0000, /* dcl_binormal, v0 */
5051 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5052 0x0000ffff /* end */
5054 /* tessfactor: fails */
5055 /* positiont: fails */
5056 const DWORD color_code[] = {
5057 0xffff0300, /* ps_3_0 */
5058 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0, v0 */
5059 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5060 0x0000ffff /* end */
5062 const DWORD fog_code[] = {
5063 0xffff0300, /* ps_3_0 */
5064 0x0200001f, 0x8000000b, 0x900f0000, /* dcl_fog, v0 */
5065 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5066 0x0000ffff /* end */
5068 const DWORD depth_code[] = {
5069 0xffff0300, /* ps_3_0 */
5070 0x0200001f, 0x8000000c, 0x900f0000, /* dcl_depth, v0 */
5071 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5072 0x0000ffff /* end */
5074 const DWORD specular_code[] = {
5075 0xffff0300, /* ps_3_0 */
5076 0x0200001f, 0x8001000a, 0x900f0000, /* dcl_color1, v0 */
5077 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
5078 0x0000ffff /* end */
5080 /* sample: fails */
5082 struct varying_test_struct tests[] = {
5083 {blendweight_code, NULL, 0x00000000, 0x00191919, "blendweight" , FALSE, TRUE },
5084 {blendindices_code, NULL, 0x00000000, 0x00000000, "blendindices" , FALSE, FALSE },
5085 {normal_code, NULL, 0x00000000, 0x004c4c4c, "normal" , FALSE, TRUE },
5086 /* Why does dx not forward the texcoord? */
5087 {texcoord0_code, NULL, 0x00000000, 0x00808c8c, "texcoord0" , FALSE, FALSE },
5088 {tangent_code, NULL, 0x00000000, 0x00999999, "tangent" , FALSE, TRUE },
5089 {binormal_code, NULL, 0x00000000, 0x00b2b2b2, "binormal" , FALSE, TRUE },
5090 {color_code, NULL, 0x00e6e6e6, 0x00e6e6e6, "color" , FALSE, FALSE },
5091 {fog_code, NULL, 0x00000000, 0x00666666, "fog" , FALSE, TRUE },
5092 {depth_code, NULL, 0x00000000, 0x00cccccc, "depth" , FALSE, TRUE },
5093 {specular_code, NULL, 0x004488ff, 0x004488ff, "specular" , FALSE, FALSE }
5095 /* Declare a monster vertex type :-) */
5096 static const D3DVERTEXELEMENT9 decl_elements[] = {
5097 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5098 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
5099 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
5100 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
5101 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
5102 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5103 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
5104 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
5105 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
5106 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5107 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
5108 D3DDECL_END()
5110 static const D3DVERTEXELEMENT9 decl_elements2[] = {
5111 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
5112 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
5113 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
5114 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
5115 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
5116 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5117 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
5118 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
5119 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
5120 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5121 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
5122 D3DDECL_END()
5124 struct hugeVertex data[4] = {
5126 -1.0, -1.0, 0.1, 1.0,
5127 0.1, 0.1, 0.1, 0.1,
5128 0.2, 0.2, 0.2, 0.2,
5129 0.3, 0.3, 0.3, 0.3,
5130 0.4, 0.4, 0.4, 0.4,
5131 0.50, 0.55, 0.55, 0.55,
5132 0.6, 0.6, 0.6, 0.7,
5133 0.7, 0.7, 0.7, 0.6,
5134 0.8, 0.8, 0.8, 0.8,
5135 0xe6e6e6e6, /* 0.9 * 256 */
5136 0x224488ff /* Nothing special */
5139 1.0, -1.0, 0.1, 1.0,
5140 0.1, 0.1, 0.1, 0.1,
5141 0.2, 0.2, 0.2, 0.2,
5142 0.3, 0.3, 0.3, 0.3,
5143 0.4, 0.4, 0.4, 0.4,
5144 0.50, 0.55, 0.55, 0.55,
5145 0.6, 0.6, 0.6, 0.7,
5146 0.7, 0.7, 0.7, 0.6,
5147 0.8, 0.8, 0.8, 0.8,
5148 0xe6e6e6e6, /* 0.9 * 256 */
5149 0x224488ff /* Nothing special */
5152 -1.0, 1.0, 0.1, 1.0,
5153 0.1, 0.1, 0.1, 0.1,
5154 0.2, 0.2, 0.2, 0.2,
5155 0.3, 0.3, 0.3, 0.3,
5156 0.4, 0.4, 0.4, 0.4,
5157 0.50, 0.55, 0.55, 0.55,
5158 0.6, 0.6, 0.6, 0.7,
5159 0.7, 0.7, 0.7, 0.6,
5160 0.8, 0.8, 0.8, 0.8,
5161 0xe6e6e6e6, /* 0.9 * 256 */
5162 0x224488ff /* Nothing special */
5165 1.0, 1.0, 0.1, 1.0,
5166 0.1, 0.1, 0.1, 0.1,
5167 0.2, 0.2, 0.2, 0.2,
5168 0.3, 0.3, 0.3, 0.3,
5169 0.4, 0.4, 0.4, 0.4,
5170 0.50, 0.55, 0.55, 0.55,
5171 0.6, 0.6, 0.6, 0.7,
5172 0.7, 0.7, 0.7, 0.6,
5173 0.8, 0.8, 0.8, 0.8,
5174 0xe6e6e6e6, /* 0.9 * 256 */
5175 0x224488ff /* Nothing special */
5178 struct hugeVertex data2[4];
5179 IDirect3DVertexDeclaration9 *decl;
5180 IDirect3DVertexDeclaration9 *decl2;
5181 HRESULT hr;
5182 unsigned int i;
5183 DWORD color, r, g, b, r_e, g_e, b_e;
5185 memcpy(data2, data, sizeof(data2));
5186 data2[0].pos_x = 0; data2[0].pos_y = 0;
5187 data2[1].pos_x = 640; data2[1].pos_y = 0;
5188 data2[2].pos_x = 0; data2[2].pos_y = 480;
5189 data2[3].pos_x = 640; data2[3].pos_y = 480;
5191 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5192 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5193 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
5194 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5195 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5196 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5198 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5200 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
5201 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %s\n",
5202 tests[i].name, DXGetErrorString9(hr));
5205 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5207 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5208 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
5210 IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5211 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5213 hr = IDirect3DDevice9_BeginScene(device);
5214 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5215 if(SUCCEEDED(hr))
5217 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(data[0]));
5218 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5219 hr = IDirect3DDevice9_EndScene(device);
5220 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5222 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5223 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5225 color = getPixelColor(device, 360, 240);
5226 r = color & 0x00ff0000 >> 16;
5227 g = color & 0x0000ff00 >> 8;
5228 b = color & 0x000000ff;
5229 r_e = tests[i].color & 0x00ff0000 >> 16;
5230 g_e = tests[i].color & 0x0000ff00 >> 8;
5231 b_e = tests[i].color & 0x000000ff;
5233 if(tests[i].todo) {
5234 todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5235 "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5236 tests[i].name, color, tests[i].color);
5237 } else {
5238 ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5239 "Test %s returned color 0x%08x, expected 0x%08x\n",
5240 tests[i].name, color, tests[i].color);
5244 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
5245 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5246 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5248 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5249 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
5251 IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5252 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5254 hr = IDirect3DDevice9_BeginScene(device);
5255 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5256 if(SUCCEEDED(hr))
5258 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
5259 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5260 hr = IDirect3DDevice9_EndScene(device);
5261 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5263 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5264 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5266 color = getPixelColor(device, 360, 240);
5267 r = color & 0x00ff0000 >> 16;
5268 g = color & 0x0000ff00 >> 8;
5269 b = color & 0x000000ff;
5270 r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
5271 g_e = tests[i].color_rhw & 0x0000ff00 >> 8;
5272 b_e = tests[i].color_rhw & 0x000000ff;
5274 if(tests[i].todo_rhw) {
5275 /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
5276 * pipeline
5278 todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5279 "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5280 tests[i].name, color, tests[i].color_rhw);
5281 } else {
5282 ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5283 "Test %s returned color 0x%08x, expected 0x%08x\n",
5284 tests[i].name, color, tests[i].color_rhw);
5288 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5290 IDirect3DPixelShader9_Release(tests[i].shader);
5293 IDirect3DVertexDeclaration9_Release(decl2);
5294 IDirect3DVertexDeclaration9_Release(decl);
5297 static void vshader_version_varying_test(IDirect3DDevice9 *device) {
5298 static const DWORD ps_code[] = {
5299 0xffff0300, /* ps_3_0 */
5300 0x05000030, 0xf00f0000, 0x00000003, 0x00000003, 0x00000001, 0x00000000, /* defi i0, 3, 3, 1, 0 */
5301 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
5302 0x0200001f, 0x8001000a, 0x900f0003, /* dcl_color1 v3 */
5303 0x0200001f, 0x8000000b, 0x900f0004, /* dcl_fog v4 */
5304 0x0200001f, 0x80030005, 0x900f0005, /* dcl_texcoord3 v5 */
5305 0x0200001f, 0x80000003, 0x900f0006,
5306 0x0200001f, 0x80000006, 0x900f0007,
5307 0x0200001f, 0x80000001, 0x900f0008,
5308 0x0200001f, 0x8000000c, 0x900f0009,
5310 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5311 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
5312 0x04000002, 0x800f0000, 0x80e40000, 0x90e42000, 0xf0e40800, /* add r0, r0, v0[aL] */
5313 0x0000001d, /* endloop */
5314 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5315 0x0000ffff /* end */
5317 static const DWORD vs_1_code[] = {
5318 0xfffe0101, /* vs_1_1 */
5319 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5320 0x00000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0 */
5321 0x00000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0 */
5322 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0 */
5323 0x00000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
5324 0x00000001, 0xd00f0000, 0xa0e40002, /* mov oD0, c2 */
5325 0x00000001, 0xd00f0001, 0xa0e40000, /* mov oD1, c0 */
5326 0x00000001, 0xc00f0001, 0xa0550001, /* mov oFog, c1.g */
5327 0x00000001, 0xe00f0000, 0xa0e40003, /* mov oT0, c3 */
5328 0x00000001, 0xe00f0001, 0xa0e40003, /* mov oT1, c3 */
5329 0x00000001, 0xe00f0002, 0xa0e40003, /* mov oT2, c3 */
5330 0x00000001, 0xe00f0003, 0xa0e40002, /* mov oT3, c2 */
5331 0x00000001, 0xe00f0004, 0xa0e40003, /* mov oT4, c3 */
5332 0x00000001, 0xe00f0005, 0xa0e40003, /* mov oT5, c3 */
5333 0x00000001, 0xe00f0006, 0xa0e40003, /* mov oT6, c3 */
5334 0x00000001, 0xe00f0007, 0xa0e40003, /* mov oT7, c3 */
5335 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5336 0x0000ffff
5338 DWORD vs_2_code[] = {
5339 0xfffe0200, /* vs_2_0 */
5340 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5341 0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.5, 0.0, 0.0, 0.0 */
5342 0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.5, 0.0, 0.0 */
5343 0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.5, 0.0 */
5344 0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
5345 0x02000001, 0xd00f0000, 0xa0e40002, /* mov oD0, c2 */
5346 0x02000001, 0xd00f0001, 0xa0e40000, /* mov oD1, c0 */
5347 0x02000001, 0xc00f0001, 0xa0550001, /* mov oFog, c1.g */
5348 0x02000001, 0xe00f0000, 0xa0e40003, /* mov oT0, c3 */
5349 0x02000001, 0xe00f0001, 0xa0e40003, /* mov oT1, c3 */
5350 0x02000001, 0xe00f0002, 0xa0e40003, /* mov oT2, c3 */
5351 0x02000001, 0xe00f0003, 0xa0e40002, /* mov oT3, c2 */
5352 0x02000001, 0xe00f0004, 0xa0e40003, /* mov oT4, c3 */
5353 0x02000001, 0xe00f0005, 0xa0e40003, /* mov oT5, c3 */
5354 0x02000001, 0xe00f0006, 0xa0e40003, /* mov oT6, c3 */
5355 0x02000001, 0xe00f0007, 0xa0e40003, /* mov oT7, c3 */
5356 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5357 0x0000ffff /* end */
5359 /* TODO: Define normal, tangent, blendweight and depth here */
5360 static const DWORD vs_3_code[] = {
5361 0xfffe0300, /* vs_3_0 */
5362 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5363 0x0200001f, 0x8001000a, 0xe00f0009, /* dcl_color1 o9 */
5364 0x0200001f, 0x8000000b, 0xe00f0002, /* dcl_fog o2 */
5365 0x0200001f, 0x80030005, 0xe00f0005, /* dcl_texcoord3 o5 */
5366 0x0200001f, 0x80000000, 0xe00f000b, /* dcl_position o11 */
5367 0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0 */
5368 0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0 */
5369 0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0 */
5370 0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
5371 0x02000001, 0xe00f0009, 0xa0e40000, /* mov o9, c0 */
5372 0x02000001, 0xe00f0002, 0xa0e40001, /* mov o2, c1 */
5373 0x02000001, 0xe00f0005, 0xa0e40002, /* mov o5, c2 */
5374 0x02000001, 0xe00f000b, 0x90e40000, /* mov o11, v0 */
5375 0x0000ffff /* end */
5377 float quad1[] = {
5378 -1.0, -1.0, 0.1,
5379 0.0, -1.0, 0.1,
5380 -1.0, 0.0, 0.1,
5381 0.0, 0.0, 0.1
5383 float quad2[] = {
5384 0.0, -1.0, 0.1,
5385 1.0, -1.0, 0.1,
5386 0.0, 0.0, 0.1,
5387 1.0, 0.0, 0.1
5389 float quad3[] = {
5390 -1.0, 0.0, 0.1,
5391 0.0, 0.0, 0.1,
5392 -1.0, 1.0, 0.1,
5393 0.0, 1.0, 0.1
5396 HRESULT hr;
5397 DWORD color;
5398 IDirect3DPixelShader9 *pixelshader = NULL;
5399 IDirect3DVertexShader9 *vs_1_shader = NULL;
5400 IDirect3DVertexShader9 *vs_2_shader = NULL;
5401 IDirect3DVertexShader9 *vs_3_shader = NULL;
5403 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff110000, 0.0, 0);
5405 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &pixelshader);
5406 ok(hr == D3D_OK, "IDirect3DDevice_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
5407 hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_code, &vs_1_shader);
5408 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5409 hr = IDirect3DDevice9_CreateVertexShader(device, vs_2_code, &vs_2_shader);
5410 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5411 hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_code, &vs_3_shader);
5412 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5413 hr = IDirect3DDevice9_SetPixelShader(device, pixelshader);
5414 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5415 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5417 hr = IDirect3DDevice9_BeginScene(device);
5418 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5419 if(SUCCEEDED(hr))
5421 hr = IDirect3DDevice9_SetVertexShader(device, vs_1_shader);
5422 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5423 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5424 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5426 hr = IDirect3DDevice9_SetVertexShader(device, vs_2_shader);
5427 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5428 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
5429 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5431 hr = IDirect3DDevice9_SetVertexShader(device, vs_3_shader);
5432 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5433 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5434 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5436 hr = IDirect3DDevice9_EndScene(device);
5437 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5439 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5440 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5442 color = getPixelColor(device, 160, 120);
5443 ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5444 (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003500 &&
5445 (color & 0x000000ff) >= 0x00000066 && (color & 0x000000ff) <= 0x00000068,
5446 "vs_3_0 returned color 0x%08x, expected 0x00203366\n", color);
5447 color = getPixelColor(device, 160, 360);
5448 ok((color & 0x00ff0000) >= 0x003c0000 && (color & 0x00ff0000) <= 0x004e0000 &&
5449 (color & 0x0000ff00) >= 0x00000000 && (color & 0x0000ff00) <= 0x00000000 &&
5450 (color & 0x000000ff) >= 0x00000066 && (color & 0x000000ff) <= 0x00000068,
5451 "vs_1_1 returned color 0x%08x, expected 0x004c0066\n", color);
5452 color = getPixelColor(device, 480, 360);
5453 ok((color & 0x00ff0000) >= 0x003c0000 && (color & 0x00ff0000) <= 0x004e0000 &&
5454 (color & 0x0000ff00) >= 0x00000000 && (color & 0x0000ff00) <= 0x00000000 &&
5455 (color & 0x000000ff) >= 0x00000066 && (color & 0x000000ff) <= 0x00000068,
5456 "vs_2_0 returned color 0x%08x, expected 0x004c0066\n", color);
5458 /* cleanup */
5459 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5460 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5461 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5462 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5463 if(pixelshader) IDirect3DPixelShader9_Release(pixelshader);
5464 if(vs_1_shader) IDirect3DVertexShader9_Release(vs_1_shader);
5465 if(vs_2_shader) IDirect3DVertexShader9_Release(vs_2_shader);
5466 if(vs_3_shader) IDirect3DVertexShader9_Release(vs_3_shader);
5469 static void pshader_version_varying_test(IDirect3DDevice9 *device) {
5470 static const DWORD vs_code[] = {
5471 0xfffe0300, /* vs_3_0 */
5472 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5473 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5474 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */
5475 0x0200001f, 0x80000005, 0xe00f0002, /* dcl_texcoord0 o2 */
5476 0x0200001f, 0x8000000b, 0xe00f0003, /* dcl_fog o3 */
5477 0x0200001f, 0x80000003, 0xe00f0004, /* dcl_normal o4 */
5478 0x0200001f, 0x8000000c, 0xe00f0005, /* dcl_depth o5 */
5479 0x0200001f, 0x80000006, 0xe00f0006, /* dcl_tangent o6 */
5480 0x0200001f, 0x80000001, 0xe00f0007, /* dcl_blendweight o7 */
5481 0x05000051, 0xa00f0001, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c1, 0.1, 0.0, 0.0, 0.0 */
5482 0x05000051, 0xa00f0002, 0x00000000, 0x3e4ccccd, 0x00000000, 0x3f800000, /* def c2, 0.0, 0.2, 0.0, 1.0 */
5483 0x05000051, 0xa00f0003, 0x3ecccccd, 0x3f59999a, 0x3f666666, 0x00000000, /* def c3, 0.4, 0.85,0.9, 0.0 */
5484 0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0 */
5486 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5487 0x02000001, 0xe00f0001, 0xa0e40001, /* mov o1, c1 */
5488 0x02000001, 0xe00f0002, 0xa0e40002, /* mov o2, c2 */
5489 0x02000001, 0xe00f0003, 0xa0e40003, /* mov o3, c3 */
5490 0x02000001, 0xe00f0004, 0xa0e40000, /* mov o4, c0 */
5491 0x02000001, 0xe00f0005, 0xa0e40000, /* mov o5, c0 */
5492 0x02000001, 0xe00f0006, 0xa0e40000, /* mov o6, c0 */
5493 0x02000001, 0xe00f0007, 0xa0e40000, /* mov o7, c0 */
5494 0x0000ffff /* end */
5496 static const DWORD ps_1_code[] = {
5497 0xffff0104, /* ps_1_4 */
5498 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
5499 0x00000040, 0x80070001, 0xb0e40000, /* texcrd r1.xyz, t0 */
5500 0x00000001, 0x80080001, 0xa0ff0000, /* mov r1.a, c0.a */
5501 0x00000002, 0x800f0000, 0x90e40000, 0x80e40001, /* add r0, v0, r1 */
5502 0x0000ffff /* end */
5504 static const DWORD ps_2_code[] = {
5505 0xffff0200, /* ps_2_0 */
5506 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
5507 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
5508 0x0200001f, 0x80000000, 0x900f0001, /* dcl v1 */
5510 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
5511 0x03000002, 0x800f0000, 0x80e40000,0xb0e40000, /* add r0, r0, t0 */
5512 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5513 0x0000ffff /* end */
5515 static const DWORD ps_3_code[] = {
5516 0xffff0300, /* ps_3_0 */
5517 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
5518 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
5519 0x0200001f, 0x8000000b, 0x900f0002, /* dcl_fog v2 */
5521 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
5522 0x03000002, 0x800f0000, 0x80e40000, 0x90e40001, /* add r0, r0, v1 */
5523 0x03000002, 0x800f0000, 0x80e40000, 0x90e40002, /* mov r0, r0, v2 */
5524 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5525 0x0000ffff /* end */
5528 float quad1[] = {
5529 -1.0, -1.0, 0.1,
5530 0.0, -1.0, 0.1,
5531 -1.0, 0.0, 0.1,
5532 0.0, 0.0, 0.1
5534 float quad2[] = {
5535 0.0, -1.0, 0.1,
5536 1.0, -1.0, 0.1,
5537 0.0, 0.0, 0.1,
5538 1.0, 0.0, 0.1
5540 float quad3[] = {
5541 -1.0, 0.0, 0.1,
5542 0.0, 0.0, 0.1,
5543 -1.0, 1.0, 0.1,
5544 0.0, 1.0, 0.1
5546 float quad4[] = {
5547 0.0, 0.0, 0.1,
5548 1.0, 0.0, 0.1,
5549 0.0, 1.0, 0.1,
5550 1.0, 1.0, 0.1
5553 HRESULT hr;
5554 DWORD color;
5555 IDirect3DVertexShader9 *vertexshader = NULL;
5556 IDirect3DPixelShader9 *ps_1_shader = NULL;
5557 IDirect3DPixelShader9 *ps_2_shader = NULL;
5558 IDirect3DPixelShader9 *ps_3_shader = NULL;
5559 IDirect3DTexture9 *texture = NULL;
5560 D3DLOCKED_RECT lr;
5561 unsigned int x, y;
5563 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5565 hr = IDirect3DDevice9_CreateTexture(device, 512, 512, 1, 0, D3DFMT_A16B16G16R16, D3DPOOL_MANAGED, &texture, NULL);
5566 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %s\n", DXGetErrorString9(hr));
5567 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5568 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %s\n", DXGetErrorString9(hr));
5569 for(y = 0; y < 512; y++) {
5570 for(x = 0; x < 512; x++) {
5571 double r_f = (double) x / (double) 512;
5572 double g_f = (double) y / (double) 512;
5573 unsigned short *dst = (unsigned short *) (((unsigned char *) lr.pBits) + y * lr.Pitch + x * 8);
5574 unsigned short r = (unsigned short) (r_f * 65535.0);
5575 unsigned short g = (unsigned short) (g_f * 65535.0);
5576 dst[0] = r;
5577 dst[1] = g;
5578 dst[2] = 0;
5579 dst[3] = 65535;
5582 hr = IDirect3DTexture9_UnlockRect(texture, 0);
5583 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %s\n", DXGetErrorString9(hr));
5585 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vertexshader);
5586 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5587 hr = IDirect3DDevice9_CreatePixelShader(device, ps_1_code, &ps_1_shader);
5588 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
5589 hr = IDirect3DDevice9_CreatePixelShader(device, ps_2_code, &ps_2_shader);
5590 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
5591 hr = IDirect3DDevice9_CreatePixelShader(device, ps_3_code, &ps_3_shader);
5592 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
5593 hr = IDirect3DDevice9_SetVertexShader(device, vertexshader);
5594 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5595 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5597 hr = IDirect3DDevice9_BeginScene(device);
5598 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5599 if(SUCCEEDED(hr))
5601 hr = IDirect3DDevice9_SetPixelShader(device, ps_1_shader);
5602 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5603 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5604 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5606 hr = IDirect3DDevice9_SetPixelShader(device, ps_2_shader);
5607 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5608 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
5609 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5611 hr = IDirect3DDevice9_SetPixelShader(device, ps_3_shader);
5612 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5613 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5614 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5616 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5617 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5618 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5619 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
5620 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
5621 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
5622 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
5623 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
5624 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5625 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5627 hr = IDirect3DDevice9_EndScene(device);
5628 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5630 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5631 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5633 color = getPixelColor(device, 160, 120);
5634 ok((color & 0x00ff0000) >= 0x00790000 && (color & 0x00ff0000) <= 0x00810000 &&
5635 (color & 0x0000ff00) == 0x0000ff00 &&
5636 (color & 0x000000ff) >= 0x000000e4 && (color & 0x000000ff) <= 0x000000e6,
5637 "ps_3_0 returned color 0x%08x, expected 0x0080ffe5\n", color);
5638 color = getPixelColor(device, 160, 360);
5639 ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5640 (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003400 &&
5641 (color & 0x000000ff) == 0x00000000,
5642 "ps_1_4 returned color 0x%08x, expected 0x00203300\n", color);
5643 color = getPixelColor(device, 480, 360);
5644 ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5645 (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5646 (color & 0x000000ff) == 0x00000000,
5647 "ps_2_0 returned color 0x%08x, expected 0x00203300\n", color);
5648 color = getPixelColor(device, 480, 160);
5649 ok( color == 0x00ffffff /* Nvidia driver garbage with HW vp */ || (
5650 (color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5651 (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5652 (color & 0x000000ff) == 0x00000000),
5653 "fixed function fragment processing returned color 0x%08x, expected 0x00203300\n", color);
5655 /* cleanup */
5656 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5657 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
5658 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5659 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5660 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5661 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5662 if(vertexshader) IDirect3DVertexShader9_Release(vertexshader);
5663 if(ps_1_shader) IDirect3DPixelShader9_Release(ps_1_shader);
5664 if(ps_2_shader) IDirect3DPixelShader9_Release(ps_2_shader);
5665 if(ps_3_shader) IDirect3DPixelShader9_Release(ps_3_shader);
5666 if(texture) IDirect3DTexture9_Release(texture);
5669 void test_compare_instructions(IDirect3DDevice9 *device)
5671 DWORD shader_sge_vec_code[] = {
5672 0xfffe0101, /* vs_1_1 */
5673 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5674 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5675 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5676 0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001, /* sge oD0, r0, c1 */
5677 0x0000ffff /* end */
5679 DWORD shader_slt_vec_code[] = {
5680 0xfffe0101, /* vs_1_1 */
5681 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5682 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5683 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5684 0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001, /* slt oD0, r0, c1 */
5685 0x0000ffff /* end */
5687 DWORD shader_sge_scalar_code[] = {
5688 0xfffe0101, /* vs_1_1 */
5689 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5690 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5691 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5692 0x0000000d, 0xd0010000, 0x80000000, 0xa0550001, /* slt oD0.r, r0.r, c1.b */
5693 0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001, /* slt oD0.g, r0.g, c1.r */
5694 0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001, /* slt oD0.b, r0.b, c1.g */
5695 0x0000ffff /* end */
5697 DWORD shader_slt_scalar_code[] = {
5698 0xfffe0101, /* vs_1_1 */
5699 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5700 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5701 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5702 0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001, /* slt oD0.r, r0.r, c1.b */
5703 0x0000000c, 0xd0020000, 0x80550000, 0xa0000001, /* slt oD0.g, r0.g, c1.r */
5704 0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001, /* slt oD0.b, r0.b, c1.g */
5705 0x0000ffff /* end */
5707 IDirect3DVertexShader9 *shader_sge_vec;
5708 IDirect3DVertexShader9 *shader_slt_vec;
5709 IDirect3DVertexShader9 *shader_sge_scalar;
5710 IDirect3DVertexShader9 *shader_slt_scalar;
5711 HRESULT hr, color;
5712 float quad1[] = {
5713 -1.0, -1.0, 0.1,
5714 0.0, -1.0, 0.1,
5715 -1.0, 0.0, 0.1,
5716 0.0, 0.0, 0.1
5718 float quad2[] = {
5719 0.0, -1.0, 0.1,
5720 1.0, -1.0, 0.1,
5721 0.0, 0.0, 0.1,
5722 1.0, 0.0, 0.1
5724 float quad3[] = {
5725 -1.0, 0.0, 0.1,
5726 0.0, 0.0, 0.1,
5727 -1.0, 1.0, 0.1,
5728 0.0, 1.0, 0.1
5730 float quad4[] = {
5731 0.0, 0.0, 0.1,
5732 1.0, 0.0, 0.1,
5733 0.0, 1.0, 0.1,
5734 1.0, 1.0, 0.1
5736 const float const0[4] = {0.8, 0.2, 0.2, 0.2};
5737 const float const1[4] = {0.2, 0.8, 0.2, 0.2};
5739 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5741 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
5742 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5743 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
5744 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5745 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
5746 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5747 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
5748 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5749 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5750 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5751 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
5752 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5753 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5754 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
5756 hr = IDirect3DDevice9_BeginScene(device);
5757 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5758 if(SUCCEEDED(hr))
5760 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
5761 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5762 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5763 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5765 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
5766 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5767 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
5768 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5770 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
5771 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5772 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5773 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5775 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5776 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5778 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
5779 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5780 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5781 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5783 hr = IDirect3DDevice9_EndScene(device);
5784 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5787 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5788 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5790 color = getPixelColor(device, 160, 360);
5791 ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
5792 color = getPixelColor(device, 480, 360);
5793 ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
5794 color = getPixelColor(device, 160, 120);
5795 ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
5796 color = getPixelColor(device, 480, 160);
5797 ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
5799 IDirect3DVertexShader9_Release(shader_sge_vec);
5800 IDirect3DVertexShader9_Release(shader_slt_vec);
5801 IDirect3DVertexShader9_Release(shader_sge_scalar);
5802 IDirect3DVertexShader9_Release(shader_slt_scalar);
5805 void test_vshader_input(IDirect3DDevice9 *device)
5807 DWORD swapped_shader_code_3[] = {
5808 0xfffe0300, /* vs_3_0 */
5809 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5810 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
5811 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5812 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
5813 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
5814 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5815 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
5816 0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
5817 0x0000ffff /* end */
5819 DWORD swapped_shader_code_1[] = {
5820 0xfffe0101, /* vs_1_1 */
5821 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5822 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
5823 0x0000001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
5824 0x00000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
5825 0x00000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
5826 0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
5827 0x0000ffff /* end */
5829 DWORD swapped_shader_code_2[] = {
5830 0xfffe0200, /* vs_2_0 */
5831 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5832 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
5833 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
5834 0x02000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
5835 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
5836 0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
5837 0x0000ffff /* end */
5839 DWORD texcoord_color_shader_code_3[] = {
5840 0xfffe0300, /* vs_3_0 */
5841 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5842 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
5843 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5844 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
5845 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5846 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
5847 0x0000ffff /* end */
5849 DWORD texcoord_color_shader_code_2[] = {
5850 0xfffe0200, /* vs_2_0 */
5851 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5852 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
5853 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5854 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
5855 0x0000ffff /* end */
5857 DWORD texcoord_color_shader_code_1[] = {
5858 0xfffe0101, /* vs_1_1 */
5859 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5860 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
5861 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5862 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
5863 0x0000ffff /* end */
5865 DWORD color_color_shader_code_3[] = {
5866 0xfffe0300, /* vs_3_0 */
5867 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5868 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
5869 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5870 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
5871 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5872 0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001, /* mul o1, c0, v1 */
5873 0x0000ffff /* end */
5875 DWORD color_color_shader_code_2[] = {
5876 0xfffe0200, /* vs_2_0 */
5877 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5878 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
5879 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5880 0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
5881 0x0000ffff /* end */
5883 DWORD color_color_shader_code_1[] = {
5884 0xfffe0101, /* vs_1_1 */
5885 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5886 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
5887 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5888 0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
5889 0x0000ffff /* end */
5891 IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
5892 HRESULT hr;
5893 DWORD color, r, g, b;
5894 float quad1[] = {
5895 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
5896 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
5897 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
5898 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
5900 float quad2[] = {
5901 0.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
5902 1.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
5903 0.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
5904 1.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
5906 float quad3[] = {
5907 -1.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0,
5908 0.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,
5909 -1.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0,
5910 0.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0,
5912 float quad4[] = {
5913 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
5914 1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
5915 0.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
5916 1.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
5918 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
5919 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5920 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5921 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
5922 D3DDECL_END()
5924 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
5925 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5926 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
5927 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5928 D3DDECL_END()
5930 static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
5931 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5932 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5933 D3DDECL_END()
5935 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
5936 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5937 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
5938 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
5939 D3DDECL_END()
5941 static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
5942 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5943 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5944 D3DDECL_END()
5946 static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
5947 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5948 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5949 D3DDECL_END()
5951 static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
5952 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5953 {0, 12, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5954 D3DDECL_END()
5956 static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
5957 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5958 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5959 D3DDECL_END()
5961 IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
5962 IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
5963 unsigned int i;
5964 float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
5965 float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
5967 struct vertex quad1_color[] = {
5968 {-1.0, -1.0, 0.1, 0x00ff8040},
5969 { 0.0, -1.0, 0.1, 0x00ff8040},
5970 {-1.0, 0.0, 0.1, 0x00ff8040},
5971 { 0.0, 0.0, 0.1, 0x00ff8040}
5973 struct vertex quad2_color[] = {
5974 { 0.0, -1.0, 0.1, 0x00ff8040},
5975 { 1.0, -1.0, 0.1, 0x00ff8040},
5976 { 0.0, 0.0, 0.1, 0x00ff8040},
5977 { 1.0, 0.0, 0.1, 0x00ff8040}
5979 struct vertex quad3_color[] = {
5980 {-1.0, 0.0, 0.1, 0x00ff8040},
5981 { 0.0, 0.0, 0.1, 0x00ff8040},
5982 {-1.0, 1.0, 0.1, 0x00ff8040},
5983 { 0.0, 1.0, 0.1, 0x00ff8040}
5985 float quad4_color[] = {
5986 0.0, 0.0, 0.1, 1.0, 1.0, 0.0, 0.0,
5987 1.0, 0.0, 0.1, 1.0, 1.0, 0.0, 1.0,
5988 0.0, 1.0, 0.1, 1.0, 1.0, 0.0, 0.0,
5989 1.0, 1.0, 0.1, 1.0, 1.0, 0.0, 1.0,
5992 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
5993 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5994 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
5995 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5996 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
5997 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5998 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
5999 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6001 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6002 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6003 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6004 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6005 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6006 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6007 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6008 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6010 for(i = 1; i <= 3; i++) {
6011 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6012 if(i == 3) {
6013 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6014 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6015 } else if(i == 2){
6016 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6017 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6018 } else if(i == 1) {
6019 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6020 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6023 hr = IDirect3DDevice9_BeginScene(device);
6024 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
6025 if(SUCCEEDED(hr))
6027 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6028 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6030 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6031 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6032 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6033 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6035 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6036 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6037 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6038 if(i == 3 || i == 2) {
6039 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6040 } else if(i == 1) {
6041 /* Succeeds or fails, depending on SW or HW vertex processing */
6042 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6045 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6046 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6047 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6048 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6050 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6051 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6052 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6053 if(i == 3 || i == 2) {
6054 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6055 } else if(i == 1) {
6056 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6059 hr = IDirect3DDevice9_EndScene(device);
6060 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
6063 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6064 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6066 if(i == 3 || i == 2) {
6067 color = getPixelColor(device, 160, 360);
6068 ok(color == 0x00FFFF80 || color == 0x00FFFF7f || color == 0x00FFFF81,
6069 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6071 /* The last value of the read but undefined stream is used */
6072 color = getPixelColor(device, 480, 360);
6073 ok(color == 0x00FFFF00, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6074 color = getPixelColor(device, 160, 120);
6075 ok(color == 0x00FF0080 || color == 0x00FF007f || color == 0x00FF0081,
6076 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6078 color = getPixelColor(device, 480, 160);
6079 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6080 } else if(i == 1) {
6081 color = getPixelColor(device, 160, 360);
6082 ok(color == 0x00FFFF80 || color == 0x00FFFF7f || color == 0x00FFFF81,
6083 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6084 color = getPixelColor(device, 480, 360);
6085 /* Accept the clear color as well in this case, since SW VP returns an error */
6086 ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6087 color = getPixelColor(device, 160, 120);
6088 ok(color == 0x00FF0080 || color == 0x00FF0000 || color == 0x00FF007f || color == 0x00FF0081,
6089 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6090 color = getPixelColor(device, 480, 160);
6091 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6094 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6095 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
6097 /* Now find out if the whole streams are re-read, or just the last active value for the
6098 * vertices is used.
6100 hr = IDirect3DDevice9_BeginScene(device);
6101 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
6102 if(SUCCEEDED(hr))
6104 float quad1_modified[] = {
6105 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0,
6106 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0,
6107 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0,
6108 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, -1.0, -1.0, 0.0,
6110 float quad2_modified[] = {
6111 0.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6112 1.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6113 0.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6114 1.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6117 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6118 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6120 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6121 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6122 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6123 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6125 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6126 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6127 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6128 if(i == 3 || i == 2) {
6129 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6130 } else if(i == 1) {
6131 /* Succeeds or fails, depending on SW or HW vertex processing */
6132 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6135 hr = IDirect3DDevice9_EndScene(device);
6136 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
6138 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6139 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6141 color = getPixelColor(device, 480, 350);
6142 /* vs_1_1 may fail, accept the clear color
6144 * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6145 * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6146 * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6147 * refrast's result.
6149 * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6151 ok(color == 0x000000FF || color == 0x00808080,
6152 "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF\n", color);
6153 color = getPixelColor(device, 160, 120);
6155 IDirect3DDevice9_SetVertexShader(device, NULL);
6156 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6158 IDirect3DVertexShader9_Release(swapped_shader);
6161 for(i = 1; i <= 3; i++) {
6162 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6163 if(i == 3) {
6164 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6165 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6166 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6167 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6168 } else if(i == 2){
6169 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6170 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6171 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6172 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6173 } else if(i == 1) {
6174 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6175 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6176 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6177 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6180 hr = IDirect3DDevice9_BeginScene(device);
6181 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
6182 if(SUCCEEDED(hr))
6184 hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6185 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6186 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6187 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6188 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6189 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6191 hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6192 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6194 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6195 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6196 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6197 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6198 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6199 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6201 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6202 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6203 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6204 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6205 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6206 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6208 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6209 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6210 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6211 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6213 hr = IDirect3DDevice9_EndScene(device);
6214 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
6216 IDirect3DDevice9_SetVertexShader(device, NULL);
6217 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6219 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6220 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6222 color = getPixelColor(device, 160, 360);
6223 r = (color & 0x00ff0000) >> 16;
6224 g = (color & 0x0000ff00) >> 8;
6225 b = (color & 0x000000ff) >> 0;
6226 ok(r >= 0xfe && r <= 0xff && g >= 0x7f && g <= 0x81 && b >= 0x3f && b <= 0x41,
6227 "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6228 color = getPixelColor(device, 480, 360);
6229 r = (color & 0x00ff0000) >> 16;
6230 g = (color & 0x0000ff00) >> 8;
6231 b = (color & 0x000000ff) >> 0;
6232 ok(r >= 0x3f && r <= 0x41 && g >= 0x7f && g <= 0x81 && b >= 0xfe && b <= 0xff,
6233 "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6234 color = getPixelColor(device, 160, 120);
6235 r = (color & 0x00ff0000) >> 16;
6236 g = (color & 0x0000ff00) >> 8;
6237 b = (color & 0x000000ff) >> 0;
6238 ok(r >= 0xfe && r <= 0xff && g >= 0x7f && g <= 0x81 && b >= 0x3f && b <= 0x41,
6239 "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6240 color = getPixelColor(device, 480, 160);
6241 r = (color & 0x00ff0000) >> 16;
6242 g = (color & 0x0000ff00) >> 8;
6243 b = (color & 0x000000ff) >> 0;
6244 ok(r >= 0xfe && r <= 0xff && g >= 0xfe && g <= 0xff && b <= 0x01,
6245 "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6247 IDirect3DVertexShader9_Release(texcoord_color_shader);
6248 IDirect3DVertexShader9_Release(color_color_shader);
6251 IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6252 IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6253 IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6254 IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6256 IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6257 IDirect3DVertexDeclaration9_Release(decl_color_color);
6258 IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6259 IDirect3DVertexDeclaration9_Release(decl_color_float);
6262 static void srgbtexture_test(IDirect3DDevice9 *device)
6264 /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6265 * texture stage state to render a quad using that texture. The resulting
6266 * color components should be 0x36 (~ 0.21), per this formula:
6267 * linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6268 * This is true where srgb_color > 0.04045.
6270 IDirect3D9 *d3d = NULL;
6271 HRESULT hr;
6272 LPDIRECT3DTEXTURE9 texture = NULL;
6273 LPDIRECT3DSURFACE9 surface = NULL;
6274 D3DLOCKED_RECT lr;
6275 DWORD color;
6276 float quad[] = {
6277 -1.0, 1.0, 0.0, 0.0, 0.0,
6278 1.0, 1.0, 0.0, 1.0, 0.0,
6279 -1.0, -1.0, 0.0, 0.0, 1.0,
6280 1.0, -1.0, 0.0, 1.0, 1.0,
6284 memset(&lr, 0, sizeof(lr));
6285 IDirect3DDevice9_GetDirect3D(device, &d3d);
6286 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6287 D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6288 D3DFMT_A8R8G8B8) != D3D_OK) {
6289 skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6290 goto out;
6293 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6294 D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6295 &texture, NULL);
6296 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
6297 if(!texture) {
6298 skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6299 goto out;
6301 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6302 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
6304 fill_surface(surface, 0xff7f7f7f);
6305 IDirect3DSurface9_Release(surface);
6307 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6308 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6309 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6310 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
6312 hr = IDirect3DDevice9_BeginScene(device);
6313 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
6314 if(SUCCEEDED(hr))
6316 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6317 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
6319 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6320 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
6323 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6324 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
6326 hr = IDirect3DDevice9_EndScene(device);
6327 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
6330 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6331 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
6332 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6333 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
6335 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6336 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6338 color = getPixelColor(device, 320, 240);
6339 ok(color == 0x00363636, "srgb quad has color %08x, expected 0x00363636\n", color);
6341 out:
6342 if(texture) IDirect3DTexture9_Release(texture);
6343 IDirect3D9_Release(d3d);
6346 static void shademode_test(IDirect3DDevice9 *device)
6348 /* Render a quad and try all of the different fixed function shading models. */
6349 HRESULT hr;
6350 DWORD color0, color1;
6351 DWORD color0_gouraud = 0, color1_gouraud = 0;
6352 BYTE r, g, b;
6353 DWORD shademode = D3DSHADE_FLAT;
6354 DWORD primtype = D3DPT_TRIANGLESTRIP;
6355 LPVOID data = NULL;
6356 LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6357 LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6358 UINT i, j;
6359 struct vertex quad_strip[] =
6361 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
6362 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6363 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6364 { 1.0f, 1.0f, 0.0f, 0xffffffff }
6366 struct vertex quad_list[] =
6368 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
6369 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6370 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6372 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6373 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6374 { 1.0f, 1.0f, 0.0f, 0xffffffff }
6377 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6378 0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6379 ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
6380 if (FAILED(hr)) goto bail;
6382 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6383 0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6384 ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
6385 if (FAILED(hr)) goto bail;
6387 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6388 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6390 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6391 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
6393 hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), (void **) &data, 0);
6394 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
6395 memcpy(data, quad_strip, sizeof(quad_strip));
6396 hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6397 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
6399 hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), (void **) &data, 0);
6400 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
6401 memcpy(data, quad_list, sizeof(quad_list));
6402 hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6403 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
6405 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
6406 * the color fixups we have to do for FLAT shading will be dependent on that. */
6407 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6408 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6410 /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6411 for (j=0; j<2; j++) {
6413 /* Inner loop just changes the D3DRS_SHADEMODE */
6414 for (i=0; i<3; i++) {
6415 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6416 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
6418 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6419 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6421 hr = IDirect3DDevice9_BeginScene(device);
6422 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
6423 if(SUCCEEDED(hr))
6425 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
6426 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %s\n", DXGetErrorString9(hr));
6428 hr = IDirect3DDevice9_EndScene(device);
6429 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
6432 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6433 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6435 /* Sample two spots from the output */
6436 color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
6437 color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
6438 switch(shademode) {
6439 case D3DSHADE_FLAT:
6440 /* Should take the color of the first vertex of each triangle */
6441 todo_wine ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000 (todo)\n", color0);
6442 todo_wine ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00 (todo)\n", color1);
6443 shademode = D3DSHADE_GOURAUD;
6444 break;
6445 case D3DSHADE_GOURAUD:
6446 /* Should be an interpolated blend */
6448 r = (color0 & 0x00ff0000) >> 16;
6449 g = (color0 & 0x0000ff00) >> 8;
6450 b = (color0 & 0x000000ff);
6451 ok(r >= 0x0c && r <= 0x0e && g == 0xca && b >= 0x27 && b <= 0x28,
6452 "GOURAUD shading has color0 %08x, expected 0x000dca28\n", color0);
6453 r = (color1 & 0x00ff0000) >> 16;
6454 g = (color1 & 0x0000ff00) >> 8;
6455 b = (color1 & 0x000000ff);
6456 ok(r >= 0x0c && r <= 0x0d && g >= 0x44 && g <= 0x45 && b >= 0xc7 && b <= 0xc8,
6457 "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
6459 color0_gouraud = color0;
6460 color1_gouraud = color1;
6462 shademode = D3DSHADE_PHONG;
6463 break;
6464 case D3DSHADE_PHONG:
6465 /* Should be the same as GOURAUD, since no hardware implements this */
6466 r = (color0 & 0x00ff0000) >> 16;
6467 g = (color0 & 0x0000ff00) >> 8;
6468 b = (color0 & 0x000000ff);
6469 ok(r >= 0x0c && r <= 0x0e && g == 0xca && b >= 0x27 && b <= 0x28,
6470 "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
6471 r = (color1 & 0x00ff0000) >> 16;
6472 g = (color1 & 0x0000ff00) >> 8;
6473 b = (color1 & 0x000000ff);
6474 ok(r >= 0x0c && r <= 0x0d && g >= 0x44 && g <= 0x45 && b >= 0xc7 && b <= 0xc8,
6475 "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
6477 ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6478 color0_gouraud, color0);
6479 ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6480 color1_gouraud, color1);
6481 break;
6484 /* Now, do it all over again with a TRIANGLELIST */
6485 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
6486 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6487 primtype = D3DPT_TRIANGLELIST;
6488 shademode = D3DSHADE_FLAT;
6491 bail:
6492 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6493 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6494 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
6495 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6497 if (vb_strip)
6498 IDirect3DVertexBuffer9_Release(vb_strip);
6499 if (vb_list)
6500 IDirect3DVertexBuffer9_Release(vb_list);
6504 static void fog_srgbwrite_test(IDirect3DDevice9 *device)
6506 /* Draw a black quad, half fogged with white fog -> grey color. Enable sRGB writing.
6507 * if sRGB writing is applied before fogging, the 0.0 will be multiplied with ~ 12.92, so still
6508 * stay 0.0. After that the fog gives 0.5. If sRGB writing is applied after fogging, the
6509 * 0.5 will run through the alternative path(0^5 ^ 0.41666 * 1.055 - 0.055), resulting in approx.
6510 * 0.73
6512 * At the time of this writing, wined3d could not apply sRGB correction to fixed function rendering,
6513 * so use shaders for this task
6515 IDirect3DPixelShader9 *pshader;
6516 IDirect3DVertexShader9 *vshader;
6517 IDirect3D9 *d3d;
6518 DWORD vshader_code[] = {
6519 0xfffe0101, /* vs_1_1 */
6520 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6521 0x00000051, 0xa00f0000, 0x3f000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.5, 0.0, 0.0, 0.0 */
6522 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6523 0x00000001, 0xc00f0001, 0xa0000000, /* mov oFog, c0.x */
6524 0x0000ffff /* end */
6526 DWORD pshader_code[] = {
6527 0xffff0101, /* ps_1_1 */
6528 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
6529 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6530 0x0000ffff /* end */
6532 const float quad[] = {
6533 -1.0, -1.0, 0.1,
6534 1.0, -1.0, 0.1,
6535 -1.0, 1.0, 0.1,
6536 1.0, 1.0, 0.1
6538 HRESULT hr;
6539 DWORD color;
6541 IDirect3DDevice9_GetDirect3D(device, &d3d);
6542 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6543 D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE,
6544 D3DRTYPE_SURFACE, D3DFMT_A8R8G8B8) != D3D_OK) {
6545 skip("No SRGBWRITEENABLE support on D3DFMT_X8R8G8B8\n");
6546 IDirect3D9_Release(d3d);
6547 return;
6549 IDirect3D9_Release(d3d);
6551 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
6552 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
6554 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
6555 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6556 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
6557 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6558 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
6559 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6560 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffffffff);
6561 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6562 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
6563 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6565 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
6566 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6567 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code, &pshader);
6568 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
6569 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6570 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
6571 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
6572 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6573 hr = IDirect3DDevice9_SetPixelShader(device, pshader);
6574 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
6576 hr = IDirect3DDevice9_BeginScene(device);
6577 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
6578 if(SUCCEEDED(hr)) {
6579 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 3);
6580 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6582 hr = IDirect3DDevice9_EndScene(device);
6583 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
6586 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6587 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6588 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6589 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
6590 IDirect3DPixelShader9_Release(pshader);
6591 IDirect3DVertexShader9_Release(vshader);
6593 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
6594 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6595 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
6596 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6598 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6599 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6600 color = getPixelColor(device, 160, 360);
6601 ok(color == 0x00808080 || color == 0x007f7f7f || color == 0x00818181,
6602 "Fog with D3DRS_SRGBWRITEENABLE returned color 0x%08x, expected 0x00808080\n", color);
6605 static void alpha_test(IDirect3DDevice9 *device)
6607 HRESULT hr;
6608 IDirect3DTexture9 *offscreenTexture;
6609 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
6610 DWORD color, red, green, blue;
6612 struct vertex quad1[] =
6614 {-1.0f, -1.0f, 0.1f, 0x4000ff00},
6615 {-1.0f, 0.0f, 0.1f, 0x4000ff00},
6616 { 1.0f, -1.0f, 0.1f, 0x4000ff00},
6617 { 1.0f, 0.0f, 0.1f, 0x4000ff00},
6619 struct vertex quad2[] =
6621 {-1.0f, 0.0f, 0.1f, 0xc00000ff},
6622 {-1.0f, 1.0f, 0.1f, 0xc00000ff},
6623 { 1.0f, 0.0f, 0.1f, 0xc00000ff},
6624 { 1.0f, 1.0f, 0.1f, 0xc00000ff},
6626 static const float composite_quad[][5] = {
6627 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
6628 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
6629 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
6630 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
6633 /* Clear the render target with alpha = 0.5 */
6634 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6635 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6637 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
6638 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
6640 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6641 ok(hr == D3D_OK, "Can't get back buffer, hr = %s\n", DXGetErrorString9(hr));
6642 if(!backbuffer) {
6643 goto out;
6646 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
6647 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %s\n", DXGetErrorString9(hr));
6648 if(!offscreen) {
6649 goto out;
6652 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6653 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6655 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6656 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
6657 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6658 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
6659 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
6660 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
6661 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
6662 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
6663 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6664 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6666 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
6667 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6668 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
6670 /* Draw two quads, one with src alpha blending, one with dest alpha blending. The
6671 * SRCALPHA / INVSRCALPHA blend doesn't give any surprises. Colors are blended based on
6672 * the input alpha
6674 * The DESTALPHA / INVDESTALPHA do not "work" on the regular buffer because there is no alpha.
6675 * They give essentially ZERO and ONE blend factors
6677 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6678 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6679 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6680 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6681 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6682 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6684 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6685 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6686 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6687 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6688 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6689 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6691 /* Switch to the offscreen buffer, and redo the testing. SRCALPHA and DESTALPHA. The offscreen buffer
6692 * has a alpha channel on its own. Clear the offscreen buffer with alpha = 0.5 again, then draw the
6693 * quads again. The SRCALPHA/INVSRCALPHA doesn't give any surprises, but the DESTALPHA/INVDESTALPHA
6694 * blending works as supposed now - blend factor is 0.5 in both cases, not 0.75 as from the input
6695 * vertices
6697 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
6698 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6699 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6700 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6702 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6703 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6704 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6705 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6706 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6707 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6709 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6710 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6711 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6712 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6713 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6714 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6716 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
6717 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6719 /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
6720 * Disable alpha blending for the final composition
6722 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
6723 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6724 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6725 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6727 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
6728 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6729 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
6730 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6731 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6732 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6734 hr = IDirect3DDevice9_EndScene(device);
6735 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
6738 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6740 color = getPixelColor(device, 160, 360);
6741 red = (color & 0x00ff0000) >> 16;
6742 green = (color & 0x0000ff00) >> 8;
6743 blue = (color & 0x000000ff);
6744 ok(red >= 0xbe && red <= 0xc0 && green >= 0x39 && green <= 0x41 && blue == 0x00,
6745 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
6747 color = getPixelColor(device, 160, 120);
6748 red = (color & 0x00ff0000) >> 16;
6749 green = (color & 0x0000ff00) >> 8;
6750 blue = (color & 0x000000ff);
6751 ok(red == 0x00 && green == 0x00 && blue >= 0xfe && blue <= 0xff ,
6752 "DSTALPHA on frame buffer returned color %08x, expected 0x00ff0000\n", color);
6754 color = getPixelColor(device, 480, 360);
6755 red = (color & 0x00ff0000) >> 16;
6756 green = (color & 0x0000ff00) >> 8;
6757 blue = (color & 0x000000ff);
6758 ok(red >= 0xbe && red <= 0xc0 && green >= 0x39 && green <= 0x41 && blue == 0x00,
6759 "SRCALPHA on texture returned color %08x, expected bar\n", color);
6761 color = getPixelColor(device, 480, 120);
6762 red = (color & 0x00ff0000) >> 16;
6763 green = (color & 0x0000ff00) >> 8;
6764 blue = (color & 0x000000ff);
6765 ok(red >= 0x7e && red <= 0x81 && green == 0x00 && blue >= 0x7e && blue <= 0x81,
6766 "DSTALPHA on texture returned color %08x, expected 0x00800080\n", color);
6768 out:
6769 /* restore things */
6770 if(backbuffer) {
6771 IDirect3DSurface9_Release(backbuffer);
6773 if(offscreenTexture) {
6774 IDirect3DTexture9_Release(offscreenTexture);
6776 if(offscreen) {
6777 IDirect3DSurface9_Release(offscreen);
6781 struct vertex_shortcolor {
6782 float x, y, z;
6783 unsigned short r, g, b, a;
6785 struct vertex_floatcolor {
6786 float x, y, z;
6787 float r, g, b, a;
6790 static void fixed_function_decl_test(IDirect3DDevice9 *device)
6792 HRESULT hr;
6793 BOOL s_ok, ub_ok, f_ok;
6794 DWORD color, size, i;
6795 void *data;
6796 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
6797 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6798 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6799 D3DDECL_END()
6801 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
6802 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6803 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6804 D3DDECL_END()
6806 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
6807 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6808 {0, 12, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6809 D3DDECL_END()
6811 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
6812 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6813 {1, 0, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6814 D3DDECL_END()
6816 static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
6817 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6818 {0, 12, D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6819 D3DDECL_END()
6821 static const D3DVERTEXELEMENT9 decl_elements_float[] = {
6822 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6823 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6824 D3DDECL_END()
6826 static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
6827 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
6828 {0, 16, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6829 D3DDECL_END()
6831 IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
6832 IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
6833 IDirect3DVertexBuffer9 *vb, *vb2;
6834 struct vertex quad1[] = /* D3DCOLOR */
6836 {-1.0f, -1.0f, 0.1f, 0x00ffff00},
6837 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
6838 { 0.0f, -1.0f, 0.1f, 0x00ffff00},
6839 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
6841 struct vertex quad2[] = /* UBYTE4N */
6843 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
6844 {-1.0f, 1.0f, 0.1f, 0x00ffff00},
6845 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
6846 { 0.0f, 1.0f, 0.1f, 0x00ffff00},
6848 struct vertex_shortcolor quad3[] = /* short */
6850 { 0.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6851 { 0.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6852 { 1.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6853 { 1.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6855 struct vertex_floatcolor quad4[] =
6857 { 0.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6858 { 0.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6859 { 1.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6860 { 1.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6862 DWORD colors[] = {
6863 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6864 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6865 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6866 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6867 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6868 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6869 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6870 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6871 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6872 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6873 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6874 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6875 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6876 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6877 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6878 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6880 float quads[] = {
6881 -1.0, -1.0, 0.1,
6882 -1.0, 0.0, 0.1,
6883 0.0, -1.0, 0.1,
6884 0.0, 0.0, 0.1,
6886 0.0, -1.0, 0.1,
6887 0.0, 0.0, 0.1,
6888 1.0, -1.0, 0.1,
6889 1.0, 0.0, 0.1,
6891 0.0, 0.0, 0.1,
6892 0.0, 1.0, 0.1,
6893 1.0, 0.0, 0.1,
6894 1.0, 1.0, 0.1,
6896 -1.0, 0.0, 0.1,
6897 -1.0, 1.0, 0.1,
6898 0.0, 0.0, 0.1,
6899 0.0, 1.0, 0.1
6901 struct tvertex quad_transformed[] = {
6902 { 90, 110, 0.1, 2.0, 0x00ffff00},
6903 { 570, 110, 0.1, 2.0, 0x00ffff00},
6904 { 90, 300, 0.1, 2.0, 0x00ffff00},
6905 { 570, 300, 0.1, 2.0, 0x00ffff00}
6907 D3DCAPS9 caps;
6909 memset(&caps, 0, sizeof(caps));
6910 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6911 ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
6913 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6914 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6916 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
6917 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6918 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
6919 ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
6920 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
6921 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6922 if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
6923 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
6924 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6925 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
6926 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6927 } else {
6928 trace("D3DDTCAPS_UBYTE4N not supported\n");
6929 dcl_ubyte_2 = NULL;
6930 dcl_ubyte = NULL;
6932 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
6933 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6934 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
6935 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6937 size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
6938 hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
6939 0, 0, D3DPOOL_MANAGED, &vb, NULL);
6940 ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
6942 hr = IDirect3DDevice9_BeginScene(device);
6943 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
6944 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
6945 if(SUCCEEDED(hr)) {
6946 if(dcl_color) {
6947 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
6948 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6949 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6950 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6953 /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
6954 * accepts them, the nvidia driver accepts them all. All those differences even though we're
6955 * using software vertex processing. Doh!
6957 if(dcl_ubyte) {
6958 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
6959 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6960 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6961 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6962 ub_ok = SUCCEEDED(hr);
6965 if(dcl_short) {
6966 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
6967 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6968 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
6969 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6970 s_ok = SUCCEEDED(hr);
6973 if(dcl_float) {
6974 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
6975 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6976 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
6977 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6978 f_ok = SUCCEEDED(hr);
6981 hr = IDirect3DDevice9_EndScene(device);
6982 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
6985 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6986 if(dcl_short) {
6987 color = getPixelColor(device, 480, 360);
6988 ok(color == 0x000000ff || !s_ok,
6989 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
6991 if(dcl_ubyte) {
6992 color = getPixelColor(device, 160, 120);
6993 ok(color == 0x0000ffff || !ub_ok,
6994 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
6996 if(dcl_color) {
6997 color = getPixelColor(device, 160, 360);
6998 ok(color == 0x00ffff00,
6999 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7001 if(dcl_float) {
7002 color = getPixelColor(device, 480, 120);
7003 ok(color == 0x00ff0000 || !f_ok,
7004 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7007 /* The following test with vertex buffers doesn't serve to find out new information from windows.
7008 * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7009 * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7010 * whether the immediate mode code works
7012 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7013 hr = IDirect3DDevice9_BeginScene(device);
7014 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7015 if(SUCCEEDED(hr)) {
7016 if(dcl_color) {
7017 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), (void **) &data, 0);
7018 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7019 memcpy(data, quad1, sizeof(quad1));
7020 hr = IDirect3DVertexBuffer9_Unlock(vb);
7021 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7022 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7023 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7024 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7025 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7026 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7027 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7030 if(dcl_ubyte) {
7031 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), (void **) &data, 0);
7032 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7033 memcpy(data, quad2, sizeof(quad2));
7034 hr = IDirect3DVertexBuffer9_Unlock(vb);
7035 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7036 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7037 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7038 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7039 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7040 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7041 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7042 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7043 ub_ok = SUCCEEDED(hr);
7046 if(dcl_short) {
7047 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), (void **) &data, 0);
7048 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7049 memcpy(data, quad3, sizeof(quad3));
7050 hr = IDirect3DVertexBuffer9_Unlock(vb);
7051 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7052 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7053 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7054 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7055 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7056 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7057 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7058 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7059 s_ok = SUCCEEDED(hr);
7062 if(dcl_float) {
7063 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), (void **) &data, 0);
7064 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7065 memcpy(data, quad4, sizeof(quad4));
7066 hr = IDirect3DVertexBuffer9_Unlock(vb);
7067 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7068 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7069 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7070 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7071 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7072 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7073 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7074 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7075 f_ok = SUCCEEDED(hr);
7078 hr = IDirect3DDevice9_EndScene(device);
7079 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7082 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7083 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7084 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7085 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7087 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7088 if(dcl_short) {
7089 color = getPixelColor(device, 480, 360);
7090 ok(color == 0x000000ff || !s_ok,
7091 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7093 if(dcl_ubyte) {
7094 color = getPixelColor(device, 160, 120);
7095 ok(color == 0x0000ffff || !ub_ok,
7096 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7098 if(dcl_color) {
7099 color = getPixelColor(device, 160, 360);
7100 ok(color == 0x00ffff00,
7101 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7103 if(dcl_float) {
7104 color = getPixelColor(device, 480, 120);
7105 ok(color == 0x00ff0000 || !f_ok,
7106 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7109 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7110 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
7112 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), (void **) &data, 0);
7113 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7114 memcpy(data, quad_transformed, sizeof(quad_transformed));
7115 hr = IDirect3DVertexBuffer9_Unlock(vb);
7116 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7118 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7119 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7121 hr = IDirect3DDevice9_BeginScene(device);
7122 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7123 if(SUCCEEDED(hr)) {
7124 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7125 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7126 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7127 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7129 hr = IDirect3DDevice9_EndScene(device);
7130 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7133 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7134 color = getPixelColor(device, 88, 108);
7135 ok(color == 0x000000ff,
7136 "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7137 color = getPixelColor(device, 92, 108);
7138 ok(color == 0x000000ff,
7139 "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7140 color = getPixelColor(device, 88, 112);
7141 ok(color == 0x000000ff,
7142 "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7143 color = getPixelColor(device, 92, 112);
7144 ok(color == 0x00ffff00,
7145 "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7147 color = getPixelColor(device, 568, 108);
7148 ok(color == 0x000000ff,
7149 "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7150 color = getPixelColor(device, 572, 108);
7151 ok(color == 0x000000ff,
7152 "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7153 color = getPixelColor(device, 568, 112);
7154 ok(color == 0x00ffff00,
7155 "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7156 color = getPixelColor(device, 572, 112);
7157 ok(color == 0x000000ff,
7158 "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7160 color = getPixelColor(device, 88, 298);
7161 ok(color == 0x000000ff,
7162 "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7163 color = getPixelColor(device, 92, 298);
7164 ok(color == 0x00ffff00,
7165 "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7166 color = getPixelColor(device, 88, 302);
7167 ok(color == 0x000000ff,
7168 "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7169 color = getPixelColor(device, 92, 302);
7170 ok(color == 0x000000ff,
7171 "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7173 color = getPixelColor(device, 568, 298);
7174 ok(color == 0x00ffff00,
7175 "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7176 color = getPixelColor(device, 572, 298);
7177 ok(color == 0x000000ff,
7178 "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7179 color = getPixelColor(device, 568, 302);
7180 ok(color == 0x000000ff,
7181 "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7182 color = getPixelColor(device, 572, 302);
7183 ok(color == 0x000000ff,
7184 "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7186 /* This test is pointless without those two declarations: */
7187 if((!dcl_color_2) || (!dcl_ubyte_2)) {
7188 skip("color-ubyte switching test declarations aren't supported\n");
7189 goto out;
7192 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), (void **) &data, 0);
7193 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7194 memcpy(data, quads, sizeof(quads));
7195 hr = IDirect3DVertexBuffer9_Unlock(vb);
7196 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7197 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7198 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7199 ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
7200 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), (void **) &data, 0);
7201 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7202 memcpy(data, colors, sizeof(colors));
7203 hr = IDirect3DVertexBuffer9_Unlock(vb2);
7204 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7206 for(i = 0; i < 2; i++) {
7207 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7208 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
7210 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7211 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7212 if(i == 0) {
7213 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7214 } else {
7215 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7217 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7219 hr = IDirect3DDevice9_BeginScene(device);
7220 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
7221 ub_ok = FALSE;
7222 if(SUCCEEDED(hr)) {
7223 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7224 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7225 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7226 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7227 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7228 ub_ok = SUCCEEDED(hr);
7230 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7231 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7232 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7233 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7235 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7236 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7237 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7238 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7239 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7240 ub_ok = (SUCCEEDED(hr) && ub_ok);
7242 hr = IDirect3DDevice9_EndScene(device);
7243 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
7246 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7247 if(i == 0) {
7248 color = getPixelColor(device, 480, 360);
7249 ok(color == 0x00ff0000,
7250 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
7251 color = getPixelColor(device, 160, 120);
7252 ok(color == 0x00ffffff,
7253 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7254 color = getPixelColor(device, 160, 360);
7255 ok(color == 0x000000ff || !ub_ok,
7256 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7257 color = getPixelColor(device, 480, 120);
7258 ok(color == 0x000000ff || !ub_ok,
7259 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7260 } else {
7261 color = getPixelColor(device, 480, 360);
7262 ok(color == 0x000000ff,
7263 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7264 color = getPixelColor(device, 160, 120);
7265 ok(color == 0x00ffffff,
7266 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7267 color = getPixelColor(device, 160, 360);
7268 ok(color == 0x00ff0000 || !ub_ok,
7269 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7270 color = getPixelColor(device, 480, 120);
7271 ok(color == 0x00ff0000 || !ub_ok,
7272 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7276 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7277 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7278 hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7279 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7280 IDirect3DVertexBuffer9_Release(vb2);
7282 out:
7283 IDirect3DVertexBuffer9_Release(vb);
7284 if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7285 if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7286 if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7287 if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7288 if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7289 if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7290 if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7293 struct vertex_float16color {
7294 float x, y, z;
7295 DWORD c1, c2;
7298 static void test_vshader_float16(IDirect3DDevice9 *device)
7300 HRESULT hr;
7301 DWORD color;
7302 void *data;
7303 static const D3DVERTEXELEMENT9 decl_elements[] = {
7304 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7305 {0, 12, D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7306 D3DDECL_END()
7308 IDirect3DVertexDeclaration9 *vdecl = NULL;
7309 IDirect3DVertexBuffer9 *buffer = NULL;
7310 IDirect3DVertexShader9 *shader;
7311 DWORD shader_code[] = {
7312 0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7313 0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7314 0x90e40001, 0x0000ffff
7316 struct vertex_float16color quad[] = {
7317 { -1.0, -1.0, 0.1, 0x3c000000, 0x00000000 }, /* green */
7318 { -1.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
7319 { 0.0, -1.0, 0.1, 0x3c000000, 0x00000000 },
7320 { 0.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
7322 { 0.0, -1.0, 0.1, 0x00003c00, 0x00000000 }, /* red */
7323 { 0.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
7324 { 1.0, -1.0, 0.1, 0x00003c00, 0x00000000 },
7325 { 1.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
7327 { 0.0, 0.0, 0.1, 0x00000000, 0x00003c00 }, /* blue */
7328 { 0.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
7329 { 1.0, 0.0, 0.1, 0x00000000, 0x00003c00 },
7330 { 1.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
7332 { -1.0, 0.0, 0.1, 0x00000000, 0x3c000000 }, /* alpha */
7333 { -1.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
7334 { 0.0, 0.0, 0.1, 0x00000000, 0x3c000000 },
7335 { 0.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
7338 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7339 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7341 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7342 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%s\n", DXGetErrorString9(hr));
7343 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7344 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%s\n", DXGetErrorString9(hr));
7345 hr = IDirect3DDevice9_SetVertexShader(device, shader);
7346 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%s\n", DXGetErrorString9(hr));
7348 hr = IDirect3DDevice9_BeginScene(device);
7349 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
7350 if(SUCCEEDED(hr)) {
7351 hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7352 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%s\n", DXGetErrorString9(hr));
7353 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 0, sizeof(quad[0]));
7354 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7355 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 4, sizeof(quad[0]));
7356 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7357 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 8, sizeof(quad[0]));
7358 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7359 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7360 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7362 hr = IDirect3DDevice9_EndScene(device);
7363 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%s\n", DXGetErrorString9(hr));
7365 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7366 color = getPixelColor(device, 480, 360);
7367 ok(color == 0x00ff0000,
7368 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7369 color = getPixelColor(device, 160, 120);
7370 ok(color == 0x00000000,
7371 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7372 color = getPixelColor(device, 160, 360);
7373 ok(color == 0x0000ff00,
7374 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7375 color = getPixelColor(device, 480, 120);
7376 ok(color == 0x000000ff,
7377 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7379 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7380 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7382 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7383 D3DPOOL_MANAGED, &buffer, NULL);
7384 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%s\n", DXGetErrorString9(hr));
7385 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), (void **) &data, 0);
7386 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%s\n", DXGetErrorString9(hr));
7387 memcpy(data, quad, sizeof(quad));
7388 hr = IDirect3DVertexBuffer9_Unlock(buffer);
7389 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%s\n", DXGetErrorString9(hr));
7390 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7391 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%s\n", DXGetErrorString9(hr));
7393 hr = IDirect3DDevice9_BeginScene(device);
7394 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7395 if(SUCCEEDED(hr)) {
7396 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7397 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7398 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7399 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7400 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7401 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7402 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7403 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7405 hr = IDirect3DDevice9_EndScene(device);
7406 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%s\n", DXGetErrorString9(hr));
7409 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7410 color = getPixelColor(device, 480, 360);
7411 ok(color == 0x00ff0000,
7412 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7413 color = getPixelColor(device, 160, 120);
7414 ok(color == 0x00000000,
7415 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7416 color = getPixelColor(device, 160, 360);
7417 ok(color == 0x0000ff00,
7418 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7419 color = getPixelColor(device, 480, 120);
7420 ok(color == 0x000000ff,
7421 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7423 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7424 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%s\n", DXGetErrorString9(hr));
7425 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7426 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%s\n", DXGetErrorString9(hr));
7427 IDirect3DDevice9_SetVertexShader(device, NULL);
7428 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%s\n", DXGetErrorString9(hr));
7430 IDirect3DVertexDeclaration9_Release(vdecl);
7431 IDirect3DVertexShader9_Release(shader);
7432 IDirect3DVertexBuffer9_Release(buffer);
7435 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7437 D3DCAPS9 caps;
7438 IDirect3DTexture9 *texture;
7439 HRESULT hr;
7440 D3DLOCKED_RECT rect;
7441 unsigned int x, y;
7442 DWORD *dst, color;
7443 const float quad[] = {
7444 -1.0, -1.0, 0.1, -0.2, -0.2,
7445 1.0, -1.0, 0.1, 1.2, -0.2,
7446 -1.0, 1.0, 0.1, -0.2, 1.2,
7447 1.0, 1.0, 0.1, 1.2, 1.2
7449 memset(&caps, 0, sizeof(caps));
7451 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7452 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%s\n", DXGetErrorString9(hr));
7453 if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7454 /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7455 ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
7456 "Card has conditional NP2 support without power of two restriction set\n");
7457 skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
7458 return;
7459 } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7460 skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7461 return;
7464 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7465 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7467 hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7468 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%s\n", DXGetErrorString9(hr));
7470 memset(&rect, 0, sizeof(rect));
7471 hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7472 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%s\n", DXGetErrorString9(hr));
7473 for(y = 0; y < 10; y++) {
7474 for(x = 0; x < 10; x++) {
7475 dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7476 if(x == 0 || x == 9 || y == 0 || y == 9) {
7477 *dst = 0x00ff0000;
7478 } else {
7479 *dst = 0x000000ff;
7483 hr = IDirect3DTexture9_UnlockRect(texture, 0);
7484 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%s\n", DXGetErrorString9(hr));
7486 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7487 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%s\n", DXGetErrorString9(hr));
7488 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
7489 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%s\n", DXGetErrorString9(hr));
7490 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
7491 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%s\n", DXGetErrorString9(hr));
7492 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7493 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%s\n", DXGetErrorString9(hr));
7495 hr = IDirect3DDevice9_BeginScene(device);
7496 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
7497 if(SUCCEEDED(hr)) {
7498 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7499 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7501 hr = IDirect3DDevice9_EndScene(device);
7502 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
7505 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7507 color = getPixelColor(device, 1, 1);
7508 ok(color == 0x00ff0000, "NP2: Pixel 1, 1 has color %08x, expected 0x00ff0000\n", color);
7509 color = getPixelColor(device, 639, 479);
7510 ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
7512 color = getPixelColor(device, 135, 101);
7513 ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
7514 color = getPixelColor(device, 140, 101);
7515 ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
7516 color = getPixelColor(device, 135, 105);
7517 ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
7518 color = getPixelColor(device, 140, 105);
7519 ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
7521 color = getPixelColor(device, 135, 376);
7522 ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
7523 color = getPixelColor(device, 140, 376);
7524 ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
7525 color = getPixelColor(device, 135, 379);
7526 ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
7527 color = getPixelColor(device, 140, 379);
7528 ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
7530 color = getPixelColor(device, 500, 101);
7531 ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
7532 color = getPixelColor(device, 504, 101);
7533 ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
7534 color = getPixelColor(device, 500, 105);
7535 ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
7536 color = getPixelColor(device, 504, 105);
7537 ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
7539 color = getPixelColor(device, 500, 376);
7540 ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
7541 color = getPixelColor(device, 504, 376);
7542 ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
7543 color = getPixelColor(device, 500, 380);
7544 ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
7545 color = getPixelColor(device, 504, 380);
7546 ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
7548 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7549 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%s\n", DXGetErrorString9(hr));
7550 IDirect3DTexture9_Release(texture);
7553 static void vFace_register_test(IDirect3DDevice9 *device)
7555 HRESULT hr;
7556 DWORD color;
7557 const DWORD shader_code[] = {
7558 0xffff0300, /* ps_3_0 */
7559 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
7560 0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
7561 0x0200001f, 0x80000000, 0x900f1001, /* dcl vFace */
7562 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
7563 0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001, /* cmp r0, vFace, c0, r1 */
7564 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
7565 0x0000ffff /* END */
7567 IDirect3DPixelShader9 *shader;
7568 IDirect3DTexture9 *texture;
7569 IDirect3DSurface9 *surface, *backbuffer;
7570 const float quad[] = {
7571 -1.0, -1.0, 0.1,
7572 1.0, -1.0, 0.1,
7573 -1.0, 0.0, 0.1,
7575 1.0, -1.0, 0.1,
7576 1.0, 0.0, 0.1,
7577 -1.0, 0.0, 0.1,
7579 -1.0, 0.0, 0.1,
7580 -1.0, 1.0, 0.1,
7581 1.0, 0.0, 0.1,
7583 1.0, 0.0, 0.1,
7584 -1.0, 1.0, 0.1,
7585 1.0, 1.0, 0.1,
7587 const float blit[] = {
7588 0.0, -1.0, 0.1, 0.0, 0.0,
7589 1.0, -1.0, 0.1, 1.0, 0.0,
7590 0.0, 1.0, 0.1, 0.0, 1.0,
7591 1.0, 1.0, 0.1, 1.0, 1.0,
7594 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
7595 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%s\n", DXGetErrorString9(hr));
7596 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
7597 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%s\n", DXGetErrorString9(hr));
7598 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7599 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%s\n", DXGetErrorString9(hr));
7600 hr = IDirect3DDevice9_SetPixelShader(device, shader);
7601 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
7602 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7603 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%s\n", DXGetErrorString9(hr));
7604 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7605 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%s\n", DXGetErrorString9(hr));
7607 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7608 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7610 hr = IDirect3DDevice9_BeginScene(device);
7611 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
7612 if(SUCCEEDED(hr)) {
7613 /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
7614 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
7615 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
7616 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7617 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7618 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7619 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7620 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7621 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
7622 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7623 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7625 /* Blit the texture onto the back buffer to make it visible */
7626 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7627 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%s\n", DXGetErrorString9(hr));
7628 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7629 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%s\n", DXGetErrorString9(hr));
7630 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7631 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%s\n", DXGetErrorString9(hr));
7632 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7633 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%s\n", DXGetErrorString9(hr));
7634 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7635 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%s\n", DXGetErrorString9(hr));
7637 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
7638 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7640 hr = IDirect3DDevice9_EndScene(device);
7641 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
7644 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7645 color = getPixelColor(device, 160, 360);
7646 ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7647 color = getPixelColor(device, 160, 120);
7648 ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7649 color = getPixelColor(device, 480, 360);
7650 ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7651 color = getPixelColor(device, 480, 120);
7652 ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7654 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
7655 IDirect3DDevice9_SetTexture(device, 0, NULL);
7656 IDirect3DPixelShader9_Release(shader);
7657 IDirect3DSurface9_Release(surface);
7658 IDirect3DSurface9_Release(backbuffer);
7659 IDirect3DTexture9_Release(texture);
7662 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
7664 HRESULT hr;
7665 DWORD color;
7666 int i;
7667 D3DCAPS9 caps;
7669 static const float quad[][7] = {
7670 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
7671 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
7672 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
7673 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
7676 static const D3DVERTEXELEMENT9 decl_elements[] = {
7677 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7678 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7679 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7680 D3DDECL_END()
7683 /* use asymmetric matrix to test loading */
7684 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
7686 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
7687 IDirect3DTexture9 *texture = NULL;
7689 memset(&caps, 0, sizeof(caps));
7690 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7691 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%s\n", DXGetErrorString9(hr));
7692 if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
7693 skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
7694 return;
7695 } else {
7696 /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
7697 * They report that it is not supported, but after that bump mapping works properly. So just test
7698 * if the format is generally supported, and check the BUMPENVMAP flag
7700 IDirect3D9 *d3d9;
7702 IDirect3DDevice9_GetDirect3D(device, &d3d9);
7703 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7704 D3DRTYPE_TEXTURE, D3DFMT_V8U8);
7705 IDirect3D9_Release(d3d9);
7706 if(FAILED(hr)) {
7707 skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
7708 return;
7712 /* Generate the textures */
7713 generate_bumpmap_textures(device);
7715 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
7716 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7717 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
7718 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7719 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
7720 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7721 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
7722 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7724 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
7725 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7726 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
7727 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7728 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
7729 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7731 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7732 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7733 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7734 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7735 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7736 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7738 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
7739 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7741 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7742 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
7744 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
7745 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
7748 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
7749 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
7750 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
7751 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
7753 hr = IDirect3DDevice9_BeginScene(device);
7754 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7756 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7757 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7759 hr = IDirect3DDevice9_EndScene(device);
7760 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7762 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7763 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7765 color = getPixelColor(device, 320-32, 240);
7766 ok(color == 0x00ffffff, "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7767 color = getPixelColor(device, 320+32, 240);
7768 ok(color == 0x00ffffff, "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7769 color = getPixelColor(device, 320, 240-32);
7770 ok(color == 0x00ffffff, "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7771 color = getPixelColor(device, 320, 240+32);
7772 ok(color == 0x00ffffff, "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7773 color = getPixelColor(device, 320, 240);
7774 ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7775 color = getPixelColor(device, 320+32, 240+32);
7776 ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7777 color = getPixelColor(device, 320-32, 240+32);
7778 ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7779 color = getPixelColor(device, 320+32, 240-32);
7780 ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7781 color = getPixelColor(device, 320-32, 240-32);
7782 ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7784 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7785 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
7786 IDirect3DVertexDeclaration9_Release(vertex_declaration);
7788 for(i = 0; i < 2; i++) {
7789 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
7790 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
7791 IDirect3DTexture9_Release(texture); /* For the GetTexture */
7792 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
7793 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
7794 IDirect3DTexture9_Release(texture); /* To destroy it */
7797 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
7798 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7799 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
7800 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7804 static void stencil_cull_test(IDirect3DDevice9 *device) {
7805 HRESULT hr;
7806 IDirect3DSurface9 *depthstencil = NULL;
7807 D3DSURFACE_DESC desc;
7808 float quad1[] = {
7809 -1.0, -1.0, 0.1,
7810 0.0, -1.0, 0.1,
7811 -1.0, 0.0, 0.1,
7812 0.0, 0.0, 0.1,
7814 float quad2[] = {
7815 0.0, -1.0, 0.1,
7816 1.0, -1.0, 0.1,
7817 0.0, 0.0, 0.1,
7818 1.0, 0.0, 0.1,
7820 float quad3[] = {
7821 0.0, 0.0, 0.1,
7822 1.0, 0.0, 0.1,
7823 0.0, 1.0, 0.1,
7824 1.0, 1.0, 0.1,
7826 float quad4[] = {
7827 -1.0, 0.0, 0.1,
7828 0.0, 0.0, 0.1,
7829 -1.0, 1.0, 0.1,
7830 0.0, 1.0, 0.1,
7832 struct vertex painter[] = {
7833 {-1.0, -1.0, 0.0, 0x00000000},
7834 { 1.0, -1.0, 0.0, 0x00000000},
7835 {-1.0, 1.0, 0.0, 0x00000000},
7836 { 1.0, 1.0, 0.0, 0x00000000},
7838 WORD indices_cw[] = {0, 1, 3};
7839 WORD indices_ccw[] = {0, 2, 3};
7840 unsigned int i;
7841 DWORD color;
7843 IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
7844 if(depthstencil == NULL) {
7845 skip("No depth stencil buffer\n");
7846 return;
7848 hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
7849 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %s\n", DXGetErrorString9(hr));
7850 IDirect3DSurface9_Release(depthstencil);
7851 if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
7852 skip("No 4 or 8 bit stencil surface\n");
7853 return;
7856 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
7857 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
7858 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7860 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
7861 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7862 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
7863 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7864 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
7865 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7866 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
7867 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7869 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
7870 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7871 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
7872 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7873 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
7874 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7876 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
7877 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7878 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
7879 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7881 /* First pass: Fill the stencil buffer with some values... */
7882 hr = IDirect3DDevice9_BeginScene(device);
7883 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
7884 if(SUCCEEDED(hr))
7886 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
7887 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7888 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7889 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
7890 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7891 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
7893 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
7894 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7895 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
7896 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7897 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7898 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
7899 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7900 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
7902 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
7903 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7904 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7905 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
7906 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7907 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
7909 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
7910 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7911 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7912 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
7913 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7914 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
7916 hr = IDirect3DDevice9_EndScene(device);
7917 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
7920 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7921 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
7922 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7923 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
7924 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7925 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
7926 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7927 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
7928 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7929 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
7930 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7931 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
7932 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7934 /* 2nd pass: Make the stencil values visible */
7935 hr = IDirect3DDevice9_BeginScene(device);
7936 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
7937 if(SUCCEEDED(hr))
7939 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
7940 for(i = 0; i < 16; i++) {
7941 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
7942 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7944 painter[0].diffuse = (i * 16); /* Creates shades of blue */
7945 painter[1].diffuse = (i * 16);
7946 painter[2].diffuse = (i * 16);
7947 painter[3].diffuse = (i * 16);
7948 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
7949 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
7951 hr = IDirect3DDevice9_EndScene(device);
7952 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
7955 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7956 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
7958 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
7959 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7961 color = getPixelColor(device, 160, 420);
7962 ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
7963 color = getPixelColor(device, 160, 300);
7964 ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
7966 color = getPixelColor(device, 480, 420);
7967 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
7968 color = getPixelColor(device, 480, 300);
7969 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
7971 color = getPixelColor(device, 160, 180);
7972 ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
7973 color = getPixelColor(device, 160, 60);
7974 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
7976 color = getPixelColor(device, 480, 180);
7977 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
7978 color = getPixelColor(device, 480, 60);
7979 ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
7982 static void vpos_register_test(IDirect3DDevice9 *device)
7984 HRESULT hr;
7985 DWORD color;
7986 const DWORD shader_code[] = {
7987 0xffff0300, /* ps_3_0 */
7988 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
7989 0x03000002, 0x80030000, 0x90541000, 0xa1fe0000, /* sub r0.xy, vPos.xy, c0.zw */
7990 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
7991 0x02000001, 0x80080002, 0xa0550000, /* mov r2.a, c0.y */
7992 0x02000001, 0x80010002, 0xa0550000, /* mov r2.r, c0.y */
7993 0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001, /* cmp r2.g, r0.x, r1.x, r1.y */
7994 0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001, /* cmp r2.b, r0.y, r1.x, r1.y */
7995 0x02000001, 0x800f0800, 0x80e40002, /* mov oC0, r2 */
7996 0x0000ffff /* end */
7998 const DWORD shader_frac_code[] = {
7999 0xffff0300, /* ps_3_0 */
8000 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8001 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8002 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
8003 0x02000013, 0x80030000, 0x90541000, /* frc r0.xy, vPos.xy */
8004 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
8005 0x0000ffff /* end */
8007 IDirect3DPixelShader9 *shader, *shader_frac;
8008 IDirect3DSurface9 *surface = NULL, *backbuffer;
8009 const float quad[] = {
8010 -1.0, -1.0, 0.1, 0.0, 0.0,
8011 1.0, -1.0, 0.1, 1.0, 0.0,
8012 -1.0, 1.0, 0.1, 0.0, 1.0,
8013 1.0, 1.0, 0.1, 1.0, 1.0,
8015 D3DLOCKED_RECT lr;
8016 float constant[4] = {1.0, 0.0, 320, 240};
8017 DWORD *pos;
8019 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8020 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
8021 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8022 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%s\n", DXGetErrorString9(hr));
8023 hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8024 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%s\n", DXGetErrorString9(hr));
8025 hr = IDirect3DDevice9_SetPixelShader(device, shader);
8026 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
8027 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8028 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%s\n", DXGetErrorString9(hr));
8029 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8030 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%s\n", DXGetErrorString9(hr));
8032 hr = IDirect3DDevice9_BeginScene(device);
8033 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
8034 if(SUCCEEDED(hr)) {
8035 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8036 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%s\n", DXGetErrorString9(hr));
8037 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8038 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8039 hr = IDirect3DDevice9_EndScene(device);
8040 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
8043 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8044 /* This has to be pixel exact */
8045 color = getPixelColor(device, 319, 239);
8046 ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8047 color = getPixelColor(device, 320, 239);
8048 ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8049 color = getPixelColor(device, 319, 240);
8050 ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8051 color = getPixelColor(device, 320, 240);
8052 ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8054 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8055 &surface, NULL);
8056 ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%s\n", DXGetErrorString9(hr));
8057 hr = IDirect3DDevice9_BeginScene(device);
8058 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
8059 if(SUCCEEDED(hr)) {
8060 constant[2] = 16; constant[3] = 16;
8061 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8062 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%s\n", DXGetErrorString9(hr));
8063 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8064 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8065 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8066 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8067 hr = IDirect3DDevice9_EndScene(device);
8068 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
8070 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8071 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%s\n", DXGetErrorString9(hr));
8073 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8074 color = *pos & 0x00ffffff;
8075 ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8076 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8077 color = *pos & 0x00ffffff;
8078 ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8079 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8080 color = *pos & 0x00ffffff;
8081 ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8082 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8083 color = *pos & 0x00ffffff;
8084 ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8086 hr = IDirect3DSurface9_UnlockRect(surface);
8087 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%s\n", DXGetErrorString9(hr));
8089 /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8090 * have full control over the multisampling setting inside this test
8092 hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8093 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
8094 hr = IDirect3DDevice9_BeginScene(device);
8095 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
8096 if(SUCCEEDED(hr)) {
8097 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8098 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
8099 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8100 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8101 hr = IDirect3DDevice9_EndScene(device);
8102 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
8104 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8105 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8107 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8108 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%s\n", DXGetErrorString9(hr));
8110 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8111 color = *pos & 0x00ffffff;
8112 ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8114 hr = IDirect3DSurface9_UnlockRect(surface);
8115 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%s\n", DXGetErrorString9(hr));
8117 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8118 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
8119 IDirect3DPixelShader9_Release(shader);
8120 IDirect3DPixelShader9_Release(shader_frac);
8121 if(surface) IDirect3DSurface9_Release(surface);
8122 IDirect3DSurface9_Release(backbuffer);
8125 static void pointsize_test(IDirect3DDevice9 *device)
8127 HRESULT hr;
8128 D3DCAPS9 caps;
8129 D3DMATRIX matrix;
8130 D3DMATRIX identity;
8131 float ptsize, ptsize_orig;
8132 DWORD color;
8134 const float vertices[] = {
8135 64, 64, 0.1,
8136 128, 64, 0.1,
8137 192, 64, 0.1,
8138 256, 64, 0.1,
8139 320, 64, 0.1,
8140 384, 64, 0.1
8143 /* Transforms the coordinate system [-1.0;1.0]x[-1.0;1.0] to [0.0;0.0]x[640.0;480.0]. Z is untouched */
8144 U(matrix).m[0][0] = 2.0/640.0; U(matrix).m[1][0] = 0.0; U(matrix).m[2][0] = 0.0; U(matrix).m[3][0] =-1.0;
8145 U(matrix).m[0][1] = 0.0; U(matrix).m[1][1] =-2.0/480.0; U(matrix).m[2][1] = 0.0; U(matrix).m[3][1] = 1.0;
8146 U(matrix).m[0][2] = 0.0; U(matrix).m[1][2] = 0.0; U(matrix).m[2][2] = 1.0; U(matrix).m[3][2] = 0.0;
8147 U(matrix).m[0][3] = 0.0; U(matrix).m[1][3] = 0.0; U(matrix).m[2][3] = 0.0; U(matrix).m[3][3] = 1.0;
8149 U(identity).m[0][0] = 1.0; U(identity).m[1][0] = 0.0; U(identity).m[2][0] = 0.0; U(identity).m[3][0] = 0.0;
8150 U(identity).m[0][1] = 0.0; U(identity).m[1][1] = 1.0; U(identity).m[2][1] = 0.0; U(identity).m[3][1] = 0.0;
8151 U(identity).m[0][2] = 0.0; U(identity).m[1][2] = 0.0; U(identity).m[2][2] = 1.0; U(identity).m[3][2] = 0.0;
8152 U(identity).m[0][3] = 0.0; U(identity).m[1][3] = 0.0; U(identity).m[2][3] = 0.0; U(identity).m[3][3] = 1.0;
8154 memset(&caps, 0, sizeof(caps));
8155 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8156 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%s\n", DXGetErrorString9(hr));
8157 if(caps.MaxPointSize < 32.0) {
8158 skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8159 return;
8162 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8163 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
8164 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8165 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%s\n", DXGetErrorString9(hr));
8166 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8167 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%s\n", DXGetErrorString9(hr));
8168 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8169 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%s\n", DXGetErrorString9(hr));
8171 hr = IDirect3DDevice9_BeginScene(device);
8172 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
8173 if(SUCCEEDED(hr)) {
8174 ptsize = 16.0;
8175 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8176 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8177 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8178 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8180 ptsize = 32.0;
8181 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8182 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8183 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
8184 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8186 ptsize = 31.5;
8187 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8188 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8189 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
8190 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8192 if(caps.MaxPointSize >= 64.0) {
8193 ptsize = 64.0;
8194 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8195 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8196 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
8197 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8199 ptsize = 63.75;
8200 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8201 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8202 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8203 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8206 ptsize = 1.0;
8207 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8208 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8209 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8210 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8212 hr = IDirect3DDevice9_EndScene(device);
8213 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
8215 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8216 color = getPixelColor(device, 64-9, 64-9);
8217 ok(color == 0x000000ff, "pSize: Pixel (64-9),(64-9) has color 0x%08x, expected 0x000000ff\n", color);
8218 color = getPixelColor(device, 64-8, 64-8);
8219 todo_wine ok(color == 0x00ffffff, "pSize: Pixel (64-8),(64-8) has color 0x%08x, expected 0x00ffffff\n", color);
8220 color = getPixelColor(device, 64-7, 64-7);
8221 ok(color == 0x00ffffff, "pSize: Pixel (64-7),(64-7) has color 0x%08x, expected 0x00ffffff\n", color);
8222 color = getPixelColor(device, 64+7, 64+7);
8223 ok(color == 0x00ffffff, "pSize: Pixel (64+7),(64+7) has color 0x%08x, expected 0x00ffffff\n", color);
8224 color = getPixelColor(device, 64+8, 64+8);
8225 ok(color == 0x000000ff, "pSize: Pixel (64+8),(64+8) has color 0x%08x, expected 0x000000ff\n", color);
8226 color = getPixelColor(device, 64+9, 64+9);
8227 ok(color == 0x000000ff, "pSize: Pixel (64+9),(64+9) has color 0x%08x, expected 0x000000ff\n", color);
8229 color = getPixelColor(device, 128-17, 64-17);
8230 ok(color == 0x000000ff, "pSize: Pixel (128-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8231 color = getPixelColor(device, 128-16, 64-16);
8232 todo_wine ok(color == 0x00ffffff, "pSize: Pixel (128-16),(64-16) has color 0x%08x, expected 0x00ffffff\n", color);
8233 color = getPixelColor(device, 128-15, 64-15);
8234 ok(color == 0x00ffffff, "pSize: Pixel (128-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8235 color = getPixelColor(device, 128+15, 64+15);
8236 ok(color == 0x00ffffff, "pSize: Pixel (128+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8237 color = getPixelColor(device, 128+16, 64+16);
8238 ok(color == 0x000000ff, "pSize: Pixel (128+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8239 color = getPixelColor(device, 128+17, 64+17);
8240 ok(color == 0x000000ff, "pSize: Pixel (128+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8242 color = getPixelColor(device, 192-17, 64-17);
8243 ok(color == 0x000000ff, "pSize: Pixel (192-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8244 color = getPixelColor(device, 192-16, 64-16);
8245 ok(color == 0x000000ff, "pSize: Pixel (192-16),(64-16) has color 0x%08x, expected 0x000000ff\n", color);
8246 color = getPixelColor(device, 192-15, 64-15);
8247 ok(color == 0x00ffffff, "pSize: Pixel (192-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8248 color = getPixelColor(device, 192+15, 64+15);
8249 ok(color == 0x00ffffff, "pSize: Pixel (192+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8250 color = getPixelColor(device, 192+16, 64+16);
8251 ok(color == 0x000000ff, "pSize: Pixel (192+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8252 color = getPixelColor(device, 192+17, 64+17);
8253 ok(color == 0x000000ff, "pSize: Pixel (192+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8255 if(caps.MaxPointSize >= 64.0) {
8256 color = getPixelColor(device, 256-33, 64-33);
8257 ok(color == 0x000000ff, "pSize: Pixel (256-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8258 color = getPixelColor(device, 256-32, 64-32);
8259 todo_wine ok(color == 0x00ffffff, "pSize: Pixel (256-32),(64-32) has color 0x%08x, expected 0x00ffffff\n", color);
8260 color = getPixelColor(device, 256-31, 64-31);
8261 ok(color == 0x00ffffff, "pSize: Pixel (256-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8262 color = getPixelColor(device, 256+31, 64+31);
8263 ok(color == 0x00ffffff, "pSize: Pixel (256+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8264 color = getPixelColor(device, 256+32, 64+32);
8265 ok(color == 0x000000ff, "pSize: Pixel (256+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8266 color = getPixelColor(device, 256+33, 64+33);
8267 ok(color == 0x000000ff, "pSize: Pixel (256+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8269 color = getPixelColor(device, 384-33, 64-33);
8270 ok(color == 0x000000ff, "pSize: Pixel (384-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8271 color = getPixelColor(device, 384-32, 64-32);
8272 ok(color == 0x000000ff, "pSize: Pixel (384-32),(64-32) has color 0x%08x, expected 0x000000ff\n", color);
8273 color = getPixelColor(device, 384-31, 64-31);
8274 ok(color == 0x00ffffff, "pSize: Pixel (384-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8275 color = getPixelColor(device, 384+31, 64+31);
8276 ok(color == 0x00ffffff, "pSize: Pixel (384+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8277 color = getPixelColor(device, 384+32, 64+32);
8278 ok(color == 0x000000ff, "pSize: Pixel (384+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8279 color = getPixelColor(device, 384+33, 64+33);
8280 ok(color == 0x000000ff, "pSize: Pixel (384+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8283 color = getPixelColor(device, 320-1, 64-1);
8284 ok(color == 0x000000ff, "pSize: Pixel (320-1),(64-1) has color 0x%08x, expected 0x000000ff\n", color);
8285 color = getPixelColor(device, 320-0, 64-0);
8286 ok(color == 0x00ffffff, "pSize: Pixel (320-0),(64-0) has color 0x%08x, expected 0x00ffffff\n", color);
8287 color = getPixelColor(device, 320+1, 64+1);
8288 ok(color == 0x000000ff, "pSize: Pixel (320+1),(64+1) has color 0x%08x, expected 0x000000ff\n", color);
8290 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
8291 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%s\n", DXGetErrorString9(hr));
8292 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
8293 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%s\n", DXGetErrorString9(hr));
8296 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
8298 HRESULT hr;
8299 IDirect3DPixelShader9 *ps;
8300 IDirect3DTexture9 *tex1, *tex2;
8301 IDirect3DSurface9 *surf1, *surf2, *backbuf;
8302 D3DCAPS9 caps;
8303 DWORD color;
8304 DWORD shader_code[] = {
8305 0xffff0300, /* ps_3_0 */
8306 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0, 1, 0, 0 */
8307 0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0, 0, 1, 0 */
8308 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
8309 0x02000001, 0x800f0801, 0xa0e40001, /* mov oC1, c1 */
8310 0x0000ffff /* END */
8312 float quad[] = {
8313 -1.0, -1.0, 0.1,
8314 1.0, -1.0, 0.1,
8315 -1.0, 1.0, 0.1,
8316 1.0, 1.0, 0.1,
8318 float texquad[] = {
8319 -1.0, -1.0, 0.1, 0.0, 0.0,
8320 0.0, -1.0, 0.1, 1.0, 0.0,
8321 -1.0, 1.0, 0.1, 0.0, 1.0,
8322 0.0, 1.0, 0.1, 1.0, 1.0,
8324 0.0, -1.0, 0.1, 0.0, 0.0,
8325 1.0, -1.0, 0.1, 1.0, 0.0,
8326 0.0, 1.0, 0.1, 0.0, 1.0,
8327 1.0, 1.0, 0.1, 1.0, 1.0,
8330 memset(&caps, 0, sizeof(caps));
8331 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8332 ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%s\n", DXGetErrorString9(hr));
8333 if(caps.NumSimultaneousRTs < 2) {
8334 skip("Only 1 simultaneous render target supported, skipping MRT test\n");
8335 return;
8338 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
8339 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
8341 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
8342 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%s\n", DXGetErrorString9(hr));
8343 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
8344 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%s\n", DXGetErrorString9(hr));
8345 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
8346 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed, hr=%s\n", DXGetErrorString9(hr));
8348 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
8349 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8350 hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
8351 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%s\n", DXGetErrorString9(hr));
8352 hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
8353 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%s\n", DXGetErrorString9(hr));
8355 hr = IDirect3DDevice9_SetPixelShader(device, ps);
8356 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%s\n", DXGetErrorString9(hr));
8357 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
8358 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8359 hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
8360 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8361 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8362 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%s\n", DXGetErrorString9(hr));
8364 hr = IDirect3DDevice9_BeginScene(device);
8365 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%s\n", DXGetErrorString9(hr));
8366 if(SUCCEEDED(hr)) {
8367 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
8368 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8370 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8371 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%s\n", DXGetErrorString9(hr));
8372 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
8373 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8374 hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
8375 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8376 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8377 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%s\n", DXGetErrorString9(hr));
8379 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8380 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%s\n", DXGetErrorString9(hr));
8381 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
8382 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8384 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
8385 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%s\n", DXGetErrorString9(hr));
8386 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
8387 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8389 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8390 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%s\n", DXGetErrorString9(hr));
8392 hr = IDirect3DDevice9_EndScene(device);
8393 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%s\n", DXGetErrorString9(hr));
8396 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8397 color = getPixelColor(device, 160, 240);
8398 ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
8399 color = getPixelColor(device, 480, 240);
8400 ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
8402 IDirect3DPixelShader9_Release(ps);
8403 IDirect3DTexture9_Release(tex1);
8404 IDirect3DTexture9_Release(tex2);
8405 IDirect3DSurface9_Release(surf1);
8406 IDirect3DSurface9_Release(surf2);
8407 IDirect3DSurface9_Release(backbuf);
8410 struct formats {
8411 const char *fmtName;
8412 D3DFORMAT textureFormat;
8413 DWORD resultColorBlending;
8414 DWORD resultColorNoBlending;
8417 const struct formats test_formats[] = {
8418 { "D3DFMT_G16R16", D3DFMT_G16R16, 0x00181800, 0x002010ff},
8419 { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
8420 { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
8421 { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
8422 { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
8423 { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
8424 { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
8425 { NULL, 0 }
8428 static void pixelshader_blending_test(IDirect3DDevice9 *device)
8430 HRESULT hr;
8431 IDirect3DTexture9 *offscreenTexture = NULL;
8432 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
8433 IDirect3D9 *d3d = NULL;
8434 DWORD color;
8435 int fmt_index;
8437 static const float quad[][5] = {
8438 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
8439 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
8440 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
8441 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
8444 /* Quad with R=0x10, G=0x20 */
8445 static const struct vertex quad1[] = {
8446 {-1.0f, -1.0f, 0.1f, 0x80102000},
8447 {-1.0f, 1.0f, 0.1f, 0x80102000},
8448 { 1.0f, -1.0f, 0.1f, 0x80102000},
8449 { 1.0f, 1.0f, 0.1f, 0x80102000},
8452 /* Quad with R=0x20, G=0x10 */
8453 static const struct vertex quad2[] = {
8454 {-1.0f, -1.0f, 0.1f, 0x80201000},
8455 {-1.0f, 1.0f, 0.1f, 0x80201000},
8456 { 1.0f, -1.0f, 0.1f, 0x80201000},
8457 { 1.0f, 1.0f, 0.1f, 0x80201000},
8460 IDirect3DDevice9_GetDirect3D(device, &d3d);
8462 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8463 ok(hr == D3D_OK, "Can't get back buffer, hr = %s\n", DXGetErrorString9(hr));
8464 if(!backbuffer) {
8465 goto out;
8468 for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
8470 D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
8471 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, fmt) != D3D_OK) {
8472 skip("%s textures not supported\n", test_formats[fmt_index].fmtName);
8473 continue;
8476 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8477 ok(hr == D3D_OK, "Clear failed, hr = %s\n", DXGetErrorString9(hr));
8479 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
8480 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %s\n", DXGetErrorString9(hr));
8481 if(!offscreenTexture) {
8482 continue;
8485 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
8486 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %s\n", DXGetErrorString9(hr));
8487 if(!offscreen) {
8488 continue;
8491 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8492 ok(hr == D3D_OK, "SetFVF failed, hr = %s\n", DXGetErrorString9(hr));
8494 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8495 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8496 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8497 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8498 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
8499 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
8500 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
8501 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
8502 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8503 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
8505 /* Below we will draw two quads with different colors and try to blend them together.
8506 * The result color is compared with the expected outcome.
8508 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
8509 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
8510 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %s\n", DXGetErrorString9(hr));
8511 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
8512 ok(hr == D3D_OK, "Clear failed, hr = %s\n", DXGetErrorString9(hr));
8514 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
8515 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8517 /* Draw a quad using color 0x0010200 */
8518 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
8519 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8520 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
8521 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8522 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8523 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8525 /* Draw a quad using color 0x0020100 */
8526 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
8527 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8528 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
8529 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8530 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8531 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8533 /* We don't want to blend the result on the backbuffer */
8534 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
8535 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8537 /* Prepare rendering the 'blended' texture quad to the backbuffer */
8538 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8539 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %s\n", DXGetErrorString9(hr));
8540 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
8541 ok(hr == D3D_OK, "SetTexture failed, %s\n", DXGetErrorString9(hr));
8543 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8544 ok(hr == D3D_OK, "SetFVF failed, hr = %s\n", DXGetErrorString9(hr));
8546 /* This time with the texture */
8547 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8548 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %s\n", DXGetErrorString9(hr));
8550 IDirect3DDevice9_EndScene(device);
8552 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8555 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
8556 /* Compare the color of the center quad with our expectation */
8557 color = getPixelColor(device, 320, 240);
8558 ok(color == test_formats[fmt_index].resultColorBlending, "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
8559 } else {
8560 /* No pixel shader blending is supported so expected garbage.The type of 'garbage' depends on the driver version and OS.
8561 * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
8562 * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
8563 color = getPixelColor(device, 320, 240);
8564 ok((color == 0x00ffffff) || (color == test_formats[fmt_index].resultColorNoBlending), "Offscreen failed for %s: expected no color blending but received it anyway.\n", test_formats[fmt_index].fmtName);
8567 IDirect3DDevice9_SetTexture(device, 0, NULL);
8568 if(offscreenTexture) {
8569 IDirect3DTexture9_Release(offscreenTexture);
8571 if(offscreen) {
8572 IDirect3DSurface9_Release(offscreen);
8576 out:
8577 /* restore things */
8578 if(backbuffer) {
8579 IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8580 IDirect3DSurface9_Release(backbuffer);
8584 static void tssargtemp_test(IDirect3DDevice9 *device)
8586 HRESULT hr;
8587 DWORD color;
8588 static const struct vertex quad[] = {
8589 {-1.0, -1.0, 0.1, 0x00ff0000},
8590 { 1.0, -1.0, 0.1, 0x00ff0000},
8591 {-1.0, 1.0, 0.1, 0x00ff0000},
8592 { 1.0, 1.0, 0.1, 0x00ff0000}
8594 D3DCAPS9 caps;
8596 memset(&caps, 0, sizeof(caps));
8597 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8598 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %s\n", DXGetErrorString9(hr));
8599 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
8600 skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
8601 return;
8604 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
8605 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
8607 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8608 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8609 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
8610 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8612 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8613 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8614 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
8615 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8616 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
8617 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8619 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
8620 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8621 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
8622 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8623 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
8624 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8626 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
8627 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8629 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
8630 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %s\n", DXGetErrorString9(hr));
8631 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8632 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %s\n", DXGetErrorString9(hr));
8634 hr = IDirect3DDevice9_BeginScene(device);
8635 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %s\n", DXGetErrorString9(hr));
8636 if(SUCCEEDED(hr)) {
8638 hr = IDirect3DDevice9_EndScene(device);
8639 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %s\n", DXGetErrorString9(hr));
8640 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8641 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
8643 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8644 color = getPixelColor(device, 320, 240);
8645 ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
8647 /* Set stage 1 back to default */
8648 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
8649 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8650 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
8651 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8652 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8653 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8654 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
8655 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8656 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
8657 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8660 struct testdata
8662 DWORD idxVertex; /* number of instances in the first stream */
8663 DWORD idxColor; /* number of instances in the second stream */
8664 DWORD idxInstance; /* should be 1 ?? */
8665 DWORD color1; /* color 1 instance */
8666 DWORD color2; /* color 2 instance */
8667 DWORD color3; /* color 3 instance */
8668 DWORD color4; /* color 4 instance */
8669 WORD strVertex; /* specify which stream to use 0-2*/
8670 WORD strColor;
8671 WORD strInstance;
8674 static const struct testdata testcases[]=
8676 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 0 */
8677 {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 1 */
8678 {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 2 */
8679 {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 3 */
8680 {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 4 */
8681 {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 5 */
8682 {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 6 */
8683 {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 7 */
8684 {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 8 */
8685 {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 9 */
8686 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 10 */
8687 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 11 */
8688 {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 12 */
8689 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 13 */
8690 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 14 */
8692 This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1)) has to return D3DERR_INVALIDCALL!
8693 {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
8697 /* Drawing Indexed Geometry with instances*/
8698 static void stream_test(IDirect3DDevice9 *device)
8700 IDirect3DVertexBuffer9 *vb = NULL;
8701 IDirect3DVertexBuffer9 *vb2 = NULL;
8702 IDirect3DVertexBuffer9 *vb3 = NULL;
8703 IDirect3DIndexBuffer9 *ib = NULL;
8704 IDirect3DVertexDeclaration9 *pDecl = NULL;
8705 IDirect3DVertexShader9 *shader = NULL;
8706 HRESULT hr;
8707 BYTE *data;
8708 DWORD color;
8709 DWORD ind;
8710 int i;
8712 const DWORD shader_code[] =
8714 0xfffe0101, /* vs_1_1 */
8715 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8716 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
8717 0x0000001f, 0x80000005, 0x900f0002, /* dcl_texcoord v2 */
8718 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
8719 0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
8720 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
8721 0x0000ffff
8724 const float quad[][3] =
8726 {-0.5f, -0.5f, 1.1f}, /*0 */
8727 {-0.5f, 0.5f, 1.1f}, /*1 */
8728 { 0.5f, -0.5f, 1.1f}, /*2 */
8729 { 0.5f, 0.5f, 1.1f}, /*3 */
8732 const float vertcolor[][4] =
8734 {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
8735 {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
8736 {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
8737 {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
8740 /* 4 position for 4 instances */
8741 const float instancepos[][3] =
8743 {-0.6f,-0.6f, 0.0f},
8744 { 0.6f,-0.6f, 0.0f},
8745 { 0.6f, 0.6f, 0.0f},
8746 {-0.6f, 0.6f, 0.0f},
8749 short indices[] = {0, 1, 2, 1, 2, 3};
8751 D3DVERTEXELEMENT9 decl[] =
8753 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8754 {1, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8755 {2, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
8756 D3DDECL_END()
8759 /* set the default value because it isn't done in wine? */
8760 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
8761 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8763 /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
8764 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
8765 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8767 /* check wrong cases */
8768 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
8769 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8770 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8771 ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8772 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
8773 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8774 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8775 ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8776 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
8777 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8778 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8779 ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8780 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
8781 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8782 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8783 ok(hr == D3D_OK && ind == (0 | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8784 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
8785 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8786 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8787 ok(hr == D3D_OK && ind == (0 | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8789 /* set the default value back */
8790 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
8791 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8793 /* create all VertexBuffers*/
8794 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
8795 ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
8796 if(!vb) {
8797 skip("Failed to create a vertex buffer\n");
8798 return;
8800 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
8801 ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
8802 if(!vb2) {
8803 skip("Failed to create a vertex buffer\n");
8804 goto out;
8806 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
8807 ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
8808 if(!vb3) {
8809 skip("Failed to create a vertex buffer\n");
8810 goto out;
8813 /* create IndexBuffer*/
8814 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
8815 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %s\n", DXGetErrorString9(hr));
8816 if(!ib) {
8817 skip("Failed to create a index buffer\n");
8818 goto out;
8821 /* copy all Buffers (Vertex + Index)*/
8822 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
8823 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
8824 memcpy(data, quad, sizeof(quad));
8825 hr = IDirect3DVertexBuffer9_Unlock(vb);
8826 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
8827 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
8828 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
8829 memcpy(data, vertcolor, sizeof(vertcolor));
8830 hr = IDirect3DVertexBuffer9_Unlock(vb2);
8831 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
8832 hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
8833 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
8834 memcpy(data, instancepos, sizeof(instancepos));
8835 hr = IDirect3DVertexBuffer9_Unlock(vb3);
8836 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
8837 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
8838 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
8839 memcpy(data, indices, sizeof(indices));
8840 hr = IDirect3DIndexBuffer9_Unlock(ib);
8841 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
8843 /* create VertexShader */
8844 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
8845 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%s\n", DXGetErrorString9(hr));
8846 if(!shader) {
8847 skip("Failed to create a vetex shader\n");
8848 goto out;
8851 hr = IDirect3DDevice9_SetVertexShader(device, shader);
8852 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%s\n", DXGetErrorString9(hr));
8854 hr = IDirect3DDevice9_SetIndices(device, ib);
8855 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
8857 /* run all tests */
8858 for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
8860 struct testdata act = testcases[i];
8861 decl[0].Stream = act.strVertex;
8862 decl[1].Stream = act.strColor;
8863 decl[2].Stream = act.strInstance;
8864 /* create VertexDeclarations */
8865 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
8866 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%s (case %i)\n", DXGetErrorString9(hr), i);
8868 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8869 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
8871 hr = IDirect3DDevice9_BeginScene(device);
8872 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
8873 if(SUCCEEDED(hr))
8875 hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
8876 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
8878 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
8879 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8880 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
8881 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8883 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
8884 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8885 hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
8886 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8888 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
8889 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8890 hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
8891 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8893 /* don't know if this is right (1*3 and 4*1)*/
8894 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 1 * 3 , 0, 4*1);
8895 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
8896 hr = IDirect3DDevice9_EndScene(device);
8897 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
8899 /* set all StreamSource && StreamSourceFreq back to default */
8900 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
8901 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8902 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
8903 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
8904 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
8905 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8906 hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
8907 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
8908 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
8909 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8910 hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
8911 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
8914 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8915 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
8917 hr = IDirect3DVertexDeclaration9_Release(pDecl);
8918 ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
8920 color = getPixelColor(device, 160, 360);
8921 ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
8922 color = getPixelColor(device, 480, 360);
8923 ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
8924 color = getPixelColor(device, 480, 120);
8925 ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
8926 color = getPixelColor(device, 160, 120);
8927 ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
8930 hr = IDirect3DDevice9_SetIndices(device, NULL);
8931 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
8933 out:
8934 if(vb) IDirect3DVertexBuffer9_Release(vb);
8935 if(vb2)IDirect3DVertexBuffer9_Release(vb2);
8936 if(vb3)IDirect3DVertexBuffer9_Release(vb3);
8937 if(ib)IDirect3DIndexBuffer9_Release(ib);
8938 if(shader)IDirect3DVertexShader9_Release(shader);
8941 START_TEST(visual)
8943 IDirect3DDevice9 *device_ptr;
8944 D3DCAPS9 caps;
8945 HRESULT hr;
8946 DWORD color;
8948 d3d9_handle = LoadLibraryA("d3d9.dll");
8949 if (!d3d9_handle)
8951 skip("Could not load d3d9.dll\n");
8952 return;
8955 device_ptr = init_d3d9();
8956 if (!device_ptr)
8958 skip("Creating the device failed\n");
8959 return;
8962 IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
8964 /* Check for the reliability of the returned data */
8965 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
8966 if(FAILED(hr))
8968 trace("Clear failed, can't assure correctness of the test results, skipping\n");
8969 goto cleanup;
8971 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
8973 color = getPixelColor(device_ptr, 1, 1);
8974 if(color !=0x00ff0000)
8976 trace("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
8977 goto cleanup;
8980 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
8981 if(FAILED(hr))
8983 trace("Clear failed, can't assure correctness of the test results, skipping\n");
8984 goto cleanup;
8986 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
8988 color = getPixelColor(device_ptr, 639, 479);
8989 if(color != 0x0000ddee)
8991 trace("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
8992 goto cleanup;
8995 /* Now execute the real tests */
8996 stretchrect_test(device_ptr);
8997 lighting_test(device_ptr);
8998 clear_test(device_ptr);
8999 fog_test(device_ptr);
9000 if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
9002 test_cube_wrap(device_ptr);
9003 } else {
9004 skip("No cube texture support\n");
9006 z_range_test(device_ptr);
9007 if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
9009 maxmip_test(device_ptr);
9011 else
9013 skip("No mipmap support\n");
9015 offscreen_test(device_ptr);
9016 alpha_test(device_ptr);
9017 shademode_test(device_ptr);
9018 srgbtexture_test(device_ptr);
9019 release_buffer_test(device_ptr);
9020 float_texture_test(device_ptr);
9021 g16r16_texture_test(device_ptr);
9022 pixelshader_blending_test(device_ptr);
9023 texture_transform_flags_test(device_ptr);
9024 autogen_mipmap_test(device_ptr);
9025 fixed_function_decl_test(device_ptr);
9026 conditional_np2_repeat_test(device_ptr);
9027 fixed_function_bumpmap_test(device_ptr);
9028 if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
9029 stencil_cull_test(device_ptr);
9030 } else {
9031 skip("No two sided stencil support\n");
9033 pointsize_test(device_ptr);
9034 tssargtemp_test(device_ptr);
9036 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
9038 test_constant_clamp_vs(device_ptr);
9039 test_compare_instructions(device_ptr);
9041 else skip("No vs_1_1 support\n");
9043 if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
9045 test_mova(device_ptr);
9046 if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
9047 test_vshader_input(device_ptr);
9048 test_vshader_float16(device_ptr);
9049 stream_test(device_ptr);
9050 } else {
9051 skip("No vs_3_0 support\n");
9054 else skip("No vs_2_0 support\n");
9056 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
9058 fog_with_shader_test(device_ptr);
9059 fog_srgbwrite_test(device_ptr);
9061 else skip("No vs_1_1 and ps_1_1 support\n");
9063 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
9065 texbem_test(device_ptr);
9066 texdepth_test(device_ptr);
9067 texkill_test(device_ptr);
9068 x8l8v8u8_test(device_ptr);
9069 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
9070 constant_clamp_ps_test(device_ptr);
9071 cnd_test(device_ptr);
9072 if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
9073 dp2add_ps_test(device_ptr);
9074 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) {
9075 nested_loop_test(device_ptr);
9076 fixed_function_varying_test(device_ptr);
9077 vFace_register_test(device_ptr);
9078 vpos_register_test(device_ptr);
9079 multiple_rendertargets_test(device_ptr);
9080 if(caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
9081 vshader_version_varying_test(device_ptr);
9082 pshader_version_varying_test(device_ptr);
9083 } else {
9084 skip("No vs_3_0 support\n");
9086 } else {
9087 skip("No ps_3_0 support\n");
9089 } else {
9090 skip("No ps_2_0 support\n");
9094 else skip("No ps_1_1 support\n");
9096 cleanup:
9097 if(device_ptr) {
9098 ULONG ref;
9100 D3DPRESENT_PARAMETERS present_parameters;
9101 IDirect3DSwapChain9 *swapchain;
9102 IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
9103 IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
9104 IDirect3DSwapChain9_Release(swapchain);
9105 ref = IDirect3DDevice9_Release(device_ptr);
9106 DestroyWindow(present_parameters.hDeviceWindow);
9107 ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);