st/nine: Account POINTSIZE_MIN and POINTSIZE_MAX for point size
[mesa.git] / src / gallium / state_trackers / nine / resource9.c
1 /*
2 * Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
3 *
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:
10 *
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
13 * Software.
14 *
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. */
22
23 #include "resource9.h"
24 #include "device9.h"
25 #include "nine_helpers.h"
26 #include "nine_defines.h"
27
28 #include "pipe/p_screen.h"
29
30 #include "util/u_hash_table.h"
31 #include "util/u_inlines.h"
32
33 #include "nine_pdata.h"
34
35 #define DBG_CHANNEL DBG_RESOURCE
36
37
38 HRESULT
39 NineResource9_ctor( struct NineResource9 *This,
40 struct NineUnknownParams *pParams,
41 struct pipe_resource *initResource,
42 BOOL Allocate,
43 D3DRESOURCETYPE Type,
44 D3DPOOL Pool,
45 DWORD Usage)
46 {
47 struct pipe_screen *screen;
48 HRESULT hr;
49
50 DBG("This=%p pParams=%p initResource=%p Allocate=%d "
51 "Type=%d Pool=%d Usage=%d\n",
52 This, pParams, initResource, (int) Allocate,
53 Type, Pool, Usage);
54
55 hr = NineUnknown_ctor(&This->base, pParams);
56 if (FAILED(hr))
57 return hr;
58
59 This->info.screen = screen = This->base.device->screen;
60 if (initResource)
61 pipe_resource_reference(&This->resource, initResource);
62
63 if (Allocate) {
64 assert(!initResource);
65 DBG("(%p) Creating pipe_resource.\n", This);
66 This->resource = screen->resource_create(screen, &This->info);
67 if (!This->resource)
68 return D3DERR_OUTOFVIDEOMEMORY;
69 }
70
71 This->type = Type;
72 This->pool = Pool;
73 This->usage = Usage;
74 This->priority = 0;
75
76 This->pdata = util_hash_table_create(ht_guid_hash, ht_guid_compare);
77 if (!This->pdata)
78 return E_OUTOFMEMORY;
79
80 return D3D_OK;
81 }
82
83 void
84 NineResource9_dtor( struct NineResource9 *This )
85 {
86 if (This->pdata) {
87 util_hash_table_foreach(This->pdata, ht_guid_delete, NULL);
88 util_hash_table_destroy(This->pdata);
89 }
90
91 /* NOTE: We do have to use refcounting, the driver might
92 * still hold a reference. */
93 pipe_resource_reference(&This->resource, NULL);
94
95 NineUnknown_dtor(&This->base);
96 }
97
98 struct pipe_resource *
99 NineResource9_GetResource( struct NineResource9 *This )
100 {
101 return This->resource;
102 }
103
104 D3DPOOL
105 NineResource9_GetPool( struct NineResource9 *This )
106 {
107 return This->pool;
108 }
109
110 HRESULT WINAPI
111 NineResource9_SetPrivateData( struct NineResource9 *This,
112 REFGUID refguid,
113 const void *pData,
114 DWORD SizeOfData,
115 DWORD Flags )
116 {
117 enum pipe_error err;
118 struct pheader *header;
119 const void *user_data = pData;
120
121 DBG("This=%p refguid=%p pData=%p SizeOfData=%u Flags=%x\n",
122 This, refguid, pData, SizeOfData, Flags);
123
124 if (Flags & D3DSPD_IUNKNOWN)
125 user_assert(SizeOfData == sizeof(IUnknown *), D3DERR_INVALIDCALL);
126
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;
131
132 /* if the refguid already exists, delete it */
133 NineResource9_FreePrivateData(This, refguid);
134
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 */
139 user_data = &pData;
140 }
141
142 header->size = SizeOfData;
143 memcpy(header->data, user_data, header->size);
144
145 err = util_hash_table_set(This->pdata, refguid, header);
146 if (err == PIPE_OK) {
147 if (header->unknown) { IUnknown_AddRef(*(IUnknown **)header->data); }
148 return D3D_OK;
149 }
150
151 FREE(header);
152 if (err == PIPE_ERROR_OUT_OF_MEMORY) { return E_OUTOFMEMORY; }
153
154 return D3DERR_DRIVERINTERNALERROR;
155 }
156
157 HRESULT WINAPI
158 NineResource9_GetPrivateData( struct NineResource9 *This,
159 REFGUID refguid,
160 void *pData,
161 DWORD *pSizeOfData )
162 {
163 struct pheader *header;
164
165 DBG("This=%p refguid=%p pData=%p pSizeOfData=%p\n",
166 This, refguid, pData, pSizeOfData);
167
168 user_assert(pSizeOfData, E_POINTER);
169
170 header = util_hash_table_get(This->pdata, refguid);
171 if (!header) { return D3DERR_NOTFOUND; }
172
173 if (!pData) {
174 *pSizeOfData = header->size;
175 return D3D_OK;
176 }
177 if (*pSizeOfData < header->size) {
178 return D3DERR_MOREDATA;
179 }
180
181 if (header->unknown) { IUnknown_AddRef(*(IUnknown **)header->data); }
182 memcpy(pData, header->data, header->size);
183
184 return D3D_OK;
185 }
186
187 HRESULT WINAPI
188 NineResource9_FreePrivateData( struct NineResource9 *This,
189 REFGUID refguid )
190 {
191 struct pheader *header;
192
193 DBG("This=%p refguid=%p\n", This, refguid);
194
195 header = util_hash_table_get(This->pdata, refguid);
196 if (!header)
197 return D3DERR_NOTFOUND;
198
199 ht_guid_delete(NULL, header, NULL);
200 util_hash_table_remove(This->pdata, refguid);
201
202 return D3D_OK;
203 }
204
205 DWORD WINAPI
206 NineResource9_SetPriority( struct NineResource9 *This,
207 DWORD PriorityNew )
208 {
209 DWORD prev = This->priority;
210
211 DBG("This=%p, PriorityNew=%d\n", This, PriorityNew);
212
213 This->priority = PriorityNew;
214 return prev;
215 }
216
217 DWORD WINAPI
218 NineResource9_GetPriority( struct NineResource9 *This )
219 {
220 return This->priority;
221 }
222
223 /* NOTE: Don't forget to adjust locked vtable if you change this ! */
224 void WINAPI
225 NineResource9_PreLoad( struct NineResource9 *This )
226 {
227 if (This->pool != D3DPOOL_MANAGED)
228 return;
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.
232 */
233 }
234
235 D3DRESOURCETYPE WINAPI
236 NineResource9_GetType( struct NineResource9 *This )
237 {
238 return This->type;
239 }