ReactOS  0.4.14-dev-999-g61c8d34
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 
27 struct 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 
45 static 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 
55 static 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  {
70  D3DDECL_END()
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 
90  d3d9_ptr = Direct3DCreate9(D3D_SDK_VERSION);
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 */
158 static 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 */
170 static 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 */
195 static 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 
218 static 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 
242 static 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. */
250 static 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;
259  D3DLOCKED_RECT lr;
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 
283  hr = IDirect3DSurface9_UnlockRect(readback);
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);
294  IDirect3DSurface9_Release(readback);
295 }
296 
297 /* Now the actual test functions */
298 static 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 
332 static 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 
375 static 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 
439 static 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 
500 static 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 
562 static 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 
626 static BOOL load_d3dcompiler(void)
627 {
628  HMODULE module;
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  {
659  todo_wine
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 
683  refcount = IDirect3DDevice9_Release(device);
684  ok(!refcount, "Device has %u references left\n", refcount);
685 }
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
#define IDirect3D9_CreateDevice(p, a, b, c, d, e, f)
Definition: d3d9.h:235
#define D3DADAPTER_DEFAULT
Definition: d3d8.h:57
#define IDirect3DDevice9_CreateVertexBuffer(p, a, b, c, d, e, f)
Definition: d3d9.h:1533
#define IDirect3DSurface9_Release(p)
Definition: d3d9.h:622
#define IDirect3D9_CheckDeviceFormat(p, a, b, c, d, e, f)
Definition: d3d9.h:229
struct param_test tests[]
GLint GLint GLsizei width
Definition: gl.h:1546
#define TRUE
Definition: types.h:120
#define IDirect3DDevice9_Clear(p, a, b, c, d, e, f)
Definition: d3d9.h:1550
HMODULE module
Definition: main.cpp:47
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:6102
Definition: mesh.c:4557
static IDirect3DDevice9 * init_d3d9(IDirect3DVertexDeclaration9 **vdeclaration, IDirect3DVertexBuffer9 **quad_geometry, IDirect3DVertexShader9 **vshader_passthru)
Definition: hlsl.c:55
START_TEST(hlsl)
Definition: hlsl.c:636
float z
Definition: hlsl.c:29
const char * message
Definition: hlsl.c:42
HRESULT hr
Definition: shlfolder.c:183
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
static BOOL load_d3dcompiler(void)
Definition: hlsl.c:626
#define IDirect3DVertexBuffer9_Unlock(p)
Definition: d3d9.h:708
static BOOL colors_match(D3DXCOLOR a, D3DXCOLOR b, float epsilon)
Definition: hlsl.c:242
GLuint GLuint GLsizei count
Definition: gl.h:1545
unsigned int y
Definition: hlsl.c:36
D3DXMATRIX *WINAPI D3DXMatrixOrthoLH(D3DXMATRIX *pout, FLOAT w, FLOAT h, FLOAT zn, FLOAT zf)
Definition: math.c:427
#define IDirect3DPixelShader9_Release(p)
Definition: d3d9.h:1261
#define ZeroMemory
Definition: winbase.h:1642
FLOAT g
Definition: d3dx9math.h:262
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
unsigned int x
Definition: hlsl.c:36
#define IDirect3DDevice9_CreateVertexDeclaration(p, a, b)
Definition: d3d9.h:1593
FLOAT a
Definition: d3dx9math.h:262
#define IDirect3DDevice9_CreateRenderTarget(p, a, b, c, d, e, f, g, h)
Definition: d3d9.h:1535
int line_number
Definition: parser.yy.c:775
#define D3DUSAGE_WRITEONLY
Definition: d3d8types.h:93
#define ID3DXConstantTable_Release(p)
Definition: d3dx9shader.h:177
#define IDirect3DDevice9_DrawPrimitive(p, a, b, c)
Definition: d3d9.h:1588
static void test_float_vectors(IDirect3DDevice9 *device, IDirect3DVertexBuffer9 *quad_geometry, IDirect3DVertexShader9 *vshader_passthru)
Definition: hlsl.c:439
#define ID3DXConstantTable_SetFloat(p, a, b, c)
Definition: d3dx9shader.h:194
FLOAT r
Definition: d3dx9math.h:262
#define E_FAIL
Definition: ddrawi.h:102
static IDirect3DPixelShader9 * compile_pixel_shader9(IDirect3DDevice9 *device, const char *shader, const char *profile, ID3DXConstantTable **constants)
Definition: hlsl.c:170
#define D3DPS_VERSION(major, minor)
Definition: d3d8types.h:474
IDirect3D9 *WINAPI Direct3DCreate9(UINT SDKVersion)
Definition: d3d9.c:57
float ty
Definition: hlsl.c:30
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
#define IDirect3DDevice9_SetRenderTarget(p, a, b)
Definition: d3d9.h:1544
static void test_conditionals(IDirect3DDevice9 *device, IDirect3DVertexBuffer9 *quad_geometry, IDirect3DVertexShader9 *vshader_passthru)
Definition: hlsl.c:375
#define IDirect3DDevice9_CreateOffscreenPlainSurface(p, a, b, c, d, e, f)
Definition: d3d9.h:1543
#define IDirect3D9_Release(p)
Definition: d3d9.h:220
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
unsigned int BOOL
Definition: ntddk_ex.h:94
Definition: devices.h:37
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryA(LPCSTR lpLibFileName)
Definition: loader.c:111
#define CreateWindowA(a, b, c, d, e, f, g, h, i, j, k)
Definition: winuser.h:4290
GLdouble GLdouble z
Definition: glext.h:5874
#define IDirect3DDevice9_SetStreamSource(p, a, b, c, d)
Definition: d3d9.h:1607
#define IDirect3DDevice9_Release(p)
Definition: d3d9.h:1508
smooth NULL
Definition: ftsmooth.c:416
static void test_swizzle(IDirect3DDevice9 *device, IDirect3DVertexBuffer9 *quad_geometry, IDirect3DVertexShader9 *vshader_passthru)
Definition: hlsl.c:298
GLuint index
Definition: glext.h:6031
enum _D3DFORMAT D3DFORMAT
float x
Definition: hlsl.c:29
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
#define IDirect3DDevice9_CreateVertexShader(p, a, b)
Definition: d3d9.h:1598
struct D3DXCOLOR D3DXCOLOR
#define IDirect3DDevice9_EndScene(p)
Definition: d3d9.h:1549
#define IDirect3DDevice9_SetPixelShader(p, a)
Definition: d3d9.h:1614
static pD3DCompile ppD3DCompile
Definition: hlsl.c:25
GLuint shader
Definition: glext.h:6030
static HWND create_window(void)
Definition: hlsl.c:45
GLfloat f
Definition: glext.h:7540
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
#define D3D_SDK_VERSION
Definition: d3d8.h:56
LONG HRESULT
Definition: typedefs.h:78
#define IDirect3DVertexShader9_Release(p)
Definition: d3d9.h:1223
float epsilon
Definition: hlsl.c:40
#define IDirect3DVertexBuffer9_Lock(p, a, b, c, d)
Definition: d3d9.h:707
static void set_float4_d3d9(IDirect3DDevice9 *device, ID3DXConstantTable *constants, const char *name, float x, float y, float z, float w)
Definition: hlsl.c:158
HRESULT WINAPI D3DXGetShaderConstantTable(const DWORD *byte_code, ID3DXConstantTable **constant_table)
Definition: shader.c:2104
#define D3DCOLOR_XRGB(r, g, b)
Definition: d3d8types.h:44
#define IDirect3DDevice9_SetTransform(p, a, b)
Definition: d3d9.h:1551
#define todo_wine
Definition: test.h:162
float tx
Definition: hlsl.c:30
#define IDirect3DVertexBuffer9_Release(p)
Definition: d3d9.h:696
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
DWORD PixelShaderVersion
Definition: d3d9caps.h:315
FLOAT b
Definition: d3dx9math.h:262
LRESULT WINAPI DefWindowProcA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define D3DDECL_END()
Definition: d3d9types.h:311
LPCSTR lpszClassName
Definition: winuser.h:3147
#define IDirect3DDevice9_CreatePixelShader(p, a, b)
Definition: d3d9.h:1613
#define IDirect3DDevice9_SetVertexShader(p, a)
Definition: d3d9.h:1599
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
_Check_return_ _CRT_JIT_INTRINSIC double __cdecl fabs(_In_ double x)
static void test_fail(IDirect3DDevice9 *device, IDirect3DVertexBuffer9 *qquad_geometry, IDirect3DVertexShader9 *vshader_passthru)
Definition: hlsl.c:562
#define ID3DXConstantTable_SetInt(p, a, b, c)
Definition: d3dx9shader.h:192
#define D3D_OK
Definition: d3d.h:106
const GLdouble * v
Definition: gl.h:2040
#define ARRAY_SIZE(a)
Definition: main.h:24
#define IDirect3DDevice9_GetDeviceCaps(p, a)
Definition: d3d9.h:1514
#define ok(value,...)
Definition: atltest.h:57
constants
Definition: resource.c:29
#define IDirect3DDevice9_GetRenderTargetData(p, a, b)
Definition: d3d9.h:1539
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_math(IDirect3DDevice9 *device, IDirect3DVertexBuffer9 *quad_geometry, IDirect3DVertexShader9 *vshader_passthru)
Definition: hlsl.c:332
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
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
WNDPROC lpfnWndProc
Definition: winuser.h:3139
#define IDirect3DSurface9_UnlockRect(p)
Definition: d3d9.h:636
#define skip(...)
Definition: atltest.h:64
D3DXCOLOR c
Definition: hlsl.c:38
Definition: name.c:38
#define D3DCREATE_HARDWARE_VERTEXPROCESSING
Definition: d3d8.h:45
float y
Definition: hlsl.c:29
unsigned int ULONG
Definition: retypes.h:1
#define GetProcAddress(x, y)
Definition: compat.h:418
#define profile
Definition: kernel32.h:12
#define IDirect3DDevice9_Present(p, a, b, c, d)
Definition: d3d9.h:1524
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
#define IDirect3DSurface9_LockRect(p, a, b, c)
Definition: d3d9.h:635
#define D3DLOCK_READONLY
Definition: d3d8types.h:69
static void test_trig(IDirect3DDevice9 *device, IDirect3DVertexBuffer9 *quad_geometry, IDirect3DVertexShader9 *vshader_passthru)
Definition: hlsl.c:500
#define IDirect3DDevice9_SetVertexDeclaration(p, a)
Definition: d3d9.h:1594
#define win_skip
Definition: test.h:149
ATOM WINAPI RegisterClassA(_In_ CONST WNDCLASSA *)
#define IDirect3DDevice9_BeginScene(p)
Definition: d3d9.h:1548
#define IDirect3DVertexDeclaration9_Release(p)
Definition: d3d9.h:1185
static void draw_quad_with_shader9(IDirect3DDevice9 *device, IDirect3DVertexBuffer9 *quad_geometry)
Definition: hlsl.c:195
#define SUCCEEDED(hr)
Definition: intsafe.h:57
D3DSWAPEFFECT SwapEffect
Definition: d3d8types.h:1128
#define ID3DXConstantTable_SetVector(p, a, b, c)
Definition: d3dx9shader.h:196
#define D3DCLEAR_TARGET
Definition: d3d8types.h:30