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