2 * Copyright (C) 2005 Henri Verbeet
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "wine/test.h"
23 static HMODULE d3d9_handle
= 0;
25 static HWND
create_window(void)
28 wc
.lpfnWndProc
= DefWindowProc
;
29 wc
.lpszClassName
= "d3d9_test_wc";
32 return CreateWindow("d3d9_test_wc", "d3d9_test",
33 0, 0, 0, 0, 0, 0, 0, 0, 0);
36 static IDirect3DDevice9
*init_d3d9(void)
38 IDirect3D9
* (__stdcall
* d3d9_create
)(UINT SDKVersion
) = 0;
39 IDirect3D9
*d3d9_ptr
= 0;
40 IDirect3DDevice9
*device_ptr
= 0;
41 D3DPRESENT_PARAMETERS present_parameters
;
44 d3d9_create
= (void *)GetProcAddress(d3d9_handle
, "Direct3DCreate9");
45 ok(d3d9_create
!= NULL
, "Failed to get address of Direct3DCreate9\n");
46 if (!d3d9_create
) return NULL
;
48 d3d9_ptr
= d3d9_create(D3D_SDK_VERSION
);
51 skip("could not create D3D9\n");
55 ZeroMemory(&present_parameters
, sizeof(present_parameters
));
56 present_parameters
.Windowed
= TRUE
;
57 present_parameters
.hDeviceWindow
= create_window();
58 present_parameters
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
60 hres
= IDirect3D9_CreateDevice(d3d9_ptr
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, NULL
, D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &present_parameters
, &device_ptr
);
64 skip("could not create device, IDirect3D9_CreateDevice returned %#x\n", hres
);
71 static int get_refcount(IUnknown
*object
)
73 IUnknown_AddRef(object
);
74 return IUnknown_Release(object
);
77 static void test_get_set_vertex_shader(IDirect3DDevice9
*device_ptr
)
80 static DWORD simple_vs
[] = {0xFFFE0101, /* vs_1_1 */
81 0x0000001F, 0x80000000, 0x900F0000, /* dcl_position0 v0 */
82 0x00000009, 0xC0010000, 0x90E40000, 0xA0E40000, /* dp4 oPos.x, v0, c0 */
83 0x00000009, 0xC0020000, 0x90E40000, 0xA0E40001, /* dp4 oPos.y, v0, c1 */
84 0x00000009, 0xC0040000, 0x90E40000, 0xA0E40002, /* dp4 oPos.z, v0, c2 */
85 0x00000009, 0xC0080000, 0x90E40000, 0xA0E40003, /* dp4 oPos.w, v0, c3 */
86 0x0000FFFF}; /* END */
88 IDirect3DVertexShader9
*shader_ptr
= 0;
89 IDirect3DVertexShader9
*current_shader_ptr
= 0;
91 int shader_refcount
= 0;
94 hret
= IDirect3DDevice9_CreateVertexShader(device_ptr
, simple_vs
, &shader_ptr
);
95 ok(hret
== D3D_OK
&& shader_ptr
!= NULL
, "CreateVertexShader returned: hret 0x%x, shader_ptr %p. "
96 "Expected hret 0x%x, shader_ptr != %p. Aborting.\n", hret
, shader_ptr
, D3D_OK
, NULL
);
97 if (hret
!= D3D_OK
|| shader_ptr
== NULL
) return;
99 /* SetVertexShader should not touch the shader's refcount. */
100 i
= get_refcount((IUnknown
*)shader_ptr
);
101 hret
= IDirect3DDevice9_SetVertexShader(device_ptr
, shader_ptr
);
102 shader_refcount
= get_refcount((IUnknown
*)shader_ptr
);
103 ok(hret
== D3D_OK
&& shader_refcount
== i
, "SetVertexShader returned: hret 0x%x, refcount %d. "
104 "Expected hret 0x%x, refcount %d.\n", hret
, shader_refcount
, D3D_OK
, i
);
106 /* GetVertexShader should increase the shader's refcount by one. */
107 i
= shader_refcount
+1;
108 hret
= IDirect3DDevice9_GetVertexShader(device_ptr
, ¤t_shader_ptr
);
109 shader_refcount
= get_refcount((IUnknown
*)shader_ptr
);
110 ok(hret
== D3D_OK
&& shader_refcount
== i
&& current_shader_ptr
== shader_ptr
,
111 "GetVertexShader returned: hret 0x%x, current_shader_ptr %p refcount %d. "
112 "Expected hret 0x%x, current_shader_ptr %p, refcount %d.\n", hret
, current_shader_ptr
, shader_refcount
, D3D_OK
, shader_ptr
, i
);
113 IDirect3DVertexShader9_Release(current_shader_ptr
);
115 IDirect3DVertexShader9_Release(shader_ptr
);
118 static void test_vertex_shader_constant(IDirect3DDevice9
*device_ptr
, DWORD consts
)
120 float c
[4] = { 0.0, 0.0, 0.0, 0.0 };
121 float d
[16] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
124 /* A simple check that the stuff works at all */
125 hr
= IDirect3DDevice9_SetVertexShaderConstantF(device_ptr
, 0, c
, 1);
126 ok(hr
== D3D_OK
, "IDirect3DDevice9_SetVertexShaderConstantF returned 0x%08x\n", hr
);
128 /* Test corner cases: Write to const MAX - 1, MAX, MAX + 1, and writing 4 consts from
131 hr
= IDirect3DDevice9_SetVertexShaderConstantF(device_ptr
, consts
- 1, c
, 1);
132 ok(hr
== D3D_OK
, "IDirect3DDevice9_SetVertexShaderConstantF returned 0x%08x\n", hr
);
133 hr
= IDirect3DDevice9_SetVertexShaderConstantF(device_ptr
, consts
+ 0, c
, 1);
134 ok(hr
== D3DERR_INVALIDCALL
, "IDirect3DDevice9_SetVertexShaderConstantF returned 0x%08x\n", hr
);
135 hr
= IDirect3DDevice9_SetVertexShaderConstantF(device_ptr
, consts
+ 1, c
, 1);
136 ok(hr
== D3DERR_INVALIDCALL
, "IDirect3DDevice9_SetVertexShaderConstantF returned 0x%08x\n", hr
);
137 hr
= IDirect3DDevice9_SetVertexShaderConstantF(device_ptr
, consts
- 1, d
, 4);
138 ok(hr
== D3DERR_INVALIDCALL
, "IDirect3DDevice9_SetVertexShaderConstantF returned 0x%08x\n", hr
);
141 hr
= IDirect3DDevice9_SetVertexShaderConstantF(device_ptr
, -1, c
, 1);
142 ok(hr
== D3DERR_INVALIDCALL
, "IDirect3DDevice9_SetVertexShaderConstantF returned 0x%08x\n", hr
);
145 static void test_get_set_pixel_shader(IDirect3DDevice9
*device_ptr
)
147 static DWORD simple_ps
[] = {0xFFFF0101, /* ps_1_1 */
148 0x00000051, 0xA00F0001, 0x3F800000, 0x00000000, 0x00000000, 0x00000000, /* def c1 = 1.0, 0.0, 0.0, 0.0 */
149 0x00000042, 0xB00F0000, /* tex t0 */
150 0x00000008, 0x800F0000, 0xA0E40001, 0xA0E40000, /* dp3 r0, c1, c0 */
151 0x00000005, 0x800F0000, 0x90E40000, 0x80E40000, /* mul r0, v0, r0 */
152 0x00000005, 0x800F0000, 0xB0E40000, 0x80E40000, /* mul r0, t0, r0 */
153 0x0000FFFF}; /* END */
155 IDirect3DPixelShader9
*shader_ptr
= 0;
156 IDirect3DPixelShader9
*current_shader_ptr
= 0;
158 int shader_refcount
= 0;
161 hret
= IDirect3DDevice9_CreatePixelShader(device_ptr
, simple_ps
, &shader_ptr
);
162 ok(hret
== D3D_OK
&& shader_ptr
!= NULL
, "CreatePixelShader returned: hret 0x%x, shader_ptr %p. "
163 "Expected hret 0x%x, shader_ptr != %p. Aborting.\n", hret
, shader_ptr
, D3D_OK
, NULL
);
164 if (hret
!= D3D_OK
|| shader_ptr
== NULL
) return;
166 /* SetPixelsShader should not touch the shader's refcount. */
167 i
= get_refcount((IUnknown
*)shader_ptr
);
168 hret
= IDirect3DDevice9_SetPixelShader(device_ptr
, shader_ptr
);
169 shader_refcount
= get_refcount((IUnknown
*)shader_ptr
);
170 ok(hret
== D3D_OK
&& shader_refcount
== i
, "SetPixelShader returned: hret 0x%x, refcount %d. "
171 "Expected hret 0x%x, refcount %d.\n", hret
, shader_refcount
, D3D_OK
, i
);
173 /* GetPixelShader should increase the shader's refcount by one. */
174 i
= shader_refcount
+1;
175 hret
= IDirect3DDevice9_GetPixelShader(device_ptr
, ¤t_shader_ptr
);
176 shader_refcount
= get_refcount((IUnknown
*)shader_ptr
);
177 ok(hret
== D3D_OK
&& shader_refcount
== i
&& current_shader_ptr
== shader_ptr
,
178 "GetPixelShader returned: hret 0x%x, current_shader_ptr %p refcount %d. "
179 "Expected hret 0x%x, current_shader_ptr %p, refcount %d.\n", hret
, current_shader_ptr
, shader_refcount
, D3D_OK
, shader_ptr
, i
);
180 IDirect3DPixelShader9_Release(current_shader_ptr
);
182 IDirect3DPixelShader9_Release(shader_ptr
);
185 static void test_pixel_shader_constant(IDirect3DDevice9
*device_ptr
)
187 float c
[4] = { 0.0, 0.0, 0.0, 0.0 };
188 float d
[16] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
192 /* A simple check that the stuff works at all */
193 hr
= IDirect3DDevice9_SetPixelShaderConstantF(device_ptr
, 0, c
, 1);
194 ok(hr
== D3D_OK
, "IDirect3DDevice9_SetVertexShaderConstantF returned 0x%08x\n", hr
);
196 /* Is there really no max pixel shader constant value??? Test how far I can go */
197 while(SUCCEEDED(IDirect3DDevice9_SetPixelShaderConstantF(device_ptr
, consts
++, c
, 1)));
199 trace("SetPixelShaderConstantF was able to set %d shader constants\n", consts
);
201 /* Test corner cases: writing 4 consts from MAX - 1, everything else is pointless
202 * given the way the constant limit was found out
204 hr
= IDirect3DDevice9_SetPixelShaderConstantF(device_ptr
, consts
- 1, d
, 4);
205 ok(hr
== D3DERR_INVALIDCALL
, "IDirect3DDevice9_SetPixelShaderConstantF returned 0x%08x\n", hr
);
208 hr
= IDirect3DDevice9_SetPixelShaderConstantF(device_ptr
, -1, c
, 1);
209 ok(hr
== D3DERR_INVALIDCALL
, "IDirect3DDevice9_SetPixelShaderConstantF returned 0x%08x\n", hr
);
212 static void test_wrong_shader(IDirect3DDevice9
*device_ptr
)
214 static const DWORD simple_vs
[] =
216 0xfffe0101, /* vs_1_1 */
217 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
218 0x00000009, 0xc0010000, 0x90e40000, 0xa0e40000, /* dp4 oPos.x, v0, c0 */
219 0x00000009, 0xc0020000, 0x90e40000, 0xa0e40001, /* dp4 oPos.y, v0, c1 */
220 0x00000009, 0xc0040000, 0x90e40000, 0xa0e40002, /* dp4 oPos.z, v0, c2 */
221 0x00000009, 0xc0080000, 0x90e40000, 0xa0e40003, /* dp4 oPos.w, v0, c3 */
225 static const DWORD simple_ps
[] =
227 0xffff0101, /* ps_1_1 */
228 0x00000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1 = 1.0, 0.0, 0.0, 0.0 */
229 0x00000042, 0xb00f0000, /* tex t0 */
230 0x00000008, 0x800f0000, 0xa0e40001, 0xa0e40000, /* dp3 r0, c1, c0 */
231 0x00000005, 0x800f0000, 0x90e40000, 0x80e40000, /* mul r0, v0, r0 */
232 0x00000005, 0x800f0000, 0xb0e40000, 0x80e40000, /* mul r0, t0, r0 */
237 float4
main(const float4 color
: COLOR
) : SV_TARGET
246 static const DWORD ps_4_0
[] =
248 0x43425844, 0x4da9446f, 0xfbe1f259, 0x3fdb3009, 0x517521fa, 0x00000001, 0x000001ac,
249 0x00000005, 0x00000034, 0x0000008c, 0x000000bc, 0x000000f0, 0x00000130, 0x46454452,
250 0x00000050, 0x00000000, 0x00000000, 0x00000000, 0x0000001c, 0xffff0400, 0x00000100,
251 0x0000001c, 0x7263694d, 0x666f736f, 0x52282074, 0x4c482029, 0x53204c53, 0x65646168,
252 0x6f432072, 0x6c69706d, 0x39207265, 0x2e39322e, 0x2e323539, 0x31313133, 0xababab00,
253 0x4e475349, 0x00000028, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000,
254 0x00000003, 0x00000000, 0x00000f0f, 0x4f4c4f43, 0xabab0052, 0x4e47534f, 0x0000002c,
255 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
256 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054, 0x52444853, 0x00000038, 0x00000040,
257 0x0000000e, 0x03001062, 0x001010f2, 0x00000000, 0x03000065, 0x001020f2, 0x00000000,
258 0x05000036, 0x001020f2, 0x00000000, 0x00101e46, 0x00000000, 0x0100003e, 0x54415453,
259 0x00000074, 0x00000002, 0x00000000, 0x00000000, 0x00000002, 0x00000000, 0x00000000,
260 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
261 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001,
262 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
263 0x00000000, 0x00000000,
266 IDirect3DVertexShader9
*vs
;
267 IDirect3DPixelShader9
*ps
;
270 hret
= IDirect3DDevice9_CreateVertexShader(device_ptr
, simple_ps
, &vs
);
271 ok(hret
== D3DERR_INVALIDCALL
, "CreateVertexShader returned: hret 0x%x, shader_ptr %p.\n", hret
, vs
);
272 hret
= IDirect3DDevice9_CreatePixelShader(device_ptr
, simple_vs
, &ps
);
273 ok(hret
== D3DERR_INVALIDCALL
, "CreatePixelShader returned: hret 0x%x, shader_ptr %p.\n", hret
, ps
);
275 hret
= IDirect3DDevice9_CreatePixelShader(device_ptr
, ps_4_0
, &ps
);
276 ok(hret
== D3DERR_INVALIDCALL
, "CreatePixelShader returned: hret 0x%x, shader_ptr %p.\n", hret
, ps
);
282 IDirect3DDevice9
*device_ptr
;
285 d3d9_handle
= LoadLibraryA("d3d9.dll");
288 skip("Could not load d3d9.dll\n");
292 device_ptr
= init_d3d9();
293 if (!device_ptr
) return;
295 IDirect3DDevice9_GetDeviceCaps(device_ptr
, &caps
);
297 if (caps
.VertexShaderVersion
& 0xffff)
299 test_get_set_vertex_shader(device_ptr
);
300 test_vertex_shader_constant(device_ptr
, caps
.MaxVertexShaderConst
);
302 else skip("No vertex shader support\n");
304 if (caps
.PixelShaderVersion
& 0xffff)
306 test_get_set_pixel_shader(device_ptr
);
307 /* No max pixel shader constant value??? */
308 test_pixel_shader_constant(device_ptr
);
309 if (caps
.VertexShaderVersion
& 0xffff)
310 test_wrong_shader(device_ptr
);
312 else skip("No pixel shader support\n");
314 refcount
= IDirect3DDevice9_Release(device_ptr
);
315 ok(!refcount
, "Device has %u references left\n", refcount
);