https://git.reactos.org/?p=reactos.git;a=commitdiff;h=b8714c31cd1f9235169341bee057ff4ef8fa7213

commit b8714c31cd1f9235169341bee057ff4ef8fa7213
Author:     winesync <[email protected]>
AuthorDate: Sat Jan 4 01:48:04 2020 +0100
Commit:     Jérôme Gardou <[email protected]>
CommitDate: Wed Feb 26 18:19:18 2020 +0100

    [WINESYNC]d3dx9: Use temporary surface in D3DXFillTexture() for unmappable 
textures.
    
    Fixes a regression triggered by commit 
949dbbd31f450178c90ea8267097a975b77c3219.
    
    Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=46453
    Signed-off-by: Paul Gofman <[email protected]>
    Signed-off-by: Matteo Bruni <[email protected]>
    Signed-off-by: Alexandre Julliard <[email protected]>
    
    wine commit id 4e44d74afb12b40f673e3be0a91cd523013544cd by Paul Gofman 
<[email protected]>
---
 dll/directx/wine/d3dx9_36/d3dx9_private.h     |   4 +
 dll/directx/wine/d3dx9_36/surface.c           |  47 ++++++++----
 dll/directx/wine/d3dx9_36/texture.c           |  28 +++++--
 modules/rostests/winetests/d3dx9_36/texture.c | 106 ++++++++++++++++++--------
 sdk/tools/winesync/d3dx9.cfg                  |   2 +-
 5 files changed, 135 insertions(+), 52 deletions(-)

diff --git a/dll/directx/wine/d3dx9_36/d3dx9_private.h 
b/dll/directx/wine/d3dx9_36/d3dx9_private.h
index 696b1859492..1c1613024dc 100644
--- a/dll/directx/wine/d3dx9_36/d3dx9_private.h
+++ b/dll/directx/wine/d3dx9_36/d3dx9_private.h
@@ -121,6 +121,10 @@ HRESULT load_volume_from_dds(IDirect3DVolume9 *dst_volume, 
const PALETTEENTRY *d
     const D3DXIMAGE_INFO *src_info) DECLSPEC_HIDDEN;
 HRESULT load_volume_texture_from_dds(IDirect3DVolumeTexture9 *volume_texture, 
const void *src_data,
     const PALETTEENTRY *palette, DWORD filter, DWORD color_key, const 
D3DXIMAGE_INFO *src_info) DECLSPEC_HIDDEN;
+HRESULT lock_surface(IDirect3DSurface9 *surface, D3DLOCKED_RECT *lock,
+        IDirect3DSurface9 **temp_surface, BOOL write) DECLSPEC_HIDDEN;
+HRESULT unlock_surface(IDirect3DSurface9 *surface, D3DLOCKED_RECT *lock,
+        IDirect3DSurface9 *temp_surface, BOOL update) DECLSPEC_HIDDEN;
 
 unsigned short float_32_to_16(const float in) DECLSPEC_HIDDEN;
 float float_16_to_32(const unsigned short in) DECLSPEC_HIDDEN;
diff --git a/dll/directx/wine/d3dx9_36/surface.c 
b/dll/directx/wine/d3dx9_36/surface.c
index 2d00cd1dcdc..a6eb5482f71 100644
--- a/dll/directx/wine/d3dx9_36/surface.c
+++ b/dll/directx/wine/d3dx9_36/surface.c
@@ -199,49 +199,70 @@ static const struct {
     { 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000, D3DFMT_X8B8G8R8 },
 };
 
-static HRESULT lock_surface(IDirect3DSurface9 *surface, D3DLOCKED_RECT *lock,
-        IDirect3DSurface9 **temp_surface)
+HRESULT lock_surface(IDirect3DSurface9 *surface, D3DLOCKED_RECT *lock,
+        IDirect3DSurface9 **temp_surface, BOOL write)
 {
     IDirect3DDevice9 *device;
     D3DSURFACE_DESC desc;
+    DWORD lock_flag;
     HRESULT hr;
 
+    lock_flag = write ? D3DLOCK_DISCARD : D3DLOCK_READONLY;
     *temp_surface = NULL;
-    if (FAILED(hr = IDirect3DSurface9_LockRect(surface, lock, NULL, 
D3DLOCK_READONLY)))
+    if (FAILED(hr = IDirect3DSurface9_LockRect(surface, lock, NULL, 
lock_flag)))
     {
         IDirect3DSurface9_GetDevice(surface, &device);
         IDirect3DSurface9_GetDesc(surface, &desc);
-        if (FAILED(hr = IDirect3DDevice9_CreateRenderTarget(device, 
desc.Width, desc.Height,
-                desc.Format, D3DMULTISAMPLE_NONE, 0, TRUE, temp_surface, 
NULL)))
+
+        hr = write ? IDirect3DDevice9_CreateOffscreenPlainSurface(device, 
desc.Width, desc.Height,
+                desc.Format, D3DPOOL_SYSTEMMEM, temp_surface, NULL)
+                : IDirect3DDevice9_CreateRenderTarget(device, desc.Width, 
desc.Height,
+                desc.Format, D3DMULTISAMPLE_NONE, 0, TRUE, temp_surface, NULL);
+        if (FAILED(hr))
         {
+            WARN("Failed to create temporary surface, surface %p, format %#x,"
+                    " usage %#x, pool %#x, write %#x, width %u, height %u.\n",
+                    surface, desc.Format, desc.Usage, desc.Pool, write, 
desc.Width, desc.Height);
             IDirect3DDevice9_Release(device);
             return hr;
         }
 
-        if (SUCCEEDED(hr = IDirect3DDevice9_StretchRect(device, surface, NULL, 
*temp_surface, NULL, D3DTEXF_NONE)))
-            hr = IDirect3DSurface9_LockRect(*temp_surface, lock, NULL, 
D3DLOCK_READONLY);
+        if (write || SUCCEEDED(hr = IDirect3DDevice9_StretchRect(device, 
surface, NULL,
+                *temp_surface, NULL, D3DTEXF_NONE)))
+            hr = IDirect3DSurface9_LockRect(*temp_surface, lock, NULL, 
lock_flag);
+
         IDirect3DDevice9_Release(device);
         if (FAILED(hr))
         {
-            WARN("Failed to lock surface %p, usage %#x, pool %#x.\n",
-                    surface, desc.Usage, desc.Pool);
+            WARN("Failed to lock surface %p, write %#x, usage %#x, pool 
%#x.\n",
+                    surface, write, desc.Usage, desc.Pool);
             IDirect3DSurface9_Release(*temp_surface);
             *temp_surface = NULL;
             return hr;
         }
+        TRACE("Created temporary surface %p.\n", surface);
     }
     return hr;
 }
 
-static HRESULT unlock_surface(IDirect3DSurface9 *surface, D3DLOCKED_RECT *lock,
-        IDirect3DSurface9 *temp_surface)
+HRESULT unlock_surface(IDirect3DSurface9 *surface, D3DLOCKED_RECT *lock,
+        IDirect3DSurface9 *temp_surface, BOOL update)
 {
+    IDirect3DDevice9 *device;
     HRESULT hr;
 
     if (!temp_surface)
         return IDirect3DSurface9_UnlockRect(surface);
 
     hr = IDirect3DSurface9_UnlockRect(temp_surface);
+    if (update)
+    {
+        IDirect3DSurface9_GetDevice(surface, &device);
+        if (FAILED(hr = IDirect3DDevice9_UpdateSurface(device, temp_surface, 
NULL, surface, NULL)))
+            WARN("Updating surface failed, hr %#x, surface %p, temp_surface 
%p.\n",
+                    hr, surface, temp_surface);
+        IDirect3DDevice9_Release(device);
+    }
     IDirect3DSurface9_Release(temp_surface);
     return hr;
 }
@@ -2026,13 +2047,13 @@ HRESULT WINAPI 
D3DXLoadSurfaceFromSurface(IDirect3DSurface9 *dst_surface,
         src_rect = &s;
     }
 
-    if (FAILED(lock_surface(src_surface, &lock, &temp_surface)))
+    if (FAILED(lock_surface(src_surface, &lock, &temp_surface, FALSE)))
         return D3DXERR_INVALIDDATA;
 
     hr = D3DXLoadSurfaceFromMemory(dst_surface, dst_palette, dst_rect, 
lock.pBits,
             src_desc.Format, lock.Pitch, src_palette, src_rect, filter, 
color_key);
 
-    if (FAILED(unlock_surface(src_surface, &lock, temp_surface)))
+    if (FAILED(unlock_surface(src_surface, &lock, temp_surface, FALSE)))
         return D3DXERR_INVALIDDATA;
 
     return hr;
diff --git a/dll/directx/wine/d3dx9_36/texture.c 
b/dll/directx/wine/d3dx9_36/texture.c
index 0f53d95bf1f..e2dfab84205 100644
--- a/dll/directx/wine/d3dx9_36/texture.c
+++ b/dll/directx/wine/d3dx9_36/texture.c
@@ -1323,6 +1323,7 @@ static inline void fill_texture(const struct 
pixel_format_desc *format, BYTE *po
 
 HRESULT WINAPI D3DXFillTexture(struct IDirect3DTexture9 *texture, LPD3DXFILL2D 
function, void *funcdata)
 {
+    IDirect3DSurface9 *surface, *temp_surface;
     DWORD miplevels;
     DWORD m, x, y;
     D3DSURFACE_DESC desc;
@@ -1331,26 +1332,34 @@ HRESULT WINAPI D3DXFillTexture(struct IDirect3DTexture9 
*texture, LPD3DXFILL2D f
     D3DXVECTOR2 coord, size;
     const struct pixel_format_desc *format;
     BYTE *data;
+    HRESULT hr;
 
-    if (texture == NULL || function == NULL)
+    TRACE("texture %p, function %p, funcdata %p.\n", texture, function, 
funcdata);
+
+    if (!texture || !function)
         return D3DERR_INVALIDCALL;
 
     miplevels = IDirect3DBaseTexture9_GetLevelCount(texture);
 
     for (m = 0; m < miplevels; m++)
     {
-        if (FAILED(IDirect3DTexture9_GetLevelDesc(texture, m, &desc)))
-            return D3DERR_INVALIDCALL;
+        if (FAILED(hr = IDirect3DTexture9_GetLevelDesc(texture, m, &desc)))
+            return hr;
 
         format = get_format_info(desc.Format);
         if (format->type != FORMAT_ARGB && format->type != FORMAT_ARGBF16 && 
format->type != FORMAT_ARGBF)
         {
-            FIXME("Unsupported texture format %#x\n", desc.Format);
+            FIXME("Unsupported texture format %#x.\n", desc.Format);
             return D3DERR_INVALIDCALL;
         }
 
-        if (FAILED(IDirect3DTexture9_LockRect(texture, m, &lock_rect, NULL, 
D3DLOCK_DISCARD)))
-            return D3DERR_INVALIDCALL;
+        if (FAILED(hr = IDirect3DTexture9_GetSurfaceLevel(texture, m, 
&surface)))
+            return hr;
+        if (FAILED(hr = lock_surface(surface, &lock_rect, &temp_surface, 
TRUE)))
+        {
+            IDirect3DSurface9_Release(surface);
+            return hr;
+        }
 
         size.x = 1.0f / desc.Width;
         size.y = 1.0f / desc.Height;
@@ -1372,7 +1381,12 @@ HRESULT WINAPI D3DXFillTexture(struct IDirect3DTexture9 
*texture, LPD3DXFILL2D f
                 fill_texture(format, data + y * lock_rect.Pitch + x * 
format->bytes_per_pixel, &value);
             }
         }
-        IDirect3DTexture9_UnlockRect(texture, m);
+        if (FAILED(hr = unlock_surface(surface, &lock_rect, temp_surface, 
TRUE)))
+        {
+            IDirect3DSurface9_Release(surface);
+            return hr;
+        }
+        IDirect3DSurface9_Release(surface);
     }
 
     return D3D_OK;
diff --git a/modules/rostests/winetests/d3dx9_36/texture.c 
b/modules/rostests/winetests/d3dx9_36/texture.c
index 79cddc73ab6..1a92a85b63e 100644
--- a/modules/rostests/winetests/d3dx9_36/texture.c
+++ b/modules/rostests/winetests/d3dx9_36/texture.c
@@ -1007,59 +1007,103 @@ static void WINAPI fillfunc(D3DXVECTOR4 *value, const 
D3DXVECTOR2 *texcoord,
 
 static void test_D3DXFillTexture(IDirect3DDevice9 *device)
 {
+    static const struct
+    {
+        DWORD usage;
+        D3DPOOL pool;
+    }
+    test_access_types[] =
+    {
+        {0,  D3DPOOL_MANAGED},
+        {0,  D3DPOOL_DEFAULT},
+        {D3DUSAGE_RENDERTARGET, D3DPOOL_DEFAULT},
+    };
+
     IDirect3DTexture9 *tex;
     HRESULT hr;
     D3DLOCKED_RECT lock_rect;
     DWORD x, y, m;
     DWORD v[4], e[4];
     DWORD value, expected, size, pitch;
+    unsigned int i;
 
-    size = 4;
-    hr = IDirect3DDevice9_CreateTexture(device, size, size, 0, 0, 
D3DFMT_A8R8G8B8,
-                                        D3DPOOL_MANAGED, &tex, NULL);
-
-    if (SUCCEEDED(hr))
+    for (i = 0; i < ARRAY_SIZE(test_access_types); ++i)
     {
+        size = 4;
+        hr = IDirect3DDevice9_CreateTexture(device, size, size, 0, 
test_access_types[i].usage,
+                D3DFMT_A8R8G8B8, test_access_types[i].pool, &tex, NULL);
+        ok(hr == D3D_OK, "Unexpected hr %#x, i %u.\n", hr, i);
+
         hr = D3DXFillTexture(tex, fillfunc, NULL);
-        ok(hr == D3D_OK, "D3DXFillTexture returned %#x, expected %#x\n", hr, 
D3D_OK);
+        ok(hr == D3D_OK, "Unexpected hr %#x, i %u.\n", hr, i);
 
         for (m = 0; m < 3; m++)
         {
-            hr = IDirect3DTexture9_LockRect(tex, m, &lock_rect, NULL, 
D3DLOCK_READONLY);
-            ok(hr == D3D_OK, "Couldn't lock the texture, error %#x\n", hr);
-            if (SUCCEEDED(hr))
+            IDirect3DSurface9 *src_surface, *temp_surface;
+
+            hr = IDirect3DTexture9_GetSurfaceLevel(tex, m, &src_surface);
+            ok(hr == D3D_OK, "Unexpected hr %#x, i %u, m %u.\n", hr, i, m);
+            temp_surface = src_surface;
+
+            if (FAILED(hr = IDirect3DSurface9_LockRect(src_surface, 
&lock_rect, NULL, D3DLOCK_READONLY)))
             {
-                pitch = lock_rect.Pitch / sizeof(DWORD);
-                for (y = 0; y < size; y++)
+                hr = IDirect3DDevice9_CreateRenderTarget(device, size, size,
+                        D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, 
&temp_surface, NULL);
+                ok(hr == D3D_OK, "Unexpected hr %#x, i %u, m %u.\n", hr, i, m);
+                hr = IDirect3DDevice9_StretchRect(device, src_surface, NULL, 
temp_surface, NULL, D3DTEXF_NONE);
+                ok(hr == D3D_OK, "Unexpected hr %#x, i %u, m %u.\n", hr, i, m);
+                hr = IDirect3DSurface9_LockRect(temp_surface, &lock_rect, 
NULL, D3DLOCK_READONLY);
+                ok(hr == D3D_OK, "Unexpected hr %#x, i %u, m %u.\n", hr, i, m);
+            }
+
+            pitch = lock_rect.Pitch / sizeof(DWORD);
+            for (y = 0; y < size; y++)
+            {
+                for (x = 0; x < size; x++)
                 {
-                    for (x = 0; x < size; x++)
-                    {
-                        value = ((DWORD *)lock_rect.pBits)[y * pitch + x];
-                        v[0] = (value >> 24) & 0xff;
-                        v[1] = (value >> 16) & 0xff;
-                        v[2] = (value >> 8) & 0xff;
-                        v[3] = value & 0xff;
-
-                        e[0] = 0xff;
-                        e[1] = (x + 0.5f) / size * 255.0f + 0.5f;
-                        e[2] = (y + 0.5f) / size * 255.0f + 0.5f;
-                        e[3] = 255.0f / size + 0.5f;
-                        expected = e[0] << 24 | e[1] << 16 | e[2] << 8 | e[3];
+                    value = ((DWORD *)lock_rect.pBits)[y * pitch + x];
+                    v[0] = (value >> 24) & 0xff;
+                    v[1] = (value >> 16) & 0xff;
+                    v[2] = (value >> 8) & 0xff;
+                    v[3] = value & 0xff;
+
+                    e[0] = 0xff;
+                    e[1] = (x + 0.5f) / size * 255.0f + 0.5f;
+                    e[2] = (y + 0.5f) / size * 255.0f + 0.5f;
+                    e[3] = 255.0f / size + 0.5f;
+                    expected = e[0] << 24 | e[1] << 16 | e[2] << 8 | e[3];
 
-                        ok(color_match(v, e),
-                           "Texel at (%u, %u) doesn't match: %#x, expected 
%#x\n",
-                           x, y, value, expected);
-                    }
+                    ok(color_match(v, e),
+                            "Texel at (%u, %u) doesn't match: %#x, expected 
%#x, i %u, m %u.\n",
+                            x, y, value, expected, i, m);
                 }
-                IDirect3DTexture9_UnlockRect(tex, m);
             }
+            IDirect3DSurface9_UnlockRect(temp_surface);
+            if (temp_surface != src_surface)
+                IDirect3DSurface9_Release(temp_surface);
+            IDirect3DSurface9_Release(src_surface);
             size >>= 1;
         }
+        IDirect3DTexture9_Release(tex);
+    }
+
+    hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 
D3DUSAGE_DEPTHSTENCIL,
+            D3DFMT_D16_LOCKABLE, D3DPOOL_DEFAULT, &tex, NULL);
+    if (hr == D3D_OK)
+    {
+        hr = D3DXFillTexture(tex, fillfunc, NULL);
+        todo_wine ok(hr == D3D_OK, "Unexpected hr %#x.\n", hr);
+        IDirect3DTexture9_Release(tex);
+    }
 
+    hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 
D3DUSAGE_DEPTHSTENCIL,
+            D3DFMT_D16, D3DPOOL_DEFAULT, &tex, NULL);
+    if (hr == D3D_OK)
+    {
+        hr = D3DXFillTexture(tex, fillfunc, NULL);
+        ok(hr == D3DERR_INVALIDCALL, "Unexpected hr %#x.\n", hr);
         IDirect3DTexture9_Release(tex);
     }
-    else
-        skip("Failed to create texture\n");
 
     hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_A1R5G5B5,
                                         D3DPOOL_MANAGED, &tex, NULL);
diff --git a/sdk/tools/winesync/d3dx9.cfg b/sdk/tools/winesync/d3dx9.cfg
index ff99278963a..8bc93affa53 100644
--- a/sdk/tools/winesync/d3dx9.cfg
+++ b/sdk/tools/winesync/d3dx9.cfg
@@ -33,4 +33,4 @@ files:
   include/d3dx9shape.h: sdk/include/dxsdk/d3dx9shape.h
   include/d3dx9tex.h: sdk/include/dxsdk/d3dx9tex.h
 tags:
-  wine: 33be8439fc95ca8f005bd3a2b6790c101842c02e
+  wine: 4e44d74afb12b40f673e3be0a91cd523013544cd

Reply via email to