#include "util/u_hash_table.h"
#include "util/u_inlines.h"
+#include "util/u_resource.h"
#include "nine_pdata.h"
#define DBG_CHANNEL DBG_RESOURCE
-
HRESULT
NineResource9_ctor( struct NineResource9 *This,
struct NineUnknownParams *pParams,
+ struct pipe_resource *initResource,
BOOL Allocate,
D3DRESOURCETYPE Type,
- D3DPOOL Pool )
+ D3DPOOL Pool,
+ DWORD Usage)
{
struct pipe_screen *screen;
HRESULT hr;
+ DBG("This=%p pParams=%p initResource=%p Allocate=%d "
+ "Type=%d Pool=%d Usage=%d\n",
+ This, pParams, initResource, (int) Allocate,
+ Type, Pool, Usage);
+
hr = NineUnknown_ctor(&This->base, pParams);
if (FAILED(hr))
return hr;
This->info.screen = screen = This->base.device->screen;
+ if (initResource)
+ pipe_resource_reference(&This->resource, initResource);
if (Allocate) {
+ assert(!initResource);
+
+ /* On Windows it is possible allocation fails when
+ * IDirect3DDevice9::GetAvailableTextureMem() still reports
+ * enough free space.
+ *
+ * Some games allocate surfaces
+ * in a loop until they receive D3DERR_OUTOFVIDEOMEMORY to measure
+ * the available texture memory size.
+ *
+ * We are not using the drivers VRAM statistics because:
+ * * This would add overhead to each resource allocation.
+ * * Freeing memory is lazy and takes some time, but applications
+ * expects the memory counter to change immediately after allocating
+ * or freeing memory.
+ *
+ * Vertexbuffers and indexbuffers are not accounted !
+ */
+ if (This->info.target != PIPE_BUFFER) {
+ This->size = util_resource_size(&This->info);
+
+ This->base.device->available_texture_mem -= This->size;
+ if (This->base.device->available_texture_mem <=
+ This->base.device->available_texture_limit) {
+ return D3DERR_OUTOFVIDEOMEMORY;
+ }
+ }
+
DBG("(%p) Creating pipe_resource.\n", This);
This->resource = screen->resource_create(screen, &This->info);
if (!This->resource)
return D3DERR_OUTOFVIDEOMEMORY;
}
- This->data = NULL; /* FIXME remove, rather set it to null in surface9.c*/
This->type = Type;
This->pool = Pool;
+ This->usage = Usage;
This->priority = 0;
This->pdata = util_hash_table_create(ht_guid_hash, ht_guid_compare);
* still hold a reference. */
pipe_resource_reference(&This->resource, NULL);
- /* release allocated system memory for non-D3DPOOL_DEFAULT resources */
- if (This->data)
- FREE(This->data);
+ /* NOTE: size is 0, unless something has actually been allocated */
+ if (This->base.device)
+ This->base.device->available_texture_mem += This->size;
NineUnknown_dtor(&This->base);
}
enum pipe_error err;
struct pheader *header;
const void *user_data = pData;
+ char guid_str[64];
- DBG("This=%p refguid=%p pData=%p SizeOfData=%u Flags=%x\n",
- This, refguid, pData, SizeOfData, Flags);
+ DBG("This=%p GUID=%s pData=%p SizeOfData=%u Flags=%x\n",
+ This, GUID_sprintf(guid_str, refguid), pData, SizeOfData, Flags);
if (Flags & D3DSPD_IUNKNOWN)
user_assert(SizeOfData == sizeof(IUnknown *), D3DERR_INVALIDCALL);
header->size = SizeOfData;
memcpy(header->data, user_data, header->size);
+ memcpy(&header->guid, refguid, sizeof(header->guid));
- err = util_hash_table_set(This->pdata, refguid, header);
+ err = util_hash_table_set(This->pdata, &header->guid, header);
if (err == PIPE_OK) {
if (header->unknown) { IUnknown_AddRef(*(IUnknown **)header->data); }
return D3D_OK;
DWORD *pSizeOfData )
{
struct pheader *header;
+ DWORD sizeofdata;
+ char guid_str[64];
- DBG("This=%p refguid=%p pData=%p pSizeOfData=%p\n",
- This, refguid, pData, pSizeOfData);
-
- user_assert(pSizeOfData, E_POINTER);
+ DBG("This=%p GUID=%s pData=%p pSizeOfData=%p\n",
+ This, GUID_sprintf(guid_str, refguid), pData, pSizeOfData);
header = util_hash_table_get(This->pdata, refguid);
if (!header) { return D3DERR_NOTFOUND; }
+ user_assert(pSizeOfData, E_POINTER);
+ sizeofdata = *pSizeOfData;
+ *pSizeOfData = header->size;
+
if (!pData) {
- *pSizeOfData = header->size;
return D3D_OK;
}
- if (*pSizeOfData < header->size) {
+ if (sizeofdata < header->size) {
return D3DERR_MOREDATA;
}
REFGUID refguid )
{
struct pheader *header;
+ char guid_str[64];
- DBG("This=%p refguid=%p\n", This, refguid);
+ DBG("This=%p GUID=%s\n", This, GUID_sprintf(guid_str, refguid));
header = util_hash_table_get(This->pdata, refguid);
if (!header)
NineResource9_SetPriority( struct NineResource9 *This,
DWORD PriorityNew )
{
- DWORD prev = This->priority;
+ DWORD prev;
+ DBG("This=%p, PriorityNew=%d\n", This, PriorityNew);
+
+ if (This->pool != D3DPOOL_MANAGED || This->type == D3DRTYPE_SURFACE)
+ return 0;
+
+ prev = This->priority;
This->priority = PriorityNew;
return prev;
}
DWORD WINAPI
NineResource9_GetPriority( struct NineResource9 *This )
{
+ if (This->pool != D3DPOOL_MANAGED || This->type == D3DRTYPE_SURFACE)
+ return 0;
+
return This->priority;
}