Wine-Devel
By thread
wine-devel@list.winehq.org
By month
Messages by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
November 2018
- 75 participants
- 1979 messages
[PATCH vkd3d 2/4] tests: Add test for shader input/output components.
by Józef Kucia
From: Józef Kucia <jkucia(a)codeweavers.com>
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
tests/d3d12.c | 260 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 260 insertions(+)
diff --git a/tests/d3d12.c b/tests/d3d12.c
index 504c77deb74b..16d0d0824911 100644
--- a/tests/d3d12.c
+++ b/tests/d3d12.c
@@ -8356,6 +8356,265 @@ static void test_shader_interstage_interface(void)
destroy_test_context(&context);
}
+static void test_shader_input_output_components(void)
+{
+ D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
+ ID3D12GraphicsCommandList *command_list;
+ D3D12_INPUT_LAYOUT_DESC input_layout;
+ D3D12_CPU_DESCRIPTOR_HANDLE rtvs[2];
+ ID3D12Resource *uint_render_target;
+ struct test_context_desc desc;
+ D3D12_VERTEX_BUFFER_VIEW vbv;
+ struct test_context context;
+ ID3D12CommandQueue *queue;
+ ID3D12Resource *vb;
+ HRESULT hr;
+
+ static const DWORD vs1_code[] =
+ {
+#if 0
+ void main(float4 in_position : POSITION, uint4 in_uint : UINT,
+ out float4 out_position : SV_POSITION, out uint out_uint : UINT,
+ out float3 out_float : FLOAT)
+ {
+ out_position = in_position;
+ out_uint = in_uint.y;
+ out_float = float3(1, 2, 3);
+ }
+#endif
+ 0x43425844, 0x0521bc60, 0xd39733a4, 0x1522eea3, 0x0c741ea3, 0x00000001, 0x0000018c, 0x00000003,
+ 0x0000002c, 0x0000007c, 0x000000ec, 0x4e475349, 0x00000048, 0x00000002, 0x00000008, 0x00000038,
+ 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x00000041, 0x00000000, 0x00000000,
+ 0x00000001, 0x00000001, 0x0000020f, 0x49534f50, 0x4e4f4954, 0x4e495500, 0xabab0054, 0x4e47534f,
+ 0x00000068, 0x00000003, 0x00000008, 0x00000050, 0x00000000, 0x00000001, 0x00000003, 0x00000000,
+ 0x0000000f, 0x0000005c, 0x00000000, 0x00000000, 0x00000001, 0x00000001, 0x00000e01, 0x00000061,
+ 0x00000000, 0x00000000, 0x00000003, 0x00000002, 0x00000807, 0x505f5653, 0x5449534f, 0x004e4f49,
+ 0x544e4955, 0x4f4c4600, 0xab005441, 0x58454853, 0x00000098, 0x00010050, 0x00000026, 0x0100086a,
+ 0x0300005f, 0x001010f2, 0x00000000, 0x0300005f, 0x00101022, 0x00000001, 0x04000067, 0x001020f2,
+ 0x00000000, 0x00000001, 0x03000065, 0x00102012, 0x00000001, 0x03000065, 0x00102072, 0x00000002,
+ 0x05000036, 0x001020f2, 0x00000000, 0x00101e46, 0x00000000, 0x05000036, 0x00102012, 0x00000001,
+ 0x0010101a, 0x00000001, 0x08000036, 0x00102072, 0x00000002, 0x00004002, 0x3f800000, 0x40000000,
+ 0x40400000, 0x00000000, 0x0100003e,
+ };
+ static const D3D12_SHADER_BYTECODE vs1 = {vs1_code, sizeof(vs1_code)};
+ static const DWORD ps1_code[] =
+ {
+#if 0
+ void main(float4 position : SV_POSITION, uint in_uint : UINT,
+ float3 in_float : FLOAT, out float4 out_float : SV_TARGET0,
+ out uint4 out_uint : SV_TARGET1)
+ {
+ out_float.x = position.w;
+ out_float.y = in_uint;
+ out_float.z = in_float.z;
+ out_float.w = 0;
+ out_uint.x = 0xdeadbeef;
+ out_uint.y = 0;
+ out_uint.z = in_uint;
+ out_uint.w = in_float.z;
+ }
+#endif
+ 0x43425844, 0x762dbf5e, 0x2cc83972, 0x60c7aa48, 0xbca6118a, 0x00000001, 0x000001d4, 0x00000003,
+ 0x0000002c, 0x0000009c, 0x000000e8, 0x4e475349, 0x00000068, 0x00000003, 0x00000008, 0x00000050,
+ 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000080f, 0x0000005c, 0x00000000, 0x00000000,
+ 0x00000001, 0x00000001, 0x00000101, 0x00000061, 0x00000000, 0x00000000, 0x00000003, 0x00000002,
+ 0x00000407, 0x505f5653, 0x5449534f, 0x004e4f49, 0x544e4955, 0x4f4c4600, 0xab005441, 0x4e47534f,
+ 0x00000044, 0x00000002, 0x00000008, 0x00000038, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
+ 0x0000000f, 0x00000038, 0x00000001, 0x00000000, 0x00000001, 0x00000001, 0x0000000f, 0x545f5653,
+ 0x45475241, 0xabab0054, 0x52444853, 0x000000e4, 0x00000040, 0x00000039, 0x04002064, 0x00101082,
+ 0x00000000, 0x00000001, 0x03000862, 0x00101012, 0x00000001, 0x03001062, 0x00101042, 0x00000002,
+ 0x03000065, 0x001020f2, 0x00000000, 0x03000065, 0x001020f2, 0x00000001, 0x05000056, 0x00102022,
+ 0x00000000, 0x0010100a, 0x00000001, 0x05000036, 0x00102012, 0x00000000, 0x0010103a, 0x00000000,
+ 0x05000036, 0x00102042, 0x00000000, 0x0010102a, 0x00000002, 0x05000036, 0x00102082, 0x00000000,
+ 0x00004001, 0x00000000, 0x0500001c, 0x00102082, 0x00000001, 0x0010102a, 0x00000002, 0x08000036,
+ 0x00102032, 0x00000001, 0x00004002, 0xdeadbeef, 0x00000000, 0x00000000, 0x00000000, 0x05000036,
+ 0x00102042, 0x00000001, 0x0010100a, 0x00000001, 0x0100003e,
+ };
+ static const D3D12_SHADER_BYTECODE ps1 = {ps1_code, sizeof(ps1_code)};
+ static const DWORD vs2_code[] =
+ {
+#if 0
+ void main(float4 in_position : POSITION,
+ float4 in_texcoord0 : TEXCOORD0, float4 in_texcoord1 : TEXCOORD1,
+ float4 in_texcoord2 : TEXCOORD2,
+ out float4 position : Sv_Position,
+ out float2 texcoord0 : TEXCOORD0, out float2 texcoord1 : TEXCOORD1,
+ out float4 texcoord2 : TEXCOORD2, out float3 texcoord3 : TEXCOORD3)
+ {
+ position = in_position;
+ texcoord0 = in_texcoord0.yx;
+ texcoord1 = in_texcoord0.wz;
+ texcoord2 = in_texcoord1;
+ texcoord3 = in_texcoord2.yzx;
+ }
+#endif
+ 0x43425844, 0x6721613b, 0xb997c7e4, 0x8bc3df4d, 0x813c93b9, 0x00000001, 0x00000224, 0x00000003,
+ 0x0000002c, 0x000000b0, 0x00000150, 0x4e475349, 0x0000007c, 0x00000004, 0x00000008, 0x00000068,
+ 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x00000071, 0x00000000, 0x00000000,
+ 0x00000003, 0x00000001, 0x00000f0f, 0x00000071, 0x00000001, 0x00000000, 0x00000003, 0x00000002,
+ 0x00000f0f, 0x00000071, 0x00000002, 0x00000000, 0x00000003, 0x00000003, 0x0000070f, 0x49534f50,
+ 0x4e4f4954, 0x58455400, 0x524f4f43, 0xabab0044, 0x4e47534f, 0x00000098, 0x00000005, 0x00000008,
+ 0x00000080, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x0000008c, 0x00000000,
+ 0x00000000, 0x00000003, 0x00000001, 0x00000c03, 0x0000008c, 0x00000001, 0x00000000, 0x00000003,
+ 0x00000001, 0x0000030c, 0x0000008c, 0x00000002, 0x00000000, 0x00000003, 0x00000002, 0x0000000f,
+ 0x0000008c, 0x00000003, 0x00000000, 0x00000003, 0x00000003, 0x00000807, 0x505f7653, 0x7469736f,
+ 0x006e6f69, 0x43584554, 0x44524f4f, 0xababab00, 0x52444853, 0x000000cc, 0x00010040, 0x00000033,
+ 0x0300005f, 0x001010f2, 0x00000000, 0x0300005f, 0x001010f2, 0x00000001, 0x0300005f, 0x001010f2,
+ 0x00000002, 0x0300005f, 0x00101072, 0x00000003, 0x04000067, 0x001020f2, 0x00000000, 0x00000001,
+ 0x03000065, 0x00102032, 0x00000001, 0x03000065, 0x001020c2, 0x00000001, 0x03000065, 0x001020f2,
+ 0x00000002, 0x03000065, 0x00102072, 0x00000003, 0x05000036, 0x001020f2, 0x00000000, 0x00101e46,
+ 0x00000000, 0x05000036, 0x001020f2, 0x00000001, 0x00101b16, 0x00000001, 0x05000036, 0x001020f2,
+ 0x00000002, 0x00101e46, 0x00000002, 0x05000036, 0x00102072, 0x00000003, 0x00101496, 0x00000003,
+ 0x0100003e,
+ };
+ static const D3D12_SHADER_BYTECODE vs2 = {vs2_code, sizeof(vs2_code)};
+ static const DWORD ps2_code[] =
+ {
+#if 0
+ void main(float4 position : Sv_Position,
+ float2 texcoord0 : TEXCOORD0, float2 texcoord1 : TEXCOORD1,
+ float4 texcoord2 : TEXCOORD2, float3 texcoord3 : TEXCOORD3,
+ out float4 target0 : Sv_Target0, out uint4 target1 : SV_Target1)
+ {
+ target0.x = texcoord0.x + texcoord0.y;
+ target0.y = texcoord1.x;
+ target0.z = texcoord3.z;
+ target0.w = texcoord1.y;
+
+ target1.x = texcoord2.x;
+ target1.y = texcoord2.y;
+ target1.w = texcoord2.w;
+ target1.z = 0;
+ }
+#endif
+ 0x43425844, 0xa6c0df60, 0x5bf34683, 0xa0093595, 0x98cca724, 0x00000001, 0x000001e8, 0x00000003,
+ 0x0000002c, 0x000000cc, 0x00000120, 0x4e475349, 0x00000098, 0x00000005, 0x00000008, 0x00000080,
+ 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000000f, 0x0000008c, 0x00000000, 0x00000000,
+ 0x00000003, 0x00000001, 0x00000303, 0x0000008c, 0x00000001, 0x00000000, 0x00000003, 0x00000001,
+ 0x00000c0c, 0x0000008c, 0x00000002, 0x00000000, 0x00000003, 0x00000002, 0x00000b0f, 0x0000008c,
+ 0x00000003, 0x00000000, 0x00000003, 0x00000003, 0x00000407, 0x505f7653, 0x7469736f, 0x006e6f69,
+ 0x43584554, 0x44524f4f, 0xababab00, 0x4e47534f, 0x0000004c, 0x00000002, 0x00000008, 0x00000038,
+ 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x0000000f, 0x00000042, 0x00000001, 0x00000000,
+ 0x00000001, 0x00000001, 0x0000000f, 0x545f7653, 0x65677261, 0x56530074, 0x7261545f, 0x00746567,
+ 0x52444853, 0x000000c0, 0x00000040, 0x00000030, 0x03001062, 0x00101032, 0x00000001, 0x03001062,
+ 0x001010c2, 0x00000001, 0x03001062, 0x001010b2, 0x00000002, 0x03001062, 0x00101042, 0x00000003,
+ 0x03000065, 0x001020f2, 0x00000000, 0x03000065, 0x001020f2, 0x00000001, 0x07000000, 0x00102012,
+ 0x00000000, 0x0010101a, 0x00000001, 0x0010100a, 0x00000001, 0x05000036, 0x001020a2, 0x00000000,
+ 0x00101ea6, 0x00000001, 0x05000036, 0x00102042, 0x00000000, 0x0010102a, 0x00000003, 0x0500001c,
+ 0x001020b2, 0x00000001, 0x00101c46, 0x00000002, 0x05000036, 0x00102042, 0x00000001, 0x00004001,
+ 0x00000000, 0x0100003e,
+ };
+ static const D3D12_SHADER_BYTECODE ps2 = {ps2_code, sizeof(ps2_code)};
+ static const D3D12_INPUT_ELEMENT_DESC layout_desc[] =
+ {
+ {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
+ {"UINT", 0, DXGI_FORMAT_R32G32B32A32_UINT, 0, 16, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
+ {"TEXCOORD", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 32, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
+ {"TEXCOORD", 1, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 48, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
+ {"TEXCOORD", 2, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 64, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
+ };
+ static const struct
+ {
+ struct vec4 position;
+ struct uvec4 u;
+ struct vec4 t0;
+ struct vec4 t1;
+ struct vec4 t2;
+ }
+ quad[] =
+ {
+ {{-1.0f, -1.0f}, {1, 2, 3, 4}, {3.0f, 3.0f, 8.0f, 4.0f}, {9.0f, 5.0f, 3.0f, 1.0f}, {7.0f, 2.0f}},
+ {{-1.0f, 1.0f}, {1, 2, 3, 4}, {3.0f, 3.0f, 8.0f, 4.0f}, {9.0f, 5.0f, 3.0f, 1.0f}, {7.0f, 2.0f}},
+ {{ 1.0f, -1.0f}, {1, 2, 3, 4}, {3.0f, 3.0f, 8.0f, 4.0f}, {9.0f, 5.0f, 3.0f, 1.0f}, {7.0f, 2.0f}},
+ {{ 1.0f, 1.0f}, {1, 2, 3, 4}, {3.0f, 3.0f, 8.0f, 4.0f}, {9.0f, 5.0f, 3.0f, 1.0f}, {7.0f, 2.0f}},
+ };
+ static const struct vec4 expected_vec4[] = {{1.0f, 2.0f, 3.0f, 0.0f}, {6.0f, 4.0f, 7.0f, 8.0f}};
+ static const struct uvec4 expected_uvec4[] = {{0xdeadbeef, 0, 2, 3}, {9, 5, 0, 1}};
+
+ memset(&desc, 0, sizeof(desc));
+ desc.rt_format = DXGI_FORMAT_R32G32B32A32_FLOAT;
+ desc.rt_descriptor_count = 2;
+ desc.no_root_signature = true;
+ if (!init_test_context(&context, &desc))
+ return;
+ command_list = context.list;
+ queue = context.queue;
+
+ context.root_signature = create_empty_root_signature(context.device,
+ D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT);
+
+ input_layout.pInputElementDescs = layout_desc;
+ input_layout.NumElements = ARRAY_SIZE(layout_desc);
+ init_pipeline_state_desc(&pso_desc, context.root_signature, desc.rt_format, &vs1, &ps1, &input_layout);
+ pso_desc.NumRenderTargets = 2;
+ pso_desc.RTVFormats[1] = DXGI_FORMAT_R32G32B32A32_UINT;
+ hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
+ &IID_ID3D12PipelineState, (void **)&context.pipeline_state);
+ ok(hr == S_OK, "Failed to create graphics pipeline state, hr %#x.\n", hr);
+
+ rtvs[0] = context.rtv;
+ rtvs[1] = get_cpu_rtv_handle(&context, context.rtv_heap, 1);
+ desc.rt_format = pso_desc.RTVFormats[1];
+ create_render_target(&context, &desc, &uint_render_target, &rtvs[1]);
+
+ vb = create_upload_buffer(context.device, sizeof(quad), quad);
+
+ vbv.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(vb);
+ vbv.StrideInBytes = sizeof(*quad);
+ vbv.SizeInBytes = sizeof(quad);
+
+ ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 2, &context.rtv, TRUE, NULL);
+ ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
+ ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
+ ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
+ ID3D12GraphicsCommandList_IASetVertexBuffers(command_list, 0, 1, &vbv);
+ ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
+ ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
+ ID3D12GraphicsCommandList_DrawInstanced(command_list, 4, 1, 0, 0);
+
+ transition_resource_state(command_list, context.render_target,
+ D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
+ check_sub_resource_vec4(context.render_target, 0, queue, command_list, &expected_vec4[0], 0);
+ reset_command_list(command_list, context.allocator);
+ transition_resource_state(command_list, uint_render_target,
+ D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
+ check_sub_resource_uvec4(uint_render_target, 0, queue, command_list, &expected_uvec4[0]);
+
+ reset_command_list(command_list, context.allocator);
+ transition_resource_state(command_list, context.render_target,
+ D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
+ transition_resource_state(command_list, uint_render_target,
+ D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET);
+
+ ID3D12PipelineState_Release(context.pipeline_state);
+ pso_desc.VS = vs2;
+ pso_desc.PS = ps2;
+ hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
+ &IID_ID3D12PipelineState, (void **)&context.pipeline_state);
+ ok(hr == S_OK, "Failed to create graphics pipeline state, hr %#x.\n", hr);
+
+ ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 2, &context.rtv, TRUE, NULL);
+ ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
+ ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
+ ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
+ ID3D12GraphicsCommandList_IASetVertexBuffers(command_list, 0, 1, &vbv);
+ ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
+ ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
+ ID3D12GraphicsCommandList_DrawInstanced(command_list, 4, 1, 0, 0);
+
+ transition_resource_state(command_list, context.render_target,
+ D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
+ check_sub_resource_vec4(context.render_target, 0, queue, command_list, &expected_vec4[1], 0);
+ reset_command_list(command_list, context.allocator);
+ transition_resource_state(command_list, uint_render_target,
+ D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
+ check_sub_resource_uvec4(uint_render_target, 0, queue, command_list, &expected_uvec4[1]);
+
+ ID3D12Resource_Release(vb);
+ ID3D12Resource_Release(uint_render_target);
+ destroy_test_context(&context);
+}
+
static void test_incompletely_initialized_shader_outputs(void)
{
static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
@@ -20914,6 +21173,7 @@ START_TEST(d3d12)
run_test(test_compute_shader_instructions);
run_test(test_discard_instruction);
run_test(test_shader_interstage_interface);
+ run_test(test_shader_input_output_components);
run_test(test_incompletely_initialized_shader_outputs);
run_test(test_root_signature_byte_code);
run_test(test_cs_constant_buffer);
--
2.18.1
Nov. 1, 2018
[PATCH v2 vkd3d 1/4] tests: Introduce check_sub_resource_uvec4().
by Józef Kucia
From: Józef Kucia <jkucia(a)codeweavers.com>
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
Version 2: Use sub_resource_idx in check_sub_resource_*() functions.
---
tests/d3d12.c | 55 ++++++++++++++++++++++++++++++++++-----------------
1 file changed, 37 insertions(+), 18 deletions(-)
diff --git a/tests/d3d12.c b/tests/d3d12.c
index 25c2fdf80439..504c77deb74b 100644
--- a/tests/d3d12.c
+++ b/tests/d3d12.c
@@ -749,7 +749,7 @@ static void check_sub_resource_uint8_(unsigned int line, ID3D12Resource *texture
{
struct resource_readback rb;
- get_texture_readback_with_command_list(texture, 0, &rb, queue, command_list);
+ get_texture_readback_with_command_list(texture, sub_resource_idx, &rb, queue, command_list);
check_readback_data_uint8_(line, &rb, NULL, expected, max_diff);
release_resource_readback(&rb);
}
@@ -805,7 +805,7 @@ static void check_sub_resource_vec4_(unsigned int line, ID3D12Resource *texture,
bool all_match = true;
struct vec4 got = {};
- get_texture_readback_with_command_list(texture, 0, &rb, queue, command_list);
+ get_texture_readback_with_command_list(texture, sub_resource_idx, &rb, queue, command_list);
for (y = 0; y < rb.height; ++y)
{
for (x = 0; x < rb.width; ++x)
@@ -826,6 +826,39 @@ static void check_sub_resource_vec4_(unsigned int line, ID3D12Resource *texture,
got.x, got.y, got.z, got.w, expected->x, expected->y, expected->z, expected->w, x, y);
}
+#define check_sub_resource_uvec4(a, b, c, d, e) check_sub_resource_uvec4_(__LINE__, a, b, c, d, e)
+static void check_sub_resource_uvec4_(unsigned int line, ID3D12Resource *texture,
+ unsigned int sub_resource_idx, ID3D12CommandQueue *queue, ID3D12GraphicsCommandList *command_list,
+ const struct uvec4 *expected_value)
+{
+ struct resource_readback rb;
+ struct uvec4 value = {};
+ unsigned int x = 0, y;
+ bool all_match = true;
+
+ get_texture_readback_with_command_list(texture, sub_resource_idx, &rb, queue, command_list);
+ for (y = 0; y < rb.height; ++y)
+ {
+ for (x = 0; x < rb.width; ++x)
+ {
+ value = *get_readback_uvec4(&rb, x, y);
+ if (!compare_uvec4(&value, expected_value))
+ {
+ all_match = false;
+ break;
+ }
+ }
+ if (!all_match)
+ break;
+ }
+ release_resource_readback(&rb);
+
+ ok_(line)(all_match,
+ "Got {0x%08x, 0x%08x, 0x%08x, 0x%08x}, expected {0x%08x, 0x%08x, 0x%08x, 0x%08x} at (%u, %u).\n",
+ value.x, value.y, value.z, value.w,
+ expected_value->x, expected_value->y, expected_value->z, expected_value->w, x, y);
+}
+
static bool use_warp_device;
static unsigned int use_adapter_idx;
@@ -5459,10 +5492,9 @@ static void test_shader_instructions(void)
ID3D12GraphicsCommandList *command_list;
struct test_context_desc desc;
struct test_context context;
- struct resource_readback rb;
ID3D12CommandQueue *queue;
- unsigned int i, x, y;
ID3D12Resource *cb;
+ unsigned int i;
HRESULT hr;
static const DWORD ps_div_code[] =
@@ -7850,20 +7882,7 @@ static void test_shader_instructions(void)
transition_resource_state(command_list, context.render_target,
D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
-
- get_texture_readback_with_command_list(context.render_target, 0, &rb, queue, command_list);
- for (y = 0; y < rb.height; ++y)
- {
- for (x = 0; x < rb.width; ++x)
- {
- const struct uvec4 *v = get_readback_uvec4(&rb, x, y);
- ok(compare_uvec4(v, &uint_tests[i].output.u),
- "Got 0x%08x, 0x%08x, 0x%08x, 0x%08x expected 0x%08x, 0x%08x, 0x%08x, 0x%08x.\n",
- v->x, v->y, v->z, v->w, uint_tests[i].output.u.x, uint_tests[i].output.u.y,
- uint_tests[i].output.u.z, uint_tests[i].output.u.w);
- }
- }
- release_resource_readback(&rb);
+ check_sub_resource_uvec4(context.render_target, 0, queue, command_list, &uint_tests[i].output.u);
reset_command_list(command_list, context.allocator);
transition_resource_state(command_list, context.render_target,
--
2.18.1
Nov. 1, 2018
Re: [PATCH 2/2] rpcrt4: Avoid reference leaks when unmarshalling [in, out] interface pointers.
by Alexandre Julliard
Zebediah Figura <z.figura12(a)gmail.com> writes:
> Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
> ---
> dlls/rpcrt4/ndr_ole.c | 10 ++++++++--
> dlls/rpcrt4/tests/ndr_marshall.c | 2 --
> 2 files changed, 8 insertions(+), 4 deletions(-)
This causes a test failure:
../../../tools/runtest -q -P wine -T ../../.. -M qmgr.dll -p qmgr_test.exe.so enum_files && touch enum_files.ok
enum_files.c:228: Test failed: Invalid call to Next succeeded: c0000005
make: *** [Makefile:189: enum_files.ok] Error 1
--
Alexandre Julliard
julliard(a)winehq.org
Nov. 1, 2018
Re: [PATCH] d3d11/tests: Add test for SO statistics queries.
by Marvin
Hi,
While running your changed tests on Windows, I think I found new failures.
Being a bot and all I'm not very good at pattern recognition, so I might be
wrong, but could you please double-check?
Full results can be found at:
https://testbot.winehq.org/JobDetails.pl?Key=43793
Your paranoid android.
=== debian9 (32 bit Wine report) ===
d3d11:
d3d11.c:5586: Test failed: Got unexpected hr 0x8876086a.
Unhandled exception: page fault on execute access to 0x00000000 in 32-bit code (0x00000000).
=== debian9 (build log) ===
=== debian9 (32 bit WoW Wine report) ===
d3d11:
Unhandled exception: page fault on execute access to 0x00000000 in 32-bit code (0x00000000).
=== debian9 (64 bit Wow Wine report) ===
d3d11:
d3d11.c:16314: Test failed: Got {-1.00787401e+00, 0.00000000e+00, 1.00000000e+00, 5.03937006e-01}, expected {-1.00000000e+00, 0.00000000e+00, 1.00000000e+00, 5.03937006e-01} at (0, 0), sub-resource 0.
=== debian9 (build log) ===
Nov. 1, 2018
[PATCH] d3d11/tests: Add test for SO statistics queries.
by Józef Kucia
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
dlls/d3d11/tests/d3d11.c | 93 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 93 insertions(+)
diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c
index 632ef4f35382..0174289879bc 100644
--- a/dlls/d3d11/tests/d3d11.c
+++ b/dlls/d3d11/tests/d3d11.c
@@ -5789,6 +5789,98 @@ static void test_timestamp_query(void)
release_test_context(&test_context);
}
+static void test_so_statistics_query(void)
+{
+ struct d3d11_test_context test_context;
+ D3D11_QUERY_DATA_SO_STATISTICS data;
+ ID3D11DeviceContext *context;
+ D3D11_QUERY_DESC query_desc;
+ ID3D11Asynchronous *query;
+ unsigned int data_size;
+ ID3D11Device *device;
+ unsigned int i;
+ HRESULT hr;
+
+ static const struct
+ {
+ D3D11_QUERY query;
+ D3D_FEATURE_LEVEL feature_level;
+ }
+ tests[] =
+ {
+ {D3D11_QUERY_SO_STATISTICS, D3D_FEATURE_LEVEL_10_0},
+ {D3D11_QUERY_SO_STATISTICS_STREAM0, D3D_FEATURE_LEVEL_11_0},
+ {D3D11_QUERY_SO_STATISTICS_STREAM1, D3D_FEATURE_LEVEL_11_0},
+ {D3D11_QUERY_SO_STATISTICS_STREAM2, D3D_FEATURE_LEVEL_11_0},
+ {D3D11_QUERY_SO_STATISTICS_STREAM3, D3D_FEATURE_LEVEL_11_0},
+ };
+
+ if (!init_test_context(&test_context, NULL))
+ return;
+
+ device = test_context.device;
+ context = test_context.immediate_context;
+
+ for (i = 0; i < ARRAY_SIZE(tests); ++i)
+ {
+ if (ID3D11Device_GetFeatureLevel(device) < tests[i].feature_level)
+ {
+ skip("Feature level %#x is required.\n", tests[i].feature_level);
+ continue;
+ }
+
+ query_desc.Query = tests[i].query;
+ query_desc.MiscFlags = 0;
+ hr = ID3D11Device_CreateQuery(device, &query_desc, (ID3D11Query **)&query);
+ todo_wine_if(query_desc.Query == D3D11_QUERY_SO_STATISTICS)
+ ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
+ if (FAILED(hr)) continue;
+ data_size = ID3D11Asynchronous_GetDataSize(query);
+ ok(data_size == sizeof(data), "Got unexpected data size %u.\n", data_size);
+
+ hr = ID3D11DeviceContext_GetData(context, query, NULL, 0, 0);
+ ok(hr == DXGI_ERROR_INVALID_CALL, "Got unexpected hr %#x.\n", hr);
+ hr = ID3D11DeviceContext_GetData(context, query, &data, sizeof(data), 0);
+ ok(hr == DXGI_ERROR_INVALID_CALL, "Got unexpected hr %#x.\n", hr);
+
+ ID3D11DeviceContext_End(context, query);
+ ID3D11DeviceContext_Begin(context, query);
+ ID3D11DeviceContext_Begin(context, query);
+
+ memset(&data, 0xff, sizeof(data));
+ hr = ID3D11DeviceContext_GetData(context, query, NULL, 0, 0);
+ todo_wine ok(hr == DXGI_ERROR_INVALID_CALL, "Got unexpected hr %#x.\n", hr);
+ hr = ID3D11DeviceContext_GetData(context, query, &data, sizeof(data), 0);
+ todo_wine ok(hr == DXGI_ERROR_INVALID_CALL, "Got unexpected hr %#x.\n", hr);
+ ok(data.NumPrimitivesWritten == ~(UINT64)0, "Data was modified.\n");
+ ok(data.PrimitivesStorageNeeded == ~(UINT64)0, "Data was modified.\n");
+
+ draw_quad(&test_context);
+
+ ID3D11DeviceContext_End(context, query);
+ get_query_data(context, query, &data, sizeof(data));
+ ok(!data.NumPrimitivesWritten, "Got unexpected NumPrimitivesWritten: %u.\n",
+ (unsigned int)data.NumPrimitivesWritten);
+ todo_wine_if(query_desc.Query == D3D11_QUERY_SO_STATISTICS_STREAM0)
+ ok(!data.PrimitivesStorageNeeded, "Got unexpected PrimitivesStorageNeeded: %u.\n",
+ (unsigned int)data.PrimitivesStorageNeeded);
+
+ ID3D11DeviceContext_Begin(context, query);
+ draw_quad(&test_context);
+ ID3D11DeviceContext_End(context, query);
+ get_query_data(context, query, &data, sizeof(data));
+ ok(!data.NumPrimitivesWritten, "Got unexpected NumPrimitivesWritten: %u.\n",
+ (unsigned int)data.NumPrimitivesWritten);
+ todo_wine_if(query_desc.Query == D3D11_QUERY_SO_STATISTICS_STREAM0)
+ ok(!data.PrimitivesStorageNeeded, "Got unexpected PrimitivesStorageNeeded: %u.\n",
+ (unsigned int)data.PrimitivesStorageNeeded);
+
+ ID3D11Asynchronous_Release(query);
+ }
+
+ release_test_context(&test_context);
+}
+
static void test_device_removed_reason(void)
{
ID3D11Device *device;
@@ -28691,6 +28783,7 @@ START_TEST(d3d11)
queue_test(test_occlusion_query);
queue_test(test_pipeline_statistics_query);
queue_test(test_timestamp_query);
+ queue_test(test_so_statistics_query);
queue_test(test_device_removed_reason);
queue_test(test_private_data);
queue_for_each_feature_level(test_state_refcounting);
--
2.18.1
Nov. 1, 2018
[PATCH v5 4/4] shell32/tests: Test the amount of enumerator resets for AutoComplete
by Gabriel Ivăncescu
Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)gmail.com>
---
It's periodically set to 0 to prevent cascading failures.
dlls/shell32/tests/autocomplete.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/dlls/shell32/tests/autocomplete.c b/dlls/shell32/tests/autocomplete.c
index 66bd472..8265bf9 100644
--- a/dlls/shell32/tests/autocomplete.c
+++ b/dlls/shell32/tests/autocomplete.c
@@ -274,6 +274,7 @@ struct string_enumerator
WCHAR **data;
int data_len;
int cur;
+ UINT num_resets;
UINT num_expand;
WCHAR last_expand[32];
};
@@ -349,6 +350,7 @@ static HRESULT WINAPI string_enumerator_Reset(IEnumString *iface)
struct string_enumerator *this = impl_from_IEnumString(iface);
this->cur = 0;
+ this->num_resets++;
return S_OK;
}
@@ -456,6 +458,7 @@ static void test_aclist_expand(HWND hwnd_edit, void *enumerator)
static WCHAR str2[] = {'t','e','s','t','\\','f','o','o','\\','b','a','r','\\','b','a',0};
static WCHAR str2a[] = {'t','e','s','t','\\','f','o','o','\\','b','a','r','\\',0};
static WCHAR str2b[] = {'t','e','s','t','\\','f','o','o','\\','b','a','r','\\','b','a','z','_','b','b','q','\\',0};
+ obj->num_resets = 0;
ok(obj->num_expand == 0, "Expected 0 expansions, got %u\n", obj->num_expand);
SendMessageW(hwnd_edit, WM_SETTEXT, 0, (LPARAM)str1);
@@ -464,12 +467,14 @@ static void test_aclist_expand(HWND hwnd_edit, void *enumerator)
dispatch_messages();
ok(obj->num_expand == 1, "Expected 1 expansion, got %u\n", obj->num_expand);
ok(lstrcmpW(obj->last_expand, str1a) == 0, "Expected %s, got %s\n", wine_dbgstr_w(str1a), wine_dbgstr_w(obj->last_expand));
+ ok(obj->num_resets == 1, "Expected 1 reset, got %u\n", obj->num_resets);
SendMessageW(hwnd_edit, WM_SETTEXT, 0, (LPARAM)str2);
SendMessageW(hwnd_edit, EM_SETSEL, ARRAY_SIZE(str2) - 1, ARRAY_SIZE(str2) - 1);
SendMessageW(hwnd_edit, WM_CHAR, 'z', 1);
dispatch_messages();
ok(obj->num_expand == 2, "Expected 2 expansions, got %u\n", obj->num_expand);
ok(lstrcmpW(obj->last_expand, str2a) == 0, "Expected %s, got %s\n", wine_dbgstr_w(str2a), wine_dbgstr_w(obj->last_expand));
+ ok(obj->num_resets == 2, "Expected 2 resets, got %u\n", obj->num_resets);
SetFocus(hwnd_edit);
SendMessageW(hwnd_edit, WM_CHAR, '_', 1);
SendMessageW(hwnd_edit, WM_CHAR, 'b', 1);
@@ -479,20 +484,24 @@ static void test_aclist_expand(HWND hwnd_edit, void *enumerator)
SendMessageW(hwnd_edit, WM_CHAR, 'q', 1);
dispatch_messages();
ok(obj->num_expand == 2, "Expected 2 expansions, got %u\n", obj->num_expand);
+ ok(obj->num_resets == 2, "Expected 2 resets, got %u\n", obj->num_resets);
SendMessageW(hwnd_edit, WM_CHAR, '\\', 1);
dispatch_messages();
ok(obj->num_expand == 3, "Expected 3 expansions, got %u\n", obj->num_expand);
ok(lstrcmpW(obj->last_expand, str2b) == 0, "Expected %s, got %s\n", wine_dbgstr_w(str2b), wine_dbgstr_w(obj->last_expand));
+ ok(obj->num_resets == 3, "Expected 3 resets, got %u\n", obj->num_resets);
SendMessageW(hwnd_edit, EM_SETSEL, ARRAY_SIZE(str1a) - 1, -1);
SendMessageW(hwnd_edit, WM_CHAR, 'x', 1);
SendMessageW(hwnd_edit, WM_CHAR, 'y', 1);
dispatch_messages();
ok(obj->num_expand == 4, "Expected 4 expansions, got %u\n", obj->num_expand);
ok(lstrcmpW(obj->last_expand, str1a) == 0, "Expected %s, got %s\n", wine_dbgstr_w(str1a), wine_dbgstr_w(obj->last_expand));
+ ok(obj->num_resets == 4, "Expected 4 resets, got %u\n", obj->num_resets);
SendMessageW(hwnd_edit, EM_SETSEL, ARRAY_SIZE(str1) - 1, -1);
SendMessageW(hwnd_edit, WM_CHAR, 'x', 1);
dispatch_messages();
ok(obj->num_expand == 4, "Expected 4 expansions, got %u\n", obj->num_expand);
+ ok(obj->num_resets == 5, "Expected 5 resets, got %u\n", obj->num_resets);
}
static void test_custom_source(void)
@@ -502,6 +511,7 @@ static void test_custom_source(void)
static WCHAR str_beta[] = {'a','u','t','o',' ','c','o','m','p','l','e','t','e',0};
static WCHAR str_au[] = {'a','u',0};
static WCHAR *suggestions[] = { str_alpha, str_alpha2, str_beta };
+ struct string_enumerator *obj;
IUnknown *enumerator;
IAutoComplete2 *autocomplete;
HWND hwnd_edit;
@@ -516,6 +526,7 @@ static void test_custom_source(void)
ok(hr == S_OK, "CoCreateInstance failed: %x\n", hr);
string_enumerator_create((void**)&enumerator, suggestions, ARRAY_SIZE(suggestions));
+ obj = (struct string_enumerator*)enumerator;
hr = IAutoComplete2_SetOptions(autocomplete, ACO_AUTOSUGGEST | ACO_AUTOAPPEND);
ok(hr == S_OK, "IAutoComplete2_SetOptions failed: %x\n", hr);
@@ -528,11 +539,14 @@ static void test_custom_source(void)
dispatch_messages();
SendMessageW(hwnd_edit, WM_GETTEXT, ARRAY_SIZE(buffer), (LPARAM)buffer);
ok(lstrcmpW(str_beta, buffer) == 0, "Expected %s, got %s\n", wine_dbgstr_w(str_beta), wine_dbgstr_w(buffer));
+ ok(obj->num_resets == 1, "Expected 1 reset, got %u\n", obj->num_resets);
SendMessageW(hwnd_edit, EM_SETSEL, 0, -1);
SendMessageW(hwnd_edit, WM_CHAR, '\b', 1);
dispatch_messages();
SendMessageW(hwnd_edit, WM_GETTEXT, ARRAY_SIZE(buffer), (LPARAM)buffer);
ok(buffer[0] == '\0', "Expected empty string, got %s\n", wine_dbgstr_w(buffer));
+ ok(obj->num_resets == 1, "Expected 1 reset, got %u\n", obj->num_resets);
+ obj->num_resets = 0;
/* hijack the window procedure */
HijackerWndProc_prev = (WNDPROC)SetWindowLongPtrW(hwnd_edit, GWLP_WNDPROC, (LONG_PTR)HijackerWndProc);
@@ -545,6 +559,7 @@ static void test_custom_source(void)
dispatch_messages();
SendMessageW(hwnd_edit, WM_GETTEXT, ARRAY_SIZE(buffer), (LPARAM)buffer);
ok(lstrcmpW(str_au, buffer) == 0, "Expected %s, got %s\n", wine_dbgstr_w(str_au), wine_dbgstr_w(buffer));
+ ok(obj->num_resets == 1, "Expected 1 reset, got %u\n", obj->num_resets);
SendMessageW(hwnd_edit, EM_SETSEL, 0, -1);
SendMessageW(hwnd_edit, WM_CHAR, '\b', 1);
dispatch_messages();
@@ -558,6 +573,7 @@ static void test_custom_source(void)
dispatch_messages();
SendMessageW(hwnd_edit, WM_GETTEXT, ARRAY_SIZE(buffer), (LPARAM)buffer);
ok(lstrcmpW(str_beta, buffer) == 0, "Expected %s, got %s\n", wine_dbgstr_w(str_beta), wine_dbgstr_w(buffer));
+ ok(obj->num_resets == 2, "Expected 2 resets, got %u\n", obj->num_resets);
/* end of hijacks */
test_aclist_expand(hwnd_edit, enumerator);
--
1.9.1
Nov. 1, 2018
[PATCH v5 3/4] shell32/autocomplete: Reset the enumerator when the text is empty even when auto-suggest is disabled
by Gabriel Ivăncescu
This is needed for auto-append only AutoComplete controls.
Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)gmail.com>
---
dlls/shell32/autocomplete.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/dlls/shell32/autocomplete.c b/dlls/shell32/autocomplete.c
index 0770549..ab95a70 100644
--- a/dlls/shell32/autocomplete.c
+++ b/dlls/shell32/autocomplete.c
@@ -455,7 +455,8 @@ static void autocomplete_text(IAutoCompleteImpl *ac, HWND hwnd, enum autoappend_
if (flag != autoappend_flag_displayempty && len == 0)
{
if (ac->options & ACO_AUTOSUGGEST)
- hide_listbox(ac, ac->hwndListBox, TRUE);
+ hide_listbox(ac, ac->hwndListBox, FALSE);
+ free_enum_strs(ac);
return;
}
--
1.9.1
Nov. 1, 2018
[PATCH v5 2/4] shell32/autocomplete: Reset the enumerator when losing focus if the edit control is not visible anymore
by Gabriel Ivăncescu
Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)gmail.com>
---
dlls/shell32/autocomplete.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/dlls/shell32/autocomplete.c b/dlls/shell32/autocomplete.c
index d557a4a..0770549 100644
--- a/dlls/shell32/autocomplete.c
+++ b/dlls/shell32/autocomplete.c
@@ -602,10 +602,14 @@ static LRESULT APIENTRY ACEditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam,
hide_listbox(This, This->hwndListBox, TRUE);
return 0;
case WM_KILLFOCUS:
- if ((This->options & ACO_AUTOSUGGEST) && ((HWND)wParam != This->hwndListBox))
+ if (This->options & ACO_AUTOSUGGEST)
{
+ if ((HWND)wParam == This->hwndListBox) break;
hide_listbox(This, This->hwndListBox, FALSE);
}
+
+ /* Reset the enumerator if it's not visible anymore */
+ if (!IsWindowVisible(hwnd)) free_enum_strs(This);
break;
case WM_KEYDOWN:
return ACEditSubclassProc_KeyDown(This, hwnd, uMsg, wParam, lParam);
--
1.9.1
Nov. 1, 2018
[PATCH v5 1/4] shell32/autocomplete: Implement a cache and sort the enumerated strings for proper behavior
by Gabriel Ivăncescu
Windows doesn't reset and re-enumerate it everytime autocompletion happens,
and it also sorts the strings. This matches it more closely and makes it
more useable on large lists as well.
Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)gmail.com>
---
dlls/shell32/autocomplete.c | 209 +++++++++++++++++++++++++++++++-------------
1 file changed, 148 insertions(+), 61 deletions(-)
diff --git a/dlls/shell32/autocomplete.c b/dlls/shell32/autocomplete.c
index b3f86f3..d557a4a 100644
--- a/dlls/shell32/autocomplete.c
+++ b/dlls/shell32/autocomplete.c
@@ -25,7 +25,6 @@
- implement ACO_FILTERPREFIXES style
- implement ACO_RTLREADING style
- implement ResetEnumerator
- - string compares should be case-insensitive, the content of the list should be sorted
*/
#include "config.h"
@@ -62,6 +61,8 @@ typedef struct
LONG ref;
BOOL initialized;
BOOL enabled;
+ UINT enum_strs_num;
+ WCHAR **enum_strs;
HWND hwndEdit;
HWND hwndListBox;
WNDPROC wpOrigEditProc;
@@ -103,10 +104,94 @@ static void set_text_and_selection(IAutoCompleteImpl *ac, HWND hwnd, WCHAR *text
CallWindowProcW(proc, hwnd, EM_SETSEL, start, end);
}
-static void hide_listbox(IAutoCompleteImpl *ac, HWND hwnd)
+static int enumerate_strings_cmpfn(const void *a, const void *b)
+{
+ return strcmpiW(*(WCHAR* const*)a, *(WCHAR* const*)b);
+}
+
+/*
+ Enumerate all of the strings and sort them in the internal list.
+
+ We don't free the enumerated strings (except on error) to avoid needless
+ copies, until the next reset (or the object itself is destroyed)
+*/
+static void enumerate_strings(IAutoCompleteImpl *ac)
+{
+ UINT cur = 0, array_size = 1024;
+ LPOLESTR *strs = NULL, *tmp;
+ ULONG read;
+
+ do
+ {
+ if ((tmp = heap_realloc(strs, array_size * sizeof(*strs))) == NULL)
+ goto fail;
+ strs = tmp;
+
+ do
+ {
+ if (FAILED(IEnumString_Next(ac->enumstr, array_size - cur, &strs[cur], &read)))
+ read = 0;
+ } while (read != 0 && (cur += read) < array_size);
+
+ array_size *= 2;
+ } while (read != 0);
+
+ /* Allocate even if there were zero strings enumerated, to mark it non-NULL */
+ if ((tmp = heap_realloc(strs, cur * sizeof(*strs))))
+ {
+ strs = tmp;
+ if (cur > 0)
+ qsort(strs, cur, sizeof(*strs), enumerate_strings_cmpfn);
+
+ ac->enum_strs = strs;
+ ac->enum_strs_num = cur;
+ return;
+ }
+
+fail:
+ while (cur--)
+ CoTaskMemFree(strs[cur]);
+ heap_free(strs);
+}
+
+static UINT find_matching_enum_str(IAutoCompleteImpl *ac, UINT start, WCHAR *text,
+ UINT len, int direction)
+{
+ WCHAR **strs = ac->enum_strs;
+ UINT index = ~0, a = start, b = ac->enum_strs_num;
+ while (a < b)
+ {
+ UINT i = (a + b - 1) / 2;
+ int cmp = strncmpiW(text, strs[i], len);
+ if (cmp == 0)
+ {
+ index = i;
+ cmp = direction;
+ }
+ if (cmp <= 0) b = i;
+ else a = i + 1;
+ }
+ return index;
+}
+
+static void free_enum_strs(IAutoCompleteImpl *ac)
+{
+ WCHAR **strs = ac->enum_strs;
+ if (strs)
+ {
+ UINT i = ac->enum_strs_num;
+ ac->enum_strs = NULL;
+ while (i--)
+ CoTaskMemFree(strs[i]);
+ heap_free(strs);
+ }
+}
+
+static void hide_listbox(IAutoCompleteImpl *ac, HWND hwnd, BOOL reset)
{
ShowWindow(hwnd, SW_HIDE);
SendMessageW(hwnd, LB_RESETCONTENT, 0, 0);
+ if (reset) free_enum_strs(ac);
}
static void show_listbox(IAutoCompleteImpl *ac, UINT cnt)
@@ -167,14 +252,14 @@ static BOOL select_item_with_return_key(IAutoCompleteImpl *ac, HWND hwnd)
{
len = SendMessageW(hwndListBox, LB_GETTEXT, sel, (LPARAM)text);
set_text_and_selection(ac, hwnd, text, 0, len);
- hide_listbox(ac, hwndListBox);
+ hide_listbox(ac, hwndListBox, TRUE);
ac->no_fwd_char = '\r'; /* RETURN char */
heap_free(text);
return TRUE;
}
}
}
- hide_listbox(ac, hwndListBox);
+ hide_listbox(ac, hwndListBox, TRUE);
return FALSE;
}
@@ -240,7 +325,11 @@ static LRESULT change_selection(IAutoCompleteImpl *ac, HWND hwnd, UINT key)
static BOOL do_aclist_expand(IAutoCompleteImpl *ac, WCHAR *txt, WCHAR *last_delim)
{
- WCHAR c = last_delim[1];
+ WCHAR c;
+ free_enum_strs(ac);
+ IEnumString_Reset(ac->enumstr); /* call before expand */
+
+ c = last_delim[1];
last_delim[1] = '\0';
IACList_Expand(ac->aclist, txt);
last_delim[1] = c;
@@ -276,6 +365,9 @@ static BOOL aclist_expand(IAutoCompleteImpl *ac, WCHAR *txt)
while (i--)
if (strchrW(delims, txt[i]))
return do_aclist_expand(ac, txt, &txt[i]);
+
+ /* Windows doesn't expand without a delim, but it does reset */
+ free_enum_strs(ac);
}
return FALSE;
@@ -312,66 +404,58 @@ static BOOL display_matching_strs(IAutoCompleteImpl *ac, WCHAR *text, UINT len,
HWND hwnd, enum autoappend_flag flag)
{
/* Return FALSE if we need to hide the listbox */
- UINT cpt;
+ WCHAR **str = ac->enum_strs;
+ UINT cnt, i, k;
+ if (!str) return (ac->options & ACO_AUTOSUGGEST) ? FALSE : TRUE;
- if (ac->options & ACO_AUTOSUGGEST)
+ if (len)
{
- SendMessageW(ac->hwndListBox, WM_SETREDRAW, FALSE, 0);
- SendMessageW(ac->hwndListBox, LB_RESETCONTENT, 0, 0);
+ i = find_matching_enum_str(ac, 0, text, len, -1);
+ if (i == ~0)
+ return (ac->options & ACO_AUTOSUGGEST) ? FALSE : TRUE;
+
+ if (flag == autoappend_flag_yes)
+ autoappend_str(ac, text, len, str[i], hwnd);
+ if (!(ac->options & ACO_AUTOSUGGEST))
+ return TRUE;
+
+ /* Find the index beyond the last string that matches */
+ k = find_matching_enum_str(ac, i + 1, text, len, 1);
+ k = (k == ~0 ? i : k) + 1;
}
- for (cpt = 0;;)
- {
- HRESULT hr;
- LPOLESTR strs = NULL;
- ULONG fetched;
-
- hr = IEnumString_Next(ac->enumstr, 1, &strs, &fetched);
- if (hr != S_OK)
- break;
-
- if (!strncmpiW(text, strs, len))
- {
- if (cpt == 0 && flag == autoappend_flag_yes)
- {
- autoappend_str(ac, text, len, strs, hwnd);
- if (!(ac->options & ACO_AUTOSUGGEST))
- {
- CoTaskMemFree(strs);
- break;
- }
- }
-
- if (ac->options & ACO_AUTOSUGGEST)
- SendMessageW(ac->hwndListBox, LB_ADDSTRING, 0, (LPARAM)strs);
-
- cpt++;
- }
-
- CoTaskMemFree(strs);
- }
-
- if (ac->options & ACO_AUTOSUGGEST)
+ else
{
- if (cpt)
- {
- show_listbox(ac, cpt);
- SendMessageW(ac->hwndListBox, WM_SETREDRAW, TRUE, 0);
- }
- else
+ if (!(ac->options & ACO_AUTOSUGGEST))
+ return TRUE;
+ i = 0;
+ k = ac->enum_strs_num;
+ if (k == 0)
return FALSE;
}
+ cnt = k - i;
+
+ SendMessageW(ac->hwndListBox, WM_SETREDRAW, FALSE, 0);
+ SendMessageW(ac->hwndListBox, LB_RESETCONTENT, 0, 0);
+ SendMessageW(ac->hwndListBox, LB_INITSTORAGE, cnt, 0);
+ do
+ SendMessageW(ac->hwndListBox, LB_INSERTSTRING, -1, (LPARAM)str[i]);
+ while (++i < k);
+
+ show_listbox(ac, cnt);
+ SendMessageW(ac->hwndListBox, WM_SETREDRAW, TRUE, 0);
return TRUE;
}
static void autocomplete_text(IAutoCompleteImpl *ac, HWND hwnd, enum autoappend_flag flag)
{
WCHAR *text;
+ BOOL expanded = FALSE;
UINT size, len = SendMessageW(hwnd, WM_GETTEXTLENGTH, 0, 0);
if (flag != autoappend_flag_displayempty && len == 0)
{
if (ac->options & ACO_AUTOSUGGEST)
- hide_listbox(ac, ac->hwndListBox);
+ hide_listbox(ac, ac->hwndListBox, TRUE);
return;
}
@@ -382,28 +466,31 @@ static void autocomplete_text(IAutoCompleteImpl *ac, HWND hwnd, enum autoappend_
if (len + 1 != size)
text = heap_realloc(text, (len + 1) * sizeof(WCHAR));
- /* Reset it here to simplify the logic in aclist_expand for
- empty strings, since it tracks changes using txtbackup,
- and Reset needs to be called before IACList::Expand */
- IEnumString_Reset(ac->enumstr);
if (ac->aclist)
{
- aclist_expand(ac, text);
if (text[len - 1] == '\\' || text[len - 1] == '/')
flag = autoappend_flag_no;
+ expanded = aclist_expand(ac, text);
+ }
+ if (expanded || !ac->enum_strs)
+ {
+ if (!expanded) IEnumString_Reset(ac->enumstr);
+ enumerate_strings(ac);
}
- /* Set txtbackup to point to text itself (which must not be released) */
+ /* Set txtbackup to point to text itself (which must not be released),
+ and it must be done here since aclist_expand uses it to track changes */
heap_free(ac->txtbackup);
ac->txtbackup = text;
if (!display_matching_strs(ac, text, len, hwnd, flag))
- hide_listbox(ac, ac->hwndListBox);
+ hide_listbox(ac, ac->hwndListBox, FALSE);
}
static void destroy_autocomplete_object(IAutoCompleteImpl *ac)
{
ac->hwndEdit = NULL;
+ free_enum_strs(ac);
if (ac->hwndListBox)
DestroyWindow(ac->hwndListBox);
IAutoComplete2_Release(&ac->IAutoComplete2_iface);
@@ -421,7 +508,7 @@ static LRESULT ACEditSubclassProc_KeyDown(IAutoCompleteImpl *ac, HWND hwnd, UINT
/* When pressing ESC, Windows hides the auto-suggest listbox, if visible */
if ((ac->options & ACO_AUTOSUGGEST) && IsWindowVisible(ac->hwndListBox))
{
- hide_listbox(ac, ac->hwndListBox);
+ hide_listbox(ac, ac->hwndListBox, FALSE);
ac->no_fwd_char = 0x1B; /* ESC char */
return 0;
}
@@ -448,7 +535,7 @@ static LRESULT ACEditSubclassProc_KeyDown(IAutoCompleteImpl *ac, HWND hwnd, UINT
}
if (ac->options & ACO_AUTOSUGGEST)
- hide_listbox(ac, ac->hwndListBox);
+ hide_listbox(ac, ac->hwndListBox, TRUE);
heap_free(text);
return 0;
}
@@ -512,12 +599,12 @@ static LRESULT APIENTRY ACEditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam,
{
case CB_SHOWDROPDOWN:
if (This->options & ACO_AUTOSUGGEST)
- hide_listbox(This, This->hwndListBox);
+ hide_listbox(This, This->hwndListBox, TRUE);
return 0;
case WM_KILLFOCUS:
if ((This->options & ACO_AUTOSUGGEST) && ((HWND)wParam != This->hwndListBox))
{
- hide_listbox(This, This->hwndListBox);
+ hide_listbox(This, This->hwndListBox, FALSE);
}
break;
case WM_KEYDOWN:
@@ -583,7 +670,7 @@ static LRESULT APIENTRY ACLBoxSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam,
break;
len = SendMessageW(hwnd, LB_GETTEXT, sel, (LPARAM)msg);
set_text_and_selection(This, This->hwndEdit, msg, 0, len);
- hide_listbox(This, hwnd);
+ hide_listbox(This, hwnd, TRUE);
heap_free(msg);
break;
default:
@@ -861,7 +948,7 @@ static HRESULT WINAPI IAutoComplete2_fnSetOptions(
if ((This->options & ACO_AUTOSUGGEST) && This->hwndEdit && !This->hwndListBox)
create_listbox(This);
else if (!(This->options & ACO_AUTOSUGGEST) && This->hwndListBox)
- hide_listbox(This, This->hwndListBox);
+ hide_listbox(This, This->hwndListBox, TRUE);
return hr;
}
--
1.9.1
Nov. 1, 2018
Re: [PATCH v2 5/5] oleaut32/tests: Add a test for marshalling of floats on x86-64.
by Marvin
Hi,
While running your changed tests on Windows, I think I found new failures.
Being a bot and all I'm not very good at pattern recognition, so I might be
wrong, but could you please double-check?
Full results can be found at:
https://testbot.winehq.org/JobDetails.pl?Key=43779
Your paranoid android.
=== debian9 (32 bit Wine report) ===
oleaut32:
Unhandled exception: page fault on write access to 0x00000004 in 32-bit code (0x7bc4d8ee).
typelib.c:5688: Test failed: got 0x00000000
Report errors:
oleaut32:tmarshal crashed (c0000005)
=== debian9 (build log) ===
=== debian9 (32 bit WoW Wine report) ===
oleaut32:
Unhandled exception: page fault on write access to 0x00000004 in 32-bit code (0x7bc4d8ee).
typelib.c:5688: Test failed: got 0x00000000
Report errors:
oleaut32:tmarshal crashed (c0000005)
=== debian9 (build log) ===
Nov. 1, 2018