[PATCH 5/6] d3dx9_36/tests: Added trigonometric functions test to HLSL test suite
Travis Athougies
iammisc at gmail.com
Wed Aug 4 17:07:19 CDT 2010
---
dlls/d3dx9_36/tests/hlsl.c | 122 ++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 122 insertions(+), 0 deletions(-)
diff --git a/dlls/d3dx9_36/tests/hlsl.c b/dlls/d3dx9_36/tests/hlsl.c
index ce206f9..609d9e3 100644
--- a/dlls/d3dx9_36/tests/hlsl.c
+++ b/dlls/d3dx9_36/tests/hlsl.c
@@ -141,6 +141,18 @@ static void set_float4(ID3DXConstantTable *constants, const char *name, float x,
ID3DXConstantTable_SetVector(constants, device, name, &vector);
}
+/* Compare floating point arrays keeping a count of how many
+ erroneous values we have found */
+static int cmp_results_linear(int samples, float epsilon, float *expected, float *actual)
+{
+ int result = 0;
+ int i = 0;
+ for(i = 0;i < samples;i++)
+ if(abs(expected[i] - actual[i]) > epsilon)
+ result ++;
+ return result;
+}
+
/* Compile our pixel shader and get back the compiled version and a constant
table */
static IDirect3DPixelShader9* compile_pixel_shader(const char *shader, const char *profile, ID3DXConstantTable **constants)
@@ -217,6 +229,40 @@ static void setup_device(IDirect3DSurface9 **render_target, IDirect3DSurface9 **
/* For all compute_shader_* calls, this framework assumes that the data types are 4 bytes
long. The two formats used here are D3DFMT_R32F and D3DFMT_A8R8G8B8 */
+/* Repeatedly call a shader with linearly varying values and collect the results */
+static void* compute_shader_linear(IDirect3DPixelShader9 *pshader, ID3DXConstantTable *constants, D3DFORMAT format, int samples)
+{
+ IDirect3DSurface9 *render_target;
+ IDirect3DSurface9 *readback;
+ int i;
+
+ HRESULT hr;
+ void *ret = NULL;
+ D3DLOCKED_RECT lr;
+
+ setup_device(&render_target, &readback, format, samples, 1, vshader_passthru, pshader);
+
+ ret = HeapAlloc(GetProcessHeap(), 0, 4 * samples);
+ for(i = 0;i < 32;i++) {
+ ID3DXConstantTable_SetFloat(constants, device, "$x", ((float) i)/((float) samples));
+ draw_quad_with_shader();
+
+ IDirect3DDevice9_GetRenderTargetData(device, render_target, readback);
+
+ hr = IDirect3DSurface9_LockRect(readback, &lr, NULL, D3DLOCK_READONLY);
+ ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned: %08x\n", hr);
+ memcpy((void*) (((DWORD) ret) + (4 * i)), lr.pBits, 4);
+ hr = IDirect3DSurface9_UnlockRect(readback);
+ ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned: %08x\n", hr);
+ }
+
+ /* release everything */
+ IUnknown_Release(render_target);
+ IUnknown_Release(readback);
+
+ return ret;
+}
+
/* Compute a shader on a fullscreen quad and get the results back */
static void* compute_shader_fullscreen(IDirect3DPixelShader9 *pshader, D3DFORMAT format, int width, int height)
{
@@ -426,6 +472,81 @@ static void test_float_vectors(void)
}
}
+static void test_trig(void)
+{
+ static float sin_expected[] = {
+ 0.500000f, 0.597545f, 0.691341f, 0.777785f,
+ 0.853553f, 0.915734f, 0.961939f, 0.990392f,
+ 1.000000f, 0.990392f, 0.961939f, 0.915734f,
+ 0.853553f, 0.777785f, 0.691341f, 0.597545f,
+ 0.500000f, 0.402454f, 0.308658f, 0.222214f,
+ 0.146446f, 0.084265f, 0.038060f, 0.009607f,
+ 0.000000f, 0.009607f, 0.038060f, 0.084265f,
+ 0.146446f, 0.222214f, 0.308658f, 0.402454f,
+ };
+
+ static float cos_expected[] = {
+ 1.000000f, 0.990392f, 0.961939f, 0.915734f,
+ 0.853553f, 0.777785f, 0.691341f, 0.597545f,
+ 0.500000f, 0.402454f, 0.308658f, 0.222214f,
+ 0.146446f, 0.084265f, 0.038060f, 0.009607f,
+ 0.000000f, 0.009607f, 0.038060f, 0.084265f,
+ 0.146446f, 0.222214f, 0.308658f, 0.402454f,
+ 0.500000f, 0.597545f, 0.691341f, 0.777785f,
+ 0.853553f, 0.915734f, 0.961939f, 0.990392f,
+ };
+
+ static const char *sin_shader =
+ "float4 test(uniform float x): COLOR \
+ { \
+ const float pi2 = 6.2831853; \
+ float calcd = (sin(x * pi2) + 1)/2; \
+ return calcd; \
+ }";
+
+ static const char *cos_shader =
+ "float4 test(uniform float x): COLOR \
+ { \
+ const float pi2 = 6.2831853; \
+ float calcd = (cos(x * pi2) + 1)/2; \
+ return calcd; \
+ }";
+
+ ID3DXConstantTable* constants;
+ IDirect3DPixelShader9* pshader;
+ void* data;
+ int errors = 0;
+
+ pshader = compile_pixel_shader(sin_shader, "ps_2_0", &constants);
+ if(pshader != NULL)
+ {
+
+ data = compute_shader_linear(pshader, constants, D3DFMT_R32F, 32);
+
+ errors = cmp_results_linear(32, 0.00001, sin_expected, data);
+ ok(errors == 0, "sin: Got %d unexpected values\n", errors);
+
+ HeapFree(GetProcessHeap(), 0, data);
+
+ IUnknown_Release(constants);
+ IUnknown_Release(pshader);
+ }
+
+ pshader = compile_pixel_shader(cos_shader, "ps_2_0", &constants);
+ if(pshader != NULL)
+ {
+ data = compute_shader_linear(pshader, constants, D3DFMT_R32F, 32);
+
+ errors = cmp_results_linear(32, 0.00001, cos_expected, data);
+ ok(errors == 0, "cos: Got %d unexpected values\n", errors);
+
+ HeapFree(GetProcessHeap(), 0, data);
+
+ IUnknown_Release(constants);
+ IUnknown_Release(pshader);
+ }
+}
+
/* The heart of our little testing framework */
START_TEST(hlsl)
{
@@ -443,6 +564,7 @@ START_TEST(hlsl)
test_math();
test_conditionals();
test_float_vectors();
+ test_trig();
}
} else skip("no pixel shader support\n");
--
1.6.4.4
More information about the wine-patches
mailing list