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