[PATCH v2 1/3] d3d9: Keep track of D3DUSAGE_AUTOGENMIPMAP textures in the d3d9 device.

Matteo Bruni mbruni at codeweavers.com
Mon Feb 4 17:59:44 CST 2019


Signed-off-by: Matteo Bruni <mbruni at 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;
-- 
2.19.2




More information about the wine-devel mailing list