Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenresource.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
1.7.6.1
|