surface.c revision 76f3927069cc452e77bf72f32d9175c0256ed3b3
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync * IDirect3DSurface8 implementation
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync * Copyright 2005 Oliver Stieber
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync * This library is free software; you can redistribute it and/or
6051541700e5859249b7cad958495579b104a934vboxsync * modify it under the terms of the GNU Lesser General Public
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync * License as published by the Free Software Foundation; either
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync * version 2.1 of the License, or (at your option) any later version.
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync * This library is distributed in the hope that it will be useful,
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync * but WITHOUT ANY WARRANTY; without even the implied warranty of
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync * Lesser General Public License for more details.
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync * You should have received a copy of the GNU Lesser General Public
b9163c0ef45a0f4a5645e874aefeae3e892f7adbvboxsync * License along with this library; if not, write to the Free Software
b9163c0ef45a0f4a5645e874aefeae3e892f7adbvboxsync * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync * a choice of LGPL license versions is made available with the language indicating
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync * that LGPLv2 or any later version may be used, or where a choice of which version
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync * of the LGPL is applied is otherwise unspecified.
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsyncstatic inline struct d3d8_surface *impl_from_IDirect3DSurface8(IDirect3DSurface8 *iface)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync return CONTAINING_RECORD(iface, struct d3d8_surface, IDirect3DSurface8_iface);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsyncstatic HRESULT WINAPI d3d8_surface_QueryInterface(IDirect3DSurface8 *iface, REFIID riid, void **out)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), out);
0bedcb6a72520b281e48445a1994af182730c31avboxsync WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsyncstatic ULONG WINAPI d3d8_surface_AddRef(IDirect3DSurface8 *iface)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync struct d3d8_surface *surface = impl_from_IDirect3DSurface8(iface);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync /* Forward refcounting */
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync TRACE("Forwarding to %p.\n", surface->forwardReference);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync /* No container, handle our own refcounting */
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync ULONG ref = InterlockedIncrement(&surface->refcount);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync TRACE("%p increasing refcount to %u.\n", iface, ref);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsyncstatic ULONG WINAPI d3d8_surface_Release(IDirect3DSurface8 *iface)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync struct d3d8_surface *surface = impl_from_IDirect3DSurface8(iface);
b9163c0ef45a0f4a5645e874aefeae3e892f7adbvboxsync /* Forward refcounting */
b9163c0ef45a0f4a5645e874aefeae3e892f7adbvboxsync TRACE("Forwarding to %p.\n", surface->forwardReference);
b9163c0ef45a0f4a5645e874aefeae3e892f7adbvboxsync return IUnknown_Release(surface->forwardReference);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync /* No container, handle our own refcounting */
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync ULONG ref = InterlockedDecrement(&surface->refcount);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync TRACE("%p decreasing refcount to %u.\n", iface, ref);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync IDirect3DDevice8 *parent_device = surface->parent_device;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync /* Implicit surfaces are destroyed with the device, not if refcount reaches 0. */
6cfc0707e3ea64a93ddf63fcc76a7d5069a34118vboxsyncstatic HRESULT WINAPI d3d8_surface_GetDevice(IDirect3DSurface8 *iface, IDirect3DDevice8 **device)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync struct d3d8_surface *surface = impl_from_IDirect3DSurface8(iface);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync hr = IUnknown_QueryInterface(surface->forwardReference, &IID_IDirect3DResource8, (void **)&resource);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync hr = IDirect3DResource8_GetDevice(resource, device);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsyncstatic HRESULT WINAPI d3d8_surface_SetPrivateData(IDirect3DSurface8 *iface, REFGUID guid,
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync struct d3d8_surface *surface = impl_from_IDirect3DSurface8(iface);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync TRACE("iface %p, guid %s, data %p, data_size %u, flags %#x.\n",
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync iface, debugstr_guid(guid), data, data_size, flags);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync resource = wined3d_surface_get_resource(surface->wined3d_surface);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync hr = wined3d_resource_set_private_data(resource, guid, data, data_size, flags);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsyncstatic HRESULT WINAPI d3d8_surface_GetPrivateData(IDirect3DSurface8 *iface, REFGUID guid,
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync struct d3d8_surface *surface = impl_from_IDirect3DSurface8(iface);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync TRACE("iface %p, guid %s, data %p, data_size %p.\n",
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync resource = wined3d_surface_get_resource(surface->wined3d_surface);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync hr = wined3d_resource_get_private_data(resource, guid, data, data_size);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsyncstatic HRESULT WINAPI d3d8_surface_FreePrivateData(IDirect3DSurface8 *iface, REFGUID guid)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync struct d3d8_surface *surface = impl_from_IDirect3DSurface8(iface);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync TRACE("iface %p, guid %s.\n", iface, debugstr_guid(guid));
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync resource = wined3d_surface_get_resource(surface->wined3d_surface);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync hr = wined3d_resource_free_private_data(resource, guid);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsyncstatic HRESULT WINAPI d3d8_surface_GetContainer(IDirect3DSurface8 *iface, REFIID riid, void **container)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync struct d3d8_surface *surface = impl_from_IDirect3DSurface8(iface);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync TRACE("iface %p, riid %s, container %p.\n", iface, debugstr_guid(riid), container);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync hr = IUnknown_QueryInterface(surface->container, riid, container);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsyncstatic HRESULT WINAPI d3d8_surface_GetDesc(IDirect3DSurface8 *iface, D3DSURFACE_DESC *desc)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync struct d3d8_surface *surface = impl_from_IDirect3DSurface8(iface);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync wined3d_resource = wined3d_surface_get_resource(surface->wined3d_surface);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync wined3d_resource_get_desc(wined3d_resource, &wined3d_desc);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync desc->Format = d3dformat_from_wined3dformat(wined3d_desc.format);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync desc->Usage = wined3d_desc.usage & WINED3DUSAGE_MASK;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync desc->MultiSampleType = wined3d_desc.multisample_type;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsyncstatic HRESULT WINAPI d3d8_surface_LockRect(IDirect3DSurface8 *iface,
6cfc0707e3ea64a93ddf63fcc76a7d5069a34118vboxsync D3DLOCKED_RECT *locked_rect, const RECT *rect, DWORD flags)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync struct d3d8_surface *surface = impl_from_IDirect3DSurface8(iface);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync TRACE("iface %p, locked_rect %p, rect %s, flags %#x.\n",
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync iface, locked_rect, wine_dbgstr_rect(rect), flags);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync WARN("Trying to lock an invalid rectangle, returning D3DERR_INVALIDCALL\n");
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync hr = wined3d_surface_map(surface->wined3d_surface, &map_desc, rect, flags);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsyncstatic HRESULT WINAPI d3d8_surface_UnlockRect(IDirect3DSurface8 *iface)
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync struct d3d8_surface *surface = impl_from_IDirect3DSurface8(iface);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync hr = wined3d_surface_unmap(surface->wined3d_surface);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync case WINEDDERR_NOTLOCKED: return D3DERR_INVALIDCALL;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync default: return hr;
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsyncstatic const IDirect3DSurface8Vtbl d3d8_surface_vtbl =
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync /* IUnknown */
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync /* IDirect3DResource8 */
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync /* IDirect3DSurface8 */
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsyncstatic void STDMETHODCALLTYPE surface_wined3d_object_destroyed(void *parent)
30f73dd60f426a41d665d9fb6284d205107095f0vboxsyncstatic const struct wined3d_parent_ops d3d8_surface_wined3d_parent_ops =
0bedcb6a72520b281e48445a1994af182730c31avboxsyncHRESULT surface_init(struct d3d8_surface *surface, struct d3d8_device *device, UINT width, UINT height,
0bedcb6a72520b281e48445a1994af182730c31avboxsync D3DFORMAT format, DWORD flags, DWORD usage, D3DPOOL pool, D3DMULTISAMPLE_TYPE multisample_type,
889febd62ca82dced9e9b9a1aa28ed96ef1a677fvboxsync surface->IDirect3DSurface8_iface.lpVtbl = &d3d8_surface_vtbl;
889febd62ca82dced9e9b9a1aa28ed96ef1a677fvboxsync /* FIXME: Check MAX bounds of MultisampleQuality. */
889febd62ca82dced9e9b9a1aa28ed96ef1a677fvboxsync FIXME("Multisample quality set to %u, substituting 0.\n", multisample_quality);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync hr = wined3d_surface_create(device->wined3d_device, width, height, wined3dformat_from_d3dformat(format),
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync usage & WINED3DUSAGE_MASK, (enum wined3d_pool)pool, multisample_type, multisample_quality,
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync flags, surface, &d3d8_surface_wined3d_parent_ops, &surface->wined3d_surface);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync WARN("Failed to create wined3d surface, hr %#x.\n", hr);
97b634ea021fd984782256de4ba4ff31cdb96c47vboxsync surface->parent_device = &device->IDirect3DDevice8_iface;