ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

resource.c
Go to the documentation of this file.
00001 /*
00002  * Copyright 2002-2004 Jason Edmeades
00003  * Copyright 2003-2004 Raphael Junqueira
00004  * Copyright 2004 Christian Costa
00005  * Copyright 2005 Oliver Stieber
00006  * Copyright 2009-2010 Henri Verbeet for CodeWeavers
00007  *
00008  * This library is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU Lesser General Public
00010  * License as published by the Free Software Foundation; either
00011  * version 2.1 of the License, or (at your option) any later version.
00012  *
00013  * This library is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016  * Lesser General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU Lesser General Public
00019  * License along with this library; if not, write to the Free Software
00020  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00021  */
00022 
00023 #include "config.h"
00024 #include "wined3d_private.h"
00025 
00026 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
00027 
00028 struct private_data
00029 {
00030     struct list entry;
00031 
00032     GUID tag;
00033     DWORD flags; /* DDSPD_* */
00034 
00035     union
00036     {
00037         void *data;
00038         IUnknown *object;
00039     } ptr;
00040 
00041     DWORD size;
00042 };
00043 
00044 static DWORD resource_access_from_pool(enum wined3d_pool pool)
00045 {
00046     switch (pool)
00047     {
00048         case WINED3D_POOL_DEFAULT:
00049             return WINED3D_RESOURCE_ACCESS_GPU;
00050 
00051         case WINED3D_POOL_MANAGED:
00052             return WINED3D_RESOURCE_ACCESS_GPU | WINED3D_RESOURCE_ACCESS_CPU;
00053 
00054         case WINED3D_POOL_SYSTEM_MEM:
00055             return WINED3D_RESOURCE_ACCESS_CPU;
00056 
00057         case WINED3D_POOL_SCRATCH:
00058             return WINED3D_RESOURCE_ACCESS_SCRATCH;
00059 
00060         default:
00061             FIXME("Unhandled pool %#x.\n", pool);
00062             return 0;
00063     }
00064 }
00065 
00066 static void resource_check_usage(DWORD usage)
00067 {
00068     static const DWORD handled = WINED3DUSAGE_RENDERTARGET
00069             | WINED3DUSAGE_DEPTHSTENCIL
00070             | WINED3DUSAGE_DYNAMIC
00071             | WINED3DUSAGE_AUTOGENMIPMAP
00072             | WINED3DUSAGE_STATICDECL
00073             | WINED3DUSAGE_OVERLAY;
00074 
00075     if (usage & ~handled)
00076         FIXME("Unhandled usage flags %#x.\n", usage & ~handled);
00077 }
00078 
00079 HRESULT resource_init(struct wined3d_resource *resource, struct wined3d_device *device,
00080         enum wined3d_resource_type type, const struct wined3d_format *format,
00081         enum wined3d_multisample_type multisample_type, UINT multisample_quality,
00082         DWORD usage, enum wined3d_pool pool, UINT width, UINT height, UINT depth, UINT size,
00083         void *parent, const struct wined3d_parent_ops *parent_ops,
00084         const struct wined3d_resource_ops *resource_ops)
00085 {
00086     resource->ref = 1;
00087     resource->device = device;
00088     resource->type = type;
00089     resource->format = format;
00090     resource->multisample_type = multisample_type;
00091     resource->multisample_quality = multisample_quality;
00092     resource->usage = usage;
00093     resource->pool = pool;
00094     resource->access_flags = resource_access_from_pool(pool);
00095     if (usage & WINED3DUSAGE_DYNAMIC)
00096         resource->access_flags |= WINED3D_RESOURCE_ACCESS_CPU;
00097     resource->width = width;
00098     resource->height = height;
00099     resource->depth = depth;
00100     resource->size = size;
00101     resource->priority = 0;
00102     resource->parent = parent;
00103     resource->parent_ops = parent_ops;
00104     resource->resource_ops = resource_ops;
00105     list_init(&resource->privateData);
00106 
00107     resource_check_usage(usage);
00108 
00109     if (size)
00110     {
00111         resource->heapMemory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size + RESOURCE_ALIGNMENT);
00112         if (!resource->heapMemory)
00113         {
00114             ERR("Out of memory!\n");
00115             return WINED3DERR_OUTOFVIDEOMEMORY;
00116         }
00117     }
00118     else
00119     {
00120         resource->heapMemory = NULL;
00121     }
00122     resource->allocatedMemory = (BYTE *)(((ULONG_PTR)resource->heapMemory
00123             + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1));
00124 
00125     /* Check that we have enough video ram left */
00126     if (pool == WINED3D_POOL_DEFAULT)
00127     {
00128         if (size > wined3d_device_get_available_texture_mem(device))
00129         {
00130             ERR("Out of adapter memory\n");
00131             HeapFree(GetProcessHeap(), 0, resource->heapMemory);
00132             return WINED3DERR_OUTOFVIDEOMEMORY;
00133         }
00134         adapter_adjust_memory(device->adapter, size);
00135     }
00136 
00137     device_resource_add(device, resource);
00138 
00139     return WINED3D_OK;
00140 }
00141 
00142 void resource_cleanup(struct wined3d_resource *resource)
00143 {
00144     struct private_data *data;
00145     struct list *e1, *e2;
00146     HRESULT hr;
00147 
00148     TRACE("Cleaning up resource %p.\n", resource);
00149 
00150     if (resource->pool == WINED3D_POOL_DEFAULT)
00151     {
00152         TRACE("Decrementing device memory pool by %u.\n", resource->size);
00153         adapter_adjust_memory(resource->device->adapter, 0 - resource->size);
00154     }
00155 
00156     LIST_FOR_EACH_SAFE(e1, e2, &resource->privateData)
00157     {
00158         data = LIST_ENTRY(e1, struct private_data, entry);
00159         hr = wined3d_resource_free_private_data(resource, &data->tag);
00160         if (FAILED(hr))
00161             ERR("Failed to free private data when destroying resource %p, hr = %#x.\n", resource, hr);
00162     }
00163 
00164     HeapFree(GetProcessHeap(), 0, resource->heapMemory);
00165     resource->allocatedMemory = 0;
00166     resource->heapMemory = 0;
00167 
00168     if (resource->device)
00169         device_resource_released(resource->device, resource);
00170 }
00171 
00172 void resource_unload(struct wined3d_resource *resource)
00173 {
00174     context_resource_unloaded(resource->device,
00175             resource, resource->type);
00176 }
00177 
00178 static struct private_data *resource_find_private_data(const struct wined3d_resource *resource, REFGUID tag)
00179 {
00180     struct private_data *data;
00181     struct list *entry;
00182 
00183     TRACE("Searching for private data %s\n", debugstr_guid(tag));
00184     LIST_FOR_EACH(entry, &resource->privateData)
00185     {
00186         data = LIST_ENTRY(entry, struct private_data, entry);
00187         if (IsEqualGUID(&data->tag, tag)) {
00188             TRACE("Found %p\n", data);
00189             return data;
00190         }
00191     }
00192     TRACE("Not found\n");
00193     return NULL;
00194 }
00195 
00196 HRESULT CDECL wined3d_resource_set_private_data(struct wined3d_resource *resource, REFGUID guid,
00197         const void *data, DWORD data_size, DWORD flags)
00198 {
00199     struct private_data *d;
00200 
00201     TRACE("resource %p, riid %s, data %p, data_size %u, flags %#x.\n",
00202             resource, debugstr_guid(guid), data, data_size, flags);
00203 
00204     wined3d_resource_free_private_data(resource, guid);
00205 
00206     d = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*d));
00207     if (!d) return E_OUTOFMEMORY;
00208 
00209     d->tag = *guid;
00210     d->flags = flags;
00211 
00212     if (flags & WINED3DSPD_IUNKNOWN)
00213     {
00214         if (data_size != sizeof(IUnknown *))
00215         {
00216             WARN("IUnknown data with size %u, returning WINED3DERR_INVALIDCALL.\n", data_size);
00217             HeapFree(GetProcessHeap(), 0, d);
00218             return WINED3DERR_INVALIDCALL;
00219         }
00220         d->ptr.object = (IUnknown *)data;
00221         d->size = sizeof(IUnknown *);
00222         IUnknown_AddRef(d->ptr.object);
00223     }
00224     else
00225     {
00226         d->ptr.data = HeapAlloc(GetProcessHeap(), 0, data_size);
00227         if (!d->ptr.data)
00228         {
00229             HeapFree(GetProcessHeap(), 0, d);
00230             return E_OUTOFMEMORY;
00231         }
00232         d->size = data_size;
00233         memcpy(d->ptr.data, data, data_size);
00234     }
00235     list_add_tail(&resource->privateData, &d->entry);
00236 
00237     return WINED3D_OK;
00238 }
00239 
00240 HRESULT CDECL wined3d_resource_get_private_data(const struct wined3d_resource *resource, REFGUID guid,
00241         void *data, DWORD *data_size)
00242 {
00243     const struct private_data *d;
00244 
00245     TRACE("resource %p, guid %s, data %p, data_size %p.\n",
00246             resource, debugstr_guid(guid), data, data_size);
00247 
00248     d = resource_find_private_data(resource, guid);
00249     if (!d) return WINED3DERR_NOTFOUND;
00250 
00251     if (*data_size < d->size)
00252     {
00253         *data_size = d->size;
00254         return WINED3DERR_MOREDATA;
00255     }
00256 
00257     if (d->flags & WINED3DSPD_IUNKNOWN)
00258     {
00259         *(IUnknown **)data = d->ptr.object;
00260         if (resource->device->wined3d->dxVersion != 7)
00261         {
00262             /* D3D8 and D3D9 addref the private data, DDraw does not. This
00263              * can't be handled in ddraw because it doesn't know if the
00264              * pointer returned is an IUnknown * or just a blob. */
00265             IUnknown_AddRef(d->ptr.object);
00266         }
00267     }
00268     else
00269     {
00270         memcpy(data, d->ptr.data, d->size);
00271     }
00272 
00273     return WINED3D_OK;
00274 }
00275 HRESULT CDECL wined3d_resource_free_private_data(struct wined3d_resource *resource, REFGUID guid)
00276 {
00277     struct private_data *data;
00278 
00279     TRACE("resource %p, guid %s.\n", resource, debugstr_guid(guid));
00280 
00281     data = resource_find_private_data(resource, guid);
00282     if (!data) return WINED3DERR_NOTFOUND;
00283 
00284     if (data->flags & WINED3DSPD_IUNKNOWN)
00285     {
00286         if (data->ptr.object)
00287             IUnknown_Release(data->ptr.object);
00288     }
00289     else
00290     {
00291         HeapFree(GetProcessHeap(), 0, data->ptr.data);
00292     }
00293     list_remove(&data->entry);
00294 
00295     HeapFree(GetProcessHeap(), 0, data);
00296 
00297     return WINED3D_OK;
00298 }
00299 
00300 DWORD resource_set_priority(struct wined3d_resource *resource, DWORD priority)
00301 {
00302     DWORD prev = resource->priority;
00303     resource->priority = priority;
00304     TRACE("resource %p, new priority %u, returning old priority %u.\n", resource, priority, prev);
00305     return prev;
00306 }
00307 
00308 DWORD resource_get_priority(const struct wined3d_resource *resource)
00309 {
00310     TRACE("resource %p, returning %u.\n", resource, resource->priority);
00311     return resource->priority;
00312 }
00313 
00314 void * CDECL wined3d_resource_get_parent(const struct wined3d_resource *resource)
00315 {
00316     return resource->parent;
00317 }
00318 
00319 void CDECL wined3d_resource_get_desc(const struct wined3d_resource *resource, struct wined3d_resource_desc *desc)
00320 {
00321     desc->resource_type = resource->type;
00322     desc->format = resource->format->id;
00323     desc->multisample_type = resource->multisample_type;
00324     desc->multisample_quality = resource->multisample_quality;
00325     desc->usage = resource->usage;
00326     desc->pool = resource->pool;
00327     desc->width = resource->width;
00328     desc->height = resource->height;
00329     desc->depth = resource->depth;
00330     desc->size = resource->size;
00331 }

Generated on Sat May 26 2012 04:20:49 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.