Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- This is sort-of a partial revert of commit 6cfab2f7adf8d8a32b5fad6bf75f9859e6fa0b01. This time use a scheme similar to the one used by Henri for system memory buffers to avoid the issues with stateblocks solved by the original patch and, at the same time, restore some lost performance.
It might also help with moving the stateblock stuff to the client libraries but I'm happy to drop this patch if it turns out to be actually harmful in that regard.
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..9fffac86ff0 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,18 @@ 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 >= D3DVERTEXTEXTURESAMPLER0 ? stage - D3DVERTEXTEXTURESAMPLER0 + 16 : stage; + + 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 +2715,14 @@ 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 = ffs(map) - 1; + map ^= 1u << i; + 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..c681e95e277 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;