Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- v2: Fix patch according to Józef's review.
Supersedes patch 157672.
dlls/d3d9/d3d9_private.h | 2 ++ dlls/d3d9/device.c | 23 +++++++++++++++++++++-- dlls/d3d9/stateblock.c | 16 +++++++++++++++- 3 files changed, 38 insertions(+), 3 deletions(-)
diff --git a/dlls/d3d9/d3d9_private.h b/dlls/d3d9/d3d9_private.h index 1032f8e8e9c..3fe0376e5c1 100644 --- a/dlls/d3d9/d3d9_private.h +++ b/dlls/d3d9/d3d9_private.h @@ -111,6 +111,8 @@ struct d3d9_device DWORD recording : 1; DWORD padding : 11;
+ DWORD auto_mipmaps; /* D3D9_MAX_TEXTURE_UNITS */ + unsigned int max_user_clip_planes;
UINT implicit_swapchain_count; diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c index 98ada03af8b..66bf69589ca 100644 --- a/dlls/d3d9/device.c +++ b/dlls/d3d9/device.c @@ -1012,6 +1012,9 @@ static HRESULT d3d9_device_reset(struct d3d9_device *device, device->device_state = D3D9_DEVICE_STATE_OK; }
+ if (!device->d3d_parent->extended) + device->auto_mipmaps = 0; + 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) @@ -2456,6 +2459,19 @@ 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) && !device->recording) + { + unsigned int i = stage < 16 || (stage >= D3DVERTEXTEXTURESAMPLER0 && stage <= D3DVERTEXTEXTURESAMPLER3) + ? stage < 16 ? stage : stage - D3DVERTEXTEXTURESAMPLER0 + 16 : ~0u; + + if (i < D3D9_MAX_TEXTURE_UNITS) + { + if (texture_impl && texture_impl->usage & D3DUSAGE_AUTOGENMIPMAP) + device->auto_mipmaps |= 1u << i; + else + device->auto_mipmaps &= ~(1u << i); + } + } wined3d_mutex_unlock();
return hr; @@ -2700,10 +2716,13 @@ static float WINAPI d3d9_device_GetNPatchMode(IDirect3DDevice9Ex *iface) static void d3d9_generate_auto_mipmaps(struct d3d9_device *device) { struct wined3d_texture *texture; - unsigned int i, stage; + unsigned int i, stage, map;
- for (i = 0; i < D3D9_MAX_TEXTURE_UNITS; ++i) + map = device->auto_mipmaps; + while (map) { + i = wined3d_bit_scan(&map); + stage = i >= 16 ? i - 16 + D3DVERTEXTEXTURESAMPLER0 : i; if ((texture = wined3d_device_get_texture(device->wined3d_device, stage))) d3d9_texture_gen_auto_mipmap(wined3d_texture_get_parent(texture)); diff --git a/dlls/d3d9/stateblock.c b/dlls/d3d9/stateblock.c index 8431ef77002..14f47d929bc 100644 --- a/dlls/d3d9/stateblock.c +++ b/dlls/d3d9/stateblock.c @@ -109,10 +109,12 @@ static HRESULT WINAPI d3d9_stateblock_Capture(IDirect3DStateBlock9 *iface) static HRESULT WINAPI d3d9_stateblock_Apply(IDirect3DStateBlock9 *iface) { struct d3d9_stateblock *stateblock = impl_from_IDirect3DStateBlock9(iface); + struct wined3d_texture *wined3d_texture; + unsigned int i, offset, stride, stage; struct wined3d_buffer *wined3d_buffer; struct d3d9_vertexbuffer *buffer; - unsigned int i, offset, stride; enum wined3d_format_id format; + struct d3d9_texture *texture; struct d3d9_device *device; HRESULT hr;
@@ -134,6 +136,18 @@ static HRESULT WINAPI d3d9_stateblock_Apply(IDirect3DStateBlock9 *iface) } device->sysmem_ib = (wined3d_buffer = wined3d_device_get_index_buffer(device->wined3d_device, &format, &offset)) && (buffer = wined3d_buffer_get_parent(wined3d_buffer)) && buffer->draw_buffer; + device->auto_mipmaps = 0; + for (i = 0; i < D3D9_MAX_TEXTURE_UNITS; ++i) + { + stage = i >= 16 ? i - 16 + D3DVERTEXTEXTURESAMPLER0 : i; + + if ((wined3d_texture = wined3d_device_get_texture(device->wined3d_device, stage)) + && (texture = wined3d_texture_get_parent(wined3d_texture)) + && texture->usage & D3DUSAGE_AUTOGENMIPMAP) + device->auto_mipmaps |= 1u << i; + else + device->auto_mipmaps &= ~(1u << i); + } wined3d_mutex_unlock();
return D3D_OK;