Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- v2: Workaround for the testbot crash, always initialize the texture level used for sampling, a few formatting fixes. v3: Further workaround for a residual testbot crash on two machines.
dlls/d3d10core/tests/device.c | 463 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 463 insertions(+)
diff --git a/dlls/d3d10core/tests/device.c b/dlls/d3d10core/tests/device.c index a77f04f3680..66591b21052 100644 --- a/dlls/d3d10core/tests/device.c +++ b/dlls/d3d10core/tests/device.c @@ -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(); }
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- dlls/wined3d/texture.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index ed1ca21117f..6c8c313ee25 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -2159,6 +2159,12 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3 return WINED3DERR_INVALIDCALL; } } + if (flags & WINED3D_TEXTURE_GENERATE_MIPMAPS && !gl_info->supported[ARB_FRAMEBUFFER_OBJECT] + && !gl_info->supported[EXT_FRAMEBUFFER_OBJECT]) + { + WARN("No mipmap generation support, returning WINED3DERR_INVALIDCALL.\n"); + return WINED3DERR_INVALIDCALL; + }
if (FAILED(hr = wined3d_texture_init(texture, &texture2d_ops, layer_count, level_count, desc, flags, device, parent, parent_ops, &texture_resource_ops))) @@ -2601,6 +2607,12 @@ static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct return WINED3DERR_INVALIDCALL; } } + if (flags & WINED3D_TEXTURE_GENERATE_MIPMAPS && !gl_info->supported[ARB_FRAMEBUFFER_OBJECT] + && !gl_info->supported[EXT_FRAMEBUFFER_OBJECT]) + { + WARN("No mipmap generation support, returning WINED3DERR_INVALIDCALL.\n"); + return WINED3DERR_INVALIDCALL; + }
if (desc->usage & WINED3DUSAGE_DYNAMIC && (wined3d_resource_access_is_managed(desc->access) || desc->usage & WINED3DUSAGE_SCRATCH)) @@ -2657,7 +2669,7 @@ static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct texture->resource.map_binding = WINED3D_LOCATION_BUFFER; }
- /* Generate all the surfaces. */ + /* Generate all the sub resources. */ for (i = 0; i < texture->level_count; ++i) { struct wined3d_texture_sub_resource *sub_resource;
On 6 February 2018 at 22:06, Matteo Bruni mbruni@codeweavers.com wrote:
@@ -2159,6 +2159,12 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3 return WINED3DERR_INVALIDCALL; } }
if (flags & WINED3D_TEXTURE_GENERATE_MIPMAPS && !gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
&& !gl_info->supported[EXT_FRAMEBUFFER_OBJECT])
{
WARN("No mipmap generation support, returning WINED3DERR_INVALIDCALL.\n");
return WINED3DERR_INVALIDCALL;
}
if (FAILED(hr = wined3d_texture_init(texture, &texture2d_ops, layer_count, level_count, desc, flags, device, parent, parent_ops, &texture_resource_ops)))
Should that check be in wined3d_texture_init() instead? Also, note that wined3d_check_device_format() uses a somewhat different check for WINED3DUSAGE_AUTOGENMIPMAP and later WINED3DUSAGE_QUERY_GENMIPMAP. I'm tempted to say we should introduce WINED3DFMT_FLAG_GEN_MIPMAP and use that both here and in wined3d_check_device_format(). And perhaps "!gl_info->fbo_ops.glGenerateMipmap" works just as well as checking individual extensions.
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- dlls/d3d9/d3d9_private.h | 25 ++++- dlls/d3d9/device.c | 75 +++++++++++++ dlls/d3d9/surface.c | 4 + dlls/d3d9/tests/device.c | 5 +- dlls/d3d9/texture.c | 270 ++++++++++++++++++++++++++++++++++++----------- 5 files changed, 313 insertions(+), 66 deletions(-)
diff --git a/dlls/d3d9/d3d9_private.h b/dlls/d3d9/d3d9_private.h index 5a1aac81ed1..ce76c71e029 100644 --- a/dlls/d3d9/d3d9_private.h +++ b/dlls/d3d9/d3d9_private.h @@ -39,8 +39,16 @@ #include "d3d9.h" #include "wine/wined3d.h"
+#define D3D9_MAX_VERTEX_SHADER_CONSTANTF 256 +#define D3D9_MAX_TEXTURE_UNITS 20 +#define D3D9_MAX_SIMULTANEOUS_RENDERTARGETS 4 + #define D3DPRESENTFLAGS_MASK 0x00000fffu
+#define D3D9_TEXTURE_MIPMAP_DIRTY 0x1 + +#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) + extern const struct wined3d_parent_ops d3d9_null_wined3d_parent_ops DECLSPEC_HIDDEN;
HRESULT vdecl_convert_fvf(DWORD FVF, D3DVERTEXELEMENT9 **ppVertexElements) DECLSPEC_HIDDEN; @@ -92,6 +100,9 @@ struct d3d9_device UINT index_buffer_size; UINT index_buffer_pos;
+ struct d3d9_texture *textures[D3D9_MAX_TEXTURE_UNITS]; + struct d3d9_surface *render_targets[D3D9_MAX_SIMULTANEOUS_RENDERTARGETS]; + LONG device_state; BOOL in_destruction; BOOL in_scene; @@ -198,6 +209,10 @@ struct d3d9_texture struct wined3d_texture *wined3d_texture; IDirect3DDevice9Ex *parent_device; struct list rtv_list; + DWORD usage; + BOOL flags; + struct wined3d_shader_resource_view *wined3d_srv; + D3DTEXTUREFILTERTYPE autogen_filter_type; };
HRESULT cubetexture_init(struct d3d9_texture *texture, struct d3d9_device *device, @@ -207,6 +222,8 @@ HRESULT texture_init(struct d3d9_texture *texture, struct d3d9_device *device, HRESULT volumetexture_init(struct d3d9_texture *texture, struct d3d9_device *device, UINT width, UINT height, UINT depth, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool) DECLSPEC_HIDDEN; struct d3d9_texture *unsafe_impl_from_IDirect3DBaseTexture9(IDirect3DBaseTexture9 *iface) DECLSPEC_HIDDEN; +void d3d9_texture_flag_auto_gen_mipmap(struct d3d9_texture *texture) DECLSPEC_HIDDEN; +void d3d9_texture_gen_auto_mipmap(struct d3d9_texture *texture) DECLSPEC_HIDDEN;
struct d3d9_stateblock { @@ -247,9 +264,6 @@ HRESULT vertexshader_init(struct d3d9_vertexshader *shader, struct d3d9_device *device, const DWORD *byte_code) DECLSPEC_HIDDEN; struct d3d9_vertexshader *unsafe_impl_from_IDirect3DVertexShader9(IDirect3DVertexShader9 *iface) DECLSPEC_HIDDEN;
-#define D3D9_MAX_VERTEX_SHADER_CONSTANTF 256 -#define D3D9_MAX_SIMULTANEOUS_RENDERTARGETS 4 - struct d3d9_pixelshader { IDirect3DPixelShader9 IDirect3DPixelShader9_iface; @@ -315,4 +329,9 @@ static inline unsigned int wined3daccess_from_d3dpool(D3DPOOL pool) } }
+static inline DWORD wined3dusage_from_d3dusage(unsigned int usage) +{ + return usage & WINED3DUSAGE_MASK & ~WINED3DUSAGE_AUTOGENMIPMAP; +} + #endif /* __WINE_D3D9_PRIVATE_H */ diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c index 954f3faa30d..d2766c72a54 100644 --- a/dlls/d3d9/device.c +++ b/dlls/d3d9/device.c @@ -816,6 +816,8 @@ static HRESULT d3d9_device_reset(struct d3d9_device *device, BOOL extended = device->d3d_parent->extended; struct wined3d_swapchain_desc swapchain_desc; struct wined3d_display_mode wined3d_mode; + struct wined3d_rendertarget_view *rtv; + unsigned int i; HRESULT hr;
if (!extended && device->device_state == D3D9_DEVICE_STATE_LOST) @@ -877,6 +879,15 @@ static HRESULT d3d9_device_reset(struct d3d9_device *device,
device->device_state = D3D9_DEVICE_STATE_OK; } + + if (!device->d3d_parent->extended) + for (i = 0; i < ARRAY_SIZE(device->textures); ++i) + device->textures[i] = NULL; + + rtv = wined3d_device_get_rendertarget_view(device->wined3d_device, 0); + device->render_targets[0] = wined3d_rendertarget_view_get_sub_resource_parent(rtv); + for (i = 1; i < ARRAY_SIZE(device->render_targets); ++i) + device->render_targets[i] = NULL; } else if (!extended) { @@ -1431,6 +1442,9 @@ static HRESULT WINAPI d3d9_device_UpdateSurface(IDirect3DDevice9Ex *iface, wined3d_texture_get_resource(dst->wined3d_texture), dst->sub_resource_idx, dst_point ? dst_point->x : 0, dst_point ? dst_point->y : 0, 0, wined3d_texture_get_resource(src->wined3d_texture), src->sub_resource_idx, &src_box); + if (SUCCEEDED(hr) && dst->texture) + d3d9_texture_flag_auto_gen_mipmap(dst->texture); + wined3d_mutex_unlock();
if (FAILED(hr)) @@ -1454,6 +1468,8 @@ static HRESULT WINAPI d3d9_device_UpdateTexture(IDirect3DDevice9Ex *iface, wined3d_mutex_lock(); hr = wined3d_device_update_texture(device->wined3d_device, src_impl->wined3d_texture, dst_impl->wined3d_texture); + if (SUCCEEDED(hr)) + d3d9_texture_flag_auto_gen_mipmap(dst_impl); wined3d_mutex_unlock();
return hr; @@ -1572,6 +1588,8 @@ static HRESULT WINAPI d3d9_device_StretchRect(IDirect3DDevice9Ex *iface, IDirect src->wined3d_texture, src->sub_resource_idx, src_rect, 0, NULL, filter); if (hr == WINEDDERR_INVALIDRECT) hr = D3DERR_INVALIDCALL; + if (SUCCEEDED(hr) && dst->texture) + d3d9_texture_flag_auto_gen_mipmap(dst->texture);
done: wined3d_mutex_unlock(); @@ -1628,6 +1646,8 @@ static HRESULT WINAPI d3d9_device_ColorFill(IDirect3DDevice9Ex *iface, hr = wined3d_device_clear_rendertarget_view(device->wined3d_device, rtv, rect, WINED3DCLEAR_TARGET, &c, 0.0f, 0); d3d9_surface_release_rendertarget_view(surface_impl, rtv); + if (SUCCEEDED(hr) && surface_impl->texture) + d3d9_texture_flag_auto_gen_mipmap(surface_impl->texture);
wined3d_mutex_unlock();
@@ -1710,6 +1730,8 @@ static HRESULT WINAPI d3d9_device_SetRenderTarget(IDirect3DDevice9Ex *iface, DWO rtv = surface_impl ? d3d9_surface_acquire_rendertarget_view(surface_impl) : NULL; hr = wined3d_device_set_rendertarget_view(device->wined3d_device, idx, rtv, TRUE); d3d9_surface_release_rendertarget_view(surface_impl, rtv); + if (SUCCEEDED(hr)) + device->render_targets[idx] = surface_impl; wined3d_mutex_unlock();
return hr; @@ -1830,6 +1852,19 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_EndScene(IDirect3DDevice9Ex return hr; }
+static void d3d9_rts_flag_auto_gen_mipmap(struct d3d9_device *device) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(device->render_targets); ++i) + { + struct d3d9_surface *surface = device->render_targets[i]; + + if (surface && surface->texture) + d3d9_texture_flag_auto_gen_mipmap(surface->texture); + } +} + static HRESULT WINAPI d3d9_device_Clear(IDirect3DDevice9Ex *iface, DWORD rect_count, const D3DRECT *rects, DWORD flags, D3DCOLOR color, float z, DWORD stencil) { @@ -1854,6 +1889,8 @@ static HRESULT WINAPI d3d9_device_Clear(IDirect3DDevice9Ex *iface, DWORD rect_co
wined3d_mutex_lock(); hr = wined3d_device_clear(device->wined3d_device, rect_count, (const RECT *)rects, flags, &c, z, stencil); + if (SUCCEEDED(hr)) + d3d9_rts_flag_auto_gen_mipmap(device); wined3d_mutex_unlock();
return hr; @@ -2251,6 +2288,13 @@ static HRESULT WINAPI d3d9_device_SetTexture(IDirect3DDevice9Ex *iface, DWORD st wined3d_mutex_lock(); hr = wined3d_device_set_texture(device->wined3d_device, stage, texture_impl ? texture_impl->wined3d_texture : NULL); + if (SUCCEEDED(hr)) + { + unsigned int i = stage >= D3DVERTEXTEXTURESAMPLER0 ? stage - D3DVERTEXTEXTURESAMPLER0 + 16 : stage; + + if (stage < ARRAY_SIZE(device->textures)) + device->textures[i] = texture_impl; + } wined3d_mutex_unlock();
return hr; @@ -2491,6 +2535,16 @@ static float WINAPI d3d9_device_GetNPatchMode(IDirect3DDevice9Ex *iface) return ret; }
+/* wined3d critical section must be taken by the caller. */ +static void d3d9_generate_auto_mipmaps(struct d3d9_device *device) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(device->textures); ++i) + if (device->textures[i]) + d3d9_texture_gen_auto_mipmap(device->textures[i]); +} + static HRESULT WINAPI d3d9_device_DrawPrimitive(IDirect3DDevice9Ex *iface, D3DPRIMITIVETYPE primitive_type, UINT start_vertex, UINT primitive_count) { @@ -2507,9 +2561,12 @@ static HRESULT WINAPI d3d9_device_DrawPrimitive(IDirect3DDevice9Ex *iface, WARN("Called without a valid vertex declaration set.\n"); return D3DERR_INVALIDCALL; } + d3d9_generate_auto_mipmaps(device); wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0); hr = wined3d_device_draw_primitive(device->wined3d_device, start_vertex, vertex_count_from_primitive_count(primitive_type, primitive_count)); + if (SUCCEEDED(hr)) + d3d9_rts_flag_auto_gen_mipmap(device); wined3d_mutex_unlock();
return hr; @@ -2534,10 +2591,13 @@ static HRESULT WINAPI d3d9_device_DrawIndexedPrimitive(IDirect3DDevice9Ex *iface WARN("Called without a valid vertex declaration set.\n"); return D3DERR_INVALIDCALL; } + d3d9_generate_auto_mipmaps(device); wined3d_device_set_base_vertex_index(device->wined3d_device, base_vertex_idx); wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0); hr = wined3d_device_draw_indexed_primitive(device->wined3d_device, start_idx, vertex_count_from_primitive_count(primitive_type, primitive_count)); + if (SUCCEEDED(hr)) + d3d9_rts_flag_auto_gen_mipmap(device); wined3d_mutex_unlock();
return hr; @@ -2629,9 +2689,12 @@ static HRESULT WINAPI d3d9_device_DrawPrimitiveUP(IDirect3DDevice9Ex *iface, if (FAILED(hr)) goto done;
+ d3d9_generate_auto_mipmaps(device); wined3d_device_set_primitive_type(device->wined3d_device, primitive_type, 0); hr = wined3d_device_draw_primitive(device->wined3d_device, vb_pos / stride, vtx_count); wined3d_device_set_stream_source(device->wined3d_device, 0, NULL, 0, 0); + if (SUCCEEDED(hr)) + d3d9_rts_flag_auto_gen_mipmap(device);
done: wined3d_mutex_unlock(); @@ -2752,6 +2815,7 @@ static HRESULT WINAPI d3d9_device_DrawIndexedPrimitiveUP(IDirect3DDevice9Ex *ifa if (FAILED(hr)) goto done;
+ d3d9_generate_auto_mipmaps(device); wined3d_device_set_index_buffer(device->wined3d_device, device->index_buffer, wined3dformat_from_d3dformat(index_format), 0); wined3d_device_set_base_vertex_index(device->wined3d_device, vb_pos / vertex_stride - min_vertex_idx); @@ -2763,6 +2827,9 @@ static HRESULT WINAPI d3d9_device_DrawIndexedPrimitiveUP(IDirect3DDevice9Ex *ifa wined3d_device_set_index_buffer(device->wined3d_device, NULL, WINED3DFMT_UNKNOWN, 0); wined3d_device_set_base_vertex_index(device->wined3d_device, 0);
+ if (SUCCEEDED(hr)) + d3d9_rts_flag_auto_gen_mipmap(device); + done: wined3d_mutex_unlock(); return hr; @@ -4147,6 +4214,14 @@ HRESULT device_init(struct d3d9_device *device, struct d3d9 *parent, struct wine return E_OUTOFMEMORY; }
+ /* We could also simply ignore the initial rendertarget since it's known + * not to be a texture (we currently use these only for automatic mipmap + * generation). */ + wined3d_mutex_lock(); + device->render_targets[0] = wined3d_rendertarget_view_get_sub_resource_parent( + wined3d_device_get_rendertarget_view(device->wined3d_device, 0)); + wined3d_mutex_unlock(); + IDirect3D9Ex_AddRef(&parent->IDirect3D9Ex_iface); device->d3d_parent = parent;
diff --git a/dlls/d3d9/surface.c b/dlls/d3d9/surface.c index 8c42a8c630d..a38cbb4d816 100644 --- a/dlls/d3d9/surface.c +++ b/dlls/d3d9/surface.c @@ -270,6 +270,8 @@ static HRESULT WINAPI d3d9_surface_UnlockRect(IDirect3DSurface9 *iface)
wined3d_mutex_lock(); hr = wined3d_resource_unmap(wined3d_texture_get_resource(surface->wined3d_texture), surface->sub_resource_idx); + if (SUCCEEDED(hr) && surface->texture) + d3d9_texture_flag_auto_gen_mipmap(surface->texture); wined3d_mutex_unlock();
if (hr == WINEDDERR_NOTLOCKED) @@ -307,6 +309,8 @@ static HRESULT WINAPI d3d9_surface_ReleaseDC(IDirect3DSurface9 *iface, HDC dc)
wined3d_mutex_lock(); hr = wined3d_texture_release_dc(surface->wined3d_texture, surface->sub_resource_idx, dc); + if (SUCCEEDED(hr) && surface->texture) + d3d9_texture_flag_auto_gen_mipmap(surface->texture); wined3d_mutex_unlock();
return hr; diff --git a/dlls/d3d9/tests/device.c b/dlls/d3d9/tests/device.c index a9fd4e4d30f..71cfdf49219 100644 --- a/dlls/d3d9/tests/device.c +++ b/dlls/d3d9/tests/device.c @@ -7124,10 +7124,9 @@ static void test_mipmap_gen(void) ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
filter_type = IDirect3DTexture9_GetAutoGenFilterType(texture); - ok(filter_type == D3DTEXF_LINEAR /* || broken(filter_type == D3DTEXF_POINT)*/, - "Got unexpected filter_type %#x.\n", filter_type); + ok(filter_type == D3DTEXF_LINEAR, "Got unexpected filter_type %#x.\n", filter_type); hr = IDirect3DTexture9_SetAutoGenFilterType(texture, D3DTEXF_NONE); - todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr); + ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr); hr = IDirect3DTexture9_SetAutoGenFilterType(texture, D3DTEXF_ANISOTROPIC); ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr); filter_type = IDirect3DTexture9_GetAutoGenFilterType(texture); diff --git a/dlls/d3d9/texture.c b/dlls/d3d9/texture.c index a1c52591c1b..e51c6fc6e58 100644 --- a/dlls/d3d9/texture.c +++ b/dlls/d3d9/texture.c @@ -38,6 +38,62 @@ static inline struct d3d9_texture *impl_from_IDirect3DVolumeTexture9(IDirect3DVo return CONTAINING_RECORD(iface, struct d3d9_texture, IDirect3DBaseTexture9_iface); }
+static void STDMETHODCALLTYPE srv_wined3d_object_destroyed(void *parent) +{ + struct d3d9_texture *texture = parent; + + texture->wined3d_srv = NULL; +} + +static const struct wined3d_parent_ops d3d9_srv_wined3d_parent_ops = +{ + srv_wined3d_object_destroyed, +}; + +/* wined3d critical section must be taken by the caller. */ +static struct wined3d_shader_resource_view *d3d9_texture_acquire_shader_resource_view(struct d3d9_texture *texture) +{ + struct wined3d_sub_resource_desc sr_desc; + struct wined3d_view_desc desc; + HRESULT hr; + + if (texture->wined3d_srv) + return texture->wined3d_srv; + + wined3d_texture_get_sub_resource_desc(texture->wined3d_texture, 0, &sr_desc); + desc.format_id = sr_desc.format; + desc.flags = 0; + desc.u.texture.level_idx = 0; + desc.u.texture.level_count = wined3d_texture_get_level_count(texture->wined3d_texture); + desc.u.texture.layer_idx = 0; + desc.u.texture.layer_count = sr_desc.usage & WINED3DUSAGE_LEGACY_CUBEMAP ? 6 : 1; + if (FAILED(hr = wined3d_shader_resource_view_create(&desc, + wined3d_texture_get_resource(texture->wined3d_texture), texture, + &d3d9_srv_wined3d_parent_ops, &texture->wined3d_srv))) + { + ERR("Failed to create shader resource view, hr %#x.\n", hr); + return NULL; + } + + return texture->wined3d_srv; +} + +/* wined3d critical section must be taken by the caller. */ +void d3d9_texture_gen_auto_mipmap(struct d3d9_texture *texture) +{ + if (!(texture->flags & D3D9_TEXTURE_MIPMAP_DIRTY)) + return; + d3d9_texture_acquire_shader_resource_view(texture); + wined3d_shader_resource_view_generate_mipmaps(texture->wined3d_srv); + texture->flags &= ~D3D9_TEXTURE_MIPMAP_DIRTY; +} + +void d3d9_texture_flag_auto_gen_mipmap(struct d3d9_texture *texture) +{ + if (texture->usage & D3DUSAGE_AUTOGENMIPMAP) + texture->flags |= D3D9_TEXTURE_MIPMAP_DIRTY; +} + static HRESULT WINAPI d3d9_texture_2d_QueryInterface(IDirect3DTexture9 *iface, REFIID riid, void **out) { TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out); @@ -95,6 +151,8 @@ static ULONG WINAPI d3d9_texture_2d_Release(IDirect3DTexture9 *iface) struct d3d9_surface *surface;
wined3d_mutex_lock(); + if (texture->wined3d_srv) + wined3d_shader_resource_view_decref(texture->wined3d_srv); LIST_FOR_EACH_ENTRY(surface, &texture->rtv_list, struct d3d9_surface, rtv_entry) { wined3d_rendertarget_view_decref(surface->wined3d_rtv); @@ -235,6 +293,9 @@ static DWORD WINAPI d3d9_texture_2d_GetLevelCount(IDirect3DTexture9 *iface)
TRACE("iface %p.\n", iface);
+ if (texture->usage & D3DUSAGE_AUTOGENMIPMAP) + return 1; + wined3d_mutex_lock(); ret = wined3d_texture_get_level_count(texture->wined3d_texture); wined3d_mutex_unlock(); @@ -245,35 +306,44 @@ static DWORD WINAPI d3d9_texture_2d_GetLevelCount(IDirect3DTexture9 *iface) static HRESULT WINAPI d3d9_texture_2d_SetAutoGenFilterType(IDirect3DTexture9 *iface, D3DTEXTUREFILTERTYPE filter_type) { struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface); - HRESULT hr;
TRACE("iface %p, filter_type %#x.\n", iface, filter_type);
- wined3d_mutex_lock(); - hr = wined3d_texture_set_autogen_filter_type(texture->wined3d_texture, - (enum wined3d_texture_filter_type)filter_type); - wined3d_mutex_unlock(); + if (filter_type == D3DTEXF_NONE) + { + WARN("Invalid filter type D3DTEXF_NONE specified.\n"); + return D3DERR_INVALIDCALL; + } + if (!(texture->usage & D3DUSAGE_AUTOGENMIPMAP)) + WARN("Called on a texture without the D3DUSAGE_AUTOGENMIPMAP flag.\n"); + else if (filter_type != D3DTEXF_LINEAR) + FIXME("Unsupported filter type %u.\n", filter_type);
- return hr; + texture->autogen_filter_type = filter_type; + return D3D_OK; }
static D3DTEXTUREFILTERTYPE WINAPI d3d9_texture_2d_GetAutoGenFilterType(IDirect3DTexture9 *iface) { struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface); - D3DTEXTUREFILTERTYPE ret;
TRACE("iface %p.\n", iface);
- wined3d_mutex_lock(); - ret = (D3DTEXTUREFILTERTYPE)wined3d_texture_get_autogen_filter_type(texture->wined3d_texture); - wined3d_mutex_unlock(); + if (!(texture->usage & D3DUSAGE_AUTOGENMIPMAP)) + WARN("Called on a texture without the D3DUSAGE_AUTOGENMIPMAP flag.\n");
- return ret; + return texture->autogen_filter_type; }
static void WINAPI d3d9_texture_2d_GenerateMipSubLevels(IDirect3DTexture9 *iface) { + struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface); + TRACE("iface %p.\n", iface); + + wined3d_mutex_lock(); + d3d9_texture_gen_auto_mipmap(texture); + wined3d_mutex_unlock(); }
static HRESULT WINAPI d3d9_texture_2d_GetLevelDesc(IDirect3DTexture9 *iface, UINT level, D3DSURFACE_DESC *desc) @@ -284,12 +354,18 @@ static HRESULT WINAPI d3d9_texture_2d_GetLevelDesc(IDirect3DTexture9 *iface, UIN
TRACE("iface %p, level %u, desc %p.\n", iface, level, desc);
+ if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level) + { + WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n"); + return D3DERR_INVALIDCALL; + } + wined3d_mutex_lock(); if (SUCCEEDED(hr = wined3d_texture_get_sub_resource_desc(texture->wined3d_texture, level, &wined3d_desc))) { desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format); desc->Type = D3DRTYPE_SURFACE; - desc->Usage = d3dusage_from_wined3dusage(wined3d_desc.usage); + desc->Usage = texture->usage; desc->Pool = d3dpool_from_wined3daccess(wined3d_desc.access, wined3d_desc.usage); desc->MultiSampleType = wined3d_desc.multisample_type; desc->MultiSampleQuality = wined3d_desc.multisample_quality; @@ -309,6 +385,12 @@ static HRESULT WINAPI d3d9_texture_2d_GetSurfaceLevel(IDirect3DTexture9 *iface,
TRACE("iface %p, level %u, surface %p.\n", iface, level, surface);
+ if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level) + { + WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n"); + return D3DERR_INVALIDCALL; + } + wined3d_mutex_lock(); if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level))) { @@ -333,6 +415,12 @@ static HRESULT WINAPI d3d9_texture_2d_LockRect(IDirect3DTexture9 *iface, TRACE("iface %p, level %u, locked_rect %p, rect %p, flags %#x.\n", iface, level, locked_rect, rect, flags);
+ if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level) + { + WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n"); + return D3DERR_INVALIDCALL; + } + wined3d_mutex_lock(); if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level))) hr = D3DERR_INVALIDCALL; @@ -351,6 +439,12 @@ static HRESULT WINAPI d3d9_texture_2d_UnlockRect(IDirect3DTexture9 *iface, UINT
TRACE("iface %p, level %u.\n", iface, level);
+ if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level) + { + WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n"); + return D3DERR_INVALIDCALL; + } + wined3d_mutex_lock(); if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level))) hr = D3DERR_INVALIDCALL; @@ -473,6 +567,8 @@ static ULONG WINAPI d3d9_texture_cube_Release(IDirect3DCubeTexture9 *iface) TRACE("Releasing child %p.\n", texture->wined3d_texture);
wined3d_mutex_lock(); + if (texture->wined3d_srv) + wined3d_shader_resource_view_decref(texture->wined3d_srv); LIST_FOR_EACH_ENTRY(surface, &texture->rtv_list, struct d3d9_surface, rtv_entry) { wined3d_rendertarget_view_decref(surface->wined3d_rtv); @@ -613,6 +709,9 @@ static DWORD WINAPI d3d9_texture_cube_GetLevelCount(IDirect3DCubeTexture9 *iface
TRACE("iface %p.\n", iface);
+ if (texture->usage & D3DUSAGE_AUTOGENMIPMAP) + return 1; + wined3d_mutex_lock(); ret = wined3d_texture_get_level_count(texture->wined3d_texture); wined3d_mutex_unlock(); @@ -624,35 +723,44 @@ static HRESULT WINAPI d3d9_texture_cube_SetAutoGenFilterType(IDirect3DCubeTextur D3DTEXTUREFILTERTYPE filter_type) { struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface); - HRESULT hr;
TRACE("iface %p, filter_type %#x.\n", iface, filter_type);
- wined3d_mutex_lock(); - hr = wined3d_texture_set_autogen_filter_type(texture->wined3d_texture, - (enum wined3d_texture_filter_type)filter_type); - wined3d_mutex_unlock(); + if (filter_type == D3DTEXF_NONE) + { + WARN("Invalid filter type D3DTEXF_NONE specified.\n"); + return D3DERR_INVALIDCALL; + } + if (!(texture->usage & D3DUSAGE_AUTOGENMIPMAP)) + WARN("Called on a texture without the D3DUSAGE_AUTOGENMIPMAP flag.\n"); + else if (filter_type != D3DTEXF_LINEAR) + FIXME("Unsupported filter type %u.\n", filter_type);
- return hr; + texture->autogen_filter_type = filter_type; + return D3D_OK; }
static D3DTEXTUREFILTERTYPE WINAPI d3d9_texture_cube_GetAutoGenFilterType(IDirect3DCubeTexture9 *iface) { struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface); - D3DTEXTUREFILTERTYPE ret;
TRACE("iface %p.\n", iface);
- wined3d_mutex_lock(); - ret = (D3DTEXTUREFILTERTYPE)wined3d_texture_get_autogen_filter_type(texture->wined3d_texture); - wined3d_mutex_unlock(); + if (!(texture->usage & D3DUSAGE_AUTOGENMIPMAP)) + WARN("Called on a texture without the D3DUSAGE_AUTOGENMIPMAP flag.\n");
- return ret; + return texture->autogen_filter_type; }
static void WINAPI d3d9_texture_cube_GenerateMipSubLevels(IDirect3DCubeTexture9 *iface) { + struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface); + TRACE("iface %p.\n", iface); + + wined3d_mutex_lock(); + d3d9_texture_gen_auto_mipmap(texture); + wined3d_mutex_unlock(); }
static HRESULT WINAPI d3d9_texture_cube_GetLevelDesc(IDirect3DCubeTexture9 *iface, UINT level, D3DSURFACE_DESC *desc) @@ -664,6 +772,12 @@ static HRESULT WINAPI d3d9_texture_cube_GetLevelDesc(IDirect3DCubeTexture9 *ifac
TRACE("iface %p, level %u, desc %p.\n", iface, level, desc);
+ if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level) + { + WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n"); + return D3DERR_INVALIDCALL; + } + wined3d_mutex_lock(); level_count = wined3d_texture_get_level_count(texture->wined3d_texture); if (level >= level_count) @@ -676,7 +790,7 @@ static HRESULT WINAPI d3d9_texture_cube_GetLevelDesc(IDirect3DCubeTexture9 *ifac { desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format); desc->Type = D3DRTYPE_SURFACE; - desc->Usage = d3dusage_from_wined3dusage(wined3d_desc.usage); + desc->Usage = texture->usage; desc->Pool = d3dpool_from_wined3daccess(wined3d_desc.access, wined3d_desc.usage); desc->MultiSampleType = wined3d_desc.multisample_type; desc->MultiSampleQuality = wined3d_desc.multisample_quality; @@ -698,6 +812,12 @@ static HRESULT WINAPI d3d9_texture_cube_GetCubeMapSurface(IDirect3DCubeTexture9
TRACE("iface %p, face %#x, level %u, surface %p.\n", iface, face, level, surface);
+ if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level) + { + WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n"); + return D3DERR_INVALIDCALL; + } + wined3d_mutex_lock(); level_count = wined3d_texture_get_level_count(texture->wined3d_texture); if (level >= level_count) @@ -732,6 +852,12 @@ static HRESULT WINAPI d3d9_texture_cube_LockRect(IDirect3DCubeTexture9 *iface, TRACE("iface %p, face %#x, level %u, locked_rect %p, rect %p, flags %#x.\n", iface, face, level, locked_rect, rect, flags);
+ if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level) + { + WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n"); + return D3DERR_INVALIDCALL; + } + wined3d_mutex_lock(); sub_resource_idx = wined3d_texture_get_level_count(texture->wined3d_texture) * face + level; if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, sub_resource_idx))) @@ -753,6 +879,12 @@ static HRESULT WINAPI d3d9_texture_cube_UnlockRect(IDirect3DCubeTexture9 *iface,
TRACE("iface %p, face %#x, level %u.\n", iface, face, level);
+ if (texture->usage & D3DUSAGE_AUTOGENMIPMAP && level) + { + WARN("D3DUSAGE_AUTOGENMIPMAP textures have only one accessible level.\n"); + return D3DERR_INVALIDCALL; + } + wined3d_mutex_lock(); sub_resource_idx = wined3d_texture_get_level_count(texture->wined3d_texture) * face + level; if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, sub_resource_idx))) @@ -1014,31 +1146,16 @@ static DWORD WINAPI d3d9_texture_3d_GetLevelCount(IDirect3DVolumeTexture9 *iface static HRESULT WINAPI d3d9_texture_3d_SetAutoGenFilterType(IDirect3DVolumeTexture9 *iface, D3DTEXTUREFILTERTYPE filter_type) { - struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface); - HRESULT hr; - TRACE("iface %p, filter_type %#x.\n", iface, filter_type);
- wined3d_mutex_lock(); - hr = wined3d_texture_set_autogen_filter_type(texture->wined3d_texture, - (enum wined3d_texture_filter_type)filter_type); - wined3d_mutex_unlock(); - - return hr; + return D3DERR_INVALIDCALL; }
static D3DTEXTUREFILTERTYPE WINAPI d3d9_texture_3d_GetAutoGenFilterType(IDirect3DVolumeTexture9 *iface) { - struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface); - D3DTEXTUREFILTERTYPE filter_type; - TRACE("iface %p.\n", iface);
- wined3d_mutex_lock(); - filter_type = (D3DTEXTUREFILTERTYPE)wined3d_texture_get_autogen_filter_type(texture->wined3d_texture); - wined3d_mutex_unlock(); - - return filter_type; + return D3DTEXF_NONE; }
static void WINAPI d3d9_texture_3d_GenerateMipSubLevels(IDirect3DVolumeTexture9 *iface) @@ -1059,7 +1176,7 @@ static HRESULT WINAPI d3d9_texture_3d_GetLevelDesc(IDirect3DVolumeTexture9 *ifac { desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format); desc->Type = D3DRTYPE_VOLUME; - desc->Usage = d3dusage_from_wined3dusage(wined3d_desc.usage); + desc->Usage = texture->usage; desc->Pool = d3dpool_from_wined3daccess(wined3d_desc.access, wined3d_desc.usage); desc->Width = wined3d_desc.width; desc->Height = wined3d_desc.height; @@ -1213,12 +1330,13 @@ HRESULT texture_init(struct d3d9_texture *texture, struct d3d9_device *device, texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_2d_vtbl; d3d9_resource_init(&texture->resource); list_init(&texture->rtv_list); + texture->usage = usage;
desc.resource_type = WINED3D_RTYPE_TEXTURE_2D; desc.format = wined3dformat_from_d3dformat(format); desc.multisample_type = WINED3D_MULTISAMPLE_NONE; desc.multisample_quality = 0; - desc.usage = usage & WINED3DUSAGE_MASK; + desc.usage = wined3dusage_from_d3dusage(usage); desc.usage |= WINED3DUSAGE_TEXTURE; if (pool == D3DPOOL_SCRATCH) desc.usage |= WINED3DUSAGE_SCRATCH; @@ -1234,13 +1352,28 @@ HRESULT texture_init(struct d3d9_texture *texture, struct d3d9_device *device, if (is_gdi_compat_wined3dformat(desc.format)) flags |= WINED3D_TEXTURE_CREATE_GET_DC;
- if (!levels) + if (usage & D3DUSAGE_AUTOGENMIPMAP) + { + if (pool == D3DPOOL_SYSTEMMEM) + { + WARN("D3DUSAGE_AUTOGENMIPMAP texture can't be in D3DPOOL_SYSTEMMEM, returning D3DERR_INVALIDCALL.\n"); + return D3DERR_INVALIDCALL; + } + if (levels && levels != 1) + { + WARN("D3DUSAGE_AUTOGENMIPMAP texture with %u levels, returning D3DERR_INVALIDCALL.\n", levels); + return D3DERR_INVALIDCALL; + } + flags |= WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS; + texture->autogen_filter_type = D3DTEXF_LINEAR; + levels = 0; + } + else { - if (usage & D3DUSAGE_AUTOGENMIPMAP) - levels = 1; - else - levels = wined3d_log2i(max(width, height)) + 1; + texture->autogen_filter_type = D3DTEXF_NONE; } + if (!levels) + levels = wined3d_log2i(max(width, height)) + 1;
wined3d_mutex_lock(); hr = wined3d_texture_create(device->wined3d_device, &desc, 1, levels, flags, @@ -1268,12 +1401,13 @@ HRESULT cubetexture_init(struct d3d9_texture *texture, struct d3d9_device *devic texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_cube_vtbl; d3d9_resource_init(&texture->resource); list_init(&texture->rtv_list); + texture->usage = usage;
desc.resource_type = WINED3D_RTYPE_TEXTURE_2D; desc.format = wined3dformat_from_d3dformat(format); desc.multisample_type = WINED3D_MULTISAMPLE_NONE; desc.multisample_quality = 0; - desc.usage = usage & WINED3DUSAGE_MASK; + desc.usage = wined3dusage_from_d3dusage(usage); desc.usage |= WINED3DUSAGE_LEGACY_CUBEMAP | WINED3DUSAGE_TEXTURE; if (pool == D3DPOOL_SCRATCH) desc.usage |= WINED3DUSAGE_SCRATCH; @@ -1289,13 +1423,28 @@ HRESULT cubetexture_init(struct d3d9_texture *texture, struct d3d9_device *devic if (is_gdi_compat_wined3dformat(desc.format)) flags |= WINED3D_TEXTURE_CREATE_GET_DC;
- if (!levels) + if (usage & D3DUSAGE_AUTOGENMIPMAP) { - if (usage & D3DUSAGE_AUTOGENMIPMAP) - levels = 1; - else - levels = wined3d_log2i(edge_length) + 1; + if (pool == D3DPOOL_SYSTEMMEM) + { + WARN("D3DUSAGE_AUTOGENMIPMAP texture can't be in D3DPOOL_SYSTEMMEM, returning D3DERR_INVALIDCALL.\n"); + return D3DERR_INVALIDCALL; + } + if (levels && levels != 1) + { + WARN("D3DUSAGE_AUTOGENMIPMAP texture with %u levels, returning D3DERR_INVALIDCALL.\n", levels); + return D3DERR_INVALIDCALL; + } + flags |= WINED3D_TEXTURE_CREATE_GENERATE_MIPMAPS; + texture->autogen_filter_type = D3DTEXF_LINEAR; + levels = 0; } + else + { + texture->autogen_filter_type = D3DTEXF_NONE; + } + if (!levels) + levels = wined3d_log2i(edge_length) + 1;
wined3d_mutex_lock(); hr = wined3d_texture_create(device->wined3d_device, &desc, 6, levels, flags, @@ -1322,12 +1471,13 @@ HRESULT volumetexture_init(struct d3d9_texture *texture, struct d3d9_device *dev texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_3d_vtbl; d3d9_resource_init(&texture->resource); list_init(&texture->rtv_list); + texture->usage = usage;
desc.resource_type = WINED3D_RTYPE_TEXTURE_3D; desc.format = wined3dformat_from_d3dformat(format); desc.multisample_type = WINED3D_MULTISAMPLE_NONE; desc.multisample_quality = 0; - desc.usage = usage & WINED3DUSAGE_MASK; + desc.usage = wined3dusage_from_d3dusage(usage); desc.usage |= WINED3DUSAGE_TEXTURE; if (pool == D3DPOOL_SCRATCH) desc.usage |= WINED3DUSAGE_SCRATCH; @@ -1337,13 +1487,13 @@ HRESULT volumetexture_init(struct d3d9_texture *texture, struct d3d9_device *dev desc.depth = depth; desc.size = 0;
- if (!levels) + if (usage & D3DUSAGE_AUTOGENMIPMAP) { - if (usage & D3DUSAGE_AUTOGENMIPMAP) - levels = 1; - else - levels = wined3d_log2i(max(max(width, height), depth)) + 1; + WARN("D3DUSAGE_AUTOGENMIPMAP volume texture is not supported, returning D3DERR_INVALIDCALL.\n"); + return D3DERR_INVALIDCALL; } + if (!levels) + levels = wined3d_log2i(max(max(width, height), depth)) + 1;
wined3d_mutex_lock(); hr = wined3d_texture_create(device->wined3d_device, &desc, 1, levels, 0,
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- It's a bit awkward to have this in a patch of its own but the alternatives I can think of don't look any better to me.
dlls/wined3d/directx.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-)
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index 000d0b75469..a2cc484727d 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -5287,7 +5287,7 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT ad const struct wined3d_gl_info *gl_info = &adapter->gl_info; const struct wined3d_format *adapter_format, *format; enum wined3d_gl_resource_type gl_type, gl_type_end; - BOOL mipmap_autogen_supported; + BOOL mipmap_gen_supported; DWORD format_flags = 0; DWORD allowed_usage;
@@ -5401,7 +5401,9 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT ad return WINED3DERR_NOTAVAILABLE; }
- mipmap_autogen_supported = gl_info->supported[SGIS_GENERATE_MIPMAP]; + mipmap_gen_supported = gl_info->supported[ARB_FRAMEBUFFER_OBJECT] + || gl_info->supported[EXT_FRAMEBUFFER_OBJECT]; + for (; gl_type <= gl_type_end; ++gl_type) { if ((format->flags[gl_type] & format_flags) != format_flags) @@ -5431,14 +5433,11 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT ad return WINED3DERR_NOTAVAILABLE; }
- if ((format->flags[gl_type] & (WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_FILTERING)) - != (WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_FILTERING)) - { - mipmap_autogen_supported = FALSE; - } + if (~format->flags[gl_type] & (WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_FILTERING)) + mipmap_gen_supported = FALSE; }
- if ((usage & WINED3DUSAGE_AUTOGENMIPMAP) && !mipmap_autogen_supported) + if ((usage & WINED3DUSAGE_AUTOGENMIPMAP) && !mipmap_gen_supported) { TRACE("No WINED3DUSAGE_AUTOGENMIPMAP support, returning WINED3DOK_NOAUTOGEN.\n"); return WINED3DOK_NOAUTOGEN; @@ -5613,7 +5612,7 @@ HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d, UINT adapte caps->Caps2 = WINED3DCAPS2_CANRENDERWINDOWED | WINED3DCAPS2_FULLSCREENGAMMA | WINED3DCAPS2_DYNAMICTEXTURES; - if (gl_info->supported[SGIS_GENERATE_MIPMAP]) + if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT] || gl_info->supported[EXT_FRAMEBUFFER_OBJECT]) caps->Caps2 |= WINED3DCAPS2_CANAUTOGENMIPMAP;
caps->Caps3 = WINED3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD |
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- dlls/d3d11/device.c | 2 +- dlls/d3d9/d3d9_private.h | 2 +- dlls/wined3d/directx.c | 13 ++++----- dlls/wined3d/resource.c | 1 - dlls/wined3d/texture.c | 60 ------------------------------------------ dlls/wined3d/utils.c | 2 +- dlls/wined3d/wined3d.spec | 2 -- dlls/wined3d/wined3d_gl.h | 2 -- dlls/wined3d/wined3d_private.h | 1 - include/wine/wined3d.h | 13 ++++----- 10 files changed, 13 insertions(+), 85 deletions(-)
diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c index b14c3862a1d..fb1aba42592 100644 --- a/dlls/d3d11/device.c +++ b/dlls/d3d11/device.c @@ -3225,7 +3225,7 @@ static HRESULT STDMETHODCALLTYPE d3d11_device_CheckFormatSupport(ID3D11Device *i { hr = wined3d_check_device_format(wined3d, params.adapter_idx, params.device_type, WINED3DFMT_UNKNOWN, flag_mapping[i].usage, flag_mapping[i].rtype, wined3d_format); - if (hr == WINED3DERR_NOTAVAILABLE || hr == WINED3DOK_NOAUTOGEN) + if (hr == WINED3DERR_NOTAVAILABLE || hr == WINED3DOK_NOMIPGEN) continue; if (hr != WINED3D_OK) { diff --git a/dlls/d3d9/d3d9_private.h b/dlls/d3d9/d3d9_private.h index ce76c71e029..72f89e1aab6 100644 --- a/dlls/d3d9/d3d9_private.h +++ b/dlls/d3d9/d3d9_private.h @@ -331,7 +331,7 @@ static inline unsigned int wined3daccess_from_d3dpool(D3DPOOL pool)
static inline DWORD wined3dusage_from_d3dusage(unsigned int usage) { - return usage & WINED3DUSAGE_MASK & ~WINED3DUSAGE_AUTOGENMIPMAP; + return usage & WINED3DUSAGE_MASK; }
#endif /* __WINE_D3D9_PRIVATE_H */ diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index a2cc484727d..b40f7c339e6 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -270,9 +270,6 @@ static const struct wined3d_extension_map gl_extension_map[] = {"GL_NV_vertex_program2", NV_VERTEX_PROGRAM2 }, {"GL_NV_vertex_program2_option", NV_VERTEX_PROGRAM2_OPTION }, {"GL_NV_vertex_program3", NV_VERTEX_PROGRAM3 }, - - /* SGI */ - {"GL_SGIS_generate_mipmap", SGIS_GENERATE_MIPMAP }, };
static const struct wined3d_extension_map wgl_extension_map[] = @@ -5329,12 +5326,12 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT ad gl_type = gl_type_end = WINED3D_GL_RES_TYPE_RB; break; } - allowed_usage |= WINED3DUSAGE_AUTOGENMIPMAP - | WINED3DUSAGE_DYNAMIC + allowed_usage |= WINED3DUSAGE_DYNAMIC | WINED3DUSAGE_LEGACY_CUBEMAP | WINED3DUSAGE_SOFTWAREPROCESSING | WINED3DUSAGE_TEXTURE | WINED3DUSAGE_QUERY_FILTER + | WINED3DUSAGE_QUERY_GENMIPMAP | WINED3DUSAGE_QUERY_LEGACYBUMPMAP | WINED3DUSAGE_QUERY_SRGBREAD | WINED3DUSAGE_QUERY_SRGBWRITE @@ -5437,10 +5434,10 @@ HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT ad mipmap_gen_supported = FALSE; }
- if ((usage & WINED3DUSAGE_AUTOGENMIPMAP) && !mipmap_gen_supported) + if ((usage & WINED3DUSAGE_QUERY_GENMIPMAP) && !mipmap_gen_supported) { TRACE("No WINED3DUSAGE_AUTOGENMIPMAP support, returning WINED3DOK_NOAUTOGEN.\n"); - return WINED3DOK_NOAUTOGEN; + return WINED3DOK_NOMIPGEN; }
return WINED3D_OK; @@ -5613,7 +5610,7 @@ HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d, UINT adapte WINED3DCAPS2_FULLSCREENGAMMA | WINED3DCAPS2_DYNAMICTEXTURES; if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT] || gl_info->supported[EXT_FRAMEBUFFER_OBJECT]) - caps->Caps2 |= WINED3DCAPS2_CANAUTOGENMIPMAP; + caps->Caps2 |= WINED3DCAPS2_CANGENMIPMAP;
caps->Caps3 = WINED3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD | WINED3DCAPS3_COPY_TO_VIDMEM | diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c index 61ff20679bd..64d9e26f89f 100644 --- a/dlls/wined3d/resource.c +++ b/dlls/wined3d/resource.c @@ -34,7 +34,6 @@ static void resource_check_usage(DWORD usage) | WINED3DUSAGE_DEPTHSTENCIL | WINED3DUSAGE_WRITEONLY | WINED3DUSAGE_DYNAMIC - | WINED3DUSAGE_AUTOGENMIPMAP | WINED3DUSAGE_STATICDECL | WINED3DUSAGE_OVERLAY | WINED3DUSAGE_SCRATCH diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index 6c8c313ee25..650a82ab3f2 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -375,7 +375,6 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc
texture->layer_count = layer_count; texture->level_count = level_count; - texture->filter_type = (desc->usage & WINED3DUSAGE_AUTOGENMIPMAP) ? WINED3D_TEXF_LINEAR : WINED3D_TEXF_NONE; texture->lod = 0; texture->flags |= WINED3D_TEXTURE_POW2_MAT_IDENT | WINED3D_TEXTURE_NORMALIZED_COORDS; if (flags & WINED3D_TEXTURE_CREATE_GET_DC_LENIENT) @@ -712,12 +711,6 @@ void wined3d_texture_bind(struct wined3d_texture *texture,
context_bind_texture(context, target, gl_tex->name);
- if (texture->resource.usage & WINED3DUSAGE_AUTOGENMIPMAP) - { - gl_info->gl_ops.gl.p_glTexParameteri(target, GL_GENERATE_MIPMAP_SGIS, GL_TRUE); - checkGLcall("glTexParameteri(target, GL_GENERATE_MIPMAP_SGIS, GL_TRUE)"); - } - /* For a new texture we have to set the texture levels after binding the * texture. Beware that texture rectangles do not support mipmapping, but * set the maxmiplevel if we're relying on the partial @@ -1161,29 +1154,6 @@ DWORD CDECL wined3d_texture_get_level_count(const struct wined3d_texture *textur return texture->level_count; }
-HRESULT CDECL wined3d_texture_set_autogen_filter_type(struct wined3d_texture *texture, - enum wined3d_texture_filter_type filter_type) -{ - FIXME("texture %p, filter_type %s stub!\n", texture, debug_d3dtexturefiltertype(filter_type)); - - if (!(texture->resource.usage & WINED3DUSAGE_AUTOGENMIPMAP)) - { - WARN("Texture doesn't have AUTOGENMIPMAP usage.\n"); - return WINED3DERR_INVALIDCALL; - } - - texture->filter_type = filter_type; - - return WINED3D_OK; -} - -enum wined3d_texture_filter_type CDECL wined3d_texture_get_autogen_filter_type(const struct wined3d_texture *texture) -{ - TRACE("texture %p.\n", texture); - - return texture->filter_type; -} - HRESULT CDECL wined3d_texture_set_color_key(struct wined3d_texture *texture, DWORD flags, const struct wined3d_color_key *color_key) { @@ -2144,21 +2114,6 @@ static HRESULT texture_init(struct wined3d_texture *texture, const struct wined3 TRACE("Creating an oversized (%ux%u) surface.\n", pow2_width, pow2_height); }
- /* Calculate levels for mip mapping. */ - if (desc->usage & WINED3DUSAGE_AUTOGENMIPMAP) - { - if (!gl_info->supported[SGIS_GENERATE_MIPMAP]) - { - WARN("No mipmap generation support, returning WINED3DERR_INVALIDCALL.\n"); - return WINED3DERR_INVALIDCALL; - } - - if (level_count != 1) - { - WARN("WINED3DUSAGE_AUTOGENMIPMAP is set, and level count != 1, returning WINED3DERR_INVALIDCALL.\n"); - return WINED3DERR_INVALIDCALL; - } - } if (flags & WINED3D_TEXTURE_GENERATE_MIPMAPS && !gl_info->supported[ARB_FRAMEBUFFER_OBJECT] && !gl_info->supported[EXT_FRAMEBUFFER_OBJECT]) { @@ -2592,21 +2547,6 @@ static HRESULT volumetexture_init(struct wined3d_texture *texture, const struct return WINED3DERR_INVALIDCALL; }
- /* Calculate levels for mip mapping. */ - if (desc->usage & WINED3DUSAGE_AUTOGENMIPMAP) - { - if (!gl_info->supported[SGIS_GENERATE_MIPMAP]) - { - WARN("No mipmap generation support, returning D3DERR_INVALIDCALL.\n"); - return WINED3DERR_INVALIDCALL; - } - - if (level_count != 1) - { - WARN("WINED3DUSAGE_AUTOGENMIPMAP is set, and level count != 1, returning D3DERR_INVALIDCALL.\n"); - return WINED3DERR_INVALIDCALL; - } - } if (flags & WINED3D_TEXTURE_GENERATE_MIPMAPS && !gl_info->supported[ARB_FRAMEBUFFER_OBJECT] && !gl_info->supported[EXT_FRAMEBUFFER_OBJECT]) { diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index a31baa43a71..c3fda3465a9 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -4160,7 +4160,6 @@ const char *debug_d3dusage(DWORD usage) WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES); WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES); WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC); - WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP); WINED3DUSAGE_TO_STR(WINED3DUSAGE_RESTRICTED_CONTENT); WINED3DUSAGE_TO_STR(WINED3DUSAGE_RESTRICT_SHARED_RESOURCE_DRIVER); WINED3DUSAGE_TO_STR(WINED3DUSAGE_RESTRICT_SHARED_RESOURCE); @@ -4184,6 +4183,7 @@ const char *debug_d3dusagequery(DWORD usagequery) buf[0] = '\0'; #define WINED3DUSAGEQUERY_TO_STR(u) if (usagequery & u) { strcat(buf, " | "#u); usagequery &= ~u; } WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER); + WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_GENMIPMAP); WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP); WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING); WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD); diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index 74e61eab39e..82ef8a1f054 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -288,7 +288,6 @@ @ cdecl wined3d_texture_create(ptr ptr long long long ptr ptr ptr ptr) @ cdecl wined3d_texture_decref(ptr) @ cdecl wined3d_texture_from_resource(ptr) -@ cdecl wined3d_texture_get_autogen_filter_type(ptr) @ cdecl wined3d_texture_get_dc(ptr long ptr) @ cdecl wined3d_texture_get_level_count(ptr) @ cdecl wined3d_texture_get_lod(ptr) @@ -300,7 +299,6 @@ @ cdecl wined3d_texture_get_sub_resource_parent(ptr long) @ cdecl wined3d_texture_incref(ptr) @ cdecl wined3d_texture_release_dc(ptr long ptr) -@ cdecl wined3d_texture_set_autogen_filter_type(ptr long) @ cdecl wined3d_texture_set_color_key(ptr long ptr) @ cdecl wined3d_texture_set_lod(ptr long) @ cdecl wined3d_texture_set_overlay_position(ptr long long long) diff --git a/dlls/wined3d/wined3d_gl.h b/dlls/wined3d/wined3d_gl.h index a3dee243595..cc6f8880256 100644 --- a/dlls/wined3d/wined3d_gl.h +++ b/dlls/wined3d/wined3d_gl.h @@ -199,8 +199,6 @@ enum wined3d_gl_extension NV_VERTEX_PROGRAM2, NV_VERTEX_PROGRAM2_OPTION, NV_VERTEX_PROGRAM3, - /* SGI */ - SGIS_GENERATE_MIPMAP, /* WGL extensions */ WGL_ARB_PIXEL_FORMAT, WGL_EXT_SWAP_CONTROL, diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 334724514df..76306d889f3 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -3101,7 +3101,6 @@ struct wined3d_texture unsigned int sysmem_count; float pow2_matrix[16]; UINT lod; - enum wined3d_texture_filter_type filter_type; DWORD sampler; DWORD flags; GLenum target; diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index 72168e5fa78..3a50c39cd67 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -36,7 +36,7 @@
#define _FACWINED3D 0x876 #define MAKE_WINED3DSTATUS(code) MAKE_HRESULT(0, _FACWINED3D, code) -#define WINED3DOK_NOAUTOGEN MAKE_WINED3DSTATUS(2159) +#define WINED3DOK_NOMIPGEN MAKE_WINED3DSTATUS(2159)
#define MAKE_WINED3DHRESULT(code) MAKE_HRESULT(1, _FACWINED3D, code) #define WINED3DERR_CONFLICTINGRENDERSTATE MAKE_WINED3DHRESULT(2081) @@ -891,13 +891,12 @@ enum wined3d_shader_byte_code_format #define WINED3DUSAGE_RTPATCHES 0x00000080 #define WINED3DUSAGE_NPATCHES 0x00000100 #define WINED3DUSAGE_DYNAMIC 0x00000200 -#define WINED3DUSAGE_AUTOGENMIPMAP 0x00000400 #define WINED3DUSAGE_RESTRICTED_CONTENT 0x00000800 #define WINED3DUSAGE_RESTRICT_SHARED_RESOURCE_DRIVER 0x00001000 #define WINED3DUSAGE_RESTRICT_SHARED_RESOURCE 0x00002000 #define WINED3DUSAGE_DMAP 0x00004000 #define WINED3DUSAGE_TEXTAPI 0x10000000 -#define WINED3DUSAGE_MASK 0x10007fff +#define WINED3DUSAGE_MASK 0x10007bff
#define WINED3DUSAGE_SCRATCH 0x00200000 #define WINED3DUSAGE_PRIVATE 0x00400000 @@ -907,6 +906,7 @@ enum wined3d_shader_byte_code_format #define WINED3DUSAGE_STATICDECL 0x04000000 #define WINED3DUSAGE_OVERLAY 0x08000000
+#define WINED3DUSAGE_QUERY_GENMIPMAP 0x00000400 #define WINED3DUSAGE_QUERY_LEGACYBUMPMAP 0x00008000 #define WINED3DUSAGE_QUERY_FILTER 0x00020000 #define WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING 0x00080000 @@ -914,7 +914,7 @@ enum wined3d_shader_byte_code_format #define WINED3DUSAGE_QUERY_SRGBWRITE 0x00040000 #define WINED3DUSAGE_QUERY_VERTEXTEXTURE 0x00100000 #define WINED3DUSAGE_QUERY_WRAPANDMIP 0x00200000 -#define WINED3DUSAGE_QUERY_MASK 0x003f8000 +#define WINED3DUSAGE_QUERY_MASK 0x003f8400
#define WINED3D_MAP_READONLY 0x0010 #define WINED3D_MAP_NOSYSLOCK 0x0800 @@ -1170,7 +1170,7 @@ enum wined3d_shader_byte_code_format #define WINED3DCAPS2_RESERVED 0x02000000 #define WINED3DCAPS2_CANMANAGERESOURCE 0x10000000 #define WINED3DCAPS2_DYNAMICTEXTURES 0x20000000 -#define WINED3DCAPS2_CANAUTOGENMIPMAP 0x40000000 +#define WINED3DCAPS2_CANGENMIPMAP 0x40000000
#define WINED3DPRASTERCAPS_DITHER 0x00000001 #define WINED3DPRASTERCAPS_ROP2 0x00000002 @@ -2668,7 +2668,6 @@ HRESULT __cdecl wined3d_texture_create(struct wined3d_device *device, const stru void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_texture **texture); struct wined3d_texture * __cdecl wined3d_texture_from_resource(struct wined3d_resource *resource); ULONG __cdecl wined3d_texture_decref(struct wined3d_texture *texture); -enum wined3d_texture_filter_type __cdecl wined3d_texture_get_autogen_filter_type(const struct wined3d_texture *texture); HRESULT __cdecl wined3d_texture_get_dc(struct wined3d_texture *texture, unsigned int sub_resource_idx, HDC *dc); DWORD __cdecl wined3d_texture_get_level_count(const struct wined3d_texture *texture); DWORD __cdecl wined3d_texture_get_lod(const struct wined3d_texture *texture); @@ -2683,8 +2682,6 @@ HRESULT __cdecl wined3d_texture_get_sub_resource_desc(const struct wined3d_textu void * __cdecl wined3d_texture_get_sub_resource_parent(struct wined3d_texture *texture, unsigned int sub_resource_idx); ULONG __cdecl wined3d_texture_incref(struct wined3d_texture *texture); HRESULT __cdecl wined3d_texture_release_dc(struct wined3d_texture *texture, unsigned int sub_resource_idx, HDC dc); -HRESULT __cdecl wined3d_texture_set_autogen_filter_type(struct wined3d_texture *texture, - enum wined3d_texture_filter_type filter_type); HRESULT __cdecl wined3d_texture_set_color_key(struct wined3d_texture *texture, DWORD flags, const struct wined3d_color_key *color_key); DWORD __cdecl wined3d_texture_set_lod(struct wined3d_texture *texture, DWORD lod);