[AMSTREAM] We don't need to define WIDL_C_INLINE_WRAPPERS here anymore.
[reactos.git] / dll / directx / wine / d3d9 / texture.c
1 /*
2 * Copyright 2002-2005 Jason Edmeades
3 * Copyright 2002-2005 Raphael Junqueira
4 * Copyright 2005 Oliver Stieber
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21 #include "d3d9_private.h"
22
23 static inline struct d3d9_texture *impl_from_IDirect3DTexture9(IDirect3DTexture9 *iface)
24 {
25 return CONTAINING_RECORD((IDirect3DBaseTexture9 *)iface, struct d3d9_texture, IDirect3DBaseTexture9_iface);
26 }
27
28 static inline struct d3d9_texture *impl_from_IDirect3DCubeTexture9(IDirect3DCubeTexture9 *iface)
29 {
30 return CONTAINING_RECORD((IDirect3DBaseTexture9 *)iface, struct d3d9_texture, IDirect3DBaseTexture9_iface);
31 }
32
33 static inline struct d3d9_texture *impl_from_IDirect3DVolumeTexture9(IDirect3DVolumeTexture9 *iface)
34 {
35 return CONTAINING_RECORD((IDirect3DBaseTexture9 *)iface, struct d3d9_texture, IDirect3DBaseTexture9_iface);
36 }
37
38 static HRESULT WINAPI d3d9_texture_2d_QueryInterface(IDirect3DTexture9 *iface, REFIID riid, void **out)
39 {
40 TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
41
42 if (IsEqualGUID(riid, &IID_IDirect3DTexture9)
43 || IsEqualGUID(riid, &IID_IDirect3DBaseTexture9)
44 || IsEqualGUID(riid, &IID_IDirect3DResource9)
45 || IsEqualGUID(riid, &IID_IUnknown))
46 {
47 IDirect3DTexture9_AddRef(iface);
48 *out = iface;
49 return S_OK;
50 }
51
52 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
53
54 *out = NULL;
55 return E_NOINTERFACE;
56 }
57
58 static ULONG WINAPI d3d9_texture_2d_AddRef(IDirect3DTexture9 *iface)
59 {
60 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
61 ULONG ref = InterlockedIncrement(&texture->resource.refcount);
62
63 TRACE("%p increasing refcount to %u.\n", iface, ref);
64
65 if (ref == 1)
66 {
67 struct d3d9_surface *surface;
68
69 IDirect3DDevice9Ex_AddRef(texture->parent_device);
70 wined3d_mutex_lock();
71 LIST_FOR_EACH_ENTRY(surface, &texture->rtv_list, struct d3d9_surface, rtv_entry)
72 {
73 wined3d_rendertarget_view_incref(surface->wined3d_rtv);
74 }
75 wined3d_texture_incref(texture->wined3d_texture);
76 wined3d_mutex_unlock();
77 }
78
79 return ref;
80 }
81
82 static ULONG WINAPI d3d9_texture_2d_Release(IDirect3DTexture9 *iface)
83 {
84 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
85 ULONG ref = InterlockedDecrement(&texture->resource.refcount);
86
87 TRACE("%p decreasing refcount to %u.\n", iface, ref);
88
89 if (!ref)
90 {
91 IDirect3DDevice9Ex *parent_device = texture->parent_device;
92 struct d3d9_surface *surface;
93
94 wined3d_mutex_lock();
95 LIST_FOR_EACH_ENTRY(surface, &texture->rtv_list, struct d3d9_surface, rtv_entry)
96 {
97 wined3d_rendertarget_view_decref(surface->wined3d_rtv);
98 }
99 wined3d_texture_decref(texture->wined3d_texture);
100 wined3d_mutex_unlock();
101
102 /* Release the device last, as it may cause the device to be destroyed. */
103 IDirect3DDevice9Ex_Release(parent_device);
104 }
105 return ref;
106 }
107
108 static HRESULT WINAPI d3d9_texture_2d_GetDevice(IDirect3DTexture9 *iface, IDirect3DDevice9 **device)
109 {
110 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
111
112 TRACE("iface %p, device %p.\n", iface, device);
113
114 *device = (IDirect3DDevice9 *)texture->parent_device;
115 IDirect3DDevice9_AddRef(*device);
116
117 TRACE("Returning device %p.\n", *device);
118
119 return D3D_OK;
120 }
121
122 static HRESULT WINAPI d3d9_texture_2d_SetPrivateData(IDirect3DTexture9 *iface,
123 REFGUID guid, const void *data, DWORD data_size, DWORD flags)
124 {
125 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
126 TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
127 iface, debugstr_guid(guid), data, data_size, flags);
128
129 return d3d9_resource_set_private_data(&texture->resource, guid, data, data_size, flags);
130 }
131
132 static HRESULT WINAPI d3d9_texture_2d_GetPrivateData(IDirect3DTexture9 *iface,
133 REFGUID guid, void *data, DWORD *data_size)
134 {
135 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
136 TRACE("iface %p, guid %s, data %p, data_size %p.\n",
137 iface, debugstr_guid(guid), data, data_size);
138
139 return d3d9_resource_get_private_data(&texture->resource, guid, data, data_size);
140 }
141
142 static HRESULT WINAPI d3d9_texture_2d_FreePrivateData(IDirect3DTexture9 *iface, REFGUID guid)
143 {
144 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
145 TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
146
147 return d3d9_resource_free_private_data(&texture->resource, guid);
148 }
149
150 static DWORD WINAPI d3d9_texture_2d_SetPriority(IDirect3DTexture9 *iface, DWORD priority)
151 {
152 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
153 struct wined3d_resource *resource;
154 DWORD ret;
155
156 TRACE("iface %p, priority %u.\n", iface, priority);
157
158 wined3d_mutex_lock();
159 resource = wined3d_texture_get_resource(texture->wined3d_texture);
160 ret = wined3d_resource_set_priority(resource, priority);
161 wined3d_mutex_unlock();
162
163 return ret;
164 }
165
166 static DWORD WINAPI d3d9_texture_2d_GetPriority(IDirect3DTexture9 *iface)
167 {
168 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
169 const struct wined3d_resource *resource;
170 DWORD ret;
171
172 TRACE("iface %p.\n", iface);
173
174 wined3d_mutex_lock();
175 resource = wined3d_texture_get_resource(texture->wined3d_texture);
176 ret = wined3d_resource_get_priority(resource);
177 wined3d_mutex_unlock();
178
179 return ret;
180 }
181
182 static void WINAPI d3d9_texture_2d_PreLoad(IDirect3DTexture9 *iface)
183 {
184 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
185
186 TRACE("iface %p.\n", iface);
187
188 wined3d_mutex_lock();
189 wined3d_resource_preload(wined3d_texture_get_resource(texture->wined3d_texture));
190 wined3d_mutex_unlock();
191 }
192
193 static D3DRESOURCETYPE WINAPI d3d9_texture_2d_GetType(IDirect3DTexture9 *iface)
194 {
195 TRACE("iface %p.\n", iface);
196
197 return D3DRTYPE_TEXTURE;
198 }
199
200 static DWORD WINAPI d3d9_texture_2d_SetLOD(IDirect3DTexture9 *iface, DWORD lod)
201 {
202 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
203 DWORD ret;
204
205 TRACE("iface %p, lod %u.\n", iface, lod);
206
207 wined3d_mutex_lock();
208 ret = wined3d_texture_set_lod(texture->wined3d_texture, lod);
209 wined3d_mutex_unlock();
210
211 return ret;
212 }
213
214 static DWORD WINAPI d3d9_texture_2d_GetLOD(IDirect3DTexture9 *iface)
215 {
216 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
217 DWORD ret;
218
219 TRACE("iface %p.\n", iface);
220
221 wined3d_mutex_lock();
222 ret = wined3d_texture_get_lod(texture->wined3d_texture);
223 wined3d_mutex_unlock();
224
225 return ret;
226 }
227
228 static DWORD WINAPI d3d9_texture_2d_GetLevelCount(IDirect3DTexture9 *iface)
229 {
230 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
231 DWORD ret;
232
233 TRACE("iface %p.\n", iface);
234
235 wined3d_mutex_lock();
236 ret = wined3d_texture_get_level_count(texture->wined3d_texture);
237 wined3d_mutex_unlock();
238
239 return ret;
240 }
241
242 static HRESULT WINAPI d3d9_texture_2d_SetAutoGenFilterType(IDirect3DTexture9 *iface, D3DTEXTUREFILTERTYPE filter_type)
243 {
244 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
245 HRESULT hr;
246
247 TRACE("iface %p, filter_type %#x.\n", iface, filter_type);
248
249 wined3d_mutex_lock();
250 hr = wined3d_texture_set_autogen_filter_type(texture->wined3d_texture,
251 (enum wined3d_texture_filter_type)filter_type);
252 wined3d_mutex_unlock();
253
254 return hr;
255 }
256
257 static D3DTEXTUREFILTERTYPE WINAPI d3d9_texture_2d_GetAutoGenFilterType(IDirect3DTexture9 *iface)
258 {
259 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
260 D3DTEXTUREFILTERTYPE ret;
261
262 TRACE("iface %p.\n", iface);
263
264 wined3d_mutex_lock();
265 ret = (D3DTEXTUREFILTERTYPE)wined3d_texture_get_autogen_filter_type(texture->wined3d_texture);
266 wined3d_mutex_unlock();
267
268 return ret;
269 }
270
271 static void WINAPI d3d9_texture_2d_GenerateMipSubLevels(IDirect3DTexture9 *iface)
272 {
273 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
274
275 TRACE("iface %p.\n", iface);
276
277 wined3d_mutex_lock();
278 wined3d_texture_generate_mipmaps(texture->wined3d_texture);
279 wined3d_mutex_unlock();
280 }
281
282 static HRESULT WINAPI d3d9_texture_2d_GetLevelDesc(IDirect3DTexture9 *iface, UINT level, D3DSURFACE_DESC *desc)
283 {
284 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
285 struct wined3d_sub_resource_desc wined3d_desc;
286 HRESULT hr;
287
288 TRACE("iface %p, level %u, desc %p.\n", iface, level, desc);
289
290 wined3d_mutex_lock();
291 if (SUCCEEDED(hr = wined3d_texture_get_sub_resource_desc(texture->wined3d_texture, level, &wined3d_desc)))
292 {
293 desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
294 desc->Type = D3DRTYPE_SURFACE;
295 desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK;
296 desc->Pool = wined3d_desc.pool;
297 desc->MultiSampleType = wined3d_desc.multisample_type;
298 desc->MultiSampleQuality = wined3d_desc.multisample_quality;
299 desc->Width = wined3d_desc.width;
300 desc->Height = wined3d_desc.height;
301 }
302 wined3d_mutex_unlock();
303
304 return hr;
305 }
306
307 static HRESULT WINAPI d3d9_texture_2d_GetSurfaceLevel(IDirect3DTexture9 *iface,
308 UINT level, IDirect3DSurface9 **surface)
309 {
310 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
311 struct d3d9_surface *surface_impl;
312
313 TRACE("iface %p, level %u, surface %p.\n", iface, level, surface);
314
315 wined3d_mutex_lock();
316 if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level)))
317 {
318 wined3d_mutex_unlock();
319 return D3DERR_INVALIDCALL;
320 }
321
322 *surface = &surface_impl->IDirect3DSurface9_iface;
323 IDirect3DSurface9_AddRef(*surface);
324 wined3d_mutex_unlock();
325
326 return D3D_OK;
327 }
328
329 static HRESULT WINAPI d3d9_texture_2d_LockRect(IDirect3DTexture9 *iface,
330 UINT level, D3DLOCKED_RECT *locked_rect, const RECT *rect, DWORD flags)
331 {
332 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
333 struct d3d9_surface *surface_impl;
334 HRESULT hr;
335
336 TRACE("iface %p, level %u, locked_rect %p, rect %p, flags %#x.\n",
337 iface, level, locked_rect, rect, flags);
338
339 wined3d_mutex_lock();
340 if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level)))
341 hr = D3DERR_INVALIDCALL;
342 else
343 hr = IDirect3DSurface9_LockRect(&surface_impl->IDirect3DSurface9_iface, locked_rect, rect, flags);
344 wined3d_mutex_unlock();
345
346 return hr;
347 }
348
349 static HRESULT WINAPI d3d9_texture_2d_UnlockRect(IDirect3DTexture9 *iface, UINT level)
350 {
351 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
352 struct d3d9_surface *surface_impl;
353 HRESULT hr;
354
355 TRACE("iface %p, level %u.\n", iface, level);
356
357 wined3d_mutex_lock();
358 if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level)))
359 hr = D3DERR_INVALIDCALL;
360 else
361 hr = IDirect3DSurface9_UnlockRect(&surface_impl->IDirect3DSurface9_iface);
362 wined3d_mutex_unlock();
363
364 return hr;
365 }
366
367 static HRESULT WINAPI d3d9_texture_2d_AddDirtyRect(IDirect3DTexture9 *iface, const RECT *dirty_rect)
368 {
369 struct d3d9_texture *texture = impl_from_IDirect3DTexture9(iface);
370 HRESULT hr;
371
372 TRACE("iface %p, dirty_rect %s.\n",
373 iface, wine_dbgstr_rect(dirty_rect));
374
375 wined3d_mutex_lock();
376 if (!dirty_rect)
377 hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, 0, NULL);
378 else
379 {
380 struct wined3d_box dirty_region;
381
382 wined3d_box_set(&dirty_region, dirty_rect->left, dirty_rect->top, dirty_rect->right, dirty_rect->bottom, 0, 1);
383 hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, 0, &dirty_region);
384 }
385 wined3d_mutex_unlock();
386
387 return hr;
388 }
389
390 static const IDirect3DTexture9Vtbl d3d9_texture_2d_vtbl =
391 {
392 /* IUnknown */
393 d3d9_texture_2d_QueryInterface,
394 d3d9_texture_2d_AddRef,
395 d3d9_texture_2d_Release,
396 /* IDirect3DResource9 */
397 d3d9_texture_2d_GetDevice,
398 d3d9_texture_2d_SetPrivateData,
399 d3d9_texture_2d_GetPrivateData,
400 d3d9_texture_2d_FreePrivateData,
401 d3d9_texture_2d_SetPriority,
402 d3d9_texture_2d_GetPriority,
403 d3d9_texture_2d_PreLoad,
404 d3d9_texture_2d_GetType,
405 /* IDirect3dBaseTexture9 */
406 d3d9_texture_2d_SetLOD,
407 d3d9_texture_2d_GetLOD,
408 d3d9_texture_2d_GetLevelCount,
409 d3d9_texture_2d_SetAutoGenFilterType,
410 d3d9_texture_2d_GetAutoGenFilterType,
411 d3d9_texture_2d_GenerateMipSubLevels,
412 /* IDirect3DTexture9 */
413 d3d9_texture_2d_GetLevelDesc,
414 d3d9_texture_2d_GetSurfaceLevel,
415 d3d9_texture_2d_LockRect,
416 d3d9_texture_2d_UnlockRect,
417 d3d9_texture_2d_AddDirtyRect,
418 };
419
420 static HRESULT WINAPI d3d9_texture_cube_QueryInterface(IDirect3DCubeTexture9 *iface, REFIID riid, void **out)
421 {
422 TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
423
424 if (IsEqualGUID(riid, &IID_IDirect3DCubeTexture9)
425 || IsEqualGUID(riid, &IID_IDirect3DBaseTexture9)
426 || IsEqualGUID(riid, &IID_IDirect3DResource9)
427 || IsEqualGUID(riid, &IID_IUnknown))
428 {
429 IDirect3DCubeTexture9_AddRef(iface);
430 *out = iface;
431 return S_OK;
432 }
433
434 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
435
436 *out = NULL;
437 return E_NOINTERFACE;
438 }
439
440 static ULONG WINAPI d3d9_texture_cube_AddRef(IDirect3DCubeTexture9 *iface)
441 {
442 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
443 ULONG ref = InterlockedIncrement(&texture->resource.refcount);
444
445 TRACE("%p increasing refcount to %u.\n", iface, ref);
446
447 if (ref == 1)
448 {
449 struct d3d9_surface *surface;
450
451 IDirect3DDevice9Ex_AddRef(texture->parent_device);
452 wined3d_mutex_lock();
453 LIST_FOR_EACH_ENTRY(surface, &texture->rtv_list, struct d3d9_surface, rtv_entry)
454 {
455 wined3d_rendertarget_view_decref(surface->wined3d_rtv);
456 }
457 wined3d_texture_incref(texture->wined3d_texture);
458 wined3d_mutex_unlock();
459 }
460
461 return ref;
462 }
463
464 static ULONG WINAPI d3d9_texture_cube_Release(IDirect3DCubeTexture9 *iface)
465 {
466 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
467 ULONG ref = InterlockedDecrement(&texture->resource.refcount);
468
469 TRACE("%p decreasing refcount to %u.\n", iface, ref);
470
471 if (!ref)
472 {
473 IDirect3DDevice9Ex *parent_device = texture->parent_device;
474 struct d3d9_surface *surface;
475
476 TRACE("Releasing child %p.\n", texture->wined3d_texture);
477
478 wined3d_mutex_lock();
479 LIST_FOR_EACH_ENTRY(surface, &texture->rtv_list, struct d3d9_surface, rtv_entry)
480 {
481 wined3d_rendertarget_view_decref(surface->wined3d_rtv);
482 }
483 wined3d_texture_decref(texture->wined3d_texture);
484 wined3d_mutex_unlock();
485
486 /* Release the device last, as it may cause the device to be destroyed. */
487 IDirect3DDevice9Ex_Release(parent_device);
488 }
489 return ref;
490 }
491
492 static HRESULT WINAPI d3d9_texture_cube_GetDevice(IDirect3DCubeTexture9 *iface, IDirect3DDevice9 **device)
493 {
494 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
495
496 TRACE("iface %p, device %p.\n", iface, device);
497
498 *device = (IDirect3DDevice9 *)texture->parent_device;
499 IDirect3DDevice9_AddRef(*device);
500
501 TRACE("Returning device %p.\n", *device);
502
503 return D3D_OK;
504 }
505
506 static HRESULT WINAPI d3d9_texture_cube_SetPrivateData(IDirect3DCubeTexture9 *iface,
507 REFGUID guid, const void *data, DWORD data_size, DWORD flags)
508 {
509 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
510 TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
511 iface, debugstr_guid(guid), data, data_size, flags);
512
513 return d3d9_resource_set_private_data(&texture->resource, guid, data, data_size, flags);
514 }
515
516 static HRESULT WINAPI d3d9_texture_cube_GetPrivateData(IDirect3DCubeTexture9 *iface,
517 REFGUID guid, void *data, DWORD *data_size)
518 {
519 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
520 TRACE("iface %p, guid %s, data %p, data_size %p.\n",
521 iface, debugstr_guid(guid), data, data_size);
522
523 return d3d9_resource_get_private_data(&texture->resource, guid, data, data_size);
524 }
525
526 static HRESULT WINAPI d3d9_texture_cube_FreePrivateData(IDirect3DCubeTexture9 *iface, REFGUID guid)
527 {
528 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
529 TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
530
531 return d3d9_resource_free_private_data(&texture->resource, guid);
532 }
533
534 static DWORD WINAPI d3d9_texture_cube_SetPriority(IDirect3DCubeTexture9 *iface, DWORD priority)
535 {
536 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
537 struct wined3d_resource *resource;
538 DWORD ret;
539
540 TRACE("iface %p, priority %u.\n", iface, priority);
541
542 wined3d_mutex_lock();
543 resource = wined3d_texture_get_resource(texture->wined3d_texture);
544 ret = wined3d_resource_set_priority(resource, priority);
545 wined3d_mutex_unlock();
546
547 return ret;
548 }
549
550 static DWORD WINAPI d3d9_texture_cube_GetPriority(IDirect3DCubeTexture9 *iface)
551 {
552 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
553 const struct wined3d_resource *resource;
554 DWORD ret;
555
556 TRACE("iface %p.\n", iface);
557
558 wined3d_mutex_lock();
559 resource = wined3d_texture_get_resource(texture->wined3d_texture);
560 ret = wined3d_resource_get_priority(resource);
561 wined3d_mutex_unlock();
562
563 return ret;
564 }
565
566 static void WINAPI d3d9_texture_cube_PreLoad(IDirect3DCubeTexture9 *iface)
567 {
568 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
569
570 TRACE("iface %p.\n", iface);
571
572 wined3d_mutex_lock();
573 wined3d_resource_preload(wined3d_texture_get_resource(texture->wined3d_texture));
574 wined3d_mutex_unlock();
575 }
576
577 static D3DRESOURCETYPE WINAPI d3d9_texture_cube_GetType(IDirect3DCubeTexture9 *iface)
578 {
579 TRACE("iface %p.\n", iface);
580
581 return D3DRTYPE_CUBETEXTURE;
582 }
583
584 static DWORD WINAPI d3d9_texture_cube_SetLOD(IDirect3DCubeTexture9 *iface, DWORD lod)
585 {
586 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
587 DWORD ret;
588
589 TRACE("iface %p, lod %u.\n", iface, lod);
590
591 wined3d_mutex_lock();
592 ret = wined3d_texture_set_lod(texture->wined3d_texture, lod);
593 wined3d_mutex_unlock();
594
595 return ret;
596 }
597
598 static DWORD WINAPI d3d9_texture_cube_GetLOD(IDirect3DCubeTexture9 *iface)
599 {
600 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
601 DWORD ret;
602
603 TRACE("iface %p.\n", iface);
604
605 wined3d_mutex_lock();
606 ret = wined3d_texture_get_lod(texture->wined3d_texture);
607 wined3d_mutex_unlock();
608
609 return ret;
610 }
611
612 static DWORD WINAPI d3d9_texture_cube_GetLevelCount(IDirect3DCubeTexture9 *iface)
613 {
614 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
615 DWORD ret;
616
617 TRACE("iface %p.\n", iface);
618
619 wined3d_mutex_lock();
620 ret = wined3d_texture_get_level_count(texture->wined3d_texture);
621 wined3d_mutex_unlock();
622
623 return ret;
624 }
625
626 static HRESULT WINAPI d3d9_texture_cube_SetAutoGenFilterType(IDirect3DCubeTexture9 *iface,
627 D3DTEXTUREFILTERTYPE filter_type)
628 {
629 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
630 HRESULT hr;
631
632 TRACE("iface %p, filter_type %#x.\n", iface, filter_type);
633
634 wined3d_mutex_lock();
635 hr = wined3d_texture_set_autogen_filter_type(texture->wined3d_texture,
636 (enum wined3d_texture_filter_type)filter_type);
637 wined3d_mutex_unlock();
638
639 return hr;
640 }
641
642 static D3DTEXTUREFILTERTYPE WINAPI d3d9_texture_cube_GetAutoGenFilterType(IDirect3DCubeTexture9 *iface)
643 {
644 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
645 D3DTEXTUREFILTERTYPE ret;
646
647 TRACE("iface %p.\n", iface);
648
649 wined3d_mutex_lock();
650 ret = (D3DTEXTUREFILTERTYPE)wined3d_texture_get_autogen_filter_type(texture->wined3d_texture);
651 wined3d_mutex_unlock();
652
653 return ret;
654 }
655
656 static void WINAPI d3d9_texture_cube_GenerateMipSubLevels(IDirect3DCubeTexture9 *iface)
657 {
658 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
659
660 TRACE("iface %p.\n", iface);
661
662 wined3d_mutex_lock();
663 wined3d_texture_generate_mipmaps(texture->wined3d_texture);
664 wined3d_mutex_unlock();
665 }
666
667 static HRESULT WINAPI d3d9_texture_cube_GetLevelDesc(IDirect3DCubeTexture9 *iface, UINT level, D3DSURFACE_DESC *desc)
668 {
669 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
670 struct wined3d_sub_resource_desc wined3d_desc;
671 DWORD level_count;
672 HRESULT hr;
673
674 TRACE("iface %p, level %u, desc %p.\n", iface, level, desc);
675
676 wined3d_mutex_lock();
677 level_count = wined3d_texture_get_level_count(texture->wined3d_texture);
678 if (level >= level_count)
679 {
680 wined3d_mutex_unlock();
681 return D3DERR_INVALIDCALL;
682 }
683
684 if (SUCCEEDED(hr = wined3d_texture_get_sub_resource_desc(texture->wined3d_texture, level, &wined3d_desc)))
685 {
686 desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
687 desc->Type = D3DRTYPE_SURFACE;
688 desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK;
689 desc->Pool = wined3d_desc.pool;
690 desc->MultiSampleType = wined3d_desc.multisample_type;
691 desc->MultiSampleQuality = wined3d_desc.multisample_quality;
692 desc->Width = wined3d_desc.width;
693 desc->Height = wined3d_desc.height;
694 }
695 wined3d_mutex_unlock();
696
697 return hr;
698 }
699
700 static HRESULT WINAPI d3d9_texture_cube_GetCubeMapSurface(IDirect3DCubeTexture9 *iface,
701 D3DCUBEMAP_FACES face, UINT level, IDirect3DSurface9 **surface)
702 {
703 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
704 struct d3d9_surface *surface_impl;
705 UINT sub_resource_idx;
706 DWORD level_count;
707
708 TRACE("iface %p, face %#x, level %u, surface %p.\n", iface, face, level, surface);
709
710 wined3d_mutex_lock();
711 level_count = wined3d_texture_get_level_count(texture->wined3d_texture);
712 if (level >= level_count)
713 {
714 wined3d_mutex_unlock();
715 return D3DERR_INVALIDCALL;
716 }
717
718 sub_resource_idx = level_count * face + level;
719 if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, sub_resource_idx)))
720 {
721 wined3d_mutex_unlock();
722 return D3DERR_INVALIDCALL;
723 }
724
725 *surface = &surface_impl->IDirect3DSurface9_iface;
726 IDirect3DSurface9_AddRef(*surface);
727 wined3d_mutex_unlock();
728
729 return D3D_OK;
730 }
731
732 static HRESULT WINAPI d3d9_texture_cube_LockRect(IDirect3DCubeTexture9 *iface,
733 D3DCUBEMAP_FACES face, UINT level, D3DLOCKED_RECT *locked_rect, const RECT *rect,
734 DWORD flags)
735 {
736 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
737 struct d3d9_surface *surface_impl;
738 UINT sub_resource_idx;
739 HRESULT hr;
740
741 TRACE("iface %p, face %#x, level %u, locked_rect %p, rect %p, flags %#x.\n",
742 iface, face, level, locked_rect, rect, flags);
743
744 wined3d_mutex_lock();
745 sub_resource_idx = wined3d_texture_get_level_count(texture->wined3d_texture) * face + level;
746 if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, sub_resource_idx)))
747 hr = D3DERR_INVALIDCALL;
748 else
749 hr = IDirect3DSurface9_LockRect(&surface_impl->IDirect3DSurface9_iface, locked_rect, rect, flags);
750 wined3d_mutex_unlock();
751
752 return hr;
753 }
754
755 static HRESULT WINAPI d3d9_texture_cube_UnlockRect(IDirect3DCubeTexture9 *iface,
756 D3DCUBEMAP_FACES face, UINT level)
757 {
758 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
759 struct d3d9_surface *surface_impl;
760 UINT sub_resource_idx;
761 HRESULT hr;
762
763 TRACE("iface %p, face %#x, level %u.\n", iface, face, level);
764
765 wined3d_mutex_lock();
766 sub_resource_idx = wined3d_texture_get_level_count(texture->wined3d_texture) * face + level;
767 if (!(surface_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, sub_resource_idx)))
768 hr = D3DERR_INVALIDCALL;
769 else
770 hr = IDirect3DSurface9_UnlockRect(&surface_impl->IDirect3DSurface9_iface);
771 wined3d_mutex_unlock();
772
773 return hr;
774 }
775
776 static HRESULT WINAPI d3d9_texture_cube_AddDirtyRect(IDirect3DCubeTexture9 *iface,
777 D3DCUBEMAP_FACES face, const RECT *dirty_rect)
778 {
779 struct d3d9_texture *texture = impl_from_IDirect3DCubeTexture9(iface);
780 HRESULT hr;
781
782 TRACE("iface %p, face %#x, dirty_rect %s.\n",
783 iface, face, wine_dbgstr_rect(dirty_rect));
784
785 wined3d_mutex_lock();
786 if (!dirty_rect)
787 hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, face, NULL);
788 else
789 {
790 struct wined3d_box dirty_region;
791
792 wined3d_box_set(&dirty_region, dirty_rect->left, dirty_rect->top, dirty_rect->right, dirty_rect->bottom, 0, 1);
793 hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, face, &dirty_region);
794 }
795 wined3d_mutex_unlock();
796
797 return hr;
798 }
799
800 static const IDirect3DCubeTexture9Vtbl d3d9_texture_cube_vtbl =
801 {
802 /* IUnknown */
803 d3d9_texture_cube_QueryInterface,
804 d3d9_texture_cube_AddRef,
805 d3d9_texture_cube_Release,
806 /* IDirect3DResource9 */
807 d3d9_texture_cube_GetDevice,
808 d3d9_texture_cube_SetPrivateData,
809 d3d9_texture_cube_GetPrivateData,
810 d3d9_texture_cube_FreePrivateData,
811 d3d9_texture_cube_SetPriority,
812 d3d9_texture_cube_GetPriority,
813 d3d9_texture_cube_PreLoad,
814 d3d9_texture_cube_GetType,
815 /* IDirect3DBaseTexture9 */
816 d3d9_texture_cube_SetLOD,
817 d3d9_texture_cube_GetLOD,
818 d3d9_texture_cube_GetLevelCount,
819 d3d9_texture_cube_SetAutoGenFilterType,
820 d3d9_texture_cube_GetAutoGenFilterType,
821 d3d9_texture_cube_GenerateMipSubLevels,
822 /* IDirect3DCubeTexture9 */
823 d3d9_texture_cube_GetLevelDesc,
824 d3d9_texture_cube_GetCubeMapSurface,
825 d3d9_texture_cube_LockRect,
826 d3d9_texture_cube_UnlockRect,
827 d3d9_texture_cube_AddDirtyRect,
828 };
829
830 static HRESULT WINAPI d3d9_texture_3d_QueryInterface(IDirect3DVolumeTexture9 *iface, REFIID riid, void **out)
831 {
832 TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
833
834 if (IsEqualGUID(riid, &IID_IDirect3DVolumeTexture9)
835 || IsEqualGUID(riid, &IID_IDirect3DBaseTexture9)
836 || IsEqualGUID(riid, &IID_IDirect3DResource9)
837 || IsEqualGUID(riid, &IID_IUnknown))
838 {
839 IDirect3DVolumeTexture9_AddRef(iface);
840 *out = iface;
841 return S_OK;
842 }
843
844 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
845
846 *out = NULL;
847 return E_NOINTERFACE;
848 }
849
850 static ULONG WINAPI d3d9_texture_3d_AddRef(IDirect3DVolumeTexture9 *iface)
851 {
852 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
853 ULONG ref = InterlockedIncrement(&texture->resource.refcount);
854
855 TRACE("%p increasing refcount to %u.\n", iface, ref);
856
857 if (ref == 1)
858 {
859 IDirect3DDevice9Ex_AddRef(texture->parent_device);
860 wined3d_mutex_lock();
861 wined3d_texture_incref(texture->wined3d_texture);
862 wined3d_mutex_unlock();
863 }
864
865 return ref;
866 }
867
868 static ULONG WINAPI d3d9_texture_3d_Release(IDirect3DVolumeTexture9 *iface)
869 {
870 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
871 ULONG ref = InterlockedDecrement(&texture->resource.refcount);
872
873 TRACE("%p decreasing refcount to %u.\n", iface, ref);
874
875 if (!ref)
876 {
877 IDirect3DDevice9Ex *parent_device = texture->parent_device;
878
879 wined3d_mutex_lock();
880 wined3d_texture_decref(texture->wined3d_texture);
881 wined3d_mutex_unlock();
882
883 /* Release the device last, as it may cause the device to be destroyed. */
884 IDirect3DDevice9Ex_Release(parent_device);
885 }
886 return ref;
887 }
888
889 static HRESULT WINAPI d3d9_texture_3d_GetDevice(IDirect3DVolumeTexture9 *iface, IDirect3DDevice9 **device)
890 {
891 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
892
893 TRACE("iface %p, device %p.\n", iface, device);
894
895 *device = (IDirect3DDevice9 *)texture->parent_device;
896 IDirect3DDevice9_AddRef(*device);
897
898 TRACE("Returning device %p.\n", *device);
899
900 return D3D_OK;
901 }
902
903 static HRESULT WINAPI d3d9_texture_3d_SetPrivateData(IDirect3DVolumeTexture9 *iface,
904 REFGUID guid, const void *data, DWORD data_size, DWORD flags)
905 {
906 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
907 TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
908 iface, debugstr_guid(guid), data, data_size, flags);
909
910 return d3d9_resource_set_private_data(&texture->resource, guid, data, data_size, flags);
911 }
912
913 static HRESULT WINAPI d3d9_texture_3d_GetPrivateData(IDirect3DVolumeTexture9 *iface,
914 REFGUID guid, void *data, DWORD *data_size)
915 {
916 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
917 TRACE("iface %p, guid %s, data %p, data_size %p.\n",
918 iface, debugstr_guid(guid), data, data_size);
919
920 return d3d9_resource_get_private_data(&texture->resource, guid, data, data_size);
921 }
922
923 static HRESULT WINAPI d3d9_texture_3d_FreePrivateData(IDirect3DVolumeTexture9 *iface, REFGUID guid)
924 {
925 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
926 TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
927
928 return d3d9_resource_free_private_data(&texture->resource, guid);
929 }
930
931 static DWORD WINAPI d3d9_texture_3d_SetPriority(IDirect3DVolumeTexture9 *iface, DWORD priority)
932 {
933 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
934 struct wined3d_resource *resource;
935 DWORD ret;
936
937 TRACE("iface %p, priority %u.\n", iface, priority);
938
939 wined3d_mutex_lock();
940 resource = wined3d_texture_get_resource(texture->wined3d_texture);
941 ret = wined3d_resource_set_priority(resource, priority);
942 wined3d_mutex_unlock();
943
944 return ret;
945 }
946
947 static DWORD WINAPI d3d9_texture_3d_GetPriority(IDirect3DVolumeTexture9 *iface)
948 {
949 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
950 const struct wined3d_resource *resource;
951 DWORD ret;
952
953 TRACE("iface %p.\n", iface);
954
955 wined3d_mutex_lock();
956 resource = wined3d_texture_get_resource(texture->wined3d_texture);
957 ret = wined3d_resource_get_priority(resource);
958 wined3d_mutex_unlock();
959
960 return ret;
961 }
962
963 static void WINAPI d3d9_texture_3d_PreLoad(IDirect3DVolumeTexture9 *iface)
964 {
965 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
966
967 TRACE("iface %p.\n", iface);
968
969 wined3d_mutex_lock();
970 wined3d_resource_preload(wined3d_texture_get_resource(texture->wined3d_texture));
971 wined3d_mutex_unlock();
972 }
973
974 static D3DRESOURCETYPE WINAPI d3d9_texture_3d_GetType(IDirect3DVolumeTexture9 *iface)
975 {
976 TRACE("iface %p.\n", iface);
977
978 return D3DRTYPE_VOLUMETEXTURE;
979 }
980
981 static DWORD WINAPI d3d9_texture_3d_SetLOD(IDirect3DVolumeTexture9 *iface, DWORD lod)
982 {
983 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
984 DWORD ret;
985
986 TRACE("iface %p, lod %u.\n", iface, lod);
987
988 wined3d_mutex_lock();
989 ret = wined3d_texture_set_lod(texture->wined3d_texture, lod);
990 wined3d_mutex_unlock();
991
992 return ret;
993 }
994
995 static DWORD WINAPI d3d9_texture_3d_GetLOD(IDirect3DVolumeTexture9 *iface)
996 {
997 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
998 DWORD ret;
999
1000 TRACE("iface %p.\n", iface);
1001
1002 wined3d_mutex_lock();
1003 ret = wined3d_texture_get_lod(texture->wined3d_texture);
1004 wined3d_mutex_unlock();
1005
1006 return ret;
1007 }
1008
1009 static DWORD WINAPI d3d9_texture_3d_GetLevelCount(IDirect3DVolumeTexture9 *iface)
1010 {
1011 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1012 DWORD ret;
1013
1014 TRACE("iface %p.\n", iface);
1015
1016 wined3d_mutex_lock();
1017 ret = wined3d_texture_get_level_count(texture->wined3d_texture);
1018 wined3d_mutex_unlock();
1019
1020 return ret;
1021 }
1022
1023 static HRESULT WINAPI d3d9_texture_3d_SetAutoGenFilterType(IDirect3DVolumeTexture9 *iface,
1024 D3DTEXTUREFILTERTYPE filter_type)
1025 {
1026 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1027 HRESULT hr;
1028
1029 TRACE("iface %p, filter_type %#x.\n", iface, filter_type);
1030
1031 wined3d_mutex_lock();
1032 hr = wined3d_texture_set_autogen_filter_type(texture->wined3d_texture,
1033 (enum wined3d_texture_filter_type)filter_type);
1034 wined3d_mutex_unlock();
1035
1036 return hr;
1037 }
1038
1039 static D3DTEXTUREFILTERTYPE WINAPI d3d9_texture_3d_GetAutoGenFilterType(IDirect3DVolumeTexture9 *iface)
1040 {
1041 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1042 D3DTEXTUREFILTERTYPE filter_type;
1043
1044 TRACE("iface %p.\n", iface);
1045
1046 wined3d_mutex_lock();
1047 filter_type = (D3DTEXTUREFILTERTYPE)wined3d_texture_get_autogen_filter_type(texture->wined3d_texture);
1048 wined3d_mutex_unlock();
1049
1050 return filter_type;
1051 }
1052
1053 static void WINAPI d3d9_texture_3d_GenerateMipSubLevels(IDirect3DVolumeTexture9 *iface)
1054 {
1055 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1056
1057 TRACE("iface %p.\n", iface);
1058
1059 wined3d_mutex_lock();
1060 wined3d_texture_generate_mipmaps(texture->wined3d_texture);
1061 wined3d_mutex_unlock();
1062 }
1063
1064 static HRESULT WINAPI d3d9_texture_3d_GetLevelDesc(IDirect3DVolumeTexture9 *iface, UINT level, D3DVOLUME_DESC *desc)
1065 {
1066 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1067 struct wined3d_sub_resource_desc wined3d_desc;
1068 HRESULT hr;
1069
1070 TRACE("iface %p, level %u, desc %p.\n", iface, level, desc);
1071
1072 wined3d_mutex_lock();
1073 if (SUCCEEDED(hr = wined3d_texture_get_sub_resource_desc(texture->wined3d_texture, level, &wined3d_desc)))
1074 {
1075 desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
1076 desc->Type = D3DRTYPE_VOLUME;
1077 desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK;
1078 desc->Pool = wined3d_desc.pool;
1079 desc->Width = wined3d_desc.width;
1080 desc->Height = wined3d_desc.height;
1081 desc->Depth = wined3d_desc.depth;
1082 }
1083 wined3d_mutex_unlock();
1084
1085 return hr;
1086 }
1087
1088 static HRESULT WINAPI d3d9_texture_3d_GetVolumeLevel(IDirect3DVolumeTexture9 *iface,
1089 UINT level, IDirect3DVolume9 **volume)
1090 {
1091 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1092 struct d3d9_volume *volume_impl;
1093
1094 TRACE("iface %p, level %u, volume %p.\n", iface, level, volume);
1095
1096 wined3d_mutex_lock();
1097 if (!(volume_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level)))
1098 {
1099 wined3d_mutex_unlock();
1100 return D3DERR_INVALIDCALL;
1101 }
1102
1103 *volume = &volume_impl->IDirect3DVolume9_iface;
1104 IDirect3DVolume9_AddRef(*volume);
1105 wined3d_mutex_unlock();
1106
1107 return D3D_OK;
1108 }
1109
1110 static HRESULT WINAPI d3d9_texture_3d_LockBox(IDirect3DVolumeTexture9 *iface,
1111 UINT level, D3DLOCKED_BOX *locked_box, const D3DBOX *box, DWORD flags)
1112 {
1113 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1114 struct d3d9_volume *volume_impl;
1115 HRESULT hr;
1116
1117 TRACE("iface %p, level %u, locked_box %p, box %p, flags %#x.\n",
1118 iface, level, locked_box, box, flags);
1119
1120 wined3d_mutex_lock();
1121 if (!(volume_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level)))
1122 hr = D3DERR_INVALIDCALL;
1123 else
1124 hr = IDirect3DVolume9_LockBox(&volume_impl->IDirect3DVolume9_iface, locked_box, box, flags);
1125 wined3d_mutex_unlock();
1126
1127 return hr;
1128 }
1129
1130 static HRESULT WINAPI d3d9_texture_3d_UnlockBox(IDirect3DVolumeTexture9 *iface, UINT level)
1131 {
1132 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1133 struct d3d9_volume *volume_impl;
1134 HRESULT hr;
1135
1136 TRACE("iface %p, level %u.\n", iface, level);
1137
1138 wined3d_mutex_lock();
1139 if (!(volume_impl = wined3d_texture_get_sub_resource_parent(texture->wined3d_texture, level)))
1140 hr = D3DERR_INVALIDCALL;
1141 else
1142 hr = IDirect3DVolume9_UnlockBox(&volume_impl->IDirect3DVolume9_iface);
1143 wined3d_mutex_unlock();
1144
1145 return hr;
1146 }
1147
1148 static HRESULT WINAPI d3d9_texture_3d_AddDirtyBox(IDirect3DVolumeTexture9 *iface, const D3DBOX *dirty_box)
1149 {
1150 struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface);
1151 HRESULT hr;
1152
1153 TRACE("iface %p, dirty_box %p.\n", iface, dirty_box);
1154
1155 wined3d_mutex_lock();
1156 hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, 0, (const struct wined3d_box *)dirty_box);
1157 wined3d_mutex_unlock();
1158
1159 return hr;
1160 }
1161
1162
1163 static const IDirect3DVolumeTexture9Vtbl d3d9_texture_3d_vtbl =
1164 {
1165 /* IUnknown */
1166 d3d9_texture_3d_QueryInterface,
1167 d3d9_texture_3d_AddRef,
1168 d3d9_texture_3d_Release,
1169 /* IDirect3DResource9 */
1170 d3d9_texture_3d_GetDevice,
1171 d3d9_texture_3d_SetPrivateData,
1172 d3d9_texture_3d_GetPrivateData,
1173 d3d9_texture_3d_FreePrivateData,
1174 d3d9_texture_3d_SetPriority,
1175 d3d9_texture_3d_GetPriority,
1176 d3d9_texture_3d_PreLoad,
1177 d3d9_texture_3d_GetType,
1178 /* IDirect3DBaseTexture9 */
1179 d3d9_texture_3d_SetLOD,
1180 d3d9_texture_3d_GetLOD,
1181 d3d9_texture_3d_GetLevelCount,
1182 d3d9_texture_3d_SetAutoGenFilterType,
1183 d3d9_texture_3d_GetAutoGenFilterType,
1184 d3d9_texture_3d_GenerateMipSubLevels,
1185 /* IDirect3DVolumeTexture9 */
1186 d3d9_texture_3d_GetLevelDesc,
1187 d3d9_texture_3d_GetVolumeLevel,
1188 d3d9_texture_3d_LockBox,
1189 d3d9_texture_3d_UnlockBox,
1190 d3d9_texture_3d_AddDirtyBox,
1191 };
1192
1193 struct d3d9_texture *unsafe_impl_from_IDirect3DBaseTexture9(IDirect3DBaseTexture9 *iface)
1194 {
1195 if (!iface)
1196 return NULL;
1197
1198 if (iface->lpVtbl != (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_2d_vtbl
1199 && iface->lpVtbl != (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_cube_vtbl
1200 && iface->lpVtbl != (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_3d_vtbl)
1201 {
1202 WARN("%p is not a valid IDirect3DBaseTexture9 interface.\n", iface);
1203 return NULL;
1204 }
1205
1206 return CONTAINING_RECORD(iface, struct d3d9_texture, IDirect3DBaseTexture9_iface);
1207 }
1208
1209 static void STDMETHODCALLTYPE d3d9_texture_wined3d_object_destroyed(void *parent)
1210 {
1211 struct d3d9_texture *texture = parent;
1212 d3d9_resource_cleanup(&texture->resource);
1213 HeapFree(GetProcessHeap(), 0, texture);
1214 }
1215
1216 static const struct wined3d_parent_ops d3d9_texture_wined3d_parent_ops =
1217 {
1218 d3d9_texture_wined3d_object_destroyed,
1219 };
1220
1221 HRESULT texture_init(struct d3d9_texture *texture, struct d3d9_device *device,
1222 UINT width, UINT height, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool)
1223 {
1224 struct wined3d_resource_desc desc;
1225 DWORD flags = 0;
1226 HRESULT hr;
1227
1228 texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_2d_vtbl;
1229 d3d9_resource_init(&texture->resource);
1230 list_init(&texture->rtv_list);
1231
1232 desc.resource_type = WINED3D_RTYPE_TEXTURE_2D;
1233 desc.format = wined3dformat_from_d3dformat(format);
1234 desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
1235 desc.multisample_quality = 0;
1236 desc.usage = usage & WINED3DUSAGE_MASK;
1237 desc.usage |= WINED3DUSAGE_TEXTURE;
1238 desc.pool = pool;
1239 desc.width = width;
1240 desc.height = height;
1241 desc.depth = 1;
1242 desc.size = 0;
1243
1244 if (pool != D3DPOOL_DEFAULT || (usage & D3DUSAGE_DYNAMIC))
1245 flags |= WINED3D_TEXTURE_CREATE_MAPPABLE;
1246
1247 if (is_gdi_compat_wined3dformat(desc.format))
1248 flags |= WINED3D_TEXTURE_CREATE_GET_DC;
1249
1250 if (!levels)
1251 {
1252 if (usage & D3DUSAGE_AUTOGENMIPMAP)
1253 levels = 1;
1254 else
1255 levels = wined3d_log2i(max(width, height)) + 1;
1256 }
1257
1258 wined3d_mutex_lock();
1259 hr = wined3d_texture_create(device->wined3d_device, &desc, 1, levels, flags,
1260 NULL, texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture);
1261 wined3d_mutex_unlock();
1262 if (FAILED(hr))
1263 {
1264 WARN("Failed to create wined3d texture, hr %#x.\n", hr);
1265 return hr;
1266 }
1267
1268 texture->parent_device = &device->IDirect3DDevice9Ex_iface;
1269 IDirect3DDevice9Ex_AddRef(texture->parent_device);
1270
1271 return D3D_OK;
1272 }
1273
1274 HRESULT cubetexture_init(struct d3d9_texture *texture, struct d3d9_device *device,
1275 UINT edge_length, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool)
1276 {
1277 struct wined3d_resource_desc desc;
1278 DWORD flags = 0;
1279 HRESULT hr;
1280
1281 texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_cube_vtbl;
1282 d3d9_resource_init(&texture->resource);
1283 list_init(&texture->rtv_list);
1284
1285 desc.resource_type = WINED3D_RTYPE_TEXTURE_2D;
1286 desc.format = wined3dformat_from_d3dformat(format);
1287 desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
1288 desc.multisample_quality = 0;
1289 desc.usage = usage & WINED3DUSAGE_MASK;
1290 desc.usage |= WINED3DUSAGE_LEGACY_CUBEMAP | WINED3DUSAGE_TEXTURE;
1291 desc.pool = pool;
1292 desc.width = edge_length;
1293 desc.height = edge_length;
1294 desc.depth = 1;
1295 desc.size = 0;
1296
1297 if (pool != D3DPOOL_DEFAULT || (usage & D3DUSAGE_DYNAMIC))
1298 flags |= WINED3D_TEXTURE_CREATE_MAPPABLE;
1299
1300 if (is_gdi_compat_wined3dformat(desc.format))
1301 flags |= WINED3D_TEXTURE_CREATE_GET_DC;
1302
1303 if (!levels)
1304 {
1305 if (usage & D3DUSAGE_AUTOGENMIPMAP)
1306 levels = 1;
1307 else
1308 levels = wined3d_log2i(edge_length) + 1;
1309 }
1310
1311 wined3d_mutex_lock();
1312 hr = wined3d_texture_create(device->wined3d_device, &desc, 6, levels, flags,
1313 NULL, texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture);
1314 wined3d_mutex_unlock();
1315 if (FAILED(hr))
1316 {
1317 WARN("Failed to create wined3d cube texture, hr %#x.\n", hr);
1318 return hr;
1319 }
1320
1321 texture->parent_device = &device->IDirect3DDevice9Ex_iface;
1322 IDirect3DDevice9Ex_AddRef(texture->parent_device);
1323
1324 return D3D_OK;
1325 }
1326
1327 HRESULT volumetexture_init(struct d3d9_texture *texture, struct d3d9_device *device,
1328 UINT width, UINT height, UINT depth, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool)
1329 {
1330 struct wined3d_resource_desc desc;
1331 HRESULT hr;
1332
1333 texture->IDirect3DBaseTexture9_iface.lpVtbl = (const IDirect3DBaseTexture9Vtbl *)&d3d9_texture_3d_vtbl;
1334 d3d9_resource_init(&texture->resource);
1335 list_init(&texture->rtv_list);
1336
1337 desc.resource_type = WINED3D_RTYPE_TEXTURE_3D;
1338 desc.format = wined3dformat_from_d3dformat(format);
1339 desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
1340 desc.multisample_quality = 0;
1341 desc.usage = usage & WINED3DUSAGE_MASK;
1342 desc.usage |= WINED3DUSAGE_TEXTURE;
1343 desc.pool = pool;
1344 desc.width = width;
1345 desc.height = height;
1346 desc.depth = depth;
1347 desc.size = 0;
1348
1349 if (!levels)
1350 {
1351 if (usage & D3DUSAGE_AUTOGENMIPMAP)
1352 levels = 1;
1353 else
1354 levels = wined3d_log2i(max(max(width, height), depth)) + 1;
1355 }
1356
1357 wined3d_mutex_lock();
1358 hr = wined3d_texture_create(device->wined3d_device, &desc, 1, levels, 0,
1359 NULL, texture, &d3d9_texture_wined3d_parent_ops, &texture->wined3d_texture);
1360 wined3d_mutex_unlock();
1361 if (FAILED(hr))
1362 {
1363 WARN("Failed to create wined3d volume texture, hr %#x.\n", hr);
1364 return hr;
1365 }
1366
1367 texture->parent_device = &device->IDirect3DDevice9Ex_iface;
1368 IDirect3DDevice9Ex_AddRef(texture->parent_device);
1369
1370 return D3D_OK;
1371 }