push 83f6eeab4f78cf34cba36fe6c2150f9c23ec0aba
[wine/hacks.git] / dlls / d3d9 / tests / visual.c
blob2c15d1c1c3a76f040b17a62b8bf914f3cb93808c
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 nvertex
136 float x, y, z;
137 float nx, ny, nz;
138 DWORD diffuse;
141 static void lighting_test(IDirect3DDevice9 *device)
143 HRESULT hr;
144 DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
145 DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
146 DWORD color;
148 float mat[16] = { 1.0f, 0.0f, 0.0f, 0.0f,
149 0.0f, 1.0f, 0.0f, 0.0f,
150 0.0f, 0.0f, 1.0f, 0.0f,
151 0.0f, 0.0f, 0.0f, 1.0f };
153 struct vertex unlitquad[] =
155 {-1.0f, -1.0f, 0.1f, 0xffff0000},
156 {-1.0f, 0.0f, 0.1f, 0xffff0000},
157 { 0.0f, 0.0f, 0.1f, 0xffff0000},
158 { 0.0f, -1.0f, 0.1f, 0xffff0000},
160 struct vertex litquad[] =
162 {-1.0f, 0.0f, 0.1f, 0xff00ff00},
163 {-1.0f, 1.0f, 0.1f, 0xff00ff00},
164 { 0.0f, 1.0f, 0.1f, 0xff00ff00},
165 { 0.0f, 0.0f, 0.1f, 0xff00ff00},
167 struct nvertex unlitnquad[] =
169 { 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
170 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
171 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
172 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xff0000ff},
174 struct nvertex litnquad[] =
176 { 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
177 { 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
178 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
179 { 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0xffffff00},
181 WORD Indices[] = {0, 1, 2, 2, 3, 0};
183 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
184 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
186 /* Setup some states that may cause issues */
187 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), (D3DMATRIX *) mat);
188 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %s\n", DXGetErrorString9(hr));
189 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, (D3DMATRIX *)mat);
190 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %s\n", DXGetErrorString9(hr));
191 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, (D3DMATRIX *) mat);
192 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %s\n", DXGetErrorString9(hr));
193 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
194 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
195 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
196 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
197 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
198 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
199 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
200 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
201 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, FALSE);
202 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
203 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
204 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
205 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
206 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
207 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
208 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %s\n", DXGetErrorString9(hr));
209 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE);
210 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %s\n", DXGetErrorString9(hr));
212 hr = IDirect3DDevice9_SetFVF(device, fvf);
213 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
215 hr = IDirect3DDevice9_BeginScene(device);
216 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
217 if(hr == D3D_OK)
219 /* No lights are defined... That means, lit vertices should be entirely black */
220 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
221 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
222 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
223 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
224 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
226 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
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, litquad, sizeof(litquad[0]));
230 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
232 hr = IDirect3DDevice9_SetFVF(device, nfvf);
233 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
235 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
236 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
237 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
238 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
239 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
241 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
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, litnquad, sizeof(litnquad[0]));
245 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
247 IDirect3DDevice9_EndScene(device);
248 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
251 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
253 color = getPixelColor(device, 160, 360); /* lower left quad - unlit without normals */
254 ok(color == 0x00ff0000, "Unlit quad without normals has color %08x\n", color);
255 color = getPixelColor(device, 160, 120); /* upper left quad - lit without normals */
256 ok(color == 0x00000000, "Lit quad without normals has color %08x\n", color);
257 color = getPixelColor(device, 480, 360); /* lower left quad - unlit width normals */
258 ok(color == 0x000000ff, "Unlit quad width normals has color %08x\n", color);
259 color = getPixelColor(device, 480, 120); /* upper left quad - lit width normals */
260 ok(color == 0x00000000, "Lit quad width normals has color %08x\n", color);
262 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
263 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
266 static void clear_test(IDirect3DDevice9 *device)
268 /* Tests the correctness of clearing parameters */
269 HRESULT hr;
270 D3DRECT rect[2];
271 D3DRECT rect_negneg;
272 DWORD color;
274 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
275 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
277 /* Positive x, negative y */
278 rect[0].x1 = 0;
279 rect[0].y1 = 480;
280 rect[0].x2 = 320;
281 rect[0].y2 = 240;
283 /* Positive x, positive y */
284 rect[1].x1 = 0;
285 rect[1].y1 = 0;
286 rect[1].x2 = 320;
287 rect[1].y2 = 240;
288 /* Clear 2 rectangles with one call. Shows that a positive value is returned, but the negative rectangle
289 * is ignored, the positive is still cleared afterwards
291 hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
292 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
294 /* negative x, negative y */
295 rect_negneg.x1 = 640;
296 rect_negneg.x1 = 240;
297 rect_negneg.x2 = 320;
298 rect_negneg.y2 = 0;
299 hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
300 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %s\n", DXGetErrorString9(hr));
302 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
304 color = getPixelColor(device, 160, 360); /* lower left quad */
305 ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
306 color = getPixelColor(device, 160, 120); /* upper left quad */
307 ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
308 color = getPixelColor(device, 480, 360); /* lower right quad */
309 ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
310 color = getPixelColor(device, 480, 120); /* upper right quad */
311 ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
314 typedef struct {
315 float in[4];
316 DWORD out;
317 } test_data_t;
320 * c7 rounded ARGB
321 * -2.4 -2 0x00ffff00
322 * -1.6 -2 0x00ffff00
323 * -0.4 0 0x0000ffff
324 * 0.4 0 0x0000ffff
325 * 1.6 2 0x00ff00ff
326 * 2.4 2 0x00ff00ff
328 static void test_mova(IDirect3DDevice9 *device)
330 static const DWORD mova_test[] = {
331 0xfffe0200, /* vs_2_0 */
332 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
333 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
334 0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
335 0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
336 0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
337 0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
338 0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
339 0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
340 0x0200002e, 0xb0010000, 0xa0000007, /* mova a0.x, c7.x */
341 0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000, /* mov oD0, c[a0.x + 3] */
342 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
343 0x0000ffff /* END */
346 static const test_data_t test_data[] = {
347 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
348 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
349 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
350 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
351 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
352 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
355 static const float quad[][3] = {
356 {-1.0f, -1.0f, 0.0f},
357 {-1.0f, 1.0f, 0.0f},
358 { 1.0f, -1.0f, 0.0f},
359 { 1.0f, 1.0f, 0.0f},
362 static const D3DVERTEXELEMENT9 decl_elements[] = {
363 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
364 D3DDECL_END()
367 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
368 IDirect3DVertexShader9 *mova_shader = NULL;
369 HRESULT hr;
370 int i;
372 hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
373 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
374 hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
375 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
377 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
378 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
379 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
380 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
382 for (i = 0; i < (sizeof(test_data) / sizeof(test_data_t)); ++i)
384 DWORD color;
386 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[i].in, 1);
387 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
389 hr = IDirect3DDevice9_BeginScene(device);
390 ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
392 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
393 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
395 hr = IDirect3DDevice9_EndScene(device);
396 ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
398 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
399 ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
401 color = getPixelColor(device, 320, 240);
402 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]);
404 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
405 ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
408 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
409 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
411 IDirect3DVertexDeclaration9_Release(vertex_declaration);
412 IDirect3DVertexShader9_Release(mova_shader);
415 struct sVertex {
416 float x, y, z;
417 DWORD diffuse;
418 DWORD specular;
421 struct sVertexT {
422 float x, y, z, rhw;
423 DWORD diffuse;
424 DWORD specular;
427 static void fog_test(IDirect3DDevice9 *device)
429 HRESULT hr;
430 DWORD color;
431 float start = 0.0f, end = 1.0f;
432 D3DCAPS9 caps;
434 /* Gets full z based fog with linear fog, no fog with specular color */
435 struct sVertex unstransformed_1[] = {
436 {-1, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
437 {-1, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
438 { 0, 0, 0.1f, 0xFFFF0000, 0xFF000000 },
439 { 0, -1, 0.1f, 0xFFFF0000, 0xFF000000 },
441 /* Ok, I am too lazy to deal with transform matrices */
442 struct sVertex unstransformed_2[] = {
443 {-1, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
444 {-1, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
445 { 0, 1, 1.0f, 0xFFFF0000, 0xFF000000 },
446 { 0, 0, 1.0f, 0xFFFF0000, 0xFF000000 },
448 /* Untransformed ones. Give them a different diffuse color to make the test look
449 * nicer. It also makes making sure that they are drawn correctly easier.
451 struct sVertexT transformed_1[] = {
452 {320, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
453 {640, 0, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
454 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
455 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
457 struct sVertexT transformed_2[] = {
458 {320, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
459 {640, 240, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
460 {640, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
461 {320, 480, 1.0f, 1.0f, 0xFFFFFF00, 0xFF000000 },
463 WORD Indices[] = {0, 1, 2, 2, 3, 0};
465 memset(&caps, 0, sizeof(caps));
466 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
467 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %s\n", DXGetErrorString9(hr));
468 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
469 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
471 /* Setup initial states: No lighting, fog on, fog color */
472 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
473 ok(hr == D3D_OK, "Turning off lighting returned %s\n", DXGetErrorString9(hr));
474 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
475 ok(hr == D3D_OK, "Turning on fog calculations returned %s\n", DXGetErrorString9(hr));
476 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
477 ok(hr == D3D_OK, "Turning on fog calculations returned %s\n", DXGetErrorString9(hr));
479 /* First test: Both table fog and vertex fog off */
480 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
481 ok(hr == D3D_OK, "Turning off table fog returned %s\n", DXGetErrorString9(hr));
482 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
483 ok(hr == D3D_OK, "Turning off table fog returned %s\n", DXGetErrorString9(hr));
485 /* Start = 0, end = 1. Should be default, but set them */
486 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
487 ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
488 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
489 ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
491 if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
493 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
494 ok( hr == D3D_OK, "SetFVF returned %s\n", DXGetErrorString9(hr));
495 /* Untransformed, vertex fog = NONE, table fog = NONE: Read the fog weighting from the specular color */
496 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
497 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
498 sizeof(unstransformed_1[0]));
499 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
501 /* That makes it use the Z value */
502 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
503 ok(hr == D3D_OK, "Turning off table fog returned %s\n", DXGetErrorString9(hr));
504 /* Untransformed, vertex fog != none (or table fog != none):
505 * Use the Z value as input into the equation
507 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
508 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
509 sizeof(unstransformed_1[0]));
510 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
512 /* transformed verts */
513 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
514 ok( hr == D3D_OK, "SetFVF returned %s\n", DXGetErrorString9(hr));
515 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
516 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
517 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
518 sizeof(transformed_1[0]));
519 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
521 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
522 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %s\n", DXGetErrorString9(hr));
523 /* Transformed, table fog != none, vertex anything: Use Z value as input to the fog
524 * equation
526 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
527 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_2,
528 sizeof(transformed_2[0]));
530 hr = IDirect3DDevice9_EndScene(device);
531 ok(hr == D3D_OK, "EndScene returned %s\n", DXGetErrorString9(hr));
533 else
535 ok(FALSE, "BeginScene failed\n");
538 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
539 color = getPixelColor(device, 160, 360);
540 ok(color == 0x00FF0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
541 color = getPixelColor(device, 160, 120);
542 ok(color == 0x0000FF00, "Untransformed vertex with linear vertex fog has color %08x\n", color);
543 color = getPixelColor(device, 480, 120);
544 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
545 if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
547 color = getPixelColor(device, 480, 360);
548 ok(color == 0x0000FF00, "Transformed vertex with linear table fog has color %08x\n", color);
550 else
552 /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
553 * The settings above result in no fogging with vertex fog
555 color = getPixelColor(device, 480, 120);
556 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
557 trace("Info: Table fog not supported by this device\n");
560 /* Now test the special case fogstart == fogend */
561 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
562 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
564 if(IDirect3DDevice9_BeginScene(device) == D3D_OK)
566 start = 512;
567 end = 512;
568 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
569 ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
570 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
571 ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
573 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
574 ok( hr == D3D_OK, "SetFVF returned %s\n", DXGetErrorString9(hr));
575 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
576 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %s\n", DXGetErrorString9(hr));
577 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
578 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %s\n", DXGetErrorString9(hr));
580 /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512. Would result in
581 * a completely fog-free primitive because start > zcoord, but because start == end, the primitive
582 * is fully covered by fog. The same happens to the 2nd untransformed quad with z = 1.0.
583 * The third transformed quad remains unfogged because the fogcoords are read from the specular
584 * color and has fixed fogstart and fogend.
586 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
587 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_1,
588 sizeof(unstransformed_1[0]));
589 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
590 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
591 2 /*PrimCount */, Indices, D3DFMT_INDEX16, unstransformed_2,
592 sizeof(unstransformed_1[0]));
593 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
595 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
596 ok( hr == D3D_OK, "SetFVF returned %s\n", DXGetErrorString9(hr));
597 /* Transformed, vertex fog != NONE, pixel fog == NONE: Use specular color alpha component */
598 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
599 2 /*PrimCount */, Indices, D3DFMT_INDEX16, transformed_1,
600 sizeof(transformed_1[0]));
601 ok(hr == D3D_OK, "DrawIndexedPrimitiveUP returned %s\n", DXGetErrorString9(hr));
603 hr = IDirect3DDevice9_EndScene(device);
604 ok(hr == D3D_OK, "EndScene returned %s\n", DXGetErrorString9(hr));
606 else
608 ok(FALSE, "BeginScene failed\n");
610 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
611 color = getPixelColor(device, 160, 360);
612 ok(color == 0x0000FF00, "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
613 color = getPixelColor(device, 160, 120);
614 ok(color == 0x0000FF00, "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
615 color = getPixelColor(device, 480, 120);
616 ok(color == 0x00FFFF00, "Transformed vertex with linear vertex fog has color %08x\n", color);
618 /* Turn off the fog master switch to avoid confusing other tests */
619 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
620 ok(hr == D3D_OK, "Turning off fog calculations returned %s\n", DXGetErrorString9(hr));
621 start = 0.0;
622 end = 1.0;
623 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
624 ok(hr == D3D_OK, "Setting fog start returned %s\n", DXGetErrorString9(hr));
625 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
626 ok(hr == D3D_OK, "Setting fog end returned %s\n", DXGetErrorString9(hr));
627 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
628 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState %s\n", DXGetErrorString9(hr));
629 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
630 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %s\n", DXGetErrorString9(hr));
633 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
634 * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
635 * regardless of the actual addressing mode set. */
636 static void test_cube_wrap(IDirect3DDevice9 *device)
638 static const float quad[][6] = {
639 {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
640 {-1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
641 { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
642 { 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
645 static const D3DVERTEXELEMENT9 decl_elements[] = {
646 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
647 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
648 D3DDECL_END()
651 static const struct {
652 D3DTEXTUREADDRESS mode;
653 const char *name;
654 } address_modes[] = {
655 {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
656 {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
657 {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
658 {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
659 {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
662 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
663 IDirect3DCubeTexture9 *texture = NULL;
664 IDirect3DSurface9 *surface = NULL;
665 D3DLOCKED_RECT locked_rect;
666 HRESULT hr;
667 INT x, y, face;
669 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
670 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
671 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
672 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
674 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
675 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
676 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
678 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, D3DLOCK_DISCARD);
679 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
681 for (y = 0; y < 128; ++y)
683 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
684 for (x = 0; x < 64; ++x)
686 *ptr++ = 0xffff0000;
688 for (x = 64; x < 128; ++x)
690 *ptr++ = 0xff0000ff;
694 hr = IDirect3DSurface9_UnlockRect(surface);
695 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
697 hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
698 D3DPOOL_DEFAULT, &texture, NULL);
699 ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
701 /* Create cube faces */
702 for (face = 0; face < 6; ++face)
704 IDirect3DSurface9 *face_surface = NULL;
706 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
707 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
709 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
710 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
712 IDirect3DSurface9_Release(face_surface);
715 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
716 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
718 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
719 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
720 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
721 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
722 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
723 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
725 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
726 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
728 for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
730 DWORD color;
732 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
733 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
734 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
735 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
737 hr = IDirect3DDevice9_BeginScene(device);
738 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
740 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
741 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
743 hr = IDirect3DDevice9_EndScene(device);
744 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
746 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
747 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
749 /* Due to the nature of this test, we sample essentially at the edge
750 * between two faces. Because of this it's undefined from which face
751 * the driver will sample. Furtunately that's not important for this
752 * test, since all we care about is that it doesn't sample from the
753 * other side of the surface or from the border. */
754 color = getPixelColor(device, 320, 240);
755 ok(color == 0x00ff0000 || color == 0x000000ff,
756 "Got color 0x%08x for addressing mode %s, expected 0x00ff0000 or 0x000000ff.\n",
757 color, address_modes[x].name);
759 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
760 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
763 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
764 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
766 IDirect3DVertexDeclaration9_Release(vertex_declaration);
767 IDirect3DCubeTexture9_Release(texture);
768 IDirect3DSurface9_Release(surface);
771 static void offscreen_test(IDirect3DDevice9 *device)
773 HRESULT hr;
774 IDirect3DTexture9 *offscreenTexture = NULL;
775 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
776 DWORD color;
778 static const float quad[][5] = {
779 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
780 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
781 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
782 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
785 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
786 ok(hr == D3D_OK, "Clear failed, hr = %s\n", DXGetErrorString9(hr));
788 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
789 ok(hr == D3D_OK || D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %s\n", DXGetErrorString9(hr));
790 if(!offscreenTexture) {
791 trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
792 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
793 ok(hr == D3D_OK || D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %s\n", DXGetErrorString9(hr));
794 if(!offscreenTexture) {
795 skip("Cannot create an offscreen render target\n");
796 goto out;
800 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
801 ok(hr == D3D_OK, "Can't get back buffer, hr = %s\n", DXGetErrorString9(hr));
802 if(!backbuffer) {
803 goto out;
806 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
807 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %s\n", DXGetErrorString9(hr));
808 if(!offscreen) {
809 goto out;
812 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
813 ok(hr == D3D_OK, "SetFVF failed, hr = %s\n", DXGetErrorString9(hr));
815 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
816 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
817 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
818 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %s\n", DXGetErrorString9(hr));
819 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_NONE);
820 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
821 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_NONE);
822 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
823 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
824 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
826 if(IDirect3DDevice9_BeginScene(device) == D3D_OK) {
827 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
828 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %s\n", DXGetErrorString9(hr));
829 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
830 ok(hr == D3D_OK, "Clear failed, hr = %s\n", DXGetErrorString9(hr));
832 /* Draw without textures - Should resut in a white quad */
833 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
834 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %s\n", DXGetErrorString9(hr));
836 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
837 ok(hr == D3D_OK, "SetRenderTarget failed, hr = %s\n", DXGetErrorString9(hr));
838 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
839 ok(hr == D3D_OK, "SetTexture failed, %s\n", DXGetErrorString9(hr));
841 /* This time with the texture */
842 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
843 ok(hr == D3D_OK, "DrawPrimitiveUP failed, hr = %s\n", DXGetErrorString9(hr));
845 IDirect3DDevice9_EndScene(device);
848 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
850 /* Center quad - should be white */
851 color = getPixelColor(device, 320, 240);
852 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
853 /* Some quad in the cleared part of the texture */
854 color = getPixelColor(device, 170, 240);
855 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
856 /* Part of the originally cleared back buffer */
857 color = getPixelColor(device, 10, 10);
858 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
859 if(0) {
860 /* Lower left corner of the screen, where back buffer offscreen rendering draws the offscreen texture.
861 * It should be red, but the offscreen texture may leave some junk there. Not tested yet. Depending on
862 * the offscreen rendering mode this test would succeed or fail
864 color = getPixelColor(device, 10, 470);
865 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
868 out:
869 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
871 /* restore things */
872 if(backbuffer) {
873 IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
874 IDirect3DSurface9_Release(backbuffer);
876 if(offscreenTexture) {
877 IDirect3DTexture9_Release(offscreenTexture);
879 if(offscreen) {
880 IDirect3DSurface9_Release(offscreen);
884 /* This test tests fog in combination with shaders.
885 * What's tested: linear fog (vertex and table) with pixel shader
886 * linear table fog with non foggy vertex shader
887 * vertex fog with foggy vertex shader
888 * What's not tested: non linear fog with shader
889 * table fog with foggy vertex shader
891 static void fog_with_shader_test(IDirect3DDevice9 *device)
893 HRESULT hr;
894 DWORD color;
895 union {
896 float f;
897 DWORD i;
898 } start, end;
899 unsigned int i, j;
901 /* basic vertex shader without fog computation ("non foggy") */
902 static const DWORD vertex_shader_code1[] = {
903 0xfffe0101, /* vs_1_1 */
904 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
905 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
906 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
907 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
908 0x0000ffff
910 /* basic vertex shader with reversed fog computation ("foggy") */
911 static const DWORD vertex_shader_code2[] = {
912 0xfffe0101, /* vs_1_1 */
913 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
914 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
915 0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
916 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
917 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
918 0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
919 0x00000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
920 0x0000ffff
922 /* basic pixel shader */
923 static const DWORD pixel_shader_code[] = {
924 0xffff0101, /* ps_1_1 */
925 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, vo */
926 0x0000ffff
929 static struct vertex quad[] = {
930 {-1.0f, -1.0f, 0.0f, 0xFFFF0000 },
931 {-1.0f, 1.0f, 0.0f, 0xFFFF0000 },
932 { 1.0f, -1.0f, 0.0f, 0xFFFF0000 },
933 { 1.0f, 1.0f, 0.0f, 0xFFFF0000 },
936 static const D3DVERTEXELEMENT9 decl_elements[] = {
937 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
938 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
939 D3DDECL_END()
942 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
943 IDirect3DVertexShader9 *vertex_shader[3] = {NULL, NULL, NULL};
944 IDirect3DPixelShader9 *pixel_shader[2] = {NULL, NULL};
946 /* This reference data was collected on a nVidia GeForce 7600GS driver version 84.19 DirectX version 9.0c on Windows XP */
947 static const struct test_data_t {
948 int vshader;
949 int pshader;
950 D3DFOGMODE vfog;
951 D3DFOGMODE tfog;
952 unsigned int color[11];
953 } test_data[] = {
954 /* only pixel shader: */
955 {0, 1, 0, 3,
956 {0x0000ff00, 0x0000ff00, 0x0020df00, 0x0040bf00, 0x005fa000, 0x007f8000,
957 0x009f6000, 0x00bf4000, 0x00df2000, 0x00ff0000, 0x00ff0000}},
958 {0, 1, 1, 3,
959 {0x0000ff00, 0x0000ff00, 0x0020df00, 0x0040bf00, 0x005fa000, 0x007f8000,
960 0x009f6000, 0x00bf4000, 0x00df2000, 0x00ff0000, 0x00ff0000}},
961 {0, 1, 2, 3,
962 {0x0000ff00, 0x0000ff00, 0x0020df00, 0x0040bf00, 0x005fa000, 0x007f8000,
963 0x009f6000, 0x00bf4000, 0x00df2000, 0x00ff0000, 0x00ff0000}},
964 {0, 1, 3, 0,
965 {0x0000ff00, 0x0000ff00, 0x0020df00, 0x0040bf00, 0x005fa000, 0x007f8000,
966 0x009f6000, 0x00bf4000, 0x00df2000, 0x00ff0000, 0x00ff0000}},
967 {0, 1, 3, 3,
968 {0x0000ff00, 0x0000ff00, 0x0020df00, 0x0040bf00, 0x005fa000, 0x007f8000,
969 0x009f6000, 0x00bf4000, 0x00df2000, 0x00ff0000, 0x00ff0000}},
971 /* vertex shader */
972 {1, 0, 0, 0,
973 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
974 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
975 {1, 0, 0, 3,
976 {0x0000ff00, 0x0000ff00, 0x0020df00, 0x0040bf00, 0x005fa000, 0x007f8000,
977 0x009f6000, 0x00bf4000, 0x00df2000, 0x00ff0000, 0x00ff0000}},
978 {1, 0, 1, 3,
979 {0x0000ff00, 0x0000ff00, 0x0020df00, 0x0040bf00, 0x005fa000, 0x007f8000,
980 0x009f6000, 0x00bf4000, 0x00df2000, 0x00ff0000, 0x00ff0000}},
981 {1, 0, 2, 3,
982 {0x0000ff00, 0x0000ff00, 0x0020df00, 0x0040bf00, 0x005fa000, 0x007f8000,
983 0x009f6000, 0x00bf4000, 0x00df2000, 0x00ff0000, 0x00ff0000}},
984 {1, 0, 3, 3,
985 {0x0000ff00, 0x0000ff00, 0x0020df00, 0x0040bf00, 0x005fa000, 0x007f8000,
986 0x009f6000, 0x00bf4000, 0x00df2000, 0x00ff0000, 0x00ff0000}},
988 /* vertex shader and pixel shader */
989 {1, 1, 0, 3,
990 {0x0000ff00, 0x0000ff00, 0x0020df00, 0x0040bf00, 0x005fa000, 0x007f8000,
991 0x009f6000, 0x00bf4000, 0x00df2000, 0x00ff0000, 0x00ff0000}},
992 {1, 1, 1, 3,
993 {0x0000ff00, 0x0000ff00, 0x0020df00, 0x0040bf00, 0x005fa000, 0x007f8000,
994 0x009f6000, 0x00bf4000, 0x00df2000, 0x00ff0000, 0x00ff0000}},
995 {1, 1, 2, 3,
996 {0x0000ff00, 0x0000ff00, 0x0020df00, 0x0040bf00, 0x005fa000, 0x007f8000,
997 0x009f6000, 0x00bf4000, 0x00df2000, 0x00ff0000, 0x00ff0000}},
998 {1, 1, 3, 3,
999 {0x0000ff00, 0x0000ff00, 0x0020df00, 0x0040bf00, 0x005fa000, 0x007f8000,
1000 0x009f6000, 0x00bf4000, 0x00df2000, 0x00ff0000, 0x00ff0000}},
1002 #if 0 /* FIXME: these fail on GeForce 8500 */
1003 /* foggy vertex shader */
1004 {2, 0, 0, 0,
1005 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1006 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1007 {2, 0, 1, 0,
1008 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1009 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1010 {2, 0, 2, 0,
1011 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1012 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1013 {2, 0, 3, 0,
1014 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1015 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1016 #endif
1018 /* foggy vertex shader and pixel shader */
1019 {2, 1, 0, 0,
1020 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1021 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1022 {2, 1, 1, 0,
1023 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1024 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1025 {2, 1, 2, 0,
1026 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1027 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1028 {2, 1, 3, 0,
1029 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1030 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1034 /* NOTE: changing these values will not affect the tests with foggy vertex shader, as the values are hardcoded in the shader*/
1035 start.f=0.9f;
1036 end.f=0.1f;
1038 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
1039 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1040 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
1041 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1042 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1043 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1044 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1045 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1047 /* Setup initial states: No lighting, fog on, fog color */
1048 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1049 ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1050 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1051 ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1052 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1053 ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1054 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1055 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1057 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1058 ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1059 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1060 ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1062 /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
1063 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
1064 ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1065 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
1066 ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1068 for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
1070 hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1071 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1072 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1073 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1074 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1075 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1076 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1077 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1079 for(j=0; j < 11; j++)
1081 /* Don't use the whole zrange to prevent rounding errors */
1082 quad[0].z = 0.001f + (float)j / 10.02f;
1083 quad[1].z = 0.001f + (float)j / 10.02f;
1084 quad[2].z = 0.001f + (float)j / 10.02f;
1085 quad[3].z = 0.001f + (float)j / 10.02f;
1087 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1088 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1090 hr = IDirect3DDevice9_BeginScene(device);
1091 ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1093 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1094 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1096 hr = IDirect3DDevice9_EndScene(device);
1097 ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1099 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1101 /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1102 color = getPixelColor(device, 128, 240);
1103 ok((unsigned char)(color) == ((unsigned char)test_data[i].color[j])
1104 && abs( ((unsigned char)(color>>8)) - (unsigned char)(test_data[i].color[j]>>8) ) < 13
1105 && abs( ((unsigned char)(color>>16)) - (unsigned char)(test_data[i].color[j]>>16) ) < 13,
1106 "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]);
1110 /* reset states */
1111 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1112 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1113 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1114 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1115 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1116 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1117 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1118 ok(hr == D3D_OK, "Turning off fog calculations failed (%08x)\n", hr);
1120 IDirect3DVertexShader9_Release(vertex_shader[1]);
1121 IDirect3DVertexShader9_Release(vertex_shader[2]);
1122 IDirect3DPixelShader9_Release(pixel_shader[1]);
1123 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1126 /* test the behavior of the texbem instruction
1127 * with normal 2D and projective 2D textures
1129 static void texbem_test(IDirect3DDevice9 *device)
1131 HRESULT hr;
1132 DWORD color;
1133 unsigned int i, x, y;
1135 static const DWORD pixel_shader_code[] = {
1136 0xffff0101, /* ps_1_1*/
1137 0x00000042, 0xb00f0000, /* tex t0*/
1138 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
1139 0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
1140 0x0000ffff
1143 static const float quad[][7] = {
1144 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
1145 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
1146 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
1147 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
1149 static const float quad_proj[][9] = {
1150 {-128.0f/640.0f, -128.0f/480.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 128.0f},
1151 {-128.0f/640.0f, 128.0f/480.0f, 0.1f, 0.0f, 1.0f, 0.0f, 128.0f, 0.0f, 128.0f},
1152 { 128.0f/640.0f, -128.0f/480.0f, 0.1f, 1.0f, 0.0f, 128.0f, 0.0f, 0.0f, 128.0f},
1153 { 128.0f/640.0f, 128.0f/480.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
1156 static const D3DVERTEXELEMENT9 decl_elements[][4] = { {
1157 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1158 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1159 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1160 D3DDECL_END()
1162 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1163 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1164 {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
1165 D3DDECL_END()
1166 } };
1168 /* use assymetric matrix to test loading */
1169 float bumpenvmat[4] = {0.0,0.5,-0.5,0.0};
1171 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
1172 IDirect3DPixelShader9 *pixel_shader = NULL;
1173 IDirect3DTexture9 *texture[2] = {NULL, NULL};
1174 D3DLOCKED_RECT locked_rect;
1176 /* Generate the textures */
1177 for(i=0; i<2; i++)
1179 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
1180 D3DPOOL_MANAGED, &texture[i], NULL);
1181 ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
1183 hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, D3DLOCK_DISCARD);
1184 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
1185 for (y = 0; y < 128; ++y)
1187 if(i)
1188 { /* Set up black texture with 2x2 texel white spot in the middle */
1189 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1190 for (x = 0; x < 128; ++x)
1192 if(y>62 && y<66 && x>62 && x<66)
1193 *ptr++ = 0xffffffff;
1194 else
1195 *ptr++ = 0xff000000;
1198 else
1199 { /* Set up a displacement map which points away from the center parallel to the closest axis.
1200 * (if multiplied with bumpenvmat)
1202 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
1203 for (x = 0; x < 128; ++x)
1205 if(abs(x-64)>abs(y-64))
1207 if(x < 64)
1208 *ptr++ = 0xc000;
1209 else
1210 *ptr++ = 0x4000;
1212 else
1214 if(y < 64)
1215 *ptr++ = 0x0040;
1216 else
1217 *ptr++ = 0x00c0;
1222 hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
1223 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
1225 hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
1226 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1228 /* Disable texture filtering */
1229 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1230 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
1231 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1232 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
1234 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1235 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
1236 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1237 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
1240 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
1241 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
1242 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
1243 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
1244 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
1246 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
1247 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1249 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1250 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1252 for(i=0; i<2; i++)
1254 if(i)
1256 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
1257 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1260 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
1261 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
1262 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1263 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
1265 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
1266 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1267 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
1268 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1270 hr = IDirect3DDevice9_BeginScene(device);
1271 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
1273 if(!i)
1274 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1275 else
1276 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
1277 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
1279 hr = IDirect3DDevice9_EndScene(device);
1280 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
1282 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1283 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1285 color = getPixelColor(device, 320-32, 240);
1286 ok(color == 0x00ffffff, "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1287 color = getPixelColor(device, 320+32, 240);
1288 ok(color == 0x00ffffff, "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1289 color = getPixelColor(device, 320, 240-32);
1290 ok(color == 0x00ffffff, "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1291 color = getPixelColor(device, 320, 240+32);
1292 ok(color == 0x00ffffff, "texbem failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1294 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
1295 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1296 IDirect3DPixelShader9_Release(pixel_shader);
1298 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
1299 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1300 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1303 /* clean up */
1304 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1305 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
1307 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
1308 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
1310 for(i=0; i<2; i++)
1312 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
1313 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
1314 IDirect3DCubeTexture9_Release(texture[i]);
1318 static void present_test(IDirect3DDevice9 *device)
1320 struct vertex quad[] =
1322 {-1.0f, -1.0f, 0.9f, 0xffff0000},
1323 {-1.0f, 1.0f, 0.9f, 0xffff0000},
1324 { 1.0f, -1.0f, 0.1f, 0xffff0000},
1325 { 1.0f, 1.0f, 0.1f, 0xffff0000},
1327 HRESULT hr;
1328 DWORD color;
1330 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
1331 * then call Present. Then clear the color buffer to make sure it has some defined content
1332 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
1333 * by the depth value.
1335 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75, 0);
1336 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
1337 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1338 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.4, 0);
1340 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
1341 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1342 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
1343 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1344 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1345 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %s\n", DXGetErrorString9(hr));
1347 hr = IDirect3DDevice9_BeginScene(device);
1348 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
1349 if(hr == D3D_OK)
1351 /* No lights are defined... That means, lit vertices should be entirely black */
1352 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2 /*PrimCount */, quad, sizeof(quad[0]));
1353 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitiveUP failed with %s\n", DXGetErrorString9(hr));
1355 hr = IDirect3DDevice9_EndScene(device);
1356 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
1359 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
1360 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %s\n", DXGetErrorString9(hr));
1362 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1363 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1364 color = getPixelColor(device, 512, 240);
1365 ok(color == 0x00ffffff, "Present failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
1366 color = getPixelColor(device, 64, 240);
1367 ok(color == 0x00ff0000, "Present failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
1370 static void fill_surface(IDirect3DSurface9 *surface, DWORD color)
1372 D3DSURFACE_DESC desc;
1373 D3DLOCKED_RECT l;
1374 HRESULT hr;
1375 unsigned int x, y;
1376 DWORD *mem;
1378 memset(&desc, 0, sizeof(desc));
1379 memset(&l, 0, sizeof(l));
1380 hr = IDirect3DSurface9_GetDesc(surface, &desc);
1381 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %s\n", DXGetErrorString9(hr));
1382 hr = IDirect3DSurface9_LockRect(surface, &l, NULL, D3DLOCK_DISCARD);
1383 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %s\n", DXGetErrorString9(hr));
1384 if(FAILED(hr)) return;
1386 for(y = 0; y < desc.Height; y++)
1388 mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
1389 for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
1391 mem[x] = color;
1394 hr = IDirect3DSurface9_UnlockRect(surface);
1395 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %s\n", DXGetErrorString9(hr));
1398 static void maxmip_test(IDirect3DDevice9 *device)
1400 IDirect3DTexture9 *texture = NULL;
1401 IDirect3DSurface9 *surface = NULL;
1402 HRESULT hr;
1403 DWORD color;
1404 const float quads[] = {
1405 -1.0, -1.0, 0.0, 0.0, 0.0,
1406 -1.0, 0.0, 0.0, 0.0, 1.0,
1407 0.0, -1.0, 0.0, 1.0, 0.0,
1408 0.0, 0.0, 0.0, 1.0, 1.0,
1410 0.0, -1.0, 0.0, 0.0, 0.0,
1411 0.0, 0.0, 0.0, 0.0, 1.0,
1412 1.0, -1.0, 0.0, 1.0, 0.0,
1413 1.0, 0.0, 0.0, 1.0, 1.0,
1415 0.0, 0.0, 0.0, 0.0, 0.0,
1416 0.0, 1.0, 0.0, 0.0, 1.0,
1417 1.0, 0.0, 0.0, 1.0, 0.0,
1418 1.0, 1.0, 0.0, 1.0, 1.0,
1420 -1.0, 0.0, 0.0, 0.0, 0.0,
1421 -1.0, 1.0, 0.0, 0.0, 1.0,
1422 0.0, 0.0, 0.0, 1.0, 0.0,
1423 0.0, 1.0, 0.0, 1.0, 1.0,
1426 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
1427 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
1429 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
1430 &texture, NULL);
1431 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
1432 if(!texture)
1434 skip("Failed to create test texture\n");
1435 return;
1438 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
1439 fill_surface(surface, 0xffff0000);
1440 IDirect3DSurface9_Release(surface);
1441 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
1442 fill_surface(surface, 0xff00ff00);
1443 IDirect3DSurface9_Release(surface);
1444 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
1445 fill_surface(surface, 0xff0000ff);
1446 IDirect3DSurface9_Release(surface);
1448 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
1449 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
1450 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1451 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
1453 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
1454 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
1456 hr = IDirect3DDevice9_BeginScene(device);
1457 if(SUCCEEDED(hr))
1459 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
1460 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
1461 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
1462 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1464 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
1465 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
1466 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
1467 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1469 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
1470 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
1471 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
1472 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1474 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
1475 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
1476 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
1477 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1478 hr = IDirect3DDevice9_EndScene(device);
1481 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1482 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1483 /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
1484 color = getPixelColor(device, 160, 360);
1485 ok(color == 0x00FF0000, "MapMip 0, no mipfilter has color %08x\n", color);
1486 color = getPixelColor(device, 160, 120);
1487 ok(color == 0x00FF0000, "MapMip 3, no mipfilter has color %08x\n", color);
1488 color = getPixelColor(device, 480, 120);
1489 ok(color == 0x00FF0000, "MapMip 2, no mipfilter has color %08x\n", color);
1490 color = getPixelColor(device, 480, 360);
1491 ok(color == 0x00FF0000, "MapMip 1, no mipfilter has color %08x\n", color);
1493 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
1494 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
1496 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
1497 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
1499 hr = IDirect3DDevice9_BeginScene(device);
1500 if(SUCCEEDED(hr))
1502 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
1503 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
1504 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[ 0], 5 * sizeof(float));
1505 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1507 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
1508 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
1509 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[20], 5 * sizeof(float));
1510 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1512 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
1513 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
1514 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[40], 5 * sizeof(float));
1515 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1517 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
1518 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
1519 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[60], 5 * sizeof(float));
1520 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1521 hr = IDirect3DDevice9_EndScene(device);
1524 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
1525 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
1526 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
1527 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
1529 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1530 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
1531 /* Max Mip level 0-2 sample from the specified texture level, Max Mip level 3(> levels in texture)
1532 * samples from the highest level in the texture(level 2)
1534 color = getPixelColor(device, 160, 360);
1535 ok(color == 0x00FF0000, "MapMip 0, point mipfilter has color %08x\n", color);
1536 color = getPixelColor(device, 160, 120);
1537 ok(color == 0x000000FF, "MapMip 3, point mipfilter has color %08x\n", color);
1538 color = getPixelColor(device, 480, 120);
1539 ok(color == 0x000000FF, "MapMip 2, point mipfilter has color %08x\n", color);
1540 color = getPixelColor(device, 480, 360);
1541 ok(color == 0x0000FF00, "MapMip 1, point mipfilter has color %08x\n", color);
1543 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1544 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
1545 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
1546 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %s\n", DXGetErrorString9(hr));
1547 IDirect3DTexture9_Release(texture);
1550 static void release_buffer_test(IDirect3DDevice9 *device)
1552 IDirect3DVertexBuffer9 *vb = NULL;
1553 IDirect3DIndexBuffer9 *ib = NULL;
1554 HRESULT hr;
1555 BYTE *data;
1556 long ref;
1558 static const struct vertex quad[] = {
1559 {-1.0, -1.0, 0.1, 0xffff0000},
1560 {-1.0, 1.0, 0.1, 0xffff0000},
1561 { 1.0, 1.0, 0.1, 0xffff0000},
1563 {-1.0, -1.0, 0.1, 0xff00ff00},
1564 {-1.0, 1.0, 0.1, 0xff00ff00},
1565 { 1.0, 1.0, 0.1, 0xff00ff00}
1567 short indices[] = {3, 4, 5};
1569 /* Index and vertex buffers should always be creatable */
1570 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, D3DFVF_XYZ | D3DFVF_DIFFUSE,
1571 D3DPOOL_MANAGED, &vb, NULL);
1572 ok(hr == D3D_OK, "CreateVertexBuffer failed with %s\n", DXGetErrorString9(hr));
1573 if(!vb) {
1574 skip("Failed to create a vertex buffer\n");
1575 return;
1577 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
1578 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %s\n", DXGetErrorString9(hr));
1579 if(!ib) {
1580 skip("Failed to create an index buffer\n");
1581 return;
1584 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
1585 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
1586 memcpy(data, quad, sizeof(quad));
1587 hr = IDirect3DVertexBuffer9_Unlock(vb);
1588 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
1590 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
1591 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %s\n", DXGetErrorString9(hr));
1592 memcpy(data, indices, sizeof(indices));
1593 hr = IDirect3DIndexBuffer9_Unlock(ib);
1594 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %s\n", DXGetErrorString9(hr));
1596 hr = IDirect3DDevice9_SetIndices(device, ib);
1597 ok(hr == D3D_OK, "IDirect3DIndexBuffer8_Unlock failed with %s\n", DXGetErrorString9(hr));
1598 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
1599 ok(hr == D3D_OK, "IDirect3DIndexBuffer8_Unlock failed with %s\n", DXGetErrorString9(hr));
1600 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1601 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
1603 /* Now destroy the bound index buffer and draw again */
1604 ref = IDirect3DIndexBuffer9_Release(ib);
1605 ok(ref == 0, "Index Buffer reference count is %08ld\n", ref);
1607 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
1608 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1610 hr = IDirect3DDevice9_BeginScene(device);
1611 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
1612 if(SUCCEEDED(hr))
1614 /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent d3d from
1615 * making assumptions about the indices or vertices
1617 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
1618 ok(hr == D3D_OK, "IDirect3DDevice9_DrawIndexedPrimitive failed with %08x\n", hr);
1619 hr = IDirect3DDevice9_EndScene(device);
1620 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
1623 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1624 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
1626 hr = IDirect3DDevice9_SetIndices(device, NULL);
1627 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
1628 hr = IDirect3DDevice9_SetStreamSource(device, 0, NULL, 0, 0);
1629 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
1631 /* Index buffer was already destroyed as part of the test */
1632 IDirect3DVertexBuffer9_Release(vb);
1635 static void float_texture_test(IDirect3DDevice9 *device)
1637 IDirect3D9 *d3d = NULL;
1638 HRESULT hr;
1639 IDirect3DTexture9 *texture = NULL;
1640 D3DLOCKED_RECT lr;
1641 float *data;
1642 DWORD color;
1643 float quad[] = {
1644 -1.0, -1.0, 0.1, 0.0, 0.0,
1645 -1.0, 1.0, 0.1, 0.0, 1.0,
1646 1.0, -1.0, 0.1, 1.0, 0.0,
1647 1.0, 1.0, 0.1, 1.0, 1.0,
1650 memset(&lr, 0, sizeof(lr));
1651 IDirect3DDevice9_GetDirect3D(device, &d3d);
1652 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
1653 D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK) {
1654 skip("D3DFMT_R32F textures not supported\n");
1655 goto out;
1658 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F,
1659 D3DPOOL_MANAGED, &texture, NULL);
1660 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr));
1661 if(!texture) {
1662 skip("Failed to create R32F texture\n");
1663 goto out;
1666 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
1667 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %s\n", DXGetErrorString9(hr));
1668 data = lr.pBits;
1669 *data = 0.0;
1670 hr = IDirect3DTexture9_UnlockRect(texture, 0);
1671 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %s\n", DXGetErrorString9(hr));
1673 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
1674 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
1676 hr = IDirect3DDevice9_BeginScene(device);
1677 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
1678 if(SUCCEEDED(hr))
1680 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1681 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
1683 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
1684 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1686 hr = IDirect3DDevice9_EndScene(device);
1687 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
1689 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
1690 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %s\n", DXGetErrorString9(hr));
1692 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1693 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
1695 color = getPixelColor(device, 240, 320);
1696 ok(color == 0x0000FFFF, "R32F with value 0.0 has color %08x, expected 0x0000FFFF\n", color);
1698 out:
1699 if(texture) IDirect3DTexture9_Release(texture);
1700 IDirect3D9_Release(d3d);
1703 static void texture_transform_flags_test(IDirect3DDevice9 *device)
1705 HRESULT hr;
1706 IDirect3D9 *d3d;
1707 D3DFORMAT fmt = D3DFMT_X8R8G8B8;
1708 D3DCAPS9 caps;
1709 IDirect3DTexture9 *texture = NULL;
1710 IDirect3DVolumeTexture9 *volume = NULL;
1711 unsigned int x, y, z;
1712 D3DLOCKED_RECT lr;
1713 D3DLOCKED_BOX lb;
1714 DWORD color;
1715 IDirect3DVertexDeclaration9 *decl, *decl2;
1716 float identity[16] = {1.0, 0.0, 0.0, 0.0,
1717 0.0, 1.0, 0.0, 0.0,
1718 0.0, 0.0, 1.0, 0.0,
1719 0.0, 0.0, 0.0, 1.0};
1720 static const D3DVERTEXELEMENT9 decl_elements[] = {
1721 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1722 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1723 D3DDECL_END()
1725 static const D3DVERTEXELEMENT9 decl_elements2[] = {
1726 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1727 {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
1728 D3DDECL_END()
1731 memset(&lr, 0, sizeof(lr));
1732 memset(&lb, 0, sizeof(lb));
1733 IDirect3DDevice9_GetDirect3D(device, &d3d);
1734 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
1735 D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK) {
1736 fmt = D3DFMT_A16B16G16R16;
1738 IDirect3D9_Release(d3d);
1740 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
1741 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
1742 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
1743 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %s\n", DXGetErrorString9(hr));
1744 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
1745 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %s\n", DXGetErrorString9(hr));
1746 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
1747 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %s\n", DXGetErrorString9(hr));
1748 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
1749 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %s\n", DXGetErrorString9(hr));
1750 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
1751 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %s\n", DXGetErrorString9(hr));
1752 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
1753 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %s\n", DXGetErrorString9(hr));
1754 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
1755 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %s\n", DXGetErrorString9(hr));
1756 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
1757 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %s\n", DXGetErrorString9(hr));
1758 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1759 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %s\n", DXGetErrorString9(hr));
1760 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
1761 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
1763 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
1764 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %s\n", DXGetErrorString9(hr));
1765 hr = IDirect3DDevice9_CreateTexture(device, caps.MaxTextureWidth, caps.MaxTextureHeight, 1,
1766 0, fmt, D3DPOOL_MANAGED, &texture, NULL);
1767 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %s\n", DXGetErrorString9(hr));
1768 if(!texture) {
1769 skip("Failed to create the test texture\n");
1770 return;
1773 /* Unfortunately there is no easy way to set up a texture coordinate passthrough
1774 * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
1775 * 1.0 in red and green for the x and y coords
1777 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
1778 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %s\n", DXGetErrorString9(hr));
1779 for(y = 0; y < caps.MaxTextureHeight; y++) {
1780 for(x = 0; x < caps.MaxTextureWidth; x++) {
1781 double r_f = (double) y / (double) caps.MaxTextureHeight;
1782 double g_f = (double) x / (double) caps.MaxTextureWidth;
1783 if(fmt == D3DFMT_A16B16G16R16) {
1784 unsigned short r, g;
1785 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
1786 r = (unsigned short) (r_f * 65536.0);
1787 g = (unsigned short) (g_f * 65536.0);
1788 dst[0] = r;
1789 dst[1] = g;
1790 dst[2] = 0;
1791 dst[3] = 65535;
1792 } else {
1793 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
1794 unsigned char r = (unsigned char) (r_f * 255.0);
1795 unsigned char g = (unsigned char) (g_f * 255.0);
1796 dst[0] = 0;
1797 dst[1] = g;
1798 dst[2] = r;
1799 dst[3] = 255;
1803 hr = IDirect3DTexture9_UnlockRect(texture, 0);
1804 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %s\n", DXGetErrorString9(hr));
1805 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
1806 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
1808 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1809 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
1810 hr = IDirect3DDevice9_BeginScene(device);
1811 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
1812 if(SUCCEEDED(hr))
1814 float quad1[] = {
1815 -1.0, -1.0, 0.1, 1.0, 1.0,
1816 -1.0, 0.0, 0.1, 1.0, 1.0,
1817 0.0, -1.0, 0.1, 1.0, 1.0,
1818 0.0, 0.0, 0.1, 1.0, 1.0,
1820 float quad2[] = {
1821 -1.0, 0.0, 0.1, 1.0, 1.0,
1822 -1.0, 1.0, 0.1, 1.0, 1.0,
1823 0.0, 0.0, 0.1, 1.0, 1.0,
1824 0.0, 1.0, 0.1, 1.0, 1.0,
1826 float quad3[] = {
1827 0.0, 0.0, 0.1, 0.5, 0.5,
1828 0.0, 1.0, 0.1, 0.5, 0.5,
1829 1.0, 0.0, 0.1, 0.5, 0.5,
1830 1.0, 1.0, 0.1, 0.5, 0.5,
1832 float quad4[] = {
1833 320, 480, 0.1, 1.0, 0.0, 1.0,
1834 320, 240, 0.1, 1.0, 0.0, 1.0,
1835 640, 480, 0.1, 1.0, 0.0, 1.0,
1836 640, 240, 0.1, 1.0, 0.0, 1.0,
1838 float mat[16] = {0.0, 0.0, 0.0, 0.0,
1839 0.0, 0.0, 0.0, 0.0,
1840 0.0, 0.0, 0.0, 0.0,
1841 0.0, 0.0, 0.0, 0.0};
1843 /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
1844 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
1845 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
1846 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
1847 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1849 /* What happens with transforms enabled? */
1850 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
1851 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
1852 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
1853 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1855 /* What happens if 4 coords are used, but only 2 given ?*/
1856 mat[8] = 1.0;
1857 mat[13] = 1.0;
1858 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
1859 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
1860 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
1861 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
1862 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
1863 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1865 /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
1866 * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
1867 * due to the coords in the vertices. (turns out red, indeed)
1869 memset(mat, 0, sizeof(mat));
1870 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
1871 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
1872 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
1873 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
1874 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
1875 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
1876 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
1877 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1879 hr = IDirect3DDevice9_EndScene(device);
1880 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
1882 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1883 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
1884 color = getPixelColor(device, 160, 360);
1885 ok(color == 0x00FFFF00 || color == 0x00FEFE00, "quad 1 has color %08x, expected 0x00FFFF00\n", color);
1886 color = getPixelColor(device, 160, 120);
1887 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
1888 color = getPixelColor(device, 480, 120);
1889 ok(color == 0x0000FF00 || color == 0x0000FE00, "quad 3 has color %08x, expected 0x0000FF00\n", color);
1890 color = getPixelColor(device, 480, 360);
1891 ok(color == 0x00FF0000 || 0x00FE0000, "quad 4 has color %08x, expected 0x00FF0000\n", color);
1893 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
1894 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
1896 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
1897 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
1898 hr = IDirect3DDevice9_BeginScene(device);
1899 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
1900 if(SUCCEEDED(hr))
1902 float quad1[] = {
1903 -1.0, -1.0, 0.1, 0.8, 0.2,
1904 -1.0, 0.0, 0.1, 0.8, 0.2,
1905 0.0, -1.0, 0.1, 0.8, 0.2,
1906 0.0, 0.0, 0.1, 0.8, 0.2,
1908 float quad2[] = {
1909 -1.0, 0.0, 0.1, 0.5, 1.0,
1910 -1.0, 1.0, 0.1, 0.5, 1.0,
1911 0.0, 0.0, 0.1, 0.5, 1.0,
1912 0.0, 1.0, 0.1, 0.5, 1.0,
1914 float quad3[] = {
1915 0.0, 0.0, 0.1, 0.5, 1.0,
1916 0.0, 1.0, 0.1, 0.5, 1.0,
1917 1.0, 0.0, 0.1, 0.5, 1.0,
1918 1.0, 1.0, 0.1, 0.5, 1.0,
1920 float quad4[] = {
1921 0.0, -1.0, 0.1, 0.8, 0.2,
1922 0.0, 0.0, 0.1, 0.8, 0.2,
1923 1.0, -1.0, 0.1, 0.8, 0.2,
1924 1.0, 0.0, 0.1, 0.8, 0.2,
1926 float mat[16] = {0.0, 0.0, 0.0, 0.0,
1927 0.0, 0.0, 0.0, 0.0,
1928 0.0, 1.0, 0.0, 0.0,
1929 0.0, 0.0, 0.0, 0.0};
1931 /* What happens to the default 1 in the 3rd coordinate if it is disabled?
1933 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
1934 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
1935 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
1936 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
1938 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
1939 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1941 /* What does this mean? Not sure... */
1942 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
1943 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
1944 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
1945 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1947 /* Just to be sure, the same as quad2 above */
1948 memset(mat, 0, sizeof(mat));
1949 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &mat);
1950 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
1951 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
1952 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
1953 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
1954 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1956 /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
1957 * used? And what happens to the first?
1959 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
1960 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
1961 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
1962 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1964 hr = IDirect3DDevice9_EndScene(device);
1965 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
1967 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1968 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
1969 color = getPixelColor(device, 160, 360);
1970 ok(color == 0x00FF0000 || color == 0x00FE0000, "quad 1 has color %08x, expected 0x00FF0000\n", color);
1971 color = getPixelColor(device, 160, 120);
1972 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
1973 color = getPixelColor(device, 480, 120);
1974 ok(color == 0x00ff8000 || color == 0x00fe7f00, "quad 3 has color %08x, expected 0x00ff8000\n", color);
1975 color = getPixelColor(device, 480, 360);
1976 ok(color == 0x0033cc00 || color == 0x0032cb00, "quad 4 has color %08x, expected 0x0033cc00\n", color);
1978 IDirect3DTexture9_Release(texture);
1980 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
1981 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
1982 /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
1983 * Thus watch out if sampling from texels between 0 and 1.
1985 hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
1986 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
1987 "IDirect3DDevice9_CreateVolumeTexture failed with %s\n", DXGetErrorString9(hr));
1988 if(!volume) {
1989 skip("Failed to create a volume texture\n");
1990 goto out;
1993 hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
1994 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %s\n", DXGetErrorString9(hr));
1995 for(z = 0; z < 32; z++) {
1996 for(y = 0; y < 32; y++) {
1997 for(x = 0; x < 32; x++) {
1998 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
1999 void *mem = ((char *) lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
2000 float r_f = (float) x / 31.0;
2001 float g_f = (float) y / 31.0;
2002 float b_f = (float) z / 31.0;
2004 if(fmt == D3DFMT_A16B16G16R16) {
2005 unsigned short *mem_s = mem;
2006 mem_s[0] = r_f * 65535.0;
2007 mem_s[1] = g_f * 65535.0;
2008 mem_s[2] = b_f * 65535.0;
2009 mem_s[3] = 65535;
2010 } else {
2011 unsigned char *mem_c = mem;
2012 mem_c[0] = b_f * 255.0;
2013 mem_c[1] = g_f * 255.0;
2014 mem_c[2] = r_f * 255.0;
2015 mem_c[3] = 255;
2020 hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
2021 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %s\n", DXGetErrorString9(hr));
2023 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
2024 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %s\n", DXGetErrorString9(hr));
2026 hr = IDirect3DDevice9_BeginScene(device);
2027 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
2028 if(SUCCEEDED(hr))
2030 float quad1[] = {
2031 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
2032 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
2033 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
2034 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
2036 float quad2[] = {
2037 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
2038 -1.0, 1.0, 0.1, 1.0, 1.0, 1.0,
2039 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
2040 0.0, 1.0, 0.1, 1.0, 1.0, 1.0
2042 float quad3[] = {
2043 0.0, 0.0, 0.1, 0.0, 0.0,
2044 0.0, 1.0, 0.1, 0.0, 0.0,
2045 1.0, 0.0, 0.1, 0.0, 0.0,
2046 1.0, 1.0, 0.1, 0.0, 0.0
2048 float quad4[] = {
2049 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
2050 0.0, 0.0, 0.1, 1.0, 1.0, 1.0,
2051 1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
2052 1.0, 0.0, 0.1, 1.0, 1.0, 1.0
2054 float mat[16] = {1.0, 0.0, 0.0, 0.0,
2055 0.0, 0.0, 1.0, 0.0,
2056 0.0, 1.0, 0.0, 0.0,
2057 0.0, 0.0, 0.0, 1.0};
2058 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
2059 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
2061 /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
2062 * values
2064 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
2065 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2066 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
2067 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2068 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
2069 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2071 /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
2072 * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
2073 * otherwise the w will be missing(blue).
2074 * turns out that the blue color is missing, so it is an output modification
2076 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
2077 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2078 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
2079 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2081 /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 4 */
2082 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
2083 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2084 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
2085 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2086 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2087 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2088 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
2089 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2091 /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0 */
2092 memset(mat, 0, sizeof(mat));
2093 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
2094 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2095 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
2096 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2097 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
2098 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
2099 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
2100 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2102 hr = IDirect3DDevice9_EndScene(device);
2103 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
2105 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2106 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2108 color = getPixelColor(device, 160, 360);
2109 ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
2110 color = getPixelColor(device, 160, 120);
2111 ok(color == 0x00ffff00, "quad 2 has color %08x, expected 0x00ffff00\n", color);
2112 color = getPixelColor(device, 480, 120);
2113 ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
2114 color = getPixelColor(device, 480, 360);
2115 ok(color == 0x00ffffff, "quad 4 has color %08x, expected 0x00ffffff\n", color);
2117 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
2118 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %s\n", DXGetErrorString9(hr));
2119 hr = IDirect3DDevice9_BeginScene(device);
2120 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %s\n", DXGetErrorString9(hr));
2121 if(SUCCEEDED(hr))
2123 float quad1[] = {
2124 -1.0, -1.0, 0.1, 1.0, 1.0, 1.0,
2125 -1.0, 0.0, 0.1, 1.0, 1.0, 1.0,
2126 0.0, -1.0, 0.1, 1.0, 1.0, 1.0,
2127 0.0, 0.0, 0.1, 1.0, 1.0, 1.0
2129 float quad2[] = {
2130 -1.0, 0.0, 0.1,
2131 -1.0, 1.0, 0.1,
2132 0.0, 0.0, 0.1,
2133 0.0, 1.0, 0.1,
2135 float quad3[] = {
2136 0.0, 0.0, 0.1, 1.0,
2137 0.0, 1.0, 0.1, 1.0,
2138 1.0, 0.0, 0.1, 1.0,
2139 1.0, 1.0, 0.1, 1.0
2141 float mat[16] = {0.0, 0.0, 0.0, 0.0,
2142 0.0, 0.0, 0.0, 0.0,
2143 0.0, 0.0, 0.0, 0.0,
2144 0.0, 1.0, 0.0, 0.0};
2145 float mat2[16] = {0.0, 0.0, 0.0, 1.0,
2146 1.0, 0.0, 0.0, 0.0,
2147 0.0, 1.0, 0.0, 0.0,
2148 0.0, 0.0, 1.0, 0.0};
2149 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
2150 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
2152 /* Default values? 4 coords used, 3 passed. What happens to the 4th?
2154 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat);
2155 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2156 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
2157 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2158 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
2159 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2161 /* None passed */
2162 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) identity);
2163 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2164 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
2165 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %s\n", DXGetErrorString9(hr));
2166 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
2167 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2169 /* 4 used, 1 passed */
2170 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
2171 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
2172 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) mat2);
2173 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2174 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
2175 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2177 hr = IDirect3DDevice9_EndScene(device);
2178 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %s\n", DXGetErrorString9(hr));
2180 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2181 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %s\n", DXGetErrorString9(hr));
2182 color = getPixelColor(device, 160, 360);
2183 ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
2184 color = getPixelColor(device, 160, 120);
2185 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
2186 color = getPixelColor(device, 480, 120);
2187 ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
2188 /* Quad4: unused */
2190 IDirect3DVolumeTexture9_Release(volume);
2192 out:
2193 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
2194 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %s\n", DXGetErrorString9(hr));
2195 IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
2196 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
2197 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, (D3DMATRIX *) &identity);
2198 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %s\n", DXGetErrorString9(hr));
2199 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
2200 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %s\n", DXGetErrorString9(hr));
2201 IDirect3DVertexDeclaration9_Release(decl);
2202 IDirect3DVertexDeclaration9_Release(decl2);
2205 START_TEST(visual)
2207 IDirect3DDevice9 *device_ptr;
2208 D3DCAPS9 caps;
2209 HRESULT hr;
2210 DWORD color;
2212 d3d9_handle = LoadLibraryA("d3d9.dll");
2213 if (!d3d9_handle)
2215 skip("Could not load d3d9.dll\n");
2216 return;
2219 device_ptr = init_d3d9();
2220 if (!device_ptr)
2222 skip("Creating the device failed\n");
2223 return;
2226 IDirect3DDevice9_GetDeviceCaps(device_ptr, &caps);
2228 /* Check for the reliability of the returned data */
2229 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
2230 if(FAILED(hr))
2232 trace("Clear failed, can't assure correctness of the test results, skipping\n");
2233 goto cleanup;
2235 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
2237 color = getPixelColor(device_ptr, 1, 1);
2238 if(color !=0x00ff0000)
2240 trace("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
2241 goto cleanup;
2244 hr = IDirect3DDevice9_Clear(device_ptr, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
2245 if(FAILED(hr))
2247 trace("Clear failed, can't assure correctness of the test results, skipping\n");
2248 goto cleanup;
2250 IDirect3DDevice9_Present(device_ptr, NULL, NULL, NULL, NULL);
2252 color = getPixelColor(device_ptr, 639, 479);
2253 if(color != 0x0000ddee)
2255 trace("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color);
2256 goto cleanup;
2259 /* Now execute the real tests */
2260 lighting_test(device_ptr);
2261 clear_test(device_ptr);
2262 fog_test(device_ptr);
2263 if(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)
2265 test_cube_wrap(device_ptr);
2266 } else {
2267 skip("No cube texture support\n");
2269 present_test(device_ptr);
2270 if(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
2272 maxmip_test(device_ptr);
2274 else
2276 skip("No mipmap support\n");
2278 offscreen_test(device_ptr);
2279 release_buffer_test(device_ptr);
2280 float_texture_test(device_ptr);
2281 texture_transform_flags_test(device_ptr);
2284 if (caps.VertexShaderVersion >= D3DVS_VERSION(2, 0))
2286 test_mova(device_ptr);
2288 else skip("No vs_2_0 support\n");
2290 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1) && caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
2292 fog_with_shader_test(device_ptr);
2294 else skip("No vs_1_1 and ps_1_1 support\n");
2296 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
2298 texbem_test(device_ptr);
2300 else skip("No ps_1_1 support\n");
2302 cleanup:
2303 if(device_ptr) IDirect3DDevice9_Release(device_ptr);