d3d10core/tests: Add tests for GenerateMips().

Signed-off-by: Matteo Bruni <mbruni@codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Matteo Bruni 2018-02-06 19:36:13 +01:00 committed by Alexandre Julliard
parent f7b95a77c3
commit 02e162eeea
1 changed files with 463 additions and 0 deletions

View File

@ -14174,6 +14174,468 @@ static void test_combined_clip_and_cull_distances(void)
release_test_context(&test_context);
}
static void test_generate_mips(void)
{
static const DWORD ps_code[] =
{
#if 0
Texture2D t;
SamplerState s;
float4 main(float4 position : SV_POSITION) : SV_Target
{
float2 p;
p.x = position.x / 640.0f;
p.y = position.y / 480.0f;
return t.Sample(s, p);
}
#endif
0x43425844, 0x1ce9b612, 0xc8176faa, 0xd37844af, 0xdb515605, 0x00000001, 0x00000134, 0x00000003,
0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x5449534f, 0x004e4f49,
0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x00000098, 0x00000040,
0x00000026, 0x0300005a, 0x00106000, 0x00000000, 0x04001858, 0x00107000, 0x00000000, 0x00005555,
0x04002064, 0x00101032, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068,
0x00000001, 0x0a000038, 0x00100032, 0x00000000, 0x00101046, 0x00000000, 0x00004002, 0x3acccccd,
0x3b088889, 0x00000000, 0x00000000, 0x09000045, 0x001020f2, 0x00000000, 0x00100046, 0x00000000,
0x00107e46, 0x00000000, 0x00106000, 0x00000000, 0x0100003e,
};
static const DWORD ps_code_3d[] =
{
#if 0
Texture3D t;
SamplerState s;
float4 main(float4 position : SV_POSITION) : SV_Target
{
float3 p;
p.x = position.x / 640.0f;
p.y = position.y / 480.0f;
p.z = 0.5f;
return t.Sample(s, p);
}
#endif
0x43425844, 0xa1e26083, 0xeb45763e, 0x1e5a5089, 0xdfbbe0df, 0x00000001, 0x00000148, 0x00000003,
0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020,
0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x5449534f, 0x004e4f49,
0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003,
0x00000000, 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x000000ac, 0x00000040,
0x0000002b, 0x0300005a, 0x00106000, 0x00000000, 0x04002858, 0x00107000, 0x00000000, 0x00005555,
0x04002064, 0x00101032, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068,
0x00000001, 0x0a000038, 0x00100032, 0x00000000, 0x00101046, 0x00000000, 0x00004002, 0x3acccccd,
0x3b088889, 0x00000000, 0x00000000, 0x05000036, 0x00100042, 0x00000000, 0x00004001, 0x3f000000,
0x09000045, 0x001020f2, 0x00000000, 0x00100246, 0x00000000, 0x00107e46, 0x00000000, 0x00106000,
0x00000000, 0x0100003e,
};
static const struct
{
D3D10_RESOURCE_DIMENSION dim;
D3D10_SRV_DIMENSION srv_dim;
unsigned int array_size;
}
resource_types[] =
{
{D3D10_RESOURCE_DIMENSION_BUFFER, D3D10_SRV_DIMENSION_BUFFER, 1},
{D3D10_RESOURCE_DIMENSION_TEXTURE2D, D3D10_SRV_DIMENSION_TEXTURE2D, 1},
{D3D10_RESOURCE_DIMENSION_TEXTURE2D, D3D10_SRV_DIMENSION_TEXTURE2DARRAY, 4},
{D3D10_RESOURCE_DIMENSION_TEXTURE3D, D3D10_SRV_DIMENSION_TEXTURE3D, 1},
};
static const struct
{
DXGI_FORMAT texture_format;
UINT bind_flags;
UINT misc_flags;
BOOL null_srv;
UINT base_level;
BOOL expected_creation;
BOOL expected_mips;
}
tests[] =
{
{DXGI_FORMAT_R8G8B8A8_UNORM, D3D10_BIND_SHADER_RESOURCE, 0, TRUE,
0, TRUE, FALSE},
{DXGI_FORMAT_R8G8B8A8_UNORM, D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE, 0, TRUE,
0, TRUE, FALSE},
{DXGI_FORMAT_R8G8B8A8_UNORM, D3D10_BIND_SHADER_RESOURCE, 0, FALSE,
0, TRUE, FALSE},
{DXGI_FORMAT_R8G8B8A8_UNORM, D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE, 0, FALSE,
0, TRUE, FALSE},
{DXGI_FORMAT_R8G8B8A8_UNORM, D3D10_BIND_SHADER_RESOURCE, D3D10_RESOURCE_MISC_GENERATE_MIPS, FALSE,
0, FALSE, FALSE},
{DXGI_FORMAT_R8G8B8A8_UNORM, D3D10_BIND_RENDER_TARGET, D3D10_RESOURCE_MISC_GENERATE_MIPS, FALSE,
0, FALSE, FALSE},
{DXGI_FORMAT_R8G8B8A8_UNORM, D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE, D3D10_RESOURCE_MISC_GENERATE_MIPS, FALSE,
0, TRUE, TRUE},
{DXGI_FORMAT_R8G8B8A8_UNORM, D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE, D3D10_RESOURCE_MISC_GENERATE_MIPS, FALSE,
1, TRUE, TRUE},
{DXGI_FORMAT_R8G8B8A8_TYPELESS, D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE, D3D10_RESOURCE_MISC_GENERATE_MIPS, FALSE,
1, TRUE, TRUE},
{DXGI_FORMAT_R8G8B8A8_UINT, D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE, D3D10_RESOURCE_MISC_GENERATE_MIPS, TRUE,
1, TRUE, FALSE},
};
static const struct
{
POINT pos;
DWORD color;
}
expected[] =
{
{{200, 200}, 0xffff0000},
{{280, 200}, 0xffff0000},
{{360, 200}, 0xff00ff00},
{{440, 200}, 0xff00ff00},
{{200, 270}, 0xff0000ff},
{{280, 270}, 0xff0000ff},
{{360, 270}, 0xff000000},
{{440, 270}, 0xff000000},
};
static const struct vec4 white = {1.0f, 1.0f, 1.0f, 1.0f};
static const RECT r1 = {8, 8, 16, 16};
static const RECT r2 = {16, 8, 24, 16};
static const RECT r3 = {8, 16, 16, 24};
static const RECT r4 = {16, 16, 24, 24};
DWORD *data, *zero_data, color, expected_color;
ID3D10ShaderResourceView *srv, *srv_sampling;
struct d3d10core_test_context test_context;
D3D10_SHADER_RESOURCE_VIEW_DESC srv_desc;
D3D10_TEXTURE2D_DESC texture2d_desc;
D3D10_TEXTURE3D_DESC texture3d_desc;
ID3D10SamplerState *sampler_state;
D3D10_SAMPLER_DESC sampler_desc;
D3D10_BUFFER_DESC buffer_desc;
unsigned int i, j, k, x, y, z;
ID3D10PixelShader *ps, *ps_3d;
struct resource_readback rb;
ID3D10Resource *resource;
ID3D10Device *device;
HRESULT hr;
if (!init_test_context(&test_context))
return;
device = test_context.device;
hr = ID3D10Device_CreatePixelShader(device, ps_code, sizeof(ps_code), &ps);
ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
hr = ID3D10Device_CreatePixelShader(device, ps_code_3d, sizeof(ps_code_3d), &ps_3d);
ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
sampler_desc.Filter = D3D10_FILTER_MIN_MAG_MIP_POINT;
sampler_desc.AddressU = D3D10_TEXTURE_ADDRESS_CLAMP;
sampler_desc.AddressV = D3D10_TEXTURE_ADDRESS_CLAMP;
sampler_desc.AddressW = D3D10_TEXTURE_ADDRESS_CLAMP;
sampler_desc.MipLODBias = 0.0f;
sampler_desc.MaxAnisotropy = 0;
sampler_desc.ComparisonFunc = D3D10_COMPARISON_NEVER;
sampler_desc.BorderColor[0] = 0.0f;
sampler_desc.BorderColor[1] = 0.0f;
sampler_desc.BorderColor[2] = 0.0f;
sampler_desc.BorderColor[3] = 0.0f;
sampler_desc.MinLOD = 0.0f;
sampler_desc.MaxLOD = D3D10_FLOAT32_MAX;
hr = ID3D10Device_CreateSamplerState(device, &sampler_desc, &sampler_state);
ok(SUCCEEDED(hr), "Failed to create sampler state, hr %#x.\n", hr);
ID3D10Device_PSSetSamplers(device, 0, 1, &sampler_state);
data = HeapAlloc(GetProcessHeap(), 0, sizeof(*data) * 32 * 32 * 32);
for (z = 0; z < 32; ++z)
{
for (y = 0; y < 32; ++y)
{
for (x = 0; x < 32; ++x)
{
DWORD *dst = &data[z * 32 * 32 + y * 32 + x];
POINT pt;
pt.x = x;
pt.y = y;
if (PtInRect(&r1, pt))
*dst = 0xffff0000;
else if (PtInRect(&r2, pt))
*dst = 0xff00ff00;
else if (PtInRect(&r3, pt))
*dst = 0xff0000ff;
else if (PtInRect(&r4, pt))
*dst = 0xff000000;
else
*dst = 0xffffffff;
}
}
}
zero_data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*zero_data) * 16 * 16 * 16);
for (i = 0; i < ARRAY_SIZE(resource_types); ++i)
{
for (j = 0; j < ARRAY_SIZE(tests); ++j)
{
unsigned int base_multiplier = 1u << tests[j].base_level;
if (is_warp_device(device) && tests[j].texture_format == DXGI_FORMAT_R8G8B8A8_UINT)
{
/* Testing this format seems to break the WARP device. */
skip("Skipping test with DXGI_FORMAT_R8G8B8A8_UINT on WARP.\n");
continue;
}
switch (resource_types[i].dim)
{
case D3D10_RESOURCE_DIMENSION_BUFFER:
buffer_desc.ByteWidth = 32 * base_multiplier;
buffer_desc.Usage = D3D10_USAGE_DEFAULT;
buffer_desc.BindFlags = tests[j].bind_flags;
buffer_desc.CPUAccessFlags = 0;
buffer_desc.MiscFlags = tests[j].misc_flags;
hr = ID3D10Device_CreateBuffer(device, &buffer_desc, NULL,
(ID3D10Buffer **)&resource);
break;
case D3D10_RESOURCE_DIMENSION_TEXTURE2D:
texture2d_desc.Width = 32 * base_multiplier;
texture2d_desc.Height = 32 * base_multiplier;
texture2d_desc.MipLevels = 0;
texture2d_desc.ArraySize = resource_types[i].array_size;
texture2d_desc.Format = tests[j].texture_format;
texture2d_desc.SampleDesc.Count = 1;
texture2d_desc.SampleDesc.Quality = 0;
texture2d_desc.Usage = D3D10_USAGE_DEFAULT;
texture2d_desc.BindFlags = tests[j].bind_flags;
texture2d_desc.CPUAccessFlags = 0;
texture2d_desc.MiscFlags = tests[j].misc_flags;
hr = ID3D10Device_CreateTexture2D(device, &texture2d_desc, NULL,
(ID3D10Texture2D **)&resource);
break;
case D3D10_RESOURCE_DIMENSION_TEXTURE3D:
texture3d_desc.Width = 32 * base_multiplier;
texture3d_desc.Height = 32 * base_multiplier;
texture3d_desc.Depth = 32 * base_multiplier;
texture3d_desc.MipLevels = 0;
texture3d_desc.Format = tests[j].texture_format;
texture3d_desc.Usage = D3D10_USAGE_DEFAULT;
texture3d_desc.BindFlags = tests[j].bind_flags;
texture3d_desc.CPUAccessFlags = 0;
texture3d_desc.MiscFlags = tests[j].misc_flags;
hr = ID3D10Device_CreateTexture3D(device, &texture3d_desc, NULL,
(ID3D10Texture3D **)&resource);
break;
default:
break;
}
if (tests[j].expected_creation && (resource_types[i].dim != D3D10_RESOURCE_DIMENSION_BUFFER
|| !(tests[j].misc_flags & D3D10_RESOURCE_MISC_GENERATE_MIPS)))
{
ok(SUCCEEDED(hr), "Resource type %u, test %u: failed to create resource, hr %#x.\n", i, j, hr);
}
else
{
ok(hr == E_INVALIDARG, "Resource type %u, test %u: unexpectedly succeeded "
"to create resource, hr %#x.\n", i, j, hr);
continue;
}
if (tests[j].null_srv)
{
hr = ID3D10Device_CreateShaderResourceView(device, resource, NULL, &srv);
}
else
{
srv_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
srv_desc.ViewDimension = resource_types[i].srv_dim;
switch (resource_types[i].srv_dim)
{
case D3D10_SRV_DIMENSION_BUFFER:
srv_desc.Buffer.ElementOffset = 0;
srv_desc.Buffer.ElementWidth = 0;
break;
case D3D10_SRV_DIMENSION_TEXTURE2D:
srv_desc.Texture2D.MostDetailedMip = tests[j].base_level;
srv_desc.Texture2D.MipLevels = ~0u;
break;
case D3D10_SRV_DIMENSION_TEXTURE2DARRAY:
srv_desc.Texture2DArray.MostDetailedMip = tests[j].base_level;
srv_desc.Texture2DArray.MipLevels = ~0u;
srv_desc.Texture2DArray.FirstArraySlice = 0;
srv_desc.Texture2DArray.ArraySize = resource_types[i].array_size;
break;
case D3D10_SRV_DIMENSION_TEXTURE3D:
srv_desc.Texture3D.MostDetailedMip = tests[j].base_level;
srv_desc.Texture3D.MipLevels = ~0u;
break;
default:
break;
}
hr = ID3D10Device_CreateShaderResourceView(device, resource, &srv_desc, &srv);
}
if (resource_types[i].dim == D3D10_RESOURCE_DIMENSION_BUFFER)
{
ok(FAILED(hr), "Test %u: unexpectedly succeeded to create shader resource view, "
"hr %#x.\n", j, hr);
ID3D10Resource_Release(resource);
continue;
}
else
{
ok(SUCCEEDED(hr), "Resource type %u, test %u: failed to create "
"shader resource view, hr %#x.\n", i, j, hr);
}
ID3D10Device_UpdateSubresource(device, resource, tests[j].base_level,
NULL, data, sizeof(*data) * 32, sizeof(*data) * 32 * 32);
ID3D10Device_UpdateSubresource(device, resource, tests[j].base_level + 1,
NULL, zero_data, sizeof(*zero_data) * 16, sizeof(*zero_data) * 16 * 16);
ID3D10Device_GenerateMips(device, srv);
ID3D10Device_ClearRenderTargetView(device, test_context.backbuffer_rtv, &white.x);
srv_desc.Format = tests[j].texture_format == DXGI_FORMAT_R8G8B8A8_UINT
? DXGI_FORMAT_R8G8B8A8_UINT : DXGI_FORMAT_R8G8B8A8_UNORM;
srv_desc.ViewDimension = resource_types[i].dim == D3D10_RESOURCE_DIMENSION_TEXTURE3D
? D3D10_SRV_DIMENSION_TEXTURE3D : D3D10_SRV_DIMENSION_TEXTURE2D;
srv_desc.Texture2D.MostDetailedMip = tests[j].base_level + 1;
srv_desc.Texture2D.MipLevels = ~0u;
hr = ID3D10Device_CreateShaderResourceView(device, resource, &srv_desc, &srv_sampling);
ok(SUCCEEDED(hr), "Resource type %u, test %u: failed to create shader resource view, "
"hr %#x.\n", i, j, hr);
ID3D10Device_PSSetShader(device, resource_types[i].dim
== D3D10_RESOURCE_DIMENSION_TEXTURE3D ? ps_3d : ps);
ID3D10Device_PSSetShaderResources(device, 0, 1, &srv_sampling);
draw_quad(&test_context);
get_texture_readback(test_context.backbuffer, 0, &rb);
for (k = 0; k < ARRAY_SIZE(expected); ++k)
{
color = get_readback_color(&rb, expected[k].pos.x, expected[k].pos.y);
expected_color = tests[j].expected_mips ? expected[k].color : 0;
ok(color == expected_color, "Resource type %u, test %u: pixel (%u, %u) "
"has color %08x, expected %08x.\n",
i, j, expected[k].pos.x, expected[k].pos.y, color, expected_color);
}
release_resource_readback(&rb);
ID3D10ShaderResourceView_Release(srv_sampling);
ID3D10ShaderResourceView_Release(srv);
ID3D10Resource_Release(resource);
}
}
if (is_warp_device(device))
{
win_skip("Creating the next texture crashes WARP on some testbot boxes.\n");
ID3D10SamplerState_Release(sampler_state);
ID3D10PixelShader_Release(ps_3d);
ID3D10PixelShader_Release(ps);
release_test_context(&test_context);
return;
}
/* Test the effect of sRGB views. */
for (y = 0; y < 32; ++y)
{
for (x = 0; x < 32; ++x)
{
DWORD *dst = &data[y * 32 + x];
*dst = (x + y) % 2 * 0xffffffff;
}
}
texture2d_desc.Width = 32;
texture2d_desc.Height = 32;
texture2d_desc.MipLevels = 0;
texture2d_desc.ArraySize = 1;
texture2d_desc.Format = DXGI_FORMAT_R8G8B8A8_TYPELESS;
texture2d_desc.SampleDesc.Count = 1;
texture2d_desc.SampleDesc.Quality = 0;
texture2d_desc.Usage = D3D10_USAGE_DEFAULT;
texture2d_desc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
texture2d_desc.CPUAccessFlags = 0;
texture2d_desc.MiscFlags = D3D10_RESOURCE_MISC_GENERATE_MIPS;
hr = ID3D10Device_CreateTexture2D(device, &texture2d_desc, NULL, (ID3D10Texture2D **)&resource);
ok(SUCCEEDED(hr), "Failed to create resource, hr %#x.\n", hr);
hr = ID3D10Device_CreateShaderResourceView(device, resource, NULL, &srv);
ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
srv_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
srv_desc.ViewDimension = D3D10_SRV_DIMENSION_TEXTURE2D;
srv_desc.Texture2D.MostDetailedMip = 0;
srv_desc.Texture2D.MipLevels = ~0u;
hr = ID3D10Device_CreateShaderResourceView(device, resource, &srv_desc, &srv);
ID3D10Device_UpdateSubresource(device, resource,
0, NULL, data, sizeof(*data) * 32, sizeof(*data) * 32 * 32);
ID3D10Device_GenerateMips(device, srv);
ID3D10Device_ClearRenderTargetView(device, test_context.backbuffer_rtv, &white.w);
srv_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
srv_desc.ViewDimension = D3D10_SRV_DIMENSION_TEXTURE2D;
srv_desc.Texture2D.MostDetailedMip = 1;
srv_desc.Texture2D.MipLevels = ~0u;
hr = ID3D10Device_CreateShaderResourceView(device, resource, &srv_desc, &srv_sampling);
ok(SUCCEEDED(hr), "Failed to create shader resource view, hr %#x.\n", hr);
ID3D10Device_PSSetShader(device, ps);
ID3D10Device_PSSetShaderResources(device, 0, 1, &srv_sampling);
draw_quad(&test_context);
get_texture_readback(test_context.backbuffer, 0, &rb);
color = get_readback_color(&rb, 320, 240);
ok(compare_color(color, 0x7fbcbcbc, 1) || broken(compare_color(color, 0x7f7f7f7f, 1)), /* AMD */
"Unexpected color %08x.\n", color);
release_resource_readback(&rb);
ID3D10ShaderResourceView_Release(srv_sampling);
ID3D10ShaderResourceView_Release(srv);
srv_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
srv_desc.ViewDimension = D3D10_SRV_DIMENSION_TEXTURE2D;
srv_desc.Texture2D.MostDetailedMip = 0;
srv_desc.Texture2D.MipLevels = ~0u;
hr = ID3D10Device_CreateShaderResourceView(device, resource, &srv_desc, &srv);
ID3D10Device_UpdateSubresource(device, resource,
0, NULL, data, sizeof(*data) * 32, sizeof(*data) * 32 * 32);
ID3D10Device_GenerateMips(device, srv);
ID3D10Device_ClearRenderTargetView(device, test_context.backbuffer_rtv, &white.w);
srv_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
srv_desc.ViewDimension = D3D10_SRV_DIMENSION_TEXTURE2D;
srv_desc.Texture2D.MostDetailedMip = 1;
srv_desc.Texture2D.MipLevels = ~0u;
hr = ID3D10Device_CreateShaderResourceView(device, resource, &srv_desc, &srv_sampling);
ok(SUCCEEDED(hr), "Failed to create shader resource view, hr %#x.\n", hr);
ID3D10Device_PSSetShader(device, ps);
ID3D10Device_PSSetShaderResources(device, 0, 1, &srv_sampling);
draw_quad(&test_context);
get_texture_readback(test_context.backbuffer, 0, &rb);
check_readback_data_color(&rb, NULL, 0x7f7f7f7f, 1);
release_resource_readback(&rb);
ID3D10ShaderResourceView_Release(srv_sampling);
ID3D10ShaderResourceView_Release(srv);
ID3D10Resource_Release(resource);
HeapFree(GetProcessHeap(), 0, data);
ID3D10SamplerState_Release(sampler_state);
ID3D10PixelShader_Release(ps_3d);
ID3D10PixelShader_Release(ps);
release_test_context(&test_context);
}
START_TEST(device)
{
test_feature_level();
@ -14253,4 +14715,5 @@ START_TEST(device)
test_format_compatibility();
test_clip_distance();
test_combined_clip_and_cull_distances();
test_generate_mips();
}