wined3d: Fix texdepth instruction.
[wine.git] / dlls / d3d9 / tests / visual.c
blob21f380963a976492fc0fd66c138db6fe27e72dda
1 /*
2 * Copyright 2005, 2007 Henri Verbeet
3 * Copyright (C) 2007 Stefan Dösinger(for CodeWeavers)
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 /* This test framework allows limited testing of rendering results. Things are rendered, shown on
21 * the framebuffer, read back from there and compared to expected colors.
23 * However, neither d3d nor opengl is guaranteed to be pixel exact, and thus the capability of this test
24 * is rather limited. As a general guideline for adding tests, do not rely on corner pixels. Draw a big enough
25 * area which shows specific behavior(like a quad on the whole screen), and try to get resulting colos with
26 * all bits set or unset in all channels(like pure red, green, blue, white, black). Hopefully everything that
27 * causes visible results in games can be tested in a way that does not depend on pixel exactness
30 #define COBJMACROS
31 #include <d3d9.h>
32 #include <dxerr9.h>
33 #include "wine/test.h"
35 static HMODULE d3d9_handle = 0;
37 static HWND create_window(void)
39 WNDCLASS wc = {0};
40 HWND ret;
41 wc.lpfnWndProc = &DefWindowProc;
42 wc.lpszClassName = "d3d9_test_wc";
43 RegisterClass(&wc);
45 ret = CreateWindow("d3d9_test_wc", "d3d9_test",
46 WS_MAXIMIZE | WS_VISIBLE | WS_CAPTION , 0, 0, 640, 480, 0, 0, 0, 0);
47 return ret;
50 static DWORD getPixelColor(IDirect3DDevice9 *device, UINT x, UINT y)
52 DWORD ret;
53 IDirect3DSurface9 *surf;
54 HRESULT hr;
55 D3DLOCKED_RECT lockedRect;
56 RECT rectToLock = {x, y, x+1, y+1};
58 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 640, 480, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf, NULL);
59 if(FAILED(hr) || !surf ) /* This is not a test */
61 trace("Can't create an offscreen plain surface to read the render target data, hr=%s\n", DXGetErrorString9(hr));
62 return 0xdeadbeef;
65 hr = IDirect3DDevice9_GetFrontBufferData(device, 0, surf);
66 if(FAILED(hr))
68 trace("Can't read the front buffer data, hr=%s\n", DXGetErrorString9(hr));
69 ret = 0xdeadbeed;
70 goto out;
73 hr = IDirect3DSurface9_LockRect(surf, &lockedRect, &rectToLock, D3DLOCK_READONLY);
74 if(FAILED(hr))
76 trace("Can't lock the offscreen surface, hr=%s\n", DXGetErrorString9(hr));
77 ret = 0xdeadbeec;
78 goto out;
81 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
82 * really important for these tests
84 ret = ((DWORD *) lockedRect.pBits)[0] & 0x00ffffff;
85 hr = IDirect3DSurface9_UnlockRect(surf);
86 if(FAILED(hr))
88 trace("Can't unlock the offscreen surface, hr=%s\n", DXGetErrorString9(hr));
91 out:
92 if(surf) IDirect3DSurface9_Release(surf);
93 return ret;
96 static IDirect3DDevice9 *init_d3d9(void)
98 IDirect3D9 * (__stdcall * d3d9_create)(UINT SDKVersion) = 0;
99 IDirect3D9 *d3d9_ptr = 0;
100 IDirect3DDevice9 *device_ptr = 0;
101 D3DPRESENT_PARAMETERS present_parameters;
102 HRESULT hr;
104 d3d9_create = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9");
105 ok(d3d9_create != NULL, "Failed to get address of Direct3DCreate9\n");
106 if (!d3d9_create) return NULL;
108 d3d9_ptr = d3d9_create(D3D_SDK_VERSION);
109 ok(d3d9_ptr != NULL, "Failed to create IDirect3D9 object\n");
110 if (!d3d9_ptr) return NULL;
112 ZeroMemory(&present_parameters, sizeof(present_parameters));
113 present_parameters.Windowed = FALSE;
114 present_parameters.hDeviceWindow = create_window();
115 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
116 present_parameters.BackBufferWidth = 640;
117 present_parameters.BackBufferHeight = 480;
118 present_parameters.BackBufferFormat = D3DFMT_X8R8G8B8;
119 present_parameters.EnableAutoDepthStencil = TRUE;
120 present_parameters.AutoDepthStencilFormat = D3DFMT_D16;
122 hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
123 ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "IDirect3D_CreateDevice returned: %s\n", DXGetErrorString9(hr));
125 return device_ptr;
128 struct vertex
130 float x, y, z;
131 DWORD diffuse;
134 struct tvertex
136 float x, y, z, rhw;
137 DWORD diffuse;
140 struct nvertex
142 float x, y, z;
143 float nx, ny, nz;
144 DWORD diffuse;
147 static void lighting_test(IDirect3DDevice9 *device)
149 HRESULT hr;
150 DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
151 DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
152 DWORD color;
154 float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
155 0.0f, 1.0f, 0.0f, 0.0f,
156 0.0f, 0.0f, 1.0f, 0.0f,
157 0.0f, 0.0f, 0.0f, 1.0f };
159 struct vertex unlitquad[] =
161 {-1.0f, -1.0f, 0.1f, 0xffff0000},
162 {-1.0f, 0.0f, 0.1f, 0xffff0000},
163 { 0.0f, 0.0f, 0.1f, 0xffff0000},
164 { 0.0f, -1.0f, 0.1f, 0xffff0000},
166 struct vertex litquad[] =
168 {-1.0f, 0.0f, 0.1f, 0xff00ff00},
169 {-1.0f, 1.0f, 0.1f, 0xff00ff00},
170 { 0.0f, 1.0f, 0.1f, 0xff00ff00},
171 { 0.0f, 0.0f, 0.1f, 0xff00ff00},
173 struct nvertex unlitnquad[] =
175 { 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
176 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
177 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
178 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
180 struct nvertex litnquad[] =
182 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
183 { 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
184 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
185 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
187 WORD Indices[] = {0, 1, 2, 2, 3, 0};
189 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
190 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
192 /* Setup some states that may cause issues */
193 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
194 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %s\n", DXGetErrorString9(hr));
195 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
196 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %s\n", DXGetErrorString9(hr));
197 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
198 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %s\n", DXGetErrorString9(hr));
199 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
200 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
201 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
202 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
203 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
204 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
205 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
206 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
207 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
208 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
209 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
210 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
211 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
212 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
213 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
214 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %s\n", DXGetErrorString9(hr));
215 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
216 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %s\n", DXGetErrorString9(hr));
218 hr = IDirect3DDevice9_SetFVF(device, fvf);
219 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
221 hr = IDirect3DDevice9_BeginScene(device);
222 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
223 if(hr == D3D_OK)
225 /* No lights are defined... That means, lit vertices should be entirely black */
226 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
227 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
228 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
229 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
230 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
232 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
233 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
234 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
235 2 /*PrimCount */, Indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
236 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
238 hr = IDirect3DDevice9_SetFVF(device, nfvf);
239 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
241 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
242 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
243 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
244 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
245 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
247 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
248 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
249 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
250 2 /*PrimCount */, Indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
251 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
253 IDirect3DDevice9_EndScene(device);
254 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
257 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
259 color = getPixelColor(device, 160, 360); /* lower left quad - unlit without normals */
260 ok(color == 0x00ff0000, "Unlit quad without normals has color %08x\n", color);
261 color = getPixelColor(device, 160, 120); /* upper left quad - lit without normals */
262 ok(color == 0x00000000, "Lit quad without normals has color %08x\n", color);
263 color = getPixelColor(device, 480, 360); /* lower left quad - unlit width normals */
264 ok(color == 0x000000ff, "Unlit quad width normals has color %08x\n", color);
265 color = getPixelColor(device, 480, 120); /* upper left quad - lit width normals */
266 ok(color == 0x00000000, "Lit quad width normals has color %08x\n", color);
268 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
269 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
272 static void clear_test(IDirect3DDevice9 *device)
274 /* Tests the correctness of clearing parameters */
275 HRESULT hr;
276 D3DRECT rect[2];
277 D3DRECT rect_negneg;
278 DWORD color;
280 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
281 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
283 /* Positive x, negative y */
284 rect[0].x1 = 0;
285 rect[0].y1 = 480;
286 rect[0].x2 = 320;
287 rect[0].y2 = 240;
289 /* Positive x, positive y */
290 rect[1].x1 = 0;
291 rect[1].y1 = 0;
292 rect[1].x2 = 320;
293 rect[1].y2 = 240;
294 /* Clear 2 rectangles with one call. Shows that a positive value is returned, but the negative rectangle
295 * is ignored, the positive is still cleared afterwards
297 hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
298 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
300 /* negative x, negative y */
301 rect_negneg.x1 = 640;
302 rect_negneg.x1 = 240;
303 rect_negneg.x2 = 320;
304 rect_negneg.y2 = 0;
305 hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
306 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
308 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
310 color = getPixelColor(device, 160, 360); /* lower left quad */
311 ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
312 color = getPixelColor(device, 160, 120); /* upper left quad */
313 ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
314 color = getPixelColor(device, 480, 360); /* lower right quad */
315 ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
316 color = getPixelColor(device, 480, 120); /* upper right quad */
317 ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
320 typedef struct {
321 float in[4];
322 DWORD out;
323 } test_data_t;
326 * c7 rounded ARGB
327 * -2.4 -2 0x00ffff00
328 * -1.6 -2 0x00ffff00
329 * -0.4 0 0x0000ffff
330 * 0.4 0 0x0000ffff
331 * 1.6 2 0x00ff00ff
332 * 2.4 2 0x00ff00ff
334 static void test_mova(IDirect3DDevice9 *device)
336 static const DWORD mova_test[] = {
337 0xfffe0200, /* vs_2_0 */
338 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
339 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
340 0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
341 0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
342 0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
343 0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
344 0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
345 0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
346 0x0200002e, 0xb0010000, 0xa0000007, /* mova a0.x, c7.x */
347 0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000, /* mov oD0, c[a0.x + 3] */
348 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
349 0x0000ffff /* END */
352 static const test_data_t test_data[] = {
353 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
354 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
355 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
356 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
357 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
358 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
361 static const float quad[][3] = {
362 {-1.0f, -1.0f, 0.0f},
363 {-1.0f, 1.0f, 0.0f},
364 { 1.0f, -1.0f, 0.0f},
365 { 1.0f, 1.0f, 0.0f},
368 static const D3DVERTEXELEMENT9 decl_elements[] = {
369 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
370 D3DDECL_END()
373 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
374 IDirect3DVertexShader9 *mova_shader = NULL;
375 HRESULT hr;
376 int i;
378 hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
379 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
380 hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
381 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
383 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
384 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
385 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
386 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
388 for (i = 0; i < (sizeof(test_data) / sizeof(test_data_t)); ++i)
390 DWORD color;
392 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[i].in, 1);
393 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
395 hr = IDirect3DDevice9_BeginScene(device);
396 ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
398 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
399 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
401 hr = IDirect3DDevice9_EndScene(device);
402 ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
404 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
405 ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
407 color = getPixelColor(device, 320, 240);
408 ok(color == test_data[i].out, "Expected color %08x, got %08x (for input %f)\n", test_data[i].out, color, test_data[i].in[0]);
410 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
411 ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
414 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
415 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
417 IDirect3DVertexDeclaration9_Release(vertex_declaration);
418 IDirect3DVertexShader9_Release(mova_shader);
421 struct sVertex {
422 float x, y, z;
423 DWORD diffuse;
424 DWORD specular;
427 struct sVertexT {
428 float x, y, z, rhw;
429 DWORD diffuse;
430 DWORD specular;
433 static void fog_test(IDirect3DDevice9 *device)
435 HRESULT hr;
436 DWORD color;
437 float start = 0.0f, end = 1.0f;
438 D3DCAPS9 caps;
440 /* Gets full z based fog with linear fog, no fog with specular color */
441 struct sVertex unstransformed_1[] = {
442 {-1, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
443 {-1, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
444 { 0, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
445 { 0, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
447 /* Ok, I am too lazy to deal with transform matrices */
448 struct sVertex unstransformed_2[] = {
449 {-1, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
450 {-1, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
451 { 0, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
452 { 0, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
454 /* Untransformed ones. Give them a different diffuse color to make the test look
455 * nicer. It also makes making sure that they are drawn correctly easier.
457 struct sVertexT transformed_1[] = {
458 {320, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
459 {640, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
460 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
461 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
463 struct sVertexT transformed_2[] = {
464 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
465 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
466 {640, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
467 {320, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
469 WORD Indices[] = {0, 1, 2, 2, 3, 0};
471 memset(&caps, 0, sizeof(caps));
472 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
473 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %s\n", DXGetErrorString9(hr));
474 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
475 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
477 /* Setup initial states: No lighting, fog on, fog color */
478 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
479 ok(hr == D3D_OK, "Turning off lighting returned %s\n", DXGetErrorString9(hr));
480 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
481 ok(hr == D3D_OK, "Turning on fog calculations returned %s\n", DXGetErrorString9(hr));
482 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
483 ok(hr == D3D_OK, "Turning on fog calculations returned %s\n", DXGetErrorString9(hr));
485 /* First test: Both table fog and vertex fog off */
486 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
487 ok(hr == D3D_OK, "Turning off table fog returned %s\n", DXGetErrorString9(hr));
488 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
489 ok(hr == D3D_OK, "Turning off table fog returned %s\n", DXGetErrorString9(hr));
491 /* Start = 0, end = 1. Should be default, but set them */
492 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
493 ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
494 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
495 ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
497 if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
499 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
500 ok( hr == D3D_OK, "SetFVF returned %s\n", DXGetErrorString9(hr));
501 /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
502 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
503 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
504 sizeof(unstransformed_1[0]));
505 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
507 /* That makes it use the Z value */
508 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
509 ok(hr == D3D_OK, "Turning off table fog returned %s\n", DXGetErrorString9(hr));
510 /* Untransformed, vertex fog != none (or table fog != none):
511 * Use the Z value as input into the equation
513 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
514 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
515 sizeof(unstransformed_1[0]));
516 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
518 /* transformed verts */
519 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
520 ok( hr == D3D_OK, "SetFVF returned %s\n", DXGetErrorString9(hr));
521 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
522 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
523 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
524 sizeof(transformed_1[0]));
525 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
527 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
528 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %s\n", DXGetErrorString9(hr));
529 /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
530 * equation
532 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
533 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
534 sizeof(transformed_2[0]));
536 hr = IDirect3DDevice9_EndScene(device);
537 ok(hr == D3D_OK, "EndScene returned %s\n", DXGetErrorString9(hr));
539 else
541 ok(FALSE, "BeginScene failed\n");
544 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
545 color = getPixelColor(device, 160, 360);
546 ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
547 color = getPixelColor(device, 160, 120);
548 ok(color == 0x0000FF00, "Untransformed vertex with linear vertex fog has color %08x\n", color);
549 color = getPixelColor(device, 480, 120);
550 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
551 if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
553 color = getPixelColor(device, 480, 360);
554 ok(color == 0x0000FF00, "Transformed vertex with linear table fog has color %08x\n", color);
556 else
558 /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
559 * The settings above result in no fogging with vertex fog
561 color = getPixelColor(device, 480, 120);
562 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
563 trace("Info: Table fog not supported by this device\n");
566 /* Now test the special case fogstart == fogend */
567 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
568 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
570 if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
572 start = 512;
573 end = 512;
574 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
575 ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
576 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
577 ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
579 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
580 ok( hr == D3D_OK, "SetFVF returned %s\n", DXGetErrorString9(hr));
581 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
582 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %s\n", DXGetErrorString9(hr));
583 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
584 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %s\n", DXGetErrorString9(hr));
586 /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
587 * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
588 * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
589 * The third transformed quad remains unfogged because the fogcoords are read from the specular
590 * color and has fixed fogstart and fogend.
592 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
593 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
594 sizeof(unstransformed_1[0]));
595 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
596 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
597 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
598 sizeof(unstransformed_1[0]));
599 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
601 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
602 ok( hr == D3D_OK, "SetFVF returned %s\n", DXGetErrorString9(hr));
603 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
604 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
605 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
606 sizeof(transformed_1[0]));
607 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
609 hr = IDirect3DDevice9_EndScene(device);
610 ok(hr == D3D_OK, "EndScene returned %s\n", DXGetErrorString9(hr));
612 else
614 ok(FALSE, "BeginScene failed\n");
616 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
617 color = getPixelColor(device, 160, 360);
618 ok(color == 0x0000FF00, "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
619 color = getPixelColor(device, 160, 120);
620 ok(color == 0x0000FF00, "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
621 color = getPixelColor(device, 480, 120);
622 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
624 /* Turn off the fog master switch to avoid confusing other tests */
625 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
626 ok(hr == D3D_OK, "Turning off fog calculations returned %s\n", DXGetErrorString9(hr));
627 start = 0.0;
628 end = 1.0;
629 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
630 ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
631 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
632 ok(hr == D3D_OK, "Setting fog end returned %s\n", DXGetErrorString9(hr));
633 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
634 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %s\n", DXGetErrorString9(hr));
635 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
636 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %s\n", DXGetErrorString9(hr));
639 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
640 * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
641 * regardless of the actual addressing mode set. */
642 static void test_cube_wrap(IDirect3DDevice9 *device)
644 static const float quad[][6] = {
645 {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
646 {-1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
647 { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
648 { 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
651 static const D3DVERTEXELEMENT9 decl_elements[] = {
652 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
653 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
654 D3DDECL_END()
657 static const struct {
658 D3DTEXTUREADDRESS mode;
659 const char *name;
660 } address_modes[] = {
661 {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
662 {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
663 {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
664 {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
665 {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
668 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
669 IDirect3DCubeTexture9 *texture = NULL;
670 IDirect3DSurface9 *surface = NULL;
671 D3DLOCKED_RECT locked_rect;
672 HRESULT hr;
673 INT x, y, face;
675 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
676 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
677 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
678 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
680 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
681 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
682 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
684 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, D3DLOCK_DISCARD);
685 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
687 for (y = 0; y < 128; ++y)
689 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
690 for (x = 0; x < 64; ++x)
692 *ptr++ = 0xffff0000;
694 for (x = 64; x < 128; ++x)
696 *ptr++ = 0xff0000ff;
700 hr = IDirect3DSurface9_UnlockRect(surface);
701 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
703 hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
704 D3DPOOL_DEFAULT, &texture, NULL);
705 ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
707 /* Create cube faces */
708 for (face = 0; face < 6; ++face)
710 IDirect3DSurface9 *face_surface = NULL;
712 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
713 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
715 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
716 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
718 IDirect3DSurface9_Release(face_surface);
721 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
722 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
724 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
725 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
726 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
727 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
728 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
729 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
731 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
732 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
734 for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
736 DWORD color;
738 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
739 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
740 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
741 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
743 hr = IDirect3DDevice9_BeginScene(device);
744 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
746 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
747 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
749 hr = IDirect3DDevice9_EndScene(device);
750 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
752 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
753 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
755 /* Due to the nature of this test, we sample essentially at the edge
756 * between two faces. Because of this it's undefined from which face
757 * the driver will sample. Furtunately that's not important for this
758 * test, since all we care about is that it doesn't sample from the
759 * other side of the surface or from the border. */
760 color = getPixelColor(device, 320, 240);
761 ok(color == 0x00ff0000 || color == 0x000000ff,
762 "Got color 0x%08x for addressing mode %s, expected 0x00ff0000 or 0x000000ff.\n",
763 color, address_modes[x].name);
765 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
766 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
769 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
770 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
772 IDirect3DVertexDeclaration9_Release(vertex_declaration);
773 IDirect3DCubeTexture9_Release(texture);
774 IDirect3DSurface9_Release(surface);
777 static void offscreen_test(IDirect3DDevice9 *device)
779 HRESULT hr;
780 IDirect3DTexture9 *offscreenTexture = NULL;
781 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
782 DWORD color;
784 static const float quad[][5] = {
785 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
786 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
787 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
788 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
791 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
792 ok(hr == D3D_OK, "Clear failed, hr = %s\n", DXGetErrorString9(hr));
794 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
795 ok(hr == D3D_OK || D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %s\n", DXGetErrorString9(hr));
796 if(!offscreenTexture) {
797 trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
798 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
799 ok(hr == D3D_OK || D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %s\n", DXGetErrorString9(hr));
800 if(!offscreenTexture) {
801 skip("Cannot create an offscreen render target\n");
802 goto out;
806 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
807 ok(hr == D3D_OK, "Can't get back buffer, hr = %s\n", DXGetErrorString9(hr));
808 if(!backbuffer) {
809 goto out;
812 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
813 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %s\n", DXGetErrorString9(hr));
814 if(!offscreen) {
815 goto out;
818 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
819 ok(hr == D3D_OK, "SetFVF failed, hr = %s\n", DXGetErrorString9(hr));
821 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
822 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
823 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
824 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
825 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_NONE);
826 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
827 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_NONE);
828 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
829 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
830 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
832 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
833 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
834 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %s\n", DXGetErrorString9(hr));
835 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
836 ok(hr == D3D_OK, "Clear failed, hr = %s\n", DXGetErrorString9(hr));
838 /* Draw without textures - Should resut in a white quad */
839 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
840 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %s\n", DXGetErrorString9(hr));
842 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
843 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %s\n", DXGetErrorString9(hr));
844 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
845 ok(hr == D3D_OK, "SetTexture failed, %s\n", DXGetErrorString9(hr));
847 /* This time with the texture */
848 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
849 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %s\n", DXGetErrorString9(hr));
851 IDirect3DDevice9_EndScene(device);
854 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
856 /* Center quad - should be white */
857 color = getPixelColor(device, 320, 240);
858 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
859 /* Some quad in the cleared part of the texture */
860 color = getPixelColor(device, 170, 240);
861 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
862 /* Part of the originally cleared back buffer */
863 color = getPixelColor(device, 10, 10);
864 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
865 if(0) {
866 /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
867 * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
868 * the offscreen rendering mode this test would succeed or fail
870 color = getPixelColor(device, 10, 470);
871 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
874 out:
875 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
877 /* restore things */
878 if(backbuffer) {
879 IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
880 IDirect3DSurface9_Release(backbuffer);
882 if(offscreenTexture) {
883 IDirect3DTexture9_Release(offscreenTexture);
885 if(offscreen) {
886 IDirect3DSurface9_Release(offscreen);
890 /* This test tests fog in combination with shaders.
891 * What's tested: linear fog (vertex and table) with pixel shader
892 * linear table fog with non foggy vertex shader
893 * vertex fog with foggy vertex shader
894 * What's not tested: non linear fog with shader
895 * table fog with foggy vertex shader
897 static void fog_with_shader_test(IDirect3DDevice9 *device)
899 HRESULT hr;
900 DWORD color;
901 union {
902 float f;
903 DWORD i;
904 } start, end;
905 unsigned int i, j;
907 /* basic vertex shader without fog computation ("non foggy") */
908 static const DWORD vertex_shader_code1[] = {
909 0xfffe0101, /* vs_1_1 */
910 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
911 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
912 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
913 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
914 0x0000ffff
916 /* basic vertex shader with reversed fog computation ("foggy") */
917 static const DWORD vertex_shader_code2[] = {
918 0xfffe0101, /* vs_1_1 */
919 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
920 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
921 0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
922 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
923 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
924 0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
925 0x00000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
926 0x0000ffff
928 /* basic pixel shader */
929 static const DWORD pixel_shader_code[] = {
930 0xffff0101, /* ps_1_1 */
931 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, vo */
932 0x0000ffff
935 static struct vertex quad[] = {
936 {-1.0f, -1.0f, 0.0f, 0xFFFF0000 },
937 {-1.0f, 1.0f, 0.0f, 0xFFFF0000 },
938 { 1.0f, -1.0f, 0.0f, 0xFFFF0000 },
939 { 1.0f, 1.0f, 0.0f, 0xFFFF0000 },
942 static const D3DVERTEXELEMENT9 decl_elements[] = {
943 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
944 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
945 D3DDECL_END()
948 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
949 IDirect3DVertexShader9 *vertex_shader[3] = {NULL, NULL, NULL};
950 IDirect3DPixelShader9 *pixel_shader[2] = {NULL, NULL};
952 /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
953 static const struct test_data_t {
954 int vshader;
955 int pshader;
956 D3DFOGMODE vfog;
957 D3DFOGMODE tfog;
958 unsigned int color[11];
959 } test_data[] = {
960 /* only pixel shader: */
961 {0, 1, 0, 3,
962 {0x0000ff00, 0x0000ff00, 0x0020df00, 0x0040bf00, 0x005fa000, 0x007f8000,
963 0x009f6000, 0x00bf4000, 0x00df2000, 0x00ff0000, 0x00ff0000}},
964 {0, 1, 1, 3,
965 {0x0000ff00, 0x0000ff00, 0x0020df00, 0x0040bf00, 0x005fa000, 0x007f8000,
966 0x009f6000, 0x00bf4000, 0x00df2000, 0x00ff0000, 0x00ff0000}},
967 {0, 1, 2, 3,
968 {0x0000ff00, 0x0000ff00, 0x0020df00, 0x0040bf00, 0x005fa000, 0x007f8000,
969 0x009f6000, 0x00bf4000, 0x00df2000, 0x00ff0000, 0x00ff0000}},
970 {0, 1, 3, 0,
971 {0x0000ff00, 0x0000ff00, 0x0020df00, 0x0040bf00, 0x005fa000, 0x007f8000,
972 0x009f6000, 0x00bf4000, 0x00df2000, 0x00ff0000, 0x00ff0000}},
973 {0, 1, 3, 3,
974 {0x0000ff00, 0x0000ff00, 0x0020df00, 0x0040bf00, 0x005fa000, 0x007f8000,
975 0x009f6000, 0x00bf4000, 0x00df2000, 0x00ff0000, 0x00ff0000}},
977 /* vertex shader */
978 {1, 0, 0, 0,
979 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
980 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
981 {1, 0, 0, 3,
982 {0x0000ff00, 0x0000ff00, 0x0020df00, 0x0040bf00, 0x005fa000, 0x007f8000,
983 0x009f6000, 0x00bf4000, 0x00df2000, 0x00ff0000, 0x00ff0000}},
984 {1, 0, 1, 3,
985 {0x0000ff00, 0x0000ff00, 0x0020df00, 0x0040bf00, 0x005fa000, 0x007f8000,
986 0x009f6000, 0x00bf4000, 0x00df2000, 0x00ff0000, 0x00ff0000}},
987 {1, 0, 2, 3,
988 {0x0000ff00, 0x0000ff00, 0x0020df00, 0x0040bf00, 0x005fa000, 0x007f8000,
989 0x009f6000, 0x00bf4000, 0x00df2000, 0x00ff0000, 0x00ff0000}},
990 {1, 0, 3, 3,
991 {0x0000ff00, 0x0000ff00, 0x0020df00, 0x0040bf00, 0x005fa000, 0x007f8000,
992 0x009f6000, 0x00bf4000, 0x00df2000, 0x00ff0000, 0x00ff0000}},
994 /* vertex shader and pixel shader */
995 {1, 1, 0, 3,
996 {0x0000ff00, 0x0000ff00, 0x0020df00, 0x0040bf00, 0x005fa000, 0x007f8000,
997 0x009f6000, 0x00bf4000, 0x00df2000, 0x00ff0000, 0x00ff0000}},
998 {1, 1, 1, 3,
999 {0x0000ff00, 0x0000ff00, 0x0020df00, 0x0040bf00, 0x005fa000, 0x007f8000,
1000 0x009f6000, 0x00bf4000, 0x00df2000, 0x00ff0000, 0x00ff0000}},
1001 {1, 1, 2, 3,
1002 {0x0000ff00, 0x0000ff00, 0x0020df00, 0x0040bf00, 0x005fa000, 0x007f8000,
1003 0x009f6000, 0x00bf4000, 0x00df2000, 0x00ff0000, 0x00ff0000}},
1004 {1, 1, 3, 3,
1005 {0x0000ff00, 0x0000ff00, 0x0020df00, 0x0040bf00, 0x005fa000, 0x007f8000,
1006 0x009f6000, 0x00bf4000, 0x00df2000, 0x00ff0000, 0x00ff0000}},
1008 #if 0 /* FIXME: these fail on GeForce 8500 */
1009 /* foggy vertex shader */
1010 {2, 0, 0, 0,
1011 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1012 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1013 {2, 0, 1, 0,
1014 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1015 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1016 {2, 0, 2, 0,
1017 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1018 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1019 {2, 0, 3, 0,
1020 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1021 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1022 #endif
1024 /* foggy vertex shader and pixel shader */
1025 {2, 1, 0, 0,
1026 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1027 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1028 {2, 1, 1, 0,
1029 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1030 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1031 {2, 1, 2, 0,
1032 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1033 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1034 {2, 1, 3, 0,
1035 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1036 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1040 /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1041 start.f=0.9f;
1042 end.f=0.1f;
1044 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1045 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1046 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1047 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1048 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1049 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1050 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1051 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1053 /* Setup initial states: No lighting, fog on, fog color */
1054 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1055 ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1056 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1057 ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1058 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1059 ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1060 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1061 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1063 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1064 ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1065 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1066 ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1068 /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1069 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1070 ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1071 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1072 ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1074 for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1076 hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1077 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1078 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1079 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1080 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1081 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1082 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1083 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1085 for(j=0; j < 11; j++)
1087 /* Don't use the whole zrange to prevent rounding errors */
1088 quad[0].z = 0.001f + (float)j / 10.02f;
1089 quad[1].z = 0.001f + (float)j / 10.02f;
1090 quad[2].z = 0.001f + (float)j / 10.02f;
1091 quad[3].z = 0.001f + (float)j / 10.02f;
1093 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1094 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1096 hr = IDirect3DDevice9_BeginScene(device);
1097 ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1099 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1100 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1102 hr = IDirect3DDevice9_EndScene(device);
1103 ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1105 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1107 /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1108 color = getPixelColor(device, 128, 240);
1109 ok((unsigned char)(color) == ((unsigned char)test_data[i].color[j])
1110 && abs( ((unsigned char)(color>>8)) - (unsigned char)(test_data[i].color[j]>>8) ) < 13
1111 && abs( ((unsigned char)(color>>16)) - (unsigned char)(test_data[i].color[j]>>16) ) < 13,
1112 "fog ps%i vs%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n", test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1116 /* reset states */
1117 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1118 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1119 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1120 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1121 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1122 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1123 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1124 ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1126 IDirect3DVertexShader9_Release(vertex_shader[1]);
1127 IDirect3DVertexShader9_Release(vertex_shader[2]);
1128 IDirect3DPixelShader9_Release(pixel_shader[1]);
1129 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1132 /* test the behavior of the texbem instruction
1133 * with normal 2D and projective 2D textures
1135 static void texbem_test(IDirect3DDevice9 *device)
1137 HRESULT hr;
1138 DWORD color;
1139 unsigned int i, x, y;
1141 static const DWORD pixel_shader_code[] = {
1142 0xffff0101, /* ps_1_1*/
1143 0x00000042, 0xb00f0000, /* tex t0*/
1144 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
1145 0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
1146 0x0000ffff
1149 static const float quad[][7] = {
1150 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
1151 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
1152 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
1153 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
1155 static const float quad_proj[][9] = {
1156 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 128.0f},
1157 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 128.0f, 0.0f, 128.0f},
1158 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f, 0.0f, 0.0f, 128.0f},
1159 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
1162 static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
1163 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1164 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1165 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1166 D3DDECL_END()
1168 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1169 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1170 {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1171 D3DDECL_END()
1172 } };
1174 /* use assymetric matrix to test loading */
1175 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
1177 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1178 IDirect3DPixelShader9 *pixel_shader = NULL;
1179 IDirect3DTexture9 *texture[2] = {NULL, NULL};
1180 D3DLOCKED_RECT locked_rect;
1182 /* Generate the textures */
1183 for(i=0; i<2; i++)
1185 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1186 D3DPOOL_MANAGED, &texture[i], NULL);
1187 ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1189 hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, D3DLOCK_DISCARD);
1190 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1191 for (y = 0; y < 128; ++y)
1193 if(i)
1194 { /* Set up black texture with 2x2 texel white spot in the middle */
1195 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1196 for (x = 0; x < 128; ++x)
1198 if(y>62 && y<66 && x>62 && x<66)
1199 *ptr++ = 0xffffffff;
1200 else
1201 *ptr++ = 0xff000000;
1204 else
1205 { /* Set up a displacement map which points away from the center parallel to the closest axis.
1206 * (if multiplied with bumpenvmat)
1208 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1209 for (x = 0; x < 128; ++x)
1211 if(abs(x-64)>abs(y-64))
1213 if(x < 64)
1214 *ptr++ = 0xc000;
1215 else
1216 *ptr++ = 0x4000;
1218 else
1220 if(y < 64)
1221 *ptr++ = 0x0040;
1222 else
1223 *ptr++ = 0x00c0;
1228 hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
1229 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1231 hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
1232 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1234 /* Disable texture filtering */
1235 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1236 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1237 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1238 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1240 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1241 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
1242 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1243 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
1246 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1247 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1248 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1249 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1250 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
1252 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1253 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1255 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1256 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1258 for(i=0; i<2; i++)
1260 if(i)
1262 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
1263 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1266 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
1267 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1268 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1269 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1271 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
1272 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1273 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1274 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1276 hr = IDirect3DDevice9_BeginScene(device);
1277 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1279 if(!i)
1280 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1281 else
1282 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
1283 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1285 hr = IDirect3DDevice9_EndScene(device);
1286 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1288 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1289 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1291 color = getPixelColor(device, 320-32, 240);
1292 ok(color == 0x00ffffff, "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1293 color = getPixelColor(device, 320+32, 240);
1294 ok(color == 0x00ffffff, "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1295 color = getPixelColor(device, 320, 240-32);
1296 ok(color == 0x00ffffff, "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1297 color = getPixelColor(device, 320, 240+32);
1298 ok(color == 0x00ffffff, "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1300 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1301 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1302 IDirect3DPixelShader9_Release(pixel_shader);
1304 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1305 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1306 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1309 /* clean up */
1310 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1311 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1313 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
1314 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1316 for(i=0; i<2; i++)
1318 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
1319 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1320 IDirect3DCubeTexture9_Release(texture[i]);
1324 static void z_range_test(IDirect3DDevice9 *device)
1326 const struct vertex quad[] =
1328 {-1.0f, 0.0f, 1.1f, 0xffff0000},
1329 {-1.0f, 1.0f, 1.1f, 0xffff0000},
1330 { 1.0f, 0.0f, -1.1f, 0xffff0000},
1331 { 1.0f, 1.0f, -1.1f, 0xffff0000},
1333 const struct vertex quad2[] =
1335 {-1.0f, 0.0f, 1.1f, 0xff0000ff},
1336 {-1.0f, 1.0f, 1.1f, 0xff0000ff},
1337 { 1.0f, 0.0f, -1.1f, 0xff0000ff},
1338 { 1.0f, 1.0f, -1.1f, 0xff0000ff},
1341 const struct tvertex quad3[] =
1343 { 0, 240, 1.1f, 1.0, 0xffffff00},
1344 { 0, 480, 1.1f, 1.0, 0xffffff00},
1345 { 640, 240, -1.1f, 1.0, 0xffffff00},
1346 { 640, 480, -1.1f, 1.0, 0xffffff00},
1348 const struct tvertex quad4[] =
1350 { 0, 240, 1.1f, 1.0, 0xff00ff00},
1351 { 0, 480, 1.1f, 1.0, 0xff00ff00},
1352 { 640, 240, -1.1f, 1.0, 0xff00ff00},
1353 { 640, 480, -1.1f, 1.0, 0xff00ff00},
1355 HRESULT hr;
1356 DWORD color;
1357 IDirect3DVertexShader9 *shader;
1358 IDirect3DVertexDeclaration9 *decl;
1359 const DWORD shader_code[] = {
1360 0xfffe0101, /* vs_1_1 */
1361 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1362 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1363 0x00000001, 0xd00f0000, 0xa0e40000, /* mov oD0, c0 */
1364 0x0000ffff /* end */
1366 static const D3DVERTEXELEMENT9 decl_elements[] = {
1367 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1368 D3DDECL_END()
1370 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
1371 * then call Present. Then clear the color buffer to make sure it has some defined content
1372 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
1373 * by the depth value.
1375 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
1376 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
1377 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1378 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
1380 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
1381 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1382 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
1383 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1384 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
1385 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1386 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
1387 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1388 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1389 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
1391 hr = IDirect3DDevice9_BeginScene(device);
1392 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
1393 if(hr == D3D_OK)
1395 /* Test the untransformed vertex path */
1396 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
1397 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1398 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
1399 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1400 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
1401 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1403 /* Test the transformed vertex path */
1404 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
1405 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
1407 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad4, sizeof(quad4[0]));
1408 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1409 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
1410 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1411 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad3, sizeof(quad3[0]));
1412 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1414 hr = IDirect3DDevice9_EndScene(device);
1415 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
1418 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1419 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1421 /* Do not test the exact corner pixels, but go pretty close to them */
1423 /* Clipped because z > 1.0 */
1424 color = getPixelColor(device, 28, 238);
1425 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1426 color = getPixelColor(device, 28, 241);
1427 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1429 /* Not clipped, > z buffer clear value(0.75) */
1430 color = getPixelColor(device, 31, 238);
1431 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1432 color = getPixelColor(device, 31, 241);
1433 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1434 color = getPixelColor(device, 100, 238);
1435 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1436 color = getPixelColor(device, 100, 241);
1437 ok(color == 0x00ffff00, "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
1439 /* Not clipped, < z buffer clear value */
1440 color = getPixelColor(device, 104, 238);
1441 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
1442 color = getPixelColor(device, 104, 241);
1443 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
1444 color = getPixelColor(device, 318, 238);
1445 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
1446 color = getPixelColor(device, 318, 241);
1447 ok(color == 0x0000ff00, "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
1449 /* Clipped because z < 0.0 */
1450 color = getPixelColor(device, 321, 238);
1451 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1452 color = getPixelColor(device, 321, 241);
1453 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1455 /* Test the shader path */
1456 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
1457 if(FAILED(hr)) {
1458 skip("Can't create test vertex shader, most likely shaders not supported\n");
1459 goto out;
1461 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
1463 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
1465 IDirect3DDevice9_SetVertexDeclaration(device, decl);
1466 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
1467 IDirect3DDevice9_SetVertexShader(device, shader);
1468 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
1470 hr = IDirect3DDevice9_BeginScene(device);
1471 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
1472 if(hr == D3D_OK)
1474 float colorf[] = {1.0, 0.0, 0.0, 1.0};
1475 float colorf2[] = {0.0, 0.0, 1.0, 1.0};
1476 IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf, 1);
1477 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
1478 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1479 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
1480 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1481 IDirect3DDevice9_SetVertexShaderConstantF(device, 0, colorf2, 1);
1482 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad2, sizeof(quad2[0]));
1483 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1485 hr = IDirect3DDevice9_EndScene(device);
1486 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
1489 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1490 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %s\n", DXGetErrorString9(hr));
1491 IDirect3DDevice9_SetVertexShader(device, NULL);
1492 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %s\n", DXGetErrorString9(hr));
1494 IDirect3DVertexDeclaration9_Release(decl);
1495 IDirect3DVertexShader9_Release(shader);
1497 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1498 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1499 /* Z < 1.0 */
1500 color = getPixelColor(device, 28, 238);
1501 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1503 /* 1.0 < z < 0.75 */
1504 color = getPixelColor(device, 31, 238);
1505 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1506 color = getPixelColor(device, 100, 238);
1507 ok(color == 0x00ff0000, "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1509 /* 0.75 < z < 0.0 */
1510 color = getPixelColor(device, 104, 238);
1511 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
1512 color = getPixelColor(device, 318, 238);
1513 ok(color == 0x000000ff, "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
1515 /* 0.0 < z */
1516 color = getPixelColor(device, 321, 238);
1517 ok(color == 0x00ffffff, "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1519 out:
1520 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
1521 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1522 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
1523 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1524 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
1525 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1528 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
1530 D3DSURFACE_DESC desc;
1531 D3DLOCKED_RECT l;
1532 HRESULT hr;
1533 unsigned int x, y;
1534 DWORD *mem;
1536 memset(&desc, 0, sizeof(desc));
1537 memset(&l, 0, sizeof(l));
1538 hr = IDirect3DSurface9_GetDesc(surface, &desc);
1539 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %s\n", DXGetErrorString9(hr));
1540 hr = IDirect3DSurface9_LockRect(surface, &l, NULL, D3DLOCK_DISCARD);
1541 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %s\n", DXGetErrorString9(hr));
1542 if(FAILED(hr)) return;
1544 for(y = 0; y < desc.Height; y++)
1546 mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
1547 for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
1549 mem[x] = color;
1552 hr = IDirect3DSurface9_UnlockRect(surface);
1553 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %s\n", DXGetErrorString9(hr));
1556 static void maxmip_test(IDirect3DDevice9 *device)
1558 IDirect3DTexture9 *texture = NULL;
1559 IDirect3DSurface9 *surface = NULL;
1560 HRESULT hr;
1561 DWORD color;
1562 const float quads[] = {
1563 -1.0, -1.0, 0.0, 0.0, 0.0,
1564 -1.0, 0.0, 0.0, 0.0, 1.0,
1565 0.0, -1.0, 0.0, 1.0, 0.0,
1566 0.0, 0.0, 0.0, 1.0, 1.0,
1568 0.0, -1.0, 0.0, 0.0, 0.0,
1569 0.0, 0.0, 0.0, 0.0, 1.0,
1570 1.0, -1.0, 0.0, 1.0, 0.0,
1571 1.0, 0.0, 0.0, 1.0, 1.0,
1573 0.0, 0.0, 0.0, 0.0, 0.0,
1574 0.0, 1.0, 0.0, 0.0, 1.0,
1575 1.0, 0.0, 0.0, 1.0, 0.0,
1576 1.0, 1.0, 0.0, 1.0, 1.0,
1578 -1.0, 0.0, 0.0, 0.0, 0.0,
1579 -1.0, 1.0, 0.0, 0.0, 1.0,
1580 0.0, 0.0, 0.0, 1.0, 0.0,
1581 0.0, 1.0, 0.0, 1.0, 1.0,
1584 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
1585 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
1587 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
1588 &texture, NULL);
1589 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
1590 if(!texture)
1592 skip("Failed to create test texture\n");
1593 return;
1596 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
1597 fill_surface(surface, 0xffff0000);
1598 IDirect3DSurface9_Release(surface);
1599 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
1600 fill_surface(surface, 0xff00ff00);
1601 IDirect3DSurface9_Release(surface);
1602 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
1603 fill_surface(surface, 0xff0000ff);
1604 IDirect3DSurface9_Release(surface);
1606 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
1607 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
1608 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1609 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
1611 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
1612 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
1614 hr = IDirect3DDevice9_BeginScene(device);
1615 if(SUCCEEDED(hr))
1617 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
1618 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
1619 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
1620 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1622 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
1623 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
1624 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
1625 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1627 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
1628 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
1629 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
1630 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1632 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
1633 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
1634 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
1635 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1636 hr = IDirect3DDevice9_EndScene(device);
1639 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1640 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1641 /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
1642 color = getPixelColor(device, 160, 360);
1643 ok(color == 0x00FF0000, "MapMip 0, no mipfilter has color %08x\n", color);
1644 color = getPixelColor(device, 160, 120);
1645 ok(color == 0x00FF0000, "MapMip 3, no mipfilter has color %08x\n", color);
1646 color = getPixelColor(device, 480, 120);
1647 ok(color == 0x00FF0000, "MapMip 2, no mipfilter has color %08x\n", color);
1648 color = getPixelColor(device, 480, 360);
1649 ok(color == 0x00FF0000, "MapMip 1, no mipfilter has color %08x\n", color);
1651 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
1652 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
1654 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
1655 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
1657 hr = IDirect3DDevice9_BeginScene(device);
1658 if(SUCCEEDED(hr))
1660 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
1661 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
1662 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
1663 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1665 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
1666 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
1667 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
1668 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1670 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
1671 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
1672 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
1673 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1675 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
1676 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
1677 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
1678 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1679 hr = IDirect3DDevice9_EndScene(device);
1682 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
1683 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
1684 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
1685 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
1687 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1688 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1689 /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
1690 * samples from the highest level in the texture(level 2)
1692 color = getPixelColor(device, 160, 360);
1693 ok(color == 0x00FF0000, "MapMip 0, point mipfilter has color %08x\n", color);
1694 color = getPixelColor(device, 160, 120);
1695 ok(color == 0x000000FF, "MapMip 3, point mipfilter has color %08x\n", color);
1696 color = getPixelColor(device, 480, 120);
1697 ok(color == 0x000000FF, "MapMip 2, point mipfilter has color %08x\n", color);
1698 color = getPixelColor(device, 480, 360);
1699 ok(color == 0x0000FF00, "MapMip 1, point mipfilter has color %08x\n", color);
1701 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1702 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
1703 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
1704 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
1705 IDirect3DTexture9_Release(texture);
1708 static void release_buffer_test(IDirect3DDevice9 *device)
1710 IDirect3DVertexBuffer9 *vb = NULL;
1711 IDirect3DIndexBuffer9 *ib = NULL;
1712 HRESULT hr;
1713 BYTE *data;
1714 long ref;
1716 static const struct vertex quad[] = {
1717 {-1.0, -1.0, 0.1, 0xffff0000},
1718 {-1.0, 1.0, 0.1, 0xffff0000},
1719 { 1.0, 1.0, 0.1, 0xffff0000},
1721 {-1.0, -1.0, 0.1, 0xff00ff00},
1722 {-1.0, 1.0, 0.1, 0xff00ff00},
1723 { 1.0, 1.0, 0.1, 0xff00ff00}
1725 short indices[] = {3, 4, 5};
1727 /* Index and vertex buffers should always be creatable */
1728 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
1729 D3DPOOL_MANAGED, &vb, NULL);
1730 ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
1731 if(!vb) {
1732 skip("Failed to create a vertex buffer\n");
1733 return;
1735 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
1736 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %s\n", DXGetErrorString9(hr));
1737 if(!ib) {
1738 skip("Failed to create an index buffer\n");
1739 return;
1742 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
1743 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
1744 memcpy(data, quad, sizeof(quad));
1745 hr = IDirect3DVertexBuffer9_Unlock(vb);
1746 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
1748 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
1749 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
1750 memcpy(data, indices, sizeof(indices));
1751 hr = IDirect3DIndexBuffer9_Unlock(ib);
1752 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
1754 hr = IDirect3DDevice9_SetIndices(device, ib);
1755 ok(hr == D3D_OK, "IDirect3DIndexBuffer8_Unlock failed with %s\n", DXGetErrorString9(hr));
1756 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
1757 ok(hr == D3D_OK, "IDirect3DIndexBuffer8_Unlock failed with %s\n", DXGetErrorString9(hr));
1758 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1759 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
1761 /* Now destroy the bound index buffer and draw again */
1762 ref = IDirect3DIndexBuffer9_Release(ib);
1763 ok(ref == 0, "Index Buffer reference count is %08ld\n", ref);
1765 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
1766 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1768 hr = IDirect3DDevice9_BeginScene(device);
1769 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
1770 if(SUCCEEDED(hr))
1772 /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
1773 * making assumptions about the indices or vertices
1775 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
1776 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
1777 hr = IDirect3DDevice9_EndScene(device);
1778 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
1781 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1782 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
1784 hr = IDirect3DDevice9_SetIndices(device, NULL);
1785 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
1786 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
1787 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
1789 /* Index buffer was already destroyed as part of the test */
1790 IDirect3DVertexBuffer9_Release(vb);
1793 static void float_texture_test(IDirect3DDevice9 *device)
1795 IDirect3D9 *d3d = NULL;
1796 HRESULT hr;
1797 IDirect3DTexture9 *texture = NULL;
1798 D3DLOCKED_RECT lr;
1799 float *data;
1800 DWORD color;
1801 float quad[] = {
1802 -1.0, -1.0, 0.1, 0.0, 0.0,
1803 -1.0, 1.0, 0.1, 0.0, 1.0,
1804 1.0, -1.0, 0.1, 1.0, 0.0,
1805 1.0, 1.0, 0.1, 1.0, 1.0,
1808 memset(&lr, 0, sizeof(lr));
1809 IDirect3DDevice9_GetDirect3D(device, &d3d);
1810 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
1811 D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
1812 skip("D3DFMT_R32F textures not supported\n");
1813 goto out;
1816 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
1817 D3DPOOL_MANAGED, &texture, NULL);
1818 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
1819 if(!texture) {
1820 skip("Failed to create R32F texture\n");
1821 goto out;
1824 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
1825 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %s\n", DXGetErrorString9(hr));
1826 data = lr.pBits;
1827 *data = 0.0;
1828 hr = IDirect3DTexture9_UnlockRect(texture, 0);
1829 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %s\n", DXGetErrorString9(hr));
1831 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
1832 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
1834 hr = IDirect3DDevice9_BeginScene(device);
1835 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
1836 if(SUCCEEDED(hr))
1838 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1839 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
1841 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
1842 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1844 hr = IDirect3DDevice9_EndScene(device);
1845 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
1847 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1848 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
1850 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1851 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
1853 color = getPixelColor(device, 240, 320);
1854 ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
1856 out:
1857 if(texture) IDirect3DTexture9_Release(texture);
1858 IDirect3D9_Release(d3d);
1861 static void texture_transform_flags_test(IDirect3DDevice9 *device)
1863 HRESULT hr;
1864 IDirect3D9 *d3d;
1865 D3DFORMAT fmt = D3DFMT_X8R8G8B8;
1866 D3DCAPS9 caps;
1867 IDirect3DTexture9 *texture = NULL;
1868 IDirect3DVolumeTexture9 *volume = NULL;
1869 unsigned int x, y, z;
1870 D3DLOCKED_RECT lr;
1871 D3DLOCKED_BOX lb;
1872 DWORD color;
1873 IDirect3DVertexDeclaration9 *decl, *decl2;
1874 float identity[16] = {1.0, 0.0, 0.0, 0.0,
1875 0.0, 1.0, 0.0, 0.0,
1876 0.0, 0.0, 1.0, 0.0,
1877 0.0, 0.0, 0.0, 1.0};
1878 static const D3DVERTEXELEMENT9 decl_elements[] = {
1879 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1880 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1881 D3DDECL_END()
1883 static const D3DVERTEXELEMENT9 decl_elements2[] = {
1884 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1885 {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1886 D3DDECL_END()
1889 memset(&lr, 0, sizeof(lr));
1890 memset(&lb, 0, sizeof(lb));
1891 IDirect3DDevice9_GetDirect3D(device, &d3d);
1892 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
1893 D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
1894 fmt = D3DFMT_A16B16G16R16;
1896 IDirect3D9_Release(d3d);
1898 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
1899 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
1900 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
1901 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
1902 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
1903 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %s\n", DXGetErrorString9(hr));
1904 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1905 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %s\n", DXGetErrorString9(hr));
1906 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1907 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %s\n", DXGetErrorString9(hr));
1908 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
1909 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %s\n", DXGetErrorString9(hr));
1910 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1911 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %s\n", DXGetErrorString9(hr));
1912 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1913 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %s\n", DXGetErrorString9(hr));
1914 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
1915 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %s\n", DXGetErrorString9(hr));
1916 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1917 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %s\n", DXGetErrorString9(hr));
1918 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
1919 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
1921 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
1922 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %s\n", DXGetErrorString9(hr));
1923 hr = IDirect3DDevice9_CreateTexture(device, caps.MaxTextureWidth, caps.MaxTextureHeight, 1,
1924 0, fmt, D3DPOOL_MANAGED, &texture, NULL);
1925 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %s\n", DXGetErrorString9(hr));
1926 if(!texture) {
1927 skip("Failed to create the test texture\n");
1928 return;
1931 /* Unfortunately there is no easy way to set up a texture coordinate passthrough
1932 * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
1933 * 1.0 in red and green for the x and y coords
1935 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
1936 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %s\n", DXGetErrorString9(hr));
1937 for(y = 0; y < caps.MaxTextureHeight; y++) {
1938 for(x = 0; x < caps.MaxTextureWidth; x++) {
1939 double r_f = (double) y / (double) caps.MaxTextureHeight;
1940 double g_f = (double) x / (double) caps.MaxTextureWidth;
1941 if(fmt == D3DFMT_A16B16G16R16) {
1942 unsigned short r, g;
1943 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
1944 r = (unsigned short) (r_f * 65536.0);
1945 g = (unsigned short) (g_f * 65536.0);
1946 dst[0] = r;
1947 dst[1] = g;
1948 dst[2] = 0;
1949 dst[3] = 65535;
1950 } else {
1951 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
1952 unsigned char r = (unsigned char) (r_f * 255.0);
1953 unsigned char g = (unsigned char) (g_f * 255.0);
1954 dst[0] = 0;
1955 dst[1] = g;
1956 dst[2] = r;
1957 dst[3] = 255;
1961 hr = IDirect3DTexture9_UnlockRect(texture, 0);
1962 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %s\n", DXGetErrorString9(hr));
1963 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
1964 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
1966 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1967 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
1968 hr = IDirect3DDevice9_BeginScene(device);
1969 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
1970 if(SUCCEEDED(hr))
1972 float quad1[] = {
1973 -1.0, -1.0, 0.1, 1.0, 1.0,
1974 -1.0, 0.0, 0.1, 1.0, 1.0,
1975 0.0, -1.0, 0.1, 1.0, 1.0,
1976 0.0, 0.0, 0.1, 1.0, 1.0,
1978 float quad2[] = {
1979 -1.0, 0.0, 0.1, 1.0, 1.0,
1980 -1.0, 1.0, 0.1, 1.0, 1.0,
1981 0.0, 0.0, 0.1, 1.0, 1.0,
1982 0.0, 1.0, 0.1, 1.0, 1.0,
1984 float quad3[] = {
1985 0.0, 0.0, 0.1, 0.5, 0.5,
1986 0.0, 1.0, 0.1, 0.5, 0.5,
1987 1.0, 0.0, 0.1, 0.5, 0.5,
1988 1.0, 1.0, 0.1, 0.5, 0.5,
1990 float quad4[] = {
1991 320, 480, 0.1, 1.0, 0.0, 1.0,
1992 320, 240, 0.1, 1.0, 0.0, 1.0,
1993 640, 480, 0.1, 1.0, 0.0, 1.0,
1994 640, 240, 0.1, 1.0, 0.0, 1.0,
1996 float mat[16] = {0.0, 0.0, 0.0, 0.0,
1997 0.0, 0.0, 0.0, 0.0,
1998 0.0, 0.0, 0.0, 0.0,
1999 0.0, 0.0, 0.0, 0.0};
2001 /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
2002 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
2003 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2004 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
2005 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2007 /* What happens with transforms enabled? */
2008 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
2009 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2010 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
2011 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2013 /* What happens if 4 coords are used, but only 2 given ?*/
2014 mat[8] = 1.0;
2015 mat[13] = 1.0;
2016 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
2017 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2018 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
2019 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2020 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
2021 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2023 /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
2024 * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
2025 * due to the coords in the vertices. (turns out red, indeed)
2027 memset(mat, 0, sizeof(mat));
2028 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
2029 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2030 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
2031 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
2032 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2033 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2034 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
2035 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2037 hr = IDirect3DDevice9_EndScene(device);
2038 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
2040 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2041 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2042 color = getPixelColor(device, 160, 360);
2043 ok(color == 0x00FFFF00 || color == 0x00FEFE00, "quad 1 has color %08x, expected 0x00FFFF00\n", color);
2044 color = getPixelColor(device, 160, 120);
2045 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
2046 color = getPixelColor(device, 480, 120);
2047 ok(color == 0x0000FF00 || color == 0x0000FE00, "quad 3 has color %08x, expected 0x0000FF00\n", color);
2048 color = getPixelColor(device, 480, 360);
2049 ok(color == 0x00FF0000 || 0x00FE0000, "quad 4 has color %08x, expected 0x00FF0000\n", color);
2051 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
2052 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
2054 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2055 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2056 hr = IDirect3DDevice9_BeginScene(device);
2057 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
2058 if(SUCCEEDED(hr))
2060 float quad1[] = {
2061 -1.0, -1.0, 0.1, 0.8, 0.2,
2062 -1.0, 0.0, 0.1, 0.8, 0.2,
2063 0.0, -1.0, 0.1, 0.8, 0.2,
2064 0.0, 0.0, 0.1, 0.8, 0.2,
2066 float quad2[] = {
2067 -1.0, 0.0, 0.1, 0.5, 1.0,
2068 -1.0, 1.0, 0.1, 0.5, 1.0,
2069 0.0, 0.0, 0.1, 0.5, 1.0,
2070 0.0, 1.0, 0.1, 0.5, 1.0,
2072 float quad3[] = {
2073 0.0, 0.0, 0.1, 0.5, 1.0,
2074 0.0, 1.0, 0.1, 0.5, 1.0,
2075 1.0, 0.0, 0.1, 0.5, 1.0,
2076 1.0, 1.0, 0.1, 0.5, 1.0,
2078 float quad4[] = {
2079 0.0, -1.0, 0.1, 0.8, 0.2,
2080 0.0, 0.0, 0.1, 0.8, 0.2,
2081 1.0, -1.0, 0.1, 0.8, 0.2,
2082 1.0, 0.0, 0.1, 0.8, 0.2,
2084 float mat[16] = {0.0, 0.0, 0.0, 0.0,
2085 0.0, 0.0, 0.0, 0.0,
2086 0.0, 1.0, 0.0, 0.0,
2087 0.0, 0.0, 0.0, 0.0};
2089 /* What happens to the default 1 in the 3rd coordinate if it is disabled?
2091 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
2092 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2093 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
2094 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2096 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
2097 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2099 /* What does this mean? Not sure... */
2100 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
2101 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2102 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
2103 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2105 /* Just to be sure, the same as quad2 above */
2106 memset(mat, 0, sizeof(mat));
2107 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
2108 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2109 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
2110 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2111 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
2112 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2114 /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
2115 * used? And what happens to the first?
2117 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
2118 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2119 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
2120 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2122 hr = IDirect3DDevice9_EndScene(device);
2123 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
2125 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2126 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2127 color = getPixelColor(device, 160, 360);
2128 ok(color == 0x00FF0000 || color == 0x00FE0000, "quad 1 has color %08x, expected 0x00FF0000\n", color);
2129 color = getPixelColor(device, 160, 120);
2130 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
2131 color = getPixelColor(device, 480, 120);
2132 ok(color == 0x00ff8000 || color == 0x00fe7f00, "quad 3 has color %08x, expected 0x00ff8000\n", color);
2133 color = getPixelColor(device, 480, 360);
2134 ok(color == 0x0033cc00 || color == 0x0032cb00, "quad 4 has color %08x, expected 0x0033cc00\n", color);
2136 IDirect3DTexture9_Release(texture);
2138 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
2139 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
2140 /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
2141 * Thus watch out if sampling from texels between 0 and 1.
2143 hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
2144 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
2145 "IDirect3DDevice9_CreateVolumeTexture failed with %s\n", DXGetErrorString9(hr));
2146 if(!volume) {
2147 skip("Failed to create a volume texture\n");
2148 goto out;
2151 hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
2152 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %s\n", DXGetErrorString9(hr));
2153 for(z = 0; z < 32; z++) {
2154 for(y = 0; y < 32; y++) {
2155 for(x = 0; x < 32; x++) {
2156 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
2157 void *mem = ((char *) lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
2158 float r_f = (float) x / 31.0;
2159 float g_f = (float) y / 31.0;
2160 float b_f = (float) z / 31.0;
2162 if(fmt == D3DFMT_A16B16G16R16) {
2163 unsigned short *mem_s = mem;
2164 mem_s[0] = r_f * 65535.0;
2165 mem_s[1] = g_f * 65535.0;
2166 mem_s[2] = b_f * 65535.0;
2167 mem_s[3] = 65535;
2168 } else {
2169 unsigned char *mem_c = mem;
2170 mem_c[0] = b_f * 255.0;
2171 mem_c[1] = g_f * 255.0;
2172 mem_c[2] = r_f * 255.0;
2173 mem_c[3] = 255;
2178 hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
2179 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %s\n", DXGetErrorString9(hr));
2181 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
2182 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %s\n", DXGetErrorString9(hr));
2184 hr = IDirect3DDevice9_BeginScene(device);
2185 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
2186 if(SUCCEEDED(hr))
2188 float quad1[] = {
2189 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
2190 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
2191 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
2192 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
2194 float quad2[] = {
2195 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
2196 -1.0, 1.0, 0.1, 1.0, 1.0, 1.0,
2197 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
2198 0.0, 1.0, 0.1, 1.0, 1.0, 1.0
2200 float quad3[] = {
2201 0.0, 0.0, 0.1, 0.0, 0.0,
2202 0.0, 1.0, 0.1, 0.0, 0.0,
2203 1.0, 0.0, 0.1, 0.0, 0.0,
2204 1.0, 1.0, 0.1, 0.0, 0.0
2206 float quad4[] = {
2207 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
2208 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
2209 1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
2210 1.0, 0.0, 0.1, 1.0, 1.0, 1.0
2212 float mat[16] = {1.0, 0.0, 0.0, 0.0,
2213 0.0, 0.0, 1.0, 0.0,
2214 0.0, 1.0, 0.0, 0.0,
2215 0.0, 0.0, 0.0, 1.0};
2216 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
2217 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
2219 /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
2220 * values
2222 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
2223 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2224 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
2225 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2226 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
2227 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2229 /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
2230 * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
2231 * otherwise the w will be missing(blue).
2232 * turns out that the blue color is missing, so it is an output modification
2234 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
2235 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2236 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
2237 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2239 /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 4 */
2240 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
2241 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2242 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
2243 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2244 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2245 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2246 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
2247 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2249 /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0 */
2250 memset(mat, 0, sizeof(mat));
2251 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
2252 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2253 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
2254 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2255 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
2256 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
2257 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
2258 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2260 hr = IDirect3DDevice9_EndScene(device);
2261 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
2263 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2264 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2266 color = getPixelColor(device, 160, 360);
2267 ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
2268 color = getPixelColor(device, 160, 120);
2269 ok(color == 0x00ffff00, "quad 2 has color %08x, expected 0x00ffff00\n", color);
2270 color = getPixelColor(device, 480, 120);
2271 ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
2272 color = getPixelColor(device, 480, 360);
2273 ok(color == 0x00ffffff, "quad 4 has color %08x, expected 0x00ffffff\n", color);
2275 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
2276 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
2277 hr = IDirect3DDevice9_BeginScene(device);
2278 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
2279 if(SUCCEEDED(hr))
2281 float quad1[] = {
2282 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
2283 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
2284 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
2285 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
2287 float quad2[] = {
2288 -1.0, 0.0, 0.1,
2289 -1.0, 1.0, 0.1,
2290 0.0, 0.0, 0.1,
2291 0.0, 1.0, 0.1,
2293 float quad3[] = {
2294 0.0, 0.0, 0.1, 1.0,
2295 0.0, 1.0, 0.1, 1.0,
2296 1.0, 0.0, 0.1, 1.0,
2297 1.0, 1.0, 0.1, 1.0
2299 float mat[16] = {0.0, 0.0, 0.0, 0.0,
2300 0.0, 0.0, 0.0, 0.0,
2301 0.0, 0.0, 0.0, 0.0,
2302 0.0, 1.0, 0.0, 0.0};
2303 float mat2[16] = {0.0, 0.0, 0.0, 1.0,
2304 1.0, 0.0, 0.0, 0.0,
2305 0.0, 1.0, 0.0, 0.0,
2306 0.0, 0.0, 1.0, 0.0};
2307 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
2308 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
2310 /* Default values? 4 coords used, 3 passed. What happens to the 4th?
2312 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
2313 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2314 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
2315 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2316 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
2317 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2319 /* None passed */
2320 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
2321 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2322 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
2323 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2324 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
2325 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2327 /* 4 used, 1 passed */
2328 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
2329 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
2330 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
2331 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2332 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
2333 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2335 hr = IDirect3DDevice9_EndScene(device);
2336 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
2338 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2339 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2340 color = getPixelColor(device, 160, 360);
2341 ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
2342 color = getPixelColor(device, 160, 120);
2343 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
2344 color = getPixelColor(device, 480, 120);
2345 ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
2346 /* Quad4: unused */
2348 IDirect3DVolumeTexture9_Release(volume);
2350 out:
2351 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2352 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
2353 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
2354 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2355 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
2356 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2357 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2358 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
2359 IDirect3DVertexDeclaration9_Release(decl);
2360 IDirect3DVertexDeclaration9_Release(decl2);
2363 static void texdepth_test(IDirect3DDevice9 *device)
2365 IDirect3DPixelShader9 *shader;
2366 HRESULT hr;
2367 const float texdepth_test_data1[] = { 0.25, 2.0, 0.0, 0.0};
2368 const float texdepth_test_data2[] = { 0.25, 0.5, 0.0, 0.0};
2369 const float texdepth_test_data3[] = {-1.00, 0.1, 0.0, 0.0};
2370 const float texdepth_test_data4[] = {-0.25, -0.5, 0.0, 0.0};
2371 const float texdepth_test_data5[] = { 1.00, -0.1, 0.0, 0.0};
2372 const float texdepth_test_data6[] = { 1.00, 0.5, 0.0, 0.0};
2373 const float texdepth_test_data7[] = { 0.50, 0.0, 0.0, 0.0};
2374 DWORD shader_code[] = {
2375 0xffff0104, /* ps_1_4 */
2376 0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c1, 0, 0, 1, 1 */
2377 0x00000001, 0x800f0005, 0xa0e40000, /* mov r5, c0 */
2378 0x0000fffd, /* phase */
2379 0x00000057, 0x800f0005, /* texdepth r5 */
2380 0x00000001, 0x800f0000, 0xa0e40001, /* mov r0, c1 */
2381 0x0000ffff /* end */
2383 DWORD color;
2384 float vertex[] = {
2385 -1.0, -1.0, 0.0,
2386 1.0, -1.0, 1.0,
2387 -1.0, 1.0, 0.0,
2388 1.0, 1.0, 1.0
2391 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
2392 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %s\n", DXGetErrorString9(hr));
2394 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
2395 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
2396 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2397 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
2398 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2399 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
2400 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
2401 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
2402 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
2404 /* Fill the depth buffer with a gradient */
2405 hr = IDirect3DDevice9_BeginScene(device);
2406 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
2407 if(SUCCEEDED(hr))
2409 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
2410 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2411 hr = IDirect3DDevice9_EndScene(device);
2412 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
2415 /* Now perform the actual tests. Same geometry, but with the shader */
2416 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2417 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
2418 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2419 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
2420 hr = IDirect3DDevice9_SetPixelShader(device, shader);
2421 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
2423 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
2424 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
2425 hr = IDirect3DDevice9_BeginScene(device);
2426 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
2427 if(SUCCEEDED(hr))
2429 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
2430 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2432 hr = IDirect3DDevice9_EndScene(device);
2433 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
2436 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2437 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2438 color = getPixelColor(device, 158, 240);
2439 ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
2440 color = getPixelColor(device, 162, 240);
2441 ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
2443 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
2445 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
2446 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
2447 hr = IDirect3DDevice9_BeginScene(device);
2448 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
2449 if(SUCCEEDED(hr))
2451 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
2452 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2454 hr = IDirect3DDevice9_EndScene(device);
2455 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
2458 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2459 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2460 color = getPixelColor(device, 318, 240);
2461 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
2462 color = getPixelColor(device, 322, 240);
2463 ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
2465 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
2467 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
2468 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
2469 hr = IDirect3DDevice9_BeginScene(device);
2470 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
2471 if(SUCCEEDED(hr))
2473 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
2474 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2476 hr = IDirect3DDevice9_EndScene(device);
2477 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
2479 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2480 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2482 color = getPixelColor(device, 1, 240);
2483 ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
2485 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
2487 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
2488 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
2489 hr = IDirect3DDevice9_BeginScene(device);
2490 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
2491 if(SUCCEEDED(hr))
2493 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
2494 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2496 hr = IDirect3DDevice9_EndScene(device);
2497 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
2499 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2500 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2501 color = getPixelColor(device, 318, 240);
2502 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
2503 color = getPixelColor(device, 322, 240);
2504 ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
2506 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
2508 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
2509 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
2510 hr = IDirect3DDevice9_BeginScene(device);
2511 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
2512 if(SUCCEEDED(hr))
2514 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
2515 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2517 hr = IDirect3DDevice9_EndScene(device);
2518 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
2520 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2521 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2523 color = getPixelColor(device, 1, 240);
2524 ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
2526 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
2528 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
2529 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
2530 hr = IDirect3DDevice9_BeginScene(device);
2531 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
2532 if(SUCCEEDED(hr))
2534 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
2535 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2537 hr = IDirect3DDevice9_EndScene(device);
2538 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
2540 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2541 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2543 color = getPixelColor(device, 638, 240);
2544 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
2546 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
2548 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
2549 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %s\n", DXGetErrorString9(hr));
2550 hr = IDirect3DDevice9_BeginScene(device);
2551 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned %s\n", DXGetErrorString9(hr));
2552 if(SUCCEEDED(hr))
2554 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
2555 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2557 hr = IDirect3DDevice9_EndScene(device);
2558 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned %s\n", DXGetErrorString9(hr));
2560 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2561 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2563 color = getPixelColor(device, 638, 240);
2564 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
2566 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
2567 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
2568 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
2569 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
2570 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
2571 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
2574 START_TEST(visual)
2576 IDirect3DDevice9 *device_ptr;
2577 D3DCAPS9 caps;
2578 HRESULT hr;
2579 DWORD color;
2581 d3d9_handle = LoadLibraryA("d3d9.dll");
2582 if (!d3d9_handle)
2584 skip("Could not load d3d9.dll\n");
2585 return;
2588 device_ptr = init_d3d9();
2589 if (!device_ptr)
2591 skip("Creating the device failed\n");
2592 return;
2595 IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
2597 /* Check for the reliability of the returned data */
2598 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
2599 if(FAILED(hr))
2601 trace("Clear failed, can't assure correctness of the test results, skipping\n");
2602 goto cleanup;
2604 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
2606 color = getPixelColor(device_ptr, 1, 1);
2607 if(color !=0x00ff0000)
2609 trace("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
2610 goto cleanup;
2613 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
2614 if(FAILED(hr))
2616 trace("Clear failed, can't assure correctness of the test results, skipping\n");
2617 goto cleanup;
2619 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
2621 color = getPixelColor(device_ptr, 639, 479);
2622 if(color != 0x0000ddee)
2624 trace("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
2625 goto cleanup;
2628 /* Now execute the real tests */
2629 lighting_test(device_ptr);
2630 clear_test(device_ptr);
2631 fog_test(device_ptr);
2632 if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
2634 test_cube_wrap(device_ptr);
2635 } else {
2636 skip("No cube texture support\n");
2638 z_range_test(device_ptr);
2639 if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
2641 maxmip_test(device_ptr);
2643 else
2645 skip("No mipmap support\n");
2647 offscreen_test(device_ptr);
2648 release_buffer_test(device_ptr);
2649 float_texture_test(device_ptr);
2650 texture_transform_flags_test(device_ptr);
2653 if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
2655 test_mova(device_ptr);
2657 else skip("No vs_2_0 support\n");
2659 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
2661 fog_with_shader_test(device_ptr);
2663 else skip("No vs_1_1 and ps_1_1 support\n");
2665 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
2667 texbem_test(device_ptr);
2668 texdepth_test(device_ptr);
2670 else skip("No ps_1_1 support\n");
2672 cleanup:
2673 if(device_ptr) IDirect3DDevice9_Release(device_ptr);