[PATCH v2 2/3] d3dcompiler/tests: Port some tests to shader model 4.

Zebediah Figura zfigura at codeweavers.com
Thu Feb 27 11:11:29 CST 2020


On 2/27/20 4:28 AM, Matteo Bruni wrote:
> On Tue, Feb 25, 2020 at 6:59 PM Zebediah Figura <zfigura at codeweavers.com> wrote:
>>
>> On 2/25/20 11:32 AM, Matteo Bruni wrote:
>>> On Tue, Feb 18, 2020 at 9:32 PM Zebediah Figura <z.figura12 at gmail.com> wrote:
>>>>
>>>> In particular, port those for which there is an interesting difference in
>>>> code generation.
>>>>
>>>> Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
>>>> ---
>>>> It might make more sense to put this in a separate file, à la ddraw, since
>>>> almost no code is shared between d3d9 and d3d11 parts.
>>>
>>> It might be a good idea. Another potential advantage is that then
>>> we'll have two separate entries on test.winehq.org.
>>> I'm okay either way though.
>>>
>>>> +#define init_d3d11_test_context(a) init_d3d11_test_context_(__LINE__, a)
>>>> +static BOOL init_d3d11_test_context_(unsigned int line, struct d3d11_test_context *context)
>>>> +{
>>>> +    const D3D11_TEXTURE2D_DESC texture_desc =
>>>> +    {
>>>> +        .Width = 640,
>>>> +        .Height = 480,
>>>> +        .MipLevels = 1,
>>>> +        .ArraySize = 1,
>>>> +        .Format = DXGI_FORMAT_R32G32B32A32_FLOAT,
>>>> +        .SampleDesc.Count = 1,
>>>> +        .Usage = D3D11_USAGE_DEFAULT,
>>>> +        .BindFlags = D3D11_BIND_RENDER_TARGET,
>>>> +    };
>>>> +    unsigned int rt_width, rt_height;
>>>> +    D3D11_VIEWPORT vp;
>>>> +    HRESULT hr;
>>>> +    RECT rect;
>>>> +
>>>> +    memset(context, 0, sizeof(*context));
>>>> +
>>>> +    if (!(context->device = create_device()))
>>>> +    {
>>>> +        skip_(__FILE__, line)("Failed to create device.\n");
>>>> +        return FALSE;
>>>> +    }
>>>> +
>>>> +    rt_width = 640;
>>>> +    rt_height = 480;
>>>> +    SetRect(&rect, 0, 0, rt_width, rt_height);
>>>> +    AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW | WS_VISIBLE, FALSE);
>>>> +    context->window = CreateWindowA("static", "d3d11_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
>>>> +            0, 0, rect.right - rect.left, rect.bottom - rect.top, NULL, NULL, NULL, NULL);
>>>> +    context->swapchain = create_swapchain(context->device, context->window);
>>>
>>> This reminds me that's probably better to do something similar WRT the
>>> window for d3d9 too, in the previous patch.
>>
>> Sure. I mostly left it as is because it doesn't save much code.
> 
> I understand it wasn't clear at all but I was referring to creating a
> sensible window and then using AdjustWindowRect() in the d3d9 tests.

Ah, I assumed you just meant using a test_context (which I did anyway, 
and I guess it's probably better.) I'll resend with AdjustWindowRect() too.

> 
>>>> +#define get_readback_vec4_d3d11(context, x, y) get_readback_vec4_d3d11_(__LINE__, context, x, y)
>>>> +static struct vec4 get_readback_vec4_d3d11_(unsigned int line, struct d3d11_test_context *context,
>>>> +        unsigned int x, unsigned int y)
>>>> +{
>>>> +    ID3D11Device *device = context->device;
>>>> +    D3D11_MAPPED_SUBRESOURCE map_desc;
>>>> +    D3D11_TEXTURE2D_DESC texture_desc;
>>>> +    ID3D11Resource *rb_texture;
>>>> +    struct vec4 ret;
>>>> +    HRESULT hr;
>>>> +
>>>> +    ID3D11Texture2D_GetDesc(context->rt, &texture_desc);
>>>> +    texture_desc.Usage = D3D11_USAGE_STAGING;
>>>> +    texture_desc.BindFlags = 0;
>>>> +    texture_desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
>>>> +    texture_desc.MiscFlags = 0;
>>>> +    hr = ID3D11Device_CreateTexture2D(device, &texture_desc, NULL, (ID3D11Texture2D **)&rb_texture);
>>>> +    ok_(__FILE__, line)(hr == S_OK, "Failed to create texture, hr %#x.\n", hr);
>>>> +
>>>> +    ID3D11DeviceContext_CopyResource(context->immediate_context, rb_texture, (ID3D11Resource *)context->rt);
>>>> +    hr = ID3D11DeviceContext_Map(context->immediate_context, rb_texture, 0, D3D11_MAP_READ, 0, &map_desc);
>>>> +    ok_(__FILE__, line)(hr == S_OK, "Failed to map texture, hr %#x.\n", hr);
>>>> +
>>>> +    ret = *((struct vec4 *)((BYTE *)map_desc.pData + y * map_desc.RowPitch) + x);
>>>> +
>>>> +    ID3D11DeviceContext_Unmap(context->immediate_context, rb_texture, 0);
>>>> +    ID3D11Resource_Release(rb_texture);
>>>> +
>>>> +    return ret;
>>>> +}
>>>
>>> Same point WRT texture readback as the previous patch.
>>>
>>>> +
>>>> +static void test_sm4_swizzle(void)
>>>> +{
>>>> +    static const struct vec4 uniform = {0.0303f, 0.0f, 0.0f, 0.0202f};
>>>> +    struct d3d11_test_context test_context;
>>>> +    ID3D10Blob *ps_code;
>>>> +    ID3D11Buffer *cb;
>>>> +    struct vec4 v;
>>>> +
>>>> +    static const char ps_source[] =
>>>> +        "uniform float4 color;\n"
>>>> +        "float4 main() : SV_TARGET\n"
>>>> +        "{\n"
>>>> +        "    float4 ret = color;\n"
>>>> +        "    ret.gb = ret.ra;\n"
>>>> +        "    ret.ra = float2(0.0101, 0.0404);\n"
>>>> +        "    return ret;\n"
>>>> +        "}";
>>>> +
>>>> +    if (!init_d3d11_test_context(&test_context))
>>>> +        return;
>>>> +
>>>> +    todo_wine ps_code = compile_shader(ps_source, "ps_4_0");
>>>> +    if (ps_code)
>>>> +    {
>>>> +        cb = create_buffer(test_context.device, D3D11_BIND_CONSTANT_BUFFER, sizeof(uniform), &uniform);
>>>> +        ID3D11DeviceContext_PSSetConstantBuffers(test_context.immediate_context, 0, 1, &cb);
>>>
>>> More of an open question than anything: is the "global" constant
>>> buffer always supposed to be at index 0?
>>>
>>
>> I don't think it's documented anywhere. In practice there seems to be a
>> stable ordering—$Global, then $Param, then declared cbuffers in order.
>>
>> For what it's worth, d2d1 (and I guess d3d11 tests in general?) kind of
>> depend on this, though maybe the logic there is that we ship the
>> bytecode and therefore already know what the buffer register is...
> 
> Yes, that's not really a dependency since everything is hardcoded. I
> guess, in theory, the test should use reflection to get the constant
> buffer index but a comment along the lines of what you wrote here
> should be also okay.
> 

I guess it's not too difficult to use reflection, at least if we write a 
helper for it. Fortunately the layout is documented, so we just need the 
index.

I do wonder if applications in the wild depend on the generated buffer 
order, though even if they do that doesn't mean we should too...



More information about the wine-devel mailing list