* Sync up to trunk head (r64377).
[reactos.git] / dll / directx / wine / d3d8 / texture.c
1 /*
2 * Copyright 2005 Oliver Stieber
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17 */
18
19 #include "d3d8_private.h"
20
21 static inline struct d3d8_texture *impl_from_IDirect3DTexture8(IDirect3DTexture8 *iface)
22 {
23 return CONTAINING_RECORD(iface, struct d3d8_texture, IDirect3DBaseTexture8_iface);
24 }
25
26 static inline struct d3d8_texture *impl_from_IDirect3DCubeTexture8(IDirect3DCubeTexture8 *iface)
27 {
28 return CONTAINING_RECORD(iface, struct d3d8_texture, IDirect3DBaseTexture8_iface);
29 }
30
31 static inline struct d3d8_texture *impl_from_IDirect3DVolumeTexture8(IDirect3DVolumeTexture8 *iface)
32 {
33 return CONTAINING_RECORD(iface, struct d3d8_texture, IDirect3DBaseTexture8_iface);
34 }
35
36 static HRESULT WINAPI d3d8_texture_2d_QueryInterface(IDirect3DTexture8 *iface, REFIID riid, void **out)
37 {
38 TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
39
40 if (IsEqualGUID(riid, &IID_IDirect3DTexture8)
41 || IsEqualGUID(riid, &IID_IDirect3DBaseTexture8)
42 || IsEqualGUID(riid, &IID_IDirect3DResource8)
43 || IsEqualGUID(riid, &IID_IUnknown))
44 {
45 IDirect3DTexture8_AddRef(iface);
46 *out = iface;
47 return S_OK;
48 }
49
50 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
51
52 *out = NULL;
53 return E_NOINTERFACE;
54 }
55
56 static ULONG WINAPI d3d8_texture_2d_AddRef(IDirect3DTexture8 *iface)
57 {
58 struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface);
59 ULONG ref = InterlockedIncrement(&texture->resource.refcount);
60
61 TRACE("%p increasing refcount to %u.\n", iface, ref);
62
63 if (ref == 1)
64 {
65 struct d3d8_surface *surface;
66
67 IDirect3DDevice8_AddRef(texture->parent_device);
68 wined3d_mutex_lock();
69 LIST_FOR_EACH_ENTRY(surface, &texture->rtv_list, struct d3d8_surface, rtv_entry)
70 {
71 wined3d_rendertarget_view_incref(surface->wined3d_rtv);
72 }
73 wined3d_texture_incref(texture->wined3d_texture);
74 wined3d_mutex_unlock();
75 }
76
77 return ref;
78 }
79
80 static ULONG WINAPI d3d8_texture_2d_Release(IDirect3DTexture8 *iface)
81 {
82 struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface);
83 ULONG ref = InterlockedDecrement(&texture->resource.refcount);
84
85 TRACE("%p decreasing refcount to %u.\n", iface, ref);
86
87 if (!ref)
88 {
89 IDirect3DDevice8 *parent_device = texture->parent_device;
90 struct d3d8_surface *surface;
91
92 wined3d_mutex_lock();
93 LIST_FOR_EACH_ENTRY(surface, &texture->rtv_list, struct d3d8_surface, rtv_entry)
94 {
95 wined3d_rendertarget_view_decref(surface->wined3d_rtv);
96 }
97 wined3d_texture_decref(texture->wined3d_texture);
98 wined3d_mutex_unlock();
99
100 /* Release the device last, as it may cause the device to be destroyed. */
101 IDirect3DDevice8_Release(parent_device);
102 }
103 return ref;
104 }
105
106 static HRESULT WINAPI d3d8_texture_2d_GetDevice(IDirect3DTexture8 *iface, IDirect3DDevice8 **device)
107 {
108 struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface);
109
110 TRACE("iface %p, device %p.\n", iface, device);
111
112 *device = texture->parent_device;
113 IDirect3DDevice8_AddRef(*device);
114
115 TRACE("Returning device %p.\n", *device);
116
117 return D3D_OK;
118 }
119
120 static HRESULT WINAPI d3d8_texture_2d_SetPrivateData(IDirect3DTexture8 *iface,
121 REFGUID guid, const void *data, DWORD data_size, DWORD flags)
122 {
123 struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface);
124 TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
125 iface, debugstr_guid(guid), data, data_size, flags);
126
127 return d3d8_resource_set_private_data(&texture->resource, guid, data, data_size, flags);
128 }
129
130 static HRESULT WINAPI d3d8_texture_2d_GetPrivateData(IDirect3DTexture8 *iface,
131 REFGUID guid, void *data, DWORD *data_size)
132 {
133 struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface);
134 TRACE("iface %p, guid %s, data %p, data_size %p.\n",
135 iface, debugstr_guid(guid), data, data_size);
136
137 return d3d8_resource_get_private_data(&texture->resource, guid, data, data_size);
138 }
139
140 static HRESULT WINAPI d3d8_texture_2d_FreePrivateData(IDirect3DTexture8 *iface, REFGUID guid)
141 {
142 struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface);
143 TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
144
145 return d3d8_resource_free_private_data(&texture->resource, guid);
146 }
147
148 static DWORD WINAPI d3d8_texture_2d_SetPriority(IDirect3DTexture8 *iface, DWORD priority)
149 {
150 struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface);
151 struct wined3d_resource *resource;
152 DWORD ret;
153
154 TRACE("iface %p, priority %u.\n", iface, priority);
155
156 wined3d_mutex_lock();
157 resource = wined3d_texture_get_resource(texture->wined3d_texture);
158 ret = wined3d_resource_set_priority(resource, priority);
159 wined3d_mutex_unlock();
160
161 return ret;
162 }
163
164 static DWORD WINAPI d3d8_texture_2d_GetPriority(IDirect3DTexture8 *iface)
165 {
166 struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface);
167 const struct wined3d_resource *resource;
168 DWORD ret;
169
170 TRACE("iface %p.\n", iface);
171
172 wined3d_mutex_lock();
173 resource = wined3d_texture_get_resource(texture->wined3d_texture);
174 ret = wined3d_resource_get_priority(resource);
175 wined3d_mutex_unlock();
176
177 return ret;
178 }
179
180 static void WINAPI d3d8_texture_2d_PreLoad(IDirect3DTexture8 *iface)
181 {
182 struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface);
183
184 TRACE("iface %p.\n", iface);
185
186 wined3d_mutex_lock();
187 wined3d_texture_preload(texture->wined3d_texture);
188 wined3d_mutex_unlock();
189 }
190
191 static D3DRESOURCETYPE WINAPI d3d8_texture_2d_GetType(IDirect3DTexture8 *iface)
192 {
193 TRACE("iface %p.\n", iface);
194
195 return D3DRTYPE_TEXTURE;
196 }
197
198 static DWORD WINAPI d3d8_texture_2d_SetLOD(IDirect3DTexture8 *iface, DWORD lod)
199 {
200 struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface);
201 DWORD ret;
202
203 TRACE("iface %p, lod %u.\n", iface, lod);
204
205 wined3d_mutex_lock();
206 ret = wined3d_texture_set_lod(texture->wined3d_texture, lod);
207 wined3d_mutex_unlock();
208
209 return ret;
210 }
211
212 static DWORD WINAPI d3d8_texture_2d_GetLOD(IDirect3DTexture8 *iface)
213 {
214 struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface);
215 DWORD ret;
216
217 TRACE("iface %p.\n", iface);
218
219 wined3d_mutex_lock();
220 ret = wined3d_texture_get_lod(texture->wined3d_texture);
221 wined3d_mutex_unlock();
222
223 return ret;
224 }
225
226 static DWORD WINAPI d3d8_texture_2d_GetLevelCount(IDirect3DTexture8 *iface)
227 {
228 struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface);
229 DWORD ret;
230
231 TRACE("iface %p.\n", iface);
232
233 wined3d_mutex_lock();
234 ret = wined3d_texture_get_level_count(texture->wined3d_texture);
235 wined3d_mutex_unlock();
236
237 return ret;
238 }
239
240 static HRESULT WINAPI d3d8_texture_2d_GetLevelDesc(IDirect3DTexture8 *iface, UINT level, D3DSURFACE_DESC *desc)
241 {
242 struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface);
243 struct wined3d_resource *sub_resource;
244 HRESULT hr = D3D_OK;
245
246 TRACE("iface %p, level %u, desc %p.\n", iface, level, desc);
247
248 wined3d_mutex_lock();
249 if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
250 hr = D3DERR_INVALIDCALL;
251 else
252 {
253 struct wined3d_resource_desc wined3d_desc;
254
255 wined3d_resource_get_desc(sub_resource, &wined3d_desc);
256 desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
257 desc->Type = wined3d_desc.resource_type;
258 desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK;
259 desc->Pool = wined3d_desc.pool;
260 desc->Size = wined3d_desc.size;
261 desc->MultiSampleType = wined3d_desc.multisample_type;
262 desc->Width = wined3d_desc.width;
263 desc->Height = wined3d_desc.height;
264 }
265 wined3d_mutex_unlock();
266
267 return hr;
268 }
269
270 static HRESULT WINAPI d3d8_texture_2d_GetSurfaceLevel(IDirect3DTexture8 *iface,
271 UINT level, IDirect3DSurface8 **surface)
272 {
273 struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface);
274 struct wined3d_resource *sub_resource;
275 struct d3d8_surface *surface_impl;
276
277 TRACE("iface %p, level %u, surface %p.\n", iface, level, surface);
278
279 wined3d_mutex_lock();
280 if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
281 {
282 wined3d_mutex_unlock();
283 return D3DERR_INVALIDCALL;
284 }
285
286 surface_impl = wined3d_resource_get_parent(sub_resource);
287 *surface = &surface_impl->IDirect3DSurface8_iface;
288 IDirect3DSurface8_AddRef(*surface);
289 wined3d_mutex_unlock();
290
291 return D3D_OK;
292 }
293
294 static HRESULT WINAPI d3d8_texture_2d_LockRect(IDirect3DTexture8 *iface, UINT level,
295 D3DLOCKED_RECT *locked_rect, const RECT *rect, DWORD flags)
296 {
297 struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface);
298 struct wined3d_resource *sub_resource;
299 struct d3d8_surface *surface_impl;
300 HRESULT hr;
301
302 TRACE("iface %p, level %u, locked_rect %p, rect %p, flags %#x.\n",
303 iface, level, locked_rect, rect, flags);
304
305 wined3d_mutex_lock();
306 if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
307 hr = D3DERR_INVALIDCALL;
308 else
309 {
310 surface_impl = wined3d_resource_get_parent(sub_resource);
311 hr = IDirect3DSurface8_LockRect(&surface_impl->IDirect3DSurface8_iface, locked_rect, rect, flags);
312 }
313 wined3d_mutex_unlock();
314
315 return hr;
316 }
317
318 static HRESULT WINAPI d3d8_texture_2d_UnlockRect(IDirect3DTexture8 *iface, UINT level)
319 {
320 struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface);
321 struct wined3d_resource *sub_resource;
322 struct d3d8_surface *surface_impl;
323 HRESULT hr;
324
325 TRACE("iface %p, level %u.\n", iface, level);
326
327 wined3d_mutex_lock();
328 if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
329 hr = D3DERR_INVALIDCALL;
330 else
331 {
332 surface_impl = wined3d_resource_get_parent(sub_resource);
333 hr = IDirect3DSurface8_UnlockRect(&surface_impl->IDirect3DSurface8_iface);
334 }
335 wined3d_mutex_unlock();
336
337 return hr;
338 }
339
340 static HRESULT WINAPI d3d8_texture_2d_AddDirtyRect(IDirect3DTexture8 *iface, const RECT *dirty_rect)
341 {
342 struct d3d8_texture *texture = impl_from_IDirect3DTexture8(iface);
343 HRESULT hr;
344
345 TRACE("iface %p, dirty_rect %s.\n",
346 iface, wine_dbgstr_rect(dirty_rect));
347
348 wined3d_mutex_lock();
349 if (!dirty_rect)
350 hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, 0, NULL);
351 else
352 {
353 struct wined3d_box dirty_region;
354
355 dirty_region.left = dirty_rect->left;
356 dirty_region.top = dirty_rect->top;
357 dirty_region.right = dirty_rect->right;
358 dirty_region.bottom = dirty_rect->bottom;
359 dirty_region.front = 0;
360 dirty_region.back = 1;
361 hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, 0, &dirty_region);
362 }
363 wined3d_mutex_unlock();
364
365 return hr;
366 }
367
368 static const IDirect3DTexture8Vtbl Direct3DTexture8_Vtbl =
369 {
370 /* IUnknown */
371 d3d8_texture_2d_QueryInterface,
372 d3d8_texture_2d_AddRef,
373 d3d8_texture_2d_Release,
374 /* IDirect3DResource8 */
375 d3d8_texture_2d_GetDevice,
376 d3d8_texture_2d_SetPrivateData,
377 d3d8_texture_2d_GetPrivateData,
378 d3d8_texture_2d_FreePrivateData,
379 d3d8_texture_2d_SetPriority,
380 d3d8_texture_2d_GetPriority,
381 d3d8_texture_2d_PreLoad,
382 d3d8_texture_2d_GetType,
383 /* IDirect3dBaseTexture8 */
384 d3d8_texture_2d_SetLOD,
385 d3d8_texture_2d_GetLOD,
386 d3d8_texture_2d_GetLevelCount,
387 /* IDirect3DTexture8 */
388 d3d8_texture_2d_GetLevelDesc,
389 d3d8_texture_2d_GetSurfaceLevel,
390 d3d8_texture_2d_LockRect,
391 d3d8_texture_2d_UnlockRect,
392 d3d8_texture_2d_AddDirtyRect,
393 };
394
395 static HRESULT WINAPI d3d8_texture_cube_QueryInterface(IDirect3DCubeTexture8 *iface, REFIID riid, void **out)
396 {
397 TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
398
399 if (IsEqualGUID(riid, &IID_IDirect3DCubeTexture8)
400 || IsEqualGUID(riid, &IID_IDirect3DBaseTexture8)
401 || IsEqualGUID(riid, &IID_IDirect3DResource8)
402 || IsEqualGUID(riid, &IID_IUnknown))
403 {
404 IDirect3DCubeTexture8_AddRef(iface);
405 *out = iface;
406 return S_OK;
407 }
408
409 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
410
411 *out = NULL;
412 return E_NOINTERFACE;
413 }
414
415 static ULONG WINAPI d3d8_texture_cube_AddRef(IDirect3DCubeTexture8 *iface)
416 {
417 struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface);
418 ULONG ref = InterlockedIncrement(&texture->resource.refcount);
419
420 TRACE("%p increasing refcount to %u.\n", iface, ref);
421
422 if (ref == 1)
423 {
424 struct d3d8_surface *surface;
425
426 IDirect3DDevice8_AddRef(texture->parent_device);
427 wined3d_mutex_lock();
428 LIST_FOR_EACH_ENTRY(surface, &texture->rtv_list, struct d3d8_surface, rtv_entry)
429 {
430 wined3d_rendertarget_view_incref(surface->wined3d_rtv);
431 }
432 wined3d_texture_incref(texture->wined3d_texture);
433 wined3d_mutex_unlock();
434 }
435
436 return ref;
437 }
438
439 static ULONG WINAPI d3d8_texture_cube_Release(IDirect3DCubeTexture8 *iface)
440 {
441 struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface);
442 ULONG ref = InterlockedDecrement(&texture->resource.refcount);
443
444 TRACE("%p decreasing refcount to %u.\n", iface, ref);
445
446 if (!ref)
447 {
448 IDirect3DDevice8 *parent_device = texture->parent_device;
449 struct d3d8_surface *surface;
450
451 TRACE("Releasing child %p.\n", texture->wined3d_texture);
452
453 wined3d_mutex_lock();
454 LIST_FOR_EACH_ENTRY(surface, &texture->rtv_list, struct d3d8_surface, rtv_entry)
455 {
456 wined3d_rendertarget_view_decref(surface->wined3d_rtv);
457 }
458 wined3d_texture_decref(texture->wined3d_texture);
459 wined3d_mutex_unlock();
460
461 /* Release the device last, as it may cause the device to be destroyed. */
462 IDirect3DDevice8_Release(parent_device);
463 }
464 return ref;
465 }
466
467 static HRESULT WINAPI d3d8_texture_cube_GetDevice(IDirect3DCubeTexture8 *iface, IDirect3DDevice8 **device)
468 {
469 struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface);
470
471 TRACE("iface %p, device %p.\n", iface, device);
472
473 *device = texture->parent_device;
474 IDirect3DDevice8_AddRef(*device);
475
476 TRACE("Returning device %p.\n", *device);
477
478 return D3D_OK;
479 }
480
481 static HRESULT WINAPI d3d8_texture_cube_SetPrivateData(IDirect3DCubeTexture8 *iface,
482 REFGUID guid, const void *data, DWORD data_size, DWORD flags)
483 {
484 struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface);
485 TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
486 iface, debugstr_guid(guid), data, data_size, flags);
487
488 return d3d8_resource_set_private_data(&texture->resource, guid, data, data_size, flags);
489 }
490
491 static HRESULT WINAPI d3d8_texture_cube_GetPrivateData(IDirect3DCubeTexture8 *iface,
492 REFGUID guid, void *data, DWORD *data_size)
493 {
494 struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface);
495 TRACE("iface %p, guid %s, data %p, data_size %p.\n",
496 iface, debugstr_guid(guid), data, data_size);
497
498 return d3d8_resource_get_private_data(&texture->resource, guid, data, data_size);
499 }
500
501 static HRESULT WINAPI d3d8_texture_cube_FreePrivateData(IDirect3DCubeTexture8 *iface, REFGUID guid)
502 {
503 struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface);
504 TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
505
506 return d3d8_resource_free_private_data(&texture->resource, guid);
507 }
508
509 static DWORD WINAPI d3d8_texture_cube_SetPriority(IDirect3DCubeTexture8 *iface, DWORD priority)
510 {
511 struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface);
512 struct wined3d_resource *resource;
513 DWORD ret;
514
515 TRACE("iface %p, priority %u.\n", iface, priority);
516
517 wined3d_mutex_lock();
518 resource = wined3d_texture_get_resource(texture->wined3d_texture);
519 ret = wined3d_resource_set_priority(resource, priority);
520 wined3d_mutex_unlock();
521
522 return ret;
523 }
524
525 static DWORD WINAPI d3d8_texture_cube_GetPriority(IDirect3DCubeTexture8 *iface)
526 {
527 struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface);
528 const struct wined3d_resource *resource;
529 DWORD ret;
530
531 TRACE("iface %p.\n", iface);
532
533 wined3d_mutex_lock();
534 resource = wined3d_texture_get_resource(texture->wined3d_texture);
535 ret = wined3d_resource_get_priority(resource);
536 wined3d_mutex_unlock();
537
538 return ret;
539 }
540
541 static void WINAPI d3d8_texture_cube_PreLoad(IDirect3DCubeTexture8 *iface)
542 {
543 struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface);
544
545 TRACE("iface %p.\n", iface);
546
547 wined3d_mutex_lock();
548 wined3d_texture_preload(texture->wined3d_texture);
549 wined3d_mutex_unlock();
550 }
551
552 static D3DRESOURCETYPE WINAPI d3d8_texture_cube_GetType(IDirect3DCubeTexture8 *iface)
553 {
554 TRACE("iface %p.\n", iface);
555
556 return D3DRTYPE_CUBETEXTURE;
557 }
558
559 static DWORD WINAPI d3d8_texture_cube_SetLOD(IDirect3DCubeTexture8 *iface, DWORD lod)
560 {
561 struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface);
562 DWORD ret;
563
564 TRACE("iface %p, lod %u.\n", iface, lod);
565
566 wined3d_mutex_lock();
567 ret = wined3d_texture_set_lod(texture->wined3d_texture, lod);
568 wined3d_mutex_unlock();
569
570 return ret;
571 }
572
573 static DWORD WINAPI d3d8_texture_cube_GetLOD(IDirect3DCubeTexture8 *iface)
574 {
575 struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface);
576 DWORD ret;
577
578 TRACE("iface %p.\n", iface);
579
580 wined3d_mutex_lock();
581 ret = wined3d_texture_get_lod(texture->wined3d_texture);
582 wined3d_mutex_unlock();
583
584 return ret;
585 }
586
587 static DWORD WINAPI d3d8_texture_cube_GetLevelCount(IDirect3DCubeTexture8 *iface)
588 {
589 struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface);
590 DWORD ret;
591
592 TRACE("iface %p.\n", iface);
593
594 wined3d_mutex_lock();
595 ret = wined3d_texture_get_level_count(texture->wined3d_texture);
596 wined3d_mutex_unlock();
597
598 return ret;
599 }
600
601 static HRESULT WINAPI d3d8_texture_cube_GetLevelDesc(IDirect3DCubeTexture8 *iface, UINT level, D3DSURFACE_DESC *desc)
602 {
603 struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface);
604 struct wined3d_resource *sub_resource;
605 HRESULT hr = D3D_OK;
606
607 TRACE("iface %p, level %u, desc %p.\n", iface, level, desc);
608
609 wined3d_mutex_lock();
610 if (level >= wined3d_texture_get_level_count(texture->wined3d_texture))
611 {
612 wined3d_mutex_unlock();
613 return D3DERR_INVALIDCALL;
614 }
615
616 if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
617 hr = D3DERR_INVALIDCALL;
618 else
619 {
620 struct wined3d_resource_desc wined3d_desc;
621
622 wined3d_resource_get_desc(sub_resource, &wined3d_desc);
623 desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
624 desc->Type = wined3d_desc.resource_type;
625 desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK;
626 desc->Pool = wined3d_desc.pool;
627 desc->Size = wined3d_desc.size;
628 desc->MultiSampleType = wined3d_desc.multisample_type;
629 desc->Width = wined3d_desc.width;
630 desc->Height = wined3d_desc.height;
631 }
632 wined3d_mutex_unlock();
633
634 return hr;
635 }
636
637 static HRESULT WINAPI d3d8_texture_cube_GetCubeMapSurface(IDirect3DCubeTexture8 *iface,
638 D3DCUBEMAP_FACES face, UINT level, IDirect3DSurface8 **surface)
639 {
640 struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface);
641 struct wined3d_resource *sub_resource;
642 struct d3d8_surface *surface_impl;
643 UINT sub_resource_idx;
644 DWORD level_count;
645
646 TRACE("iface %p, face %#x, level %u, surface %p.\n", iface, face, level, surface);
647
648 wined3d_mutex_lock();
649 level_count = wined3d_texture_get_level_count(texture->wined3d_texture);
650 if (level >= level_count)
651 {
652 wined3d_mutex_unlock();
653 return D3DERR_INVALIDCALL;
654 }
655
656 sub_resource_idx = level_count * face + level;
657 if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, sub_resource_idx)))
658 {
659 wined3d_mutex_unlock();
660 return D3DERR_INVALIDCALL;
661 }
662
663 surface_impl = wined3d_resource_get_parent(sub_resource);
664 *surface = &surface_impl->IDirect3DSurface8_iface;
665 IDirect3DSurface8_AddRef(*surface);
666 wined3d_mutex_unlock();
667
668 return D3D_OK;
669 }
670
671 static HRESULT WINAPI d3d8_texture_cube_LockRect(IDirect3DCubeTexture8 *iface,
672 D3DCUBEMAP_FACES face, UINT level, D3DLOCKED_RECT *locked_rect, const RECT *rect,
673 DWORD flags)
674 {
675 struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface);
676 struct wined3d_resource *sub_resource;
677 struct d3d8_surface *surface_impl;
678 UINT sub_resource_idx;
679 HRESULT hr;
680
681 TRACE("iface %p, face %#x, level %u, locked_rect %p, rect %p, flags %#x.\n",
682 iface, face, level, locked_rect, rect, flags);
683
684 wined3d_mutex_lock();
685 sub_resource_idx = wined3d_texture_get_level_count(texture->wined3d_texture) * face + level;
686 if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, sub_resource_idx)))
687 hr = D3DERR_INVALIDCALL;
688 else
689 {
690 surface_impl = wined3d_resource_get_parent(sub_resource);
691 hr = IDirect3DSurface8_LockRect(&surface_impl->IDirect3DSurface8_iface, locked_rect, rect, flags);
692 }
693 wined3d_mutex_unlock();
694
695 return hr;
696 }
697
698 static HRESULT WINAPI d3d8_texture_cube_UnlockRect(IDirect3DCubeTexture8 *iface,
699 D3DCUBEMAP_FACES face, UINT level)
700 {
701 struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface);
702 struct wined3d_resource *sub_resource;
703 struct d3d8_surface *surface_impl;
704 UINT sub_resource_idx;
705 HRESULT hr;
706
707 TRACE("iface %p, face %#x, level %u.\n", iface, face, level);
708
709 wined3d_mutex_lock();
710 sub_resource_idx = wined3d_texture_get_level_count(texture->wined3d_texture) * face + level;
711 if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, sub_resource_idx)))
712 hr = D3DERR_INVALIDCALL;
713 else
714 {
715 surface_impl = wined3d_resource_get_parent(sub_resource);
716 hr = IDirect3DSurface8_UnlockRect(&surface_impl->IDirect3DSurface8_iface);
717 }
718 wined3d_mutex_unlock();
719
720 return hr;
721 }
722
723 static HRESULT WINAPI d3d8_texture_cube_AddDirtyRect(IDirect3DCubeTexture8 *iface,
724 D3DCUBEMAP_FACES face, const RECT *dirty_rect)
725 {
726 struct d3d8_texture *texture = impl_from_IDirect3DCubeTexture8(iface);
727 HRESULT hr;
728
729 TRACE("iface %p, face %#x, dirty_rect %s.\n",
730 iface, face, wine_dbgstr_rect(dirty_rect));
731
732 wined3d_mutex_lock();
733 if (!dirty_rect)
734 hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, face, NULL);
735 else
736 {
737 struct wined3d_box dirty_region;
738
739 dirty_region.left = dirty_rect->left;
740 dirty_region.top = dirty_rect->top;
741 dirty_region.right = dirty_rect->right;
742 dirty_region.bottom = dirty_rect->bottom;
743 dirty_region.front = 0;
744 dirty_region.back = 1;
745 hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, face, &dirty_region);
746 }
747 wined3d_mutex_unlock();
748
749 return hr;
750 }
751
752 static const IDirect3DCubeTexture8Vtbl Direct3DCubeTexture8_Vtbl =
753 {
754 /* IUnknown */
755 d3d8_texture_cube_QueryInterface,
756 d3d8_texture_cube_AddRef,
757 d3d8_texture_cube_Release,
758 /* IDirect3DResource8 */
759 d3d8_texture_cube_GetDevice,
760 d3d8_texture_cube_SetPrivateData,
761 d3d8_texture_cube_GetPrivateData,
762 d3d8_texture_cube_FreePrivateData,
763 d3d8_texture_cube_SetPriority,
764 d3d8_texture_cube_GetPriority,
765 d3d8_texture_cube_PreLoad,
766 d3d8_texture_cube_GetType,
767 /* IDirect3DBaseTexture8 */
768 d3d8_texture_cube_SetLOD,
769 d3d8_texture_cube_GetLOD,
770 d3d8_texture_cube_GetLevelCount,
771 /* IDirect3DCubeTexture8 */
772 d3d8_texture_cube_GetLevelDesc,
773 d3d8_texture_cube_GetCubeMapSurface,
774 d3d8_texture_cube_LockRect,
775 d3d8_texture_cube_UnlockRect,
776 d3d8_texture_cube_AddDirtyRect,
777 };
778
779 static HRESULT WINAPI d3d8_texture_3d_QueryInterface(IDirect3DVolumeTexture8 *iface, REFIID riid, void **out)
780 {
781 TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
782
783 if (IsEqualGUID(riid, &IID_IDirect3DVolumeTexture8)
784 || IsEqualGUID(riid, &IID_IDirect3DBaseTexture8)
785 || IsEqualGUID(riid, &IID_IDirect3DResource8)
786 || IsEqualGUID(riid, &IID_IUnknown))
787 {
788 IDirect3DVolumeTexture8_AddRef(iface);
789 *out = iface;
790 return S_OK;
791 }
792
793 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
794
795 *out = NULL;
796 return E_NOINTERFACE;
797 }
798
799 static ULONG WINAPI d3d8_texture_3d_AddRef(IDirect3DVolumeTexture8 *iface)
800 {
801 struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface);
802 ULONG ref = InterlockedIncrement(&texture->resource.refcount);
803
804 TRACE("%p increasing refcount to %u.\n", iface, ref);
805
806 if (ref == 1)
807 {
808 IDirect3DDevice8_AddRef(texture->parent_device);
809 wined3d_mutex_lock();
810 wined3d_texture_incref(texture->wined3d_texture);
811 wined3d_mutex_unlock();
812 }
813
814 return ref;
815 }
816
817 static ULONG WINAPI d3d8_texture_3d_Release(IDirect3DVolumeTexture8 *iface)
818 {
819 struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface);
820 ULONG ref = InterlockedDecrement(&texture->resource.refcount);
821
822 TRACE("%p decreasing refcount to %u.\n", iface, ref);
823
824 if (!ref)
825 {
826 IDirect3DDevice8 *parent_device = texture->parent_device;
827
828 wined3d_mutex_lock();
829 wined3d_texture_decref(texture->wined3d_texture);
830 wined3d_mutex_unlock();
831
832 /* Release the device last, as it may cause the device to be destroyed. */
833 IDirect3DDevice8_Release(parent_device);
834 }
835 return ref;
836 }
837
838 static HRESULT WINAPI d3d8_texture_3d_GetDevice(IDirect3DVolumeTexture8 *iface, IDirect3DDevice8 **device)
839 {
840 struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface);
841
842 TRACE("iface %p, device %p.\n", iface, device);
843
844 *device = texture->parent_device;
845 IDirect3DDevice8_AddRef(*device);
846
847 TRACE("Returning device %p.\n", *device);
848
849 return D3D_OK;
850 }
851
852 static HRESULT WINAPI d3d8_texture_3d_SetPrivateData(IDirect3DVolumeTexture8 *iface,
853 REFGUID guid, const void *data, DWORD data_size, DWORD flags)
854 {
855 struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface);
856 TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
857 iface, debugstr_guid(guid), data, data_size, flags);
858
859 return d3d8_resource_set_private_data(&texture->resource, guid, data, data_size, flags);
860 }
861
862 static HRESULT WINAPI d3d8_texture_3d_GetPrivateData(IDirect3DVolumeTexture8 *iface,
863 REFGUID guid, void *data, DWORD *data_size)
864 {
865 struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface);
866 TRACE("iface %p, guid %s, data %p, data_size %p.\n",
867 iface, debugstr_guid(guid), data, data_size);
868
869 return d3d8_resource_get_private_data(&texture->resource, guid, data, data_size);
870 }
871
872 static HRESULT WINAPI d3d8_texture_3d_FreePrivateData(IDirect3DVolumeTexture8 *iface, REFGUID guid)
873 {
874 struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface);
875 TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
876
877 return d3d8_resource_free_private_data(&texture->resource, guid);
878 }
879
880 static DWORD WINAPI d3d8_texture_3d_SetPriority(IDirect3DVolumeTexture8 *iface, DWORD priority)
881 {
882 struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface);
883 struct wined3d_resource *resource;
884 DWORD ret;
885
886 TRACE("iface %p, priority %u.\n", iface, priority);
887
888 wined3d_mutex_lock();
889 resource = wined3d_texture_get_resource(texture->wined3d_texture);
890 ret = wined3d_resource_set_priority(resource, priority);
891 wined3d_mutex_unlock();
892
893 return ret;
894 }
895
896 static DWORD WINAPI d3d8_texture_3d_GetPriority(IDirect3DVolumeTexture8 *iface)
897 {
898 struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface);
899 const struct wined3d_resource *resource;
900 DWORD ret;
901
902 TRACE("iface %p.\n", iface);
903
904 wined3d_mutex_lock();
905 resource = wined3d_texture_get_resource(texture->wined3d_texture);
906 ret = wined3d_resource_get_priority(resource);
907 wined3d_mutex_unlock();
908
909 return ret;
910 }
911
912 static void WINAPI d3d8_texture_3d_PreLoad(IDirect3DVolumeTexture8 *iface)
913 {
914 struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface);
915
916 TRACE("iface %p.\n", iface);
917
918 wined3d_mutex_lock();
919 wined3d_texture_preload(texture->wined3d_texture);
920 wined3d_mutex_unlock();
921 }
922
923 static D3DRESOURCETYPE WINAPI d3d8_texture_3d_GetType(IDirect3DVolumeTexture8 *iface)
924 {
925 TRACE("iface %p.\n", iface);
926
927 return D3DRTYPE_VOLUMETEXTURE;
928 }
929
930 static DWORD WINAPI d3d8_texture_3d_SetLOD(IDirect3DVolumeTexture8 *iface, DWORD lod)
931 {
932 struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface);
933 DWORD ret;
934
935 TRACE("iface %p, lod %u.\n", iface, lod);
936
937 wined3d_mutex_lock();
938 ret = wined3d_texture_set_lod(texture->wined3d_texture, lod);
939 wined3d_mutex_unlock();
940
941 return ret;
942 }
943
944 static DWORD WINAPI d3d8_texture_3d_GetLOD(IDirect3DVolumeTexture8 *iface)
945 {
946 struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface);
947 DWORD ret;
948
949 TRACE("iface %p.\n", iface);
950
951 wined3d_mutex_lock();
952 ret = wined3d_texture_get_lod(texture->wined3d_texture);
953 wined3d_mutex_unlock();
954
955 return ret;
956 }
957
958 static DWORD WINAPI d3d8_texture_3d_GetLevelCount(IDirect3DVolumeTexture8 *iface)
959 {
960 struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface);
961 DWORD ret;
962
963 TRACE("iface %p.\n", iface);
964
965 wined3d_mutex_lock();
966 ret = wined3d_texture_get_level_count(texture->wined3d_texture);
967 wined3d_mutex_unlock();
968
969 return ret;
970 }
971
972 static HRESULT WINAPI d3d8_texture_3d_GetLevelDesc(IDirect3DVolumeTexture8 *iface, UINT level, D3DVOLUME_DESC *desc)
973 {
974 struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface);
975 struct wined3d_resource *sub_resource;
976 HRESULT hr = D3D_OK;
977
978 TRACE("iface %p, level %u, desc %p.\n", iface, level, desc);
979
980 wined3d_mutex_lock();
981 if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
982 hr = D3DERR_INVALIDCALL;
983 else
984 {
985 struct wined3d_resource_desc wined3d_desc;
986
987 wined3d_resource_get_desc(sub_resource, &wined3d_desc);
988 desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
989 desc->Type = wined3d_desc.resource_type;
990 desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK;
991 desc->Pool = wined3d_desc.pool;
992 desc->Size = wined3d_desc.size;
993 desc->Width = wined3d_desc.width;
994 desc->Height = wined3d_desc.height;
995 desc->Depth = wined3d_desc.depth;
996 }
997 wined3d_mutex_unlock();
998
999 return hr;
1000 }
1001
1002 static HRESULT WINAPI d3d8_texture_3d_GetVolumeLevel(IDirect3DVolumeTexture8 *iface,
1003 UINT level, IDirect3DVolume8 **volume)
1004 {
1005 struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface);
1006 struct wined3d_resource *sub_resource;
1007 struct d3d8_volume *volume_impl;
1008
1009 TRACE("iface %p, level %u, volume %p.\n", iface, level, volume);
1010
1011 wined3d_mutex_lock();
1012 if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
1013 {
1014 wined3d_mutex_unlock();
1015 return D3DERR_INVALIDCALL;
1016 }
1017
1018 volume_impl = wined3d_resource_get_parent(sub_resource);
1019 *volume = &volume_impl->IDirect3DVolume8_iface;
1020 IDirect3DVolume8_AddRef(*volume);
1021 wined3d_mutex_unlock();
1022
1023 return D3D_OK;
1024 }
1025
1026 static HRESULT WINAPI d3d8_texture_3d_LockBox(IDirect3DVolumeTexture8 *iface,
1027 UINT level, D3DLOCKED_BOX *locked_box, const D3DBOX *box, DWORD flags)
1028 {
1029 struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface);
1030 struct wined3d_resource *sub_resource;
1031 struct d3d8_volume *volume_impl;
1032 HRESULT hr;
1033
1034 TRACE("iface %p, level %u, locked_box %p, box %p, flags %#x.\n",
1035 iface, level, locked_box, box, flags);
1036
1037 wined3d_mutex_lock();
1038 if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
1039 hr = D3DERR_INVALIDCALL;
1040 else
1041 {
1042 volume_impl = wined3d_resource_get_parent(sub_resource);
1043 hr = IDirect3DVolume8_LockBox(&volume_impl->IDirect3DVolume8_iface, locked_box, box, flags);
1044 }
1045 wined3d_mutex_unlock();
1046
1047 return hr;
1048 }
1049
1050 static HRESULT WINAPI d3d8_texture_3d_UnlockBox(IDirect3DVolumeTexture8 *iface, UINT level)
1051 {
1052 struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface);
1053 struct wined3d_resource *sub_resource;
1054 struct d3d8_volume *volume_impl;
1055 HRESULT hr;
1056
1057 TRACE("iface %p, level %u.\n", iface, level);
1058
1059 wined3d_mutex_lock();
1060 if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level)))
1061 hr = D3DERR_INVALIDCALL;
1062 else
1063 {
1064 volume_impl = wined3d_resource_get_parent(sub_resource);
1065 hr = IDirect3DVolume8_UnlockBox(&volume_impl->IDirect3DVolume8_iface);
1066 }
1067 wined3d_mutex_unlock();
1068
1069 return hr;
1070 }
1071
1072 static HRESULT WINAPI d3d8_texture_3d_AddDirtyBox(IDirect3DVolumeTexture8 *iface, const D3DBOX *dirty_box)
1073 {
1074 struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface);
1075 HRESULT hr;
1076
1077 TRACE("iface %p, dirty_box %p.\n", iface, dirty_box);
1078
1079 wined3d_mutex_lock();
1080 hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, 0, (const struct wined3d_box *)dirty_box);
1081 wined3d_mutex_unlock();
1082
1083 return hr;
1084 }
1085
1086 static const IDirect3DVolumeTexture8Vtbl Direct3DVolumeTexture8_Vtbl =
1087 {
1088 /* IUnknown */
1089 d3d8_texture_3d_QueryInterface,
1090 d3d8_texture_3d_AddRef,
1091 d3d8_texture_3d_Release,
1092 /* IDirect3DResource8 */
1093 d3d8_texture_3d_GetDevice,
1094 d3d8_texture_3d_SetPrivateData,
1095 d3d8_texture_3d_GetPrivateData,
1096 d3d8_texture_3d_FreePrivateData,
1097 d3d8_texture_3d_SetPriority,
1098 d3d8_texture_3d_GetPriority,
1099 d3d8_texture_3d_PreLoad,
1100 d3d8_texture_3d_GetType,
1101 /* IDirect3DBaseTexture8 */
1102 d3d8_texture_3d_SetLOD,
1103 d3d8_texture_3d_GetLOD,
1104 d3d8_texture_3d_GetLevelCount,
1105 /* IDirect3DVolumeTexture8 */
1106 d3d8_texture_3d_GetLevelDesc,
1107 d3d8_texture_3d_GetVolumeLevel,
1108 d3d8_texture_3d_LockBox,
1109 d3d8_texture_3d_UnlockBox,
1110 d3d8_texture_3d_AddDirtyBox
1111 };
1112
1113 struct d3d8_texture *unsafe_impl_from_IDirect3DBaseTexture8(IDirect3DBaseTexture8 *iface)
1114 {
1115 if (!iface)
1116 return NULL;
1117
1118 /* SetTexture() in particular doesn't do a lot of validation on the pointer
1119 * that gets passed in, and passing an invalid pointer works as long as the
1120 * application doesn't try to actually render anything with it, so we print
1121 * a WARN and return NULL instead of having the usual assert() here.
1122 * One application affected by this is Fishdom 2. */
1123 if (iface->lpVtbl != (const IDirect3DBaseTexture8Vtbl *)&Direct3DTexture8_Vtbl
1124 && iface->lpVtbl != (const IDirect3DBaseTexture8Vtbl *)&Direct3DCubeTexture8_Vtbl
1125 && iface->lpVtbl != (const IDirect3DBaseTexture8Vtbl *)&Direct3DVolumeTexture8_Vtbl)
1126 {
1127 WARN("%p is not a valid IDirect3DBaseTexture8 interface.\n", iface);
1128 return NULL;
1129 }
1130
1131 return CONTAINING_RECORD(iface, struct d3d8_texture, IDirect3DBaseTexture8_iface);
1132 }
1133
1134 static void STDMETHODCALLTYPE d3d8_texture_wined3d_object_destroyed(void *parent)
1135 {
1136 struct d3d8_texture *texture = parent;
1137 d3d8_resource_cleanup(&texture->resource);
1138 HeapFree(GetProcessHeap(), 0, texture);
1139 }
1140
1141 static const struct wined3d_parent_ops d3d8_texture_wined3d_parent_ops =
1142 {
1143 d3d8_texture_wined3d_object_destroyed,
1144 };
1145
1146 HRESULT texture_init(struct d3d8_texture *texture, struct d3d8_device *device,
1147 UINT width, UINT height, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool)
1148 {
1149 struct wined3d_resource_desc desc;
1150 DWORD surface_flags = 0;
1151 HRESULT hr;
1152
1153 texture->IDirect3DBaseTexture8_iface.lpVtbl = (const IDirect3DBaseTexture8Vtbl *)&Direct3DTexture8_Vtbl;
1154 d3d8_resource_init(&texture->resource);
1155 list_init(&texture->rtv_list);
1156
1157 desc.resource_type = WINED3D_RTYPE_TEXTURE;
1158 desc.format = wined3dformat_from_d3dformat(format);
1159 desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
1160 desc.multisample_quality = 0;
1161 desc.usage = usage & WINED3DUSAGE_MASK;
1162 desc.usage |= WINED3DUSAGE_TEXTURE;
1163 desc.pool = pool;
1164 desc.width = width;
1165 desc.height = height;
1166 desc.depth = 1;
1167 desc.size = 0;
1168
1169 if (pool != D3DPOOL_DEFAULT || (usage & D3DUSAGE_DYNAMIC))
1170 surface_flags |= WINED3D_SURFACE_MAPPABLE;
1171
1172 wined3d_mutex_lock();
1173 hr = wined3d_texture_create(device->wined3d_device, &desc, levels, surface_flags,
1174 texture, &d3d8_texture_wined3d_parent_ops, &texture->wined3d_texture);
1175 wined3d_mutex_unlock();
1176 if (FAILED(hr))
1177 {
1178 WARN("Failed to create wined3d texture, hr %#x.\n", hr);
1179 return hr;
1180 }
1181
1182 texture->parent_device = &device->IDirect3DDevice8_iface;
1183 IDirect3DDevice8_AddRef(texture->parent_device);
1184
1185 return D3D_OK;
1186 }
1187
1188 HRESULT cubetexture_init(struct d3d8_texture *texture, struct d3d8_device *device,
1189 UINT edge_length, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool)
1190 {
1191 struct wined3d_resource_desc desc;
1192 DWORD surface_flags = 0;
1193 HRESULT hr;
1194
1195 texture->IDirect3DBaseTexture8_iface.lpVtbl = (const IDirect3DBaseTexture8Vtbl *)&Direct3DCubeTexture8_Vtbl;
1196 d3d8_resource_init(&texture->resource);
1197 list_init(&texture->rtv_list);
1198
1199 desc.resource_type = WINED3D_RTYPE_CUBE_TEXTURE;
1200 desc.format = wined3dformat_from_d3dformat(format);
1201 desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
1202 desc.multisample_quality = 0;
1203 desc.usage = usage & WINED3DUSAGE_MASK;
1204 desc.usage |= WINED3DUSAGE_TEXTURE;
1205 desc.pool = pool;
1206 desc.width = edge_length;
1207 desc.height = edge_length;
1208 desc.depth = 1;
1209 desc.size = 0;
1210
1211 if (pool != D3DPOOL_DEFAULT || (usage & D3DUSAGE_DYNAMIC))
1212 surface_flags |= WINED3D_SURFACE_MAPPABLE;
1213
1214 wined3d_mutex_lock();
1215 hr = wined3d_texture_create(device->wined3d_device, &desc, levels, surface_flags,
1216 texture, &d3d8_texture_wined3d_parent_ops, &texture->wined3d_texture);
1217 wined3d_mutex_unlock();
1218 if (FAILED(hr))
1219 {
1220 WARN("Failed to create wined3d cube texture, hr %#x.\n", hr);
1221 return hr;
1222 }
1223
1224 texture->parent_device = &device->IDirect3DDevice8_iface;
1225 IDirect3DDevice8_AddRef(texture->parent_device);
1226
1227 return D3D_OK;
1228 }
1229
1230 HRESULT volumetexture_init(struct d3d8_texture *texture, struct d3d8_device *device,
1231 UINT width, UINT height, UINT depth, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool)
1232 {
1233 struct wined3d_resource_desc desc;
1234 HRESULT hr;
1235
1236 texture->IDirect3DBaseTexture8_iface.lpVtbl = (const IDirect3DBaseTexture8Vtbl *)&Direct3DVolumeTexture8_Vtbl;
1237 d3d8_resource_init(&texture->resource);
1238 list_init(&texture->rtv_list);
1239
1240 desc.resource_type = WINED3D_RTYPE_VOLUME_TEXTURE;
1241 desc.format = wined3dformat_from_d3dformat(format);
1242 desc.multisample_type = WINED3D_MULTISAMPLE_NONE;
1243 desc.multisample_quality = 0;
1244 desc.usage = usage & WINED3DUSAGE_MASK;
1245 desc.usage |= WINED3DUSAGE_TEXTURE;
1246 desc.pool = pool;
1247 desc.width = width;
1248 desc.height = height;
1249 desc.depth = depth;
1250 desc.size = 0;
1251
1252 wined3d_mutex_lock();
1253 hr = wined3d_texture_create(device->wined3d_device, &desc, levels, 0,
1254 texture, &d3d8_texture_wined3d_parent_ops, &texture->wined3d_texture);
1255 wined3d_mutex_unlock();
1256 if (FAILED(hr))
1257 {
1258 WARN("Failed to create wined3d volume texture, hr %#x.\n", hr);
1259 return hr;
1260 }
1261
1262 texture->parent_device = &device->IDirect3DDevice8_iface;
1263 IDirect3DDevice8_AddRef(texture->parent_device);
1264
1265 return D3D_OK;
1266 }