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
33 #include "wine/test.h"
35 static HMODULE d3d9_handle
= 0;
37 static HWND
create_window(void)
41 wc
.lpfnWndProc
= &DefWindowProc
;
42 wc
.lpszClassName
= "d3d9_test_wc";
45 ret
= CreateWindow("d3d9_test_wc", "d3d9_test",
46 WS_MAXIMIZE
| WS_VISIBLE
| WS_CAPTION
, 0, 0, 640, 480, 0, 0, 0, 0);
50 static DWORD
getPixelColor(IDirect3DDevice9
*device
, UINT x
, UINT y
)
53 IDirect3DSurface9
*surf
;
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
));
65 hr
= IDirect3DDevice9_GetFrontBufferData(device
, 0, surf
);
68 trace("Can't read the front buffer data, hr=%s\n", DXGetErrorString9(hr
));
73 hr
= IDirect3DSurface9_LockRect(surf
, &lockedRect
, &rectToLock
, D3DLOCK_READONLY
);
76 trace("Can't lock the offscreen surface, hr=%s\n", DXGetErrorString9(hr
));
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
);
88 trace("Can't unlock the offscreen surface, hr=%s\n", DXGetErrorString9(hr
));
92 if(surf
) IDirect3DSurface9_Release(surf
);
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
;
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
));
141 static void lighting_test(IDirect3DDevice9
*device
)
144 DWORD fvf
= D3DFVF_XYZ
| D3DFVF_DIFFUSE
;
145 DWORD nfvf
= D3DFVF_XYZ
| D3DFVF_DIFFUSE
| D3DFVF_NORMAL
;
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
));
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 */
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 */
283 /* Positive x, positive y */
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;
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
);
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 */
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
},
358 { 1.0f
, -1.0f
, 0.0f
},
362 static const D3DVERTEXELEMENT9 decl_elements
[] = {
363 {0, 0, D3DDECLTYPE_FLOAT3
, D3DDECLMETHOD_DEFAULT
, D3DDECLUSAGE_POSITION
, 0},
367 IDirect3DVertexDeclaration9
*vertex_declaration
= NULL
;
368 IDirect3DVertexShader9
*mova_shader
= NULL
;
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
)
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
);
427 static void fog_test(IDirect3DDevice9
*device
)
431 float start
= 0.0f
, end
= 1.0f
;
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
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
));
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
);
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
)
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
));
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
));
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},
651 static const struct {
652 D3DTEXTUREADDRESS mode
;
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
;
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
)
688 for (x
= 64; x
< 128; ++x
)
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
)
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
)
774 IDirect3DTexture9
*offscreenTexture
= NULL
;
775 IDirect3DSurface9
*backbuffer
= NULL
, *offscreen
= NULL
;
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");
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
));
806 hr
= IDirect3DTexture9_GetSurfaceLevel(offscreenTexture
, 0, &offscreen
);
807 ok(hr
== D3D_OK
, "Can't get offscreen surface, hr = %s\n", DXGetErrorString9(hr
));
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
);
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
);
869 hr
= IDirect3DDevice9_SetTexture(device
, 0, NULL
);
873 IDirect3DDevice9_SetRenderTarget(device
, 0, backbuffer
);
874 IDirect3DSurface9_Release(backbuffer
);
876 if(offscreenTexture
) {
877 IDirect3DTexture9_Release(offscreenTexture
);
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
)
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 */
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 */
922 /* basic pixel shader */
923 static const DWORD pixel_shader_code
[] = {
924 0xffff0101, /* ps_1_1 */
925 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, vo */
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},
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
{
952 unsigned int color
[11];
954 /* only pixel shader: */
956 {0x0000ff00, 0x0000ff00, 0x0020df00, 0x0040bf00, 0x005fa000, 0x007f8000,
957 0x009f6000, 0x00bf4000, 0x00df2000, 0x00ff0000, 0x00ff0000}},
959 {0x0000ff00, 0x0000ff00, 0x0020df00, 0x0040bf00, 0x005fa000, 0x007f8000,
960 0x009f6000, 0x00bf4000, 0x00df2000, 0x00ff0000, 0x00ff0000}},
962 {0x0000ff00, 0x0000ff00, 0x0020df00, 0x0040bf00, 0x005fa000, 0x007f8000,
963 0x009f6000, 0x00bf4000, 0x00df2000, 0x00ff0000, 0x00ff0000}},
965 {0x0000ff00, 0x0000ff00, 0x0020df00, 0x0040bf00, 0x005fa000, 0x007f8000,
966 0x009f6000, 0x00bf4000, 0x00df2000, 0x00ff0000, 0x00ff0000}},
968 {0x0000ff00, 0x0000ff00, 0x0020df00, 0x0040bf00, 0x005fa000, 0x007f8000,
969 0x009f6000, 0x00bf4000, 0x00df2000, 0x00ff0000, 0x00ff0000}},
973 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
974 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
976 {0x0000ff00, 0x0000ff00, 0x0020df00, 0x0040bf00, 0x005fa000, 0x007f8000,
977 0x009f6000, 0x00bf4000, 0x00df2000, 0x00ff0000, 0x00ff0000}},
979 {0x0000ff00, 0x0000ff00, 0x0020df00, 0x0040bf00, 0x005fa000, 0x007f8000,
980 0x009f6000, 0x00bf4000, 0x00df2000, 0x00ff0000, 0x00ff0000}},
982 {0x0000ff00, 0x0000ff00, 0x0020df00, 0x0040bf00, 0x005fa000, 0x007f8000,
983 0x009f6000, 0x00bf4000, 0x00df2000, 0x00ff0000, 0x00ff0000}},
985 {0x0000ff00, 0x0000ff00, 0x0020df00, 0x0040bf00, 0x005fa000, 0x007f8000,
986 0x009f6000, 0x00bf4000, 0x00df2000, 0x00ff0000, 0x00ff0000}},
988 /* vertex shader and pixel shader */
990 {0x0000ff00, 0x0000ff00, 0x0020df00, 0x0040bf00, 0x005fa000, 0x007f8000,
991 0x009f6000, 0x00bf4000, 0x00df2000, 0x00ff0000, 0x00ff0000}},
993 {0x0000ff00, 0x0000ff00, 0x0020df00, 0x0040bf00, 0x005fa000, 0x007f8000,
994 0x009f6000, 0x00bf4000, 0x00df2000, 0x00ff0000, 0x00ff0000}},
996 {0x0000ff00, 0x0000ff00, 0x0020df00, 0x0040bf00, 0x005fa000, 0x007f8000,
997 0x009f6000, 0x00bf4000, 0x00df2000, 0x00ff0000, 0x00ff0000}},
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 */
1005 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1006 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1008 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1009 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1011 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1012 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1014 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1015 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1018 /* foggy vertex shader and pixel shader */
1020 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1021 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1023 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1024 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1026 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1027 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
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*/
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
]);
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
)
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*/
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},
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},
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 */
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
)
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;
1195 *ptr
++ = 0xff000000;
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))
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
);
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
);
1274 hr
= IDirect3DDevice9_DrawPrimitiveUP(device
, D3DPT_TRIANGLESTRIP
, 2, &quad
[0], sizeof(quad
[0]));
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
);
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
);
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},
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
));
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
;
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
++)
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
;
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
,
1431 ok(hr
== D3D_OK
, "IDirect3DDevice9_CreateTexture failed with %s\n", DXGetErrorString9(hr
));
1434 skip("Failed to create test texture\n");
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
);
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
);
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
;
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 createable */
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
));
1574 skip("Failed to create a vertex buffer\n");
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
));
1580 skip("Failed to create an index buffer\n");
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
);
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
;
1639 IDirect3DTexture9
*texture
= NULL
;
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");
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
));
1662 skip("Failed to create R32F texture\n");
1666 hr
= IDirect3DTexture9_LockRect(texture
, 0, &lr
, NULL
, 0);
1667 ok(hr
== D3D_OK
, "IDirect3DTexture9_LockRect failed with %s\n", DXGetErrorString9(hr
));
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
));
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
);
1699 if(texture
) IDirect3DTexture9_Release(texture
);
1700 IDirect3D9_Release(d3d
);
1705 IDirect3DDevice9
*device_ptr
;
1710 d3d9_handle
= LoadLibraryA("d3d9.dll");
1713 skip("Could not load d3d9.dll\n");
1717 device_ptr
= init_d3d9();
1720 skip("Creating the device failed\n");
1724 IDirect3DDevice9_GetDeviceCaps(device_ptr
, &caps
);
1726 /* Check for the reliability of the returned data */
1727 hr
= IDirect3DDevice9_Clear(device_ptr
, 0, NULL
, D3DCLEAR_TARGET
, 0xffff0000, 0.0, 0);
1730 trace("Clear failed, can't assure correctness of the test results, skipping\n");
1733 IDirect3DDevice9_Present(device_ptr
, NULL
, NULL
, NULL
, NULL
);
1735 color
= getPixelColor(device_ptr
, 1, 1);
1736 if(color
!=0x00ff0000)
1738 trace("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color
);
1742 hr
= IDirect3DDevice9_Clear(device_ptr
, 0, NULL
, D3DCLEAR_TARGET
, 0xff00ddee, 0.0, 0);
1745 trace("Clear failed, can't assure correctness of the test results, skipping\n");
1748 IDirect3DDevice9_Present(device_ptr
, NULL
, NULL
, NULL
, NULL
);
1750 color
= getPixelColor(device_ptr
, 639, 479);
1751 if(color
!= 0x0000ddee)
1753 trace("Sanity check returned an incorrect color(%08x), can't assure the correctness of the tests, skipping\n", color
);
1757 /* Now execute the real tests */
1758 lighting_test(device_ptr
);
1759 clear_test(device_ptr
);
1760 fog_test(device_ptr
);
1761 if(caps
.TextureCaps
& D3DPTEXTURECAPS_CUBEMAP
)
1763 test_cube_wrap(device_ptr
);
1765 skip("No cube texture support\n");
1767 present_test(device_ptr
);
1768 if(caps
.TextureCaps
& D3DPTEXTURECAPS_MIPMAP
)
1770 maxmip_test(device_ptr
);
1774 skip("No mipmap support\n");
1776 offscreen_test(device_ptr
);
1777 release_buffer_test(device_ptr
);
1778 float_texture_test(device_ptr
);
1780 if (caps
.VertexShaderVersion
>= D3DVS_VERSION(2, 0))
1782 test_mova(device_ptr
);
1784 else skip("No vs_2_0 support\n");
1786 if (caps
.VertexShaderVersion
>= D3DVS_VERSION(1, 1) && caps
.PixelShaderVersion
>= D3DPS_VERSION(1, 1))
1788 fog_with_shader_test(device_ptr
);
1790 else skip("No vs_1_1 and ps_1_1 support\n");
1792 if (caps
.PixelShaderVersion
>= D3DPS_VERSION(1, 1))
1794 texbem_test(device_ptr
);
1796 else skip("No ps_1_1 support\n");
1799 if(device_ptr
) IDirect3DDevice9_Release(device_ptr
);