/*
 * Copyright (C) 2010 Travis Athougies
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */
#define COBJMACROS
#include "wine/test.h"
#include "d3dx9.h"
#include "d3dcompiler.h"

#include <math.h>

struct vertex
{
    float x, y, z;
    float tx, ty;
};

/* Tells compute_shader_probe* which pixels should be what colors */
struct hlsl_probe_info
{
    unsigned int x, y;
    /* The expected values in this region */
    D3DXCOLOR c;
    /* The max error for any value */
    float epsilon;
    /* An error message to print if this test fails */
    const char *message;
};

static HWND create_window(void)
{
    WNDCLASS wc = {0};
    wc.lpfnWndProc = DefWindowProc;
    wc.lpszClassName = "d3d9_test_wc";
    RegisterClass(&wc);

    return CreateWindow("d3d9_test_wc", "d3d9_test",
            0, 0, 0, 0, 0, 0, 0, 0, 0);
}

static IDirect3DDevice9 *init_d3d9(IDirect3DVertexDeclaration9 **vdeclaration,
        IDirect3DVertexBuffer9 **quad_geometry, IDirect3DVertexShader9 **vshader_passthru)
{
    static const struct vertex quad_vertices[4] =
    {
        {-1.0f, -1.0f, 0.0f, 0.0f, 1.0f},
        {-1.0f,  1.0f, 0.0f, 0.0f, 0.0f},
        { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f},
        { 1.0f,  1.0f, 0.0f, 1.0f, 0.0f}
    };

    static const D3DVERTEXELEMENT9 vdeclelements[] =
    {
        {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
        {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
        D3DDECL_END()
    };

    static const char *vshader_passthru_hlsl =
        "float4 vshader(float4 pos: POSITION, inout float2 texcoord: TEXCOORD0): POSITION\n"
        "{\n"
        "   return pos;\n"
        "}";

    IDirect3D9 *d3d9_ptr;
    IDirect3DDevice9 *device_ptr = NULL;
    D3DPRESENT_PARAMETERS present_parameters;

    void *temp_geometry_vertices;

    ID3D10Blob *compiled = NULL;
    ID3D10Blob *errors = NULL;

    HRESULT hr;

    d3d9_ptr = Direct3DCreate9(D3D_SDK_VERSION);
    if (!d3d9_ptr)
    {
        skip("could not create D3D9\n");
        return NULL;
    }

    hr = IDirect3D9_CheckDeviceFormat(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
            0, D3DRTYPE_SURFACE, D3DFMT_A32B32G32R32F);
    if (FAILED(hr))
    {
        skip("A32B32G32R32F format not available on this device\n");
        return NULL;
    }

    ZeroMemory(&present_parameters, sizeof(present_parameters));
    present_parameters.Windowed = TRUE;
    present_parameters.hDeviceWindow = create_window();
    present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;

    hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, NULL,
            D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
    if (FAILED(hr))
    {
        skip("could not create Direct3D9 device\n");
        return NULL;
    }

    /* Create the quad geometry */
    hr = IDirect3DDevice9_CreateVertexBuffer(device_ptr, 4 * sizeof(struct vertex),
            D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, quad_geometry, NULL);
    ok(SUCCEEDED(hr),
            "Could not create vertex buffer, IDirect3DDevice9_CreateVertexBuffer returned: %08x\n", hr);

    hr = IDirect3DVertexBuffer9_Lock(*quad_geometry, 0, sizeof(quad_vertices), &temp_geometry_vertices, 0);
    ok(SUCCEEDED(hr), "IDirect3DVertexBuffer9_Lock returned: %08x\n", hr);
    memcpy(temp_geometry_vertices, quad_vertices, sizeof(quad_vertices));
    IDirect3DVertexBuffer9_Unlock(*quad_geometry);

    hr = IDirect3DDevice9_CreateVertexDeclaration(device_ptr, vdeclelements, vdeclaration);
    ok(SUCCEEDED(hr), "Could not create vertex declaration: "
            "IDirect3DDevice9_CreateVertexDeclaration returned: %08x\n", hr);

    hr = IDirect3DDevice9_SetVertexDeclaration(device_ptr, *vdeclaration);
    ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned: %08x\n", hr);

    /* Create a simple vertex shader to just pass through the values */
    hr = D3DCompile(vshader_passthru_hlsl, strlen(vshader_passthru_hlsl), NULL,
            NULL, NULL, "vshader", "vs_1_1", 0, 0, &compiled, &errors);
    if (FAILED(hr))
    {
        skip("not compiling vertex shader due to lacking wine HLSL support!\n");
        if (errors)
            IUnknown_Release(errors);
        return NULL;
    }

    hr = IDirect3DDevice9_CreateVertexShader(device_ptr, ID3D10Blob_GetBufferPointer(compiled),
            vshader_passthru);
    ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader returned: %08x\n", hr);
    IUnknown_Release(compiled);

    return device_ptr;
}

/* Convenience functions */
static void set_float4_d3d9(IDirect3DDevice9 *device, ID3DXConstantTable *constants, const char *name,
        float x, float y, float z, float w)
{
    D3DXVECTOR4 vector;
    vector.x = x;
    vector.y = y;
    vector.z = z;
    vector.w = w;
    ID3DXConstantTable_SetVector(constants, device, name, &vector);
}

/* Compile our pixel shader and get back the compiled version and a constant table */
static IDirect3DPixelShader9 *compile_pixel_shader9(IDirect3DDevice9 *device, const char *shader,
        const char *profile, ID3DXConstantTable **constants)
{
    ID3D10Blob *compiled = NULL;
    ID3D10Blob *errors = NULL;
    IDirect3DPixelShader9 *pshader;
    HRESULT hr;

    hr = D3DCompile(shader, strlen(shader), NULL, NULL,
            NULL, "test", profile, /* test is the name of the entry point of our shader */
            0, 0, &compiled, &errors);
    ok(hr == D3D_OK, "Pixel shader %s compilation failed: %s\n", shader,
            errors ? (char *)ID3D10Blob_GetBufferPointer(errors) : "");
    if (FAILED(hr)) return NULL;

    hr = D3DXGetShaderConstantTable(ID3D10Blob_GetBufferPointer(compiled), constants);
    ok(hr == D3D_OK, "Could not get constant table from compiled pixel shader\n");

    hr = IDirect3DDevice9_CreatePixelShader(device, ID3D10Blob_GetBufferPointer(compiled), &pshader);
    ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader returned: %08x\n", hr);
    IUnknown_Release(compiled);
    return pshader;
}

/* Draw a full screen quad */
static void draw_quad_with_shader9(IDirect3DDevice9 *device, IDirect3DVertexBuffer9 *quad_geometry)
{
    HRESULT hr;
    D3DXMATRIX projection_matrix;

    D3DXMatrixOrthoLH(&projection_matrix, 2.0f, 2.0f, 0.0f, 1.0f);
    IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &projection_matrix);

    hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
    ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned: %08x\n", hr);

    hr = IDirect3DDevice9_BeginScene(device);
    ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned: %08x\n", hr);

    hr = IDirect3DDevice9_SetStreamSource(device, 0, quad_geometry, 0, sizeof(struct vertex));
    ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource returned: %08x\n", hr);
    hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
    ok(hr == D3D_OK, "IDirect3DDevice9_DrawPrimitive returned: %08x\n", hr);

    hr = IDirect3DDevice9_EndScene(device);
    ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned: %08x\n", hr);
}

static void setup_device9(IDirect3DDevice9 *device, IDirect3DSurface9 **render_target,
        IDirect3DSurface9 **readback, D3DFORMAT format, unsigned int width, unsigned int height,
        IDirect3DVertexShader9 *vshader, IDirect3DPixelShader9 *pshader)
{
    HRESULT hr;
    hr = IDirect3DDevice9_CreateRenderTarget(device, width, height, format,
            D3DMULTISAMPLE_NONE, 0, FALSE, render_target, NULL);
    ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget returned: %08x\n", hr);

    /* The Direct3D 9 docs state that we cannot lock a render target surface,
       instead we must copy the render target onto this surface to lock it */
    hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, width, height, format,
            D3DPOOL_SYSTEMMEM, readback, NULL);
    ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface returned: %08x\n", hr);

    hr = IDirect3DDevice9_SetRenderTarget(device, 0, *render_target);
    ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget returned: %08x\n", hr);

    hr = IDirect3DDevice9_SetVertexShader(device, vshader);
    ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned: %08x\n", hr);
    hr = IDirect3DDevice9_SetPixelShader(device, pshader);
    ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned: %08x\n", hr);
}

static int colors_match(D3DXCOLOR a, D3DXCOLOR b, float epsilon)
{
  return (fabs(a.r - b.r) < epsilon && fabs(a.g - b.g) < epsilon && fabs(a.b - b.b) < epsilon &&
          fabs(a.a - b.a) < epsilon);
}

/* Compute a shader on a width by height buffer and probes certain locations
   to see if they are as expected. */
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)
{
    IDirect3DSurface9 *render_target;
    IDirect3DSurface9 *readback;

    HRESULT hr;
    D3DLOCKED_RECT lr;
    D3DXCOLOR *pbits_data;
    unsigned int i;

    setup_device9(device, &render_target, &readback, D3DFMT_A32B32G32R32F,
            width, height, vshader, pshader);

    /* Draw the quad with the shader and read back the data */
    draw_quad_with_shader9(device, quad_geometry);
    IDirect3DDevice9_GetRenderTargetData(device, render_target, readback);
    hr = IDirect3DSurface9_LockRect(readback, &lr, NULL, D3DLOCK_READONLY);
    ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned: %08x\n", hr);
    pbits_data = lr.pBits;

    /* Now go through the probes and check each one */
    for (i = 0; i < count; i++, probes++) {
        int index = probes->x + (probes->y * lr.Pitch);
        ok(colors_match(probes->c, pbits_data[index], probes->epsilon),
                "Line %d: At (%d, %d): %s: Expected (%.04f,%.04f,%.04f, %.04f), got "
                "(%.04f,%.04f,%.04f,%.04f)\n", line_number, probes->x, probes->y, probes->message,
                probes->c.r, probes->c.g, probes->c.b, probes->c.a, pbits_data[index].r,
                pbits_data[index].g, pbits_data[index].b, pbits_data[index].a);
    }

    hr = IDirect3DSurface9_UnlockRect(readback);
    ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned: %08x\n", hr);

    /* We now present the scene. This is mostly for debugging purposes, since GetRenderTargetData
       also waits for drawing commands to complete. The reason this call is here and not in a
       draw function is because the contents of the render target surface are invalidated after
       this call. */
    hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
    ok(hr == D3D_OK, "IDirect3DDevice9_Present returned: %08x\n", hr);

    IUnknown_Release(render_target);
    IUnknown_Release(readback);
}

/* Now the actual test functions */
static void test_swizzle(IDirect3DDevice9 *device, IDirect3DVertexBuffer9 *quad_geometry,
        IDirect3DVertexShader9 *vshader_passthru)
{
    static const struct hlsl_probe_info probes[] =
    {
       {0, 0, {0.0101f, 0.0303f, 0.0202f, 0.0404f}, 0.0001f, "swizzle_test failed"}
    };

    static const char *swizzle_test_shader =
        "uniform float4 color;\n"
        "float4 test(): COLOR\n"
        "{\n"
        "    float4 ret = color;\n"
        "    ret.gb = ret.ra;\n"
        "    ret.ra = float2(0.0101, 0.0404);\n"
        "    return ret;\n"
        "}";

    ID3DXConstantTable *constants;
    IDirect3DPixelShader9 *pshader;

    pshader = compile_pixel_shader9(device, swizzle_test_shader, "ps_2_0", &constants);
    if (pshader != NULL)
    {
        set_float4_d3d9(device, constants, "color", 0.0303f, 0.0f, 0.0f, 0.0202f);

        compute_shader_probe9(device, vshader_passthru, pshader, quad_geometry,
                probes, sizeof(probes) / sizeof(*probes), 1, 1, __LINE__);

        IUnknown_Release(constants);
        IUnknown_Release(pshader);
    }
}

static void test_math(IDirect3DDevice9 *device, IDirect3DVertexBuffer9 *quad_geometry,
        IDirect3DVertexShader9 *vshader_passthru)
{
    /* Tests order of operations */
    static const float u = 2.5f, v = 0.3f, w = 0.2f, x = 0.7f, y = 0.1f, z = 1.5f;

    static const struct hlsl_probe_info probes[] =
    {
        {0, 0, {-12.4300f, 9.8333f, 1.6000f, 34.9999f}, 0.0001f,
                "order of operations test failed"}
    };

    static const char *order_of_operations_shader =
        "float4 test(uniform float u, uniform float v, uniform float w, uniform float x,\n"
        "            uniform float y, uniform float z): COLOR\n"
        "{\n"
        "    return float4(x * y - z / w + --u / -v,\n"
        "            z * x / y + w / -v,\n"
        "            u + v - w,\n"
        "            x / y / w);\n"
        "}";

    ID3DXConstantTable *constants;
    IDirect3DPixelShader9 *pshader;

    pshader = compile_pixel_shader9(device, order_of_operations_shader, "ps_2_0", &constants);
    if (pshader != NULL)
    {
        ID3DXConstantTable_SetFloat(constants, device, "$u", u);
        ID3DXConstantTable_SetFloat(constants, device, "$v", v);
        ID3DXConstantTable_SetFloat(constants, device, "$w", w);
        ID3DXConstantTable_SetFloat(constants, device, "$x", x);
        ID3DXConstantTable_SetFloat(constants, device, "$y", y);
        ID3DXConstantTable_SetFloat(constants, device, "$z", z);

        compute_shader_probe9(device, vshader_passthru, pshader, quad_geometry,
                probes, sizeof(probes) / sizeof(*probes), 1, 1, __LINE__);

        IUnknown_Release(constants);
        IUnknown_Release(pshader);
    }
}

static void test_conditionals(IDirect3DDevice9 *device, IDirect3DVertexBuffer9 *quad_geometry,
        IDirect3DVertexShader9 *vshader_passthru)
{
    static const struct hlsl_probe_info if_greater_probes[] =
    {
        { 0, 0, {0.9f, 0.8f, 0.7f, 0.6f}, 0.0001f, "if greater test failed"},
        { 5, 0, {0.9f, 0.8f, 0.7f, 0.6f}, 0.0001f, "if greater test failed"},
        {10, 0, {0.9f, 0.8f, 0.7f, 0.6f}, 0.0001f, "if greater test failed"},
        {15, 0, {0.9f, 0.8f, 0.7f, 0.6f}, 0.0001f, "if greater test failed"},
        {25, 0, {0.1f, 0.2f, 0.3f, 0.4f}, 0.0001f, "if greater test failed"},
        {30, 0, {0.1f, 0.2f, 0.3f, 0.4f}, 0.0001f, "if greater test failed"}
    };

    static const char *if_greater_shader =
        "float4 test(float2 pos: TEXCOORD0): COLOR\n"
        "{\n"
        "    if((pos.x * 32.0) > 20.0)\n"
        "        return float4(0.1, 0.2, 0.3, 0.4);\n"
        "    else\n"
        "        return float4(0.9, 0.8, 0.7, 0.6);\n"
        "}";

    static const struct hlsl_probe_info ternary_operator_probes[] =
    {
        {0, 0, {0.50f, 0.25f, 0.50f, 0.75f}, 0.00001f, "ternary operator test failed"},
        {1, 0, {0.50f, 0.25f, 0.50f, 0.75f}, 0.00001f, "ternary operator test failed"},
        {2, 0, {0.50f, 0.25f, 0.50f, 0.75f}, 0.00001f, "ternary operator test failed"},
        {3, 0, {0.50f, 0.25f, 0.50f, 0.75f}, 0.00001f, "ternary operator test failed"},
        {4, 0, {0.60f, 0.80f, 0.10f, 0.20f}, 0.00001f, "ternary operator test failed"},
        {5, 0, {0.60f, 0.80f, 0.10f, 0.20f}, 0.00001f, "ternary operator test failed"},
        {6, 0, {0.60f, 0.80f, 0.10f, 0.20f}, 0.00001f, "ternary operator test failed"},
        {7, 0, {0.60f, 0.80f, 0.10f, 0.20f}, 0.00001f, "ternary operator test failed"}
    };

    static const char *ternary_operator_shader =
        "float4 test(float2 pos: TEXCOORD0): COLOR\n"
        "{\n"
        "    return (pos.x < 0.5?float4(0.5, 0.25, 0.5, 0.75):float4(0.6, 0.8, 0.1, 0.2));\n"
        "}";

    ID3DXConstantTable *constants;
    IDirect3DPixelShader9 *pshader;

    pshader = compile_pixel_shader9(device, if_greater_shader, "ps_2_0", &constants);
    if (pshader != NULL)
    {
        compute_shader_probe9(device, vshader_passthru, pshader, quad_geometry, if_greater_probes,
                sizeof(if_greater_probes) / sizeof(*if_greater_probes), 32, 1, __LINE__);

        IUnknown_Release(constants);
        IUnknown_Release(pshader);
    }

    pshader = compile_pixel_shader9(device, ternary_operator_shader, "ps_2_0", &constants);
    if (pshader != NULL)
    {
        compute_shader_probe9(device, vshader_passthru, pshader, quad_geometry, ternary_operator_probes,
                sizeof(ternary_operator_probes) / sizeof(*ternary_operator_probes), 8, 1, __LINE__);

        IUnknown_Release(constants);
        IUnknown_Release(pshader);
    }
}

static void test_float_vectors(IDirect3DDevice9 *device, IDirect3DVertexBuffer9 *quad_geometry,
        IDirect3DVertexShader9 *vshader_passthru)
{
    static const struct hlsl_probe_info vec4_indexing_test1_probes[] =
    {
        {0, 0, {0.020f, 0.245f, 0.351f, 1.000f}, 0.0001f, "vec4 indexing test 1 failed"}
    };

    static const char *vec4_indexing_test1_shader =
        "float4 test(): COLOR\n"
        "{\n"
        "    float4 color;\n"
        "    color[0] = 0.020;\n"
        "    color[1] = 0.245;\n"
        "    color[2] = 0.351;\n"
        "    color[3] = 1.0;\n"
        "    return color;\n"
        "}";

    static const struct hlsl_probe_info vec4_indexing_test2_probes[] =
    {
        {0, 0, {0.5f, 0.3f, 0.8f, 0.2f}, 0.0001f, "vec4 indexing test 2 failed"}
    };

    /* We have this uniform i here so the compiler can't optimize */
    static const char *vec4_indexing_test2_shader =
        "uniform int i;\n"
        "float4 test(): COLOR\n"
        "{\n"
        "    float4 color = float4(0.5, 0.4, 0.3, 0.2);\n"
        "    color.g = color[i];\n"
        "    color.b = 0.8;\n"
        "    return color;\n"
        "}";

    ID3DXConstantTable *constants;
    IDirect3DPixelShader9 *pshader;

    pshader = compile_pixel_shader9(device, vec4_indexing_test1_shader, "ps_2_0", &constants);
    if (pshader != NULL)
    {
        compute_shader_probe9(device, vshader_passthru, pshader, quad_geometry, vec4_indexing_test1_probes,
                sizeof(vec4_indexing_test1_probes) / sizeof(*vec4_indexing_test1_probes), 1, 1, __LINE__);

        IUnknown_Release(constants);
        IUnknown_Release(pshader);
    }

    pshader = compile_pixel_shader9(device, vec4_indexing_test2_shader, "ps_2_0", &constants);
    if (pshader != NULL)
    {
        ID3DXConstantTable_SetInt(constants, device, "i", 2);

        compute_shader_probe9(device, vshader_passthru, pshader, quad_geometry, vec4_indexing_test2_probes,
                sizeof(vec4_indexing_test2_probes) / sizeof(*vec4_indexing_test2_probes), 32, 1, __LINE__);

        IUnknown_Release(constants);
        IUnknown_Release(pshader);
    }
}

static void test_trig(IDirect3DDevice9 *device, IDirect3DVertexBuffer9 *quad_geometry,
        IDirect3DVertexShader9 *vshader_passthru)
{
    static const struct hlsl_probe_info sincos_probes[] =
    {
        {0, 0, {0.5000f, 1.0000f, 0.0f, 0.0f}, 0.001f, "sin/cos test failed"},
        {1, 0, {0.5975f, 0.9904f, 0.0f, 0.0f}, 0.001f, "sin/cos test failed"},
        {2, 0, {0.6913f, 0.9620f, 0.0f, 0.0f}, 0.001f, "sin/cos test failed"},
        {3, 0, {0.7778f, 0.9160f, 0.0f, 0.0f}, 0.001f, "sin/cos test failed"},
        {4, 0, {0.8536f, 0.8536f, 0.0f, 0.0f}, 0.001f, "sin/cos test failed"},
        {5, 0, {0.9157f, 0.7778f, 0.0f, 0.0f}, 0.001f, "sin/cos test failed"},
        {6, 0, {0.9620f, 0.6913f, 0.0f, 0.0f}, 0.001f, "sin/cos test failed"},
        {7, 0, {0.9904f, 0.5975f, 0.0f, 0.0f}, 0.001f, "sin/cos test failed"},
        {8, 0, {1.0000f, 0.5000f, 0.0f, 0.0f}, 0.001f, "sin/cos test failed"},
        {9, 0, {0.9904f, 0.4025f, 0.0f, 0.0f}, 0.001f, "sin/cos test failed"},
        {10, 0, {0.9619f, 0.3087f, 0.0f, 0.0f}, 0.001f, "sin/cos test failed"},
        {11, 0, {0.9157f, 0.2222f, 0.0f, 0.0f}, 0.001f, "sin/cos test failed"},
        {12, 0, {0.8536f, 0.1464f, 0.0f, 0.0f}, 0.001f, "sin/cos test failed"},
        {13, 0, {0.7778f, 0.0843f, 0.0f, 0.0f}, 0.001f, "sin/cos test failed"},
        {14, 0, {0.6913f, 0.0381f, 0.0f, 0.0f}, 0.001f, "sin/cos test failed"},
        {15, 0, {0.5975f, 0.0096f, 0.0f, 0.0f}, 0.001f, "sin/cos test failed"},
        {16, 0, {0.5000f, 0.0000f, 0.0f, 0.0f}, 0.001f, "sin/cos test failed"},
        {17, 0, {0.4025f, 0.0096f, 0.0f, 0.0f}, 0.001f, "sin/cos test failed"},
        {18, 0, {0.3087f, 0.0381f, 0.0f, 0.0f}, 0.001f, "sin/cos test failed"},
        {19, 0, {0.2222f, 0.0843f, 0.0f, 0.0f}, 0.001f, "sin/cos test failed"},
        {20, 0, {0.1464f, 0.1464f, 0.0f, 0.0f}, 0.001f, "sin/cos test failed"},
        {21, 0, {0.0843f, 0.2222f, 0.0f, 0.0f}, 0.001f, "sin/cos test failed"},
        {22, 0, {0.0381f, 0.3087f, 0.0f, 0.0f}, 0.001f, "sin/cos test failed"},
        {23, 0, {0.0096f, 0.4025f, 0.0f, 0.0f}, 0.001f, "sin/cos test failed"},
        {24, 0, {0.0000f, 0.5000f, 0.0f, 0.0f}, 0.001f, "sin/cos test failed"},
        {25, 0, {0.0096f, 0.5975f, 0.0f, 0.0f}, 0.001f, "sin/cos test failed"},
        {26, 0, {0.0381f, 0.6913f, 0.0f, 0.0f}, 0.001f, "sin/cos test failed"},
        {27, 0, {0.0843f, 0.7778f, 0.0f, 0.0f}, 0.001f, "sin/cos test failed"},
        {28, 0, {0.1464f, 0.8536f, 0.0f, 0.0f}, 0.001f, "sin/cos test failed"},
        {29, 0, {0.2222f, 0.9157f, 0.0f, 0.0f}, 0.001f, "sin/cos test failed"},
        {30, 0, {0.3087f, 0.9619f, 0.0f, 0.0f}, 0.001f, "sin/cos test failed"},
        {31, 0, {0.4025f, 0.9904f, 0.0f, 0.0f}, 0.001f, "sin/cos test failed"},
    };

    static const char *sincos_shader =
        "float4 test(float x: TEXCOORD0): COLOR\n"
        "{\n"
        "    const float pi2 = 6.2831853;\n"
        "    float calcd_sin = (sin(x * pi2) + 1)/2;\n"
        "    float calcd_cos = (cos(x * pi2) + 1)/2;\n"
        "    return float4(calcd_sin, calcd_cos, 0, 0);\n"
        "}";

    ID3DXConstantTable *constants;
    IDirect3DPixelShader9 *pshader;

    pshader = compile_pixel_shader9(device, sincos_shader, "ps_2_0", &constants);
    if (pshader != NULL)
    {
        compute_shader_probe9(device, vshader_passthru, pshader, quad_geometry, sincos_probes,
                sizeof(sincos_probes) / sizeof(*sincos_probes), 32, 1, __LINE__);

        IUnknown_Release(constants);
        IUnknown_Release(pshader);
    }
}

static void test_fail(IDirect3DDevice9 *device, IDirect3DVertexBuffer9 *qquad_geometry,
        IDirect3DVertexShader9 *vshader_passthru)
{
    static const char *undefined_variable_shader =
        "float4 test(float2 pos: TEXCOORD0) : COLOR\n"
        "{\n"
        "   return y;\n"
        "}";

    static const char *invalid_swizzle_shader =
        "float4 test(float2 pos: TEXCOORD0) : COLOR\n"
        "{\n"
        "  float4 x = float4(0, 0, 0, 0);\n"
        "  x.xzzx = float4(1, 2, 3, 4);\n"
        "  return x;\n"
        "}";

    static const char *invalid_conversion_shader =
        "float4 test(float2 pos: TEXCOORD0) : COLOR\n"
        "{\n"
        "  float4 x = pos;\n"
        "  return x;\n"
        "}";

    static const char *invalid_syntax_shader =
        "float4 test(float2 pos, TEXCOORD0) ; COLOR\n"
        "{\n"
        "  pos = float4 x;\n"
        "  mul(float4(5, 4, 3, 2), mvp) = x;\n"
        "  return float4;\n"
        "}";

    static const char *invalid_identifiers_shader =
        "float4 563r(float2 45s: TEXCOORD0) : COLOR\n"
        "{\n"
        "  float2 x = 45s;\n"
        "  return float4(x.x, x.y, 0, 0);\n"
        "}";

    ID3D10Blob *compiled = NULL, *errors = NULL;
    HRESULT hr;

    hr = D3DCompile(undefined_variable_shader, strlen(undefined_variable_shader), NULL, NULL, NULL,
            "test", "ps_2_0", 0, 0, &compiled, &errors);
    ok(hr != D3D_OK, "Pixel shader compilation succeeded on shader with undefined variable\n");
    ok(errors != NULL, "No errors returned for a shader with undefined variables\n");
    ok(compiled == NULL, "A shader blob was returned for a shader with undefined variables\n");

    IUnknown_Release(errors);
    errors = NULL;

    hr = D3DCompile(invalid_swizzle_shader, strlen(invalid_swizzle_shader), NULL, NULL, NULL,
            "test","ps_2_0", 0, 0, &compiled, &errors);
    ok(hr != D3D_OK, "Pixel shader compilation succeeded on shader with an invalid swizzle mask\n");
    ok(errors != NULL, "No errors returned for a shader with an invalid swizzle mask\n");
    ok(compiled == NULL, "A shader blob was returned for a shader with an invalid swizzle mask\n");

    IUnknown_Release(errors);
    errors = NULL;

    hr = D3DCompile(invalid_conversion_shader, strlen(invalid_conversion_shader), NULL, NULL, NULL,
             "test", "ps_2_0", 0, 0, &compiled, &errors);
    ok(hr != D3D_OK, "Pixel shader compilation succeeded on shader with an invalid type "
            "conversion\n");
    ok(errors != NULL, "No errors returned for a shader with invalid type conversions\n");
    ok(compiled == NULL, "A shader blob was returned for a shader with invalid type conversions\n");

    IUnknown_Release(errors);
    errors = NULL;

    hr = D3DCompile(invalid_syntax_shader, strlen(invalid_syntax_shader), NULL, NULL, NULL, "test",
            "ps_2_0", 0, 0, &compiled, &errors);
    ok(hr != D3D_OK, "Pixel shader compilation succeeded on shader with blatantly invalid "
            "syntax\n");
    ok(errors != NULL, "No errors returned for a shader with invalid syntax\n");
    ok(compiled == NULL, "A shader blob was returned for a shader with invalid syntax\n");

    IUnknown_Release(errors);
    errors = NULL;

    hr = D3DCompile(invalid_identifiers_shader, strlen(invalid_identifiers_shader), NULL, NULL,
            NULL, "test", "ps_2_0", 0, 0, &compiled, &errors);
    ok(hr != D3D_OK, "Pixel shader compilation successful on a shader with invalid variable and "
            "function names\n");
    ok(errors != NULL, "No errors returned for a shader with invalid variable and function "
            "names\n");
    ok(compiled == NULL, "A shader blob was returend for a shader with invalid variable and "
            "function names\n");

    IUnknown_Release(errors);
}

START_TEST(hlsl)
{
    D3DCAPS9 caps;
    ULONG refcount;
    IDirect3DDevice9 *device;
    IDirect3DVertexDeclaration9 *vdeclaration;
    IDirect3DVertexBuffer9 *quad_geometry;
    IDirect3DVertexShader9 *vshader_passthru;

    device = init_d3d9(&vdeclaration, &quad_geometry, &vshader_passthru);
    if (!device) return;

    /* Make sure we support pixel shaders, before trying to compile them! */
    /* Direct3D 9 (Shader model 1-3 tests) */
    IDirect3DDevice9_GetDeviceCaps(device, &caps);
    if (caps.PixelShaderVersion >= D3DPS_VERSION(2, 0))
    {
        todo_wine
        {
            test_swizzle(device, quad_geometry, vshader_passthru);
            test_math(device, quad_geometry, vshader_passthru);
            test_conditionals(device, quad_geometry, vshader_passthru);
            test_float_vectors(device, quad_geometry, vshader_passthru);
            test_trig(device, quad_geometry, vshader_passthru);
            test_fail(device, quad_geometry, vshader_passthru);
        }
    } else skip("no pixel shader support\n");

    /* Reference counting sanity checks */
    if (vshader_passthru)
    {
        refcount = IUnknown_Release(vshader_passthru);
        ok(!refcount, "Pass-through vertex shader has %u references left\n", refcount);
    }

    refcount = IUnknown_Release(quad_geometry);
    ok(!refcount, "Vertex buffer has %u references left\n", refcount);

    refcount = IUnknown_Release(vdeclaration);
    ok(!refcount, "Vertex declaration has %u references left\n", refcount);

    refcount = IUnknown_Release(device);
    ok(!refcount, "Device has %u references left\n", refcount);
}
