1 /*
2  * Tests for the D3DX9 texture functions
3  *
4  * Copyright 2009 Tony Wasserka
5  * Copyright 2010 Owen Rudge for CodeWeavers
6  * Copyright 2010 Matteo Bruni for CodeWeavers
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21  */
22 
23 #define COBJMACROS
24 #include "wine/test.h"
25 #include "d3dx9tex.h"
26 #include "resources.h"
27 
28 static int has_2d_dxt1, has_2d_dxt3, has_2d_dxt5, has_cube_dxt5, has_3d_dxt3;
29 
30 /* 2x2 16-bit dds, no mipmaps */
31 static const unsigned char dds_16bit[] = {
32 0x44,0x44,0x53,0x20,0x7c,0x00,0x00,0x00,0x07,0x10,0x08,0x00,0x02,0x00,0x00,0x00,
33 0x02,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
34 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
35 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
36 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,
37 0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x7c,0x00,0x00,
38 0xe0,0x03,0x00,0x00,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,
39 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
40 0xff,0x7f,0xff,0x7f,0xff,0x7f,0xff,0x7f
41 };
42 
43 /* 2x2 24-bit dds, 2 mipmaps */
44 static const unsigned char dds_24bit[] = {
45 0x44,0x44,0x53,0x20,0x7c,0x00,0x00,0x00,0x07,0x10,0x0a,0x00,0x02,0x00,0x00,0x00,
46 0x02,0x00,0x00,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,
47 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
48 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
49 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,
50 0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0xff,0x00,
51 0x00,0xff,0x00,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0x40,0x00,
52 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
53 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
54 };
55 
56 /* 4x4 cube map dds */
57 static const unsigned char dds_cube_map[] = {
58 0x44,0x44,0x53,0x20,0x7c,0x00,0x00,0x00,0x07,0x10,0x08,0x00,0x04,0x00,0x00,0x00,
59 0x04,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
60 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
61 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
62 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,
63 0x04,0x00,0x00,0x00,0x44,0x58,0x54,0x35,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
64 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0x00,0x00,
65 0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
66 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x50,
67 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x51,
68 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x52,
69 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x53,
70 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x54,
71 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x55
72 };
73 
74 /* 4x4x2 volume map dds, 2 mipmaps */
75 static const unsigned char dds_volume_map[] = {
76 0x44,0x44,0x53,0x20,0x7c,0x00,0x00,0x00,0x07,0x10,0x8a,0x00,0x04,0x00,0x00,0x00,
77 0x04,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
78 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
79 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
80 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,
81 0x04,0x00,0x00,0x00,0x44,0x58,0x54,0x33,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
82 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0x40,0x00,
83 0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
84 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x50,
85 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x50,
86 0xff,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x2f,0x7e,0xcf,0x79,0x01,0x54,0x5c,0x5c,
87 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x84,0xef,0x7b,0xaa,0xab,0xab,0xab
88 };
89 
90 /* 4x2 dxt5 */
91 static const BYTE dds_dxt5[] =
92 {
93     0x44,0x44,0x53,0x20,0x7c,0x00,0x00,0x00,0x07,0x10,0x08,0x00,0x02,0x00,0x00,0x00,
94     0x04,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
95     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
96     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
97     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,
98     0x04,0x00,0x00,0x00,0x44,0x58,0x54,0x35,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
99     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0x00,0x00,
100     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
101     0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xef,0x87,0x0f,0x78,0x05,0x05,0x50,0x50,
102 };
103 
104 static const BYTE dds_dxt5_8_8[] =
105 {
106     0x44,0x44,0x53,0x20,0x7c,0x00,0x00,0x00,0x07,0x10,0x08,0x00,0x08,0x00,0x00,0x00,
107     0x08,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
108     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
109     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
110     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,
111     0x04,0x00,0x00,0x00,0x44,0x58,0x54,0x35,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
112     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x10,0x00,0x00,
113     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
114     0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0x00,0xe0,0x07,0x05,0x05,0x50,0x50,
115     0x3f,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0xff,0x07,0x05,0x05,0x50,0x50,
116     0x7f,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0xf8,0xe0,0xff,0x05,0x05,0x50,0x50,
117     0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x00,0x00,0x05,0x05,0x50,0x50,
118 };
119 
120 static const unsigned char png_grayscale[] =
121 {
122     0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49,
123     0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00,
124     0x00, 0x00, 0x00, 0x3a, 0x7e, 0x9b, 0x55, 0x00, 0x00, 0x00, 0x0a, 0x49, 0x44,
125     0x41, 0x54, 0x08, 0xd7, 0x63, 0xf8, 0x0f, 0x00, 0x01, 0x01, 0x01, 0x00, 0x1b,
126     0xb6, 0xee, 0x56, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42,
127     0x60, 0x82
128 };
129 
130 #define ADMITTED_ERROR 0.0001f
131 
relative_error(float expected,float got)132 static inline float relative_error(float expected, float got)
133 {
134     return expected == 0.0f ? fabs(expected - got) : fabs(1.0f - got / expected);
135 }
136 
137 #define expect_vec4(expected, got) expect_vec4_(__LINE__, expected, got)
expect_vec4_(unsigned int line,const D3DXVECTOR4 * expected,const D3DXVECTOR4 * got)138 static inline void expect_vec4_(unsigned int line, const D3DXVECTOR4 *expected, const D3DXVECTOR4 *got)
139 {
140     ok_(__FILE__, line)(relative_error(expected->x, got->x) < ADMITTED_ERROR
141         && relative_error(expected->y, got->y) < ADMITTED_ERROR
142         && relative_error(expected->z, got->z) < ADMITTED_ERROR
143         && relative_error(expected->w, got->w) < ADMITTED_ERROR,
144         "Expected (%f, %f, %f, %f), got (%f, %f, %f, %f)\n",
145         expected->x, expected->y, expected->z, expected->w,
146         got->x, got->y, got->z, got->w);
147 }
148 
compare_uint(unsigned int x,unsigned int y,unsigned int max_diff)149 static BOOL compare_uint(unsigned int x, unsigned int y, unsigned int max_diff)
150 {
151     unsigned int diff = x > y ? x - y : y - x;
152 
153     return diff <= max_diff;
154 }
155 
compare_color(DWORD c1,DWORD c2,BYTE max_diff)156 static BOOL compare_color(DWORD c1, DWORD c2, BYTE max_diff)
157 {
158     return compare_uint(c1 & 0xff, c2 & 0xff, max_diff)
159             && compare_uint((c1 >> 8) & 0xff, (c2 >> 8) & 0xff, max_diff)
160             && compare_uint((c1 >> 16) & 0xff, (c2 >> 16) & 0xff, max_diff)
161             && compare_uint((c1 >> 24) & 0xff, (c2 >> 24) & 0xff, max_diff);
162 }
163 
is_autogenmipmap_supported(IDirect3DDevice9 * device,D3DRESOURCETYPE resource_type)164 static BOOL is_autogenmipmap_supported(IDirect3DDevice9 *device, D3DRESOURCETYPE resource_type)
165 {
166     HRESULT hr;
167     D3DCAPS9 caps;
168     IDirect3D9 *d3d9;
169     D3DDISPLAYMODE mode;
170     D3DDEVICE_CREATION_PARAMETERS params;
171 
172     IDirect3DDevice9_GetDeviceCaps(device, &caps);
173     IDirect3DDevice9_GetDirect3D(device, &d3d9);
174     IDirect3DDevice9_GetCreationParameters(device, &params);
175     IDirect3DDevice9_GetDisplayMode(device, 0, &mode);
176 
177     if (!(caps.Caps2 & D3DCAPS2_CANAUTOGENMIPMAP))
178         return FALSE;
179 
180     hr = IDirect3D9_CheckDeviceFormat(d3d9, params.AdapterOrdinal, params.DeviceType,
181         mode.Format, D3DUSAGE_AUTOGENMIPMAP, resource_type, D3DFMT_A8R8G8B8);
182 
183     IDirect3D9_Release(d3d9);
184     return hr == D3D_OK;
185 }
186 
test_D3DXCheckTextureRequirements(IDirect3DDevice9 * device)187 static void test_D3DXCheckTextureRequirements(IDirect3DDevice9 *device)
188 {
189     UINT width, height, mipmaps;
190     D3DFORMAT format, expected;
191     D3DCAPS9 caps;
192     HRESULT hr;
193     IDirect3D9 *d3d;
194     D3DDEVICE_CREATION_PARAMETERS params;
195     D3DDISPLAYMODE mode;
196 
197     IDirect3DDevice9_GetDeviceCaps(device, &caps);
198 
199     /* general tests */
200     hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
201     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
202 
203     hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, D3DX_DEFAULT, NULL, D3DPOOL_DEFAULT);
204     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
205 
206     hr = D3DXCheckTextureRequirements(NULL, NULL, NULL, NULL, D3DX_DEFAULT, NULL, D3DPOOL_DEFAULT);
207     ok(hr == D3DERR_INVALIDCALL, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
208 
209     /* width & height */
210     width = height = D3DX_DEFAULT;
211     hr = D3DXCheckTextureRequirements(device, &width, &height, NULL, 0, NULL, D3DPOOL_DEFAULT);
212     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
213     ok(width == 256, "Returned width %d, expected %d\n", width, 256);
214     ok(height == 256, "Returned height %d, expected %d\n", height, 256);
215 
216     width = D3DX_DEFAULT;
217     hr = D3DXCheckTextureRequirements(device, &width, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
218     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
219     ok(width == 256, "Returned width %d, expected %d\n", width, 256);
220 
221     if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
222         skip("Hardware only supports pow2 textures\n");
223     else
224     {
225         width = 62;
226         hr = D3DXCheckTextureRequirements(device, &width, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
227         ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
228         ok(width == 62, "Returned width %d, expected %d\n", width, 62);
229 
230         width = D3DX_DEFAULT; height = 63;
231         hr = D3DXCheckTextureRequirements(device, &width, &height, NULL, 0, NULL, D3DPOOL_DEFAULT);
232         ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
233         ok(width == height, "Returned width %d, expected %d\n", width, height);
234         ok(height == 63, "Returned height %d, expected %d\n", height, 63);
235     }
236 
237     width = D3DX_DEFAULT; height = 0;
238     hr = D3DXCheckTextureRequirements(device, &width, &height, NULL, 0, NULL, D3DPOOL_DEFAULT);
239     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
240     ok(width == 1, "Returned width %d, expected %d\n", width, 1);
241     ok(height == 1, "Returned height %d, expected %d\n", height, 1);
242 
243     width = 0; height = 0;
244     hr = D3DXCheckTextureRequirements(device, &width, &height, NULL, 0, NULL, D3DPOOL_DEFAULT);
245     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
246     ok(width == 1, "Returned width %d, expected %d\n", width, 1);
247     ok(height == 1, "Returned height %d, expected %d\n", height, 1);
248 
249     width = 0;
250     hr = D3DXCheckTextureRequirements(device, &width, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
251     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
252     ok(width == 1, "Returned width %d, expected %d\n", width, 1);
253 
254     width = 0xFFFFFFFE;
255     hr = D3DXCheckTextureRequirements(device, &width, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
256     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
257     ok(width == caps.MaxTextureWidth, "Returned width %d, expected %d\n", width, caps.MaxTextureWidth);
258 
259     width = caps.MaxTextureWidth-1;
260     hr = D3DXCheckTextureRequirements(device, &width, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
261     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
262     if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
263         ok(width == caps.MaxTextureWidth, "Returned width %d, expected %d\n", width, caps.MaxTextureWidth);
264     else
265         ok(width == caps.MaxTextureWidth-1, "Returned width %d, expected %d\n", width, caps.MaxTextureWidth-1);
266 
267     /* mipmaps */
268     width = 64; height = 63;
269     mipmaps = 9;
270     hr = D3DXCheckTextureRequirements(device, &width, &height, &mipmaps, 0, NULL, D3DPOOL_DEFAULT);
271     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
272     ok(mipmaps == 7, "Returned mipmaps %d, expected %d\n", mipmaps, 7);
273 
274     if (!(caps.TextureCaps & D3DPTEXTURECAPS_POW2))
275     {
276         width = 284; height = 137;
277         mipmaps = 20;
278         hr = D3DXCheckTextureRequirements(device, &width, &height, &mipmaps, 0, NULL, D3DPOOL_DEFAULT);
279         ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
280         ok(mipmaps == 9, "Returned mipmaps %d, expected %d\n", mipmaps, 9);
281 
282         width = height = 63;
283         mipmaps = 9;
284         hr = D3DXCheckTextureRequirements(device, &width, &height, &mipmaps, 0, NULL, D3DPOOL_DEFAULT);
285         ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
286         ok(mipmaps == 6, "Returned mipmaps %d, expected %d\n", mipmaps, 6);
287     }
288     else
289         skip("Skipping some tests, npot2 textures unsupported\n");
290 
291     mipmaps = 20;
292     hr = D3DXCheckTextureRequirements(device, NULL, NULL, &mipmaps, 0, NULL, D3DPOOL_DEFAULT);
293     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
294     ok(mipmaps == 9, "Returned mipmaps %d, expected %d\n", mipmaps, 9);
295 
296     mipmaps = 0;
297     hr = D3DXCheckTextureRequirements(device, NULL, NULL, &mipmaps, 0, NULL, D3DPOOL_DEFAULT);
298     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
299     ok(mipmaps == 9, "Returned mipmaps %d, expected %d\n", mipmaps, 9);
300 
301     /* mipmaps when D3DUSAGE_AUTOGENMIPMAP is set */
302     if (is_autogenmipmap_supported(device, D3DRTYPE_TEXTURE))
303     {
304         mipmaps = 0;
305         hr = D3DXCheckTextureRequirements(device, NULL, NULL, &mipmaps, D3DUSAGE_AUTOGENMIPMAP, NULL, D3DPOOL_DEFAULT);
306         ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
307         ok(mipmaps == 0, "Returned mipmaps %d, expected %d\n", mipmaps, 0);
308         mipmaps = 1;
309         hr = D3DXCheckTextureRequirements(device, NULL, NULL, &mipmaps, D3DUSAGE_AUTOGENMIPMAP, NULL, D3DPOOL_DEFAULT);
310         ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
311         ok(mipmaps == 1, "Returned mipmaps %d, expected %d\n", mipmaps, 1);
312         mipmaps = 2;
313         hr = D3DXCheckTextureRequirements(device, NULL, NULL, &mipmaps, D3DUSAGE_AUTOGENMIPMAP, NULL, D3DPOOL_DEFAULT);
314         ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
315         ok(mipmaps == 0, "Returned mipmaps %d, expected %d\n", mipmaps, 0);
316         mipmaps = 6;
317         hr = D3DXCheckTextureRequirements(device, NULL, NULL, &mipmaps, D3DUSAGE_AUTOGENMIPMAP, NULL, D3DPOOL_DEFAULT);
318         ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
319         ok(mipmaps == 0, "Returned mipmaps %d, expected %d\n", mipmaps, 0);
320     }
321     else
322         skip("No D3DUSAGE_AUTOGENMIPMAP support for textures\n");
323 
324     /* usage */
325     hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, D3DUSAGE_WRITEONLY, NULL, D3DPOOL_DEFAULT);
326     ok(hr == D3DERR_INVALIDCALL, "D3DXCheckTextureRequirements succeeded, but should've failed.\n");
327     hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, D3DUSAGE_DONOTCLIP, NULL, D3DPOOL_DEFAULT);
328     ok(hr == D3DERR_INVALIDCALL, "D3DXCheckTextureRequirements succeeded, but should've failed.\n");
329     hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, D3DUSAGE_POINTS, NULL, D3DPOOL_DEFAULT);
330     ok(hr == D3DERR_INVALIDCALL, "D3DXCheckTextureRequirements succeeded, but should've failed.\n");
331     hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, D3DUSAGE_RTPATCHES, NULL, D3DPOOL_DEFAULT);
332     ok(hr == D3DERR_INVALIDCALL, "D3DXCheckTextureRequirements succeeded, but should've failed.\n");
333     hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, D3DUSAGE_NPATCHES, NULL, D3DPOOL_DEFAULT);
334     ok(hr == D3DERR_INVALIDCALL, "D3DXCheckTextureRequirements succeeded, but should've failed.\n");
335 
336     /* format */
337     hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
338     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
339 
340     format = D3DFMT_UNKNOWN;
341     hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
342     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
343     ok(format == D3DFMT_A8R8G8B8, "Returned format %u, expected %u\n", format, D3DFMT_A8R8G8B8);
344 
345     format = D3DX_DEFAULT;
346     hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
347     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
348     ok(format == D3DFMT_A8R8G8B8, "Returned format %u, expected %u\n", format, D3DFMT_A8R8G8B8);
349 
350     format = D3DFMT_R8G8B8;
351     hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
352     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
353     ok(format == D3DFMT_X8R8G8B8, "Returned format %u, expected %u\n", format, D3DFMT_X8R8G8B8);
354 
355     IDirect3DDevice9_GetDirect3D(device, &d3d);
356     IDirect3DDevice9_GetCreationParameters(device, &params);
357     IDirect3DDevice9_GetDisplayMode(device, 0, &mode);
358 
359     if (SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, params.AdapterOrdinal, params.DeviceType,
360                                                mode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_R3G3B2)))
361         expected = D3DFMT_R3G3B2;
362     else if (SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, params.AdapterOrdinal, params.DeviceType,
363                                                     mode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_X4R4G4B4)))
364         expected = D3DFMT_X4R4G4B4;
365     else if (SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, params.AdapterOrdinal, params.DeviceType,
366                                                     mode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_X1R5G5B5)))
367         expected = D3DFMT_X1R5G5B5;
368     else
369         expected = D3DFMT_R5G6B5;
370 
371     format = D3DFMT_R3G3B2;
372     hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
373     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
374     ok(format == expected, "Returned format %u, expected %u\n", format, expected);
375 
376     if(SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, params.AdapterOrdinal, params.DeviceType,
377                                               mode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_A8R3G3B2)))
378         expected = D3DFMT_A8R3G3B2;
379     else
380         expected = D3DFMT_A8R8G8B8;
381 
382     format = D3DFMT_A8R3G3B2;
383     hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
384     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
385     ok(format == expected, "Returned format %u, expected %u\n", format, expected);
386 
387     if(SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, params.AdapterOrdinal, params.DeviceType,
388                                               mode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_P8)))
389         expected = D3DFMT_P8;
390     else
391         expected = D3DFMT_A8R8G8B8;
392 
393     format = D3DFMT_P8;
394     hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
395     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
396     ok(format == expected, "Returned format %u, expected %u\n", format, expected);
397 
398     if(SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, params.AdapterOrdinal, params.DeviceType,
399             mode.Format, D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, D3DFMT_L8)))
400         expected = D3DFMT_L8;
401     else
402         expected = D3DFMT_X8R8G8B8;
403 
404     format = D3DFMT_L8;
405     hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, D3DUSAGE_RENDERTARGET, &format, D3DPOOL_DEFAULT);
406     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
407     ok(format == expected, "Returned format %u, expected %u\n", format, expected);
408 
409     if(SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, params.AdapterOrdinal, params.DeviceType,
410             mode.Format, D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, D3DFMT_L16)))
411         expected = D3DFMT_L16;
412     else
413         expected = D3DFMT_A16B16G16R16;
414 
415     format = D3DFMT_L16;
416     hr = D3DXCheckTextureRequirements(device, NULL, NULL, NULL, D3DUSAGE_RENDERTARGET, &format, D3DPOOL_DEFAULT);
417     ok(hr == D3D_OK, "D3DXCheckTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
418     ok(format == expected, "Returned format %u, expected %u\n", format, expected);
419 
420     /* Block-based texture formats and size < block size. */
421     format = D3DFMT_DXT1;
422     width = 2; height = 2;
423     mipmaps = 1;
424     hr = D3DXCheckTextureRequirements(device, &width, &height, &mipmaps, 0, &format, D3DPOOL_DEFAULT);
425     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
426     ok(mipmaps == 1, "Got unexpected level count %u.\n", mipmaps);
427     if (has_2d_dxt1)
428     {
429         ok(width == 4, "Got unexpected width %d.\n", width);
430         ok(height == 4, "Got unexpected height %d.\n", height);
431         ok(format == D3DFMT_DXT1, "Got unexpected format %u.\n", format);
432     }
433     else
434     {
435         ok(width == 2, "Got unexpected width %d.\n", width);
436         ok(height == 2, "Got unexpected height %d.\n", height);
437         ok(format == D3DFMT_A8R8G8B8, "Got unexpected format %u.\n", format);
438     }
439 
440     format = D3DFMT_DXT5;
441     width = 2; height = 2;
442     hr = D3DXCheckTextureRequirements(device, &width, &height, &mipmaps, 0, &format, D3DPOOL_DEFAULT);
443     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
444     ok(mipmaps == 1, "Got unexpected level count %u.\n", mipmaps);
445     if (has_2d_dxt5)
446     {
447         ok(width == 4, "Got unexpected width %d.\n", width);
448         ok(height == 4, "Got unexpected height %d.\n", height);
449         ok(format == D3DFMT_DXT5, "Got unexpected format %u.\n", format);
450 
451         width = 9;
452         height = 9;
453         hr = D3DXCheckTextureRequirements(device, &width, &height, &mipmaps, 0, &format, D3DPOOL_DEFAULT);
454         ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
455         ok(width == 12, "Got unexpected width %u.\n", width);
456         ok(height == 12, "Got unexpected height %u.\n", height);
457         ok(mipmaps == 1, "Got unexpected level count %u.\n", mipmaps);
458         ok(format == D3DFMT_DXT5, "Got unexpected format %u.\n", format);
459     }
460     else
461     {
462         ok(width == 2, "Got unexpected width %d.\n", width);
463         ok(height == 2, "Got unexpected height %d.\n", height);
464         ok(format == D3DFMT_A8R8G8B8, "Got unexpected format %u.\n", format);
465     }
466     width = 4;
467     height = 2;
468     hr = D3DXCheckTextureRequirements(device, &width, &height, &mipmaps, 0, &format, D3DPOOL_DEFAULT);
469     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
470     ok(width == 4, "Got unexpected width %u.\n", width);
471     ok(mipmaps == 1, "Got unexpected level count %u.\n", mipmaps);
472     if (has_2d_dxt5)
473     {
474         ok(height == 4, "Got unexpected height %u.\n", height);
475         ok(format == D3DFMT_DXT5, "Got unexpected format %u.\n", format);
476     }
477     else
478     {
479         ok(height == 2, "Got unexpected height %u.\n", height);
480         ok(format == D3DFMT_A8R8G8B8, "Got unexpected format %u.\n", format);
481     }
482 
483     IDirect3D9_Release(d3d);
484 }
485 
test_D3DXCheckCubeTextureRequirements(IDirect3DDevice9 * device)486 static void test_D3DXCheckCubeTextureRequirements(IDirect3DDevice9 *device)
487 {
488     UINT size, mipmaps, expected;
489     D3DFORMAT format;
490     D3DCAPS9 caps;
491     HRESULT hr;
492 
493     IDirect3DDevice9_GetDeviceCaps(device, &caps);
494 
495     if (!(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP))
496     {
497         skip("No cube textures support\n");
498         return;
499     }
500 
501     /* general tests */
502     hr = D3DXCheckCubeTextureRequirements(device, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
503     ok(hr == D3D_OK, "D3DXCheckCubeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
504 
505     hr = D3DXCheckCubeTextureRequirements(device, NULL, NULL, D3DX_DEFAULT, NULL, D3DPOOL_DEFAULT);
506     ok(hr == D3D_OK, "D3DXCheckCubeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
507 
508     hr = D3DXCheckCubeTextureRequirements(NULL, NULL, NULL, D3DX_DEFAULT, NULL, D3DPOOL_DEFAULT);
509     ok(hr == D3DERR_INVALIDCALL, "D3DXCheckCubeTextureRequirements returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
510 
511     /* size */
512     size = D3DX_DEFAULT;
513     hr = D3DXCheckCubeTextureRequirements(device, &size, NULL, 0, NULL, D3DPOOL_DEFAULT);
514     ok(hr == D3D_OK, "D3DXCheckCubeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
515     ok(size == 256, "Returned size %d, expected %d\n", size, 256);
516 
517     /* mipmaps */
518     size = 64;
519     mipmaps = 9;
520     hr = D3DXCheckCubeTextureRequirements(device, &size, &mipmaps, 0, NULL, D3DPOOL_DEFAULT);
521     ok(hr == D3D_OK, "D3DXCheckCubeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
522     ok(mipmaps == 7, "Returned mipmaps %d, expected %d\n", mipmaps, 7);
523 
524     size = 284;
525     mipmaps = 20;
526     expected = caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP_POW2 ? 10 : 9;
527     expected = caps.TextureCaps & D3DPTEXTURECAPS_MIPCUBEMAP ? expected : 1;
528     hr = D3DXCheckCubeTextureRequirements(device, &size, &mipmaps, 0, NULL, D3DPOOL_DEFAULT);
529     ok(hr == D3D_OK, "D3DXCheckCubeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
530     ok(mipmaps == expected, "Returned mipmaps %d, expected %d\n", mipmaps, expected);
531 
532     size = 63;
533     mipmaps = 9;
534     expected = caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP_POW2 ? 7 : 6;
535     expected = caps.TextureCaps & D3DPTEXTURECAPS_MIPCUBEMAP ? expected : 1;
536     hr = D3DXCheckCubeTextureRequirements(device, &size, &mipmaps, 0, NULL, D3DPOOL_DEFAULT);
537     ok(hr == D3D_OK, "D3DXCheckCubeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
538     ok(mipmaps == expected, "Returned mipmaps %d, expected %d\n", mipmaps, expected);
539 
540     mipmaps = 0;
541     hr = D3DXCheckCubeTextureRequirements(device, NULL, &mipmaps, 0, NULL, D3DPOOL_DEFAULT);
542     ok(hr == D3D_OK, "D3DXCheckCubeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
543     ok(mipmaps == 9, "Returned mipmaps %d, expected %d\n", mipmaps, 9);
544 
545     if (is_autogenmipmap_supported(device, D3DRTYPE_CUBETEXTURE))
546     {
547         mipmaps = 3;
548         hr = D3DXCheckCubeTextureRequirements(device, NULL,  &mipmaps, D3DUSAGE_AUTOGENMIPMAP, NULL, D3DPOOL_DEFAULT);
549         ok(hr == D3D_OK, "D3DXCheckCubeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
550         ok(mipmaps == 0, "Returned mipmaps %d, expected %d\n", mipmaps, 0);
551     }
552     else
553         skip("No D3DUSAGE_AUTOGENMIPMAP support for cube textures\n");
554 
555     /* usage */
556     hr = D3DXCheckCubeTextureRequirements(device, NULL, NULL, D3DUSAGE_WRITEONLY, NULL, D3DPOOL_DEFAULT);
557     ok(hr == D3DERR_INVALIDCALL, "D3DXCheckCubeTextureRequirements succeeded, but should've failed.\n");
558     hr = D3DXCheckCubeTextureRequirements(device, NULL, NULL, D3DUSAGE_DONOTCLIP, NULL, D3DPOOL_DEFAULT);
559     ok(hr == D3DERR_INVALIDCALL, "D3DXCheckCubeTextureRequirements succeeded, but should've failed.\n");
560     hr = D3DXCheckCubeTextureRequirements(device, NULL, NULL, D3DUSAGE_POINTS, NULL, D3DPOOL_DEFAULT);
561     ok(hr == D3DERR_INVALIDCALL, "D3DXCheckCubeTextureRequirements succeeded, but should've failed.\n");
562     hr = D3DXCheckCubeTextureRequirements(device, NULL, NULL, D3DUSAGE_RTPATCHES, NULL, D3DPOOL_DEFAULT);
563     ok(hr == D3DERR_INVALIDCALL, "D3DXCheckCubeTextureRequirements succeeded, but should've failed.\n");
564     hr = D3DXCheckCubeTextureRequirements(device, NULL, NULL, D3DUSAGE_NPATCHES, NULL, D3DPOOL_DEFAULT);
565     ok(hr == D3DERR_INVALIDCALL, "D3DXCheckCubeTextureRequirements succeeded, but should've failed.\n");
566 
567     /* format */
568     hr = D3DXCheckCubeTextureRequirements(device, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
569     ok(hr == D3D_OK, "D3DXCheckCubeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
570 
571     format = D3DFMT_UNKNOWN;
572     hr = D3DXCheckCubeTextureRequirements(device, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
573     ok(hr == D3D_OK, "D3DXCheckCubeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
574     ok(format == D3DFMT_A8R8G8B8, "Returned format %u, expected %u\n", format, D3DFMT_A8R8G8B8);
575 
576     format = D3DX_DEFAULT;
577     hr = D3DXCheckCubeTextureRequirements(device, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
578     ok(hr == D3D_OK, "D3DXCheckCubeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
579     ok(format == D3DFMT_A8R8G8B8, "Returned format %u, expected %u\n", format, D3DFMT_A8R8G8B8);
580 
581     format = D3DFMT_R8G8B8;
582     hr = D3DXCheckCubeTextureRequirements(device, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
583     ok(hr == D3D_OK, "D3DXCheckCubeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
584     ok(format == D3DFMT_X8R8G8B8, "Returned format %u, expected %u\n", format, D3DFMT_X8R8G8B8);
585 }
586 
test_D3DXCheckVolumeTextureRequirements(IDirect3DDevice9 * device)587 static void test_D3DXCheckVolumeTextureRequirements(IDirect3DDevice9 *device)
588 {
589     UINT width, height, depth, mipmaps, expected;
590     D3DFORMAT format;
591     D3DCAPS9 caps;
592     HRESULT hr;
593 
594     IDirect3DDevice9_GetDeviceCaps(device, &caps);
595 
596     if (!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP) || (caps.MaxVolumeExtent < 256))
597     {
598         skip("Limited or no volume textures support.\n");
599         return;
600     }
601 
602     /* general tests */
603     hr = D3DXCheckVolumeTextureRequirements(device, NULL, NULL, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
604     ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
605 
606     hr = D3DXCheckVolumeTextureRequirements(device, NULL, NULL, NULL, NULL, D3DX_DEFAULT, NULL, D3DPOOL_DEFAULT);
607     ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
608 
609     hr = D3DXCheckVolumeTextureRequirements(NULL, NULL, NULL, NULL, NULL, D3DX_DEFAULT, NULL, D3DPOOL_DEFAULT);
610     ok(hr == D3DERR_INVALIDCALL, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
611 
612     /* width, height, depth */
613     width = height = depth = D3DX_DEFAULT;
614     hr = D3DXCheckVolumeTextureRequirements(device, &width, &height, &depth, NULL, 0, NULL, D3DPOOL_DEFAULT);
615     ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
616     ok(width == 256, "Returned width %d, expected %d\n", width, 256);
617     ok(height == 256, "Returned height %d, expected %d\n", height, 256);
618     ok(depth == 1, "Returned depth %d, expected %d\n", depth, 1);
619 
620     width = D3DX_DEFAULT;
621     hr = D3DXCheckVolumeTextureRequirements(device, &width, NULL, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
622     ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
623     ok(width == 256, "Returned width %d, expected %d\n", width, 256);
624 
625     width = D3DX_DEFAULT; height = 0; depth = 0;
626     hr = D3DXCheckVolumeTextureRequirements(device, &width, &height, &depth, NULL, 0, NULL, D3DPOOL_DEFAULT);
627     ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
628     ok(width == 1, "Returned width %d, expected %d\n", width, 1);
629     ok(height == 1, "Returned height %d, expected %d\n", height, 1);
630     ok(depth == 1, "Returned height %d, expected %d\n", depth, 1);
631 
632     width = 0; height = 0; depth = 0;
633     hr = D3DXCheckVolumeTextureRequirements(device, &width, &height, &depth, NULL, 0, NULL, D3DPOOL_DEFAULT);
634     ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
635     ok(width == 1, "Returned width %d, expected %d\n", width, 1);
636     ok(height == 1, "Returned height %d, expected %d\n", height, 1);
637     ok(depth == 1, "Returned height %d, expected %d\n", depth, 1);
638 
639     width = 0;
640     hr = D3DXCheckVolumeTextureRequirements(device, &width, NULL, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
641     ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
642     ok(width == 1, "Returned width %d, expected %d\n", width, 1);
643 
644     width = 0xFFFFFFFE;
645     hr = D3DXCheckVolumeTextureRequirements(device, &width, NULL, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
646     ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
647     ok(width == caps.MaxVolumeExtent, "Returned width %d, expected %d\n", width, caps.MaxVolumeExtent);
648 
649     /* format */
650     hr = D3DXCheckVolumeTextureRequirements(device, NULL, NULL, NULL, NULL, 0, NULL, D3DPOOL_DEFAULT);
651     ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
652 
653     format = D3DFMT_UNKNOWN;
654     hr = D3DXCheckVolumeTextureRequirements(device, NULL, NULL, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
655     ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
656     ok(format == D3DFMT_A8R8G8B8, "Returned format %u, expected %u\n", format, D3DFMT_A8R8G8B8);
657 
658     format = D3DX_DEFAULT;
659     hr = D3DXCheckVolumeTextureRequirements(device, NULL, NULL, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
660     ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
661     ok(format == D3DFMT_A8R8G8B8, "Returned format %u, expected %u\n", format, D3DFMT_A8R8G8B8);
662 
663     format = D3DFMT_R8G8B8;
664     hr = D3DXCheckVolumeTextureRequirements(device, NULL, NULL, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
665     ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
666     ok(format == D3DFMT_X8R8G8B8, "Returned format %u, expected %u\n", format, D3DFMT_X8R8G8B8);
667 
668     format = D3DFMT_DXT3;
669     hr = D3DXCheckVolumeTextureRequirements(device, NULL, NULL, NULL, NULL, 0, &format, D3DPOOL_DEFAULT);
670     ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
671     if (has_3d_dxt3)
672         ok(format == D3DFMT_DXT3, "Returned format %u, expected %u\n", format, D3DFMT_DXT3);
673     else
674         ok(format == D3DFMT_A8R8G8B8, "Returned format %u, expected %u\n", format, D3DFMT_A8R8G8B8);
675 
676     /* mipmaps */
677     if (!(caps.TextureCaps & D3DPTEXTURECAPS_MIPVOLUMEMAP))
678     {
679         skip("No volume textures mipmapping support\n");
680         return;
681     }
682 
683     width = height = depth = 64;
684     mipmaps = 9;
685     hr = D3DXCheckVolumeTextureRequirements(device, &width, &height, &depth, &mipmaps, 0, NULL, D3DPOOL_DEFAULT);
686     ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
687     ok(mipmaps == 7, "Returned mipmaps %d, expected %d\n", mipmaps, 7);
688 
689     width = 284;
690     height = 143;
691     depth = 55;
692     mipmaps = 20;
693     expected = (caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP_POW2 && caps.MaxVolumeExtent >= 512) ? 10 : 9;
694     hr = D3DXCheckVolumeTextureRequirements(device, &width, &height, &depth, &mipmaps, 0, NULL, D3DPOOL_DEFAULT);
695     ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
696     ok(mipmaps == expected, "Returned mipmaps %d, expected %d\n", mipmaps, expected);
697 
698     mipmaps = 0;
699     hr = D3DXCheckVolumeTextureRequirements(device, NULL, NULL, NULL, &mipmaps, 0, NULL, D3DPOOL_DEFAULT);
700     ok(hr == D3D_OK, "D3DXCheckVolumeTextureRequirements returned %#x, expected %#x\n", hr, D3D_OK);
701     ok(mipmaps == 9, "Returned mipmaps %d, expected %d\n", mipmaps, 9);
702 
703     /* D3DUSAGE_AUTOGENMIPMAP is never supported for volume textures. */
704     ok(!is_autogenmipmap_supported(device, D3DRTYPE_VOLUMETEXTURE),
705             "D3DUSAGE_AUTOGENMIPMAP is unexpectedly supported on volume textures.\n");
706 }
707 
test_D3DXCreateTexture(IDirect3DDevice9 * device)708 static void test_D3DXCreateTexture(IDirect3DDevice9 *device)
709 {
710     IDirect3DTexture9 *texture;
711     D3DSURFACE_DESC desc;
712     D3DCAPS9 caps;
713     UINT mipmaps;
714     HRESULT hr;
715 
716     IDirect3DDevice9_GetDeviceCaps(device, &caps);
717 
718     hr = D3DXCreateTexture(NULL, 0, 0, 0, 0, D3DX_DEFAULT, D3DPOOL_DEFAULT, NULL);
719     ok(hr == D3DERR_INVALIDCALL, "D3DXCreateTexture returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
720 
721     /* width and height tests */
722 
723     hr = D3DXCreateTexture(device, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, 0, D3DPOOL_DEFAULT, &texture);
724     ok(hr == D3D_OK, "D3DXCreateTexture returned %#x, expected %#x\n", hr, D3D_OK);
725 
726     if (texture)
727     {
728         hr = IDirect3DTexture9_GetLevelDesc(texture, 0, &desc);
729         ok(hr == D3D_OK, "GetLevelDesc returned %#x, expected %#x\n", hr, D3D_OK);
730         ok(desc.Format == D3DFMT_A8R8G8B8, "Returned format %u, expected %u\n", desc.Format, D3DFMT_A8R8G8B8);
731 
732         ok(desc.Width == 256, "Returned width %d, expected %d\n", desc.Width, 256);
733         ok(desc.Height == 256, "Returned height %d, expected %d\n", desc.Height, 256);
734 
735         IDirect3DTexture9_Release(texture);
736     }
737 
738 
739     hr = D3DXCreateTexture(device, 0, 0, 0, 0, 0, D3DPOOL_DEFAULT, &texture);
740     ok(hr == D3D_OK, "D3DXCreateTexture returned %#x, expected %#x\n", hr, D3D_OK);
741 
742     if (texture)
743     {
744         hr = IDirect3DTexture9_GetLevelDesc(texture, 0, &desc);
745         ok(hr == D3D_OK, "GetLevelDesc returned %#x, expected %#x\n", hr, D3D_OK);
746         ok(desc.Format == D3DFMT_A8R8G8B8, "Returned format %u, expected %u\n", desc.Format, D3DFMT_A8R8G8B8);
747 
748         ok(desc.Width == 1, "Returned width %d, expected %d\n", desc.Width, 1);
749         ok(desc.Height == 1, "Returned height %d, expected %d\n", desc.Height, 1);
750 
751         IDirect3DTexture9_Release(texture);
752     }
753 
754 
755     if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
756         skip("Hardware only supports pow2 textures\n");
757     else
758     {
759         hr = D3DXCreateTexture(device, D3DX_DEFAULT, 63, 0, 0, 0, D3DPOOL_DEFAULT, &texture);
760         ok((hr == D3D_OK) ||
761            /* may not work with conditional NPOT */
762            ((hr != D3D_OK) && (caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL)),
763            "D3DXCreateTexture returned %#x, expected %#x\n", hr, D3D_OK);
764 
765         if (texture)
766         {
767             hr = IDirect3DTexture9_GetLevelDesc(texture, 0, &desc);
768             ok(hr == D3D_OK, "GetLevelDesc returned %#x, expected %#x\n", hr, D3D_OK);
769             ok(desc.Format == D3DFMT_A8R8G8B8, "Returned format %u, expected %u\n", desc.Format, D3DFMT_A8R8G8B8);
770 
771             /* Conditional NPOT may create a texture with different dimensions, so allow those
772                situations instead of returning a fail */
773 
774             ok(desc.Width == 63 ||
775                (caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL),
776                "Returned width %d, expected %d\n", desc.Width, 63);
777 
778             ok(desc.Height == 63 ||
779                (caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL),
780                "Returned height %d, expected %d\n", desc.Height, 63);
781 
782             IDirect3DTexture9_Release(texture);
783         }
784     }
785 
786     /* mipmaps */
787 
788     hr = D3DXCreateTexture(device, 64, 63, 9, 0, 0, D3DPOOL_DEFAULT, &texture);
789     ok(hr == D3D_OK, "D3DXCreateTexture returned %#x, expected %#x\n", hr, D3D_OK);
790 
791     if (texture)
792     {
793         mipmaps = IDirect3DTexture9_GetLevelCount(texture);
794         ok(mipmaps == 7, "Returned mipmaps %d, expected %d\n", mipmaps, 7);
795 
796         IDirect3DTexture9_Release(texture);
797     }
798 
799 
800     hr = D3DXCreateTexture(device, 284, 137, 9, 0, 0, D3DPOOL_DEFAULT, &texture);
801     ok(hr == D3D_OK, "D3DXCreateTexture returned %#x, expected %#x\n", hr, D3D_OK);
802 
803     if (texture)
804     {
805         mipmaps = IDirect3DTexture9_GetLevelCount(texture);
806         ok(mipmaps == 9, "Returned mipmaps %d, expected %d\n", mipmaps, 9);
807 
808         IDirect3DTexture9_Release(texture);
809     }
810 
811 
812     hr = D3DXCreateTexture(device, 0, 0, 20, 0, 0, D3DPOOL_DEFAULT, &texture);
813     ok(hr == D3D_OK, "D3DXCreateTexture returned %#x, expected %#x\n", hr, D3D_OK);
814 
815     if (texture)
816     {
817         mipmaps = IDirect3DTexture9_GetLevelCount(texture);
818         ok(mipmaps == 1, "Returned mipmaps %d, expected %d\n", mipmaps, 1);
819 
820         IDirect3DTexture9_Release(texture);
821     }
822 
823 
824     hr = D3DXCreateTexture(device, 64, 64, 1, 0, 0, D3DPOOL_DEFAULT, &texture);
825     ok(hr == D3D_OK, "D3DXCreateTexture returned %#x, expected %#x\n", hr, D3D_OK);
826 
827     if (texture)
828     {
829         mipmaps = IDirect3DTexture9_GetLevelCount(texture);
830         ok(mipmaps == 1, "Returned mipmaps %d, expected %d\n", mipmaps, 1);
831 
832         IDirect3DTexture9_Release(texture);
833     }
834 
835     /* usage */
836 
837     hr = D3DXCreateTexture(device, 0, 0, 0, D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &texture);
838     ok(hr == D3DERR_INVALIDCALL, "D3DXCreateTexture succeeded, but should have failed.\n");
839     hr = D3DXCreateTexture(device, 0, 0, 0, D3DUSAGE_DONOTCLIP, 0, D3DPOOL_DEFAULT, &texture);
840     ok(hr == D3DERR_INVALIDCALL, "D3DXCreateTexture succeeded, but should have failed.\n");
841     hr = D3DXCreateTexture(device, 0, 0, 0, D3DUSAGE_POINTS, 0, D3DPOOL_DEFAULT, &texture);
842     ok(hr == D3DERR_INVALIDCALL, "D3DXCreateTexture succeeded, but should have failed.\n");
843     hr = D3DXCreateTexture(device, 0, 0, 0, D3DUSAGE_RTPATCHES, 0, D3DPOOL_DEFAULT, &texture);
844     ok(hr == D3DERR_INVALIDCALL, "D3DXCreateTexture succeeded, but should have failed.\n");
845     hr = D3DXCreateTexture(device, 0, 0, 0, D3DUSAGE_NPATCHES, 0, D3DPOOL_DEFAULT, &texture);
846     ok(hr == D3DERR_INVALIDCALL, "D3DXCreateTexture succeeded, but should have failed.\n");
847 
848     /* format */
849 
850     hr = D3DXCreateTexture(device, 0, 0, 0, 0, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, &texture);
851     ok(hr == D3D_OK, "D3DXCreateTexture returned %#x, expected %#x\n", hr, D3D_OK);
852 
853     if (texture)
854     {
855         hr = IDirect3DTexture9_GetLevelDesc(texture, 0, &desc);
856         ok(hr == D3D_OK, "GetLevelDesc returned %#x, expected %#x\n", hr, D3D_OK);
857         ok(desc.Format == D3DFMT_A8R8G8B8, "Returned format %u, expected %u\n", desc.Format, D3DFMT_A8R8G8B8);
858 
859         IDirect3DTexture9_Release(texture);
860     }
861 
862 
863     hr = D3DXCreateTexture(device, 0, 0, 0, 0, 0, D3DPOOL_DEFAULT, &texture);
864     ok(hr == D3D_OK, "D3DXCreateTexture returned %#x, expected %#x\n", hr, D3D_OK);
865 
866     if (texture)
867     {
868         hr = IDirect3DTexture9_GetLevelDesc(texture, 0, &desc);
869         ok(hr == D3D_OK, "GetLevelDesc returned %#x, expected %#x\n", hr, D3D_OK);
870         ok(desc.Format == D3DFMT_A8R8G8B8, "Returned format %u, expected %u\n", desc.Format, D3DFMT_A8R8G8B8);
871 
872         IDirect3DTexture9_Release(texture);
873     }
874 
875     /* D3DXCreateTextureFromResource */
876     hr = D3DXCreateTextureFromResourceA(device, NULL, MAKEINTRESOURCEA(IDB_BITMAP_1x1), &texture);
877     ok(hr == D3D_OK, "D3DXCreateTextureFromResource returned %#x, expected %#x\n", hr, D3D_OK);
878     if (SUCCEEDED(hr)) IDirect3DTexture9_Release(texture);
879 
880     hr = D3DXCreateTextureFromResourceA(device, NULL, MAKEINTRESOURCEA(IDD_BITMAPDATA_1x1), &texture);
881     ok(hr == D3D_OK, "D3DXCreateTextureFromResource returned %#x, expected %#x\n", hr, D3D_OK);
882     if (SUCCEEDED(hr)) IDirect3DTexture9_Release(texture);
883 
884     hr = D3DXCreateTextureFromResourceA(device, NULL, MAKEINTRESOURCEA(IDS_STRING), &texture);
885     ok(hr == D3DXERR_INVALIDDATA, "D3DXCreateTextureFromResource returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
886 
887     hr = D3DXCreateTextureFromResourceA(NULL, NULL, MAKEINTRESOURCEA(IDD_BITMAPDATA_1x1), &texture);
888     ok(hr == D3DERR_INVALIDCALL, "D3DXCreateTextureFromResource returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
889 
890     hr = D3DXCreateTextureFromResourceA(device, NULL, NULL, &texture);
891     ok(hr == D3DXERR_INVALIDDATA, "D3DXCreateTextureFromResource returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
892 
893     hr = D3DXCreateTextureFromResourceA(device, NULL, MAKEINTRESOURCEA(IDD_BITMAPDATA_1x1), NULL);
894     ok(hr == D3DERR_INVALIDCALL, "D3DXCreateTextureFromResource returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
895 
896 
897     /* D3DXCreateTextureFromResourceEx */
898     hr = D3DXCreateTextureFromResourceExA(device, NULL, MAKEINTRESOURCEA(IDD_BITMAPDATA_1x1), D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &texture);
899     ok(hr == D3D_OK, "D3DXCreateTextureFromResourceEx returned %#x, expected %#x\n", hr, D3D_OK);
900     if (SUCCEEDED(hr)) IDirect3DTexture9_Release(texture);
901 
902     hr = D3DXCreateTextureFromResourceExA(device, NULL, MAKEINTRESOURCEA(IDS_STRING), D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &texture);
903     ok(hr == D3DXERR_INVALIDDATA, "D3DXCreateTextureFromResourceEx returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
904 
905     hr = D3DXCreateTextureFromResourceExA(NULL, NULL, MAKEINTRESOURCEA(IDD_BITMAPDATA_1x1), D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &texture);
906     ok(hr == D3DERR_INVALIDCALL, "D3DXCreateTextureFromResourceEx returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
907 
908     hr = D3DXCreateTextureFromResourceExA(device, NULL, NULL, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &texture);
909     ok(hr == D3DXERR_INVALIDDATA, "D3DXCreateTextureFromResourceEx returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
910 
911     hr = D3DXCreateTextureFromResourceExA(device, NULL, MAKEINTRESOURCEA(IDD_BITMAPDATA_1x1), D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, NULL);
912     ok(hr == D3DERR_INVALIDCALL, "D3DXCreateTextureFromResourceEx returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
913 }
914 
test_D3DXFilterTexture(IDirect3DDevice9 * device)915 static void test_D3DXFilterTexture(IDirect3DDevice9 *device)
916 {
917     IDirect3DTexture9 *tex;
918     IDirect3DCubeTexture9 *cubetex;
919     IDirect3DVolumeTexture9 *voltex;
920     HRESULT hr;
921 
922     hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 5, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex, NULL);
923 
924     if (SUCCEEDED(hr))
925     {
926         hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, NULL, D3DX_DEFAULT, D3DX_FILTER_NONE);
927         ok(hr == D3D_OK, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3D_OK);
928 
929         hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, NULL, 0, D3DX_FILTER_NONE);
930         ok(hr == D3D_OK, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3D_OK);
931 
932         hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, NULL, 0, D3DX_FILTER_BOX + 1); /* Invalid filter */
933         ok(hr == D3DERR_INVALIDCALL, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
934 
935         hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, NULL, 5, D3DX_FILTER_NONE); /* Invalid miplevel */
936         ok(hr == D3DERR_INVALIDCALL, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
937 
938         IDirect3DTexture9_Release(tex);
939     }
940     else
941         skip("Failed to create texture\n");
942 
943     hr = D3DXFilterTexture(NULL, NULL, 0, D3DX_FILTER_NONE);
944     ok(hr == D3DERR_INVALIDCALL, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
945 
946     /* Test different pools */
947     hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 0, 0, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &tex, NULL);
948 
949     if (SUCCEEDED(hr))
950     {
951         hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, NULL, 0, D3DX_FILTER_NONE);
952         ok(hr == D3D_OK, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3D_OK);
953         IDirect3DTexture9_Release(tex);
954     }
955     else
956         skip("Failed to create texture\n");
957 
958     hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 0, 0, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &tex, NULL);
959 
960     if (SUCCEEDED(hr))
961     {
962         hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, NULL, 0, D3DX_FILTER_NONE);
963         ok(hr == D3D_OK, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3D_OK);
964         IDirect3DTexture9_Release(tex);
965     }
966     else
967         skip("Failed to create texture\n");
968 
969     hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 0, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex, NULL);
970     if (SUCCEEDED(hr))
971     {
972         hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, NULL, 0, D3DX_FILTER_POINT);
973         ok(hr == D3D_OK, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3D_OK);
974         IDirect3DTexture9_Release(tex);
975     }
976     else
977         skip("Failed to create texture\n");
978 
979     hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 0, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex, NULL);
980     if (SUCCEEDED(hr))
981     {
982         hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, NULL, 0, D3DX_FILTER_POINT);
983         ok(hr == D3D_OK, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3D_OK);
984         IDirect3DTexture9_Release(tex);
985     }
986     else
987         skip("Failed to create texture\n");
988 
989     /* Cube texture test */
990     hr = IDirect3DDevice9_CreateCubeTexture(device, 256, 5, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &cubetex, NULL);
991 
992     if (SUCCEEDED(hr))
993     {
994         hr = D3DXFilterTexture((IDirect3DBaseTexture9*) cubetex, NULL, 0, D3DX_FILTER_NONE);
995         ok(hr == D3D_OK, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3D_OK);
996 
997         hr = D3DXFilterTexture((IDirect3DBaseTexture9*) cubetex, NULL, 0, D3DX_FILTER_BOX + 1); /* Invalid filter */
998         ok(hr == D3DERR_INVALIDCALL, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
999 
1000         hr = D3DXFilterTexture((IDirect3DBaseTexture9*) cubetex, NULL, 5, D3DX_FILTER_NONE); /* Invalid miplevel */
1001         ok(hr == D3DERR_INVALIDCALL, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
1002         IDirect3DCubeTexture9_Release(cubetex);
1003     }
1004     else
1005         skip("Failed to create texture\n");
1006 
1007     /* Volume texture test */
1008     hr = IDirect3DDevice9_CreateVolumeTexture(device, 256, 256, 4, 0, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &voltex, NULL);
1009     if (SUCCEEDED(hr))
1010     {
1011         DWORD level_count = IDirect3DVolumeTexture9_GetLevelCount(voltex);
1012 
1013         hr = D3DXFilterTexture((IDirect3DBaseTexture9*) voltex, NULL, 0, D3DX_FILTER_NONE);
1014         ok(hr == D3D_OK, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3D_OK);
1015 
1016         hr = D3DXFilterTexture((IDirect3DBaseTexture9*) voltex, NULL, 0, D3DX_DEFAULT);
1017         ok(hr == D3D_OK, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3D_OK);
1018 
1019         hr = D3DXFilterTexture((IDirect3DBaseTexture9*) voltex, NULL, 0, D3DX_FILTER_BOX);
1020         ok(hr == D3D_OK, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3D_OK);
1021 
1022         hr = D3DXFilterTexture((IDirect3DBaseTexture9*) voltex, NULL, level_count - 1, D3DX_DEFAULT);
1023         ok(hr == D3D_OK, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3D_OK);
1024 
1025         hr = D3DXFilterTexture((IDirect3DBaseTexture9*) voltex, NULL, level_count, D3DX_DEFAULT);
1026         ok(hr == D3DERR_INVALIDCALL, "D3DXFilterTexture returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
1027 
1028         IDirect3DVolumeTexture9_Release(voltex);
1029     }
1030     else
1031         skip("Failed to create volume texture\n");
1032 
1033     /* Test textures with D3DUSAGE_AUTOGENMIPMAP usage */
1034     if (!is_autogenmipmap_supported(device, D3DRTYPE_TEXTURE))
1035     {
1036         skip("No D3DUSAGE_AUTOGENMIPMAP supported for textures\n");
1037         return;
1038     }
1039 
1040     hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 0, D3DUSAGE_DYNAMIC | D3DUSAGE_AUTOGENMIPMAP, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex, NULL);
1041     if (SUCCEEDED(hr))
1042     {
1043         hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, NULL, 0, D3DX_FILTER_NONE);
1044         ok(hr == D3D_OK, "D3dXFilteTexture returned %#x, expected %#x\n", hr, D3D_OK);
1045         IDirect3DTexture9_Release(tex);
1046     }
1047     else
1048         skip("Failed to create texture\n");
1049 
1050     hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, D3DUSAGE_DYNAMIC | D3DUSAGE_AUTOGENMIPMAP, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex, NULL);
1051     if (SUCCEEDED(hr))
1052     {
1053         hr = D3DXFilterTexture((IDirect3DBaseTexture9*) tex, NULL, 0, D3DX_FILTER_NONE);
1054         ok(hr == D3D_OK, "D3dXFilteTexture returned %#x, expected %#x\n", hr, D3D_OK);
1055         IDirect3DTexture9_Release(tex);
1056     }
1057     else
1058         skip("Failed to create texture\n");
1059 }
1060 
color_match(const DWORD * value,const DWORD * expected)1061 static BOOL color_match(const DWORD *value, const DWORD *expected)
1062 {
1063     int i;
1064 
1065     for (i = 0; i < 4; i++)
1066     {
1067         DWORD diff = value[i] > expected[i] ? value[i] - expected[i] : expected[i] - value[i];
1068         if (diff > 1) return FALSE;
1069     }
1070     return TRUE;
1071 }
1072 
fillfunc(D3DXVECTOR4 * value,const D3DXVECTOR2 * texcoord,const D3DXVECTOR2 * texelsize,void * data)1073 static void WINAPI fillfunc(D3DXVECTOR4 *value, const D3DXVECTOR2 *texcoord,
1074                             const D3DXVECTOR2 *texelsize, void *data)
1075 {
1076     value->x = texcoord->x;
1077     value->y = texcoord->y;
1078     value->z = texelsize->x;
1079     value->w = 1.0f;
1080 }
1081 
test_D3DXFillTexture(IDirect3DDevice9 * device)1082 static void test_D3DXFillTexture(IDirect3DDevice9 *device)
1083 {
1084     static const struct
1085     {
1086         DWORD usage;
1087         D3DPOOL pool;
1088     }
1089     test_access_types[] =
1090     {
1091         {0,  D3DPOOL_MANAGED},
1092         {0,  D3DPOOL_DEFAULT},
1093         {D3DUSAGE_RENDERTARGET, D3DPOOL_DEFAULT},
1094     };
1095 
1096     IDirect3DTexture9 *tex;
1097     HRESULT hr;
1098     D3DLOCKED_RECT lock_rect;
1099     DWORD x, y, m;
1100     DWORD v[4], e[4];
1101     DWORD value, expected, size, pitch;
1102     unsigned int i;
1103 
1104     for (i = 0; i < ARRAY_SIZE(test_access_types); ++i)
1105     {
1106         size = 4;
1107         hr = IDirect3DDevice9_CreateTexture(device, size, size, 0, test_access_types[i].usage,
1108                 D3DFMT_A8R8G8B8, test_access_types[i].pool, &tex, NULL);
1109         ok(hr == D3D_OK, "Unexpected hr %#x, i %u.\n", hr, i);
1110 
1111         hr = D3DXFillTexture(tex, fillfunc, NULL);
1112         ok(hr == D3D_OK, "Unexpected hr %#x, i %u.\n", hr, i);
1113 
1114         for (m = 0; m < 3; m++)
1115         {
1116             IDirect3DSurface9 *src_surface, *temp_surface;
1117 
1118             hr = IDirect3DTexture9_GetSurfaceLevel(tex, m, &src_surface);
1119             ok(hr == D3D_OK, "Unexpected hr %#x, i %u, m %u.\n", hr, i, m);
1120             temp_surface = src_surface;
1121 
1122             if (FAILED(hr = IDirect3DSurface9_LockRect(src_surface, &lock_rect, NULL, D3DLOCK_READONLY)))
1123             {
1124                 hr = IDirect3DDevice9_CreateRenderTarget(device, size, size,
1125                         D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &temp_surface, NULL);
1126                 ok(hr == D3D_OK, "Unexpected hr %#x, i %u, m %u.\n", hr, i, m);
1127                 hr = IDirect3DDevice9_StretchRect(device, src_surface, NULL, temp_surface, NULL, D3DTEXF_NONE);
1128                 ok(hr == D3D_OK, "Unexpected hr %#x, i %u, m %u.\n", hr, i, m);
1129                 hr = IDirect3DSurface9_LockRect(temp_surface, &lock_rect, NULL, D3DLOCK_READONLY);
1130                 ok(hr == D3D_OK, "Unexpected hr %#x, i %u, m %u.\n", hr, i, m);
1131             }
1132 
1133             pitch = lock_rect.Pitch / sizeof(DWORD);
1134             for (y = 0; y < size; y++)
1135             {
1136                 for (x = 0; x < size; x++)
1137                 {
1138                     value = ((DWORD *)lock_rect.pBits)[y * pitch + x];
1139                     v[0] = (value >> 24) & 0xff;
1140                     v[1] = (value >> 16) & 0xff;
1141                     v[2] = (value >> 8) & 0xff;
1142                     v[3] = value & 0xff;
1143 
1144                     e[0] = 0xff;
1145                     e[1] = (x + 0.5f) / size * 255.0f + 0.5f;
1146                     e[2] = (y + 0.5f) / size * 255.0f + 0.5f;
1147                     e[3] = 255.0f / size + 0.5f;
1148                     expected = e[0] << 24 | e[1] << 16 | e[2] << 8 | e[3];
1149 
1150                     ok(color_match(v, e),
1151                             "Texel at (%u, %u) doesn't match: %#x, expected %#x, i %u, m %u.\n",
1152                             x, y, value, expected, i, m);
1153                 }
1154             }
1155             IDirect3DSurface9_UnlockRect(temp_surface);
1156             if (temp_surface != src_surface)
1157                 IDirect3DSurface9_Release(temp_surface);
1158             IDirect3DSurface9_Release(src_surface);
1159             size >>= 1;
1160         }
1161         IDirect3DTexture9_Release(tex);
1162     }
1163 
1164     hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, D3DUSAGE_DEPTHSTENCIL,
1165             D3DFMT_D16_LOCKABLE, D3DPOOL_DEFAULT, &tex, NULL);
1166     if (hr == D3D_OK)
1167     {
1168         hr = D3DXFillTexture(tex, fillfunc, NULL);
1169         todo_wine ok(hr == D3D_OK, "Unexpected hr %#x.\n", hr);
1170         IDirect3DTexture9_Release(tex);
1171     }
1172 
1173     hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, D3DUSAGE_DEPTHSTENCIL,
1174             D3DFMT_D16, D3DPOOL_DEFAULT, &tex, NULL);
1175     if (hr == D3D_OK)
1176     {
1177         hr = D3DXFillTexture(tex, fillfunc, NULL);
1178         ok(hr == D3DERR_INVALIDCALL, "Unexpected hr %#x.\n", hr);
1179         IDirect3DTexture9_Release(tex);
1180     }
1181 
1182     hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_A1R5G5B5,
1183                                         D3DPOOL_MANAGED, &tex, NULL);
1184 
1185     if (SUCCEEDED(hr))
1186     {
1187         hr = D3DXFillTexture(tex, fillfunc, NULL);
1188         ok(hr == D3D_OK, "D3DXFillTexture returned %#x, expected %#x\n", hr, D3D_OK);
1189 
1190         hr = IDirect3DTexture9_LockRect(tex, 0, &lock_rect, NULL, D3DLOCK_READONLY);
1191         ok(hr == D3D_OK, "Couldn't lock the texture, error %#x\n", hr);
1192         if (SUCCEEDED(hr))
1193         {
1194             pitch = lock_rect.Pitch / sizeof(WORD);
1195             for (y = 0; y < 4; y++)
1196             {
1197                 for (x = 0; x < 4; x++)
1198                 {
1199                     value = ((WORD *)lock_rect.pBits)[y * pitch + x];
1200                     v[0] = value >> 15;
1201                     v[1] = value >> 10 & 0x1f;
1202                     v[2] = value >> 5 & 0x1f;
1203                     v[3] = value & 0x1f;
1204 
1205                     e[0] = 1;
1206                     e[1] = (x + 0.5f) / 4.0f * 31.0f + 0.5f;
1207                     e[2] = (y + 0.5f) / 4.0f * 31.0f + 0.5f;
1208                     e[3] = 8;
1209                     expected = e[0] << 15 | e[1] << 10 | e[2] << 5 | e[3];
1210 
1211                     ok(color_match(v, e),
1212                        "Texel at (%u, %u) doesn't match: %#x, expected %#x\n",
1213                        x, y, value, expected);
1214                 }
1215             }
1216             IDirect3DTexture9_UnlockRect(tex, 0);
1217         }
1218 
1219         IDirect3DTexture9_Release(tex);
1220     }
1221     else
1222         skip("Failed to create texture\n");
1223 
1224     /* test floating-point textures */
1225     hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_A16B16G16R16F,
1226                                         D3DPOOL_MANAGED, &tex, NULL);
1227 
1228     if (SUCCEEDED(hr))
1229     {
1230         hr = D3DXFillTexture(tex, fillfunc, NULL);
1231         ok(hr == D3D_OK, "D3DXFillTexture returned %#x, expected %#x\n", hr, D3D_OK);
1232 
1233         hr = IDirect3DTexture9_LockRect(tex, 0, &lock_rect, NULL, D3DLOCK_READONLY);
1234         if (SUCCEEDED(hr))
1235         {
1236             pitch = lock_rect.Pitch / sizeof(WORD);
1237             for (y = 0; y < 4; y++)
1238             {
1239                 WORD *ptr = (WORD *)lock_rect.pBits + y * pitch;
1240                 for (x = 0; x < 4; x++)
1241                 {
1242                     D3DXVECTOR4 got, expected;
1243 
1244                     D3DXFloat16To32Array((FLOAT *)&got, (D3DXFLOAT16 *)ptr, 4);
1245                     ptr += 4;
1246 
1247                     expected.x = (x + 0.5f) / 4.0f;
1248                     expected.y = (y + 0.5f) / 4.0f;
1249                     expected.z = 1.0f / 4.0f;
1250                     expected.w = 1.0f;
1251 
1252                     expect_vec4(&expected, &got);
1253                 }
1254             }
1255 
1256             IDirect3DTexture9_UnlockRect(tex, 0);
1257         }
1258         else
1259             skip("Failed to lock texture\n");
1260 
1261         IDirect3DTexture9_Release(tex);
1262     }
1263     else
1264         skip("Failed to create D3DFMT_A16B16G16R16F texture\n");
1265 
1266     hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_A32B32G32R32F,
1267                                         D3DPOOL_MANAGED, &tex, NULL);
1268 
1269     if (SUCCEEDED(hr))
1270     {
1271         hr = D3DXFillTexture(tex, fillfunc, NULL);
1272         ok(hr == D3D_OK, "D3DXFillTexture returned %#x, expected %#x\n", hr, D3D_OK);
1273 
1274         hr = IDirect3DTexture9_LockRect(tex, 0, &lock_rect, NULL, D3DLOCK_READONLY);
1275         if (SUCCEEDED(hr))
1276         {
1277             pitch = lock_rect.Pitch / sizeof(float);
1278             for (y = 0; y < 4; y++)
1279             {
1280                 float *ptr = (float *)lock_rect.pBits + y * pitch;
1281                 for (x = 0; x < 4; x++)
1282                 {
1283                     D3DXVECTOR4 got, expected;
1284 
1285                     got.x = *ptr++;
1286                     got.y = *ptr++;
1287                     got.z = *ptr++;
1288                     got.w = *ptr++;
1289 
1290                     expected.x = (x + 0.5f) / 4.0f;
1291                     expected.y = (y + 0.5f) / 4.0f;
1292                     expected.z = 1.0f / 4.0f;
1293                     expected.w = 1.0f;
1294 
1295                     expect_vec4(&expected, &got);
1296                 }
1297             }
1298 
1299             IDirect3DTexture9_UnlockRect(tex, 0);
1300         }
1301         else
1302             skip("Failed to lock texture\n");
1303 
1304         IDirect3DTexture9_Release(tex);
1305     }
1306     else
1307         skip("Failed to create D3DFMT_A32B32G32R32F texture\n");
1308 
1309     /* test a compressed texture */
1310     hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_DXT1,
1311                                         D3DPOOL_MANAGED, &tex, NULL);
1312 
1313     if (SUCCEEDED(hr))
1314     {
1315         hr = D3DXFillTexture(tex, fillfunc, NULL);
1316         todo_wine ok(hr == D3D_OK, "D3DXFillTexture returned %#x, expected %#x\n", hr, D3D_OK);
1317 
1318         IDirect3DTexture9_Release(tex);
1319     }
1320     else
1321         skip("Failed to create D3DFMT_DXT1 texture\n");
1322 }
1323 
fillfunc_cube(D3DXVECTOR4 * value,const D3DXVECTOR3 * texcoord,const D3DXVECTOR3 * texelsize,void * data)1324 static void WINAPI fillfunc_cube(D3DXVECTOR4 *value, const D3DXVECTOR3 *texcoord,
1325                                  const D3DXVECTOR3 *texelsize, void *data)
1326 {
1327     value->x = (texcoord->x + 1.0f) / 2.0f;
1328     value->y = (texcoord->y + 1.0f) / 2.0f;
1329     value->z = (texcoord->z + 1.0f) / 2.0f;
1330     value->w = texelsize->x;
1331 }
1332 
1333 enum cube_coord
1334 {
1335     XCOORD = 0,
1336     XCOORDINV = 1,
1337     YCOORD = 2,
1338     YCOORDINV = 3,
1339     ZERO = 4,
1340     ONE = 5
1341 };
1342 
get_cube_coord(enum cube_coord coord,unsigned int x,unsigned int y,unsigned int size)1343 static float get_cube_coord(enum cube_coord coord, unsigned int x, unsigned int y, unsigned int size)
1344 {
1345     switch (coord)
1346     {
1347         case XCOORD:
1348             return x + 0.5f;
1349         case XCOORDINV:
1350             return size - x - 0.5f;
1351         case YCOORD:
1352             return y + 0.5f;
1353         case YCOORDINV:
1354             return size - y - 0.5f;
1355         case ZERO:
1356             return 0.0f;
1357         case ONE:
1358             return size;
1359         default:
1360            trace("Unexpected coordinate value\n");
1361            return 0.0f;
1362     }
1363 }
1364 
test_D3DXFillCubeTexture(IDirect3DDevice9 * device)1365 static void test_D3DXFillCubeTexture(IDirect3DDevice9 *device)
1366 {
1367     IDirect3DCubeTexture9 *tex;
1368     HRESULT hr;
1369     D3DLOCKED_RECT lock_rect;
1370     DWORD x, y, f, m;
1371     DWORD v[4], e[4];
1372     DWORD value, expected, size, pitch;
1373     enum cube_coord coordmap[6][3] =
1374         {
1375             {ONE, YCOORDINV, XCOORDINV},
1376             {ZERO, YCOORDINV, XCOORD},
1377             {XCOORD, ONE, YCOORD},
1378             {XCOORD, ZERO, YCOORDINV},
1379             {XCOORD, YCOORDINV, ONE},
1380             {XCOORDINV, YCOORDINV, ZERO}
1381         };
1382 
1383     size = 4;
1384     hr = IDirect3DDevice9_CreateCubeTexture(device, size, 0, 0, D3DFMT_A8R8G8B8,
1385                                             D3DPOOL_MANAGED, &tex, NULL);
1386 
1387     if (SUCCEEDED(hr))
1388     {
1389         hr = D3DXFillCubeTexture(tex, fillfunc_cube, NULL);
1390         ok(hr == D3D_OK, "D3DXFillCubeTexture returned %#x, expected %#x\n", hr, D3D_OK);
1391 
1392         for (m = 0; m < 3; m++)
1393         {
1394             for (f = 0; f < 6; f++)
1395             {
1396                 hr = IDirect3DCubeTexture9_LockRect(tex, f, m, &lock_rect, NULL, D3DLOCK_READONLY);
1397                 ok(hr == D3D_OK, "Couldn't lock the texture, error %#x\n", hr);
1398                 if (SUCCEEDED(hr))
1399                 {
1400                     pitch = lock_rect.Pitch / sizeof(DWORD);
1401                     for (y = 0; y < size; y++)
1402                     {
1403                         for (x = 0; x < size; x++)
1404                         {
1405                             value = ((DWORD *)lock_rect.pBits)[y * pitch + x];
1406                             v[0] = (value >> 24) & 0xff;
1407                             v[1] = (value >> 16) & 0xff;
1408                             v[2] = (value >> 8) & 0xff;
1409                             v[3] = value & 0xff;
1410 
1411                             e[0] = (f == 0) || (f == 1) ?
1412                                 0 : (BYTE)(255.0f / size * 2.0f + 0.5f);
1413                             e[1] = get_cube_coord(coordmap[f][0], x, y, size) / size * 255.0f + 0.5f;
1414                             e[2] = get_cube_coord(coordmap[f][1], x, y, size) / size * 255.0f + 0.5f;
1415                             e[3] = get_cube_coord(coordmap[f][2], x, y, size) / size * 255.0f + 0.5f;
1416                             expected = e[0] << 24 | e[1] << 16 | e[2] << 8 | e[3];
1417 
1418                             ok(color_match(v, e),
1419                                "Texel at face %u (%u, %u) doesn't match: %#x, expected %#x\n",
1420                                f, x, y, value, expected);
1421                         }
1422                     }
1423                     IDirect3DCubeTexture9_UnlockRect(tex, f, m);
1424                 }
1425             }
1426             size >>= 1;
1427         }
1428 
1429         IDirect3DCubeTexture9_Release(tex);
1430     }
1431     else
1432         skip("Failed to create texture\n");
1433 
1434     hr = IDirect3DDevice9_CreateCubeTexture(device, 4, 1, 0, D3DFMT_A1R5G5B5,
1435                                             D3DPOOL_MANAGED, &tex, NULL);
1436 
1437     if (SUCCEEDED(hr))
1438     {
1439         hr = D3DXFillCubeTexture(tex, fillfunc_cube, NULL);
1440         ok(hr == D3D_OK, "D3DXFillTexture returned %#x, expected %#x\n", hr, D3D_OK);
1441         for (f = 0; f < 6; f++)
1442         {
1443             hr = IDirect3DCubeTexture9_LockRect(tex, f, 0, &lock_rect, NULL, D3DLOCK_READONLY);
1444             ok(hr == D3D_OK, "Couldn't lock the texture, error %#x\n", hr);
1445             if (SUCCEEDED(hr))
1446             {
1447                 pitch = lock_rect.Pitch / sizeof(WORD);
1448                 for (y = 0; y < 4; y++)
1449                 {
1450                     for (x = 0; x < 4; x++)
1451                     {
1452                         value = ((WORD *)lock_rect.pBits)[y * pitch + x];
1453                         v[0] = value >> 15;
1454                         v[1] = value >> 10 & 0x1f;
1455                         v[2] = value >> 5 & 0x1f;
1456                         v[3] = value & 0x1f;
1457 
1458                         e[0] = (f == 0) || (f == 1) ?
1459                             0 : (BYTE)(1.0f / size * 2.0f + 0.5f);
1460                         e[1] = get_cube_coord(coordmap[f][0], x, y, 4) / 4 * 31.0f + 0.5f;
1461                         e[2] = get_cube_coord(coordmap[f][1], x, y, 4) / 4 * 31.0f + 0.5f;
1462                         e[3] = get_cube_coord(coordmap[f][2], x, y, 4) / 4 * 31.0f + 0.5f;
1463                         expected = e[0] << 15 | e[1] << 10 | e[2] << 5 | e[3];
1464 
1465                         ok(color_match(v, e),
1466                            "Texel at face %u (%u, %u) doesn't match: %#x, expected %#x\n",
1467                            f, x, y, value, expected);
1468                     }
1469                 }
1470                 IDirect3DCubeTexture9_UnlockRect(tex, f, 0);
1471             }
1472         }
1473 
1474         IDirect3DCubeTexture9_Release(tex);
1475     }
1476     else
1477         skip("Failed to create texture\n");
1478 }
1479 
fillfunc_volume(D3DXVECTOR4 * value,const D3DXVECTOR3 * texcoord,const D3DXVECTOR3 * texelsize,void * data)1480 static void WINAPI fillfunc_volume(D3DXVECTOR4 *value, const D3DXVECTOR3 *texcoord,
1481                                    const D3DXVECTOR3 *texelsize, void *data)
1482 {
1483     value->x = texcoord->x;
1484     value->y = texcoord->y;
1485     value->z = texcoord->z;
1486     value->w = texelsize->x;
1487 }
1488 
test_D3DXFillVolumeTexture(IDirect3DDevice9 * device)1489 static void test_D3DXFillVolumeTexture(IDirect3DDevice9 *device)
1490 {
1491     IDirect3DVolumeTexture9 *tex;
1492     HRESULT hr;
1493     D3DLOCKED_BOX lock_box;
1494     DWORD x, y, z, m;
1495     DWORD v[4], e[4];
1496     DWORD value, expected, size, row_pitch, slice_pitch;
1497 
1498     size = 4;
1499     hr = IDirect3DDevice9_CreateVolumeTexture(device, size, size, size, 0, 0, D3DFMT_A8R8G8B8,
1500             D3DPOOL_DEFAULT, &tex, NULL);
1501     ok(hr == D3D_OK, "Unexpected hr %#x.\n", hr);
1502     hr = D3DXFillVolumeTexture(tex, fillfunc_volume, NULL);
1503     ok(hr == D3DERR_INVALIDCALL, "Unexpected hr %#x.\n", hr);
1504     IDirect3DVolumeTexture9_Release(tex);
1505 
1506     hr = IDirect3DDevice9_CreateVolumeTexture(device, size, size, size, 0, 0, D3DFMT_A8R8G8B8,
1507             D3DPOOL_MANAGED, &tex, NULL);
1508     if (SUCCEEDED(hr))
1509     {
1510         hr = D3DXFillVolumeTexture(tex, fillfunc_volume, NULL);
1511         ok(hr == D3D_OK, "D3DXFillVolumeTexture returned %#x, expected %#x\n", hr, D3D_OK);
1512 
1513         for (m = 0; m < 3; m++)
1514         {
1515             hr = IDirect3DVolumeTexture9_LockBox(tex, m, &lock_box, NULL, D3DLOCK_READONLY);
1516             ok(hr == D3D_OK, "Couldn't lock the texture, error %#x\n", hr);
1517             if (SUCCEEDED(hr))
1518             {
1519                 row_pitch = lock_box.RowPitch / sizeof(DWORD);
1520                 slice_pitch = lock_box.SlicePitch / sizeof(DWORD);
1521                 for (z = 0; z < size; z++)
1522                 {
1523                     for (y = 0; y < size; y++)
1524                     {
1525                         for (x = 0; x < size; x++)
1526                         {
1527                             value = ((DWORD *)lock_box.pBits)[z * slice_pitch + y * row_pitch + x];
1528                             v[0] = (value >> 24) & 0xff;
1529                             v[1] = (value >> 16) & 0xff;
1530                             v[2] = (value >> 8) & 0xff;
1531                             v[3] = value & 0xff;
1532 
1533                             e[0] = 255.0f / size + 0.5f;
1534                             e[1] = (x + 0.5f) / size * 255.0f + 0.5f;
1535                             e[2] = (y + 0.5f) / size * 255.0f + 0.5f;
1536                             e[3] = (z + 0.5f) / size * 255.0f + 0.5f;
1537                             expected = e[0] << 24 | e[1] << 16 | e[2] << 8 | e[3];
1538 
1539                             ok(color_match(v, e),
1540                                "Texel at (%u, %u, %u) doesn't match: %#x, expected %#x\n",
1541                                x, y, z, value, expected);
1542                         }
1543                     }
1544                 }
1545                 IDirect3DVolumeTexture9_UnlockBox(tex, m);
1546             }
1547             size >>= 1;
1548         }
1549 
1550         IDirect3DVolumeTexture9_Release(tex);
1551     }
1552     else
1553         skip("Failed to create texture\n");
1554 
1555     hr = IDirect3DDevice9_CreateVolumeTexture(device, 4, 4, 4, 1, 0, D3DFMT_A1R5G5B5,
1556                                               D3DPOOL_MANAGED, &tex, NULL);
1557 
1558     if (SUCCEEDED(hr))
1559     {
1560         hr = D3DXFillVolumeTexture(tex, fillfunc_volume, NULL);
1561         ok(hr == D3D_OK, "D3DXFillTexture returned %#x, expected %#x\n", hr, D3D_OK);
1562         hr = IDirect3DVolumeTexture9_LockBox(tex, 0, &lock_box, NULL, D3DLOCK_READONLY);
1563         ok(hr == D3D_OK, "Couldn't lock the texture, error %#x\n", hr);
1564         if (SUCCEEDED(hr))
1565         {
1566             row_pitch = lock_box.RowPitch / sizeof(WORD);
1567             slice_pitch = lock_box.SlicePitch / sizeof(WORD);
1568             for (z = 0; z < 4; z++)
1569             {
1570                 for (y = 0; y < 4; y++)
1571                 {
1572                     for (x = 0; x < 4; x++)
1573                     {
1574                         value = ((WORD *)lock_box.pBits)[z * slice_pitch + y * row_pitch + x];
1575                         v[0] = value >> 15;
1576                         v[1] = value >> 10 & 0x1f;
1577                         v[2] = value >> 5 & 0x1f;
1578                         v[3] = value & 0x1f;
1579 
1580                         e[0] = 1;
1581                         e[1] = (x + 0.5f) / 4 * 31.0f + 0.5f;
1582                         e[2] = (y + 0.5f) / 4 * 31.0f + 0.5f;
1583                         e[3] = (z + 0.5f) / 4 * 31.0f + 0.5f;
1584                         expected = e[0] << 15 | e[1] << 10 | e[2] << 5 | e[3];
1585 
1586                         ok(color_match(v, e),
1587                            "Texel at (%u, %u, %u) doesn't match: %#x, expected %#x\n",
1588                            x, y, z, value, expected);
1589                     }
1590                 }
1591             }
1592             IDirect3DVolumeTexture9_UnlockBox(tex, 0);
1593         }
1594 
1595         IDirect3DVolumeTexture9_Release(tex);
1596     }
1597     else
1598         skip("Failed to create texture\n");
1599 }
1600 
test_D3DXCreateTextureFromFileInMemory(IDirect3DDevice9 * device)1601 static void test_D3DXCreateTextureFromFileInMemory(IDirect3DDevice9 *device)
1602 {
1603     static const DWORD dds_dxt5_expected[] =
1604     {
1605         0xff7b207b, 0xff7b207b, 0xff84df7b, 0xff84df7b,
1606         0xff7b207b, 0xff7b207b, 0xff84df7b, 0xff84df7b,
1607         0xff7b207b, 0xff7b207b, 0xff84df7b, 0xff84df7b,
1608         0xff7b207b, 0xff7b207b, 0xff84df7b, 0xff84df7b,
1609     };
1610     static const DWORD dds_dxt5_8_8_expected[] =
1611     {
1612         0x0000ff00, 0x0000ff00, 0x000000ff, 0x000000ff, 0x3f00ffff, 0x3f00ffff, 0x3fff0000, 0x3fff0000,
1613         0x0000ff00, 0x0000ff00, 0x000000ff, 0x000000ff, 0x3f00ffff, 0x3f00ffff, 0x3fff0000, 0x3fff0000,
1614         0x000000ff, 0x000000ff, 0x0000ff00, 0x0000ff00, 0x3fff0000, 0x3fff0000, 0x3f00ffff, 0x3f00ffff,
1615         0x000000ff, 0x000000ff, 0x0000ff00, 0x0000ff00, 0x3fff0000, 0x3fff0000, 0x3f00ffff, 0x3f00ffff,
1616         0x7fffff00, 0x7fffff00, 0x7fff00ff, 0x7fff00ff, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff,
1617         0x7fffff00, 0x7fffff00, 0x7fff00ff, 0x7fff00ff, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff,
1618         0x7fff00ff, 0x7fff00ff, 0x7fffff00, 0x7fffff00, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000,
1619         0x7fff00ff, 0x7fff00ff, 0x7fffff00, 0x7fffff00, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000,
1620     };
1621     static const DWORD dds_dxt5_8_8_expected_misaligned_1[] =
1622     {
1623         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x3fff0000, 0x3fff0000, 0x3fff0000, 0x3fff0000,
1624         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x3fff0000, 0x3fff0000, 0x3fff0000, 0x3fff0000,
1625         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x3fff0000, 0x3fff0000, 0x3fff0000, 0x3fff0000,
1626         0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x3fff0000, 0x3fff0000, 0x3fff0000, 0x3fff0000,
1627         0x7fff00ff, 0x7fff00ff, 0x7fff00ff, 0x7fff00ff, 0xff000000, 0xff000000, 0xff000000, 0xff000000,
1628         0x7fff00ff, 0x7fff00ff, 0x7fff00ff, 0x7fff00ff, 0xff000000, 0xff000000, 0xff000000, 0xff000000,
1629         0x7fff00ff, 0x7fff00ff, 0x7fff00ff, 0x7fff00ff, 0xff000000, 0xff000000, 0xff000000, 0xff000000,
1630         0x7fff00ff, 0x7fff00ff, 0x7fff00ff, 0x7fff00ff, 0xff000000, 0xff000000, 0xff000000, 0xff000000,
1631     };
1632     static const DWORD dds_dxt5_8_8_expected_misaligned_3[] =
1633     {
1634         0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1635         0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1636         0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00, 0x3fff0000, 0x3fff0000, 0x00000000, 0x00000000,
1637         0x00000000, 0x00000000, 0x0000ff00, 0x0000ff00, 0x3fff0000, 0x3fff0000, 0x00000000, 0x00000000,
1638         0x00000000, 0x00000000, 0x7fff00ff, 0x7fff00ff, 0xff000000, 0xff000000, 0x00000000, 0x00000000,
1639         0x00000000, 0x00000000, 0x7fff00ff, 0x7fff00ff, 0xff000000, 0xff000000, 0x00000000, 0x00000000,
1640         0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1641         0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1642     };
1643     IDirect3DSurface9 *surface, *uncompressed_surface;
1644     IDirect3DTexture9 *texture;
1645     D3DLOCKED_RECT lock_rect;
1646     D3DRESOURCETYPE type;
1647     D3DSURFACE_DESC desc;
1648     unsigned int i, x, y;
1649     DWORD level_count;
1650     HRESULT hr;
1651     RECT rect;
1652 
1653     hr = D3DXCreateTextureFromFileInMemory(device, dds_16bit, sizeof(dds_16bit), &texture);
1654     ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
1655     if (SUCCEEDED(hr)) IDirect3DTexture9_Release(texture);
1656 
1657     hr = D3DXCreateTextureFromFileInMemory(device, dds_24bit, sizeof(dds_24bit), &texture);
1658     ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
1659     if (SUCCEEDED(hr)) IDirect3DTexture9_Release(texture);
1660 
1661     hr = D3DXCreateTextureFromFileInMemory(device, dds_24bit, sizeof(dds_24bit) - 1, &texture);
1662     ok(hr == D3DXERR_INVALIDDATA, "D3DXCreateTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DXERR_INVALIDDATA);
1663 
1664     /* Check that D3DXCreateTextureFromFileInMemory accepts cube texture dds file (only first face texture is loaded) */
1665     hr = D3DXCreateTextureFromFileInMemory(device, dds_cube_map, sizeof(dds_cube_map), &texture);
1666     ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemory returned %#x, expected %#x.\n", hr, D3D_OK);
1667     type = IDirect3DTexture9_GetType(texture);
1668     ok(type == D3DRTYPE_TEXTURE, "IDirect3DTexture9_GetType returned %u, expected %u.\n", type, D3DRTYPE_TEXTURE);
1669     hr = IDirect3DTexture9_GetLevelDesc(texture, 0, &desc);
1670     ok(hr == D3D_OK, "IDirect3DTexture9_GetLevelDesc returned %#x, expected %#x.\n", hr, D3D_OK);
1671     ok(desc.Width == 4, "Width is %u, expected 4.\n", desc.Width);
1672     ok(desc.Height == 4, "Height is %u, expected 4.\n", desc.Height);
1673     if (has_cube_dxt5)
1674     {
1675         ok(desc.Format == D3DFMT_DXT5, "Unexpected texture format %#x.\n", desc.Format);
1676         hr = IDirect3DTexture9_LockRect(texture, 0, &lock_rect, NULL, D3DLOCK_READONLY);
1677         ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %#x, expected %#x\n", hr, D3D_OK);
1678         if (SUCCEEDED(hr))
1679         {
1680             for (i = 0; i < 16; i++)
1681                 ok(((BYTE *)lock_rect.pBits)[i] == dds_cube_map[128 + i],
1682                         "Byte at index %u is 0x%02x, expected 0x%02x.\n",
1683                         i, ((BYTE *)lock_rect.pBits)[i], dds_cube_map[128 + i]);
1684             IDirect3DTexture9_UnlockRect(texture, 0);
1685         }
1686     }
1687     else
1688     {
1689         ok(desc.Format == D3DFMT_A8R8G8B8, "Unexpected texture format %#x.\n", desc.Format);
1690         skip("D3DFMT_DXT5 textures are not supported, skipping a test.\n");
1691     }
1692     IDirect3DTexture9_Release(texture);
1693 
1694     /* Test with a DXT5 texture smaller than the block size. */
1695     hr = D3DXCreateTextureFromFileInMemory(device, dds_dxt5, sizeof(dds_dxt5), &texture);
1696     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1697     if (SUCCEEDED(hr) && has_2d_dxt5)
1698     {
1699         type = IDirect3DTexture9_GetType(texture);
1700         ok(type == D3DRTYPE_TEXTURE, "Got unexpected type %u.\n", type);
1701         hr = IDirect3DTexture9_GetLevelDesc(texture, 0, &desc);
1702         ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1703         ok(desc.Width == 4, "Got unexpected width %u.\n", desc.Width);
1704         ok(desc.Height == 4, "Got unexpected height %u.\n", desc.Height);
1705 
1706         IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
1707         hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 4, 4, D3DFMT_A8R8G8B8,
1708                 D3DPOOL_DEFAULT, &uncompressed_surface, NULL);
1709         ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1710         hr = D3DXLoadSurfaceFromSurface(uncompressed_surface, NULL, NULL, surface, NULL, NULL, D3DX_FILTER_NONE, 0);
1711         ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1712         hr = IDirect3DSurface9_LockRect(uncompressed_surface, &lock_rect, NULL, D3DLOCK_READONLY);
1713         ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1714         for (y = 0; y < 4; ++y)
1715         {
1716             for (x = 0; x < 4; ++x)
1717             {
1718                 /* Use a large tolerance, decompression + stretching +
1719                  * compression + decompression again introduce quite a bit of
1720                  * precision loss. */
1721                 ok(compare_color(((DWORD *)lock_rect.pBits)[lock_rect.Pitch / 4 * y + x],
1722                         dds_dxt5_expected[y * 4 + x], 32),
1723                         "Color at position %u, %u is 0x%08x, expected 0x%08x.\n",
1724                         x, y, ((DWORD *)lock_rect.pBits)[lock_rect.Pitch / 4 * y + x],
1725                         dds_dxt5_expected[y * 4 + x]);
1726             }
1727         }
1728         hr = IDirect3DSurface9_UnlockRect(uncompressed_surface);
1729         ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1730 
1731         IDirect3DSurface9_Release(uncompressed_surface);
1732         IDirect3DSurface9_Release(surface);
1733     }
1734     if (SUCCEEDED(hr))
1735         IDirect3DTexture9_Release(texture);
1736 
1737     /* Test with a larger DXT5 texture. */
1738     hr = D3DXCreateTextureFromFileInMemory(device, dds_dxt5_8_8, sizeof(dds_dxt5_8_8), &texture);
1739     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1740     type = IDirect3DTexture9_GetType(texture);
1741     ok(type == D3DRTYPE_TEXTURE, "Got unexpected type %u.\n", type);
1742     hr = IDirect3DTexture9_GetLevelDesc(texture, 0, &desc);
1743     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1744     ok(desc.Width == 8, "Got unexpected width %u.\n", desc.Width);
1745     ok(desc.Height == 8, "Got unexpected height %u.\n", desc.Height);
1746     IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
1747 
1748     hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 8, 8, D3DFMT_A8R8G8B8,
1749             D3DPOOL_DEFAULT, &uncompressed_surface, NULL);
1750     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1751     hr = D3DXLoadSurfaceFromSurface(uncompressed_surface, NULL, NULL, surface, NULL, NULL, D3DX_FILTER_NONE, 0);
1752     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1753     if (SUCCEEDED(hr))
1754     {
1755         hr = IDirect3DSurface9_LockRect(uncompressed_surface, &lock_rect, NULL, D3DLOCK_READONLY);
1756         ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1757         for (y = 0; y < 8; ++y)
1758         {
1759             for (x = 0; x < 8; ++x)
1760             {
1761                 ok(compare_color(((DWORD *)lock_rect.pBits)[lock_rect.Pitch / 4 * y + x],
1762                         dds_dxt5_8_8_expected[y * 8 + x], 0),
1763                         "Color at position %u, %u is 0x%08x, expected 0x%08x.\n",
1764                         x, y, ((DWORD *)lock_rect.pBits)[lock_rect.Pitch / 4 * y + x],
1765                         dds_dxt5_8_8_expected[y * 8 + x]);
1766             }
1767         }
1768         hr = IDirect3DSurface9_UnlockRect(uncompressed_surface);
1769         ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1770     }
1771 
1772     hr = IDirect3DSurface9_LockRect(surface, &lock_rect, NULL, D3DLOCK_READONLY);
1773     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1774     for (y = 0; y < 2; ++y)
1775         memset(&((BYTE *)lock_rect.pBits)[y * lock_rect.Pitch], 0, 16 * 2);
1776     hr = IDirect3DSurface9_UnlockRect(surface);
1777     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1778 
1779     SetRect(&rect, 2, 2, 6, 6);
1780     hr = D3DXLoadSurfaceFromMemory(surface, NULL, NULL, &dds_dxt5_8_8[128],
1781             D3DFMT_DXT5, 16 * 2, NULL, &rect, D3DX_FILTER_POINT, 0);
1782     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1783     hr = D3DXLoadSurfaceFromSurface(uncompressed_surface, NULL, NULL, surface, NULL, NULL, D3DX_FILTER_NONE, 0);
1784     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1785 
1786     hr = IDirect3DSurface9_LockRect(uncompressed_surface, &lock_rect, NULL, D3DLOCK_READONLY);
1787     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1788     for (y = 0; y < 8; ++y)
1789     {
1790         for (x = 0; x < 8; ++x)
1791         {
1792             ok(compare_color(((DWORD *)lock_rect.pBits)[lock_rect.Pitch / 4 * y + x],
1793                     dds_dxt5_8_8_expected_misaligned_1[y * 8 + x], 0),
1794                     "Color at position %u, %u is 0x%08x, expected 0x%08x.\n",
1795                     x, y, ((DWORD *)lock_rect.pBits)[lock_rect.Pitch / 4 * y + x],
1796                     dds_dxt5_8_8_expected_misaligned_1[y * 8 + x]);
1797         }
1798     }
1799     hr = IDirect3DSurface9_UnlockRect(uncompressed_surface);
1800     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1801 
1802     hr = IDirect3DSurface9_LockRect(surface, &lock_rect, NULL, D3DLOCK_READONLY);
1803     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1804     for (y = 0; y < 2; ++y)
1805         memset(&((BYTE *)lock_rect.pBits)[y * lock_rect.Pitch], 0, 16 * 2);
1806     hr = IDirect3DSurface9_UnlockRect(surface);
1807     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1808 
1809     hr = D3DXLoadSurfaceFromMemory(surface, NULL, &rect, &dds_dxt5_8_8[128],
1810             D3DFMT_DXT5, 16 * 2, NULL, NULL, D3DX_FILTER_POINT, 0);
1811     ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
1812 
1813     hr = D3DXLoadSurfaceFromMemory(surface, NULL, &rect, &dds_dxt5_8_8[128],
1814             D3DFMT_DXT5, 16 * 2, NULL, &rect, D3DX_FILTER_POINT, 0);
1815     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1816     hr = D3DXLoadSurfaceFromSurface(uncompressed_surface, NULL, NULL, surface, NULL, NULL, D3DX_FILTER_NONE, 0);
1817     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1818 
1819     hr = IDirect3DSurface9_LockRect(uncompressed_surface, &lock_rect, NULL, D3DLOCK_READONLY);
1820     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1821     for (y = 0; y < 8; ++y)
1822     {
1823         for (x = 0; x < 8; ++x)
1824         {
1825             ok(compare_color(((DWORD *)lock_rect.pBits)[lock_rect.Pitch / 4 * y + x],
1826                     dds_dxt5_8_8_expected_misaligned_3[y * 8 + x], 0),
1827                     "Color at position %u, %u is 0x%08x, expected 0x%08x.\n",
1828                     x, y, ((DWORD *)lock_rect.pBits)[lock_rect.Pitch / 4 * y + x],
1829                     dds_dxt5_8_8_expected_misaligned_3[y * 8 + x]);
1830         }
1831     }
1832     hr = IDirect3DSurface9_UnlockRect(uncompressed_surface);
1833     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1834 
1835     hr = D3DXLoadSurfaceFromFileInMemory(surface, NULL, &rect, dds_dxt5_8_8,
1836             sizeof(dds_dxt5_8_8), &rect, D3DX_FILTER_POINT, 0, NULL);
1837     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1838     hr = D3DXLoadSurfaceFromSurface(uncompressed_surface, NULL, NULL, surface, NULL, NULL, D3DX_FILTER_NONE, 0);
1839     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1840 
1841     hr = IDirect3DSurface9_LockRect(uncompressed_surface, &lock_rect, NULL, D3DLOCK_READONLY);
1842     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1843     for (y = 0; y < 8; ++y)
1844     {
1845         for (x = 0; x < 8; ++x)
1846         {
1847             ok(compare_color(((DWORD *)lock_rect.pBits)[lock_rect.Pitch / 4 * y + x],
1848                     dds_dxt5_8_8_expected_misaligned_3[y * 8 + x], 0),
1849                     "Color at position %u, %u is 0x%08x, expected 0x%08x.\n",
1850                     x, y, ((DWORD *)lock_rect.pBits)[lock_rect.Pitch / 4 * y + x],
1851                     dds_dxt5_8_8_expected_misaligned_3[y * 8 + x]);
1852         }
1853     }
1854     hr = IDirect3DSurface9_UnlockRect(uncompressed_surface);
1855     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
1856 
1857     IDirect3DSurface9_Release(uncompressed_surface);
1858     IDirect3DSurface9_Release(surface);
1859     IDirect3DTexture9_Release(texture);
1860 
1861     /* Volume textures work too. */
1862     hr = D3DXCreateTextureFromFileInMemory(device, dds_volume_map, sizeof(dds_volume_map), &texture);
1863     ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemory returned %#x, expected %#x.\n", hr, D3D_OK);
1864     type = IDirect3DTexture9_GetType(texture);
1865     ok(type == D3DRTYPE_TEXTURE, "IDirect3DTexture9_GetType returned %u, expected %u.\n", type, D3DRTYPE_TEXTURE);
1866     level_count = IDirect3DBaseTexture9_GetLevelCount((IDirect3DBaseTexture9 *)texture);
1867     todo_wine ok(level_count == 3, "Texture has %u mip levels, 3 expected.\n", level_count);
1868     hr = IDirect3DTexture9_GetLevelDesc(texture, 0, &desc);
1869     ok(hr == D3D_OK, "IDirect3DTexture9_GetLevelDesc returned %#x, expected %#x.\n", hr, D3D_OK);
1870     ok(desc.Width == 4, "Width is %u, expected 4.\n", desc.Width);
1871     ok(desc.Height == 4, "Height is %u, expected 4.\n", desc.Height);
1872 
1873     if (has_2d_dxt3)
1874     {
1875         ok(desc.Format == D3DFMT_DXT3, "Unexpected texture format %#x.\n", desc.Format);
1876         hr = IDirect3DTexture9_LockRect(texture, 0, &lock_rect, NULL, D3DLOCK_READONLY);
1877         ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %#x, expected %#x.\n", hr, D3D_OK);
1878         if (SUCCEEDED(hr))
1879         {
1880             for (i = 0; i < 16; ++i)
1881                 ok(((BYTE *)lock_rect.pBits)[i] == dds_volume_map[128 + i],
1882                         "Byte at index %u is 0x%02x, expected 0x%02x.\n",
1883                         i, ((BYTE *)lock_rect.pBits)[i], dds_volume_map[128 + i]);
1884             IDirect3DTexture9_UnlockRect(texture, 0);
1885         }
1886     }
1887     else
1888     {
1889         ok(desc.Format == D3DFMT_A8R8G8B8, "Unexpected texture format %#x.\n", desc.Format);
1890         skip("D3DFMT_DXT3 volume textures are not supported, skipping a test.\n");
1891     }
1892     /* The lower texture levels are apparently generated by filtering the level 0 surface
1893      * I.e. following levels from the file are ignored. */
1894     IDirect3DTexture9_Release(texture);
1895 }
1896 
test_D3DXCreateTextureFromFileInMemoryEx(IDirect3DDevice9 * device)1897 static void test_D3DXCreateTextureFromFileInMemoryEx(IDirect3DDevice9 *device)
1898 {
1899     HRESULT hr;
1900     IDirect3DTexture9 *texture;
1901     unsigned int miplevels;
1902     IDirect3DSurface9 *surface;
1903     D3DSURFACE_DESC desc;
1904 
1905     hr = D3DXCreateTextureFromFileInMemoryEx(device, dds_16bit, sizeof(dds_16bit), D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT,
1906         0, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &texture);
1907     ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemoryEx returned %#x, expected %#x\n", hr, D3D_OK);
1908     IDirect3DTexture9_Release(texture);
1909 
1910     hr = D3DXCreateTextureFromFileInMemoryEx(device, dds_16bit, sizeof(dds_16bit), D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT,
1911         D3DUSAGE_DYNAMIC, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &texture);
1912     ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemoryEx returned %#x, expected %#x\n", hr, D3D_OK);
1913     IDirect3DTexture9_Release(texture);
1914 
1915     hr = D3DXCreateTextureFromFileInMemoryEx(device, dds_24bit, sizeof(dds_24bit), D3DX_DEFAULT,
1916             D3DX_DEFAULT, D3DX_DEFAULT, D3DUSAGE_DYNAMIC, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT,
1917             D3DX_DEFAULT, D3DX_SKIP_DDS_MIP_LEVELS(1, D3DX_FILTER_POINT), 0, NULL, NULL, &texture);
1918     ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemoryEx returned %#x, expected %#x\n", hr, D3D_OK);
1919     miplevels = IDirect3DTexture9_GetLevelCount(texture);
1920     ok(miplevels == 1, "Got miplevels %u, expected %u.\n", miplevels, 1);
1921     IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
1922     IDirect3DSurface9_GetDesc(surface, &desc);
1923     ok(desc.Width == 1 && desc.Height == 1,
1924             "Surface dimensions are %ux%u, expected 1x1.\n", desc.Width, desc.Height);
1925     IDirect3DSurface9_Release(surface);
1926     IDirect3DTexture9_Release(texture);
1927 
1928     if (!is_autogenmipmap_supported(device, D3DRTYPE_TEXTURE))
1929     {
1930         skip("No D3DUSAGE_AUTOGENMIPMAP support for textures\n");
1931         return;
1932     }
1933 
1934     hr = D3DXCreateTextureFromFileInMemoryEx(device, dds_16bit, sizeof(dds_16bit), D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT,
1935         D3DUSAGE_DYNAMIC | D3DUSAGE_AUTOGENMIPMAP, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &texture);
1936     ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemoryEx returned %#x, expected %#x\n", hr, D3D_OK);
1937     IDirect3DTexture9_Release(texture);
1938 
1939     /* Checking for color key format overrides. */
1940     hr = D3DXCreateTextureFromFileInMemoryEx(device, dds_16bit, sizeof(dds_16bit),
1941             D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT,
1942             D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &texture);
1943     ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemoryEx returned %#x, expected %#x.\n", hr, D3D_OK);
1944     IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
1945     IDirect3DSurface9_GetDesc(surface, &desc);
1946     ok(desc.Format == D3DFMT_X1R5G5B5, "Returned format %u, expected %u.\n", desc.Format, D3DFMT_X1R5G5B5);
1947     IDirect3DSurface9_Release(surface);
1948     IDirect3DTexture9_Release(texture);
1949     hr = D3DXCreateTextureFromFileInMemoryEx(device, dds_16bit, sizeof(dds_16bit),
1950             D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT,
1951             D3DX_DEFAULT, D3DX_DEFAULT, 0xff000000, NULL, NULL, &texture);
1952     ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemoryEx returned %#x, expected %#x.\n", hr, D3D_OK);
1953     IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
1954     IDirect3DSurface9_GetDesc(surface, &desc);
1955     ok(desc.Format == D3DFMT_A1R5G5B5, "Returned format %u, expected %u.\n", desc.Format, D3DFMT_A1R5G5B5);
1956     IDirect3DSurface9_Release(surface);
1957     IDirect3DTexture9_Release(texture);
1958     hr = D3DXCreateTextureFromFileInMemoryEx(device, dds_16bit, sizeof(dds_16bit),
1959             D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_X1R5G5B5, D3DPOOL_DEFAULT,
1960             D3DX_DEFAULT, D3DX_DEFAULT, 0xff000000, NULL, NULL, &texture);
1961     ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemoryEx returned %#x, expected %#x.\n", hr, D3D_OK);
1962     IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
1963     IDirect3DSurface9_GetDesc(surface, &desc);
1964     ok(desc.Format == D3DFMT_X1R5G5B5, "Returned format %u, expected %u.\n", desc.Format, D3DFMT_X1R5G5B5);
1965     IDirect3DSurface9_Release(surface);
1966     IDirect3DTexture9_Release(texture);
1967 
1968     hr = D3DXCreateTextureFromFileInMemoryEx(device, dds_24bit, sizeof(dds_24bit),
1969             D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT,
1970             D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &texture);
1971     ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemoryEx returned %#x, expected %#x.\n", hr, D3D_OK);
1972     IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
1973     IDirect3DSurface9_GetDesc(surface, &desc);
1974     ok(desc.Format == D3DFMT_X8R8G8B8, "Returned format %u, expected %u.\n", desc.Format, D3DFMT_X8R8G8B8);
1975     IDirect3DSurface9_Release(surface);
1976     IDirect3DTexture9_Release(texture);
1977     hr = D3DXCreateTextureFromFileInMemoryEx(device, dds_24bit, sizeof(dds_24bit),
1978             D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT,
1979             D3DX_DEFAULT, D3DX_DEFAULT, 0xff000000, NULL, NULL, &texture);
1980     ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemoryEx returned %#x, expected %#x.\n", hr, D3D_OK);
1981     IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
1982     IDirect3DSurface9_GetDesc(surface, &desc);
1983     ok(desc.Format == D3DFMT_A8R8G8B8, "Returned format %u, expected %u.\n", desc.Format, D3DFMT_A8R8G8B8);
1984     IDirect3DSurface9_Release(surface);
1985     IDirect3DTexture9_Release(texture);
1986     hr = D3DXCreateTextureFromFileInMemoryEx(device, dds_24bit, sizeof(dds_24bit),
1987             D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT,
1988             D3DX_DEFAULT, D3DX_DEFAULT, 0xff000000, NULL, NULL, &texture);
1989     ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemoryEx returned %#x, expected %#x.\n", hr, D3D_OK);
1990     IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
1991     IDirect3DSurface9_GetDesc(surface, &desc);
1992     ok(desc.Format == D3DFMT_X8R8G8B8, "Returned format %u, expected %u.\n", desc.Format, D3DFMT_X8R8G8B8);
1993     IDirect3DSurface9_Release(surface);
1994     IDirect3DTexture9_Release(texture);
1995 
1996     hr = D3DXCreateTextureFromFileInMemoryEx(device, png_grayscale, sizeof(png_grayscale),
1997             D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT,
1998             D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &texture);
1999     ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemoryEx returned %#x, expected %#x.\n", hr, D3D_OK);
2000     IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
2001     IDirect3DSurface9_GetDesc(surface, &desc);
2002     ok(desc.Format == D3DFMT_L8, "Returned format %u, expected %u.\n", desc.Format, D3DFMT_L8);
2003     IDirect3DSurface9_Release(surface);
2004     IDirect3DTexture9_Release(texture);
2005     hr = D3DXCreateTextureFromFileInMemoryEx(device, png_grayscale, sizeof(png_grayscale),
2006             D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT,
2007             D3DX_DEFAULT, D3DX_DEFAULT, 0xff000000, NULL, NULL, &texture);
2008     ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemoryEx returned %#x, expected %#x.\n", hr, D3D_OK);
2009     IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
2010     IDirect3DSurface9_GetDesc(surface, &desc);
2011     ok(desc.Format == D3DFMT_A8L8, "Returned format %u, expected %u.\n", desc.Format, D3DFMT_A8L8);
2012     IDirect3DSurface9_Release(surface);
2013     IDirect3DTexture9_Release(texture);
2014     hr = D3DXCreateTextureFromFileInMemoryEx(device, png_grayscale, sizeof(png_grayscale),
2015             D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_L8, D3DPOOL_DEFAULT,
2016             D3DX_DEFAULT, D3DX_DEFAULT, 0xff000000, NULL, NULL, &texture);
2017     ok(hr == D3D_OK, "D3DXCreateTextureFromFileInMemoryEx returned %#x, expected %#x.\n", hr, D3D_OK);
2018     IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
2019     IDirect3DSurface9_GetDesc(surface, &desc);
2020     ok(desc.Format == D3DFMT_L8, "Returned format %u, expected %u.\n", desc.Format, D3DFMT_L8);
2021     IDirect3DSurface9_Release(surface);
2022     IDirect3DTexture9_Release(texture);
2023 }
2024 
test_D3DXCreateCubeTextureFromFileInMemory(IDirect3DDevice9 * device)2025 static void test_D3DXCreateCubeTextureFromFileInMemory(IDirect3DDevice9 *device)
2026 {
2027     HRESULT hr;
2028     ULONG ref;
2029     DWORD levelcount;
2030     IDirect3DCubeTexture9 *cube_texture;
2031     D3DSURFACE_DESC surface_desc;
2032 
2033     hr = D3DXCreateCubeTextureFromFileInMemory(NULL, dds_cube_map, sizeof(dds_cube_map), &cube_texture);
2034     ok(hr == D3DERR_INVALIDCALL, "D3DXCreateCubeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
2035 
2036     hr = D3DXCreateCubeTextureFromFileInMemory(device, NULL, sizeof(dds_cube_map), &cube_texture);
2037     ok(hr == D3DERR_INVALIDCALL, "D3DXCreateCubeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
2038 
2039     hr = D3DXCreateCubeTextureFromFileInMemory(device, dds_cube_map, 0, &cube_texture);
2040     ok(hr == D3DERR_INVALIDCALL, "D3DXCreateCubeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
2041 
2042     hr = D3DXCreateCubeTextureFromFileInMemory(device, dds_cube_map, sizeof(dds_cube_map), NULL);
2043     ok(hr == D3DERR_INVALIDCALL, "D3DXCreateCubeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
2044 
2045     hr = D3DXCreateCubeTextureFromFileInMemory(device, dds_cube_map, sizeof(dds_cube_map), &cube_texture);
2046     if (SUCCEEDED(hr))
2047     {
2048         levelcount = IDirect3DCubeTexture9_GetLevelCount(cube_texture);
2049         ok(levelcount == 3, "GetLevelCount returned %u, expected 3\n", levelcount);
2050 
2051         hr = IDirect3DCubeTexture9_GetLevelDesc(cube_texture, 0, &surface_desc);
2052         ok(hr == D3D_OK, "GetLevelDesc returned %#x, expected %#x\n", hr, D3D_OK);
2053         ok(surface_desc.Width == 4, "Got width %u, expected 4\n", surface_desc.Width);
2054         ok(surface_desc.Height == 4, "Got height %u, expected 4\n", surface_desc.Height);
2055 
2056         ref = IDirect3DCubeTexture9_Release(cube_texture);
2057         ok(ref == 0, "Invalid reference count. Got %u, expected 0\n", ref);
2058     } else skip("Couldn't create cube texture\n");
2059 }
2060 
test_D3DXCreateCubeTextureFromFileInMemoryEx(IDirect3DDevice9 * device)2061 static void test_D3DXCreateCubeTextureFromFileInMemoryEx(IDirect3DDevice9 *device)
2062 {
2063     IDirect3DCubeTexture9 *cube_texture;
2064     HRESULT hr;
2065 
2066     hr = D3DXCreateCubeTextureFromFileInMemoryEx(device, dds_cube_map, sizeof(dds_cube_map), D3DX_DEFAULT,
2067             D3DX_DEFAULT, D3DUSAGE_RENDERTARGET, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, D3DX_DEFAULT,
2068             D3DX_DEFAULT, 0, NULL, NULL, &cube_texture);
2069     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2070     IDirect3DCubeTexture9_Release(cube_texture);
2071 
2072     if (!is_autogenmipmap_supported(device, D3DRTYPE_CUBETEXTURE))
2073     {
2074         skip("No D3DUSAGE_AUTOGENMIPMAP support for cube textures\n");
2075         return;
2076     }
2077 
2078     hr = D3DXCreateCubeTextureFromFileInMemoryEx(device, dds_cube_map, sizeof(dds_cube_map), D3DX_DEFAULT,
2079             D3DX_DEFAULT, D3DUSAGE_DYNAMIC | D3DUSAGE_AUTOGENMIPMAP, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT,
2080             D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &cube_texture);
2081     ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
2082     IDirect3DCubeTexture9_Release(cube_texture);
2083 }
2084 
test_D3DXCreateVolumeTextureFromFileInMemory(IDirect3DDevice9 * device)2085 static void test_D3DXCreateVolumeTextureFromFileInMemory(IDirect3DDevice9 *device)
2086 {
2087     HRESULT hr;
2088     ULONG ref;
2089     DWORD levelcount;
2090     IDirect3DVolumeTexture9 *volume_texture;
2091     D3DVOLUME_DESC volume_desc;
2092 
2093     hr = D3DXCreateVolumeTextureFromFileInMemory(NULL, dds_volume_map, sizeof(dds_volume_map), &volume_texture);
2094     ok(hr == D3DERR_INVALIDCALL, "D3DXCreateVolumeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
2095 
2096     hr = D3DXCreateVolumeTextureFromFileInMemory(device, NULL, sizeof(dds_volume_map), &volume_texture);
2097     ok(hr == D3DERR_INVALIDCALL, "D3DXCreateVolumeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
2098 
2099     hr = D3DXCreateVolumeTextureFromFileInMemory(device, dds_volume_map, 0, &volume_texture);
2100     ok(hr == D3DERR_INVALIDCALL, "D3DXCreateVolumeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
2101 
2102     hr = D3DXCreateVolumeTextureFromFileInMemory(device, dds_volume_map, sizeof(dds_volume_map), NULL);
2103     ok(hr == D3DERR_INVALIDCALL, "D3DXCreateVolumeTextureFromFileInMemory returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
2104 
2105     hr = D3DXCreateVolumeTextureFromFileInMemory(device, dds_volume_map, sizeof(dds_volume_map), &volume_texture);
2106     ok(hr == D3D_OK, "D3DXCreateVolumeTextureFromFileInMemory returned %#x, expected %#x.\n", hr, D3D_OK);
2107     levelcount = IDirect3DVolumeTexture9_GetLevelCount(volume_texture);
2108     ok(levelcount == 3, "GetLevelCount returned %u, expected 3.\n", levelcount);
2109 
2110     hr = IDirect3DVolumeTexture9_GetLevelDesc(volume_texture, 0, &volume_desc);
2111     ok(hr == D3D_OK, "GetLevelDesc returned %#x, expected %#x.\n", hr, D3D_OK);
2112     ok(volume_desc.Width == 4, "Got width %u, expected 4.\n", volume_desc.Width);
2113     ok(volume_desc.Height == 4, "Got height %u, expected 4.\n", volume_desc.Height);
2114     ok(volume_desc.Depth == 2, "Got depth %u, expected 2.\n", volume_desc.Depth);
2115     ok(volume_desc.Pool == D3DPOOL_MANAGED, "Got pool %u, expected D3DPOOL_MANAGED.\n", volume_desc.Pool);
2116 
2117     hr = IDirect3DVolumeTexture9_GetLevelDesc(volume_texture, 1, &volume_desc);
2118     ok(hr == D3D_OK, "GetLevelDesc returned %#x, expected %#x.\n", hr, D3D_OK);
2119     ok(volume_desc.Width == 2, "Got width %u, expected 2.\n", volume_desc.Width);
2120     ok(volume_desc.Height == 2, "Got height %u, expected 2.\n", volume_desc.Height);
2121     ok(volume_desc.Depth == 1, "Got depth %u, expected 1.\n", volume_desc.Depth);
2122 
2123     ref = IDirect3DVolumeTexture9_Release(volume_texture);
2124     ok(ref == 0, "Invalid reference count. Got %u, expected 0.\n", ref);
2125 }
2126 
test_D3DXCreateVolumeTextureFromFileInMemoryEx(IDirect3DDevice9 * device)2127 static void test_D3DXCreateVolumeTextureFromFileInMemoryEx(IDirect3DDevice9 *device)
2128 {
2129     IDirect3DVolumeTexture9 *volume_texture;
2130     HRESULT hr;
2131 
2132     hr = D3DXCreateVolumeTextureFromFileInMemoryEx(device, dds_volume_map, sizeof(dds_volume_map), D3DX_DEFAULT,
2133             D3DX_DEFAULT, D3DX_DEFAULT, 1, D3DUSAGE_RENDERTARGET, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, D3DX_DEFAULT,
2134             D3DX_DEFAULT, 0, NULL, NULL, &volume_texture);
2135     ok(hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x.\n", hr);
2136 
2137     hr = D3DXCreateVolumeTextureFromFileInMemoryEx(device, dds_volume_map, sizeof(dds_volume_map), D3DX_DEFAULT,
2138             D3DX_DEFAULT, D3DX_DEFAULT, 1, D3DUSAGE_DEPTHSTENCIL, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, D3DX_DEFAULT,
2139             D3DX_DEFAULT, 0, NULL, NULL, &volume_texture);
2140     ok(hr == D3DERR_NOTAVAILABLE, "Got unexpected hr %#x.\n", hr);
2141 }
2142 
2143 /* fills positive x face with red color */
fill_cube_positive_x(D3DXVECTOR4 * out,const D3DXVECTOR3 * tex_coord,const D3DXVECTOR3 * texel_size,void * data)2144 static void WINAPI fill_cube_positive_x(D3DXVECTOR4 *out, const D3DXVECTOR3 *tex_coord, const D3DXVECTOR3 *texel_size, void *data)
2145 {
2146     memset(out, 0, sizeof(*out));
2147     if (tex_coord->x > 0 && fabs(tex_coord->x) > fabs(tex_coord->y) && fabs(tex_coord->x) > fabs(tex_coord->z))
2148         out->x = 1;
2149 }
2150 
test_D3DXSaveTextureToFileInMemory(IDirect3DDevice9 * device)2151 static void test_D3DXSaveTextureToFileInMemory(IDirect3DDevice9 *device)
2152 {
2153     HRESULT hr;
2154     IDirect3DTexture9 *texture;
2155     IDirect3DCubeTexture9 *cube_texture;
2156     IDirect3DVolumeTexture9 *volume_texture;
2157     ID3DXBuffer *buffer;
2158     void *buffer_pointer;
2159     DWORD buffer_size;
2160     D3DXIMAGE_INFO info;
2161     D3DXIMAGE_FILEFORMAT file_format;
2162 
2163     /* textures */
2164     hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 0, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
2165     if (FAILED(hr))
2166     {
2167         skip("Failed to create texture\n");
2168         return;
2169     }
2170 
2171     for (file_format = D3DXIFF_BMP; file_format <= D3DXIFF_JPG; file_format++)
2172     {
2173         hr = D3DXSaveTextureToFileInMemory(&buffer, file_format, (IDirect3DBaseTexture9 *)texture, NULL);
2174         ok(hr == D3D_OK, "D3DXSaveTextureToFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
2175         if (SUCCEEDED(hr))
2176         {
2177             buffer_pointer = ID3DXBuffer_GetBufferPointer(buffer);
2178             buffer_size = ID3DXBuffer_GetBufferSize(buffer);
2179             hr = D3DXGetImageInfoFromFileInMemory(buffer_pointer, buffer_size, &info);
2180             ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
2181 
2182             ok(info.Width == 256, "Got width %u, expected %u\n", info.Width, 256);
2183             ok(info.Height == 256, "Got height %u, expected %u\n", info.Height, 256);
2184             ok(info.MipLevels == 1, "Got miplevels %u, expected %u\n", info.MipLevels, 1);
2185             ok(info.ResourceType == D3DRTYPE_TEXTURE, "Got resource type %#x, expected %#x\n", info.ResourceType, D3DRTYPE_TEXTURE);
2186             ok(info.ImageFileFormat == file_format, "Got file format %#x, expected %#x\n", info.ImageFileFormat, file_format);
2187             ID3DXBuffer_Release(buffer);
2188         }
2189     }
2190 
2191     todo_wine {
2192     hr = D3DXSaveTextureToFileInMemory(&buffer, D3DXIFF_DDS, (IDirect3DBaseTexture9 *)texture, NULL);
2193     ok(hr == D3D_OK, "D3DXSaveTextureToFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
2194     if (SUCCEEDED(hr))
2195     {
2196         buffer_pointer = ID3DXBuffer_GetBufferPointer(buffer);
2197         buffer_size = ID3DXBuffer_GetBufferSize(buffer);
2198         hr = D3DXGetImageInfoFromFileInMemory(buffer_pointer, buffer_size, &info);
2199         ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
2200 
2201         ok(info.Width == 256, "Got width %u, expected %u\n", info.Width, 256);
2202         ok(info.Height == 256, "Got height %u, expected %u\n", info.Height, 256);
2203         ok(info.MipLevels == 9, "Got miplevels %u, expected %u\n", info.MipLevels, 9);
2204         ok(info.ResourceType == D3DRTYPE_TEXTURE, "Got resource type %#x, expected %#x\n", info.ResourceType, D3DRTYPE_TEXTURE);
2205         ok(info.ImageFileFormat == D3DXIFF_DDS, "Got file format %#x, expected %#x\n", info.ImageFileFormat, D3DXIFF_DDS);
2206         ID3DXBuffer_Release(buffer);
2207     }
2208     }
2209 
2210     IDirect3DTexture9_Release(texture);
2211 
2212     /* cube textures */
2213     hr = IDirect3DDevice9_CreateCubeTexture(device, 256, 0, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &cube_texture, NULL);
2214     if (FAILED(hr))
2215     {
2216         skip("Failed to create cube texture\n");
2217         return;
2218     }
2219 
2220     hr = D3DXFillCubeTexture(cube_texture, fill_cube_positive_x, NULL);
2221     ok(hr == D3D_OK, "D3DXFillCubeTexture returned %#x, expected %#x\n", hr, D3D_OK);
2222 
2223     hr = D3DXSaveTextureToFileInMemory(&buffer, D3DXIFF_BMP, (IDirect3DBaseTexture9 *)cube_texture, NULL);
2224     ok(hr == D3D_OK, "D3DXSaveTextureToFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
2225     if (SUCCEEDED(hr))
2226     {
2227         IDirect3DSurface9 *surface;
2228 
2229         buffer_pointer = ID3DXBuffer_GetBufferPointer(buffer);
2230         buffer_size = ID3DXBuffer_GetBufferSize(buffer);
2231         hr = D3DXGetImageInfoFromFileInMemory(buffer_pointer, buffer_size, &info);
2232         ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
2233 
2234         ok(info.Width == 256, "Got width %u, expected %u\n", info.Width, 256);
2235         ok(info.Height == 256, "Got height %u, expected %u\n", info.Height, 256);
2236         ok(info.MipLevels == 1, "Got miplevels %u, expected %u\n", info.MipLevels, 1);
2237         ok(info.ResourceType == D3DRTYPE_TEXTURE, "Got resource type %#x, expected %#x\n", info.ResourceType, D3DRTYPE_TEXTURE);
2238         ok(info.ImageFileFormat == D3DXIFF_BMP, "Got file format %#x, expected %#x\n", info.ImageFileFormat, D3DXIFF_BMP);
2239 
2240         /* positive x face is saved */
2241         hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 256, 256, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
2242         if (SUCCEEDED(hr))
2243         {
2244             D3DLOCKED_RECT locked_rect;
2245 
2246             hr = D3DXLoadSurfaceFromFileInMemory(surface, NULL, NULL, buffer_pointer, buffer_size, NULL, D3DX_FILTER_NONE, 0, NULL);
2247             ok(hr == D3D_OK, "D3DXLoadSurfaceFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
2248 
2249             hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, D3DLOCK_READONLY);
2250             if (SUCCEEDED(hr))
2251             {
2252                 DWORD *color = locked_rect.pBits;
2253                 ok(*color == 0x00ff0000, "Got color %#x, expected %#x\n", *color, 0x00ff0000);
2254                 IDirect3DSurface9_UnlockRect(surface);
2255             }
2256 
2257             IDirect3DSurface9_Release(surface);
2258         } else skip("Failed to create surface\n");
2259 
2260         ID3DXBuffer_Release(buffer);
2261     }
2262 
2263     todo_wine {
2264     hr = D3DXSaveTextureToFileInMemory(&buffer, D3DXIFF_DDS, (IDirect3DBaseTexture9 *)cube_texture, NULL);
2265     ok(hr == D3D_OK, "D3DXSaveTextureToFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
2266     if (SUCCEEDED(hr))
2267     {
2268         buffer_pointer = ID3DXBuffer_GetBufferPointer(buffer);
2269         buffer_size = ID3DXBuffer_GetBufferSize(buffer);
2270         hr = D3DXGetImageInfoFromFileInMemory(buffer_pointer, buffer_size, &info);
2271         ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
2272 
2273         ok(info.Width == 256, "Got width %u, expected %u\n", info.Width, 256);
2274         ok(info.Height == 256, "Got height %u, expected %u\n", info.Height, 256);
2275         ok(info.MipLevels == 9, "Got miplevels %u, expected %u\n", info.MipLevels, 9);
2276         ok(info.ResourceType == D3DRTYPE_CUBETEXTURE, "Got resource type %#x, expected %#x\n", info.ResourceType, D3DRTYPE_CUBETEXTURE);
2277         ok(info.ImageFileFormat == D3DXIFF_DDS, "Got file format %#x, expected %#x\n", info.ImageFileFormat, D3DXIFF_DDS);
2278         ID3DXBuffer_Release(buffer);
2279     }
2280     }
2281 
2282     IDirect3DCubeTexture9_Release(cube_texture);
2283 
2284     /* volume textures */
2285     hr = IDirect3DDevice9_CreateVolumeTexture(device, 256, 256, 256, 0, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &volume_texture, NULL);
2286     if (FAILED(hr))
2287     {
2288         skip("Failed to create volume texture\n");
2289         return;
2290     }
2291 
2292     todo_wine {
2293     hr = D3DXSaveTextureToFileInMemory(&buffer, D3DXIFF_BMP, (IDirect3DBaseTexture9 *)volume_texture, NULL);
2294     ok(hr == D3D_OK, "D3DXSaveTextureToFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
2295     if (SUCCEEDED(hr))
2296     {
2297         buffer_pointer = ID3DXBuffer_GetBufferPointer(buffer);
2298         buffer_size = ID3DXBuffer_GetBufferSize(buffer);
2299         hr = D3DXGetImageInfoFromFileInMemory(buffer_pointer, buffer_size, &info);
2300         ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
2301 
2302         ok(info.Width == 256, "Got width %u, expected %u\n", info.Width, 256);
2303         ok(info.Height == 256, "Got height %u, expected %u\n", info.Height, 256);
2304         ok(info.Depth == 1, "Got depth %u, expected %u\n", info.Depth, 1);
2305         ok(info.MipLevels == 1, "Got miplevels %u, expected %u\n", info.MipLevels, 1);
2306         ok(info.ResourceType == D3DRTYPE_TEXTURE, "Got resource type %#x, expected %#x\n", info.ResourceType, D3DRTYPE_TEXTURE);
2307         ok(info.ImageFileFormat == D3DXIFF_BMP, "Got file format %#x, expected %#x\n", info.ImageFileFormat, D3DXIFF_BMP);
2308         ID3DXBuffer_Release(buffer);
2309     }
2310 
2311     hr = D3DXSaveTextureToFileInMemory(&buffer, D3DXIFF_DDS, (IDirect3DBaseTexture9 *)volume_texture, NULL);
2312     ok(hr == D3D_OK, "D3DXSaveTextureToFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
2313     if (SUCCEEDED(hr))
2314     {
2315         buffer_pointer = ID3DXBuffer_GetBufferPointer(buffer);
2316         buffer_size = ID3DXBuffer_GetBufferSize(buffer);
2317         hr = D3DXGetImageInfoFromFileInMemory(buffer_pointer, buffer_size, &info);
2318         ok(hr == D3D_OK, "D3DXGetImageInfoFromFileInMemory returned %#x, expected %#x\n", hr, D3D_OK);
2319 
2320         ok(info.Width == 256, "Got width %u, expected %u\n", info.Width, 256);
2321         ok(info.Height == 256, "Got height %u, expected %u\n", info.Height, 256);
2322         ok(info.Depth == 256, "Got depth %u, expected %u\n", info.Depth, 256);
2323         ok(info.MipLevels == 9, "Got miplevels %u, expected %u\n", info.MipLevels, 9);
2324         ok(info.ResourceType == D3DRTYPE_VOLUMETEXTURE, "Got resource type %#x, expected %#x\n", info.ResourceType, D3DRTYPE_VOLUMETEXTURE);
2325         ok(info.ImageFileFormat == D3DXIFF_DDS, "Got file format %#x, expected %#x\n", info.ImageFileFormat, D3DXIFF_DDS);
2326         ID3DXBuffer_Release(buffer);
2327     }
2328     }
2329 
2330     IDirect3DVolumeTexture9_Release(volume_texture);
2331 }
2332 
test_texture_shader(void)2333 static void test_texture_shader(void)
2334 {
2335     static const DWORD shader_zero[] = {0x0};
2336     static const DWORD shader_invalid[] = {0xeeee0100};
2337     static const DWORD shader_empty[] = {0xfffe0200, 0x0000ffff};
2338 #if 0
2339 float4 main(float3 pos : POSITION, float3 size : PSIZE) : COLOR
2340 {
2341     return float4(pos, 1.0);
2342 }
2343 #endif
2344     static const DWORD shader_code[] =
2345     {
2346         0x54580100, 0x0015fffe, 0x42415443, 0x0000001c, 0x0000001f, 0x54580100, 0x00000000, 0x00000000,
2347         0x00000100, 0x0000001c, 0x4d007874, 0x6f726369, 0x74666f73, 0x29522820, 0x534c4820, 0x6853204c,
2348         0x72656461, 0x6d6f4320, 0x656c6970, 0x2e392072, 0x392e3932, 0x332e3235, 0x00313131, 0x000afffe,
2349         0x54494c43, 0x00000004, 0x00000000, 0x3ff00000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2350         0x00000000, 0x00000000, 0x0014fffe, 0x434c5846, 0x00000002, 0x10000003, 0x00000001, 0x00000000,
2351         0x00000003, 0x00000000, 0x00000000, 0x00000004, 0x00000000, 0x10000001, 0x00000001, 0x00000000,
2352         0x00000001, 0x00000000, 0x00000000, 0x00000004, 0x00000003, 0xf0f0f0f0, 0x0f0f0f0f, 0x0000ffff,
2353     };
2354     IDirect3DVolumeTexture9 *volume_texture;
2355     IDirect3DCubeTexture9 *cube_texture;
2356     D3DPRESENT_PARAMETERS d3dpp;
2357     IDirect3DTexture9 *texture;
2358     IDirect3DDevice9 *device;
2359     ID3DXTextureShader *tx;
2360     unsigned int x, y, z;
2361     ID3DXBuffer *buffer;
2362     unsigned int *data;
2363     D3DLOCKED_RECT lr;
2364     D3DLOCKED_BOX lb;
2365     IDirect3D9 *d3d;
2366     D3DCAPS9 caps;
2367     HRESULT hr;
2368     HWND wnd;
2369 
2370     hr = D3DXCreateTextureShader(NULL, NULL);
2371     ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
2372 
2373     hr = D3DXCreateTextureShader(NULL, &tx);
2374     ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
2375 
2376     hr = D3DXCreateTextureShader(shader_invalid, &tx);
2377     todo_wine ok(hr == D3DXERR_INVALIDDATA, "Got unexpected hr %#x.\n", hr);
2378 
2379     hr = D3DXCreateTextureShader(shader_zero, &tx);
2380     todo_wine ok(hr == D3DXERR_INVALIDDATA, "Got unexpected hr %#x.\n", hr);
2381 
2382     hr = D3DXCreateTextureShader(shader_empty, &tx);
2383     todo_wine ok(hr == D3DXERR_INVALIDDATA, "Got unexpected hr %#x.\n", hr);
2384 
2385     hr = D3DXCreateTextureShader(shader_code, &tx);
2386     ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
2387 
2388     hr = tx->lpVtbl->GetFunction(tx, &buffer);
2389     todo_wine ok(SUCCEEDED(hr), "Failed to get texture shader bytecode.\n");
2390     if (FAILED(hr))
2391     {
2392         skip("Texture shaders not supported, skipping further tests.\n");
2393         IUnknown_Release(tx);
2394         return;
2395     }
2396     ID3DXBuffer_Release(buffer);
2397 
2398     if (!(wnd = CreateWindowA("static", "d3dx9_test", WS_OVERLAPPEDWINDOW, 0, 0,
2399             640, 480, NULL, NULL, NULL, NULL)))
2400     {
2401         skip("Couldn't create application window.\n");
2402         IUnknown_Release(tx);
2403         return;
2404     }
2405     d3d = Direct3DCreate9(D3D_SDK_VERSION);
2406     if (!d3d)
2407     {
2408         skip("Couldn't create IDirect3D9 object.\n");
2409         DestroyWindow(wnd);
2410         IUnknown_Release(tx);
2411         return;
2412     }
2413 
2414     ZeroMemory(&d3dpp, sizeof(d3dpp));
2415     d3dpp.Windowed = TRUE;
2416     d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2417     hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, wnd,
2418             D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &device);
2419     if (FAILED(hr))
2420     {
2421         skip("Failed to create IDirect3DDevice9 object, hr %#x.\n", hr);
2422         IDirect3D9_Release(d3d);
2423         DestroyWindow(wnd);
2424         IUnknown_Release(tx);
2425         return;
2426     }
2427 
2428     IDirect3DDevice9_GetDeviceCaps(device, &caps);
2429 
2430     hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM,
2431             &texture, NULL);
2432     ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
2433 
2434     hr = D3DXFillTextureTX(texture, tx);
2435     ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
2436 
2437     hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, D3DLOCK_READONLY);
2438     ok(SUCCEEDED(hr), "Locking texture failed, hr %#x.\n", hr);
2439     data = lr.pBits;
2440     for (y = 0; y < 256; ++y)
2441     {
2442         for (x = 0; x < 256; ++x)
2443         {
2444             unsigned int expected = 0xff000000 | x << 16 | y << 8;
2445             /* The third position coordinate is apparently undefined for 2D textures. */
2446             unsigned int color = data[y * lr.Pitch / sizeof(*data) + x] & 0xffffff00;
2447 
2448             ok(compare_color(color, expected, 1), "Unexpected color %08x at (%u, %u).\n", color, x, y);
2449         }
2450     }
2451     hr = IDirect3DTexture9_UnlockRect(texture, 0);
2452     ok(SUCCEEDED(hr), "Unlocking texture failed, hr %#x.\n", hr);
2453 
2454     IDirect3DTexture9_Release(texture);
2455 
2456     if (!(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP))
2457     {
2458         skip("Cube textures not supported, skipping tests.\n");
2459         goto cleanup;
2460     }
2461 
2462     hr = IDirect3DDevice9_CreateCubeTexture(device, 256, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM,
2463             &cube_texture, NULL);
2464     ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
2465 
2466     hr = D3DXFillCubeTextureTX(cube_texture, tx);
2467     ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
2468 
2469     for (z = 0; z < 6; ++z)
2470     {
2471         static const char * const mapping[6][3] =
2472         {
2473             {"-x", "-y", "1"},
2474             {"+x", "-y", "0"},
2475             {"+y", "1", "+x"},
2476             {"-y", "0", "+x"},
2477             {"1", "-y", "+x"},
2478             {"0", "-y", "-x"},
2479         };
2480 
2481         hr = IDirect3DCubeTexture9_LockRect(cube_texture, z, 0, &lr, NULL, D3DLOCK_READONLY);
2482         ok(SUCCEEDED(hr), "Locking texture failed, hr %#x.\n", hr);
2483         data = lr.pBits;
2484         for (y = 0; y < 256; ++y)
2485         {
2486             for (x = 0; x < 256; ++x)
2487             {
2488                 unsigned int color = data[y * lr.Pitch / sizeof(*data) + x];
2489                 unsigned int expected = 0xff000000;
2490                 unsigned int i;
2491 
2492                 for (i = 0; i < 3; ++i)
2493                 {
2494                     int component;
2495 
2496                     if (mapping[z][i][0] == '0')
2497                         component = 0;
2498                     else if (mapping[z][i][0] == '1')
2499                         component = 255;
2500                     else
2501                         component = mapping[z][i][1] == 'x' ? x * 2 - 255 : y * 2 - 255;
2502                     if (mapping[z][i][0] == '-')
2503                         component = -component;
2504                     expected |= max(component, 0) << i * 8;
2505                 }
2506                 ok(compare_color(color, expected, 1), "Unexpected color %08x at (%u, %u, %u).\n",
2507                         color, x, y, z);
2508             }
2509         }
2510         hr = IDirect3DCubeTexture9_UnlockRect(cube_texture, z, 0);
2511         ok(SUCCEEDED(hr), "Unlocking texture failed, hr %#x.\n", hr);
2512     }
2513 
2514     IDirect3DCubeTexture9_Release(cube_texture);
2515 
2516     if (!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP) || caps.MaxVolumeExtent < 64)
2517     {
2518         skip("Volume textures not supported, skipping test.\n");
2519         goto cleanup;
2520     }
2521     hr = IDirect3DDevice9_CreateVolumeTexture(device, 64, 64, 64, 1, 0, D3DFMT_A8R8G8B8,
2522             D3DPOOL_SYSTEMMEM, &volume_texture, NULL);
2523     ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
2524 
2525     hr = D3DXFillVolumeTextureTX(volume_texture, tx);
2526     ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
2527 
2528     hr = IDirect3DVolumeTexture9_LockBox(volume_texture, 0, &lb, NULL, D3DLOCK_READONLY);
2529     ok(SUCCEEDED(hr), "Locking texture failed, hr %#x.\n", hr);
2530     data = lb.pBits;
2531     for (z = 0; z < 64; ++z)
2532     {
2533         for (y = 0; y < 64; ++y)
2534         {
2535             for (x = 0; x < 64; ++x)
2536             {
2537                 unsigned int expected = 0xff000000 | ((x * 4 + 2) << 16) | ((y * 4 + 2) << 8) | (z * 4 + 2);
2538                 unsigned int color = data[z * lb.SlicePitch / sizeof(*data) + y * lb.RowPitch / sizeof(*data) + x];
2539 
2540                 ok(compare_color(color, expected, 1), "Unexpected color %08x at (%u, %u, %u).\n",
2541                         color, x, y, z);
2542             }
2543         }
2544     }
2545     hr = IDirect3DVolumeTexture9_UnlockBox(volume_texture, 0);
2546     ok(SUCCEEDED(hr), "Unlocking texture failed, hr %#x.\n", hr);
2547 
2548     IDirect3DVolumeTexture9_Release(volume_texture);
2549 
2550  cleanup:
2551     IDirect3DDevice9_Release(device);
2552     IDirect3D9_Release(d3d);
2553     DestroyWindow(wnd);
2554     IUnknown_Release(tx);
2555 }
2556 
START_TEST(texture)2557 START_TEST(texture)
2558 {
2559     HWND wnd;
2560     IDirect3D9 *d3d;
2561     IDirect3DDevice9 *device;
2562     D3DPRESENT_PARAMETERS d3dpp;
2563     HRESULT hr;
2564     ULONG ref;
2565 
2566     if (!(wnd = CreateWindowA("static", "d3dx9_test", WS_OVERLAPPEDWINDOW, 0, 0,
2567             640, 480, NULL, NULL, NULL, NULL)))
2568     {
2569         skip("Couldn't create application window\n");
2570         return;
2571     }
2572     d3d = Direct3DCreate9(D3D_SDK_VERSION);
2573     if (!d3d) {
2574         skip("Couldn't create IDirect3D9 object\n");
2575         DestroyWindow(wnd);
2576         return;
2577     }
2578 
2579     ZeroMemory(&d3dpp, sizeof(d3dpp));
2580     d3dpp.Windowed   = TRUE;
2581     d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2582     hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, wnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &device);
2583     if (FAILED(hr)) {
2584         skip("Failed to create IDirect3DDevice9 object %#x\n", hr);
2585         IDirect3D9_Release(d3d);
2586         DestroyWindow(wnd);
2587         return;
2588     }
2589 
2590     /* Check whether DXTn textures are supported. */
2591     has_2d_dxt1 = SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
2592             D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1));
2593     has_2d_dxt3 = SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
2594             D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT3));
2595     has_2d_dxt5 = SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
2596             D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT5));
2597     has_cube_dxt5 = SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
2598             D3DFMT_X8R8G8B8, 0, D3DRTYPE_CUBETEXTURE, D3DFMT_DXT5));
2599     has_3d_dxt3 = SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
2600             D3DFMT_X8R8G8B8, 0, D3DRTYPE_VOLUMETEXTURE, D3DFMT_DXT3));
2601     trace("DXTn texture support: 2D DXT1 %#x, 2D DXT3 %#x, 2D DXT5 %#x, cube DXT5 %#x, 3D dxt3 %#x.\n",
2602             has_2d_dxt1, has_2d_dxt3, has_2d_dxt5, has_cube_dxt5, has_3d_dxt3);
2603 
2604     test_D3DXCheckTextureRequirements(device);
2605     test_D3DXCheckCubeTextureRequirements(device);
2606     test_D3DXCheckVolumeTextureRequirements(device);
2607     test_D3DXCreateTexture(device);
2608     test_D3DXFilterTexture(device);
2609     test_D3DXFillTexture(device);
2610     test_D3DXFillCubeTexture(device);
2611     test_D3DXFillVolumeTexture(device);
2612     test_D3DXCreateTextureFromFileInMemory(device);
2613     test_D3DXCreateTextureFromFileInMemoryEx(device);
2614     test_D3DXCreateCubeTextureFromFileInMemory(device);
2615     test_D3DXCreateCubeTextureFromFileInMemoryEx(device);
2616     test_D3DXCreateVolumeTextureFromFileInMemory(device);
2617     test_D3DXCreateVolumeTextureFromFileInMemoryEx(device);
2618     test_D3DXSaveTextureToFileInMemory(device);
2619 
2620     ref = IDirect3DDevice9_Release(device);
2621     ok(!ref, "Device has %u references left.\n", ref);
2622 
2623     IDirect3D9_Release(d3d);
2624     DestroyWindow(wnd);
2625 
2626     test_texture_shader();
2627 }
2628