mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-01-28 13:05:02 -08:00
tests: Add test for atomic instructions.
This commit is contained in:
parent
b5c89fa89f
commit
dc51597db8
319
tests/d3d12.c
319
tests/d3d12.c
@ -10305,6 +10305,324 @@ static void test_cs_uav_store(void)
|
||||
destroy_test_context(&context);
|
||||
}
|
||||
|
||||
static void test_atomic_instructions(void)
|
||||
{
|
||||
ID3D12Resource *ps_buffer, *cs_buffer, *cs_buffer2;
|
||||
D3D12_ROOT_SIGNATURE_DESC root_signature_desc;
|
||||
D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
|
||||
ID3D12GraphicsCommandList *command_list;
|
||||
D3D12_ROOT_PARAMETER root_parameters[3];
|
||||
D3D12_HEAP_PROPERTIES heap_properties;
|
||||
ID3D12PipelineState *pipeline_state;
|
||||
D3D12_RESOURCE_DESC resource_desc;
|
||||
struct test_context_desc desc;
|
||||
struct resource_readback rb;
|
||||
struct test_context context;
|
||||
ID3D12CommandQueue *queue;
|
||||
ID3D12Device *device;
|
||||
unsigned int i, j;
|
||||
HRESULT hr;
|
||||
|
||||
static const DWORD ps_atomics_code[] =
|
||||
{
|
||||
#if 0
|
||||
RWByteAddressBuffer u;
|
||||
|
||||
uint4 v;
|
||||
int4 i;
|
||||
|
||||
void main()
|
||||
{
|
||||
u.InterlockedAnd(0 * 4, v.x);
|
||||
u.InterlockedCompareStore(1 * 4, v.y, v.x);
|
||||
u.InterlockedAdd(2 * 4, v.x);
|
||||
u.InterlockedOr(3 * 4, v.x);
|
||||
u.InterlockedMax(4 * 4, i.x);
|
||||
u.InterlockedMin(5 * 4, i.x);
|
||||
u.InterlockedMax(6 * 4, v.x);
|
||||
u.InterlockedMin(7 * 4, v.x);
|
||||
u.InterlockedXor(8 * 4, v.x);
|
||||
}
|
||||
#endif
|
||||
0x43425844, 0x24c6a30c, 0x2ce4437d, 0xdee8a0df, 0xd18cb4bc, 0x00000001, 0x000001ac, 0x00000003,
|
||||
0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
|
||||
0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x00000158, 0x00000050, 0x00000056, 0x0100086a,
|
||||
0x04000059, 0x00208e46, 0x00000000, 0x00000002, 0x0300009d, 0x0011e000, 0x00000000, 0x080000a9,
|
||||
0x0011e000, 0x00000000, 0x00004001, 0x00000000, 0x0020800a, 0x00000000, 0x00000000, 0x0b0000ac,
|
||||
0x0011e000, 0x00000000, 0x00004001, 0x00000004, 0x0020801a, 0x00000000, 0x00000000, 0x0020800a,
|
||||
0x00000000, 0x00000000, 0x080000ad, 0x0011e000, 0x00000000, 0x00004001, 0x00000008, 0x0020800a,
|
||||
0x00000000, 0x00000000, 0x080000aa, 0x0011e000, 0x00000000, 0x00004001, 0x0000000c, 0x0020800a,
|
||||
0x00000000, 0x00000000, 0x080000ae, 0x0011e000, 0x00000000, 0x00004001, 0x00000010, 0x0020800a,
|
||||
0x00000000, 0x00000001, 0x080000af, 0x0011e000, 0x00000000, 0x00004001, 0x00000014, 0x0020800a,
|
||||
0x00000000, 0x00000001, 0x080000b0, 0x0011e000, 0x00000000, 0x00004001, 0x00000018, 0x0020800a,
|
||||
0x00000000, 0x00000000, 0x080000b1, 0x0011e000, 0x00000000, 0x00004001, 0x0000001c, 0x0020800a,
|
||||
0x00000000, 0x00000000, 0x080000ab, 0x0011e000, 0x00000000, 0x00004001, 0x00000020, 0x0020800a,
|
||||
0x00000000, 0x00000000, 0x0100003e,
|
||||
};
|
||||
static const D3D12_SHADER_BYTECODE ps_atomics = {ps_atomics_code, sizeof(ps_atomics_code)};
|
||||
static const DWORD cs_atomics_code[] =
|
||||
{
|
||||
#if 0
|
||||
RWByteAddressBuffer u;
|
||||
RWByteAddressBuffer u2;
|
||||
|
||||
uint4 v;
|
||||
int4 i;
|
||||
|
||||
[numthreads(1, 1, 1)]
|
||||
void main()
|
||||
{
|
||||
uint r;
|
||||
u.InterlockedAnd(0 * 4, v.x, r);
|
||||
u2.Store(0 * 4, r);
|
||||
u.InterlockedCompareExchange(1 * 4, v.y, v.x, r);
|
||||
u2.Store(1 * 4, r);
|
||||
u.InterlockedAdd(2 * 4, v.x, r);
|
||||
u2.Store(2 * 4, r);
|
||||
u.InterlockedOr(3 * 4, v.x, r);
|
||||
u2.Store(3 * 4, r);
|
||||
u.InterlockedMax(4 * 4, i.x, r);
|
||||
u2.Store(4 * 4, r);
|
||||
u.InterlockedMin(5 * 4, i.x, r);
|
||||
u2.Store(5 * 4, r);
|
||||
u.InterlockedMax(6 * 4, v.x, r);
|
||||
u2.Store(6 * 4, r);
|
||||
u.InterlockedMin(7 * 4, v.x, r);
|
||||
u2.Store(7 * 4, r);
|
||||
u.InterlockedXor(8 * 4, v.x, r);
|
||||
u2.Store(8 * 4, r);
|
||||
}
|
||||
#endif
|
||||
0x43425844, 0x859a96e3, 0x1a35e463, 0x1e89ce58, 0x5cfe430a, 0x00000001, 0x0000026c, 0x00000003,
|
||||
0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
|
||||
0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x00000218, 0x00050050, 0x00000086, 0x0100086a,
|
||||
0x04000059, 0x00208e46, 0x00000000, 0x00000002, 0x0300009d, 0x0011e000, 0x00000000, 0x0300009d,
|
||||
0x0011e000, 0x00000001, 0x02000068, 0x00000001, 0x0400009b, 0x00000001, 0x00000001, 0x00000001,
|
||||
0x0a0000b5, 0x00100012, 0x00000000, 0x0011e000, 0x00000000, 0x00004001, 0x00000000, 0x0020800a,
|
||||
0x00000000, 0x00000000, 0x0d0000b9, 0x00100022, 0x00000000, 0x0011e000, 0x00000000, 0x00004001,
|
||||
0x00000004, 0x0020801a, 0x00000000, 0x00000000, 0x0020800a, 0x00000000, 0x00000000, 0x0a0000b4,
|
||||
0x00100042, 0x00000000, 0x0011e000, 0x00000000, 0x00004001, 0x00000008, 0x0020800a, 0x00000000,
|
||||
0x00000000, 0x0a0000b6, 0x00100082, 0x00000000, 0x0011e000, 0x00000000, 0x00004001, 0x0000000c,
|
||||
0x0020800a, 0x00000000, 0x00000000, 0x070000a6, 0x0011e0f2, 0x00000001, 0x00004001, 0x00000000,
|
||||
0x00100e46, 0x00000000, 0x0a0000ba, 0x00100012, 0x00000000, 0x0011e000, 0x00000000, 0x00004001,
|
||||
0x00000010, 0x0020800a, 0x00000000, 0x00000001, 0x0a0000bb, 0x00100022, 0x00000000, 0x0011e000,
|
||||
0x00000000, 0x00004001, 0x00000014, 0x0020800a, 0x00000000, 0x00000001, 0x0a0000bc, 0x00100042,
|
||||
0x00000000, 0x0011e000, 0x00000000, 0x00004001, 0x00000018, 0x0020800a, 0x00000000, 0x00000000,
|
||||
0x0a0000bd, 0x00100082, 0x00000000, 0x0011e000, 0x00000000, 0x00004001, 0x0000001c, 0x0020800a,
|
||||
0x00000000, 0x00000000, 0x070000a6, 0x0011e0f2, 0x00000001, 0x00004001, 0x00000010, 0x00100e46,
|
||||
0x00000000, 0x0a0000b7, 0x00100012, 0x00000000, 0x0011e000, 0x00000000, 0x00004001, 0x00000020,
|
||||
0x0020800a, 0x00000000, 0x00000000, 0x070000a6, 0x0011e012, 0x00000001, 0x00004001, 0x00000020,
|
||||
0x0010000a, 0x00000000, 0x0100003e,
|
||||
};
|
||||
static D3D12_SHADER_BYTECODE cs_atomics = {cs_atomics_code, sizeof(cs_atomics_code)};
|
||||
static const char * const instructions[] =
|
||||
{
|
||||
"atomic_and", "atomic_cmp_store", "atomic_iadd", "atomic_or",
|
||||
"atomic_imax", "atomic_imin", "atomic_umax", "atomic_umin", "atomic_xor",
|
||||
};
|
||||
static const char * const imm_instructions[] =
|
||||
{
|
||||
"imm_atomic_and", "imm_atomic_cmp_exch", "imm_atomic_iadd", "imm_atomic_or",
|
||||
"imm_atomic_imax", "imm_atomic_imin", "imm_atomic_umax", "imm_atomic_umin", "imm_atomic_xor",
|
||||
};
|
||||
static const struct test
|
||||
{
|
||||
struct uvec4 v;
|
||||
struct ivec4 i;
|
||||
unsigned int input[ARRAY_SIZE(instructions)];
|
||||
unsigned int expected_result[ARRAY_SIZE(instructions)];
|
||||
}
|
||||
tests[] =
|
||||
{
|
||||
{{ 1, 0 }, {-1}, {0xffff, 0, 1, 0, 0, 0, 0, 0, 0xff }, { 1, 1, 2, 1, 0, ~0u, 1, 0, 0xfe}},
|
||||
{{~0u, ~0u}, { 0}, {0xffff, 0xf, 1, 0, 0, 0, 0, 9, ~0u}, {0xffff, 0xf, 0, ~0u, 0, 0, ~0u, 9, 0}},
|
||||
};
|
||||
|
||||
memset(&desc, 0, sizeof(desc));
|
||||
desc.rt_width = 1;
|
||||
desc.rt_height = 1;
|
||||
desc.rt_format = DXGI_FORMAT_R32_FLOAT;
|
||||
desc.no_root_signature = true;
|
||||
if (!init_test_context(&context, &desc))
|
||||
return;
|
||||
device = context.device;
|
||||
command_list = context.list;
|
||||
queue = context.queue;
|
||||
|
||||
root_parameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV;
|
||||
root_parameters[0].Descriptor.ShaderRegister = 0;
|
||||
root_parameters[0].Descriptor.RegisterSpace = 0;
|
||||
root_parameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
|
||||
root_parameters[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV;
|
||||
root_parameters[1].Descriptor.ShaderRegister = 1;
|
||||
root_parameters[1].Descriptor.RegisterSpace = 0;
|
||||
root_parameters[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
|
||||
root_parameters[2].ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
|
||||
root_parameters[2].Constants.ShaderRegister = 0;
|
||||
root_parameters[2].Constants.RegisterSpace = 0;
|
||||
root_parameters[2].Constants.Num32BitValues = 8;
|
||||
root_parameters[2].ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
|
||||
root_signature_desc.NumParameters = 3;
|
||||
root_signature_desc.pParameters = root_parameters;
|
||||
root_signature_desc.NumStaticSamplers = 0;
|
||||
root_signature_desc.pStaticSamplers = NULL;
|
||||
root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_NONE;
|
||||
hr = create_root_signature(device, &root_signature_desc, &context.root_signature);
|
||||
ok(SUCCEEDED(hr), "Failed to create root signature, hr %#x.\n", hr);
|
||||
|
||||
memset(&heap_properties, 0, sizeof(heap_properties));
|
||||
heap_properties.Type = D3D12_HEAP_TYPE_DEFAULT;
|
||||
resource_desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
|
||||
resource_desc.Alignment = 0;
|
||||
resource_desc.Width = sizeof(tests->input);
|
||||
resource_desc.Height = 1;
|
||||
resource_desc.DepthOrArraySize = 1;
|
||||
resource_desc.MipLevels = 1;
|
||||
resource_desc.Format = DXGI_FORMAT_UNKNOWN;
|
||||
resource_desc.SampleDesc.Count = 1;
|
||||
resource_desc.SampleDesc.Quality = 0;
|
||||
resource_desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
|
||||
resource_desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
|
||||
hr = ID3D12Device_CreateCommittedResource(device,
|
||||
&heap_properties, D3D12_HEAP_FLAG_NONE, &resource_desc,
|
||||
D3D12_RESOURCE_STATE_COPY_DEST, NULL,
|
||||
&IID_ID3D12Resource, (void **)&ps_buffer);
|
||||
ok(SUCCEEDED(hr), "Failed to create buffer, hr %#x.\n", hr);
|
||||
hr = ID3D12Device_CreateCommittedResource(device,
|
||||
&heap_properties, D3D12_HEAP_FLAG_NONE, &resource_desc,
|
||||
D3D12_RESOURCE_STATE_COPY_DEST, NULL,
|
||||
&IID_ID3D12Resource, (void **)&cs_buffer);
|
||||
ok(SUCCEEDED(hr), "Failed to create buffer, hr %#x.\n", hr);
|
||||
hr = ID3D12Device_CreateCommittedResource(device,
|
||||
&heap_properties, D3D12_HEAP_FLAG_NONE, &resource_desc,
|
||||
D3D12_RESOURCE_STATE_COPY_DEST, NULL,
|
||||
&IID_ID3D12Resource, (void **)&cs_buffer2);
|
||||
ok(SUCCEEDED(hr), "Failed to create buffer, hr %#x.\n", hr);
|
||||
|
||||
init_pipeline_state_desc(&pso_desc, context.root_signature, 0, NULL, &ps_atomics, NULL);
|
||||
pso_desc.NumRenderTargets = 0;
|
||||
hr = ID3D12Device_CreateGraphicsPipelineState(context.device, &pso_desc,
|
||||
&IID_ID3D12PipelineState, (void **)&context.pipeline_state);
|
||||
ok(SUCCEEDED(hr), "Failed to create graphics pipeline state, hr %#x.\n", hr);
|
||||
|
||||
pipeline_state = create_compute_pipeline_state(device, context.root_signature, cs_atomics);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(tests); ++i)
|
||||
{
|
||||
const struct test *test = &tests[i];
|
||||
|
||||
upload_buffer_data(ps_buffer, 0, sizeof(test->input), test->input, queue, command_list);
|
||||
reset_command_list(command_list, context.allocator);
|
||||
|
||||
upload_buffer_data(cs_buffer, 0, sizeof(test->input), test->input, queue, command_list);
|
||||
reset_command_list(command_list, context.allocator);
|
||||
|
||||
transition_sub_resource_state(command_list, ps_buffer, 0,
|
||||
D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
|
||||
transition_sub_resource_state(command_list, cs_buffer, 0,
|
||||
D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
|
||||
transition_sub_resource_state(command_list, cs_buffer2, 0,
|
||||
D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
|
||||
|
||||
ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
|
||||
ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
|
||||
ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
|
||||
ID3D12GraphicsCommandList_SetGraphicsRootUnorderedAccessView(command_list,
|
||||
0, ID3D12Resource_GetGPUVirtualAddress(ps_buffer));
|
||||
ID3D12GraphicsCommandList_SetGraphicsRootUnorderedAccessView(command_list,
|
||||
1, ID3D12Resource_GetGPUVirtualAddress(cs_buffer));
|
||||
ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 2, 4, &test->v, 0);
|
||||
ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 2, 4, &test->i, 4);
|
||||
|
||||
ID3D12GraphicsCommandList_SetPipelineState(command_list, context.pipeline_state);
|
||||
ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
|
||||
|
||||
ID3D12GraphicsCommandList_SetComputeRootSignature(command_list, context.root_signature);
|
||||
ID3D12GraphicsCommandList_SetComputeRootUnorderedAccessView(command_list,
|
||||
0, ID3D12Resource_GetGPUVirtualAddress(cs_buffer));
|
||||
ID3D12GraphicsCommandList_SetComputeRootUnorderedAccessView(command_list,
|
||||
1, ID3D12Resource_GetGPUVirtualAddress(cs_buffer2));
|
||||
ID3D12GraphicsCommandList_SetComputeRoot32BitConstants(command_list, 2, 4, &test->v, 0);
|
||||
ID3D12GraphicsCommandList_SetComputeRoot32BitConstants(command_list, 2, 4, &test->i, 4);
|
||||
|
||||
ID3D12GraphicsCommandList_SetPipelineState(command_list, pipeline_state);
|
||||
ID3D12GraphicsCommandList_Dispatch(command_list, 1, 1, 1);
|
||||
|
||||
transition_sub_resource_state(command_list, ps_buffer, 0,
|
||||
D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
|
||||
get_buffer_readback_with_command_list(ps_buffer, DXGI_FORMAT_R32_UINT, &rb, queue, command_list);
|
||||
for (j = 0; j < ARRAY_SIZE(instructions); ++j)
|
||||
{
|
||||
unsigned int value = get_readback_uint(&rb, j, 0);
|
||||
unsigned int expected = test->expected_result[j];
|
||||
|
||||
if (test->i.x < 0
|
||||
&& (!strcmp(instructions[j], "atomic_imax") || !strcmp(instructions[j], "atomic_imin")))
|
||||
todo(value == expected, "Test %u: Got %#x (%d), expected %#x (%d) for '%s' "
|
||||
"with inputs (%u, %u), (%d), %#x (%d).\n",
|
||||
i, value, value, expected, expected, instructions[j],
|
||||
test->v.x, test->v.y, test->i.x, test->input[j], test->input[j]);
|
||||
else
|
||||
ok(value == expected, "Test %u: Got %#x (%d), expected %#x (%d) for '%s' "
|
||||
"with inputs (%u, %u), (%d), %#x (%d).\n",
|
||||
i, value, value, expected, expected, instructions[j],
|
||||
test->v.x, test->v.y, test->i.x, test->input[j], test->input[j]);
|
||||
}
|
||||
release_resource_readback(&rb);
|
||||
reset_command_list(command_list, context.allocator);
|
||||
|
||||
transition_sub_resource_state(command_list, cs_buffer, 0,
|
||||
D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
|
||||
get_buffer_readback_with_command_list(cs_buffer, DXGI_FORMAT_R32_UINT, &rb, queue, command_list);
|
||||
for (j = 0; j < ARRAY_SIZE(instructions); ++j)
|
||||
{
|
||||
BOOL todo_instruction = !strcmp(imm_instructions[j], "imm_atomic_imax")
|
||||
|| !strcmp(imm_instructions[j], "imm_atomic_imin");
|
||||
unsigned int value = get_readback_uint(&rb, j, 0);
|
||||
unsigned int expected = test->expected_result[j];
|
||||
|
||||
if (test->i.x < 0 && todo_instruction)
|
||||
todo(value == expected, "Test %u: Got %#x (%d), expected %#x (%d) for '%s' "
|
||||
"with inputs (%u, %u), (%d), %#x (%d).\n",
|
||||
i, value, value, expected, expected, imm_instructions[j],
|
||||
test->v.x, test->v.y, test->i.x, test->input[j], test->input[j]);
|
||||
else
|
||||
ok(value == expected, "Test %u: Got %#x (%d), expected %#x (%d) for '%s' "
|
||||
"with inputs (%u, %u), (%d), %#x (%d).\n",
|
||||
i, value, value, expected, expected, imm_instructions[j],
|
||||
test->v.x, test->v.y, test->i.x, test->input[j], test->input[j]);
|
||||
}
|
||||
release_resource_readback(&rb);
|
||||
reset_command_list(command_list, context.allocator);
|
||||
|
||||
transition_sub_resource_state(command_list, cs_buffer2, 0,
|
||||
D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
|
||||
get_buffer_readback_with_command_list(cs_buffer2, DXGI_FORMAT_R32_UINT, &rb, queue, command_list);
|
||||
for (j = 0; j < ARRAY_SIZE(instructions); ++j)
|
||||
{
|
||||
unsigned int out_value = get_readback_uint(&rb, j, 0);
|
||||
ok(out_value == test->input[j], "Got original value %u, expected %u for '%s'.\n",
|
||||
out_value, test->input[j], imm_instructions[j]);
|
||||
}
|
||||
release_resource_readback(&rb);
|
||||
reset_command_list(command_list, context.allocator);
|
||||
|
||||
transition_sub_resource_state(command_list, ps_buffer, 0,
|
||||
D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_COPY_DEST);
|
||||
transition_sub_resource_state(command_list, cs_buffer, 0,
|
||||
D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_COPY_DEST);
|
||||
transition_sub_resource_state(command_list, cs_buffer2, 0,
|
||||
D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_COPY_DEST);
|
||||
}
|
||||
|
||||
ID3D12Resource_Release(ps_buffer);
|
||||
ID3D12Resource_Release(cs_buffer);
|
||||
ID3D12Resource_Release(cs_buffer2);
|
||||
ID3D12PipelineState_Release(pipeline_state);
|
||||
destroy_test_context(&context);
|
||||
}
|
||||
|
||||
static void test_buffer_srv(void)
|
||||
{
|
||||
struct buffer
|
||||
@ -10847,6 +11165,7 @@ START_TEST(d3d12)
|
||||
run_test(test_compute_shader_registers);
|
||||
run_test(test_tgsm);
|
||||
run_test(test_cs_uav_store);
|
||||
run_test(test_atomic_instructions);
|
||||
run_test(test_buffer_srv);
|
||||
run_test(test_create_query_heap);
|
||||
run_test(test_query_timestamp);
|
||||
|
Loading…
x
Reference in New Issue
Block a user