d3d9: Make the offscreen format test a bit more tolerant.
[wine/wine-kai.git] / dlls / d3d9 / tests / visual.c
blob2c224e84bee16b9a91c64925cf53c4ebc764c1c0
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 = NULL;
2047 IDirect3DSurface9 *surf_tex_rt32 = NULL, *surf_tex_rt64 = NULL, *surf_tex_rt_dest64 = NULL;
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;
5184 BOOL drawok;
5186 memcpy(data2, data, sizeof(data2));
5187 data2[0].pos_x = 0; data2[0].pos_y = 0;
5188 data2[1].pos_x = 640; data2[1].pos_y = 0;
5189 data2[2].pos_x = 0; data2[2].pos_y = 480;
5190 data2[3].pos_x = 640; data2[3].pos_y = 480;
5192 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5193 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5194 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
5195 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5196 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5197 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5199 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5201 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &tests[i].shader);
5202 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed for shader %s, hr = %s\n",
5203 tests[i].name, DXGetErrorString9(hr));
5206 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5208 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5209 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
5211 IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5212 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5214 hr = IDirect3DDevice9_BeginScene(device);
5215 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5216 drawok = FALSE;
5217 if(SUCCEEDED(hr))
5219 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(data[0]));
5220 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed (%08x)\n", hr);
5221 drawok = SUCCEEDED(hr);
5222 hr = IDirect3DDevice9_EndScene(device);
5223 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5225 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5226 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5228 /* Some drivers reject the combination of ps_3_0 and fixed function vertex processing. Accept
5229 * the failure and do not check the color if it failed
5231 if(!drawok) {
5232 continue;
5235 color = getPixelColor(device, 360, 240);
5236 r = color & 0x00ff0000 >> 16;
5237 g = color & 0x0000ff00 >> 8;
5238 b = color & 0x000000ff;
5239 r_e = tests[i].color & 0x00ff0000 >> 16;
5240 g_e = tests[i].color & 0x0000ff00 >> 8;
5241 b_e = tests[i].color & 0x000000ff;
5243 if(tests[i].todo) {
5244 todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5245 "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5246 tests[i].name, color, tests[i].color);
5247 } else {
5248 ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5249 "Test %s returned color 0x%08x, expected 0x%08x\n",
5250 tests[i].name, color, tests[i].color);
5254 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
5255 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
5256 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5258 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5259 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
5261 IDirect3DDevice9_SetPixelShader(device, tests[i].shader);
5262 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5264 hr = IDirect3DDevice9_BeginScene(device);
5265 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5266 if(SUCCEEDED(hr))
5268 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data2, sizeof(data2[0]));
5269 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5270 hr = IDirect3DDevice9_EndScene(device);
5271 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5273 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5274 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5276 color = getPixelColor(device, 360, 240);
5277 r = color & 0x00ff0000 >> 16;
5278 g = color & 0x0000ff00 >> 8;
5279 b = color & 0x000000ff;
5280 r_e = tests[i].color_rhw & 0x00ff0000 >> 16;
5281 g_e = tests[i].color_rhw & 0x0000ff00 >> 8;
5282 b_e = tests[i].color_rhw & 0x000000ff;
5284 if(tests[i].todo_rhw) {
5285 /* This isn't a weekend's job to fix, ignore the problem for now. Needs a replacement
5286 * pipeline
5288 todo_wine ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5289 "Test %s returned color 0x%08x, expected 0x%08x(todo)\n",
5290 tests[i].name, color, tests[i].color_rhw);
5291 } else {
5292 ok(abs(r - r_e) <= 1 && abs(g - g_e) <= 1 && abs(b - b_e) <= 1,
5293 "Test %s returned color 0x%08x, expected 0x%08x\n",
5294 tests[i].name, color, tests[i].color_rhw);
5298 for(i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
5300 IDirect3DPixelShader9_Release(tests[i].shader);
5303 IDirect3DVertexDeclaration9_Release(decl2);
5304 IDirect3DVertexDeclaration9_Release(decl);
5307 static void vshader_version_varying_test(IDirect3DDevice9 *device) {
5308 static const DWORD ps_code[] = {
5309 0xffff0300, /* ps_3_0 */
5310 0x05000030, 0xf00f0000, 0x00000003, 0x00000003, 0x00000001, 0x00000000, /* defi i0, 3, 3, 1, 0 */
5311 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
5312 0x0200001f, 0x8001000a, 0x900f0003, /* dcl_color1 v3 */
5313 0x0200001f, 0x8000000b, 0x900f0004, /* dcl_fog v4 */
5314 0x0200001f, 0x80030005, 0x900f0005, /* dcl_texcoord3 v5 */
5315 0x0200001f, 0x80000003, 0x900f0006,
5316 0x0200001f, 0x80000006, 0x900f0007,
5317 0x0200001f, 0x80000001, 0x900f0008,
5318 0x0200001f, 0x8000000c, 0x900f0009,
5320 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5321 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
5322 0x04000002, 0x800f0000, 0x80e40000, 0x90e42000, 0xf0e40800, /* add r0, r0, v0[aL] */
5323 0x0000001d, /* endloop */
5324 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5325 0x0000ffff /* end */
5327 static const DWORD vs_1_code[] = {
5328 0xfffe0101, /* vs_1_1 */
5329 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5330 0x00000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0 */
5331 0x00000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0 */
5332 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0 */
5333 0x00000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
5334 0x00000001, 0xd00f0000, 0xa0e40002, /* mov oD0, c2 */
5335 0x00000001, 0xd00f0001, 0xa0e40000, /* mov oD1, c0 */
5336 0x00000001, 0xc00f0001, 0xa0550001, /* mov oFog, c1.g */
5337 0x00000001, 0xe00f0000, 0xa0e40003, /* mov oT0, c3 */
5338 0x00000001, 0xe00f0001, 0xa0e40003, /* mov oT1, c3 */
5339 0x00000001, 0xe00f0002, 0xa0e40003, /* mov oT2, c3 */
5340 0x00000001, 0xe00f0003, 0xa0e40002, /* mov oT3, c2 */
5341 0x00000001, 0xe00f0004, 0xa0e40003, /* mov oT4, c3 */
5342 0x00000001, 0xe00f0005, 0xa0e40003, /* mov oT5, c3 */
5343 0x00000001, 0xe00f0006, 0xa0e40003, /* mov oT6, c3 */
5344 0x00000001, 0xe00f0007, 0xa0e40003, /* mov oT7, c3 */
5345 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5346 0x0000ffff
5348 DWORD vs_2_code[] = {
5349 0xfffe0200, /* vs_2_0 */
5350 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5351 0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.5, 0.0, 0.0, 0.0 */
5352 0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.5, 0.0, 0.0 */
5353 0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.5, 0.0 */
5354 0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
5355 0x02000001, 0xd00f0000, 0xa0e40002, /* mov oD0, c2 */
5356 0x02000001, 0xd00f0001, 0xa0e40000, /* mov oD1, c0 */
5357 0x02000001, 0xc00f0001, 0xa0550001, /* mov oFog, c1.g */
5358 0x02000001, 0xe00f0000, 0xa0e40003, /* mov oT0, c3 */
5359 0x02000001, 0xe00f0001, 0xa0e40003, /* mov oT1, c3 */
5360 0x02000001, 0xe00f0002, 0xa0e40003, /* mov oT2, c3 */
5361 0x02000001, 0xe00f0003, 0xa0e40002, /* mov oT3, c2 */
5362 0x02000001, 0xe00f0004, 0xa0e40003, /* mov oT4, c3 */
5363 0x02000001, 0xe00f0005, 0xa0e40003, /* mov oT5, c3 */
5364 0x02000001, 0xe00f0006, 0xa0e40003, /* mov oT6, c3 */
5365 0x02000001, 0xe00f0007, 0xa0e40003, /* mov oT7, c3 */
5366 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5367 0x0000ffff /* end */
5369 /* TODO: Define normal, tangent, blendweight and depth here */
5370 static const DWORD vs_3_code[] = {
5371 0xfffe0300, /* vs_3_0 */
5372 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5373 0x0200001f, 0x8001000a, 0xe00f0009, /* dcl_color1 o9 */
5374 0x0200001f, 0x8000000b, 0xe00f0002, /* dcl_fog o2 */
5375 0x0200001f, 0x80030005, 0xe00f0005, /* dcl_texcoord3 o5 */
5376 0x0200001f, 0x80000000, 0xe00f000b, /* dcl_position o11 */
5377 0x05000051, 0xa00f0000, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.1, 0.0, 0.0, 0.0 */
5378 0x05000051, 0xa00f0001, 0x00000000, 0x3e4ccccd, 0x00000000, 0x00000000, /* def c1, 0.0, 0.2, 0.0, 0.0 */
5379 0x05000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3ecccccd, 0x00000000, /* def c2, 0.0, 0.0, 0.4, 0.0 */
5380 0x05000051, 0xa00f0003, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 1.0, 1.0, 1.0, 1.0 */
5381 0x02000001, 0xe00f0009, 0xa0e40000, /* mov o9, c0 */
5382 0x02000001, 0xe00f0002, 0xa0e40001, /* mov o2, c1 */
5383 0x02000001, 0xe00f0005, 0xa0e40002, /* mov o5, c2 */
5384 0x02000001, 0xe00f000b, 0x90e40000, /* mov o11, v0 */
5385 0x0000ffff /* end */
5387 float quad1[] = {
5388 -1.0, -1.0, 0.1,
5389 0.0, -1.0, 0.1,
5390 -1.0, 0.0, 0.1,
5391 0.0, 0.0, 0.1
5393 float quad2[] = {
5394 0.0, -1.0, 0.1,
5395 1.0, -1.0, 0.1,
5396 0.0, 0.0, 0.1,
5397 1.0, 0.0, 0.1
5399 float quad3[] = {
5400 -1.0, 0.0, 0.1,
5401 0.0, 0.0, 0.1,
5402 -1.0, 1.0, 0.1,
5403 0.0, 1.0, 0.1
5406 HRESULT hr;
5407 DWORD color;
5408 IDirect3DPixelShader9 *pixelshader = NULL;
5409 IDirect3DVertexShader9 *vs_1_shader = NULL;
5410 IDirect3DVertexShader9 *vs_2_shader = NULL;
5411 IDirect3DVertexShader9 *vs_3_shader = NULL;
5413 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff110000, 0.0, 0);
5415 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &pixelshader);
5416 ok(hr == D3D_OK, "IDirect3DDevice_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
5417 hr = IDirect3DDevice9_CreateVertexShader(device, vs_1_code, &vs_1_shader);
5418 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5419 hr = IDirect3DDevice9_CreateVertexShader(device, vs_2_code, &vs_2_shader);
5420 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5421 hr = IDirect3DDevice9_CreateVertexShader(device, vs_3_code, &vs_3_shader);
5422 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5423 hr = IDirect3DDevice9_SetPixelShader(device, pixelshader);
5424 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5425 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5427 hr = IDirect3DDevice9_BeginScene(device);
5428 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5429 if(SUCCEEDED(hr))
5431 hr = IDirect3DDevice9_SetVertexShader(device, vs_1_shader);
5432 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5433 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5434 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5436 hr = IDirect3DDevice9_SetVertexShader(device, vs_2_shader);
5437 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5438 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
5439 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5441 hr = IDirect3DDevice9_SetVertexShader(device, vs_3_shader);
5442 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5443 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5444 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5446 hr = IDirect3DDevice9_EndScene(device);
5447 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5449 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5450 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5452 color = getPixelColor(device, 160, 120);
5453 ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5454 (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003500 &&
5455 (color & 0x000000ff) >= 0x00000066 && (color & 0x000000ff) <= 0x00000068,
5456 "vs_3_0 returned color 0x%08x, expected 0x00203366\n", color);
5457 color = getPixelColor(device, 160, 360);
5458 ok((color & 0x00ff0000) >= 0x003c0000 && (color & 0x00ff0000) <= 0x004e0000 &&
5459 (color & 0x0000ff00) >= 0x00000000 && (color & 0x0000ff00) <= 0x00000000 &&
5460 (color & 0x000000ff) >= 0x00000066 && (color & 0x000000ff) <= 0x00000068,
5461 "vs_1_1 returned color 0x%08x, expected 0x004c0066\n", color);
5462 color = getPixelColor(device, 480, 360);
5463 ok((color & 0x00ff0000) >= 0x003c0000 && (color & 0x00ff0000) <= 0x004e0000 &&
5464 (color & 0x0000ff00) >= 0x00000000 && (color & 0x0000ff00) <= 0x00000000 &&
5465 (color & 0x000000ff) >= 0x00000066 && (color & 0x000000ff) <= 0x00000068,
5466 "vs_2_0 returned color 0x%08x, expected 0x004c0066\n", color);
5468 /* cleanup */
5469 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5470 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5471 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5472 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5473 if(pixelshader) IDirect3DPixelShader9_Release(pixelshader);
5474 if(vs_1_shader) IDirect3DVertexShader9_Release(vs_1_shader);
5475 if(vs_2_shader) IDirect3DVertexShader9_Release(vs_2_shader);
5476 if(vs_3_shader) IDirect3DVertexShader9_Release(vs_3_shader);
5479 static void pshader_version_varying_test(IDirect3DDevice9 *device) {
5480 static const DWORD vs_code[] = {
5481 0xfffe0300, /* vs_3_0 */
5482 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5483 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5484 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */
5485 0x0200001f, 0x80000005, 0xe00f0002, /* dcl_texcoord0 o2 */
5486 0x0200001f, 0x8000000b, 0xe00f0003, /* dcl_fog o3 */
5487 0x0200001f, 0x80000003, 0xe00f0004, /* dcl_normal o4 */
5488 0x0200001f, 0x8000000c, 0xe00f0005, /* dcl_depth o5 */
5489 0x0200001f, 0x80000006, 0xe00f0006, /* dcl_tangent o6 */
5490 0x0200001f, 0x80000001, 0xe00f0007, /* dcl_blendweight o7 */
5491 0x05000051, 0xa00f0001, 0x3dcccccd, 0x00000000, 0x00000000, 0x00000000, /* def c1, 0.1, 0.0, 0.0, 0.0 */
5492 0x05000051, 0xa00f0002, 0x00000000, 0x3e4ccccd, 0x00000000, 0x3f800000, /* def c2, 0.0, 0.2, 0.0, 1.0 */
5493 0x05000051, 0xa00f0003, 0x3ecccccd, 0x3f59999a, 0x3f666666, 0x00000000, /* def c3, 0.4, 0.85,0.9, 0.0 */
5494 0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0 */
5496 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5497 0x02000001, 0xe00f0001, 0xa0e40001, /* mov o1, c1 */
5498 0x02000001, 0xe00f0002, 0xa0e40002, /* mov o2, c2 */
5499 0x02000001, 0xe00f0003, 0xa0e40003, /* mov o3, c3 */
5500 0x02000001, 0xe00f0004, 0xa0e40000, /* mov o4, c0 */
5501 0x02000001, 0xe00f0005, 0xa0e40000, /* mov o5, c0 */
5502 0x02000001, 0xe00f0006, 0xa0e40000, /* mov o6, c0 */
5503 0x02000001, 0xe00f0007, 0xa0e40000, /* mov o7, c0 */
5504 0x0000ffff /* end */
5506 static const DWORD ps_1_code[] = {
5507 0xffff0104, /* ps_1_4 */
5508 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
5509 0x00000040, 0x80070001, 0xb0e40000, /* texcrd r1.xyz, t0 */
5510 0x00000001, 0x80080001, 0xa0ff0000, /* mov r1.a, c0.a */
5511 0x00000002, 0x800f0000, 0x90e40000, 0x80e40001, /* add r0, v0, r1 */
5512 0x0000ffff /* end */
5514 static const DWORD ps_2_code[] = {
5515 0xffff0200, /* ps_2_0 */
5516 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
5517 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
5518 0x0200001f, 0x80000000, 0x900f0001, /* dcl v1 */
5520 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
5521 0x03000002, 0x800f0000, 0x80e40000,0xb0e40000, /* add r0, r0, t0 */
5522 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5523 0x0000ffff /* end */
5525 static const DWORD ps_3_code[] = {
5526 0xffff0300, /* ps_3_0 */
5527 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
5528 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
5529 0x0200001f, 0x8000000b, 0x900f0002, /* dcl_fog v2 */
5531 0x02000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
5532 0x03000002, 0x800f0000, 0x80e40000, 0x90e40001, /* add r0, r0, v1 */
5533 0x03000002, 0x800f0000, 0x80e40000, 0x90e40002, /* mov r0, r0, v2 */
5534 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5535 0x0000ffff /* end */
5538 float quad1[] = {
5539 -1.0, -1.0, 0.1,
5540 0.0, -1.0, 0.1,
5541 -1.0, 0.0, 0.1,
5542 0.0, 0.0, 0.1
5544 float quad2[] = {
5545 0.0, -1.0, 0.1,
5546 1.0, -1.0, 0.1,
5547 0.0, 0.0, 0.1,
5548 1.0, 0.0, 0.1
5550 float quad3[] = {
5551 -1.0, 0.0, 0.1,
5552 0.0, 0.0, 0.1,
5553 -1.0, 1.0, 0.1,
5554 0.0, 1.0, 0.1
5556 float quad4[] = {
5557 0.0, 0.0, 0.1,
5558 1.0, 0.0, 0.1,
5559 0.0, 1.0, 0.1,
5560 1.0, 1.0, 0.1
5563 HRESULT hr;
5564 DWORD color;
5565 IDirect3DVertexShader9 *vertexshader = NULL;
5566 IDirect3DPixelShader9 *ps_1_shader = NULL;
5567 IDirect3DPixelShader9 *ps_2_shader = NULL;
5568 IDirect3DPixelShader9 *ps_3_shader = NULL;
5569 IDirect3DTexture9 *texture = NULL;
5570 D3DLOCKED_RECT lr;
5571 unsigned int x, y;
5573 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5575 hr = IDirect3DDevice9_CreateTexture(device, 512, 512, 1, 0, D3DFMT_A16B16G16R16, D3DPOOL_MANAGED, &texture, NULL);
5576 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %s\n", DXGetErrorString9(hr));
5577 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5578 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %s\n", DXGetErrorString9(hr));
5579 for(y = 0; y < 512; y++) {
5580 for(x = 0; x < 512; x++) {
5581 double r_f = (double) x / (double) 512;
5582 double g_f = (double) y / (double) 512;
5583 unsigned short *dst = (unsigned short *) (((unsigned char *) lr.pBits) + y * lr.Pitch + x * 8);
5584 unsigned short r = (unsigned short) (r_f * 65535.0);
5585 unsigned short g = (unsigned short) (g_f * 65535.0);
5586 dst[0] = r;
5587 dst[1] = g;
5588 dst[2] = 0;
5589 dst[3] = 65535;
5592 hr = IDirect3DTexture9_UnlockRect(texture, 0);
5593 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %s\n", DXGetErrorString9(hr));
5595 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vertexshader);
5596 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5597 hr = IDirect3DDevice9_CreatePixelShader(device, ps_1_code, &ps_1_shader);
5598 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
5599 hr = IDirect3DDevice9_CreatePixelShader(device, ps_2_code, &ps_2_shader);
5600 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
5601 hr = IDirect3DDevice9_CreatePixelShader(device, ps_3_code, &ps_3_shader);
5602 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
5603 hr = IDirect3DDevice9_SetVertexShader(device, vertexshader);
5604 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5605 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5607 hr = IDirect3DDevice9_BeginScene(device);
5608 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5609 if(SUCCEEDED(hr))
5611 hr = IDirect3DDevice9_SetPixelShader(device, ps_1_shader);
5612 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5613 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5614 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5616 hr = IDirect3DDevice9_SetPixelShader(device, ps_2_shader);
5617 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5618 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
5619 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5621 hr = IDirect3DDevice9_SetPixelShader(device, ps_3_shader);
5622 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5623 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5624 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5626 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5627 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5628 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5629 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
5630 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
5631 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
5632 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
5633 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
5634 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5635 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5637 hr = IDirect3DDevice9_EndScene(device);
5638 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5640 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5641 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5643 color = getPixelColor(device, 160, 120);
5644 ok((color & 0x00ff0000) >= 0x00790000 && (color & 0x00ff0000) <= 0x00810000 &&
5645 (color & 0x0000ff00) == 0x0000ff00 &&
5646 (color & 0x000000ff) >= 0x000000e4 && (color & 0x000000ff) <= 0x000000e6,
5647 "ps_3_0 returned color 0x%08x, expected 0x0080ffe5\n", color);
5648 color = getPixelColor(device, 160, 360);
5649 ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5650 (color & 0x0000ff00) >= 0x00003300 && (color & 0x0000ff00) <= 0x00003400 &&
5651 (color & 0x000000ff) == 0x00000000,
5652 "ps_1_4 returned color 0x%08x, expected 0x00203300\n", color);
5653 color = getPixelColor(device, 480, 360);
5654 ok((color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5655 (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5656 (color & 0x000000ff) == 0x00000000,
5657 "ps_2_0 returned color 0x%08x, expected 0x00203300\n", color);
5658 color = getPixelColor(device, 480, 160);
5659 ok( color == 0x00ffffff /* Nvidia driver garbage with HW vp */ || (
5660 (color & 0x00ff0000) >= 0x00190000 && (color & 0x00ff0000) <= 0x00210000 &&
5661 (color & 0x0000ff00) >= 0x00003200 && (color & 0x0000ff00) <= 0x00003400 &&
5662 (color & 0x000000ff) == 0x00000000),
5663 "fixed function fragment processing returned color 0x%08x, expected 0x00203300\n", color);
5665 /* cleanup */
5666 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5667 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
5668 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5669 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
5670 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
5671 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5672 if(vertexshader) IDirect3DVertexShader9_Release(vertexshader);
5673 if(ps_1_shader) IDirect3DPixelShader9_Release(ps_1_shader);
5674 if(ps_2_shader) IDirect3DPixelShader9_Release(ps_2_shader);
5675 if(ps_3_shader) IDirect3DPixelShader9_Release(ps_3_shader);
5676 if(texture) IDirect3DTexture9_Release(texture);
5679 void test_compare_instructions(IDirect3DDevice9 *device)
5681 DWORD shader_sge_vec_code[] = {
5682 0xfffe0101, /* vs_1_1 */
5683 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5684 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5685 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5686 0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001, /* sge oD0, r0, c1 */
5687 0x0000ffff /* end */
5689 DWORD shader_slt_vec_code[] = {
5690 0xfffe0101, /* vs_1_1 */
5691 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5692 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5693 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5694 0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001, /* slt oD0, r0, c1 */
5695 0x0000ffff /* end */
5697 DWORD shader_sge_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 0x0000000d, 0xd0010000, 0x80000000, 0xa0550001, /* slt oD0.r, r0.r, c1.b */
5703 0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001, /* slt oD0.g, r0.g, c1.r */
5704 0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001, /* slt oD0.b, r0.b, c1.g */
5705 0x0000ffff /* end */
5707 DWORD shader_slt_scalar_code[] = {
5708 0xfffe0101, /* vs_1_1 */
5709 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5710 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5711 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5712 0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001, /* slt oD0.r, r0.r, c1.b */
5713 0x0000000c, 0xd0020000, 0x80550000, 0xa0000001, /* slt oD0.g, r0.g, c1.r */
5714 0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001, /* slt oD0.b, r0.b, c1.g */
5715 0x0000ffff /* end */
5717 IDirect3DVertexShader9 *shader_sge_vec;
5718 IDirect3DVertexShader9 *shader_slt_vec;
5719 IDirect3DVertexShader9 *shader_sge_scalar;
5720 IDirect3DVertexShader9 *shader_slt_scalar;
5721 HRESULT hr, color;
5722 float quad1[] = {
5723 -1.0, -1.0, 0.1,
5724 0.0, -1.0, 0.1,
5725 -1.0, 0.0, 0.1,
5726 0.0, 0.0, 0.1
5728 float quad2[] = {
5729 0.0, -1.0, 0.1,
5730 1.0, -1.0, 0.1,
5731 0.0, 0.0, 0.1,
5732 1.0, 0.0, 0.1
5734 float quad3[] = {
5735 -1.0, 0.0, 0.1,
5736 0.0, 0.0, 0.1,
5737 -1.0, 1.0, 0.1,
5738 0.0, 1.0, 0.1
5740 float quad4[] = {
5741 0.0, 0.0, 0.1,
5742 1.0, 0.0, 0.1,
5743 0.0, 1.0, 0.1,
5744 1.0, 1.0, 0.1
5746 const float const0[4] = {0.8, 0.2, 0.2, 0.2};
5747 const float const1[4] = {0.2, 0.8, 0.2, 0.2};
5749 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
5751 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
5752 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5753 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
5754 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5755 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
5756 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5757 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
5758 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
5759 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5760 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5761 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
5762 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5763 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5764 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
5766 hr = IDirect3DDevice9_BeginScene(device);
5767 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
5768 if(SUCCEEDED(hr))
5770 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
5771 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5772 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
5773 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5775 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
5776 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5777 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
5778 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5780 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
5781 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5782 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
5783 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5785 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
5786 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
5788 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
5789 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
5790 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
5791 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5793 hr = IDirect3DDevice9_EndScene(device);
5794 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
5797 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5798 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
5800 color = getPixelColor(device, 160, 360);
5801 ok(color == 0x00FF00FF, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00FF00FF\n", color);
5802 color = getPixelColor(device, 480, 360);
5803 ok(color == 0x0000FF00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000FF00\n", color);
5804 color = getPixelColor(device, 160, 120);
5805 ok(color == 0x00FFFFFF, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00FFFFFF\n", color);
5806 color = getPixelColor(device, 480, 160);
5807 ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
5809 IDirect3DVertexShader9_Release(shader_sge_vec);
5810 IDirect3DVertexShader9_Release(shader_slt_vec);
5811 IDirect3DVertexShader9_Release(shader_sge_scalar);
5812 IDirect3DVertexShader9_Release(shader_slt_scalar);
5815 void test_vshader_input(IDirect3DDevice9 *device)
5817 DWORD swapped_shader_code_3[] = {
5818 0xfffe0300, /* vs_3_0 */
5819 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5820 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
5821 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5822 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
5823 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
5824 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5825 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
5826 0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
5827 0x0000ffff /* end */
5829 DWORD swapped_shader_code_1[] = {
5830 0xfffe0101, /* vs_1_1 */
5831 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5832 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
5833 0x0000001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
5834 0x00000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
5835 0x00000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
5836 0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
5837 0x0000ffff /* end */
5839 DWORD swapped_shader_code_2[] = {
5840 0xfffe0200, /* vs_2_0 */
5841 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5842 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
5843 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
5844 0x02000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
5845 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
5846 0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
5847 0x0000ffff /* end */
5849 DWORD texcoord_color_shader_code_3[] = {
5850 0xfffe0300, /* vs_3_0 */
5851 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5852 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
5853 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5854 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
5855 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5856 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
5857 0x0000ffff /* end */
5859 DWORD texcoord_color_shader_code_2[] = {
5860 0xfffe0200, /* vs_2_0 */
5861 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5862 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
5863 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5864 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
5865 0x0000ffff /* end */
5867 DWORD texcoord_color_shader_code_1[] = {
5868 0xfffe0101, /* vs_1_1 */
5869 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5870 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
5871 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5872 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
5873 0x0000ffff /* end */
5875 DWORD color_color_shader_code_3[] = {
5876 0xfffe0300, /* vs_3_0 */
5877 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
5878 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
5879 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5880 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
5881 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
5882 0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001, /* mul o1, c0, v1 */
5883 0x0000ffff /* end */
5885 DWORD color_color_shader_code_2[] = {
5886 0xfffe0200, /* vs_2_0 */
5887 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5888 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
5889 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5890 0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
5891 0x0000ffff /* end */
5893 DWORD color_color_shader_code_1[] = {
5894 0xfffe0101, /* vs_1_1 */
5895 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5896 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
5897 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5898 0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
5899 0x0000ffff /* end */
5901 IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
5902 HRESULT hr;
5903 DWORD color, r, g, b;
5904 float quad1[] = {
5905 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
5906 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
5907 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
5908 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
5910 float quad2[] = {
5911 0.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
5912 1.0, -1.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
5913 0.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
5914 1.0, 0.0, 0.1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
5916 float quad3[] = {
5917 -1.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0,
5918 0.0, 0.0, 0.1, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,
5919 -1.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0,
5920 0.0, 1.0, 0.1, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0,
5922 float quad4[] = {
5923 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
5924 1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
5925 0.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
5926 1.0, 1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.5, 0.0,
5928 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] = {
5929 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5930 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5931 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
5932 D3DDECL_END()
5934 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] = {
5935 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5936 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
5937 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5938 D3DDECL_END()
5940 static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] = {
5941 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5942 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5943 D3DDECL_END()
5945 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] = {
5946 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5947 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
5948 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
5949 D3DDECL_END()
5951 static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] = {
5952 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5953 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
5954 D3DDECL_END()
5956 static const D3DVERTEXELEMENT9 decl_elements_color_color[] = {
5957 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5958 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5959 D3DDECL_END()
5961 static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] = {
5962 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5963 {0, 12, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5964 D3DDECL_END()
5966 static const D3DVERTEXELEMENT9 decl_elements_color_float[] = {
5967 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5968 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
5969 D3DDECL_END()
5971 IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
5972 IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
5973 unsigned int i;
5974 float normalize[4] = {1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0};
5975 float no_normalize[4] = {1.0, 1.0, 1.0, 1.0};
5977 struct vertex quad1_color[] = {
5978 {-1.0, -1.0, 0.1, 0x00ff8040},
5979 { 0.0, -1.0, 0.1, 0x00ff8040},
5980 {-1.0, 0.0, 0.1, 0x00ff8040},
5981 { 0.0, 0.0, 0.1, 0x00ff8040}
5983 struct vertex quad2_color[] = {
5984 { 0.0, -1.0, 0.1, 0x00ff8040},
5985 { 1.0, -1.0, 0.1, 0x00ff8040},
5986 { 0.0, 0.0, 0.1, 0x00ff8040},
5987 { 1.0, 0.0, 0.1, 0x00ff8040}
5989 struct vertex quad3_color[] = {
5990 {-1.0, 0.0, 0.1, 0x00ff8040},
5991 { 0.0, 0.0, 0.1, 0x00ff8040},
5992 {-1.0, 1.0, 0.1, 0x00ff8040},
5993 { 0.0, 1.0, 0.1, 0x00ff8040}
5995 float quad4_color[] = {
5996 0.0, 0.0, 0.1, 1.0, 1.0, 0.0, 0.0,
5997 1.0, 0.0, 0.1, 1.0, 1.0, 0.0, 1.0,
5998 0.0, 1.0, 0.1, 1.0, 1.0, 0.0, 0.0,
5999 1.0, 1.0, 0.1, 1.0, 1.0, 0.0, 1.0,
6002 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
6003 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6004 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
6005 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6006 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
6007 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6008 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
6009 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6011 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
6012 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6013 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
6014 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6015 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
6016 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6017 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
6018 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6020 for(i = 1; i <= 3; i++) {
6021 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
6022 if(i == 3) {
6023 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
6024 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6025 } else if(i == 2){
6026 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
6027 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6028 } else if(i == 1) {
6029 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
6030 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6033 hr = IDirect3DDevice9_BeginScene(device);
6034 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
6035 if(SUCCEEDED(hr))
6037 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6038 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6040 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6041 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6042 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
6043 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6045 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6046 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6047 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
6048 if(i == 3 || i == 2) {
6049 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6050 } else if(i == 1) {
6051 /* Succeeds or fails, depending on SW or HW vertex processing */
6052 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6055 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
6056 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6057 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
6058 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6060 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
6061 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6062 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
6063 if(i == 3 || i == 2) {
6064 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6065 } else if(i == 1) {
6066 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = 1\n", hr);
6069 hr = IDirect3DDevice9_EndScene(device);
6070 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
6073 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6074 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6076 if(i == 3 || i == 2) {
6077 color = getPixelColor(device, 160, 360);
6078 ok(color == 0x00FFFF80 || color == 0x00FFFF7f || color == 0x00FFFF81,
6079 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6081 /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
6082 color = getPixelColor(device, 480, 360);
6083 ok(color == 0x00FFFF00 || color ==0x00FF0000,
6084 "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6085 color = getPixelColor(device, 160, 120);
6086 /* Same as above, accept both the last used value and 0.0 for the undefined streams */
6087 ok(color == 0x00FF0080 || color == 0x00FF007f || color == 0x00FF0081 || color == 0x00FF0000,
6088 "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);
6092 } else if(i == 1) {
6093 color = getPixelColor(device, 160, 360);
6094 ok(color == 0x00FFFF80 || color == 0x00FFFF7f || color == 0x00FFFF81,
6095 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00FFFF80\n", color);
6096 color = getPixelColor(device, 480, 360);
6097 /* Accept the clear color as well in this case, since SW VP returns an error */
6098 ok(color == 0x00FFFF00 || color == 0x00FF0000, "Input test: Quad 2(1crd) returned color 0x%08x, expected 0x00FFFF00\n", color);
6099 color = getPixelColor(device, 160, 120);
6100 ok(color == 0x00FF0080 || color == 0x00FF0000 || color == 0x00FF007f || color == 0x00FF0081,
6101 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00FF0080\n", color);
6102 color = getPixelColor(device, 480, 160);
6103 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
6106 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
6107 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
6109 /* Now find out if the whole streams are re-read, or just the last active value for the
6110 * vertices is used.
6112 hr = IDirect3DDevice9_BeginScene(device);
6113 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
6114 if(SUCCEEDED(hr))
6116 float quad1_modified[] = {
6117 -1.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0,
6118 0.0, -1.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0,
6119 -1.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0,
6120 0.0, 0.0, 0.1, 1.0, 0.0, 1.0, 0.0, -1.0, -1.0, -1.0, 0.0,
6122 float quad2_modified[] = {
6123 0.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6124 1.0, -1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6125 0.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6126 1.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
6129 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
6130 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6132 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
6133 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6134 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
6135 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6137 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
6138 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6139 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
6140 if(i == 3 || i == 2) {
6141 ok(hr == D3D_OK, "DrawPrimitiveUP returned (%08x) i = %d\n", hr, i);
6142 } else if(i == 1) {
6143 /* Succeeds or fails, depending on SW or HW vertex processing */
6144 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "DrawPrimitiveUP returned (%08x), i = 1\n", hr);
6147 hr = IDirect3DDevice9_EndScene(device);
6148 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
6150 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6151 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6153 color = getPixelColor(device, 480, 350);
6154 /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
6155 * as well.
6157 * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
6158 * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
6159 * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
6160 * refrast's result.
6162 * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
6164 ok(color == 0x000000FF || color == 0x00808080 || color == 0x00000000,
6165 "Input test: Quad 2(different colors) returned color 0x%08x, expected 0x000000FF, 0x00808080 or 0x00000000\n", color);
6166 color = getPixelColor(device, 160, 120);
6168 IDirect3DDevice9_SetVertexShader(device, NULL);
6169 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6171 IDirect3DVertexShader9_Release(swapped_shader);
6174 for(i = 1; i <= 3; i++) {
6175 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
6176 if(i == 3) {
6177 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
6178 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6179 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
6180 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6181 } else if(i == 2){
6182 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
6183 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6184 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
6185 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6186 } else if(i == 1) {
6187 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
6188 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6189 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
6190 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6193 hr = IDirect3DDevice9_BeginScene(device);
6194 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
6195 if(SUCCEEDED(hr))
6197 hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
6198 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6199 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
6200 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6201 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
6202 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6204 hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
6205 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6207 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
6208 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6209 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
6210 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6211 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
6212 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6214 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
6215 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6216 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
6217 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6218 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
6219 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6221 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
6222 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
6223 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
6224 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6226 hr = IDirect3DDevice9_EndScene(device);
6227 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
6229 IDirect3DDevice9_SetVertexShader(device, NULL);
6230 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
6232 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6233 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6235 color = getPixelColor(device, 160, 360);
6236 r = (color & 0x00ff0000) >> 16;
6237 g = (color & 0x0000ff00) >> 8;
6238 b = (color & 0x000000ff) >> 0;
6239 ok(r >= 0xfe && r <= 0xff && g >= 0x7f && g <= 0x81 && b >= 0x3f && b <= 0x41,
6240 "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
6241 color = getPixelColor(device, 480, 360);
6242 r = (color & 0x00ff0000) >> 16;
6243 g = (color & 0x0000ff00) >> 8;
6244 b = (color & 0x000000ff) >> 0;
6245 ok(r >= 0x3f && r <= 0x41 && g >= 0x7f && g <= 0x81 && b >= 0xfe && b <= 0xff,
6246 "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
6247 color = getPixelColor(device, 160, 120);
6248 r = (color & 0x00ff0000) >> 16;
6249 g = (color & 0x0000ff00) >> 8;
6250 b = (color & 0x000000ff) >> 0;
6251 ok(r >= 0xfe && r <= 0xff && g >= 0x7f && g <= 0x81 && b >= 0x3f && b <= 0x41,
6252 "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
6253 color = getPixelColor(device, 480, 160);
6254 r = (color & 0x00ff0000) >> 16;
6255 g = (color & 0x0000ff00) >> 8;
6256 b = (color & 0x000000ff) >> 0;
6257 ok(r >= 0xfe && r <= 0xff && g >= 0xfe && g <= 0xff && b <= 0x01,
6258 "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00FFFF00\n", color);
6260 IDirect3DVertexShader9_Release(texcoord_color_shader);
6261 IDirect3DVertexShader9_Release(color_color_shader);
6264 IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
6265 IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
6266 IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
6267 IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
6269 IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
6270 IDirect3DVertexDeclaration9_Release(decl_color_color);
6271 IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
6272 IDirect3DVertexDeclaration9_Release(decl_color_float);
6275 static void srgbtexture_test(IDirect3DDevice9 *device)
6277 /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
6278 * texture stage state to render a quad using that texture. The resulting
6279 * color components should be 0x36 (~ 0.21), per this formula:
6280 * linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
6281 * This is true where srgb_color > 0.04045.
6283 IDirect3D9 *d3d = NULL;
6284 HRESULT hr;
6285 LPDIRECT3DTEXTURE9 texture = NULL;
6286 LPDIRECT3DSURFACE9 surface = NULL;
6287 D3DLOCKED_RECT lr;
6288 DWORD color;
6289 float quad[] = {
6290 -1.0, 1.0, 0.0, 0.0, 0.0,
6291 1.0, 1.0, 0.0, 1.0, 0.0,
6292 -1.0, -1.0, 0.0, 0.0, 1.0,
6293 1.0, -1.0, 0.0, 1.0, 1.0,
6297 memset(&lr, 0, sizeof(lr));
6298 IDirect3DDevice9_GetDirect3D(device, &d3d);
6299 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6300 D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
6301 D3DFMT_A8R8G8B8) != D3D_OK) {
6302 skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported\n");
6303 goto out;
6306 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0,
6307 D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
6308 &texture, NULL);
6309 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
6310 if(!texture) {
6311 skip("Failed to create A8R8G8B8 texture with SRGBREAD\n");
6312 goto out;
6314 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
6315 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
6317 fill_surface(surface, 0xff7f7f7f);
6318 IDirect3DSurface9_Release(surface);
6320 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6321 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6322 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
6323 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
6325 hr = IDirect3DDevice9_BeginScene(device);
6326 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
6327 if(SUCCEEDED(hr))
6329 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
6330 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
6332 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6333 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
6336 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
6337 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
6339 hr = IDirect3DDevice9_EndScene(device);
6340 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
6343 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6344 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
6345 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
6346 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
6348 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6349 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6351 color = getPixelColor(device, 320, 240);
6352 ok(color == 0x00363636 || color == 0x00373737, "srgb quad has color %08x, expected 0x00363636\n", color);
6354 out:
6355 if(texture) IDirect3DTexture9_Release(texture);
6356 IDirect3D9_Release(d3d);
6359 static void shademode_test(IDirect3DDevice9 *device)
6361 /* Render a quad and try all of the different fixed function shading models. */
6362 HRESULT hr;
6363 DWORD color0, color1;
6364 DWORD color0_gouraud = 0, color1_gouraud = 0;
6365 BYTE r, g, b;
6366 DWORD shademode = D3DSHADE_FLAT;
6367 DWORD primtype = D3DPT_TRIANGLESTRIP;
6368 LPVOID data = NULL;
6369 LPDIRECT3DVERTEXBUFFER9 vb_strip = NULL;
6370 LPDIRECT3DVERTEXBUFFER9 vb_list = NULL;
6371 UINT i, j;
6372 struct vertex quad_strip[] =
6374 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
6375 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6376 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6377 { 1.0f, 1.0f, 0.0f, 0xffffffff }
6379 struct vertex quad_list[] =
6381 {-1.0f, -1.0f, 0.0f, 0xffff0000 },
6382 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6383 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6385 {-1.0f, 1.0f, 0.0f, 0xff00ff00 },
6386 { 1.0f, -1.0f, 0.0f, 0xff0000ff },
6387 { 1.0f, 1.0f, 0.0f, 0xffffffff }
6390 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip),
6391 0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
6392 ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
6393 if (FAILED(hr)) goto bail;
6395 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list),
6396 0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
6397 ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
6398 if (FAILED(hr)) goto bail;
6400 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6401 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6403 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6404 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
6406 hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), (void **) &data, 0);
6407 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
6408 memcpy(data, quad_strip, sizeof(quad_strip));
6409 hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
6410 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
6412 hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), (void **) &data, 0);
6413 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
6414 memcpy(data, quad_list, sizeof(quad_list));
6415 hr = IDirect3DVertexBuffer9_Unlock(vb_list);
6416 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
6418 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
6419 * the color fixups we have to do for FLAT shading will be dependent on that. */
6420 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_strip, 0, sizeof(quad_strip[0]));
6421 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6423 /* First loop uses a TRIANGLESTRIP geometry, 2nd uses a TRIANGLELIST */
6424 for (j=0; j<2; j++) {
6426 /* Inner loop just changes the D3DRS_SHADEMODE */
6427 for (i=0; i<3; i++) {
6428 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6429 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
6431 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, shademode);
6432 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6434 hr = IDirect3DDevice9_BeginScene(device);
6435 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
6436 if(SUCCEEDED(hr))
6438 hr = IDirect3DDevice9_DrawPrimitive(device, primtype, 0, 2);
6439 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed with %s\n", DXGetErrorString9(hr));
6441 hr = IDirect3DDevice9_EndScene(device);
6442 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
6445 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6446 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6448 /* Sample two spots from the output */
6449 color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
6450 color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
6451 switch(shademode) {
6452 case D3DSHADE_FLAT:
6453 /* Should take the color of the first vertex of each triangle */
6454 todo_wine ok(color0 == 0x00ff0000, "FLAT shading has color0 %08x, expected 0x00ff0000 (todo)\n", color0);
6455 todo_wine ok(color1 == 0x0000ff00, "FLAT shading has color1 %08x, expected 0x0000ff00 (todo)\n", color1);
6456 shademode = D3DSHADE_GOURAUD;
6457 break;
6458 case D3DSHADE_GOURAUD:
6459 /* Should be an interpolated blend */
6461 r = (color0 & 0x00ff0000) >> 16;
6462 g = (color0 & 0x0000ff00) >> 8;
6463 b = (color0 & 0x000000ff);
6464 ok(r >= 0x0c && r <= 0x0e && g == 0xca && b >= 0x27 && b <= 0x28,
6465 "GOURAUD shading has color0 %08x, expected 0x000dca28\n", color0);
6466 r = (color1 & 0x00ff0000) >> 16;
6467 g = (color1 & 0x0000ff00) >> 8;
6468 b = (color1 & 0x000000ff);
6469 ok(r >= 0x0c && r <= 0x0d && g >= 0x44 && g <= 0x45 && b >= 0xc7 && b <= 0xc8,
6470 "GOURAUD shading has color1 %08x, expected 0x000d45c7\n", color1);
6472 color0_gouraud = color0;
6473 color1_gouraud = color1;
6475 shademode = D3DSHADE_PHONG;
6476 break;
6477 case D3DSHADE_PHONG:
6478 /* Should be the same as GOURAUD, since no hardware implements this */
6479 r = (color0 & 0x00ff0000) >> 16;
6480 g = (color0 & 0x0000ff00) >> 8;
6481 b = (color0 & 0x000000ff);
6482 ok(r >= 0x0c && r <= 0x0e && g == 0xca && b >= 0x27 && b <= 0x28,
6483 "PHONG shading has color0 %08x, expected 0x000dca28\n", color0);
6484 r = (color1 & 0x00ff0000) >> 16;
6485 g = (color1 & 0x0000ff00) >> 8;
6486 b = (color1 & 0x000000ff);
6487 ok(r >= 0x0c && r <= 0x0d && g >= 0x44 && g <= 0x45 && b >= 0xc7 && b <= 0xc8,
6488 "PHONG shading has color1 %08x, expected 0x000d45c7\n", color1);
6490 ok(color0 == color0_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6491 color0_gouraud, color0);
6492 ok(color1 == color1_gouraud, "difference between GOURAUD and PHONG shading detected: %08x %08x\n",
6493 color1_gouraud, color1);
6494 break;
6497 /* Now, do it all over again with a TRIANGLELIST */
6498 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb_list, 0, sizeof(quad_list[0]));
6499 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6500 primtype = D3DPT_TRIANGLELIST;
6501 shademode = D3DSHADE_FLAT;
6504 bail:
6505 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
6506 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
6507 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
6508 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6510 if (vb_strip)
6511 IDirect3DVertexBuffer9_Release(vb_strip);
6512 if (vb_list)
6513 IDirect3DVertexBuffer9_Release(vb_list);
6517 static void fog_srgbwrite_test(IDirect3DDevice9 *device)
6519 /* Draw a black quad, half fogged with white fog -> grey color. Enable sRGB writing.
6520 * if sRGB writing is applied before fogging, the 0.0 will be multiplied with ~ 12.92, so still
6521 * stay 0.0. After that the fog gives 0.5. If sRGB writing is applied after fogging, the
6522 * 0.5 will run through the alternative path(0^5 ^ 0.41666 * 1.055 - 0.055), resulting in approx.
6523 * 0.73
6525 * At the time of this writing, wined3d could not apply sRGB correction to fixed function rendering,
6526 * so use shaders for this task
6528 IDirect3DPixelShader9 *pshader;
6529 IDirect3DVertexShader9 *vshader;
6530 IDirect3D9 *d3d;
6531 DWORD vshader_code[] = {
6532 0xfffe0101, /* vs_1_1 */
6533 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6534 0x00000051, 0xa00f0000, 0x3f000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.5, 0.0, 0.0, 0.0 */
6535 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6536 0x00000001, 0xc00f0001, 0xa0000000, /* mov oFog, c0.x */
6537 0x0000ffff /* end */
6539 DWORD pshader_code[] = {
6540 0xffff0101, /* ps_1_1 */
6541 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
6542 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6543 0x0000ffff /* end */
6545 const float quad[] = {
6546 -1.0, -1.0, 0.1,
6547 1.0, -1.0, 0.1,
6548 -1.0, 1.0, 0.1,
6549 1.0, 1.0, 0.1
6551 HRESULT hr;
6552 DWORD color;
6554 IDirect3DDevice9_GetDirect3D(device, &d3d);
6555 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
6556 D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBWRITE,
6557 D3DRTYPE_SURFACE, D3DFMT_A8R8G8B8) != D3D_OK) {
6558 skip("No SRGBWRITEENABLE support on D3DFMT_X8R8G8B8\n");
6559 IDirect3D9_Release(d3d);
6560 return;
6562 IDirect3D9_Release(d3d);
6564 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
6565 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
6567 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
6568 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6569 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
6570 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6571 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
6572 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6573 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffffffff);
6574 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6575 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
6576 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6578 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
6579 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %s\n", DXGetErrorString9(hr));
6580 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code, &pshader);
6581 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
6582 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6583 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
6584 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
6585 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6586 hr = IDirect3DDevice9_SetPixelShader(device, pshader);
6587 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
6589 hr = IDirect3DDevice9_BeginScene(device);
6590 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
6591 if(SUCCEEDED(hr)) {
6592 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 3);
6593 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6595 hr = IDirect3DDevice9_EndScene(device);
6596 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
6599 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
6600 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
6601 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6602 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %s\n", DXGetErrorString9(hr));
6603 IDirect3DPixelShader9_Release(pshader);
6604 IDirect3DVertexShader9_Release(vshader);
6606 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
6607 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6608 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
6609 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6611 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6612 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
6613 color = getPixelColor(device, 160, 360);
6614 ok(color == 0x00808080 || color == 0x007f7f7f || color == 0x00818181,
6615 "Fog with D3DRS_SRGBWRITEENABLE returned color 0x%08x, expected 0x00808080\n", color);
6618 static void alpha_test(IDirect3DDevice9 *device)
6620 HRESULT hr;
6621 IDirect3DTexture9 *offscreenTexture;
6622 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
6623 DWORD color, red, green, blue;
6625 struct vertex quad1[] =
6627 {-1.0f, -1.0f, 0.1f, 0x4000ff00},
6628 {-1.0f, 0.0f, 0.1f, 0x4000ff00},
6629 { 1.0f, -1.0f, 0.1f, 0x4000ff00},
6630 { 1.0f, 0.0f, 0.1f, 0x4000ff00},
6632 struct vertex quad2[] =
6634 {-1.0f, 0.0f, 0.1f, 0xc00000ff},
6635 {-1.0f, 1.0f, 0.1f, 0xc00000ff},
6636 { 1.0f, 0.0f, 0.1f, 0xc00000ff},
6637 { 1.0f, 1.0f, 0.1f, 0xc00000ff},
6639 static const float composite_quad[][5] = {
6640 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
6641 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
6642 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
6643 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
6646 /* Clear the render target with alpha = 0.5 */
6647 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6648 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6650 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
6651 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
6653 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6654 ok(hr == D3D_OK, "Can't get back buffer, hr = %s\n", DXGetErrorString9(hr));
6655 if(!backbuffer) {
6656 goto out;
6659 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
6660 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %s\n", DXGetErrorString9(hr));
6661 if(!offscreen) {
6662 goto out;
6665 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6666 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6668 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6669 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
6670 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6671 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
6672 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
6673 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
6674 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
6675 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
6676 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6677 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
6679 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
6680 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6681 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
6683 /* Draw two quads, one with src alpha blending, one with dest alpha blending. The
6684 * SRCALPHA / INVSRCALPHA blend doesn't give any surprises. Colors are blended based on
6685 * the input alpha
6687 * The DESTALPHA / INVDESTALPHA do not "work" on the regular buffer because there is no alpha.
6688 * They give essentially ZERO and ONE blend factors
6690 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6691 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6692 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6693 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6694 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6695 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6697 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6698 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6699 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6700 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6701 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6702 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6704 /* Switch to the offscreen buffer, and redo the testing. SRCALPHA and DESTALPHA. The offscreen buffer
6705 * has a alpha channel on its own. Clear the offscreen buffer with alpha = 0.5 again, then draw the
6706 * quads again. The SRCALPHA/INVSRCALPHA doesn't give any surprises, but the DESTALPHA/INVDESTALPHA
6707 * blending works as supposed now - blend factor is 0.5 in both cases, not 0.75 as from the input
6708 * vertices
6710 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
6711 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6712 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
6713 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6715 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
6716 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6717 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
6718 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6719 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6720 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6722 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
6723 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6724 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
6725 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6726 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6727 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6729 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
6730 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
6732 /* Render the offscreen texture onto the frame buffer to be able to compare it regularly.
6733 * Disable alpha blending for the final composition
6735 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
6736 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
6737 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6738 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
6740 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
6741 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6742 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
6743 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6744 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
6745 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr = %08x\n", hr);
6747 hr = IDirect3DDevice9_EndScene(device);
6748 ok(hr == D3D_OK, "IDirect3DDevice7_EndScene failed, hr = %08x\n", hr);
6751 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6753 color = getPixelColor(device, 160, 360);
6754 red = (color & 0x00ff0000) >> 16;
6755 green = (color & 0x0000ff00) >> 8;
6756 blue = (color & 0x000000ff);
6757 ok(red >= 0xbe && red <= 0xc0 && green >= 0x39 && green <= 0x41 && blue == 0x00,
6758 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
6760 color = getPixelColor(device, 160, 120);
6761 red = (color & 0x00ff0000) >> 16;
6762 green = (color & 0x0000ff00) >> 8;
6763 blue = (color & 0x000000ff);
6764 ok(red == 0x00 && green == 0x00 && blue >= 0xfe && blue <= 0xff ,
6765 "DSTALPHA on frame buffer returned color %08x, expected 0x00ff0000\n", color);
6767 color = getPixelColor(device, 480, 360);
6768 red = (color & 0x00ff0000) >> 16;
6769 green = (color & 0x0000ff00) >> 8;
6770 blue = (color & 0x000000ff);
6771 ok(red >= 0xbe && red <= 0xc0 && green >= 0x39 && green <= 0x41 && blue == 0x00,
6772 "SRCALPHA on texture returned color %08x, expected bar\n", color);
6774 color = getPixelColor(device, 480, 120);
6775 red = (color & 0x00ff0000) >> 16;
6776 green = (color & 0x0000ff00) >> 8;
6777 blue = (color & 0x000000ff);
6778 ok(red >= 0x7e && red <= 0x81 && green == 0x00 && blue >= 0x7e && blue <= 0x81,
6779 "DSTALPHA on texture returned color %08x, expected 0x00800080\n", color);
6781 out:
6782 /* restore things */
6783 if(backbuffer) {
6784 IDirect3DSurface9_Release(backbuffer);
6786 if(offscreenTexture) {
6787 IDirect3DTexture9_Release(offscreenTexture);
6789 if(offscreen) {
6790 IDirect3DSurface9_Release(offscreen);
6794 struct vertex_shortcolor {
6795 float x, y, z;
6796 unsigned short r, g, b, a;
6798 struct vertex_floatcolor {
6799 float x, y, z;
6800 float r, g, b, a;
6803 static void fixed_function_decl_test(IDirect3DDevice9 *device)
6805 HRESULT hr;
6806 BOOL s_ok, ub_ok, f_ok;
6807 DWORD color, size, i;
6808 void *data;
6809 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
6810 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6811 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6812 D3DDECL_END()
6814 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
6815 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6816 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6817 D3DDECL_END()
6819 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
6820 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6821 {0, 12, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6822 D3DDECL_END()
6824 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
6825 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6826 {1, 0, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6827 D3DDECL_END()
6829 static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
6830 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6831 {0, 12, D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6832 D3DDECL_END()
6834 static const D3DVERTEXELEMENT9 decl_elements_float[] = {
6835 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6836 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6837 D3DDECL_END()
6839 static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
6840 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
6841 {0, 16, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
6842 D3DDECL_END()
6844 IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
6845 IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_positiont;
6846 IDirect3DVertexBuffer9 *vb, *vb2;
6847 struct vertex quad1[] = /* D3DCOLOR */
6849 {-1.0f, -1.0f, 0.1f, 0x00ffff00},
6850 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
6851 { 0.0f, -1.0f, 0.1f, 0x00ffff00},
6852 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
6854 struct vertex quad2[] = /* UBYTE4N */
6856 {-1.0f, 0.0f, 0.1f, 0x00ffff00},
6857 {-1.0f, 1.0f, 0.1f, 0x00ffff00},
6858 { 0.0f, 0.0f, 0.1f, 0x00ffff00},
6859 { 0.0f, 1.0f, 0.1f, 0x00ffff00},
6861 struct vertex_shortcolor quad3[] = /* short */
6863 { 0.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6864 { 0.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6865 { 1.0f, -1.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6866 { 1.0f, 0.0f, 0.1f, 0x0000, 0x0000, 0xffff, 0xffff},
6868 struct vertex_floatcolor quad4[] =
6870 { 0.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6871 { 0.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6872 { 1.0f, 0.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6873 { 1.0f, 1.0f, 0.1f, 1.0, 0.0, 0.0, 0.0},
6875 DWORD colors[] = {
6876 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6877 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6878 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6879 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6880 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6881 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6882 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6883 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6884 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6885 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6886 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6887 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6888 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6889 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6890 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6891 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
6893 float quads[] = {
6894 -1.0, -1.0, 0.1,
6895 -1.0, 0.0, 0.1,
6896 0.0, -1.0, 0.1,
6897 0.0, 0.0, 0.1,
6899 0.0, -1.0, 0.1,
6900 0.0, 0.0, 0.1,
6901 1.0, -1.0, 0.1,
6902 1.0, 0.0, 0.1,
6904 0.0, 0.0, 0.1,
6905 0.0, 1.0, 0.1,
6906 1.0, 0.0, 0.1,
6907 1.0, 1.0, 0.1,
6909 -1.0, 0.0, 0.1,
6910 -1.0, 1.0, 0.1,
6911 0.0, 0.0, 0.1,
6912 0.0, 1.0, 0.1
6914 struct tvertex quad_transformed[] = {
6915 { 90, 110, 0.1, 2.0, 0x00ffff00},
6916 { 570, 110, 0.1, 2.0, 0x00ffff00},
6917 { 90, 300, 0.1, 2.0, 0x00ffff00},
6918 { 570, 300, 0.1, 2.0, 0x00ffff00}
6920 D3DCAPS9 caps;
6922 memset(&caps, 0, sizeof(caps));
6923 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6924 ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
6926 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
6927 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
6929 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
6930 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6931 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
6932 ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
6933 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
6934 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6935 if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
6936 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
6937 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6938 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
6939 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6940 } else {
6941 trace("D3DDTCAPS_UBYTE4N not supported\n");
6942 dcl_ubyte_2 = NULL;
6943 dcl_ubyte = NULL;
6945 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
6946 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6947 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
6948 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
6950 size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
6951 hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
6952 0, 0, D3DPOOL_MANAGED, &vb, NULL);
6953 ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
6955 hr = IDirect3DDevice9_BeginScene(device);
6956 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
6957 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
6958 if(SUCCEEDED(hr)) {
6959 if(dcl_color) {
6960 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
6961 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6962 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
6963 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6966 /* Tests with non-standard fixed function types fail on the refrast. The ATI driver partially
6967 * accepts them, the nvidia driver accepts them all. All those differences even though we're
6968 * using software vertex processing. Doh!
6970 if(dcl_ubyte) {
6971 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
6972 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6973 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
6974 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6975 ub_ok = SUCCEEDED(hr);
6978 if(dcl_short) {
6979 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
6980 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6981 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
6982 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6983 s_ok = SUCCEEDED(hr);
6986 if(dcl_float) {
6987 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
6988 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
6989 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
6990 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
6991 f_ok = SUCCEEDED(hr);
6994 hr = IDirect3DDevice9_EndScene(device);
6995 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
6998 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6999 if(dcl_short) {
7000 color = getPixelColor(device, 480, 360);
7001 ok(color == 0x000000ff || !s_ok,
7002 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7004 if(dcl_ubyte) {
7005 color = getPixelColor(device, 160, 120);
7006 ok(color == 0x0000ffff || !ub_ok,
7007 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7009 if(dcl_color) {
7010 color = getPixelColor(device, 160, 360);
7011 ok(color == 0x00ffff00,
7012 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7014 if(dcl_float) {
7015 color = getPixelColor(device, 480, 120);
7016 ok(color == 0x00ff0000 || !f_ok,
7017 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7020 /* The following test with vertex buffers doesn't serve to find out new information from windows.
7021 * It is a plain regression test because wined3d uses different codepaths for attribute conversion
7022 * with vertex buffers. It makes sure that the vertex buffer one works, while the above tests
7023 * whether the immediate mode code works
7025 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
7026 hr = IDirect3DDevice9_BeginScene(device);
7027 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7028 if(SUCCEEDED(hr)) {
7029 if(dcl_color) {
7030 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), (void **) &data, 0);
7031 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7032 memcpy(data, quad1, sizeof(quad1));
7033 hr = IDirect3DVertexBuffer9_Unlock(vb);
7034 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7035 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
7036 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7037 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
7038 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7039 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7040 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7043 if(dcl_ubyte) {
7044 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), (void **) &data, 0);
7045 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7046 memcpy(data, quad2, sizeof(quad2));
7047 hr = IDirect3DVertexBuffer9_Unlock(vb);
7048 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7049 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
7050 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7051 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
7052 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7053 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7054 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7055 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7056 ub_ok = SUCCEEDED(hr);
7059 if(dcl_short) {
7060 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), (void **) &data, 0);
7061 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7062 memcpy(data, quad3, sizeof(quad3));
7063 hr = IDirect3DVertexBuffer9_Unlock(vb);
7064 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7065 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
7066 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7067 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
7068 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7069 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7070 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7071 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7072 s_ok = SUCCEEDED(hr);
7075 if(dcl_float) {
7076 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), (void **) &data, 0);
7077 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7078 memcpy(data, quad4, sizeof(quad4));
7079 hr = IDirect3DVertexBuffer9_Unlock(vb);
7080 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7081 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
7082 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7083 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
7084 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7085 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7086 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7087 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7088 f_ok = SUCCEEDED(hr);
7091 hr = IDirect3DDevice9_EndScene(device);
7092 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %#08x\n", hr);
7095 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7096 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7097 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7098 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed (%08x)\n", hr);
7100 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7101 if(dcl_short) {
7102 color = getPixelColor(device, 480, 360);
7103 ok(color == 0x000000ff || !s_ok,
7104 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
7106 if(dcl_ubyte) {
7107 color = getPixelColor(device, 160, 120);
7108 ok(color == 0x0000ffff || !ub_ok,
7109 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
7111 if(dcl_color) {
7112 color = getPixelColor(device, 160, 360);
7113 ok(color == 0x00ffff00,
7114 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7116 if(dcl_float) {
7117 color = getPixelColor(device, 480, 120);
7118 ok(color == 0x00ff0000 || !f_ok,
7119 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
7122 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7123 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
7125 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), (void **) &data, 0);
7126 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7127 memcpy(data, quad_transformed, sizeof(quad_transformed));
7128 hr = IDirect3DVertexBuffer9_Unlock(vb);
7129 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7131 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
7132 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7134 hr = IDirect3DDevice9_BeginScene(device);
7135 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7136 if(SUCCEEDED(hr)) {
7137 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
7138 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7139 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7140 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7142 hr = IDirect3DDevice9_EndScene(device);
7143 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7146 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7147 color = getPixelColor(device, 88, 108);
7148 ok(color == 0x000000ff,
7149 "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7150 color = getPixelColor(device, 92, 108);
7151 ok(color == 0x000000ff,
7152 "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7153 color = getPixelColor(device, 88, 112);
7154 ok(color == 0x000000ff,
7155 "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7156 color = getPixelColor(device, 92, 112);
7157 ok(color == 0x00ffff00,
7158 "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7160 color = getPixelColor(device, 568, 108);
7161 ok(color == 0x000000ff,
7162 "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7163 color = getPixelColor(device, 572, 108);
7164 ok(color == 0x000000ff,
7165 "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7166 color = getPixelColor(device, 568, 112);
7167 ok(color == 0x00ffff00,
7168 "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7169 color = getPixelColor(device, 572, 112);
7170 ok(color == 0x000000ff,
7171 "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7173 color = getPixelColor(device, 88, 298);
7174 ok(color == 0x000000ff,
7175 "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7176 color = getPixelColor(device, 92, 298);
7177 ok(color == 0x00ffff00,
7178 "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7179 color = getPixelColor(device, 88, 302);
7180 ok(color == 0x000000ff,
7181 "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7182 color = getPixelColor(device, 92, 302);
7183 ok(color == 0x000000ff,
7184 "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7186 color = getPixelColor(device, 568, 298);
7187 ok(color == 0x00ffff00,
7188 "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7189 color = getPixelColor(device, 572, 298);
7190 ok(color == 0x000000ff,
7191 "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7192 color = getPixelColor(device, 568, 302);
7193 ok(color == 0x000000ff,
7194 "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7195 color = getPixelColor(device, 572, 302);
7196 ok(color == 0x000000ff,
7197 "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7199 /* This test is pointless without those two declarations: */
7200 if((!dcl_color_2) || (!dcl_ubyte_2)) {
7201 skip("color-ubyte switching test declarations aren't supported\n");
7202 goto out;
7205 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), (void **) &data, 0);
7206 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7207 memcpy(data, quads, sizeof(quads));
7208 hr = IDirect3DVertexBuffer9_Unlock(vb);
7209 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7210 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
7211 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
7212 ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
7213 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), (void **) &data, 0);
7214 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
7215 memcpy(data, colors, sizeof(colors));
7216 hr = IDirect3DVertexBuffer9_Unlock(vb2);
7217 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
7219 for(i = 0; i < 2; i++) {
7220 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
7221 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
7223 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
7224 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7225 if(i == 0) {
7226 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
7227 } else {
7228 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
7230 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7232 hr = IDirect3DDevice9_BeginScene(device);
7233 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
7234 ub_ok = FALSE;
7235 if(SUCCEEDED(hr)) {
7236 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7237 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7238 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7239 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7240 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7241 ub_ok = SUCCEEDED(hr);
7243 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
7244 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7245 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7246 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7248 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
7249 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
7250 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7251 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
7252 "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7253 ub_ok = (SUCCEEDED(hr) && ub_ok);
7255 hr = IDirect3DDevice9_EndScene(device);
7256 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
7259 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7260 if(i == 0) {
7261 color = getPixelColor(device, 480, 360);
7262 ok(color == 0x00ff0000,
7263 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\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 == 0x000000ff || !ub_ok,
7269 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7270 color = getPixelColor(device, 480, 120);
7271 ok(color == 0x000000ff || !ub_ok,
7272 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
7273 } else {
7274 color = getPixelColor(device, 480, 360);
7275 ok(color == 0x000000ff,
7276 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
7277 color = getPixelColor(device, 160, 120);
7278 ok(color == 0x00ffffff,
7279 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
7280 color = getPixelColor(device, 160, 360);
7281 ok(color == 0x00ff0000 || !ub_ok,
7282 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7283 color = getPixelColor(device, 480, 120);
7284 ok(color == 0x00ff0000 || !ub_ok,
7285 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
7289 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7290 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7291 hr = IDirect3DDevice9_SetStreamSource(device, 1, NULL, 0, 0);
7292 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %s\n", DXGetErrorString9(hr));
7293 IDirect3DVertexBuffer9_Release(vb2);
7295 out:
7296 IDirect3DVertexBuffer9_Release(vb);
7297 if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
7298 if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
7299 if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
7300 if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
7301 if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
7302 if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
7303 if(dcl_positiont) IDirect3DVertexDeclaration9_Release(dcl_positiont);
7306 struct vertex_float16color {
7307 float x, y, z;
7308 DWORD c1, c2;
7311 static void test_vshader_float16(IDirect3DDevice9 *device)
7313 HRESULT hr;
7314 DWORD color;
7315 void *data;
7316 static const D3DVERTEXELEMENT9 decl_elements[] = {
7317 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7318 {0, 12, D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7319 D3DDECL_END()
7321 IDirect3DVertexDeclaration9 *vdecl = NULL;
7322 IDirect3DVertexBuffer9 *buffer = NULL;
7323 IDirect3DVertexShader9 *shader;
7324 DWORD shader_code[] = {
7325 0xfffe0101, 0x0000001f, 0x80000000, 0x900f0000, 0x0000001f, 0x8000000a,
7326 0x900f0001, 0x00000001, 0xc00f0000, 0x90e40000, 0x00000001, 0xd00f0000,
7327 0x90e40001, 0x0000ffff
7329 struct vertex_float16color quad[] = {
7330 { -1.0, -1.0, 0.1, 0x3c000000, 0x00000000 }, /* green */
7331 { -1.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
7332 { 0.0, -1.0, 0.1, 0x3c000000, 0x00000000 },
7333 { 0.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
7335 { 0.0, -1.0, 0.1, 0x00003c00, 0x00000000 }, /* red */
7336 { 0.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
7337 { 1.0, -1.0, 0.1, 0x00003c00, 0x00000000 },
7338 { 1.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
7340 { 0.0, 0.0, 0.1, 0x00000000, 0x00003c00 }, /* blue */
7341 { 0.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
7342 { 1.0, 0.0, 0.1, 0x00000000, 0x00003c00 },
7343 { 1.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
7345 { -1.0, 0.0, 0.1, 0x00000000, 0x3c000000 }, /* alpha */
7346 { -1.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
7347 { 0.0, 0.0, 0.1, 0x00000000, 0x3c000000 },
7348 { 0.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
7351 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7352 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7354 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
7355 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%s\n", DXGetErrorString9(hr));
7356 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
7357 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%s\n", DXGetErrorString9(hr));
7358 hr = IDirect3DDevice9_SetVertexShader(device, shader);
7359 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%s\n", DXGetErrorString9(hr));
7361 hr = IDirect3DDevice9_BeginScene(device);
7362 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
7363 if(SUCCEEDED(hr)) {
7364 hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
7365 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%s\n", DXGetErrorString9(hr));
7366 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 0, sizeof(quad[0]));
7367 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7368 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 4, sizeof(quad[0]));
7369 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7370 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 8, sizeof(quad[0]));
7371 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7372 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
7373 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7375 hr = IDirect3DDevice9_EndScene(device);
7376 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%s\n", DXGetErrorString9(hr));
7378 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7379 color = getPixelColor(device, 480, 360);
7380 ok(color == 0x00ff0000,
7381 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7382 color = getPixelColor(device, 160, 120);
7383 ok(color == 0x00000000,
7384 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7385 color = getPixelColor(device, 160, 360);
7386 ok(color == 0x0000ff00,
7387 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7388 color = getPixelColor(device, 480, 120);
7389 ok(color == 0x000000ff,
7390 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7392 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
7393 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7395 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
7396 D3DPOOL_MANAGED, &buffer, NULL);
7397 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%s\n", DXGetErrorString9(hr));
7398 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), (void **) &data, 0);
7399 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%s\n", DXGetErrorString9(hr));
7400 memcpy(data, quad, sizeof(quad));
7401 hr = IDirect3DVertexBuffer9_Unlock(buffer);
7402 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%s\n", DXGetErrorString9(hr));
7403 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
7404 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%s\n", DXGetErrorString9(hr));
7406 hr = IDirect3DDevice9_BeginScene(device);
7407 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed (%08x)\n", hr);
7408 if(SUCCEEDED(hr)) {
7409 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
7410 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7411 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
7412 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7413 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
7414 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7415 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
7416 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive failed, hr = %#08x\n", hr);
7418 hr = IDirect3DDevice9_EndScene(device);
7419 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%s\n", DXGetErrorString9(hr));
7422 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7423 color = getPixelColor(device, 480, 360);
7424 ok(color == 0x00ff0000,
7425 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
7426 color = getPixelColor(device, 160, 120);
7427 ok(color == 0x00000000,
7428 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
7429 color = getPixelColor(device, 160, 360);
7430 ok(color == 0x0000ff00,
7431 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
7432 color = getPixelColor(device, 480, 120);
7433 ok(color == 0x000000ff,
7434 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
7436 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
7437 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%s\n", DXGetErrorString9(hr));
7438 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7439 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%s\n", DXGetErrorString9(hr));
7440 IDirect3DDevice9_SetVertexShader(device, NULL);
7441 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%s\n", DXGetErrorString9(hr));
7443 IDirect3DVertexDeclaration9_Release(vdecl);
7444 IDirect3DVertexShader9_Release(shader);
7445 IDirect3DVertexBuffer9_Release(buffer);
7448 static void conditional_np2_repeat_test(IDirect3DDevice9 *device)
7450 D3DCAPS9 caps;
7451 IDirect3DTexture9 *texture;
7452 HRESULT hr;
7453 D3DLOCKED_RECT rect;
7454 unsigned int x, y;
7455 DWORD *dst, color;
7456 const float quad[] = {
7457 -1.0, -1.0, 0.1, -0.2, -0.2,
7458 1.0, -1.0, 0.1, 1.2, -0.2,
7459 -1.0, 1.0, 0.1, -0.2, 1.2,
7460 1.0, 1.0, 0.1, 1.2, 1.2
7462 memset(&caps, 0, sizeof(caps));
7464 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7465 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%s\n", DXGetErrorString9(hr));
7466 if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7467 /* NP2 conditional requires the POW2 flag. Check that while we're at it */
7468 ok((caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) == 0,
7469 "Card has conditional NP2 support without power of two restriction set\n");
7470 skip("Card has unconditional pow2 support, skipping conditional NP2 tests\n");
7471 return;
7472 } else if(!(caps.TextureCaps & D3DPTEXTURECAPS_POW2)) {
7473 skip("No conditional NP2 support, skipping conditional NP2 tests\n");
7474 return;
7477 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
7478 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7480 hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
7481 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%s\n", DXGetErrorString9(hr));
7483 memset(&rect, 0, sizeof(rect));
7484 hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
7485 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%s\n", DXGetErrorString9(hr));
7486 for(y = 0; y < 10; y++) {
7487 for(x = 0; x < 10; x++) {
7488 dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
7489 if(x == 0 || x == 9 || y == 0 || y == 9) {
7490 *dst = 0x00ff0000;
7491 } else {
7492 *dst = 0x000000ff;
7496 hr = IDirect3DTexture9_UnlockRect(texture, 0);
7497 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%s\n", DXGetErrorString9(hr));
7499 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7500 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%s\n", DXGetErrorString9(hr));
7501 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
7502 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%s\n", DXGetErrorString9(hr));
7503 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
7504 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%s\n", DXGetErrorString9(hr));
7505 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7506 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%s\n", DXGetErrorString9(hr));
7508 hr = IDirect3DDevice9_BeginScene(device);
7509 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
7510 if(SUCCEEDED(hr)) {
7511 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
7512 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7514 hr = IDirect3DDevice9_EndScene(device);
7515 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
7518 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7520 color = getPixelColor(device, 1, 1);
7521 ok(color == 0x00ff0000, "NP2: Pixel 1, 1 has color %08x, expected 0x00ff0000\n", color);
7522 color = getPixelColor(device, 639, 479);
7523 ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
7525 color = getPixelColor(device, 135, 101);
7526 ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
7527 color = getPixelColor(device, 140, 101);
7528 ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
7529 color = getPixelColor(device, 135, 105);
7530 ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
7531 color = getPixelColor(device, 140, 105);
7532 ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
7534 color = getPixelColor(device, 135, 376);
7535 ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
7536 color = getPixelColor(device, 140, 376);
7537 ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
7538 color = getPixelColor(device, 135, 379);
7539 ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
7540 color = getPixelColor(device, 140, 379);
7541 ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
7543 color = getPixelColor(device, 500, 101);
7544 ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
7545 color = getPixelColor(device, 504, 101);
7546 ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
7547 color = getPixelColor(device, 500, 105);
7548 ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
7549 color = getPixelColor(device, 504, 105);
7550 ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
7552 color = getPixelColor(device, 500, 376);
7553 ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
7554 color = getPixelColor(device, 504, 376);
7555 ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
7556 color = getPixelColor(device, 500, 380);
7557 ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
7558 color = getPixelColor(device, 504, 380);
7559 ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
7561 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
7562 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%s\n", DXGetErrorString9(hr));
7563 IDirect3DTexture9_Release(texture);
7566 static void vFace_register_test(IDirect3DDevice9 *device)
7568 HRESULT hr;
7569 DWORD color;
7570 const DWORD shader_code[] = {
7571 0xffff0300, /* ps_3_0 */
7572 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
7573 0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
7574 0x0200001f, 0x80000000, 0x900f1001, /* dcl vFace */
7575 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
7576 0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001, /* cmp r0, vFace, c0, r1 */
7577 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
7578 0x0000ffff /* END */
7580 IDirect3DPixelShader9 *shader;
7581 IDirect3DTexture9 *texture;
7582 IDirect3DSurface9 *surface, *backbuffer;
7583 const float quad[] = {
7584 -1.0, -1.0, 0.1,
7585 1.0, -1.0, 0.1,
7586 -1.0, 0.0, 0.1,
7588 1.0, -1.0, 0.1,
7589 1.0, 0.0, 0.1,
7590 -1.0, 0.0, 0.1,
7592 -1.0, 0.0, 0.1,
7593 -1.0, 1.0, 0.1,
7594 1.0, 0.0, 0.1,
7596 1.0, 0.0, 0.1,
7597 -1.0, 1.0, 0.1,
7598 1.0, 1.0, 0.1,
7600 const float blit[] = {
7601 0.0, -1.0, 0.1, 0.0, 0.0,
7602 1.0, -1.0, 0.1, 1.0, 0.0,
7603 0.0, 1.0, 0.1, 0.0, 1.0,
7604 1.0, 1.0, 0.1, 1.0, 1.0,
7607 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
7608 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%s\n", DXGetErrorString9(hr));
7609 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
7610 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%s\n", DXGetErrorString9(hr));
7611 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
7612 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%s\n", DXGetErrorString9(hr));
7613 hr = IDirect3DDevice9_SetPixelShader(device, shader);
7614 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
7615 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7616 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%s\n", DXGetErrorString9(hr));
7617 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
7618 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%s\n", DXGetErrorString9(hr));
7620 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7621 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7623 hr = IDirect3DDevice9_BeginScene(device);
7624 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
7625 if(SUCCEEDED(hr)) {
7626 /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
7627 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
7628 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
7629 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7630 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
7631 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7632 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7633 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
7634 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
7635 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
7636 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7638 /* Blit the texture onto the back buffer to make it visible */
7639 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7640 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%s\n", DXGetErrorString9(hr));
7641 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
7642 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%s\n", DXGetErrorString9(hr));
7643 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7644 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%s\n", DXGetErrorString9(hr));
7645 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7646 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed, hr=%s\n", DXGetErrorString9(hr));
7647 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
7648 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%s\n", DXGetErrorString9(hr));
7650 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
7651 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
7653 hr = IDirect3DDevice9_EndScene(device);
7654 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
7657 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7658 color = getPixelColor(device, 160, 360);
7659 ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7660 color = getPixelColor(device, 160, 120);
7661 ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7662 color = getPixelColor(device, 480, 360);
7663 ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
7664 color = getPixelColor(device, 480, 120);
7665 ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
7667 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
7668 IDirect3DDevice9_SetTexture(device, 0, NULL);
7669 IDirect3DPixelShader9_Release(shader);
7670 IDirect3DSurface9_Release(surface);
7671 IDirect3DSurface9_Release(backbuffer);
7672 IDirect3DTexture9_Release(texture);
7675 static void fixed_function_bumpmap_test(IDirect3DDevice9 *device)
7677 HRESULT hr;
7678 DWORD color;
7679 int i;
7680 D3DCAPS9 caps;
7682 static const float quad[][7] = {
7683 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
7684 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
7685 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
7686 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
7689 static const D3DVERTEXELEMENT9 decl_elements[] = {
7690 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7691 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7692 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7693 D3DDECL_END()
7696 /* use asymmetric matrix to test loading */
7697 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
7699 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
7700 IDirect3DTexture9 *texture = NULL;
7702 memset(&caps, 0, sizeof(caps));
7703 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7704 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%s\n", DXGetErrorString9(hr));
7705 if(!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP)) {
7706 skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
7707 return;
7708 } else {
7709 /* This check is disabled, some Windows drivers do not handle D3DUSAGE_QUERY_LEGACYBUMPMAP properly.
7710 * They report that it is not supported, but after that bump mapping works properly. So just test
7711 * if the format is generally supported, and check the BUMPENVMAP flag
7713 IDirect3D9 *d3d9;
7715 IDirect3DDevice9_GetDirect3D(device, &d3d9);
7716 hr = IDirect3D9_CheckDeviceFormat(d3d9, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
7717 D3DRTYPE_TEXTURE, D3DFMT_V8U8);
7718 IDirect3D9_Release(d3d9);
7719 if(FAILED(hr)) {
7720 skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
7721 return;
7725 /* Generate the textures */
7726 generate_bumpmap_textures(device);
7728 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
7729 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7730 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
7731 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7732 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
7733 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7734 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
7735 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7737 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
7738 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7739 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
7740 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7741 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
7742 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7744 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7745 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7746 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7747 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7748 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7749 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7751 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
7752 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7754 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
7755 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
7757 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
7758 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
7761 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
7762 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
7763 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
7764 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
7766 hr = IDirect3DDevice9_BeginScene(device);
7767 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
7769 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
7770 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
7772 hr = IDirect3DDevice9_EndScene(device);
7773 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
7775 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7776 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
7778 color = getPixelColor(device, 320-32, 240);
7779 ok(color == 0x00ffffff, "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7780 color = getPixelColor(device, 320+32, 240);
7781 ok(color == 0x00ffffff, "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7782 color = getPixelColor(device, 320, 240-32);
7783 ok(color == 0x00ffffff, "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7784 color = getPixelColor(device, 320, 240+32);
7785 ok(color == 0x00ffffff, "bumpmap failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
7786 color = getPixelColor(device, 320, 240);
7787 ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7788 color = getPixelColor(device, 320+32, 240+32);
7789 ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7790 color = getPixelColor(device, 320-32, 240+32);
7791 ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7792 color = getPixelColor(device, 320+32, 240-32);
7793 ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7794 color = getPixelColor(device, 320-32, 240-32);
7795 ok(color == 0x00000000, "bumpmap failed: Got color 0x%08x, expected 0x00000000.\n", color);
7797 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7798 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
7799 IDirect3DVertexDeclaration9_Release(vertex_declaration);
7801 for(i = 0; i < 2; i++) {
7802 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
7803 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
7804 IDirect3DTexture9_Release(texture); /* For the GetTexture */
7805 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
7806 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
7807 IDirect3DTexture9_Release(texture); /* To destroy it */
7810 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
7811 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7812 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
7813 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
7817 static void stencil_cull_test(IDirect3DDevice9 *device) {
7818 HRESULT hr;
7819 IDirect3DSurface9 *depthstencil = NULL;
7820 D3DSURFACE_DESC desc;
7821 float quad1[] = {
7822 -1.0, -1.0, 0.1,
7823 0.0, -1.0, 0.1,
7824 -1.0, 0.0, 0.1,
7825 0.0, 0.0, 0.1,
7827 float quad2[] = {
7828 0.0, -1.0, 0.1,
7829 1.0, -1.0, 0.1,
7830 0.0, 0.0, 0.1,
7831 1.0, 0.0, 0.1,
7833 float quad3[] = {
7834 0.0, 0.0, 0.1,
7835 1.0, 0.0, 0.1,
7836 0.0, 1.0, 0.1,
7837 1.0, 1.0, 0.1,
7839 float quad4[] = {
7840 -1.0, 0.0, 0.1,
7841 0.0, 0.0, 0.1,
7842 -1.0, 1.0, 0.1,
7843 0.0, 1.0, 0.1,
7845 struct vertex painter[] = {
7846 {-1.0, -1.0, 0.0, 0x00000000},
7847 { 1.0, -1.0, 0.0, 0x00000000},
7848 {-1.0, 1.0, 0.0, 0x00000000},
7849 { 1.0, 1.0, 0.0, 0x00000000},
7851 WORD indices_cw[] = {0, 1, 3};
7852 WORD indices_ccw[] = {0, 2, 3};
7853 unsigned int i;
7854 DWORD color;
7856 IDirect3DDevice9_GetDepthStencilSurface(device, &depthstencil);
7857 if(depthstencil == NULL) {
7858 skip("No depth stencil buffer\n");
7859 return;
7861 hr = IDirect3DSurface9_GetDesc(depthstencil, &desc);
7862 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %s\n", DXGetErrorString9(hr));
7863 IDirect3DSurface9_Release(depthstencil);
7864 if(desc.Format != D3DFMT_D24S8 && desc.Format != D3DFMT_D24X4S4) {
7865 skip("No 4 or 8 bit stencil surface\n");
7866 return;
7869 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
7870 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
7871 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7873 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
7874 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7875 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
7876 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7877 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
7878 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7879 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
7880 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7882 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
7883 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7884 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
7885 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7886 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
7887 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7889 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
7890 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7891 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
7892 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7894 /* First pass: Fill the stencil buffer with some values... */
7895 hr = IDirect3DDevice9_BeginScene(device);
7896 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
7897 if(SUCCEEDED(hr))
7899 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
7900 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7901 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7902 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
7903 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7904 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
7906 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
7907 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7908 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
7909 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7910 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7911 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
7912 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7913 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
7915 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
7916 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7917 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7918 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
7919 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7920 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
7922 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
7923 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7924 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7925 1 /*PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
7926 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
7927 1 /*PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
7929 hr = IDirect3DDevice9_EndScene(device);
7930 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
7933 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7934 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
7935 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7936 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
7937 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7938 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
7939 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7940 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
7941 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7942 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
7943 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7944 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
7945 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7947 /* 2nd pass: Make the stencil values visible */
7948 hr = IDirect3DDevice9_BeginScene(device);
7949 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
7950 if(SUCCEEDED(hr))
7952 IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
7953 for(i = 0; i < 16; i++) {
7954 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
7955 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7957 painter[0].diffuse = (i * 16); /* Creates shades of blue */
7958 painter[1].diffuse = (i * 16);
7959 painter[2].diffuse = (i * 16);
7960 painter[3].diffuse = (i * 16);
7961 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
7962 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
7964 hr = IDirect3DDevice9_EndScene(device);
7965 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
7968 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7969 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
7971 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
7972 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
7974 color = getPixelColor(device, 160, 420);
7975 ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
7976 color = getPixelColor(device, 160, 300);
7977 ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
7979 color = getPixelColor(device, 480, 420);
7980 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
7981 color = getPixelColor(device, 480, 300);
7982 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
7984 color = getPixelColor(device, 160, 180);
7985 ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
7986 color = getPixelColor(device, 160, 60);
7987 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
7989 color = getPixelColor(device, 480, 180);
7990 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
7991 color = getPixelColor(device, 480, 60);
7992 ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
7995 static void vpos_register_test(IDirect3DDevice9 *device)
7997 HRESULT hr;
7998 DWORD color;
7999 const DWORD shader_code[] = {
8000 0xffff0300, /* ps_3_0 */
8001 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8002 0x03000002, 0x80030000, 0x90541000, 0xa1fe0000, /* sub r0.xy, vPos.xy, c0.zw */
8003 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
8004 0x02000001, 0x80080002, 0xa0550000, /* mov r2.a, c0.y */
8005 0x02000001, 0x80010002, 0xa0550000, /* mov r2.r, c0.y */
8006 0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001, /* cmp r2.g, r0.x, r1.x, r1.y */
8007 0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001, /* cmp r2.b, r0.y, r1.x, r1.y */
8008 0x02000001, 0x800f0800, 0x80e40002, /* mov oC0, r2 */
8009 0x0000ffff /* end */
8011 const DWORD shader_frac_code[] = {
8012 0xffff0300, /* ps_3_0 */
8013 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
8014 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
8015 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
8016 0x02000013, 0x80030000, 0x90541000, /* frc r0.xy, vPos.xy */
8017 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
8018 0x0000ffff /* end */
8020 IDirect3DPixelShader9 *shader, *shader_frac;
8021 IDirect3DSurface9 *surface = NULL, *backbuffer;
8022 const float quad[] = {
8023 -1.0, -1.0, 0.1, 0.0, 0.0,
8024 1.0, -1.0, 0.1, 1.0, 0.0,
8025 -1.0, 1.0, 0.1, 0.0, 1.0,
8026 1.0, 1.0, 0.1, 1.0, 1.0,
8028 D3DLOCKED_RECT lr;
8029 float constant[4] = {1.0, 0.0, 320, 240};
8030 DWORD *pos;
8032 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8033 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
8034 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
8035 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%s\n", DXGetErrorString9(hr));
8036 hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
8037 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%s\n", DXGetErrorString9(hr));
8038 hr = IDirect3DDevice9_SetPixelShader(device, shader);
8039 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
8040 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8041 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%s\n", DXGetErrorString9(hr));
8042 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8043 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%s\n", DXGetErrorString9(hr));
8045 hr = IDirect3DDevice9_BeginScene(device);
8046 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
8047 if(SUCCEEDED(hr)) {
8048 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8049 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%s\n", DXGetErrorString9(hr));
8050 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8051 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8052 hr = IDirect3DDevice9_EndScene(device);
8053 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
8056 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8057 /* This has to be pixel exact */
8058 color = getPixelColor(device, 319, 239);
8059 ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
8060 color = getPixelColor(device, 320, 239);
8061 ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
8062 color = getPixelColor(device, 319, 240);
8063 ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
8064 color = getPixelColor(device, 320, 240);
8065 ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
8067 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
8068 &surface, NULL);
8069 ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%s\n", DXGetErrorString9(hr));
8070 hr = IDirect3DDevice9_BeginScene(device);
8071 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
8072 if(SUCCEEDED(hr)) {
8073 constant[2] = 16; constant[3] = 16;
8074 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
8075 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF failed hr=%s\n", DXGetErrorString9(hr));
8076 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
8077 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8078 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8079 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8080 hr = IDirect3DDevice9_EndScene(device);
8081 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
8083 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8084 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%s\n", DXGetErrorString9(hr));
8086 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8087 color = *pos & 0x00ffffff;
8088 ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
8089 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
8090 color = *pos & 0x00ffffff;
8091 ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
8092 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
8093 color = *pos & 0x00ffffff;
8094 ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
8095 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
8096 color = *pos & 0x00ffffff;
8097 ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
8099 hr = IDirect3DSurface9_UnlockRect(surface);
8100 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%s\n", DXGetErrorString9(hr));
8102 /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
8103 * have full control over the multisampling setting inside this test
8105 hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
8106 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
8107 hr = IDirect3DDevice9_BeginScene(device);
8108 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
8109 if(SUCCEEDED(hr)) {
8110 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8111 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
8112 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
8113 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8114 hr = IDirect3DDevice9_EndScene(device);
8115 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
8117 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8118 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8120 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
8121 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%s\n", DXGetErrorString9(hr));
8123 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
8124 color = *pos & 0x00ffffff;
8125 ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
8127 hr = IDirect3DSurface9_UnlockRect(surface);
8128 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%s\n", DXGetErrorString9(hr));
8130 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8131 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%s\n", DXGetErrorString9(hr));
8132 IDirect3DPixelShader9_Release(shader);
8133 IDirect3DPixelShader9_Release(shader_frac);
8134 if(surface) IDirect3DSurface9_Release(surface);
8135 IDirect3DSurface9_Release(backbuffer);
8138 static void pointsize_test(IDirect3DDevice9 *device)
8140 HRESULT hr;
8141 D3DCAPS9 caps;
8142 D3DMATRIX matrix;
8143 D3DMATRIX identity;
8144 float ptsize, ptsize_orig;
8145 DWORD color;
8147 const float vertices[] = {
8148 64, 64, 0.1,
8149 128, 64, 0.1,
8150 192, 64, 0.1,
8151 256, 64, 0.1,
8152 320, 64, 0.1,
8153 384, 64, 0.1
8156 /* 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 */
8157 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;
8158 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;
8159 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;
8160 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;
8162 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;
8163 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;
8164 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;
8165 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;
8167 memset(&caps, 0, sizeof(caps));
8168 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8169 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%s\n", DXGetErrorString9(hr));
8170 if(caps.MaxPointSize < 32.0) {
8171 skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
8172 return;
8175 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0, 0);
8176 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
8177 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
8178 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%s\n", DXGetErrorString9(hr));
8179 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8180 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%s\n", DXGetErrorString9(hr));
8181 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, (DWORD *) &ptsize_orig);
8182 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed hr=%s\n", DXGetErrorString9(hr));
8184 hr = IDirect3DDevice9_BeginScene(device);
8185 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed hr=%s\n", DXGetErrorString9(hr));
8186 if(SUCCEEDED(hr)) {
8187 ptsize = 16.0;
8188 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8189 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8190 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
8191 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8193 ptsize = 32.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[3], sizeof(float) * 3);
8197 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8199 ptsize = 31.5;
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[6], sizeof(float) * 3);
8203 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8205 if(caps.MaxPointSize >= 64.0) {
8206 ptsize = 64.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[9], sizeof(float) * 3);
8210 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8212 ptsize = 63.75;
8213 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8214 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8215 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
8216 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8219 ptsize = 1.0;
8220 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
8221 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%s\n", DXGetErrorString9(hr));
8222 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
8223 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8225 hr = IDirect3DDevice9_EndScene(device);
8226 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed hr=%s\n", DXGetErrorString9(hr));
8228 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8229 color = getPixelColor(device, 64-9, 64-9);
8230 ok(color == 0x000000ff, "pSize: Pixel (64-9),(64-9) has color 0x%08x, expected 0x000000ff\n", color);
8231 color = getPixelColor(device, 64-8, 64-8);
8232 todo_wine ok(color == 0x00ffffff, "pSize: Pixel (64-8),(64-8) has color 0x%08x, expected 0x00ffffff\n", color);
8233 color = getPixelColor(device, 64-7, 64-7);
8234 ok(color == 0x00ffffff, "pSize: Pixel (64-7),(64-7) has color 0x%08x, expected 0x00ffffff\n", color);
8235 color = getPixelColor(device, 64+7, 64+7);
8236 ok(color == 0x00ffffff, "pSize: Pixel (64+7),(64+7) has color 0x%08x, expected 0x00ffffff\n", color);
8237 color = getPixelColor(device, 64+8, 64+8);
8238 ok(color == 0x000000ff, "pSize: Pixel (64+8),(64+8) has color 0x%08x, expected 0x000000ff\n", color);
8239 color = getPixelColor(device, 64+9, 64+9);
8240 ok(color == 0x000000ff, "pSize: Pixel (64+9),(64+9) has color 0x%08x, expected 0x000000ff\n", color);
8242 color = getPixelColor(device, 128-17, 64-17);
8243 ok(color == 0x000000ff, "pSize: Pixel (128-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8244 color = getPixelColor(device, 128-16, 64-16);
8245 todo_wine ok(color == 0x00ffffff, "pSize: Pixel (128-16),(64-16) has color 0x%08x, expected 0x00ffffff\n", color);
8246 color = getPixelColor(device, 128-15, 64-15);
8247 ok(color == 0x00ffffff, "pSize: Pixel (128-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8248 color = getPixelColor(device, 128+15, 64+15);
8249 ok(color == 0x00ffffff, "pSize: Pixel (128+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8250 color = getPixelColor(device, 128+16, 64+16);
8251 ok(color == 0x000000ff, "pSize: Pixel (128+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8252 color = getPixelColor(device, 128+17, 64+17);
8253 ok(color == 0x000000ff, "pSize: Pixel (128+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8255 color = getPixelColor(device, 192-17, 64-17);
8256 ok(color == 0x000000ff, "pSize: Pixel (192-17),(64-17) has color 0x%08x, expected 0x000000ff\n", color);
8257 color = getPixelColor(device, 192-16, 64-16);
8258 ok(color == 0x000000ff, "pSize: Pixel (192-16),(64-16) has color 0x%08x, expected 0x000000ff\n", color);
8259 color = getPixelColor(device, 192-15, 64-15);
8260 ok(color == 0x00ffffff, "pSize: Pixel (192-15),(64-15) has color 0x%08x, expected 0x00ffffff\n", color);
8261 color = getPixelColor(device, 192+15, 64+15);
8262 ok(color == 0x00ffffff, "pSize: Pixel (192+15),(64+15) has color 0x%08x, expected 0x00ffffff\n", color);
8263 color = getPixelColor(device, 192+16, 64+16);
8264 ok(color == 0x000000ff, "pSize: Pixel (192+16),(64+16) has color 0x%08x, expected 0x000000ff\n", color);
8265 color = getPixelColor(device, 192+17, 64+17);
8266 ok(color == 0x000000ff, "pSize: Pixel (192+17),(64+17) has color 0x%08x, expected 0x000000ff\n", color);
8268 if(caps.MaxPointSize >= 64.0) {
8269 color = getPixelColor(device, 256-33, 64-33);
8270 ok(color == 0x000000ff, "pSize: Pixel (256-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8271 color = getPixelColor(device, 256-32, 64-32);
8272 todo_wine ok(color == 0x00ffffff, "pSize: Pixel (256-32),(64-32) has color 0x%08x, expected 0x00ffffff\n", color);
8273 color = getPixelColor(device, 256-31, 64-31);
8274 ok(color == 0x00ffffff, "pSize: Pixel (256-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8275 color = getPixelColor(device, 256+31, 64+31);
8276 ok(color == 0x00ffffff, "pSize: Pixel (256+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8277 color = getPixelColor(device, 256+32, 64+32);
8278 ok(color == 0x000000ff, "pSize: Pixel (256+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8279 color = getPixelColor(device, 256+33, 64+33);
8280 ok(color == 0x000000ff, "pSize: Pixel (256+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8282 color = getPixelColor(device, 384-33, 64-33);
8283 ok(color == 0x000000ff, "pSize: Pixel (384-33),(64-33) has color 0x%08x, expected 0x000000ff\n", color);
8284 color = getPixelColor(device, 384-32, 64-32);
8285 ok(color == 0x000000ff, "pSize: Pixel (384-32),(64-32) has color 0x%08x, expected 0x000000ff\n", color);
8286 color = getPixelColor(device, 384-31, 64-31);
8287 ok(color == 0x00ffffff, "pSize: Pixel (384-31),(64-31) has color 0x%08x, expected 0x00ffffff\n", color);
8288 color = getPixelColor(device, 384+31, 64+31);
8289 ok(color == 0x00ffffff, "pSize: Pixel (384+31),(64+31) has color 0x%08x, expected 0x00ffffff\n", color);
8290 color = getPixelColor(device, 384+32, 64+32);
8291 ok(color == 0x000000ff, "pSize: Pixel (384+32),(64+32) has color 0x%08x, expected 0x000000ff\n", color);
8292 color = getPixelColor(device, 384+33, 64+33);
8293 ok(color == 0x000000ff, "pSize: Pixel (384+33),(64+33) has color 0x%08x, expected 0x000000ff\n", color);
8296 color = getPixelColor(device, 320-1, 64-1);
8297 ok(color == 0x000000ff, "pSize: Pixel (320-1),(64-1) has color 0x%08x, expected 0x000000ff\n", color);
8298 color = getPixelColor(device, 320-0, 64-0);
8299 ok(color == 0x00ffffff, "pSize: Pixel (320-0),(64-0) has color 0x%08x, expected 0x00ffffff\n", color);
8300 color = getPixelColor(device, 320+1, 64+1);
8301 ok(color == 0x000000ff, "pSize: Pixel (320+1),(64+1) has color 0x%08x, expected 0x000000ff\n", color);
8303 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize_orig)));
8304 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%s\n", DXGetErrorString9(hr));
8305 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
8306 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%s\n", DXGetErrorString9(hr));
8309 static void multiple_rendertargets_test(IDirect3DDevice9 *device)
8311 HRESULT hr;
8312 IDirect3DPixelShader9 *ps;
8313 IDirect3DTexture9 *tex1, *tex2;
8314 IDirect3DSurface9 *surf1, *surf2, *backbuf;
8315 D3DCAPS9 caps;
8316 DWORD color;
8317 DWORD shader_code[] = {
8318 0xffff0300, /* ps_3_0 */
8319 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0, 1, 0, 0 */
8320 0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0, 0, 1, 0 */
8321 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
8322 0x02000001, 0x800f0801, 0xa0e40001, /* mov oC1, c1 */
8323 0x0000ffff /* END */
8325 float quad[] = {
8326 -1.0, -1.0, 0.1,
8327 1.0, -1.0, 0.1,
8328 -1.0, 1.0, 0.1,
8329 1.0, 1.0, 0.1,
8331 float texquad[] = {
8332 -1.0, -1.0, 0.1, 0.0, 0.0,
8333 0.0, -1.0, 0.1, 1.0, 0.0,
8334 -1.0, 1.0, 0.1, 0.0, 1.0,
8335 0.0, 1.0, 0.1, 1.0, 1.0,
8337 0.0, -1.0, 0.1, 0.0, 0.0,
8338 1.0, -1.0, 0.1, 1.0, 0.0,
8339 0.0, 1.0, 0.1, 0.0, 1.0,
8340 1.0, 1.0, 0.1, 1.0, 1.0,
8343 memset(&caps, 0, sizeof(caps));
8344 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8345 ok(hr == D3D_OK, "IDirect3DDevice9_GetCaps failed, hr=%s\n", DXGetErrorString9(hr));
8346 if(caps.NumSimultaneousRTs < 2) {
8347 skip("Only 1 simultaneous render target supported, skipping MRT test\n");
8348 return;
8351 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0, 0);
8352 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%s\n", DXGetErrorString9(hr));
8354 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
8355 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%s\n", DXGetErrorString9(hr));
8356 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
8357 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%s\n", DXGetErrorString9(hr));
8358 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
8359 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed, hr=%s\n", DXGetErrorString9(hr));
8361 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
8362 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8363 hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
8364 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%s\n", DXGetErrorString9(hr));
8365 hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
8366 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%s\n", DXGetErrorString9(hr));
8368 hr = IDirect3DDevice9_SetPixelShader(device, ps);
8369 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%s\n", DXGetErrorString9(hr));
8370 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
8371 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8372 hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
8373 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8374 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
8375 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%s\n", DXGetErrorString9(hr));
8377 hr = IDirect3DDevice9_BeginScene(device);
8378 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr=%s\n", DXGetErrorString9(hr));
8379 if(SUCCEEDED(hr)) {
8380 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
8381 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8383 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
8384 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%s\n", DXGetErrorString9(hr));
8385 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
8386 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8387 hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
8388 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%s\n", DXGetErrorString9(hr));
8389 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8390 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%s\n", DXGetErrorString9(hr));
8392 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
8393 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%s\n", DXGetErrorString9(hr));
8394 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
8395 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8397 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
8398 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%s\n", DXGetErrorString9(hr));
8399 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
8400 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed, hr=%s\n", DXGetErrorString9(hr));
8402 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
8403 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed, hr=%s\n", DXGetErrorString9(hr));
8405 hr = IDirect3DDevice9_EndScene(device);
8406 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr=%s\n", DXGetErrorString9(hr));
8409 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8410 color = getPixelColor(device, 160, 240);
8411 ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
8412 color = getPixelColor(device, 480, 240);
8413 ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
8415 IDirect3DPixelShader9_Release(ps);
8416 IDirect3DTexture9_Release(tex1);
8417 IDirect3DTexture9_Release(tex2);
8418 IDirect3DSurface9_Release(surf1);
8419 IDirect3DSurface9_Release(surf2);
8420 IDirect3DSurface9_Release(backbuf);
8423 struct formats {
8424 const char *fmtName;
8425 D3DFORMAT textureFormat;
8426 DWORD resultColorBlending;
8427 DWORD resultColorNoBlending;
8430 const struct formats test_formats[] = {
8431 { "D3DFMT_G16R16", D3DFMT_G16R16, 0x00181800, 0x002010ff},
8432 { "D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff },
8433 { "D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff },
8434 { "D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000 },
8435 { "D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff },
8436 { "D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff },
8437 { "D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000 },
8438 { NULL, 0 }
8441 static void pixelshader_blending_test(IDirect3DDevice9 *device)
8443 HRESULT hr;
8444 IDirect3DTexture9 *offscreenTexture = NULL;
8445 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
8446 IDirect3D9 *d3d = NULL;
8447 DWORD color;
8448 DWORD r0, g0, b0, r1, g1, b1;
8449 int fmt_index;
8451 static const float quad[][5] = {
8452 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
8453 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
8454 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
8455 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
8458 /* Quad with R=0x10, G=0x20 */
8459 static const struct vertex quad1[] = {
8460 {-1.0f, -1.0f, 0.1f, 0x80102000},
8461 {-1.0f, 1.0f, 0.1f, 0x80102000},
8462 { 1.0f, -1.0f, 0.1f, 0x80102000},
8463 { 1.0f, 1.0f, 0.1f, 0x80102000},
8466 /* Quad with R=0x20, G=0x10 */
8467 static const struct vertex quad2[] = {
8468 {-1.0f, -1.0f, 0.1f, 0x80201000},
8469 {-1.0f, 1.0f, 0.1f, 0x80201000},
8470 { 1.0f, -1.0f, 0.1f, 0x80201000},
8471 { 1.0f, 1.0f, 0.1f, 0x80201000},
8474 IDirect3DDevice9_GetDirect3D(device, &d3d);
8476 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8477 ok(hr == D3D_OK, "Can't get back buffer, hr = %s\n", DXGetErrorString9(hr));
8478 if(!backbuffer) {
8479 goto out;
8482 for(fmt_index=0; test_formats[fmt_index].textureFormat != 0; fmt_index++)
8484 D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
8485 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, fmt) != D3D_OK) {
8486 skip("%s textures not supported\n", test_formats[fmt_index].fmtName);
8487 continue;
8490 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8491 ok(hr == D3D_OK, "Clear failed, hr = %s\n", DXGetErrorString9(hr));
8493 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
8494 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %s\n", DXGetErrorString9(hr));
8495 if(!offscreenTexture) {
8496 continue;
8499 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
8500 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %s\n", DXGetErrorString9(hr));
8501 if(!offscreen) {
8502 continue;
8505 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8506 ok(hr == D3D_OK, "SetFVF failed, hr = %s\n", DXGetErrorString9(hr));
8508 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8509 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8510 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8511 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8512 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
8513 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
8514 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
8515 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
8516 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8517 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
8519 /* Below we will draw two quads with different colors and try to blend them together.
8520 * The result color is compared with the expected outcome.
8522 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
8523 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
8524 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %s\n", DXGetErrorString9(hr));
8525 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
8526 ok(hr == D3D_OK, "Clear failed, hr = %s\n", DXGetErrorString9(hr));
8528 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
8529 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8531 /* Draw a quad using color 0x0010200 */
8532 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
8533 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8534 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
8535 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8536 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8537 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8539 /* Draw a quad using color 0x0020100 */
8540 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
8541 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8542 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
8543 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8544 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8545 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %#08x\n", hr);
8547 /* We don't want to blend the result on the backbuffer */
8548 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
8549 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8551 /* Prepare rendering the 'blended' texture quad to the backbuffer */
8552 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8553 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %s\n", DXGetErrorString9(hr));
8554 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
8555 ok(hr == D3D_OK, "SetTexture failed, %s\n", DXGetErrorString9(hr));
8557 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8558 ok(hr == D3D_OK, "SetFVF failed, hr = %s\n", DXGetErrorString9(hr));
8560 /* This time with the texture */
8561 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8562 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %s\n", DXGetErrorString9(hr));
8564 IDirect3DDevice9_EndScene(device);
8566 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8569 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK) {
8570 /* Compare the color of the center quad with our expectation */
8571 color = getPixelColor(device, 320, 240);
8572 r0 = (color & 0x00ff0000) >> 16;
8573 g0 = (color & 0x0000ff00) >> 8;
8574 b0 = (color & 0x000000ff) >> 0;
8576 r1 = (test_formats[fmt_index].resultColorBlending & 0x00ff0000) >> 16;
8577 g1 = (test_formats[fmt_index].resultColorBlending & 0x0000ff00) >> 8;
8578 b1 = (test_formats[fmt_index].resultColorBlending & 0x000000ff) >> 0;
8580 ok(r0 >= max(r1, 1) - 1 && r0 <= r1 + 1 &&
8581 g0 >= max(g1, 1) - 1 && g0 <= g1 + 1 &&
8582 b0 >= max(b1, 1) - 1 && b0 <= b1 + 1,
8583 "Offscreen failed for %s: Got color %#08x, expected %#08x.\n", test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
8584 } else {
8585 /* No pixel shader blending is supported so expected garbage.The type of 'garbage' depends on the driver version and OS.
8586 * E.g. on G16R16 ati reports (on old r9600 drivers) 0x00ffffff and on modern ones 0x002010ff which is also what Nvidia
8587 * reports. On Vista Nvidia seems to report 0x00ffffff on Geforce7 cards. */
8588 color = getPixelColor(device, 320, 240);
8589 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);
8592 IDirect3DDevice9_SetTexture(device, 0, NULL);
8593 if(offscreenTexture) {
8594 IDirect3DTexture9_Release(offscreenTexture);
8596 if(offscreen) {
8597 IDirect3DSurface9_Release(offscreen);
8601 out:
8602 /* restore things */
8603 if(backbuffer) {
8604 IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8605 IDirect3DSurface9_Release(backbuffer);
8609 static void tssargtemp_test(IDirect3DDevice9 *device)
8611 HRESULT hr;
8612 DWORD color;
8613 static const struct vertex quad[] = {
8614 {-1.0, -1.0, 0.1, 0x00ff0000},
8615 { 1.0, -1.0, 0.1, 0x00ff0000},
8616 {-1.0, 1.0, 0.1, 0x00ff0000},
8617 { 1.0, 1.0, 0.1, 0x00ff0000}
8619 D3DCAPS9 caps;
8621 memset(&caps, 0, sizeof(caps));
8622 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8623 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %s\n", DXGetErrorString9(hr));
8624 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
8625 skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
8626 return;
8629 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
8630 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
8632 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8633 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8634 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
8635 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8637 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8638 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8639 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
8640 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8641 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
8642 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8644 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
8645 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8646 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
8647 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8648 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
8649 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8651 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
8652 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8654 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
8655 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %s\n", DXGetErrorString9(hr));
8656 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8657 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %s\n", DXGetErrorString9(hr));
8659 hr = IDirect3DDevice9_BeginScene(device);
8660 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed, hr = %s\n", DXGetErrorString9(hr));
8661 if(SUCCEEDED(hr)) {
8663 hr = IDirect3DDevice9_EndScene(device);
8664 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed, hr = %s\n", DXGetErrorString9(hr));
8665 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8666 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
8668 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8669 color = getPixelColor(device, 320, 240);
8670 ok(color == 0x00FFFF00, "TSSARGTEMP test returned color 0x%08x, expected 0x00FFFF00\n", color);
8672 /* Set stage 1 back to default */
8673 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_CURRENT);
8674 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8675 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
8676 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8677 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
8678 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8679 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
8680 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8681 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
8682 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
8685 struct testdata
8687 DWORD idxVertex; /* number of instances in the first stream */
8688 DWORD idxColor; /* number of instances in the second stream */
8689 DWORD idxInstance; /* should be 1 ?? */
8690 DWORD color1; /* color 1 instance */
8691 DWORD color2; /* color 2 instance */
8692 DWORD color3; /* color 3 instance */
8693 DWORD color4; /* color 4 instance */
8694 WORD strVertex; /* specify which stream to use 0-2*/
8695 WORD strColor;
8696 WORD strInstance;
8699 static const struct testdata testcases[]=
8701 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 0 */
8702 {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 1 */
8703 {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 2 */
8704 {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 3 */
8705 {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 4 */
8706 {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 5 */
8707 {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 6 */
8708 {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 7 */
8709 {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 8 */
8710 {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 9 */
8711 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 10 */
8712 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 11 */
8713 {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 12 */
8714 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 13 */
8715 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 14 */
8717 This case is handled in a stand alone test, SetStreamSourceFreq(0,(D3DSTREAMSOURCE_INSTANCEDATA | 1)) has to return D3DERR_INVALIDCALL!
8718 {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0, D3DERR_INVALIDCALL},
8722 /* Drawing Indexed Geometry with instances*/
8723 static void stream_test(IDirect3DDevice9 *device)
8725 IDirect3DVertexBuffer9 *vb = NULL;
8726 IDirect3DVertexBuffer9 *vb2 = NULL;
8727 IDirect3DVertexBuffer9 *vb3 = NULL;
8728 IDirect3DIndexBuffer9 *ib = NULL;
8729 IDirect3DVertexDeclaration9 *pDecl = NULL;
8730 IDirect3DVertexShader9 *shader = NULL;
8731 HRESULT hr;
8732 BYTE *data;
8733 DWORD color;
8734 DWORD ind;
8735 int i;
8737 const DWORD shader_code[] =
8739 0xfffe0101, /* vs_1_1 */
8740 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8741 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
8742 0x0000001f, 0x80000005, 0x900f0002, /* dcl_texcoord v2 */
8743 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
8744 0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
8745 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
8746 0x0000ffff
8749 const float quad[][3] =
8751 {-0.5f, -0.5f, 1.1f}, /*0 */
8752 {-0.5f, 0.5f, 1.1f}, /*1 */
8753 { 0.5f, -0.5f, 1.1f}, /*2 */
8754 { 0.5f, 0.5f, 1.1f}, /*3 */
8757 const float vertcolor[][4] =
8759 {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
8760 {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
8761 {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
8762 {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
8765 /* 4 position for 4 instances */
8766 const float instancepos[][3] =
8768 {-0.6f,-0.6f, 0.0f},
8769 { 0.6f,-0.6f, 0.0f},
8770 { 0.6f, 0.6f, 0.0f},
8771 {-0.6f, 0.6f, 0.0f},
8774 short indices[] = {0, 1, 2, 1, 2, 3};
8776 D3DVERTEXELEMENT9 decl[] =
8778 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8779 {1, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8780 {2, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
8781 D3DDECL_END()
8784 /* set the default value because it isn't done in wine? */
8785 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
8786 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8788 /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
8789 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
8790 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8792 /* check wrong cases */
8793 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
8794 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8795 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8796 ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8797 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
8798 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8799 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8800 ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8801 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
8802 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8803 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8804 ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8805 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
8806 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8807 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8808 ok(hr == D3D_OK && ind == (0 | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8809 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
8810 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8811 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
8812 ok(hr == D3D_OK && ind == (0 | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8814 /* set the default value back */
8815 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
8816 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s\n", DXGetErrorString9(hr));
8818 /* create all VertexBuffers*/
8819 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
8820 ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
8821 if(!vb) {
8822 skip("Failed to create a vertex buffer\n");
8823 return;
8825 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
8826 ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
8827 if(!vb2) {
8828 skip("Failed to create a vertex buffer\n");
8829 goto out;
8831 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
8832 ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
8833 if(!vb3) {
8834 skip("Failed to create a vertex buffer\n");
8835 goto out;
8838 /* create IndexBuffer*/
8839 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
8840 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %s\n", DXGetErrorString9(hr));
8841 if(!ib) {
8842 skip("Failed to create a index buffer\n");
8843 goto out;
8846 /* copy all Buffers (Vertex + Index)*/
8847 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
8848 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
8849 memcpy(data, quad, sizeof(quad));
8850 hr = IDirect3DVertexBuffer9_Unlock(vb);
8851 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
8852 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
8853 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
8854 memcpy(data, vertcolor, sizeof(vertcolor));
8855 hr = IDirect3DVertexBuffer9_Unlock(vb2);
8856 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
8857 hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
8858 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
8859 memcpy(data, instancepos, sizeof(instancepos));
8860 hr = IDirect3DVertexBuffer9_Unlock(vb3);
8861 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
8862 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
8863 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
8864 memcpy(data, indices, sizeof(indices));
8865 hr = IDirect3DIndexBuffer9_Unlock(ib);
8866 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
8868 /* create VertexShader */
8869 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
8870 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%s\n", DXGetErrorString9(hr));
8871 if(!shader) {
8872 skip("Failed to create a vetex shader\n");
8873 goto out;
8876 hr = IDirect3DDevice9_SetVertexShader(device, shader);
8877 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%s\n", DXGetErrorString9(hr));
8879 hr = IDirect3DDevice9_SetIndices(device, ib);
8880 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
8882 /* run all tests */
8883 for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
8885 struct testdata act = testcases[i];
8886 decl[0].Stream = act.strVertex;
8887 decl[1].Stream = act.strColor;
8888 decl[2].Stream = act.strInstance;
8889 /* create VertexDeclarations */
8890 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
8891 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%s (case %i)\n", DXGetErrorString9(hr), i);
8893 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
8894 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
8896 hr = IDirect3DDevice9_BeginScene(device);
8897 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x (case %i)\n", hr, i);
8898 if(SUCCEEDED(hr))
8900 hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
8901 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x (case %i)\n", hr, i);
8903 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
8904 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8905 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
8906 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8908 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor, (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
8909 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8910 hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
8911 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8913 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance, (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
8914 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8915 hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
8916 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8918 /* don't know if this is right (1*3 and 4*1)*/
8919 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 1 * 3 , 0, 4*1);
8920 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x (case %i)\n", hr, i);
8921 hr = IDirect3DDevice9_EndScene(device);
8922 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x (case %i)\n", hr, i);
8924 /* set all StreamSource && StreamSourceFreq back to default */
8925 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
8926 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8927 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
8928 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
8929 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
8930 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8931 hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
8932 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
8933 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
8934 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %s (case %i)\n", DXGetErrorString9(hr), i);
8935 hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
8936 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x (case %i)\n", hr, i);
8939 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8940 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
8942 hr = IDirect3DVertexDeclaration9_Release(pDecl);
8943 ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
8945 color = getPixelColor(device, 160, 360);
8946 ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
8947 color = getPixelColor(device, 480, 360);
8948 ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
8949 color = getPixelColor(device, 480, 120);
8950 ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
8951 color = getPixelColor(device, 160, 120);
8952 ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
8955 hr = IDirect3DDevice9_SetIndices(device, NULL);
8956 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
8958 out:
8959 if(vb) IDirect3DVertexBuffer9_Release(vb);
8960 if(vb2)IDirect3DVertexBuffer9_Release(vb2);
8961 if(vb3)IDirect3DVertexBuffer9_Release(vb3);
8962 if(ib)IDirect3DIndexBuffer9_Release(ib);
8963 if(shader)IDirect3DVertexShader9_Release(shader);
8966 static void np2_stretch_rect_test(IDirect3DDevice9 *device) {
8967 IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
8968 IDirect3DTexture9 *dsttex = NULL;
8969 HRESULT hr;
8970 DWORD color;
8971 D3DRECT r1 = {0, 0, 50, 50 };
8972 D3DRECT r2 = {50, 0, 100, 50 };
8973 D3DRECT r3 = {50, 50, 100, 100};
8974 D3DRECT r4 = {0, 50, 50, 100};
8975 const float quad[] = {
8976 -1.0, -1.0, 0.1, 0.0, 0.0,
8977 1.0, -1.0, 0.1, 1.0, 0.0,
8978 -1.0, 1.0, 0.1, 0.0, 1.0,
8979 1.0, 1.0, 0.1, 1.0, 1.0,
8982 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8983 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %s\n", DXGetErrorString9(hr));
8985 hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
8986 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %s\n", DXGetErrorString9(hr));
8987 hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
8988 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
8990 if(!src || !dsttex) {
8991 skip("One or more test resources could not be created\n");
8992 goto cleanup;
8995 hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
8996 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %s\n", DXGetErrorString9(hr));
8998 hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
8999 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
9001 /* Clear the StretchRect destination for debugging */
9002 hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
9003 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %s\n", DXGetErrorString9(hr));
9004 hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
9005 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
9007 hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
9008 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %s\n", DXGetErrorString9(hr));
9010 hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9011 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
9012 hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
9013 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
9014 hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9015 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
9016 hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
9017 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
9019 /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
9020 * the target -> texture GL blit path
9022 hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
9023 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %s\n", DXGetErrorString9(hr));
9024 IDirect3DSurface9_Release(dst);
9026 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9027 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %s\n", DXGetErrorString9(hr));
9029 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
9030 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
9031 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9032 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
9033 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9034 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
9035 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9036 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
9038 hr = IDirect3DDevice9_BeginScene(device);
9039 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
9040 if(SUCCEEDED(hr)) {
9041 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9042 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
9043 hr = IDirect3DDevice9_EndScene(device);
9044 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
9047 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9048 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
9049 color = getPixelColor(device, 160, 360);
9050 ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
9051 color = getPixelColor(device, 480, 360);
9052 ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
9053 color = getPixelColor(device, 480, 120);
9054 ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
9055 color = getPixelColor(device, 160, 120);
9056 ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
9058 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
9059 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
9060 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
9061 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
9063 cleanup:
9064 if(src) IDirect3DSurface9_Release(src);
9065 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
9066 if(dsttex) IDirect3DTexture9_Release(dsttex);
9069 START_TEST(visual)
9071 IDirect3DDevice9 *device_ptr;
9072 D3DCAPS9 caps;
9073 HRESULT hr;
9074 DWORD color;
9076 d3d9_handle = LoadLibraryA("d3d9.dll");
9077 if (!d3d9_handle)
9079 skip("Could not load d3d9.dll\n");
9080 return;
9083 device_ptr = init_d3d9();
9084 if (!device_ptr)
9086 skip("Creating the device failed\n");
9087 return;
9090 IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
9092 /* Check for the reliability of the returned data */
9093 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
9094 if(FAILED(hr))
9096 trace("Clear failed, can't assure correctness of the test results, skipping\n");
9097 goto cleanup;
9099 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
9101 color = getPixelColor(device_ptr, 1, 1);
9102 if(color !=0x00ff0000)
9104 trace("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
9105 goto cleanup;
9108 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
9109 if(FAILED(hr))
9111 trace("Clear failed, can't assure correctness of the test results, skipping\n");
9112 goto cleanup;
9114 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
9116 color = getPixelColor(device_ptr, 639, 479);
9117 if(color != 0x0000ddee)
9119 trace("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
9120 goto cleanup;
9123 /* Now execute the real tests */
9124 stretchrect_test(device_ptr);
9125 lighting_test(device_ptr);
9126 clear_test(device_ptr);
9127 fog_test(device_ptr);
9128 if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
9130 test_cube_wrap(device_ptr);
9131 } else {
9132 skip("No cube texture support\n");
9134 z_range_test(device_ptr);
9135 if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
9137 maxmip_test(device_ptr);
9139 else
9141 skip("No mipmap support\n");
9143 offscreen_test(device_ptr);
9144 alpha_test(device_ptr);
9145 shademode_test(device_ptr);
9146 srgbtexture_test(device_ptr);
9147 release_buffer_test(device_ptr);
9148 float_texture_test(device_ptr);
9149 g16r16_texture_test(device_ptr);
9150 pixelshader_blending_test(device_ptr);
9151 texture_transform_flags_test(device_ptr);
9152 autogen_mipmap_test(device_ptr);
9153 fixed_function_decl_test(device_ptr);
9154 conditional_np2_repeat_test(device_ptr);
9155 fixed_function_bumpmap_test(device_ptr);
9156 if(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) {
9157 stencil_cull_test(device_ptr);
9158 } else {
9159 skip("No two sided stencil support\n");
9161 pointsize_test(device_ptr);
9162 tssargtemp_test(device_ptr);
9163 np2_stretch_rect_test(device_ptr);
9165 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
9167 test_constant_clamp_vs(device_ptr);
9168 test_compare_instructions(device_ptr);
9170 else skip("No vs_1_1 support\n");
9172 if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
9174 test_mova(device_ptr);
9175 if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
9176 test_vshader_input(device_ptr);
9177 test_vshader_float16(device_ptr);
9178 stream_test(device_ptr);
9179 } else {
9180 skip("No vs_3_0 support\n");
9183 else skip("No vs_2_0 support\n");
9185 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
9187 fog_with_shader_test(device_ptr);
9188 fog_srgbwrite_test(device_ptr);
9190 else skip("No vs_1_1 and ps_1_1 support\n");
9192 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
9194 texbem_test(device_ptr);
9195 texdepth_test(device_ptr);
9196 texkill_test(device_ptr);
9197 x8l8v8u8_test(device_ptr);
9198 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) {
9199 constant_clamp_ps_test(device_ptr);
9200 cnd_test(device_ptr);
9201 if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) {
9202 dp2add_ps_test(device_ptr);
9203 if (caps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) {
9204 nested_loop_test(device_ptr);
9205 fixed_function_varying_test(device_ptr);
9206 vFace_register_test(device_ptr);
9207 vpos_register_test(device_ptr);
9208 multiple_rendertargets_test(device_ptr);
9209 if(caps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) {
9210 vshader_version_varying_test(device_ptr);
9211 pshader_version_varying_test(device_ptr);
9212 } else {
9213 skip("No vs_3_0 support\n");
9215 } else {
9216 skip("No ps_3_0 support\n");
9218 } else {
9219 skip("No ps_2_0 support\n");
9223 else skip("No ps_1_1 support\n");
9225 cleanup:
9226 if(device_ptr) {
9227 ULONG ref;
9229 D3DPRESENT_PARAMETERS present_parameters;
9230 IDirect3DSwapChain9 *swapchain;
9231 IDirect3DDevice9_GetSwapChain(device_ptr, 0, &swapchain);
9232 IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
9233 IDirect3DSwapChain9_Release(swapchain);
9234 ref = IDirect3DDevice9_Release(device_ptr);
9235 DestroyWindow(present_parameters.hDeviceWindow);
9236 ok(ref == 0, "The device was not properly freed: refcount %u\n", ref);