2 * Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * on the rights to use, copy, modify, merge, publish, distribute, sub
8 * license, and/or sell copies of the Software, and to permit persons to whom
9 * the Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21 * USE OR OTHER DEALINGS IN THE SOFTWARE. */
23 #include "resource9.h"
25 #include "nine_helpers.h"
26 #include "nine_defines.h"
28 #include "pipe/p_screen.h"
30 #include "util/u_hash_table.h"
31 #include "util/u_inlines.h"
33 #include "nine_pdata.h"
35 #define DBG_CHANNEL DBG_RESOURCE
39 NineResource9_ctor( struct NineResource9
*This
,
40 struct NineUnknownParams
*pParams
,
41 struct pipe_resource
*initResource
,
47 struct pipe_screen
*screen
;
50 DBG("This=%p pParams=%p initResource=%p Allocate=%d "
51 "Type=%d Pool=%d Usage=%d\n",
52 This
, pParams
, initResource
, (int) Allocate
,
55 hr
= NineUnknown_ctor(&This
->base
, pParams
);
59 This
->info
.screen
= screen
= This
->base
.device
->screen
;
61 pipe_resource_reference(&This
->resource
, initResource
);
64 assert(!initResource
);
65 DBG("(%p) Creating pipe_resource.\n", This
);
66 This
->resource
= screen
->resource_create(screen
, &This
->info
);
68 return D3DERR_OUTOFVIDEOMEMORY
;
76 This
->pdata
= util_hash_table_create(ht_guid_hash
, ht_guid_compare
);
84 NineResource9_dtor( struct NineResource9
*This
)
87 util_hash_table_foreach(This
->pdata
, ht_guid_delete
, NULL
);
88 util_hash_table_destroy(This
->pdata
);
91 /* NOTE: We do have to use refcounting, the driver might
92 * still hold a reference. */
93 pipe_resource_reference(&This
->resource
, NULL
);
95 NineUnknown_dtor(&This
->base
);
98 struct pipe_resource
*
99 NineResource9_GetResource( struct NineResource9
*This
)
101 return This
->resource
;
105 NineResource9_GetPool( struct NineResource9
*This
)
111 NineResource9_SetPrivateData( struct NineResource9
*This
,
118 struct pheader
*header
;
119 const void *user_data
= pData
;
121 DBG("This=%p refguid=%p pData=%p SizeOfData=%u Flags=%x\n",
122 This
, refguid
, pData
, SizeOfData
, Flags
);
124 if (Flags
& D3DSPD_IUNKNOWN
)
125 user_assert(SizeOfData
== sizeof(IUnknown
*), D3DERR_INVALIDCALL
);
127 /* data consists of a header and the actual data. avoiding 2 mallocs */
128 header
= CALLOC_VARIANT_LENGTH_STRUCT(pheader
, SizeOfData
-1);
129 if (!header
) { return E_OUTOFMEMORY
; }
130 header
->unknown
= (Flags
& D3DSPD_IUNKNOWN
) ? TRUE
: FALSE
;
132 /* if the refguid already exists, delete it */
133 NineResource9_FreePrivateData(This
, refguid
);
135 /* IUnknown special case */
136 if (header
->unknown
) {
137 /* here the pointer doesn't point to the data we want, so point at the
138 * pointer making what we eventually copy is the pointer itself */
142 header
->size
= SizeOfData
;
143 memcpy(header
->data
, user_data
, header
->size
);
145 err
= util_hash_table_set(This
->pdata
, refguid
, header
);
146 if (err
== PIPE_OK
) {
147 if (header
->unknown
) { IUnknown_AddRef(*(IUnknown
**)header
->data
); }
152 if (err
== PIPE_ERROR_OUT_OF_MEMORY
) { return E_OUTOFMEMORY
; }
154 return D3DERR_DRIVERINTERNALERROR
;
158 NineResource9_GetPrivateData( struct NineResource9
*This
,
163 struct pheader
*header
;
165 DBG("This=%p refguid=%p pData=%p pSizeOfData=%p\n",
166 This
, refguid
, pData
, pSizeOfData
);
168 user_assert(pSizeOfData
, E_POINTER
);
170 header
= util_hash_table_get(This
->pdata
, refguid
);
171 if (!header
) { return D3DERR_NOTFOUND
; }
174 *pSizeOfData
= header
->size
;
177 if (*pSizeOfData
< header
->size
) {
178 return D3DERR_MOREDATA
;
181 if (header
->unknown
) { IUnknown_AddRef(*(IUnknown
**)header
->data
); }
182 memcpy(pData
, header
->data
, header
->size
);
188 NineResource9_FreePrivateData( struct NineResource9
*This
,
191 struct pheader
*header
;
193 DBG("This=%p refguid=%p\n", This
, refguid
);
195 header
= util_hash_table_get(This
->pdata
, refguid
);
197 return D3DERR_NOTFOUND
;
199 ht_guid_delete(NULL
, header
, NULL
);
200 util_hash_table_remove(This
->pdata
, refguid
);
206 NineResource9_SetPriority( struct NineResource9
*This
,
209 DWORD prev
= This
->priority
;
211 DBG("This=%p, PriorityNew=%d\n", This
, PriorityNew
);
213 This
->priority
= PriorityNew
;
218 NineResource9_GetPriority( struct NineResource9
*This
)
220 return This
->priority
;
223 /* NOTE: Don't forget to adjust locked vtable if you change this ! */
225 NineResource9_PreLoad( struct NineResource9
*This
)
227 if (This
->pool
!= D3DPOOL_MANAGED
)
229 /* We don't treat managed vertex or index buffers different from
230 * default ones (are managed vertex buffers even allowed ?), and
231 * the PreLoad for textures is overridden by superclass.
235 D3DRESOURCETYPE WINAPI
236 NineResource9_GetType( struct NineResource9
*This
)