[PATCH v2 1/3] d3dcompiler/tests: Rewrite to use a separate d3d9 device for each test.

Zebediah Figura zfigura at codeweavers.com
Tue Feb 25 11:55:48 CST 2020


On 2/25/20 11:30 AM, Matteo Bruni wrote:
> On Tue, Feb 18, 2020 at 9:32 PM Zebediah Figura <z.figura12 at gmail.com> wrote:
>>
>> This brings the d3dcompiler tests more in line with existing d3d9 tests, and
>> allows potentially running the tests in parallel.
>>
>> Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
>> ---
>>  dlls/d3dcompiler_43/tests/hlsl.c | 801 +++++++++++++++----------------
>>  1 file changed, 384 insertions(+), 417 deletions(-)
> 
> This gives me some warnings:
> 
> In file included from /home/matteo/wine/include/d3d11shader.h:22,
>                  from /home/matteo/wine/include/d3dcompiler.h:22,
>                  from /home/matteo/wine/dlls/d3dcompiler_43/tests/hlsl.c:22:
> /home/matteo/wine/dlls/d3dcompiler_43/tests/hlsl.c: In function ‘func_hlsl’:
> ../../../include/d3dcommon.h:120:12: warning: ‘ps_code’ may be used
> uninitialized in this function [-Wmaybe-uninitialized]
>   120 |     return This->lpVtbl->Release(This);
>       |            ^~~~~~~~~~~~~~~~~~~~~~~~~~~
> /home/matteo/wine/dlls/d3dcompiler_43/tests/hlsl.c:523:17: note:
> ‘ps_code’ was declared here
>   523 |     ID3D10Blob *ps_code;
>       |                 ^~~~~~~
> 
> and similarly for the other calls to compile_shader(). It looks like
> the compiler gets confused by the todo_wine and thinks that the
> ps_code assignment might not happen. Initializing ps_code to NULL
> works around. For reference, this is 32-bit mingw-w64 based on gcc
> 9.2.
> 
> Otherwise it looks pretty good. A few comments inline:
> 
>> -    hr = IDirect3D9_CreateDevice(d3d9_ptr, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, NULL,
>> -            D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device_ptr);
>> -    IDirect3D9_Release(d3d9_ptr);
>> -    if (FAILED(hr))
>> +    if (FAILED(hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A32B32G32R32F,
>> +            D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL)))
>>      {
>> -        skip("could not create Direct3D9 device\n");
>> +        skip("Failed to create an A32B32G32R32F surface, hr %#x.\n", hr);
>> +        IDirect3DDevice9_Release(device);
>>          return NULL;
>>      }
>> +    ok(hr == D3D_OK, "Failed to create render target, hr %#x.\n", hr);
> 
> I'd just write "Got unexpected hr %#x.\n": technically this shouldn't
> fail since if FAILED(CreateRenderTarget()) is handled by the if above,
> so this would only catch S_FALSE or something similar.
> 
>> +    hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
>> +    ok(hr == D3D_OK, "Failed to set render target, hr %#x.\n", hr);
>> +    IDirect3DSurface9_Release(rt);
>>
>> -    /* 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);
>> +    return device;
>> +}
>>
>> -    hr = IDirect3DDevice9_CreateVertexDeclaration(device_ptr, vdeclelements, vdeclaration);
>> -    ok(SUCCEEDED(hr), "Could not create vertex declaration: "
>> -            "IDirect3DDevice9_CreateVertexDeclaration returned: %08x\n", hr);
>> +#define draw_quad(device, ps_code) draw_quad_(__LINE__, device, ps_code)
>> +static void draw_quad_(unsigned int line, IDirect3DDevice9 *device, ID3D10Blob *ps_code)
> 
> If we're not splitting d3d10+ tests to a separate file, this could use
> a d3d9 specifier. Otherwise, I guess all the specifiers in the *other*
> functions could go away.
> 
>> +{
>> +    IDirect3DVertexDeclaration9 *vertex_declaration;
>> +    IDirect3DVertexShader9 *vs;
>> +    IDirect3DPixelShader9 *ps;
>> +    ID3D10Blob *vs_code;
>> +    HRESULT hr;
>>
>> -    hr = IDirect3DDevice9_SetVertexDeclaration(device_ptr, *vdeclaration);
>> -    ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned: %08x\n", hr);
>> +    static const D3DVERTEXELEMENT9 decl_elements[] =
>> +    {
>> +        {0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
>> +        {0, 8, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
>> +        D3DDECL_END()
>> +    };
>>
>> -    /* Create a simple vertex shader to just pass through the values */
>> -    hr = ppD3DCompile(vshader_passthru_hlsl, strlen(vshader_passthru_hlsl), NULL,
>> -            NULL, NULL, "vshader", "vs_1_1", 0, 0, &compiled, &errors);
>> -    if (FAILED(hr))
>> +    static const struct
>>      {
>> -        skip("not compiling vertex shader due to lacking wine HLSL support!\n");
>> -        if (errors)
>> -            ID3D10Blob_Release(errors);
>> -        return NULL;
>> +        struct vec2 position;
>> +        struct vec2 t0;
>>      }
>> +    quad[] =
>> +    {
>> +        {{-1.0f, -1.0f}, {0.0f, 1.0f}},
>> +        {{-1.0f,  1.0f}, {0.0f, 0.0f}},
>> +        {{ 1.0f, -1.0f}, {1.0f, 1.0f}},
>> +        {{ 1.0f,  1.0f}, {1.0f, 0.0f}},
>> +    };
>>
>> -    hr = IDirect3DDevice9_CreateVertexShader(device_ptr, ID3D10Blob_GetBufferPointer(compiled),
>> -            vshader_passthru);
>> -    ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader returned: %08x\n", hr);
>> -    ID3D10Blob_Release(compiled);
>> +    static const char vs_source[] =
>> +        "float4 main(float4 pos : POSITION, inout float2 texcoord : TEXCOORD0) : POSITION\n"
>> +        "{\n"
>> +        "   return pos;\n"
>> +        "}";
>>
>> -    return device_ptr;
>> -}
>> +    hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
>> +    ok_(__FILE__, line)(hr == D3D_OK, "Failed to create vertex declaration, hr %#x.\n", hr);
>>
>> -/* 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);
>> -}
>> +    hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
>> +    ok_(__FILE__, line)(hr == D3D_OK, "Failed to set vertex declaration, hr %#x.\n", hr);
>>
>> -/* 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;
>> +    vs_code = compile_shader(vs_source, "vs_2_0");
>> +
>> +    hr = IDirect3DDevice9_CreateVertexShader(device, ID3D10Blob_GetBufferPointer(vs_code), &vs);
>> +    ok_(__FILE__, line)(hr == D3D_OK, "Failed to create vertex shader, hr %#x.\n", hr);
>> +
>> +    hr = IDirect3DDevice9_SetVertexShader(device, vs);
>> +    ok_(__FILE__, line)(hr == D3D_OK, "Failed to set vertex shader, hr %#x.\n", hr);
>> +
>> +    hr = IDirect3DDevice9_CreatePixelShader(device, ID3D10Blob_GetBufferPointer(ps_code), &ps);
>> +    ok_(__FILE__, line)(hr == D3D_OK, "Failed to create pixel shader, hr %#x.\n", hr);
>> +
>> +    hr = IDirect3DDevice9_SetPixelShader(device, ps);
>> +    ok_(__FILE__, line)(hr == D3D_OK, "Failed to set pixel shader, hr %#x.\n", hr);
>> +
>> +    hr = IDirect3DDevice9_BeginScene(device);
>> +    ok_(__FILE__, line)(hr == D3D_OK, "Failed to draw, hr %#x.\n", hr);
>>
>> -    hr = ppD3DCompile(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 = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
>> +    ok_(__FILE__, line)(hr == D3D_OK, "Failed to draw, hr %#x.\n", hr);
>>
>> -    hr = pD3DXGetShaderConstantTable(ID3D10Blob_GetBufferPointer(compiled), constants);
>> -    ok(hr == D3D_OK, "Could not get constant table from compiled pixel shader\n");
>> +    hr = IDirect3DDevice9_EndScene(device);
>> +    ok_(__FILE__, line)(hr == D3D_OK, "Failed to draw, hr %#x.\n", hr);
>>
>> -    hr = IDirect3DDevice9_CreatePixelShader(device, ID3D10Blob_GetBufferPointer(compiled), &pshader);
>> -    ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader returned: %08x\n", hr);
>> -    ID3D10Blob_Release(compiled);
>> -    return pshader;
>> +    IDirect3DVertexShader9_Release(vs);
>> +    IDirect3DPixelShader9_Release(ps);
>> +    ID3D10Blob_Release(vs_code);
> 
> Missing release of the vertex declaration.
> 
>>  }
>>
>> -/* Draw a full screen quad */
>> -static void draw_quad_with_shader9(IDirect3DDevice9 *device, IDirect3DVertexBuffer9 *quad_geometry)
>> +static struct vec4 get_readback_vec4_d3d9(IDirect3DDevice9 *device, unsigned int x, unsigned int y)
>>  {
>> +    IDirect3DSurface9 *surface = NULL, *target = NULL;
>> +    RECT rect = {x, y, x + 1, y + 1};
>> +    D3DLOCKED_RECT locked_rect;
>> +    D3DSURFACE_DESC desc;
>> +    struct vec4 ret;
>>      HRESULT hr;
>> -    D3DXMATRIX projection_matrix;
>>
>> -    pD3DXMatrixOrthoLH(&projection_matrix, 2.0f, 2.0f, 0.0f, 1.0f);
>> -    IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &projection_matrix);
>> +    hr = IDirect3DDevice9Ex_GetRenderTarget(device, 0, &target);
>> +    ok(hr == D3D_OK, "Failed to get render target, hr %#x.\n", hr);
>>
>> -    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 = IDirect3DSurface9_GetDesc(target, &desc);
>> +    ok(hr == D3D_OK, "Failed to get surface desc, hr %#x.\n", hr);
>> +    hr = IDirect3DDevice9Ex_CreateOffscreenPlainSurface(device, desc.Width, desc.Height,
>> +            desc.Format, D3DPOOL_SYSTEMMEM, &surface, NULL);
>> +    ok(hr == D3D_OK, "Failed to create surface, hr %#x.\n", hr);
>>
>> -    hr = IDirect3DDevice9_BeginScene(device);
>> -    ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene returned: %08x\n", hr);
>> +    hr = IDirect3DDevice9Ex_GetRenderTargetData(device, target, surface);
>> +    ok(hr == D3D_OK, "Failed to get render target data, hr %#x.\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 = IDirect3DSurface9_LockRect(surface, &locked_rect, &rect, D3DLOCK_READONLY);
>> +    ok(hr == D3D_OK, "Failed to lock surface, hr %#x.\n", hr);
>>
>> -    hr = IDirect3DDevice9_EndScene(device);
>> -    ok(hr == D3D_OK, "IDirect3DDevice9_EndScene returned: %08x\n", hr);
>> +    ret = ((struct vec4 *)locked_rect.pBits)[0];
>> +
>> +    IDirect3DSurface9_UnlockRect(surface);
>> +
>> +    IDirect3DSurface9_Release(target);
>> +    IDirect3DSurface9_Release(surface);
>> +    return ret;
>>  }
> 
> This isn't quite the get_readback_*() thing from the d3d tests: it
> both maps / unmaps the texture and returns the value, so it's more
> akin to a get_color(). The function is probably okay for now (it can
> be reimplemented on top of an actual get_readback_*() and such if need
> be) but I find the current naming a bit confusing.
> 
>>
>> -static void setup_device9(IDirect3DDevice9 *device, IDirect3DSurface9 **render_target,
>> -        IDirect3DSurface9 **readback, D3DFORMAT format, unsigned int width, unsigned int height,
>> -        IDirect3DVertexShader9 *vshader, IDirect3DPixelShader9 *pshader)
>> +#define set_float_d3d9(a, b, c, d) set_float_d3d9_(__LINE__, a, b, c, d)
>> +static void set_float_d3d9_(unsigned int line, IDirect3DDevice9 *device, ID3D10Blob *blob, const char *name, float f)
>>  {
>> +    ID3DXConstantTable *constants;
>>      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);
>> +
>> +    hr = pD3DXGetShaderConstantTable(ID3D10Blob_GetBufferPointer(blob), &constants);
>> +    ok_(__FILE__, line)(hr == D3D_OK, "Failed to get constant table, hr %#x.\n", hr);
>> +
>> +    hr = ID3DXConstantTable_SetFloat(constants, device, name, f);
>> +    ok_(__FILE__, line)(hr == D3D_OK, "Failed to set constant, hr %#x.\n", hr);
>> +
>> +    ID3DXConstantTable_Release(constants);
>>  }
>>
>> -static BOOL colors_match(D3DXCOLOR a, D3DXCOLOR b, float epsilon)
>> +#define set_float4_d3d9(a, b, c, d, e, f, g) set_float4_d3d9_(__LINE__, a, b, c, d, e, f, g)
>> +static void set_float4_d3d9_(unsigned int line, IDirect3DDevice9 *device, ID3D10Blob *blob,
>> +        const char *name, float x, float y, float z, float w)
>>  {
>> -  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);
>> +    ID3DXConstantTable *constants;
>> +    D3DXVECTOR4 v = {x, y, z, w};
>> +    HRESULT hr;
>> +
>> +    hr = pD3DXGetShaderConstantTable(ID3D10Blob_GetBufferPointer(blob), &constants);
>> +    ok_(__FILE__, line)(hr == D3D_OK, "Failed to get constant table, hr %#x.\n", hr);
>> +
>> +    hr = ID3DXConstantTable_SetVector(constants, device, name, &v);
>> +    ok_(__FILE__, line)(hr == D3D_OK, "Failed to set constant, hr %#x.\n", hr);
>> +
>> +    ID3DXConstantTable_Release(constants);
>>  }
> 
> It's a bit ugly and inefficient to redundantly create and destroy
> ID3DXConstantTable objects for shaders with multiple constants that
> need to be set, like in test_math(). I guess another option would be
> to not use these helpers in those cases, but that would somewhat
> defeat their purpose.
> Maybe give this the "readback" treatment and introduce a helper that
> only does the constant setting and reimplement this in terms of the
> new one. Then for tests setting a single constant you would call this
> and for the multiple constants case you would call the slimmer, new
> helper (and probably manually create and destroy the constant table in
> the test).

Eh, I guess the helper isn't really doing much anyway. Maybe just a
two-line helper to translate four floats into a D3DXVECTOR4 would be best.

> 
>> +static HWND create_window(void)
>> +{
>> +    WNDCLASSA wc = {0};
>> +    wc.lpfnWndProc = DefWindowProcA;
>> +    wc.lpszClassName = "d3d9_test_wc";
>> +    RegisterClassA(&wc);
>>
>> -    IDirect3DSurface9_Release(render_target);
>> -    IDirect3DSurface9_Release(readback);
>> +    return CreateWindowA("d3d9_test_wc", "d3d9_test", 0, 0, 0, 0, 0, 0, 0, 0, 0);
>>  }
> 
> Nitpick, class and window names could mention d3dcompiler (and maybe d3d9).
> 
>> -static void test_conditionals(IDirect3DDevice9 *device, IDirect3DVertexBuffer9 *quad_geometry,
>> -        IDirect3DVertexShader9 *vshader_passthru)
>> +static void test_conditionals(void)
>>  {
>> -    static const struct hlsl_probe_info if_greater_probes[] =
>> -    {
>> -        { 0, 0, {0.9f, 0.8f, 0.7f, 0.6f}, 0.0001f, "if greater test"},
>> -        { 5, 0, {0.9f, 0.8f, 0.7f, 0.6f}, 0.0001f, "if greater test"},
>> -        {10, 0, {0.9f, 0.8f, 0.7f, 0.6f}, 0.0001f, "if greater test"},
>> -        {15, 0, {0.9f, 0.8f, 0.7f, 0.6f}, 0.0001f, "if greater test"},
>> -        {25, 0, {0.1f, 0.2f, 0.3f, 0.4f}, 0.0001f, "if greater test"},
>> -        {30, 0, {0.1f, 0.2f, 0.3f, 0.4f}, 0.0001f, "if greater test"}
>> -    };
>> +    IDirect3DDevice9 *device;
>> +    ID3D10Blob *ps_code;
>> +    unsigned int i;
>> +    struct vec4 v;
>> +    HWND window;
>>
>> -    static const char *if_greater_shader =
>> -        "float4 test(float2 pos: TEXCOORD0): COLOR\n"
>> +    static const char ps_if_source[] =
>> +        "float4 main(float2 pos : TEXCOORD0) : COLOR\n"
>>          "{\n"
>> -        "    if((pos.x * 32.0) > 20.0)\n"
>> +        "    if((pos.x * 640.0) > 200.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"},
>> -        {1, 0, {0.50f, 0.25f, 0.50f, 0.75f}, 0.00001f, "ternary operator test"},
>> -        {2, 0, {0.50f, 0.25f, 0.50f, 0.75f}, 0.00001f, "ternary operator test"},
>> -        {3, 0, {0.50f, 0.25f, 0.50f, 0.75f}, 0.00001f, "ternary operator test"},
>> -        {4, 0, {0.60f, 0.80f, 0.10f, 0.20f}, 0.00001f, "ternary operator test"},
>> -        {5, 0, {0.60f, 0.80f, 0.10f, 0.20f}, 0.00001f, "ternary operator test"},
>> -        {6, 0, {0.60f, 0.80f, 0.10f, 0.20f}, 0.00001f, "ternary operator test"},
>> -        {7, 0, {0.60f, 0.80f, 0.10f, 0.20f}, 0.00001f, "ternary operator test"}
>> -    };
>> -
>> -    static const char *ternary_operator_shader =
>> -        "float4 test(float2 pos: TEXCOORD0): COLOR\n"
>> +    static const char ps_ternary_source[] =
>> +        "float4 main(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"
>>          "}";
> 
> I guess you could add a few whitespaces in there while at it.
> 
>>
>> -    ID3DXConstantTable *constants;
>> -    IDirect3DPixelShader9 *pshader;
>> +    window = create_window();
>> +    ok(!!window, "Failed to create a window.\n");
>> +
>> +    if (!(device = create_d3d9_device(window)))
>> +    {
>> +        DestroyWindow(window);
>> +        return;
>> +    }
>>
>> -    pshader = compile_pixel_shader9(device, if_greater_shader, "ps_2_0", &constants);
>> -    if (pshader != NULL)
>> +    todo_wine ps_code = compile_shader(ps_if_source, "ps_2_0");
>> +    if (ps_code)
>>      {
>> -        compute_shader_probe9(device, vshader_passthru, pshader, quad_geometry, if_greater_probes,
>> -                ARRAY_SIZE(if_greater_probes), 32, 1, __LINE__);
>> +        draw_quad(device, ps_code);
>>
>> -        ID3DXConstantTable_Release(constants);
>> -        IDirect3DPixelShader9_Release(pshader);
>> +        for (i = 0; i < 200; i += 40)
>> +        {
>> +            v = get_readback_vec4_d3d9(device, i, 0);
>> +            ok(compare_vec4(&v, 0.9f, 0.8f, 0.7f, 0.6f, 0),
>> +                    "Got unexpected value {%.8e, %.8e, %.8e, %.8e}.\n", v.x, v.y, v.z, v.w);
>> +        }
>> +
>> +        for (i = 240; i < 640; i += 40)
>> +        {
>> +            v = get_readback_vec4_d3d9(device, i, 0);
>> +            ok(compare_vec4(&v, 0.1f, 0.2f, 0.3f, 0.4f, 0),
>> +                    "Got unexpected value {%.8e, %.8e, %.8e, %.8e}.\n", v.x, v.y, v.z, v.w);
>> +        }
>> +
>> +        ID3D10Blob_Release(ps_code);
>>      }
>>
>> -    pshader = compile_pixel_shader9(device, ternary_operator_shader, "ps_2_0", &constants);
>> -    if (pshader != NULL)
>> +    todo_wine ps_code = compile_shader(ps_ternary_source, "ps_2_0");
>> +    if (ps_code)
>>      {
>> -        compute_shader_probe9(device, vshader_passthru, pshader, quad_geometry, ternary_operator_probes,
>> -                ARRAY_SIZE(ternary_operator_probes), 8, 1, __LINE__);
>> +        draw_quad(device, ps_code);
>>
>> -        ID3DXConstantTable_Release(constants);
>> -        IDirect3DPixelShader9_Release(pshader);
>> +        for (i = 0; i < 320; i += 40)
>> +        {
>> +            v = get_readback_vec4_d3d9(device, i, 0);
>> +            ok(compare_vec4(&v, 0.5f, 0.25f, 0.5f, 0.75f, 0),
>> +                    "Got unexpected value {%.8e, %.8e, %.8e, %.8e}.\n", v.x, v.y, v.z, v.w);
>> +        }
>> +
>> +        for (i = 360; i < 640; i += 40)
>> +        {
>> +            v = get_readback_vec4_d3d9(device, i, 0);
>> +            ok(compare_vec4(&v, 0.6f, 0.8f, 0.1f, 0.2f, 0),
>> +                    "Got unexpected value {%.8e, %.8e, %.8e, %.8e}.\n", v.x, v.y, v.z, v.w);
>> +        }
> 
> This test is a case where it would be nice to have actual
> get_readback_*() functions and only map + unmap the texture once.
> 
>> +
>> +        ID3D10Blob_Release(ps_code);
>>      }
>> +
>> +    IDirect3DDevice9_Release(device);
>> +    DestroyWindow(window);
>>  }
>>
>> -static void test_float_vectors(IDirect3DDevice9 *device, IDirect3DVertexBuffer9 *quad_geometry,
>> -        IDirect3DVertexShader9 *vshader_passthru)
>> +static void test_float_vectors(void)
>>  {
>> -    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"}
>> -    };
>> +    ID3DXConstantTable *constants;
>> +    IDirect3DDevice9 *device;
>> +    ID3D10Blob *ps_code;
>> +    struct vec4 v;
>> +    HWND window;
>> +    HRESULT hr;
>>
>> -    static const char *vec4_indexing_test1_shader =
>> -        "float4 test(): COLOR\n"
>> +    static const char ps_indexing_source[] =
>> +        "float4 main() : COLOR\n"
>>          "{\n"
>>          "    float4 color;\n"
>>          "    color[0] = 0.020;\n"
>> @@ -458,15 +464,10 @@ static void test_float_vectors(IDirect3DDevice9 *device, IDirect3DVertexBuffer9
>>          "    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"}
>> -    };
>> -
>> -    /* We have this uniform i here so the compiler can't optimize */
>> -    static const char *vec4_indexing_test2_shader =
>> +    /* A uniform index is used so that the compiler can't optimize. */
>> +    static const char ps_uniform_indexing_source[] =
>>          "uniform int i;\n"
>> -        "float4 test(): COLOR\n"
>> +        "float4 main() : COLOR\n"
>>          "{\n"
>>          "    float4 color = float4(0.5, 0.4, 0.3, 0.2);\n"
>>          "    color.g = color[i];\n"
>> @@ -474,73 +475,58 @@ static void test_float_vectors(IDirect3DDevice9 *device, IDirect3DVertexBuffer9
>>          "    return color;\n"
>>          "}";
>>
>> -    ID3DXConstantTable *constants;
>> -    IDirect3DPixelShader9 *pshader;
>> +    window = create_window();
>> +    ok(!!window, "Failed to create a window.\n");
>>
>> -    pshader = compile_pixel_shader9(device, vec4_indexing_test1_shader, "ps_2_0", &constants);
>> -    if (pshader != NULL)
>> +    if (!(device = create_d3d9_device(window)))
>>      {
>> -        compute_shader_probe9(device, vshader_passthru, pshader, quad_geometry, vec4_indexing_test1_probes,
>> -                ARRAY_SIZE(vec4_indexing_test1_probes), 1, 1, __LINE__);
>> -
>> -        ID3DXConstantTable_Release(constants);
>> -        IDirect3DPixelShader9_Release(pshader);
>> +        DestroyWindow(window);
>> +        return;
>>      }
>>
>> -    pshader = compile_pixel_shader9(device, vec4_indexing_test2_shader, "ps_2_0", &constants);
>> -    if (pshader != NULL)
>> +    todo_wine ps_code = compile_shader(ps_indexing_source, "ps_2_0");
>> +    if (ps_code)
>>      {
>> -        ID3DXConstantTable_SetInt(constants, device, "i", 2);
>> +        draw_quad(device, ps_code);
>> +
>> +        v = get_readback_vec4_d3d9(device, 0, 0);
>> +        ok(compare_vec4(&v, 0.02f, 0.245f, 0.351f, 1.0f, 0),
>> +                "Got unexpected value {%.8e, %.8e, %.8e, %.8e}.\n", v.x, v.y, v.z, v.w);
> 
> Something for a separate patch: this test could be extended to check
> what happens if 'i' is outside of the valid range. If it turns out to
> be undefined behavior, a small comment will suffice.
> 

I guess that strikes me as more of a d3d core test than a d3dcompiler
test, but I don't feel strongly about it.



More information about the wine-devel mailing list