-- v2: d3d11/tests: Add a test for NV12 textures.
From: Giovanni Mascellani gmascellani@codeweavers.com
--- dlls/d3d11/tests/Makefile.in | 2 +- dlls/d3d11/tests/d3d11.c | 270 +++++++++++++++++++++++++++++++++++ 2 files changed, 271 insertions(+), 1 deletion(-)
diff --git a/dlls/d3d11/tests/Makefile.in b/dlls/d3d11/tests/Makefile.in index 8af7276c427..fbae8aa09c6 100644 --- a/dlls/d3d11/tests/Makefile.in +++ b/dlls/d3d11/tests/Makefile.in @@ -1,5 +1,5 @@ TESTDLL = d3d11.dll -IMPORTS = d3d11 dxgi user32 gdi32 +IMPORTS = d3d11 dxgi user32 gdi32 d3dcompiler
SOURCES = \ d3d11.c diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c index 24fdb32b829..1ddd156d9bf 100644 --- a/dlls/d3d11/tests/d3d11.c +++ b/dlls/d3d11/tests/d3d11.c @@ -26,6 +26,7 @@ #define COBJMACROS #include "initguid.h" #include "d3d11_4.h" +#include "d3dcompiler.h" #include "winternl.h" #include "wine/wined3d.h" #include "wine/test.h" @@ -130,6 +131,23 @@ struct swapchain_desc DWORD flags; };
+static ID3D10Blob *compile_shader(const char *source, size_t len, const char *profile) +{ + ID3D10Blob *bytecode = NULL, *errors = NULL; + HRESULT hr; + + hr = D3DCompile(source, len, NULL, NULL, NULL, "main", profile, 0, 0, &bytecode, &errors); + ok(hr == S_OK, "Cannot compile shader, hr %#lx.\n", hr); + ok(!!bytecode, "Compilation didn't produce any bytecode.\n"); + if (errors) + { + trace("Compilation errors:\n%s\n", (char *)ID3D10Blob_GetBufferPointer(errors)); + ID3D10Blob_Release(errors); + } + + return bytecode; +} + static void queue_test_entry(const struct test_entry *t) { if (mt_test_count >= mt_tests_size) @@ -36164,6 +36182,257 @@ static void test_high_resource_count(void) release_test_context(&test_context); }
+static void test_nv12(void) +{ + struct d3d11_test_context test_context; + D3D11_UNORDERED_ACCESS_VIEW_DESC uav_desc = {0}; + D3D11_SHADER_RESOURCE_VIEW_DESC srv_desc = {0}; + D3D11_SUBRESOURCE_DATA subresource_data = {0}; + D3D11_RENDER_TARGET_VIEW_DESC rtv_desc = {0}; + ID3D11Texture2D *texture, *check_texture; + ID3D11ShaderResourceView *srv1, *srv2; + ID3D11UnorderedAccessView *check_uav; + ID3D11RenderTargetView *rtv1, *rtv2; + D3D11_TEXTURE2D_DESC desc = {0}; + ID3D11DeviceContext *device_context; + ID3D10Blob *bytecode; + ID3D11ComputeShader *luma_cs, *chroma_cs; + ID3D11PixelShader *luma_ps, *chroma_ps; + struct resource_readback rb; + ID3D11Device *device; + unsigned int i, j; + HRESULT hr; + char *buf; + + static const uint32_t clear_values[4] = {0xabcdef00, 0xabcdef00, 0xabcdef00, 0xabcdef00}; + static const float clear_values_float[4] = {100.0, 100.0, 100.0, 100.0}; + static const unsigned int width = 640; + static const unsigned int height = 480; + + static const char luma_cs_code[] = + "Texture2D<uint> luma;\n" + "RWTexture2D<uint> check : register(u1);\n" + "\n" + "[numthreads(1, 1, 1)]\n" + "void main(uint3 threadID : SV_DispatchThreadID)\n" + "{\n" + " uint2 coords = threadID.xy;\n" + " check[threadID.xy] = luma[coords] == ((coords.y & 7) << 3 | (coords.x & 7));\n" + " coords = threadID.xy + uint2(0, 1);\n" + " check[threadID.xy] &= luma[coords] == ((coords.y & 7) << 3 | (coords.x & 7));\n" + " coords = threadID.xy + uint2(1, 0);\n" + " check[threadID.xy] &= luma[coords] == ((coords.y & 7) << 3 | (coords.x & 7));\n" + " coords = threadID.xy + uint2(1, 1);\n" + " check[threadID.xy] &= luma[coords] == ((coords.y & 7) << 3 | (coords.x & 7));\n" + "}\n"; + + static const char chroma_cs_code[] = + "Texture2D<uint2> chroma;\n" + "RWTexture2D<uint> check : register(u1);\n" + "\n" + "[numthreads(1, 1, 1)]\n" + "void main(uint3 threadID : SV_DispatchThreadID)\n" + "{\n" + " uint2 coords = threadID.xy;\n" + " check[threadID.xy] = chroma[coords].x == (1 << 6 | (coords.y & 7) << 3 | (coords.x & 7));\n" + " check[threadID.xy] &= chroma[coords].y == (1 << 7 | (coords.y & 7) << 3 | (coords.x & 7));\n" + "}\n"; + + static const char luma_ps_code[] = + "uint main(float4 pos : SV_Position) : SV_Target\n" + "{\n" + " uint2 coords = pos.xy;\n" + " return (coords.y & 7) << 3 | (coords.x & 7);\n" + "}\n"; + + static const char chroma_ps_code[] = + "uint2 main(float4 pos : SV_Position) : SV_Target\n" + "{\n" + " uint2 coords = pos.xy;\n" + " return uint2(1 << 6 | (coords.y & 7) << 3 | (coords.x & 7),\n" + " 1 << 7 | (coords.y & 7) << 3 | (coords.x & 7));\n" + "}\n"; + + if (!init_test_context(&test_context, NULL)) + return; + device = test_context.device; + device_context = test_context.immediate_context; + + desc.Width = width; + desc.Height = height; + desc.MipLevels = 1; + desc.ArraySize = 1; + desc.Format = DXGI_FORMAT_NV12; + desc.SampleDesc.Count = 1; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; + + buf = calloc(width * height * 3 / 2, 1); + ok(!!buf, "Failed to allocate memory.\n"); + + for (i = 0; i < height; ++i) + { + for (j = 0; j < width; ++j) + { + unsigned int idx = i * width + j; + + buf[idx] = (i & 7) << 3 | (j & 7); + } + } + + for (i = 0; i < height / 2; ++i) + { + for (j = 0; j < width / 2; ++j) + { + unsigned int idx = width * height + i * width + j * 2; + + buf[idx] = 1 << 6 | (i & 7) << 3 | (j & 7); + buf[idx + 1] = 1 << 7 | (i & 7) << 3 | (j & 7); + } + } + + subresource_data.pSysMem = buf; + subresource_data.SysMemPitch = width; + + hr = ID3D11Device_CreateTexture2D(device, &desc, &subresource_data, &texture); + todo_wine + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + free(buf); + + if (FAILED(hr)) + { + release_test_context(&test_context); + return; + } + + bytecode = compile_shader(luma_cs_code, sizeof(luma_cs_code) - 1, "cs_5_0"); + hr = ID3D11Device_CreateComputeShader(device, ID3D10Blob_GetBufferPointer(bytecode), + ID3D10Blob_GetBufferSize(bytecode), NULL, &luma_cs); + ID3D10Blob_Release(bytecode); + + bytecode = compile_shader(chroma_cs_code, sizeof(chroma_cs_code) - 1, "cs_5_0"); + hr = ID3D11Device_CreateComputeShader(device, ID3D10Blob_GetBufferPointer(bytecode), + ID3D10Blob_GetBufferSize(bytecode), NULL, &chroma_cs); + ID3D10Blob_Release(bytecode); + + bytecode = compile_shader(luma_ps_code, sizeof(luma_ps_code) - 1, "ps_4_0"); + hr = ID3D11Device_CreatePixelShader(device, ID3D10Blob_GetBufferPointer(bytecode), + ID3D10Blob_GetBufferSize(bytecode), NULL, &luma_ps); + ID3D10Blob_Release(bytecode); + + bytecode = compile_shader(chroma_ps_code, sizeof(chroma_ps_code) - 1, "ps_4_0"); + hr = ID3D11Device_CreatePixelShader(device, ID3D10Blob_GetBufferPointer(bytecode), + ID3D10Blob_GetBufferSize(bytecode), NULL, &chroma_ps); + ID3D10Blob_Release(bytecode); + + desc.Width = width / 2; + desc.Height = height / 2; + desc.Format = DXGI_FORMAT_R8_UINT; + desc.BindFlags = D3D11_BIND_UNORDERED_ACCESS; + + hr = ID3D11Device_CreateTexture2D(device, &desc, NULL, &check_texture); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + srv_desc.Format = DXGI_FORMAT_R8_UINT; + srv_desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + srv_desc.Texture2D.MostDetailedMip = 0; + srv_desc.Texture2D.MipLevels = 1; + + hr = ID3D11Device_CreateShaderResourceView(device, (ID3D11Resource *)texture, &srv_desc, &srv1); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + srv_desc.Format = DXGI_FORMAT_R8G8_UINT; + + hr = ID3D11Device_CreateShaderResourceView(device, (ID3D11Resource *)texture, &srv_desc, &srv2); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + uav_desc.Format = DXGI_FORMAT_R8_UINT; + uav_desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D; + uav_desc.Texture2D.MipSlice = 0; + + hr = ID3D11Device_CreateUnorderedAccessView(device, (ID3D11Resource *)check_texture, &uav_desc, &check_uav); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + ID3D11DeviceContext_ClearUnorderedAccessViewUint(device_context, check_uav, clear_values); + ID3D11DeviceContext_CSSetShader(device_context, luma_cs, NULL, 0); + ID3D11DeviceContext_CSSetShaderResources(device_context, 0, 1, &srv1); + ID3D11DeviceContext_CSSetUnorderedAccessViews(device_context, 1, 1, &check_uav, NULL); + ID3D11DeviceContext_Dispatch(device_context, width / 2, height / 2, 1); + + get_texture_readback(check_texture, 0, &rb); + check_readback_data_u8(&rb, NULL, 0x1, 0); + release_resource_readback(&rb); + + ID3D11DeviceContext_ClearUnorderedAccessViewUint(device_context, check_uav, clear_values); + ID3D11DeviceContext_CSSetShader(device_context, chroma_cs, NULL, 0); + ID3D11DeviceContext_CSSetShaderResources(device_context, 0, 1, &srv2); + ID3D11DeviceContext_CSSetUnorderedAccessViews(device_context, 1, 1, &check_uav, NULL); + ID3D11DeviceContext_Dispatch(device_context, width / 2, height / 2, 1); + + get_texture_readback(check_texture, 0, &rb); + check_readback_data_u8(&rb, NULL, 0x1, 0); + release_resource_readback(&rb); + + rtv_desc.Format = DXGI_FORMAT_R8_UINT; + rtv_desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; + rtv_desc.Texture2D.MipSlice = 0; + + hr = ID3D11Device_CreateRenderTargetView(device, (ID3D11Resource *)texture, &rtv_desc, &rtv1); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + rtv_desc.Format = DXGI_FORMAT_R8G8_UINT; + + hr = ID3D11Device_CreateRenderTargetView(device, (ID3D11Resource *)texture, &rtv_desc, &rtv2); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + ID3D11DeviceContext_ClearRenderTargetView(device_context, rtv1, clear_values_float); + set_viewport(device_context, 0.0, 0.0, width, height, 0.0, 1.0); + ID3D11DeviceContext_OMSetRenderTargets(device_context, 1, &rtv1, NULL); + ID3D11DeviceContext_PSSetShader(device_context, luma_ps, NULL, 0); + draw_quad(&test_context); + + ID3D11DeviceContext_ClearRenderTargetView(device_context, rtv2, clear_values_float); + set_viewport(device_context, 0.0, 0.0, width, height, 0.0, 1.0); + ID3D11DeviceContext_OMSetRenderTargets(device_context, 1, &rtv2, NULL); + ID3D11DeviceContext_PSSetShader(device_context, chroma_ps, NULL, 0); + draw_quad(&test_context); + + ID3D11DeviceContext_OMSetRenderTargets(device_context, 0, NULL, NULL); + ID3D11DeviceContext_ClearUnorderedAccessViewUint(device_context, check_uav, clear_values); + ID3D11DeviceContext_CSSetShader(device_context, luma_cs, NULL, 0); + ID3D11DeviceContext_CSSetShaderResources(device_context, 0, 1, &srv1); + ID3D11DeviceContext_CSSetUnorderedAccessViews(device_context, 1, 1, &check_uav, NULL); + ID3D11DeviceContext_Dispatch(device_context, width / 2, height / 2, 1); + + get_texture_readback(check_texture, 0, &rb); + check_readback_data_u8(&rb, NULL, 0x1, 0); + release_resource_readback(&rb); + + ID3D11DeviceContext_ClearUnorderedAccessViewUint(device_context, check_uav, clear_values); + ID3D11DeviceContext_CSSetShader(device_context, chroma_cs, NULL, 0); + ID3D11DeviceContext_CSSetShaderResources(device_context, 0, 1, &srv2); + ID3D11DeviceContext_CSSetUnorderedAccessViews(device_context, 1, 1, &check_uav, NULL); + ID3D11DeviceContext_Dispatch(device_context, width / 2, height / 2, 1); + + get_texture_readback(check_texture, 0, &rb); + check_readback_data_u8(&rb, NULL, 0x1, 0); + release_resource_readback(&rb); + + ID3D11RenderTargetView_Release(rtv2); + ID3D11RenderTargetView_Release(rtv1); + ID3D11UnorderedAccessView_Release(check_uav); + ID3D11ShaderResourceView_Release(srv2); + ID3D11ShaderResourceView_Release(srv1); + ID3D11Texture2D_Release(check_texture); + ID3D11PixelShader_Release(chroma_ps); + ID3D11PixelShader_Release(luma_ps); + ID3D11ComputeShader_Release(chroma_cs); + ID3D11ComputeShader_Release(luma_cs); + ID3D11Texture2D_Release(texture); + release_test_context(&test_context); +} + START_TEST(d3d11) { unsigned int argc, i; @@ -36363,6 +36632,7 @@ START_TEST(d3d11) queue_test(test_clear_during_render); queue_test(test_stencil_export); queue_test(test_high_resource_count); + queue_test(test_nv12);
run_queued_tests();
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=146058
Your paranoid android.
=== w7u_2qxl (32 bit report) ===
d3d11: d3d11.c:36299: Test failed: Got hr 0x80070057.
=== w7u_adm (32 bit report) ===
d3d11: d3d11.c:36299: Test failed: Got hr 0x80070057.
=== w7u_el (32 bit report) ===
d3d11: d3d11.c:36299: Test failed: Got hr 0x80070057.
=== w7pro64 (64 bit report) ===
d3d11: d3d11.c:36299: Test failed: Got hr 0x80070057.
`test-linux-32` passed the first time, so I guess it's just flaky.
This is fine, although the slightly unfortunate thing about writing the test this way is that you can't see what the actual texture contents are if they're wrong. I.e. could we instead just write the loaded values directly into the UAV/RTV and check them on CPU?