diff --git a/dlls/d3d8/Makefile.in b/dlls/d3d8/Makefile.in index 4504604f3ff..7bf737e35c2 100644 --- a/dlls/d3d8/Makefile.in +++ b/dlls/d3d8/Makefile.in @@ -12,9 +12,7 @@ C_SRCS = \ swapchain.c \ texture.c \ vertexdeclaration.c \ - volume.c \ - volumetexture.c - + volume.c RC_SRCS = version.rc @MAKE_DLL_RULES@ diff --git a/dlls/d3d8/texture.c b/dlls/d3d8/texture.c index edf003db384..700ee37dc19 100644 --- a/dlls/d3d8/texture.c +++ b/dlls/d3d8/texture.c @@ -31,6 +31,11 @@ static inline struct d3d8_texture *impl_from_IDirect3DCubeTexture8(IDirect3DCube return CONTAINING_RECORD(iface, struct d3d8_texture, IDirect3DBaseTexture8_iface); } +static inline struct d3d8_texture *impl_from_IDirect3DVolumeTexture8(IDirect3DVolumeTexture8 *iface) +{ + return CONTAINING_RECORD(iface, struct d3d8_texture, IDirect3DBaseTexture8_iface); +} + static HRESULT WINAPI d3d8_texture_2d_QueryInterface(IDirect3DTexture8 *iface, REFIID riid, void **out) { TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out); @@ -778,6 +783,360 @@ static const IDirect3DCubeTexture8Vtbl Direct3DCubeTexture8_Vtbl = d3d8_texture_cube_AddDirtyRect, }; +static HRESULT WINAPI d3d8_texture_3d_QueryInterface(IDirect3DVolumeTexture8 *iface, REFIID riid, void **out) +{ + TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out); + + if (IsEqualGUID(riid, &IID_IDirect3DVolumeTexture8) + || IsEqualGUID(riid, &IID_IDirect3DBaseTexture8) + || IsEqualGUID(riid, &IID_IDirect3DResource8) + || IsEqualGUID(riid, &IID_IUnknown)) + { + IUnknown_AddRef(iface); + *out = iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); + + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI d3d8_texture_3d_AddRef(IDirect3DVolumeTexture8 *iface) +{ + struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface); + ULONG ref = InterlockedIncrement(&texture->refcount); + + TRACE("%p increasing refcount to %u.\n", iface, ref); + + if (ref == 1) + { + IDirect3DDevice8_AddRef(texture->parent_device); + wined3d_mutex_lock(); + wined3d_texture_incref(texture->wined3d_texture); + wined3d_mutex_unlock(); + } + + return ref; +} + +static ULONG WINAPI d3d8_texture_3d_Release(IDirect3DVolumeTexture8 *iface) +{ + struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface); + ULONG ref = InterlockedDecrement(&texture->refcount); + + TRACE("%p decreasing refcount to %u.\n", iface, ref); + + if (!ref) + { + IDirect3DDevice8 *parent_device = texture->parent_device; + + wined3d_mutex_lock(); + wined3d_texture_decref(texture->wined3d_texture); + wined3d_mutex_unlock(); + + /* Release the device last, as it may cause the device to be destroyed. */ + IDirect3DDevice8_Release(parent_device); + } + return ref; +} + +static HRESULT WINAPI d3d8_texture_3d_GetDevice(IDirect3DVolumeTexture8 *iface, IDirect3DDevice8 **device) +{ + struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface); + + TRACE("iface %p, device %p.\n", iface, device); + + *device = texture->parent_device; + IDirect3DDevice8_AddRef(*device); + + TRACE("Returning device %p.\n", *device); + + return D3D_OK; +} + +static HRESULT WINAPI d3d8_texture_3d_SetPrivateData(IDirect3DVolumeTexture8 *iface, + REFGUID guid, const void *data, DWORD data_size, DWORD flags) +{ + struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface); + struct wined3d_resource *resource; + HRESULT hr; + + TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n", + iface, debugstr_guid(guid), data, data_size, flags); + + wined3d_mutex_lock(); + resource = wined3d_texture_get_resource(texture->wined3d_texture); + hr = wined3d_resource_set_private_data(resource, guid, data, data_size, flags); + wined3d_mutex_unlock(); + + return hr; +} + +static HRESULT WINAPI d3d8_texture_3d_GetPrivateData(IDirect3DVolumeTexture8 *iface, + REFGUID guid, void *data, DWORD *data_size) +{ + struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface); + struct wined3d_resource *resource; + HRESULT hr; + + TRACE("iface %p, guid %s, data %p, data_size %p.\n", + iface, debugstr_guid(guid), data, data_size); + + wined3d_mutex_lock(); + resource = wined3d_texture_get_resource(texture->wined3d_texture); + hr = wined3d_resource_get_private_data(resource, guid, data, data_size); + wined3d_mutex_unlock(); + + return hr; +} + +static HRESULT WINAPI d3d8_texture_3d_FreePrivateData(IDirect3DVolumeTexture8 *iface, REFGUID guid) +{ + struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface); + struct wined3d_resource *resource; + HRESULT hr; + + TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid)); + + wined3d_mutex_lock(); + resource = wined3d_texture_get_resource(texture->wined3d_texture); + hr = wined3d_resource_free_private_data(resource, guid); + wined3d_mutex_unlock(); + + return hr; +} + +static DWORD WINAPI d3d8_texture_3d_SetPriority(IDirect3DVolumeTexture8 *iface, DWORD priority) +{ + struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface); + DWORD ret; + + TRACE("iface %p, priority %u.\n", iface, priority); + + wined3d_mutex_lock(); + ret = wined3d_texture_set_priority(texture->wined3d_texture, priority); + wined3d_mutex_unlock(); + + return ret; +} + +static DWORD WINAPI d3d8_texture_3d_GetPriority(IDirect3DVolumeTexture8 *iface) +{ + struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface); + DWORD ret; + + TRACE("iface %p.\n", iface); + + wined3d_mutex_lock(); + ret = wined3d_texture_get_priority(texture->wined3d_texture); + wined3d_mutex_unlock(); + + return ret; +} + +static void WINAPI d3d8_texture_3d_PreLoad(IDirect3DVolumeTexture8 *iface) +{ + struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface); + + TRACE("iface %p.\n", iface); + + wined3d_mutex_lock(); + wined3d_texture_preload(texture->wined3d_texture); + wined3d_mutex_unlock(); +} + +static D3DRESOURCETYPE WINAPI d3d8_texture_3d_GetType(IDirect3DVolumeTexture8 *iface) +{ + TRACE("iface %p.\n", iface); + + return D3DRTYPE_VOLUMETEXTURE; +} + +static DWORD WINAPI d3d8_texture_3d_SetLOD(IDirect3DVolumeTexture8 *iface, DWORD lod) +{ + struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface); + DWORD ret; + + TRACE("iface %p, lod %u.\n", iface, lod); + + wined3d_mutex_lock(); + ret = wined3d_texture_set_lod(texture->wined3d_texture, lod); + wined3d_mutex_unlock(); + + return ret; +} + +static DWORD WINAPI d3d8_texture_3d_GetLOD(IDirect3DVolumeTexture8 *iface) +{ + struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface); + DWORD ret; + + TRACE("iface %p.\n", iface); + + wined3d_mutex_lock(); + ret = wined3d_texture_get_lod(texture->wined3d_texture); + wined3d_mutex_unlock(); + + return ret; +} + +static DWORD WINAPI d3d8_texture_3d_GetLevelCount(IDirect3DVolumeTexture8 *iface) +{ + struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface); + DWORD ret; + + TRACE("iface %p.\n", iface); + + wined3d_mutex_lock(); + ret = wined3d_texture_get_level_count(texture->wined3d_texture); + wined3d_mutex_unlock(); + + return ret; +} + +static HRESULT WINAPI d3d8_texture_3d_GetLevelDesc(IDirect3DVolumeTexture8 *iface, UINT level, D3DVOLUME_DESC *desc) +{ + struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface); + struct wined3d_resource *sub_resource; + HRESULT hr = D3D_OK; + + TRACE("iface %p, level %u, desc %p.\n", iface, level, desc); + + wined3d_mutex_lock(); + if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level))) + hr = D3DERR_INVALIDCALL; + else + { + struct wined3d_resource_desc wined3d_desc; + + wined3d_resource_get_desc(sub_resource, &wined3d_desc); + desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format); + desc->Type = wined3d_desc.resource_type; + desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK; + desc->Pool = wined3d_desc.pool; + desc->Size = wined3d_desc.size; + desc->Width = wined3d_desc.width; + desc->Height = wined3d_desc.height; + desc->Depth = wined3d_desc.depth; + } + wined3d_mutex_unlock(); + + return hr; +} + +static HRESULT WINAPI d3d8_texture_3d_GetVolumeLevel(IDirect3DVolumeTexture8 *iface, + UINT level, IDirect3DVolume8 **volume) +{ + struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface); + struct wined3d_resource *sub_resource; + IDirect3DVolume8Impl *volume_impl; + + TRACE("iface %p, level %u, volume %p.\n", iface, level, volume); + + wined3d_mutex_lock(); + if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level))) + { + wined3d_mutex_unlock(); + return D3DERR_INVALIDCALL; + } + + volume_impl = wined3d_resource_get_parent(sub_resource); + *volume = &volume_impl->IDirect3DVolume8_iface; + IDirect3DVolume8_AddRef(*volume); + wined3d_mutex_unlock(); + + return D3D_OK; +} + +static HRESULT WINAPI d3d8_texture_3d_LockBox(IDirect3DVolumeTexture8 *iface, + UINT level, D3DLOCKED_BOX *locked_box, const D3DBOX *box, DWORD flags) +{ + struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface); + struct wined3d_resource *sub_resource; + IDirect3DVolume8Impl *volume_impl; + HRESULT hr; + + TRACE("iface %p, level %u, locked_box %p, box %p, flags %#x.\n", + iface, level, locked_box, box, flags); + + wined3d_mutex_lock(); + if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level))) + hr = D3DERR_INVALIDCALL; + else + { + volume_impl = wined3d_resource_get_parent(sub_resource); + hr = IDirect3DVolume8_LockBox(&volume_impl->IDirect3DVolume8_iface, locked_box, box, flags); + } + wined3d_mutex_unlock(); + + return hr; +} + +static HRESULT WINAPI d3d8_texture_3d_UnlockBox(IDirect3DVolumeTexture8 *iface, UINT level) +{ + struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface); + struct wined3d_resource *sub_resource; + IDirect3DVolume8Impl *volume_impl; + HRESULT hr; + + TRACE("iface %p, level %u.\n", iface, level); + + wined3d_mutex_lock(); + if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level))) + hr = D3DERR_INVALIDCALL; + else + { + volume_impl = wined3d_resource_get_parent(sub_resource); + hr = IDirect3DVolume8_UnlockBox(&volume_impl->IDirect3DVolume8_iface); + } + wined3d_mutex_unlock(); + + return hr; +} + +static HRESULT WINAPI d3d8_texture_3d_AddDirtyBox(IDirect3DVolumeTexture8 *iface, const D3DBOX *dirty_box) +{ + struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface); + HRESULT hr; + + TRACE("iface %p, dirty_box %p.\n", iface, dirty_box); + + wined3d_mutex_lock(); + hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, 0, (const struct wined3d_box *)dirty_box); + wined3d_mutex_unlock(); + + return hr; +} + +static const IDirect3DVolumeTexture8Vtbl Direct3DVolumeTexture8_Vtbl = +{ + /* IUnknown */ + d3d8_texture_3d_QueryInterface, + d3d8_texture_3d_AddRef, + d3d8_texture_3d_Release, + /* IDirect3DResource8 */ + d3d8_texture_3d_GetDevice, + d3d8_texture_3d_SetPrivateData, + d3d8_texture_3d_GetPrivateData, + d3d8_texture_3d_FreePrivateData, + d3d8_texture_3d_SetPriority, + d3d8_texture_3d_GetPriority, + d3d8_texture_3d_PreLoad, + d3d8_texture_3d_GetType, + /* IDirect3DBaseTexture8 */ + d3d8_texture_3d_SetLOD, + d3d8_texture_3d_GetLOD, + d3d8_texture_3d_GetLevelCount, + /* IDirect3DVolumeTexture8 */ + d3d8_texture_3d_GetLevelDesc, + d3d8_texture_3d_GetVolumeLevel, + d3d8_texture_3d_LockBox, + d3d8_texture_3d_UnlockBox, + d3d8_texture_3d_AddDirtyBox +}; + static void STDMETHODCALLTYPE d3d8_texture_wined3d_object_destroyed(void *parent) { HeapFree(GetProcessHeap(), 0, parent); @@ -837,3 +1196,28 @@ HRESULT cubetexture_init(struct d3d8_texture *texture, IDirect3DDevice8Impl *dev return D3D_OK; } + +HRESULT volumetexture_init(struct d3d8_texture *texture, IDirect3DDevice8Impl *device, + UINT width, UINT height, UINT depth, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool) +{ + HRESULT hr; + + texture->IDirect3DBaseTexture8_iface.lpVtbl = (const IDirect3DBaseTexture8Vtbl *)&Direct3DVolumeTexture8_Vtbl; + texture->refcount = 1; + + wined3d_mutex_lock(); + hr = wined3d_texture_create_3d(device->wined3d_device, width, height, depth, levels, + usage & WINED3DUSAGE_MASK, wined3dformat_from_d3dformat(format), pool, texture, + &d3d8_texture_wined3d_parent_ops, &texture->wined3d_texture); + wined3d_mutex_unlock(); + if (FAILED(hr)) + { + WARN("Failed to create wined3d volume texture, hr %#x.\n", hr); + return hr; + } + + texture->parent_device = &device->IDirect3DDevice8_iface; + IDirect3DDevice8_AddRef(texture->parent_device); + + return D3D_OK; +} diff --git a/dlls/d3d8/volumetexture.c b/dlls/d3d8/volumetexture.c deleted file mode 100644 index 2f5093a747c..00000000000 --- a/dlls/d3d8/volumetexture.c +++ /dev/null @@ -1,418 +0,0 @@ -/* - * IDirect3DVolumeTexture8 implementation - * - * Copyright 2005 Oliver Stieber - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "config.h" -#include "d3d8_private.h" - -WINE_DEFAULT_DEBUG_CHANNEL(d3d8); - -static inline struct d3d8_texture *impl_from_IDirect3DVolumeTexture8(IDirect3DVolumeTexture8 *iface) -{ - return CONTAINING_RECORD(iface, struct d3d8_texture, IDirect3DBaseTexture8_iface); -} - -static HRESULT WINAPI d3d8_texture_3d_QueryInterface(IDirect3DVolumeTexture8 *iface, REFIID riid, void **out) -{ - TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out); - - if (IsEqualGUID(riid, &IID_IDirect3DVolumeTexture8) - || IsEqualGUID(riid, &IID_IDirect3DBaseTexture8) - || IsEqualGUID(riid, &IID_IDirect3DResource8) - || IsEqualGUID(riid, &IID_IUnknown)) - { - IUnknown_AddRef(iface); - *out = iface; - return S_OK; - } - - WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); - - *out = NULL; - return E_NOINTERFACE; -} - -static ULONG WINAPI d3d8_texture_3d_AddRef(IDirect3DVolumeTexture8 *iface) -{ - struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface); - ULONG ref = InterlockedIncrement(&texture->refcount); - - TRACE("%p increasing refcount to %u.\n", iface, ref); - - if (ref == 1) - { - IDirect3DDevice8_AddRef(texture->parent_device); - wined3d_mutex_lock(); - wined3d_texture_incref(texture->wined3d_texture); - wined3d_mutex_unlock(); - } - - return ref; -} - -static ULONG WINAPI d3d8_texture_3d_Release(IDirect3DVolumeTexture8 *iface) -{ - struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface); - ULONG ref = InterlockedDecrement(&texture->refcount); - - TRACE("%p decreasing refcount to %u.\n", iface, ref); - - if (!ref) - { - IDirect3DDevice8 *parent_device = texture->parent_device; - - wined3d_mutex_lock(); - wined3d_texture_decref(texture->wined3d_texture); - wined3d_mutex_unlock(); - - /* Release the device last, as it may cause the device to be destroyed. */ - IDirect3DDevice8_Release(parent_device); - } - return ref; -} - -static HRESULT WINAPI d3d8_texture_3d_GetDevice(IDirect3DVolumeTexture8 *iface, IDirect3DDevice8 **device) -{ - struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface); - - TRACE("iface %p, device %p.\n", iface, device); - - *device = texture->parent_device; - IDirect3DDevice8_AddRef(*device); - - TRACE("Returning device %p.\n", *device); - - return D3D_OK; -} - -static HRESULT WINAPI d3d8_texture_3d_SetPrivateData(IDirect3DVolumeTexture8 *iface, - REFGUID guid, const void *data, DWORD data_size, DWORD flags) -{ - struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface); - struct wined3d_resource *resource; - HRESULT hr; - - TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n", - iface, debugstr_guid(guid), data, data_size, flags); - - wined3d_mutex_lock(); - resource = wined3d_texture_get_resource(texture->wined3d_texture); - hr = wined3d_resource_set_private_data(resource, guid, data, data_size, flags); - wined3d_mutex_unlock(); - - return hr; -} - -static HRESULT WINAPI d3d8_texture_3d_GetPrivateData(IDirect3DVolumeTexture8 *iface, - REFGUID guid, void *data, DWORD *data_size) -{ - struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface); - struct wined3d_resource *resource; - HRESULT hr; - - TRACE("iface %p, guid %s, data %p, data_size %p.\n", - iface, debugstr_guid(guid), data, data_size); - - wined3d_mutex_lock(); - resource = wined3d_texture_get_resource(texture->wined3d_texture); - hr = wined3d_resource_get_private_data(resource, guid, data, data_size); - wined3d_mutex_unlock(); - - return hr; -} - -static HRESULT WINAPI d3d8_texture_3d_FreePrivateData(IDirect3DVolumeTexture8 *iface, REFGUID guid) -{ - struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface); - struct wined3d_resource *resource; - HRESULT hr; - - TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid)); - - wined3d_mutex_lock(); - resource = wined3d_texture_get_resource(texture->wined3d_texture); - hr = wined3d_resource_free_private_data(resource, guid); - wined3d_mutex_unlock(); - - return hr; -} - -static DWORD WINAPI d3d8_texture_3d_SetPriority(IDirect3DVolumeTexture8 *iface, DWORD priority) -{ - struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface); - DWORD ret; - - TRACE("iface %p, priority %u.\n", iface, priority); - - wined3d_mutex_lock(); - ret = wined3d_texture_set_priority(texture->wined3d_texture, priority); - wined3d_mutex_unlock(); - - return ret; -} - -static DWORD WINAPI d3d8_texture_3d_GetPriority(IDirect3DVolumeTexture8 *iface) -{ - struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface); - DWORD ret; - - TRACE("iface %p.\n", iface); - - wined3d_mutex_lock(); - ret = wined3d_texture_get_priority(texture->wined3d_texture); - wined3d_mutex_unlock(); - - return ret; -} - -static void WINAPI d3d8_texture_3d_PreLoad(IDirect3DVolumeTexture8 *iface) -{ - struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface); - - TRACE("iface %p.\n", iface); - - wined3d_mutex_lock(); - wined3d_texture_preload(texture->wined3d_texture); - wined3d_mutex_unlock(); -} - -static D3DRESOURCETYPE WINAPI d3d8_texture_3d_GetType(IDirect3DVolumeTexture8 *iface) -{ - TRACE("iface %p.\n", iface); - - return D3DRTYPE_VOLUMETEXTURE; -} - -static DWORD WINAPI d3d8_texture_3d_SetLOD(IDirect3DVolumeTexture8 *iface, DWORD lod) -{ - struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface); - DWORD ret; - - TRACE("iface %p, lod %u.\n", iface, lod); - - wined3d_mutex_lock(); - ret = wined3d_texture_set_lod(texture->wined3d_texture, lod); - wined3d_mutex_unlock(); - - return ret; -} - -static DWORD WINAPI d3d8_texture_3d_GetLOD(IDirect3DVolumeTexture8 *iface) -{ - struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface); - DWORD ret; - - TRACE("iface %p.\n", iface); - - wined3d_mutex_lock(); - ret = wined3d_texture_get_lod(texture->wined3d_texture); - wined3d_mutex_unlock(); - - return ret; -} - -static DWORD WINAPI d3d8_texture_3d_GetLevelCount(IDirect3DVolumeTexture8 *iface) -{ - struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface); - DWORD ret; - - TRACE("iface %p.\n", iface); - - wined3d_mutex_lock(); - ret = wined3d_texture_get_level_count(texture->wined3d_texture); - wined3d_mutex_unlock(); - - return ret; -} - -static HRESULT WINAPI d3d8_texture_3d_GetLevelDesc(IDirect3DVolumeTexture8 *iface, UINT level, D3DVOLUME_DESC *desc) -{ - struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface); - struct wined3d_resource *sub_resource; - HRESULT hr = D3D_OK; - - TRACE("iface %p, level %u, desc %p.\n", iface, level, desc); - - wined3d_mutex_lock(); - if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level))) - hr = D3DERR_INVALIDCALL; - else - { - struct wined3d_resource_desc wined3d_desc; - - wined3d_resource_get_desc(sub_resource, &wined3d_desc); - desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format); - desc->Type = wined3d_desc.resource_type; - desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK; - desc->Pool = wined3d_desc.pool; - desc->Size = wined3d_desc.size; - desc->Width = wined3d_desc.width; - desc->Height = wined3d_desc.height; - desc->Depth = wined3d_desc.depth; - } - wined3d_mutex_unlock(); - - return hr; -} - -static HRESULT WINAPI d3d8_texture_3d_GetVolumeLevel(IDirect3DVolumeTexture8 *iface, - UINT level, IDirect3DVolume8 **volume) -{ - struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface); - struct wined3d_resource *sub_resource; - IDirect3DVolume8Impl *volume_impl; - - TRACE("iface %p, level %u, volume %p.\n", iface, level, volume); - - wined3d_mutex_lock(); - if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level))) - { - wined3d_mutex_unlock(); - return D3DERR_INVALIDCALL; - } - - volume_impl = wined3d_resource_get_parent(sub_resource); - *volume = &volume_impl->IDirect3DVolume8_iface; - IDirect3DVolume8_AddRef(*volume); - wined3d_mutex_unlock(); - - return D3D_OK; -} - -static HRESULT WINAPI d3d8_texture_3d_LockBox(IDirect3DVolumeTexture8 *iface, - UINT level, D3DLOCKED_BOX *locked_box, const D3DBOX *box, DWORD flags) -{ - struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface); - struct wined3d_resource *sub_resource; - IDirect3DVolume8Impl *volume_impl; - HRESULT hr; - - TRACE("iface %p, level %u, locked_box %p, box %p, flags %#x.\n", - iface, level, locked_box, box, flags); - - wined3d_mutex_lock(); - if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level))) - hr = D3DERR_INVALIDCALL; - else - { - volume_impl = wined3d_resource_get_parent(sub_resource); - hr = IDirect3DVolume8_LockBox(&volume_impl->IDirect3DVolume8_iface, locked_box, box, flags); - } - wined3d_mutex_unlock(); - - return hr; -} - -static HRESULT WINAPI d3d8_texture_3d_UnlockBox(IDirect3DVolumeTexture8 *iface, UINT level) -{ - struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface); - struct wined3d_resource *sub_resource; - IDirect3DVolume8Impl *volume_impl; - HRESULT hr; - - TRACE("iface %p, level %u.\n", iface, level); - - wined3d_mutex_lock(); - if (!(sub_resource = wined3d_texture_get_sub_resource(texture->wined3d_texture, level))) - hr = D3DERR_INVALIDCALL; - else - { - volume_impl = wined3d_resource_get_parent(sub_resource); - hr = IDirect3DVolume8_UnlockBox(&volume_impl->IDirect3DVolume8_iface); - } - wined3d_mutex_unlock(); - - return hr; -} - -static HRESULT WINAPI d3d8_texture_3d_AddDirtyBox(IDirect3DVolumeTexture8 *iface, const D3DBOX *dirty_box) -{ - struct d3d8_texture *texture = impl_from_IDirect3DVolumeTexture8(iface); - HRESULT hr; - - TRACE("iface %p, dirty_box %p.\n", iface, dirty_box); - - wined3d_mutex_lock(); - hr = wined3d_texture_add_dirty_region(texture->wined3d_texture, 0, (const struct wined3d_box *)dirty_box); - wined3d_mutex_unlock(); - - return hr; -} - -static const IDirect3DVolumeTexture8Vtbl Direct3DVolumeTexture8_Vtbl = -{ - /* IUnknown */ - d3d8_texture_3d_QueryInterface, - d3d8_texture_3d_AddRef, - d3d8_texture_3d_Release, - /* IDirect3DResource8 */ - d3d8_texture_3d_GetDevice, - d3d8_texture_3d_SetPrivateData, - d3d8_texture_3d_GetPrivateData, - d3d8_texture_3d_FreePrivateData, - d3d8_texture_3d_SetPriority, - d3d8_texture_3d_GetPriority, - d3d8_texture_3d_PreLoad, - d3d8_texture_3d_GetType, - /* IDirect3DBaseTexture8 */ - d3d8_texture_3d_SetLOD, - d3d8_texture_3d_GetLOD, - d3d8_texture_3d_GetLevelCount, - /* IDirect3DVolumeTexture8 */ - d3d8_texture_3d_GetLevelDesc, - d3d8_texture_3d_GetVolumeLevel, - d3d8_texture_3d_LockBox, - d3d8_texture_3d_UnlockBox, - d3d8_texture_3d_AddDirtyBox -}; - -static void STDMETHODCALLTYPE volumetexture_wined3d_object_destroyed(void *parent) -{ - HeapFree(GetProcessHeap(), 0, parent); -} - -static const struct wined3d_parent_ops d3d8_volumetexture_wined3d_parent_ops = -{ - volumetexture_wined3d_object_destroyed, -}; - -HRESULT volumetexture_init(struct d3d8_texture *texture, IDirect3DDevice8Impl *device, - UINT width, UINT height, UINT depth, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool) -{ - HRESULT hr; - - texture->IDirect3DBaseTexture8_iface.lpVtbl = (const IDirect3DBaseTexture8Vtbl *)&Direct3DVolumeTexture8_Vtbl; - texture->refcount = 1; - - wined3d_mutex_lock(); - hr = wined3d_texture_create_3d(device->wined3d_device, width, height, depth, levels, - usage & WINED3DUSAGE_MASK, wined3dformat_from_d3dformat(format), pool, texture, - &d3d8_volumetexture_wined3d_parent_ops, &texture->wined3d_texture); - wined3d_mutex_unlock(); - if (FAILED(hr)) - { - WARN("Failed to create wined3d volume texture, hr %#x.\n", hr); - return hr; - } - - texture->parent_device = &device->IDirect3DDevice8_iface; - IDirect3DDevice8_AddRef(texture->parent_device); - - return D3D_OK; -}