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