ReactOS 0.4.15-dev-7958-gcd0bb1a
hlsl.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2010 Travis Athougies
3 *
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.
8 *
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.
13 *
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
17 */
18#define COBJMACROS
19#include "wine/test.h"
20#include "d3dx9.h"
21#include "d3dcompiler.h"
22
23#include <math.h>
24
26
27struct vertex
28{
29 float x, y, z;
30 float tx, ty;
31};
32
33/* Tells compute_shader_probe* which pixels should be what colors */
35{
36 unsigned int x, y;
37 /* The expected values in this region */
39 /* The max error for any value */
40 float epsilon;
41 /* An error message to print if this test fails */
42 const char *message;
43};
44
45static HWND create_window(void)
46{
47 WNDCLASSA wc = {0};
49 wc.lpszClassName = "d3d9_test_wc";
50 RegisterClassA(&wc);
51
52 return CreateWindowA("d3d9_test_wc", "d3d9_test", 0, 0, 0, 0, 0, 0, 0, 0, 0);
53}
54
55static IDirect3DDevice9 *init_d3d9(IDirect3DVertexDeclaration9 **vdeclaration,
56 IDirect3DVertexBuffer9 **quad_geometry, IDirect3DVertexShader9 **vshader_passthru)
57{
58 static const struct vertex quad_vertices[4] =
59 {
60 {-1.0f, -1.0f, 0.0f, 0.0f, 1.0f},
61 {-1.0f, 1.0f, 0.0f, 0.0f, 0.0f},
62 { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f},
63 { 1.0f, 1.0f, 0.0f, 1.0f, 0.0f}
64 };
65
66 static const D3DVERTEXELEMENT9 vdeclelements[] =
67 {
71 };
72
73 static const char *vshader_passthru_hlsl =
74 "float4 vshader(float4 pos: POSITION, inout float2 texcoord: TEXCOORD0): POSITION\n"
75 "{\n"
76 " return pos;\n"
77 "}";
78
79 IDirect3D9 *d3d9_ptr;
80 IDirect3DDevice9 *device_ptr = NULL;
81 D3DPRESENT_PARAMETERS present_parameters;
82
83 void *temp_geometry_vertices;
84
85 ID3D10Blob *compiled = NULL;
86 ID3D10Blob *errors = NULL;
87
88 HRESULT hr;
89
91 if (!d3d9_ptr)
92 {
93 skip("could not create D3D9\n");
94 return NULL;
95 }
96
99 if (FAILED(hr))
100 {
101 skip("A32B32G32R32F format not available on this device\n");
102 IDirect3D9_Release(d3d9_ptr);
103 return NULL;
104 }
105
106 ZeroMemory(&present_parameters, sizeof(present_parameters));
107 present_parameters.Windowed = TRUE;
108 present_parameters.hDeviceWindow = create_window();
109 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
110
112 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
113 IDirect3D9_Release(d3d9_ptr);
114 if (FAILED(hr))
115 {
116 skip("could not create Direct3D9 device\n");
117 return NULL;
118 }
119
120 /* Create the quad geometry */
121 hr = IDirect3DDevice9_CreateVertexBuffer(device_ptr, 4 * sizeof(struct vertex),
122 D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, quad_geometry, NULL);
123 ok(SUCCEEDED(hr),
124 "Could not create vertex buffer, IDirect3DDevice9_CreateVertexBuffer returned: %08x\n", hr);
125
126 hr = IDirect3DVertexBuffer9_Lock(*quad_geometry, 0, sizeof(quad_vertices), &temp_geometry_vertices, 0);
127 ok(SUCCEEDED(hr), "IDirect3DVertexBuffer9_Lock returned: %08x\n", hr);
128 memcpy(temp_geometry_vertices, quad_vertices, sizeof(quad_vertices));
129 IDirect3DVertexBuffer9_Unlock(*quad_geometry);
130
131 hr = IDirect3DDevice9_CreateVertexDeclaration(device_ptr, vdeclelements, vdeclaration);
132 ok(SUCCEEDED(hr), "Could not create vertex declaration: "
133 "IDirect3DDevice9_CreateVertexDeclaration returned: %08x\n", hr);
134
135 hr = IDirect3DDevice9_SetVertexDeclaration(device_ptr, *vdeclaration);
136 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned: %08x\n", hr);
137
138 /* Create a simple vertex shader to just pass through the values */
139 hr = ppD3DCompile(vshader_passthru_hlsl, strlen(vshader_passthru_hlsl), NULL,
140 NULL, NULL, "vshader", "vs_1_1", 0, 0, &compiled, &errors);
141 if (FAILED(hr))
142 {
143 skip("not compiling vertex shader due to lacking wine HLSL support!\n");
144 if (errors)
145 ID3D10Blob_Release(errors);
146 return NULL;
147 }
148
149 hr = IDirect3DDevice9_CreateVertexShader(device_ptr, ID3D10Blob_GetBufferPointer(compiled),
150 vshader_passthru);
151 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader returned: %08x\n", hr);
152 ID3D10Blob_Release(compiled);
153
154 return device_ptr;
155}
156
157/* Convenience functions */
158static void set_float4_d3d9(IDirect3DDevice9 *device, ID3DXConstantTable *constants, const char *name,
159 float x, float y, float z, float w)
160{
162 vector.x = x;
163 vector.y = y;
164 vector.z = z;
165 vector.w = w;
167}
168
169/* Compile our pixel shader and get back the compiled version and a constant table */
170static IDirect3DPixelShader9 *compile_pixel_shader9(IDirect3DDevice9 *device, const char *shader,
171 const char *profile, ID3DXConstantTable **constants)
172{
173 ID3D10Blob *compiled = NULL;
174 ID3D10Blob *errors = NULL;
175 IDirect3DPixelShader9 *pshader;
176 HRESULT hr;
177
179 NULL, "test", profile, /* test is the name of the entry point of our shader */
180 0, 0, &compiled, &errors);
181 ok(hr == D3D_OK, "Pixel shader %s compilation failed: %s\n", shader,
182 errors ? (char *)ID3D10Blob_GetBufferPointer(errors) : "");
183 if (FAILED(hr)) return NULL;
184
185 hr = D3DXGetShaderConstantTable(ID3D10Blob_GetBufferPointer(compiled), constants);
186 ok(hr == D3D_OK, "Could not get constant table from compiled pixel shader\n");
187
188 hr = IDirect3DDevice9_CreatePixelShader(device, ID3D10Blob_GetBufferPointer(compiled), &pshader);
189 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader returned: %08x\n", hr);
190 ID3D10Blob_Release(compiled);
191 return pshader;
192}
193
194/* Draw a full screen quad */
195static void draw_quad_with_shader9(IDirect3DDevice9 *device, IDirect3DVertexBuffer9 *quad_geometry)
196{
197 HRESULT hr;
198 D3DXMATRIX projection_matrix;
199
200 D3DXMatrixOrthoLH(&projection_matrix, 2.0f, 2.0f, 0.0f, 1.0f);
202
204 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned: %08x\n", hr);
205
207 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned: %08x\n", hr);
208
209 hr = IDirect3DDevice9_SetStreamSource(device, 0, quad_geometry, 0, sizeof(struct vertex));
210 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource returned: %08x\n", hr);
212 ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive returned: %08x\n", hr);
213
215 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned: %08x\n", hr);
216}
217
218static void setup_device9(IDirect3DDevice9 *device, IDirect3DSurface9 **render_target,
219 IDirect3DSurface9 **readback, D3DFORMAT format, unsigned int width, unsigned int height,
220 IDirect3DVertexShader9 *vshader, IDirect3DPixelShader9 *pshader)
221{
222 HRESULT hr;
224 D3DMULTISAMPLE_NONE, 0, FALSE, render_target, NULL);
225 ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget returned: %08x\n", hr);
226
227 /* The Direct3D 9 docs state that we cannot lock a render target surface,
228 instead we must copy the render target onto this surface to lock it */
230 D3DPOOL_SYSTEMMEM, readback, NULL);
231 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface returned: %08x\n", hr);
232
233 hr = IDirect3DDevice9_SetRenderTarget(device, 0, *render_target);
234 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget returned: %08x\n", hr);
235
237 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned: %08x\n", hr);
239 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned: %08x\n", hr);
240}
241
242static BOOL colors_match(D3DXCOLOR a, D3DXCOLOR b, float epsilon)
243{
244 return (fabs(a.r - b.r) < epsilon && fabs(a.g - b.g) < epsilon && fabs(a.b - b.b) < epsilon &&
245 fabs(a.a - b.a) < epsilon);
246}
247
248/* Compute a shader on a width by height buffer and probes certain locations
249 to see if they are as expected. */
250static void compute_shader_probe9(IDirect3DDevice9 *device, IDirect3DVertexShader9 *vshader,
251 IDirect3DPixelShader9 *pshader, IDirect3DVertexBuffer9 *quad_geometry,
252 const struct hlsl_probe_info *probes, unsigned int count,
253 unsigned int width, unsigned int height, unsigned int line_number)
254{
255 IDirect3DSurface9 *render_target;
256 IDirect3DSurface9 *readback;
257
258 HRESULT hr;
260 D3DXCOLOR *pbits_data;
261 unsigned int i;
262
263 setup_device9(device, &render_target, &readback, D3DFMT_A32B32G32R32F,
264 width, height, vshader, pshader);
265
266 /* Draw the quad with the shader and read back the data */
267 draw_quad_with_shader9(device, quad_geometry);
268 IDirect3DDevice9_GetRenderTargetData(device, render_target, readback);
270 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned: %08x\n", hr);
271 pbits_data = lr.pBits;
272
273 /* Now go through the probes and check each one */
274 for (i = 0; i < count; i++, probes++) {
275 int index = probes->x + (probes->y * lr.Pitch / sizeof(D3DXCOLOR));
276 ok(colors_match(probes->c, pbits_data[index], probes->epsilon),
277 "Line %d: At (%d, %d): %s: Expected (%.04f,%.04f,%.04f, %.04f), got "
278 "(%.04f,%.04f,%.04f,%.04f)\n", line_number, probes->x, probes->y, probes->message,
279 probes->c.r, probes->c.g, probes->c.b, probes->c.a, pbits_data[index].r,
280 pbits_data[index].g, pbits_data[index].b, pbits_data[index].a);
281 }
282
284 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned: %08x\n", hr);
285
286 /* We now present the scene. This is mostly for debugging purposes, since GetRenderTargetData
287 also waits for drawing commands to complete. The reason this call is here and not in a
288 draw function is because the contents of the render target surface are invalidated after
289 this call. */
291 ok(hr == D3D_OK, "IDirect3DDevice9_Present returned: %08x\n", hr);
292
293 IDirect3DSurface9_Release(render_target);
295}
296
297/* Now the actual test functions */
298static void test_swizzle(IDirect3DDevice9 *device, IDirect3DVertexBuffer9 *quad_geometry,
299 IDirect3DVertexShader9 *vshader_passthru)
300{
301 static const struct hlsl_probe_info probes[] =
302 {
303 {0, 0, {0.0101f, 0.0303f, 0.0202f, 0.0404f}, 0.0001f, "swizzle_test"}
304 };
305
306 static const char *swizzle_test_shader =
307 "uniform float4 color;\n"
308 "float4 test(): COLOR\n"
309 "{\n"
310 " float4 ret = color;\n"
311 " ret.gb = ret.ra;\n"
312 " ret.ra = float2(0.0101, 0.0404);\n"
313 " return ret;\n"
314 "}";
315
316 ID3DXConstantTable *constants;
317 IDirect3DPixelShader9 *pshader;
318
319 pshader = compile_pixel_shader9(device, swizzle_test_shader, "ps_2_0", &constants);
320 if (pshader != NULL)
321 {
322 set_float4_d3d9(device, constants, "color", 0.0303f, 0.0f, 0.0f, 0.0202f);
323
324 compute_shader_probe9(device, vshader_passthru, pshader, quad_geometry,
325 probes, ARRAY_SIZE(probes), 1, 1, __LINE__);
326
329 }
330}
331
332static void test_math(IDirect3DDevice9 *device, IDirect3DVertexBuffer9 *quad_geometry,
333 IDirect3DVertexShader9 *vshader_passthru)
334{
335 /* Tests order of operations */
336 static const float u = 2.5f, v = 0.3f, w = 0.2f, x = 0.7f, y = 0.1f, z = 1.5f;
337
338 static const struct hlsl_probe_info probes[] =
339 {
340 {0, 0, {-12.4300f, 9.8333f, 1.6000f, 34.9999f}, 0.0001f,
341 "order of operations test"}
342 };
343
344 static const char *order_of_operations_shader =
345 "float4 test(uniform float u, uniform float v, uniform float w, uniform float x,\n"
346 " uniform float y, uniform float z): COLOR\n"
347 "{\n"
348 " return float4(x * y - z / w + --u / -v,\n"
349 " z * x / y + w / -v,\n"
350 " u + v - w,\n"
351 " x / y / w);\n"
352 "}";
353
354 ID3DXConstantTable *constants;
355 IDirect3DPixelShader9 *pshader;
356
357 pshader = compile_pixel_shader9(device, order_of_operations_shader, "ps_2_0", &constants);
358 if (pshader != NULL)
359 {
366
367 compute_shader_probe9(device, vshader_passthru, pshader, quad_geometry,
368 probes, ARRAY_SIZE(probes), 1, 1, __LINE__);
369
372 }
373}
374
375static void test_conditionals(IDirect3DDevice9 *device, IDirect3DVertexBuffer9 *quad_geometry,
376 IDirect3DVertexShader9 *vshader_passthru)
377{
378 static const struct hlsl_probe_info if_greater_probes[] =
379 {
380 { 0, 0, {0.9f, 0.8f, 0.7f, 0.6f}, 0.0001f, "if greater test"},
381 { 5, 0, {0.9f, 0.8f, 0.7f, 0.6f}, 0.0001f, "if greater test"},
382 {10, 0, {0.9f, 0.8f, 0.7f, 0.6f}, 0.0001f, "if greater test"},
383 {15, 0, {0.9f, 0.8f, 0.7f, 0.6f}, 0.0001f, "if greater test"},
384 {25, 0, {0.1f, 0.2f, 0.3f, 0.4f}, 0.0001f, "if greater test"},
385 {30, 0, {0.1f, 0.2f, 0.3f, 0.4f}, 0.0001f, "if greater test"}
386 };
387
388 static const char *if_greater_shader =
389 "float4 test(float2 pos: TEXCOORD0): COLOR\n"
390 "{\n"
391 " if((pos.x * 32.0) > 20.0)\n"
392 " return float4(0.1, 0.2, 0.3, 0.4);\n"
393 " else\n"
394 " return float4(0.9, 0.8, 0.7, 0.6);\n"
395 "}";
396
397 static const struct hlsl_probe_info ternary_operator_probes[] =
398 {
399 {0, 0, {0.50f, 0.25f, 0.50f, 0.75f}, 0.00001f, "ternary operator test"},
400 {1, 0, {0.50f, 0.25f, 0.50f, 0.75f}, 0.00001f, "ternary operator test"},
401 {2, 0, {0.50f, 0.25f, 0.50f, 0.75f}, 0.00001f, "ternary operator test"},
402 {3, 0, {0.50f, 0.25f, 0.50f, 0.75f}, 0.00001f, "ternary operator test"},
403 {4, 0, {0.60f, 0.80f, 0.10f, 0.20f}, 0.00001f, "ternary operator test"},
404 {5, 0, {0.60f, 0.80f, 0.10f, 0.20f}, 0.00001f, "ternary operator test"},
405 {6, 0, {0.60f, 0.80f, 0.10f, 0.20f}, 0.00001f, "ternary operator test"},
406 {7, 0, {0.60f, 0.80f, 0.10f, 0.20f}, 0.00001f, "ternary operator test"}
407 };
408
409 static const char *ternary_operator_shader =
410 "float4 test(float2 pos: TEXCOORD0): COLOR\n"
411 "{\n"
412 " return (pos.x < 0.5?float4(0.5, 0.25, 0.5, 0.75):float4(0.6, 0.8, 0.1, 0.2));\n"
413 "}";
414
415 ID3DXConstantTable *constants;
416 IDirect3DPixelShader9 *pshader;
417
418 pshader = compile_pixel_shader9(device, if_greater_shader, "ps_2_0", &constants);
419 if (pshader != NULL)
420 {
421 compute_shader_probe9(device, vshader_passthru, pshader, quad_geometry, if_greater_probes,
422 ARRAY_SIZE(if_greater_probes), 32, 1, __LINE__);
423
426 }
427
428 pshader = compile_pixel_shader9(device, ternary_operator_shader, "ps_2_0", &constants);
429 if (pshader != NULL)
430 {
431 compute_shader_probe9(device, vshader_passthru, pshader, quad_geometry, ternary_operator_probes,
432 ARRAY_SIZE(ternary_operator_probes), 8, 1, __LINE__);
433
436 }
437}
438
439static void test_float_vectors(IDirect3DDevice9 *device, IDirect3DVertexBuffer9 *quad_geometry,
440 IDirect3DVertexShader9 *vshader_passthru)
441{
442 static const struct hlsl_probe_info vec4_indexing_test1_probes[] =
443 {
444 {0, 0, {0.020f, 0.245f, 0.351f, 1.000f}, 0.0001f, "vec4 indexing test 1"}
445 };
446
447 static const char *vec4_indexing_test1_shader =
448 "float4 test(): COLOR\n"
449 "{\n"
450 " float4 color;\n"
451 " color[0] = 0.020;\n"
452 " color[1] = 0.245;\n"
453 " color[2] = 0.351;\n"
454 " color[3] = 1.0;\n"
455 " return color;\n"
456 "}";
457
458 static const struct hlsl_probe_info vec4_indexing_test2_probes[] =
459 {
460 {0, 0, {0.5f, 0.3f, 0.8f, 0.2f}, 0.0001f, "vec4 indexing test 2"}
461 };
462
463 /* We have this uniform i here so the compiler can't optimize */
464 static const char *vec4_indexing_test2_shader =
465 "uniform int i;\n"
466 "float4 test(): COLOR\n"
467 "{\n"
468 " float4 color = float4(0.5, 0.4, 0.3, 0.2);\n"
469 " color.g = color[i];\n"
470 " color.b = 0.8;\n"
471 " return color;\n"
472 "}";
473
474 ID3DXConstantTable *constants;
475 IDirect3DPixelShader9 *pshader;
476
477 pshader = compile_pixel_shader9(device, vec4_indexing_test1_shader, "ps_2_0", &constants);
478 if (pshader != NULL)
479 {
480 compute_shader_probe9(device, vshader_passthru, pshader, quad_geometry, vec4_indexing_test1_probes,
481 ARRAY_SIZE(vec4_indexing_test1_probes), 1, 1, __LINE__);
482
485 }
486
487 pshader = compile_pixel_shader9(device, vec4_indexing_test2_shader, "ps_2_0", &constants);
488 if (pshader != NULL)
489 {
491
492 compute_shader_probe9(device, vshader_passthru, pshader, quad_geometry, vec4_indexing_test2_probes,
493 ARRAY_SIZE(vec4_indexing_test2_probes), 32, 1, __LINE__);
494
497 }
498}
499
500static void test_trig(IDirect3DDevice9 *device, IDirect3DVertexBuffer9 *quad_geometry,
501 IDirect3DVertexShader9 *vshader_passthru)
502{
503 static const struct hlsl_probe_info sincos_probes[] =
504 {
505 {0, 0, {0.5000f, 1.0000f, 0.0f, 0.0f}, 0.001f, "sin/cos test"},
506 {1, 0, {0.5975f, 0.9904f, 0.0f, 0.0f}, 0.001f, "sin/cos test"},
507 {2, 0, {0.6913f, 0.9620f, 0.0f, 0.0f}, 0.001f, "sin/cos test"},
508 {3, 0, {0.7778f, 0.9160f, 0.0f, 0.0f}, 0.001f, "sin/cos test"},
509 {4, 0, {0.8536f, 0.8536f, 0.0f, 0.0f}, 0.001f, "sin/cos test"},
510 {5, 0, {0.9157f, 0.7778f, 0.0f, 0.0f}, 0.001f, "sin/cos test"},
511 {6, 0, {0.9620f, 0.6913f, 0.0f, 0.0f}, 0.001f, "sin/cos test"},
512 {7, 0, {0.9904f, 0.5975f, 0.0f, 0.0f}, 0.001f, "sin/cos test"},
513 {8, 0, {1.0000f, 0.5000f, 0.0f, 0.0f}, 0.001f, "sin/cos test"},
514 {9, 0, {0.9904f, 0.4025f, 0.0f, 0.0f}, 0.001f, "sin/cos test"},
515 {10, 0, {0.9619f, 0.3087f, 0.0f, 0.0f}, 0.001f, "sin/cos test"},
516 {11, 0, {0.9157f, 0.2222f, 0.0f, 0.0f}, 0.001f, "sin/cos test"},
517 {12, 0, {0.8536f, 0.1464f, 0.0f, 0.0f}, 0.001f, "sin/cos test"},
518 {13, 0, {0.7778f, 0.0843f, 0.0f, 0.0f}, 0.001f, "sin/cos test"},
519 {14, 0, {0.6913f, 0.0381f, 0.0f, 0.0f}, 0.001f, "sin/cos test"},
520 {15, 0, {0.5975f, 0.0096f, 0.0f, 0.0f}, 0.001f, "sin/cos test"},
521 {16, 0, {0.5000f, 0.0000f, 0.0f, 0.0f}, 0.001f, "sin/cos test"},
522 {17, 0, {0.4025f, 0.0096f, 0.0f, 0.0f}, 0.001f, "sin/cos test"},
523 {18, 0, {0.3087f, 0.0381f, 0.0f, 0.0f}, 0.001f, "sin/cos test"},
524 {19, 0, {0.2222f, 0.0843f, 0.0f, 0.0f}, 0.001f, "sin/cos test"},
525 {20, 0, {0.1464f, 0.1464f, 0.0f, 0.0f}, 0.001f, "sin/cos test"},
526 {21, 0, {0.0843f, 0.2222f, 0.0f, 0.0f}, 0.001f, "sin/cos test"},
527 {22, 0, {0.0381f, 0.3087f, 0.0f, 0.0f}, 0.001f, "sin/cos test"},
528 {23, 0, {0.0096f, 0.4025f, 0.0f, 0.0f}, 0.001f, "sin/cos test"},
529 {24, 0, {0.0000f, 0.5000f, 0.0f, 0.0f}, 0.001f, "sin/cos test"},
530 {25, 0, {0.0096f, 0.5975f, 0.0f, 0.0f}, 0.001f, "sin/cos test"},
531 {26, 0, {0.0381f, 0.6913f, 0.0f, 0.0f}, 0.001f, "sin/cos test"},
532 {27, 0, {0.0843f, 0.7778f, 0.0f, 0.0f}, 0.001f, "sin/cos test"},
533 {28, 0, {0.1464f, 0.8536f, 0.0f, 0.0f}, 0.001f, "sin/cos test"},
534 {29, 0, {0.2222f, 0.9157f, 0.0f, 0.0f}, 0.001f, "sin/cos test"},
535 {30, 0, {0.3087f, 0.9619f, 0.0f, 0.0f}, 0.001f, "sin/cos test"},
536 {31, 0, {0.4025f, 0.9904f, 0.0f, 0.0f}, 0.001f, "sin/cos test"},
537 };
538
539 static const char *sincos_shader =
540 "float4 test(float x: TEXCOORD0): COLOR\n"
541 "{\n"
542 " const float pi2 = 6.2831853;\n"
543 " float calcd_sin = (sin(x * pi2) + 1)/2;\n"
544 " float calcd_cos = (cos(x * pi2) + 1)/2;\n"
545 " return float4(calcd_sin, calcd_cos, 0, 0);\n"
546 "}";
547
548 ID3DXConstantTable *constants;
549 IDirect3DPixelShader9 *pshader;
550
551 pshader = compile_pixel_shader9(device, sincos_shader, "ps_2_0", &constants);
552 if (pshader != NULL)
553 {
554 compute_shader_probe9(device, vshader_passthru, pshader, quad_geometry, sincos_probes,
555 ARRAY_SIZE(sincos_probes), 32, 1, __LINE__);
556
559 }
560}
561
562static void test_fail(IDirect3DDevice9 *device, IDirect3DVertexBuffer9 *qquad_geometry,
563 IDirect3DVertexShader9 *vshader_passthru)
564{
565 static const char *tests[] =
566 {
567 "float4 test(float2 pos: TEXCOORD0) : COLOR\n"
568 "{\n"
569 " return y;\n"
570 "}",
571
572 "float4 test(float2 pos: TEXCOORD0) : COLOR\n"
573 "{\n"
574 " float4 x = float4(0, 0, 0, 0);\n"
575 " x.xzzx = float4(1, 2, 3, 4);\n"
576 " return x;\n"
577 "}",
578
579 "float4 test(float2 pos: TEXCOORD0) : COLOR\n"
580 "{\n"
581 " float4 x = pos;\n"
582 " return x;\n"
583 "}",
584
585 "float4 test(float2 pos, TEXCOORD0) ; COLOR\n"
586 "{\n"
587 " pos = float4 x;\n"
588 " mul(float4(5, 4, 3, 2), mvp) = x;\n"
589 " return float4;\n"
590 "}",
591
592 "float4 563r(float2 45s: TEXCOORD0) : COLOR\n"
593 "{\n"
594 " float2 x = 45s;\n"
595 " return float4(x.x, x.y, 0, 0);\n"
596 "}",
597
598 "float4 test(float2 pos: TEXCOORD0) : COLOR\n"
599 "{\n"
600 " struct { int b,c; } x = {0};\n"
601 " return y;\n"
602 "}",
603
604 "float4 test(float2 pos: TEXCOORD0) : COLOR\n"
605 "{\n"
606 " struct {} x = {};\n"
607 " return y;\n"
608 "}",
609 };
610
611 ID3D10Blob *compiled, *errors;
612 unsigned int i;
613 HRESULT hr;
614
615 for (i = 0; i < ARRAY_SIZE(tests); ++i)
616 {
617 compiled = errors = NULL;
618 hr = ppD3DCompile(tests[i], strlen(tests[i]), NULL, NULL, NULL, "test", "ps_2_0", 0, 0, &compiled, &errors);
619 ok(hr == E_FAIL, "Test %u, got unexpected hr %#x.\n", i, hr);
620 ok(!!errors, "Test %u, expected non-NULL error blob.\n", i);
621 ok(!compiled, "Test %u, expected no compiled shader blob.\n", i);
622 ID3D10Blob_Release(errors);
623 }
624}
625
627{
629
630 if (!(module = LoadLibraryA("d3dcompiler_43.dll"))) return FALSE;
631
632 ppD3DCompile = (void*)GetProcAddress(module, "D3DCompile");
633 return TRUE;
634}
635
637{
638 D3DCAPS9 caps;
639 ULONG refcount;
640 IDirect3DDevice9 *device;
641 IDirect3DVertexDeclaration9 *vdeclaration;
642 IDirect3DVertexBuffer9 *quad_geometry;
643 IDirect3DVertexShader9 *vshader_passthru;
644
645 if (!load_d3dcompiler())
646 {
647 win_skip("Could not load d3dcompiler_43.dll\n");
648 return;
649 }
650
651 device = init_d3d9(&vdeclaration, &quad_geometry, &vshader_passthru);
652 if (!device) return;
653
654 /* Make sure we support pixel shaders, before trying to compile them! */
655 /* Direct3D 9 (Shader model 1-3 tests) */
657 if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0))
658 {
660 {
661 test_swizzle(device, quad_geometry, vshader_passthru);
662 test_math(device, quad_geometry, vshader_passthru);
663 test_conditionals(device, quad_geometry, vshader_passthru);
664 test_float_vectors(device, quad_geometry, vshader_passthru);
665 test_trig(device, quad_geometry, vshader_passthru);
666 test_fail(device, quad_geometry, vshader_passthru);
667 }
668 } else skip("no pixel shader support\n");
669
670 /* Reference counting sanity checks */
671 if (vshader_passthru)
672 {
673 refcount = IDirect3DVertexShader9_Release(vshader_passthru);
674 ok(!refcount, "Pass-through vertex shader has %u references left\n", refcount);
675 }
676
677 refcount = IDirect3DVertexBuffer9_Release(quad_geometry);
678 ok(!refcount, "Vertex buffer has %u references left\n", refcount);
679
680 refcount = IDirect3DVertexDeclaration9_Release(vdeclaration);
681 ok(!refcount, "Vertex declaration has %u references left\n", refcount);
682
684 ok(!refcount, "Device has %u references left\n", refcount);
685}
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define START_TEST(x)
Definition: atltest.h:75
#define ARRAY_SIZE(A)
Definition: main.h:33
#define D3DPS_VERSION(major, minor)
Definition: d3d8types.h:474
@ D3DMULTISAMPLE_NONE
Definition: d3d8types.h:672
@ D3DFMT_X8R8G8B8
Definition: d3d8types.h:605
#define D3DUSAGE_WRITEONLY
Definition: d3d8types.h:93
@ D3DRTYPE_SURFACE
Definition: d3d8types.h:810
@ D3DSWAPEFFECT_DISCARD
Definition: d3d8types.h:851
@ D3DPT_TRIANGLESTRIP
Definition: d3d8types.h:722
@ D3DDEVTYPE_HAL
Definition: d3d8types.h:576
@ D3DPOOL_DEFAULT
Definition: d3d8types.h:709
@ D3DPOOL_SYSTEMMEM
Definition: d3d8types.h:711
enum _D3DFORMAT D3DFORMAT
#define D3DCOLOR_XRGB(r, g, b)
Definition: d3d8types.h:44
@ D3DTS_PROJECTION
Definition: d3d8types.h:956
#define D3DCLEAR_TARGET
Definition: d3d8types.h:30
#define D3DLOCK_READONLY
Definition: d3d8types.h:69
IDirect3D9 *WINAPI Direct3DCreate9(UINT SDKVersion)
Definition: d3d9.c:57
#define IDirect3DDevice9_EndScene(p)
Definition: d3d9.h:1549
#define IDirect3DDevice9_BeginScene(p)
Definition: d3d9.h:1548
#define IDirect3DVertexBuffer9_Unlock(p)
Definition: d3d9.h:708
#define IDirect3DDevice9_CreatePixelShader(p, a, b)
Definition: d3d9.h:1613
#define IDirect3DDevice9_CreateVertexDeclaration(p, a, b)
Definition: d3d9.h:1593
#define IDirect3DVertexBuffer9_Release(p)
Definition: d3d9.h:696
#define IDirect3DSurface9_LockRect(p, a, b, c)
Definition: d3d9.h:635
#define IDirect3D9_CreateDevice(p, a, b, c, d, e, f)
Definition: d3d9.h:235
#define IDirect3DVertexBuffer9_Lock(p, a, b, c, d)
Definition: d3d9.h:707
#define IDirect3DDevice9_GetRenderTargetData(p, a, b)
Definition: d3d9.h:1539
#define IDirect3DDevice9_SetRenderTarget(p, a, b)
Definition: d3d9.h:1544
#define IDirect3DDevice9_SetPixelShader(p, a)
Definition: d3d9.h:1614
#define IDirect3DDevice9_Present(p, a, b, c, d)
Definition: d3d9.h:1524
#define IDirect3DDevice9_GetDeviceCaps(p, a)
Definition: d3d9.h:1514
#define IDirect3DVertexDeclaration9_Release(p)
Definition: d3d9.h:1185
#define IDirect3DDevice9_SetStreamSource(p, a, b, c, d)
Definition: d3d9.h:1607
#define IDirect3DDevice9_SetTransform(p, a, b)
Definition: d3d9.h:1551
#define IDirect3DPixelShader9_Release(p)
Definition: d3d9.h:1261
#define IDirect3D9_Release(p)
Definition: d3d9.h:220
#define IDirect3DVertexShader9_Release(p)
Definition: d3d9.h:1223
#define IDirect3DDevice9_DrawPrimitive(p, a, b, c)
Definition: d3d9.h:1588
#define IDirect3DDevice9_SetVertexShader(p, a)
Definition: d3d9.h:1599
#define IDirect3DDevice9_Release(p)
Definition: d3d9.h:1508
#define IDirect3DDevice9_Clear(p, a, b, c, d, e, f)
Definition: d3d9.h:1550
#define IDirect3D9_CheckDeviceFormat(p, a, b, c, d, e, f)
Definition: d3d9.h:229
#define IDirect3DSurface9_UnlockRect(p)
Definition: d3d9.h:636
#define IDirect3DDevice9_CreateVertexBuffer(p, a, b, c, d, e, f)
Definition: d3d9.h:1533
#define IDirect3DSurface9_Release(p)
Definition: d3d9.h:622
#define IDirect3DDevice9_SetVertexDeclaration(p, a)
Definition: d3d9.h:1594
#define IDirect3DDevice9_CreateRenderTarget(p, a, b, c, d, e, f, g, h)
Definition: d3d9.h:1535
#define IDirect3DDevice9_CreateVertexShader(p, a, b)
Definition: d3d9.h:1598
#define IDirect3DDevice9_CreateOffscreenPlainSurface(p, a, b, c, d, e, f)
Definition: d3d9.h:1543
@ D3DDECLUSAGE_TEXCOORD
Definition: d3d9types.h:225
@ D3DDECLUSAGE_POSITION
Definition: d3d9types.h:220
@ D3DDECLTYPE_FLOAT3
Definition: d3d9types.h:257
@ D3DDECLTYPE_FLOAT2
Definition: d3d9types.h:256
#define D3DDECL_END()
Definition: d3d9types.h:311
@ D3DFMT_A32B32G32R32F
Definition: d3d9types.h:836
@ D3DDECLMETHOD_DEFAULT
Definition: d3d9types.h:242
#define D3D_OK
Definition: d3d.h:106
HRESULT(WINAPI * pD3DCompile)(const void *data, SIZE_T data_size, const char *filename, const D3D_SHADER_MACRO *defines, ID3DInclude *include, const char *entrypoint, const char *target, UINT sflags, UINT eflags, ID3DBlob **shader, ID3DBlob **error_messages)
Definition: d3dcompiler.h:71
#define ID3DXConstantTable_Release(p)
Definition: d3dx9shader.h:177
#define ID3DXConstantTable_SetVector(p, a, b, c)
Definition: d3dx9shader.h:196
#define ID3DXConstantTable_SetFloat(p, a, b, c)
Definition: d3dx9shader.h:194
#define ID3DXConstantTable_SetInt(p, a, b, c)
Definition: d3dx9shader.h:192
#define E_FAIL
Definition: ddrawi.h:102
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
D3DXMATRIX *WINAPI D3DXMatrixOrthoLH(D3DXMATRIX *pout, FLOAT w, FLOAT h, FLOAT zn, FLOAT zf)
Definition: math.c:431
HRESULT WINAPI D3DXGetShaderConstantTable(const DWORD *byte_code, ID3DXConstantTable **constant_table)
Definition: shader.c:2111
#define GetProcAddress(x, y)
Definition: compat.h:753
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryA(LPCSTR lpLibFileName)
Definition: loader.c:111
unsigned int BOOL
Definition: ntddk_ex.h:94
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
const GLdouble * v
Definition: gl.h:2040
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
GLint GLint GLsizei width
Definition: gl.h:1546
GLuint shader
Definition: glext.h:6030
GLuint index
Definition: glext.h:6031
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:6102
GLdouble GLdouble z
Definition: glext.h:5874
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
static pD3DCompile ppD3DCompile
Definition: hlsl.c:25
static IDirect3DPixelShader9 * compile_pixel_shader9(IDirect3DDevice9 *device, const char *shader, const char *profile, ID3DXConstantTable **constants)
Definition: hlsl.c:170
static void test_math(IDirect3DDevice9 *device, IDirect3DVertexBuffer9 *quad_geometry, IDirect3DVertexShader9 *vshader_passthru)
Definition: hlsl.c:332
static BOOL colors_match(D3DXCOLOR a, D3DXCOLOR b, float epsilon)
Definition: hlsl.c:242
static IDirect3DDevice9 * init_d3d9(IDirect3DVertexDeclaration9 **vdeclaration, IDirect3DVertexBuffer9 **quad_geometry, IDirect3DVertexShader9 **vshader_passthru)
Definition: hlsl.c:55
static void test_fail(IDirect3DDevice9 *device, IDirect3DVertexBuffer9 *qquad_geometry, IDirect3DVertexShader9 *vshader_passthru)
Definition: hlsl.c:562
static void draw_quad_with_shader9(IDirect3DDevice9 *device, IDirect3DVertexBuffer9 *quad_geometry)
Definition: hlsl.c:195
static void test_trig(IDirect3DDevice9 *device, IDirect3DVertexBuffer9 *quad_geometry, IDirect3DVertexShader9 *vshader_passthru)
Definition: hlsl.c:500
static void set_float4_d3d9(IDirect3DDevice9 *device, ID3DXConstantTable *constants, const char *name, float x, float y, float z, float w)
Definition: hlsl.c:158
static void setup_device9(IDirect3DDevice9 *device, IDirect3DSurface9 **render_target, IDirect3DSurface9 **readback, D3DFORMAT format, unsigned int width, unsigned int height, IDirect3DVertexShader9 *vshader, IDirect3DPixelShader9 *pshader)
Definition: hlsl.c:218
static void test_conditionals(IDirect3DDevice9 *device, IDirect3DVertexBuffer9 *quad_geometry, IDirect3DVertexShader9 *vshader_passthru)
Definition: hlsl.c:375
static void test_float_vectors(IDirect3DDevice9 *device, IDirect3DVertexBuffer9 *quad_geometry, IDirect3DVertexShader9 *vshader_passthru)
Definition: hlsl.c:439
static HWND create_window(void)
Definition: hlsl.c:45
static void test_swizzle(IDirect3DDevice9 *device, IDirect3DVertexBuffer9 *quad_geometry, IDirect3DVertexShader9 *vshader_passthru)
Definition: hlsl.c:298
static void compute_shader_probe9(IDirect3DDevice9 *device, IDirect3DVertexShader9 *vshader, IDirect3DPixelShader9 *pshader, IDirect3DVertexBuffer9 *quad_geometry, const struct hlsl_probe_info *probes, unsigned int count, unsigned int width, unsigned int height, unsigned int line_number)
Definition: hlsl.c:250
static BOOL load_d3dcompiler(void)
Definition: hlsl.c:626
_Check_return_ _CRT_JIT_INTRINSIC double __cdecl fabs(_In_ double x)
Definition: fabs.c:17
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
#define profile
Definition: kernel32.h:12
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static struct test_info tests[]
constants
Definition: resource.c:29
#define todo_wine
Definition: custom.c:79
#define D3DADAPTER_DEFAULT
Definition: d3d8.h:57
#define D3DCREATE_HARDWARE_VERTEXPROCESSING
Definition: d3d8.h:45
#define D3D_SDK_VERSION
Definition: d3d8.h:56
#define win_skip
Definition: test.h:160
static long line_number
Definition: main.cpp:17
HRESULT hr
Definition: shlfolder.c:183
FLOAT g
Definition: d3dx9math.h:262
FLOAT a
Definition: d3dx9math.h:262
FLOAT b
Definition: d3dx9math.h:262
FLOAT r
Definition: d3dx9math.h:262
DWORD PixelShaderVersion
Definition: d3d9caps.h:315
D3DSWAPEFFECT SwapEffect
Definition: d3d8types.h:1128
LPCSTR lpszClassName
Definition: winuser.h:3172
WNDPROC lpfnWndProc
Definition: winuser.h:3164
Definition: devices.h:37
float epsilon
Definition: hlsl.c:40
const char * message
Definition: hlsl.c:42
unsigned int x
Definition: hlsl.c:36
unsigned int y
Definition: hlsl.c:36
D3DXCOLOR c
Definition: hlsl.c:38
Definition: name.c:39
Definition: mesh.c:4558
float ty
Definition: hlsl.c:30
float x
Definition: hlsl.c:29
float tx
Definition: hlsl.c:30
float y
Definition: hlsl.c:29
float z
Definition: hlsl.c:29
uint32_t ULONG
Definition: typedefs.h:59
#define ZeroMemory
Definition: winbase.h:1712
LRESULT WINAPI DefWindowProcA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define CreateWindowA(a, b, c, d, e, f, g, h, i, j, k)
Definition: winuser.h:4315
ATOM WINAPI RegisterClassA(_In_ CONST WNDCLASSA *)