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();