d3d10core/tests: Read back directly from the mipmap texture in test_generate_mips().

This is far simpler than drawing with it.

The immediate motivation here is that the DXGI_FORMAT_R8G8B8A8_UINT test causes
a validation error when drawing, since the shader declares its resource as a
float4 texture, which does not match the UINT view format. This could be fixed
by using a different shader, but it seems more prudent to just simplify the test
to not draw at all.
This commit is contained in:
Zebediah Figura 2023-06-14 17:02:06 -05:00 committed by Alexandre Julliard
parent 0135114951
commit 9f2cf25c2d

View file

@ -594,8 +594,8 @@ struct resource_readback
{
D3D10_RESOURCE_DIMENSION dimension;
ID3D10Resource *resource;
D3D10_MAPPED_TEXTURE2D map_desc;
unsigned int width, height, sub_resource_idx;
D3D10_MAPPED_TEXTURE3D map_desc;
unsigned int width, height, depth, sub_resource_idx;
};
static void get_buffer_readback(ID3D10Buffer *buffer, struct resource_readback *rb)
@ -623,6 +623,7 @@ static void get_buffer_readback(ID3D10Buffer *buffer, struct resource_readback *
rb->width = buffer_desc.ByteWidth;
rb->height = 1;
rb->depth = 1;
rb->sub_resource_idx = 0;
ID3D10Device_CopyResource(device, rb->resource, (ID3D10Resource *)buffer);
@ -633,6 +634,7 @@ static void get_buffer_readback(ID3D10Buffer *buffer, struct resource_readback *
rb->resource = NULL;
}
rb->map_desc.RowPitch = 0;
rb->map_desc.DepthPitch = 0;
ID3D10Device_Release(device);
}
@ -665,6 +667,7 @@ static void get_texture1d_readback(ID3D10Texture1D *texture, unsigned int sub_re
miplevel = sub_resource_idx % texture_desc.MipLevels;
rb->width = max(1, texture_desc.Width >> miplevel);
rb->height = 1;
rb->depth = 1;
rb->sub_resource_idx = sub_resource_idx;
ID3D10Device_CopyResource(device, rb->resource, (ID3D10Resource *)texture);
@ -676,6 +679,7 @@ static void get_texture1d_readback(ID3D10Texture1D *texture, unsigned int sub_re
rb->resource = NULL;
}
rb->map_desc.RowPitch = 0;
rb->map_desc.DepthPitch = 0;
ID3D10Device_Release(device);
}
@ -684,6 +688,7 @@ static void get_texture_readback(ID3D10Texture2D *texture, unsigned int sub_reso
struct resource_readback *rb)
{
D3D10_TEXTURE2D_DESC texture_desc;
D3D10_MAPPED_TEXTURE2D map_desc;
unsigned int miplevel;
ID3D10Device *device;
HRESULT hr;
@ -708,10 +713,57 @@ static void get_texture_readback(ID3D10Texture2D *texture, unsigned int sub_reso
miplevel = sub_resource_idx % texture_desc.MipLevels;
rb->width = max(1, texture_desc.Width >> miplevel);
rb->height = max(1, texture_desc.Height >> miplevel);
rb->depth = 1;
rb->sub_resource_idx = sub_resource_idx;
ID3D10Device_CopyResource(device, rb->resource, (ID3D10Resource *)texture);
if (FAILED(hr = ID3D10Texture2D_Map((ID3D10Texture2D *)rb->resource, sub_resource_idx,
D3D10_MAP_READ, 0, &map_desc)))
{
trace("Failed to map sub-resource %u, hr %#lx.\n", sub_resource_idx, hr);
ID3D10Resource_Release(rb->resource);
rb->resource = NULL;
}
rb->map_desc.pData = map_desc.pData;
rb->map_desc.RowPitch = map_desc.RowPitch;
rb->map_desc.DepthPitch = 0;
ID3D10Device_Release(device);
}
static void get_texture3d_readback(ID3D10Texture3D *texture, unsigned int sub_resource_idx,
struct resource_readback *rb)
{
D3D10_TEXTURE3D_DESC texture_desc;
unsigned int miplevel;
ID3D10Device *device;
HRESULT hr;
memset(rb, 0, sizeof(*rb));
rb->dimension = D3D10_RESOURCE_DIMENSION_TEXTURE3D;
ID3D10Texture3D_GetDevice(texture, &device);
ID3D10Texture3D_GetDesc(texture, &texture_desc);
texture_desc.Usage = D3D10_USAGE_STAGING;
texture_desc.BindFlags = 0;
texture_desc.CPUAccessFlags = D3D10_CPU_ACCESS_READ;
texture_desc.MiscFlags = 0;
if (FAILED(hr = ID3D10Device_CreateTexture3D(device, &texture_desc, NULL, (ID3D10Texture3D **)&rb->resource)))
{
trace("Failed to create texture, hr %#lx.\n", hr);
ID3D10Device_Release(device);
return;
}
miplevel = sub_resource_idx % texture_desc.MipLevels;
rb->width = max(1, texture_desc.Width >> miplevel);
rb->height = max(1, texture_desc.Height >> miplevel);
rb->depth = max(1, texture_desc.Depth >> miplevel);
rb->sub_resource_idx = sub_resource_idx;
ID3D10Device_CopyResource(device, rb->resource, (ID3D10Resource *)texture);
if (FAILED(hr = ID3D10Texture3D_Map((ID3D10Texture3D *)rb->resource, sub_resource_idx,
D3D10_MAP_READ, 0, &rb->map_desc)))
{
trace("Failed to map sub-resource %u, hr %#lx.\n", sub_resource_idx, hr);
@ -722,6 +774,36 @@ static void get_texture_readback(ID3D10Texture2D *texture, unsigned int sub_reso
ID3D10Device_Release(device);
}
static void get_resource_readback(ID3D10Resource *resource,
unsigned int sub_resource_idx, struct resource_readback *rb)
{
D3D10_RESOURCE_DIMENSION d;
ID3D10Resource_GetType(resource, &d);
switch (d)
{
case D3D10_RESOURCE_DIMENSION_BUFFER:
get_buffer_readback((ID3D10Buffer *)resource, rb);
return;
case D3D10_RESOURCE_DIMENSION_TEXTURE1D:
get_texture1d_readback((ID3D10Texture1D *)resource, sub_resource_idx, rb);
return;
case D3D10_RESOURCE_DIMENSION_TEXTURE2D:
get_texture_readback((ID3D10Texture2D *)resource, sub_resource_idx, rb);
return;
case D3D10_RESOURCE_DIMENSION_TEXTURE3D:
get_texture3d_readback((ID3D10Texture3D *)resource, sub_resource_idx, rb);
return;
default:
memset(rb, 0, sizeof(*rb));
return;
}
}
static void *get_readback_data(struct resource_readback *rb, unsigned int x, unsigned int y, unsigned byte_width)
{
return (BYTE *)rb->map_desc.pData + y * rb->map_desc.RowPitch + x * byte_width;
@ -775,6 +857,9 @@ static void release_resource_readback(struct resource_readback *rb)
case D3D10_RESOURCE_DIMENSION_TEXTURE2D:
ID3D10Texture2D_Unmap((ID3D10Texture2D *)rb->resource, rb->sub_resource_idx);
break;
case D3D10_RESOURCE_DIMENSION_TEXTURE3D:
ID3D10Texture3D_Unmap((ID3D10Texture3D *)rb->resource, rb->sub_resource_idx);
break;
default:
trace("Unhandled resource dimension %#x.\n", rb->dimension);
break;
@ -17116,60 +17201,6 @@ static void test_combined_clip_and_cull_distances(void)
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;
@ -17223,64 +17254,36 @@ static void test_generate_mips(void)
}
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},
{{10, 12}, 0xffff0000},
{{14, 12}, 0xffff0000},
{{18, 12}, 0xff00ff00},
{{22, 12}, 0xff00ff00},
{{10, 18}, 0xff0000ff},
{{14, 18}, 0xff0000ff},
{{18, 18}, 0xff000000},
{{22, 18}, 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};
unsigned int *data, *zero_data, color, expected_color, i, j, k, x, y, z;
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;
ID3D10ShaderResourceView *srv;
D3D10_BUFFER_DESC buffer_desc;
ID3D10PixelShader *ps, *ps_3d;
struct resource_readback rb;
ID3D10Resource *resource;
ID3D10Device *device;
HRESULT hr;
HRESULT hr = S_OK;
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 %#lx.\n", hr);
hr = ID3D10Device_CreatePixelShader(device, ps_code_3d, sizeof(ps_code_3d), &ps_3d);
ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#lx.\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 %#lx.\n", hr);
ID3D10Device_PSSetSamplers(device, 0, 1, &sampler_state);
data = heap_alloc(sizeof(*data) * 32 * 32 * 32);
for (z = 0; z < 32; ++z)
@ -17433,35 +17436,17 @@ static void test_generate_mips(void)
ID3D10Device_GenerateMips(device, srv);
clear_backbuffer_rtv(&test_context, &white);
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 %#lx.\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);
get_resource_readback(resource, tests[j].base_level + 1, &rb);
for (k = 0; k < ARRAY_SIZE(expected); ++k)
{
color = get_readback_color(&rb, expected[k].pos.x, expected[k].pos.y);
color = get_readback_color(&rb, expected[k].pos.x >> 1, expected[k].pos.y >> 1);
expected_color = tests[j].expected_mips ? expected[k].color : 0;
ok(color == expected_color, "Resource type %u, test %u: pixel (%ld, %ld) "
"has color %08x, expected %08x.\n",
i, j, expected[k].pos.x, expected[k].pos.y, color, expected_color);
i, j, expected[k].pos.x >> 1, expected[k].pos.y >> 1, color, expected_color);
}
release_resource_readback(&rb);
ID3D10ShaderResourceView_Release(srv_sampling);
ID3D10ShaderResourceView_Release(srv);
ID3D10Resource_Release(resource);
}
@ -17472,9 +17457,6 @@ static void test_generate_mips(void)
win_skip("Creating the next texture crashes WARP on some testbot boxes.\n");
heap_free(zero_data);
heap_free(data);
ID3D10SamplerState_Release(sampler_state);
ID3D10PixelShader_Release(ps_3d);
ID3D10PixelShader_Release(ps);
release_test_context(&test_context);
return;
}
@ -17515,26 +17497,12 @@ static void test_generate_mips(void)
ID3D10Device_GenerateMips(device, srv);
clear_backbuffer_rtv(&test_context, &white);
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 %#lx.\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);
get_resource_readback(resource, 1, &rb);
color = get_readback_color(&rb, 8, 8);
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;
@ -17547,24 +17515,10 @@ static void test_generate_mips(void)
ID3D10Device_GenerateMips(device, srv);
clear_backbuffer_rtv(&test_context, &white);
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 %#lx.\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);
get_resource_readback(resource, 1, &rb);
check_readback_data_color(&rb, NULL, 0x7f7f7f7f, 1);
release_resource_readback(&rb);
ID3D10ShaderResourceView_Release(srv_sampling);
ID3D10ShaderResourceView_Release(srv);
ID3D10Resource_Release(resource);
@ -17572,9 +17526,6 @@ static void test_generate_mips(void)
heap_free(zero_data);
heap_free(data);
ID3D10SamplerState_Release(sampler_state);
ID3D10PixelShader_Release(ps_3d);
ID3D10PixelShader_Release(ps);
release_test_context(&test_context);
}