wined3d: Recognize Nvidia GT520 cards.
[wine] / dlls / d3d10core / state.c
1 /*
2  * Copyright 2009 Henri Verbeet for CodeWeavers
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  *
18  */
19
20 #include "config.h"
21 #include "wine/port.h"
22
23 #include "d3d10core_private.h"
24
25 WINE_DEFAULT_DEBUG_CHANNEL(d3d10core);
26
27 static inline struct d3d10_blend_state *impl_from_ID3D10BlendState(ID3D10BlendState *iface)
28 {
29     return CONTAINING_RECORD(iface, struct d3d10_blend_state, ID3D10BlendState_iface);
30 }
31
32 /* IUnknown methods */
33
34 static HRESULT STDMETHODCALLTYPE d3d10_blend_state_QueryInterface(ID3D10BlendState *iface,
35         REFIID riid, void **object)
36 {
37     TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
38
39     if (IsEqualGUID(riid, &IID_ID3D10BlendState)
40             || IsEqualGUID(riid, &IID_ID3D10DeviceChild)
41             || IsEqualGUID(riid, &IID_IUnknown))
42     {
43         IUnknown_AddRef(iface);
44         *object = iface;
45         return S_OK;
46     }
47
48     WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
49
50     *object = NULL;
51     return E_NOINTERFACE;
52 }
53
54 static ULONG STDMETHODCALLTYPE d3d10_blend_state_AddRef(ID3D10BlendState *iface)
55 {
56     struct d3d10_blend_state *This = impl_from_ID3D10BlendState(iface);
57     ULONG refcount = InterlockedIncrement(&This->refcount);
58
59     TRACE("%p increasing refcount to %u.\n", This, refcount);
60
61     return refcount;
62 }
63
64 static ULONG STDMETHODCALLTYPE d3d10_blend_state_Release(ID3D10BlendState *iface)
65 {
66     struct d3d10_blend_state *state = impl_from_ID3D10BlendState(iface);
67     ULONG refcount = InterlockedDecrement(&state->refcount);
68
69     TRACE("%p decreasing refcount to %u.\n", state, refcount);
70
71     if (!refcount)
72     {
73         wine_rb_remove(&state->device->blend_states, &state->desc);
74         HeapFree(GetProcessHeap(), 0, state);
75     }
76
77     return refcount;
78 }
79
80 /* ID3D10DeviceChild methods */
81
82 static void STDMETHODCALLTYPE d3d10_blend_state_GetDevice(ID3D10BlendState *iface, ID3D10Device **device)
83 {
84     FIXME("iface %p, device %p stub!\n", iface, device);
85 }
86
87 static HRESULT STDMETHODCALLTYPE d3d10_blend_state_GetPrivateData(ID3D10BlendState *iface,
88         REFGUID guid, UINT *data_size, void *data)
89 {
90     FIXME("iface %p, guid %s, data_size %p, data %p stub!\n",
91             iface, debugstr_guid(guid), data_size, data);
92
93     return E_NOTIMPL;
94 }
95
96 static HRESULT STDMETHODCALLTYPE d3d10_blend_state_SetPrivateData(ID3D10BlendState *iface,
97         REFGUID guid, UINT data_size, const void *data)
98 {
99     FIXME("iface %p, guid %s, data_size %u, data %p stub!\n",
100             iface, debugstr_guid(guid), data_size, data);
101
102     return E_NOTIMPL;
103 }
104
105 static HRESULT STDMETHODCALLTYPE d3d10_blend_state_SetPrivateDataInterface(ID3D10BlendState *iface,
106         REFGUID guid, const IUnknown *data)
107 {
108     FIXME("iface %p, guid %s, data %p stub!\n", iface, debugstr_guid(guid), data);
109
110     return E_NOTIMPL;
111 }
112
113 /* ID3D10BlendState methods */
114
115 static void STDMETHODCALLTYPE d3d10_blend_state_GetDesc(ID3D10BlendState *iface,
116         D3D10_BLEND_DESC *desc)
117 {
118     struct d3d10_blend_state *state = impl_from_ID3D10BlendState(iface);
119
120     TRACE("iface %p, desc %p.\n", iface, desc);
121
122     *desc = state->desc;
123 }
124
125 static const struct ID3D10BlendStateVtbl d3d10_blend_state_vtbl =
126 {
127     /* IUnknown methods */
128     d3d10_blend_state_QueryInterface,
129     d3d10_blend_state_AddRef,
130     d3d10_blend_state_Release,
131     /* ID3D10DeviceChild methods */
132     d3d10_blend_state_GetDevice,
133     d3d10_blend_state_GetPrivateData,
134     d3d10_blend_state_SetPrivateData,
135     d3d10_blend_state_SetPrivateDataInterface,
136     /* ID3D10BlendState methods */
137     d3d10_blend_state_GetDesc,
138 };
139
140 HRESULT d3d10_blend_state_init(struct d3d10_blend_state *state, struct d3d10_device *device,
141         const D3D10_BLEND_DESC *desc)
142 {
143     state->ID3D10BlendState_iface.lpVtbl = &d3d10_blend_state_vtbl;
144     state->refcount = 1;
145     state->device = device;
146     state->desc = *desc;
147
148     if (wine_rb_put(&device->blend_states, desc, &state->entry) == -1)
149     {
150         ERR("Failed to insert blend state entry.\n");
151         return E_FAIL;
152     }
153
154     return S_OK;
155 }
156
157 struct d3d10_blend_state *unsafe_impl_from_ID3D10BlendState(ID3D10BlendState *iface)
158 {
159     if (!iface)
160         return NULL;
161     assert(iface->lpVtbl == &d3d10_blend_state_vtbl);
162
163     return impl_from_ID3D10BlendState(iface);
164 }
165
166 static inline struct d3d10_depthstencil_state *impl_from_ID3D10DepthStencilState(ID3D10DepthStencilState *iface)
167 {
168     return CONTAINING_RECORD(iface, struct d3d10_depthstencil_state, ID3D10DepthStencilState_iface);
169 }
170
171 /* IUnknown methods */
172
173 static HRESULT STDMETHODCALLTYPE d3d10_depthstencil_state_QueryInterface(ID3D10DepthStencilState *iface,
174         REFIID riid, void **object)
175 {
176     TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
177
178     if (IsEqualGUID(riid, &IID_ID3D10DepthStencilState)
179             || IsEqualGUID(riid, &IID_ID3D10DeviceChild)
180             || IsEqualGUID(riid, &IID_IUnknown))
181     {
182         IUnknown_AddRef(iface);
183         *object = iface;
184         return S_OK;
185     }
186
187     WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
188
189     *object = NULL;
190     return E_NOINTERFACE;
191 }
192
193 static ULONG STDMETHODCALLTYPE d3d10_depthstencil_state_AddRef(ID3D10DepthStencilState *iface)
194 {
195     struct d3d10_depthstencil_state *This = impl_from_ID3D10DepthStencilState(iface);
196     ULONG refcount = InterlockedIncrement(&This->refcount);
197
198     TRACE("%p increasing refcount to %u.\n", This, refcount);
199
200     return refcount;
201 }
202
203 static ULONG STDMETHODCALLTYPE d3d10_depthstencil_state_Release(ID3D10DepthStencilState *iface)
204 {
205     struct d3d10_depthstencil_state *state = impl_from_ID3D10DepthStencilState(iface);
206     ULONG refcount = InterlockedDecrement(&state->refcount);
207
208     TRACE("%p decreasing refcount to %u.\n", state, refcount);
209
210     if (!refcount)
211     {
212         wine_rb_remove(&state->device->depthstencil_states, &state->desc);
213         HeapFree(GetProcessHeap(), 0, state);
214     }
215
216     return refcount;
217 }
218
219 /* ID3D10DeviceChild methods */
220
221 static void STDMETHODCALLTYPE d3d10_depthstencil_state_GetDevice(ID3D10DepthStencilState *iface, ID3D10Device **device)
222 {
223     FIXME("iface %p, device %p stub!\n", iface, device);
224 }
225
226 static HRESULT STDMETHODCALLTYPE d3d10_depthstencil_state_GetPrivateData(ID3D10DepthStencilState *iface,
227         REFGUID guid, UINT *data_size, void *data)
228 {
229     FIXME("iface %p, guid %s, data_size %p, data %p stub!\n",
230             iface, debugstr_guid(guid), data_size, data);
231
232     return E_NOTIMPL;
233 }
234
235 static HRESULT STDMETHODCALLTYPE d3d10_depthstencil_state_SetPrivateData(ID3D10DepthStencilState *iface,
236         REFGUID guid, UINT data_size, const void *data)
237 {
238     FIXME("iface %p, guid %s, data_size %u, data %p stub!\n",
239             iface, debugstr_guid(guid), data_size, data);
240
241     return E_NOTIMPL;
242 }
243
244 static HRESULT STDMETHODCALLTYPE d3d10_depthstencil_state_SetPrivateDataInterface(ID3D10DepthStencilState *iface,
245         REFGUID guid, const IUnknown *data)
246 {
247     FIXME("iface %p, guid %s, data %p stub!\n", iface, debugstr_guid(guid), data);
248
249     return E_NOTIMPL;
250 }
251
252 /* ID3D10DepthStencilState methods */
253
254 static void STDMETHODCALLTYPE d3d10_depthstencil_state_GetDesc(ID3D10DepthStencilState *iface,
255         D3D10_DEPTH_STENCIL_DESC *desc)
256 {
257     struct d3d10_depthstencil_state *state = impl_from_ID3D10DepthStencilState(iface);
258
259     TRACE("iface %p, desc %p.\n", iface, desc);
260
261     *desc = state->desc;
262 }
263
264 static const struct ID3D10DepthStencilStateVtbl d3d10_depthstencil_state_vtbl =
265 {
266     /* IUnknown methods */
267     d3d10_depthstencil_state_QueryInterface,
268     d3d10_depthstencil_state_AddRef,
269     d3d10_depthstencil_state_Release,
270     /* ID3D10DeviceChild methods */
271     d3d10_depthstencil_state_GetDevice,
272     d3d10_depthstencil_state_GetPrivateData,
273     d3d10_depthstencil_state_SetPrivateData,
274     d3d10_depthstencil_state_SetPrivateDataInterface,
275     /* ID3D10DepthStencilState methods */
276     d3d10_depthstencil_state_GetDesc,
277 };
278
279 HRESULT d3d10_depthstencil_state_init(struct d3d10_depthstencil_state *state, struct d3d10_device *device,
280         const D3D10_DEPTH_STENCIL_DESC *desc)
281 {
282     state->ID3D10DepthStencilState_iface.lpVtbl = &d3d10_depthstencil_state_vtbl;
283     state->refcount = 1;
284     state->device = device;
285     state->desc = *desc;
286
287     if (wine_rb_put(&device->depthstencil_states, desc, &state->entry) == -1)
288     {
289         ERR("Failed to insert depthstencil state entry.\n");
290         return E_FAIL;
291     }
292
293     return S_OK;
294 }
295
296 struct d3d10_depthstencil_state *unsafe_impl_from_ID3D10DepthStencilState(ID3D10DepthStencilState *iface)
297 {
298     if (!iface)
299         return NULL;
300     assert(iface->lpVtbl == &d3d10_depthstencil_state_vtbl);
301
302     return impl_from_ID3D10DepthStencilState(iface);
303 }
304
305 static inline struct d3d10_rasterizer_state *impl_from_ID3D10RasterizerState(ID3D10RasterizerState *iface)
306 {
307     return CONTAINING_RECORD(iface, struct d3d10_rasterizer_state, ID3D10RasterizerState_iface);
308 }
309
310 /* IUnknown methods */
311
312 static HRESULT STDMETHODCALLTYPE d3d10_rasterizer_state_QueryInterface(ID3D10RasterizerState *iface,
313         REFIID riid, void **object)
314 {
315     TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
316
317     if (IsEqualGUID(riid, &IID_ID3D10RasterizerState)
318             || IsEqualGUID(riid, &IID_ID3D10DeviceChild)
319             || IsEqualGUID(riid, &IID_IUnknown))
320     {
321         IUnknown_AddRef(iface);
322         *object = iface;
323         return S_OK;
324     }
325
326     WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
327
328     *object = NULL;
329     return E_NOINTERFACE;
330 }
331
332 static ULONG STDMETHODCALLTYPE d3d10_rasterizer_state_AddRef(ID3D10RasterizerState *iface)
333 {
334     struct d3d10_rasterizer_state *This = impl_from_ID3D10RasterizerState(iface);
335     ULONG refcount = InterlockedIncrement(&This->refcount);
336
337     TRACE("%p increasing refcount to %u.\n", This, refcount);
338
339     return refcount;
340 }
341
342 static ULONG STDMETHODCALLTYPE d3d10_rasterizer_state_Release(ID3D10RasterizerState *iface)
343 {
344     struct d3d10_rasterizer_state *This = impl_from_ID3D10RasterizerState(iface);
345     ULONG refcount = InterlockedDecrement(&This->refcount);
346
347     TRACE("%p decreasing refcount to %u.\n", This, refcount);
348
349     if (!refcount)
350     {
351         HeapFree(GetProcessHeap(), 0, This);
352     }
353
354     return refcount;
355 }
356
357 /* ID3D10DeviceChild methods */
358
359 static void STDMETHODCALLTYPE d3d10_rasterizer_state_GetDevice(ID3D10RasterizerState *iface, ID3D10Device **device)
360 {
361     FIXME("iface %p, device %p stub!\n", iface, device);
362 }
363
364 static HRESULT STDMETHODCALLTYPE d3d10_rasterizer_state_GetPrivateData(ID3D10RasterizerState *iface,
365         REFGUID guid, UINT *data_size, void *data)
366 {
367     FIXME("iface %p, guid %s, data_size %p, data %p stub!\n",
368             iface, debugstr_guid(guid), data_size, data);
369
370     return E_NOTIMPL;
371 }
372
373 static HRESULT STDMETHODCALLTYPE d3d10_rasterizer_state_SetPrivateData(ID3D10RasterizerState *iface,
374         REFGUID guid, UINT data_size, const void *data)
375 {
376     FIXME("iface %p, guid %s, data_size %u, data %p stub!\n",
377             iface, debugstr_guid(guid), data_size, data);
378
379     return E_NOTIMPL;
380 }
381
382 static HRESULT STDMETHODCALLTYPE d3d10_rasterizer_state_SetPrivateDataInterface(ID3D10RasterizerState *iface,
383         REFGUID guid, const IUnknown *data)
384 {
385     FIXME("iface %p, guid %s, data %p stub!\n", iface, debugstr_guid(guid), data);
386
387     return E_NOTIMPL;
388 }
389
390 /* ID3D10RasterizerState methods */
391
392 static void STDMETHODCALLTYPE d3d10_rasterizer_state_GetDesc(ID3D10RasterizerState *iface,
393         D3D10_RASTERIZER_DESC *desc)
394 {
395     FIXME("iface %p, desc %p stub!\n", iface, desc);
396 }
397
398 static const struct ID3D10RasterizerStateVtbl d3d10_rasterizer_state_vtbl =
399 {
400     /* IUnknown methods */
401     d3d10_rasterizer_state_QueryInterface,
402     d3d10_rasterizer_state_AddRef,
403     d3d10_rasterizer_state_Release,
404     /* ID3D10DeviceChild methods */
405     d3d10_rasterizer_state_GetDevice,
406     d3d10_rasterizer_state_GetPrivateData,
407     d3d10_rasterizer_state_SetPrivateData,
408     d3d10_rasterizer_state_SetPrivateDataInterface,
409     /* ID3D10RasterizerState methods */
410     d3d10_rasterizer_state_GetDesc,
411 };
412
413 HRESULT d3d10_rasterizer_state_init(struct d3d10_rasterizer_state *state)
414 {
415     state->ID3D10RasterizerState_iface.lpVtbl = &d3d10_rasterizer_state_vtbl;
416     state->refcount = 1;
417
418     return S_OK;
419 }
420
421 struct d3d10_rasterizer_state *unsafe_impl_from_ID3D10RasterizerState(ID3D10RasterizerState *iface)
422 {
423     if (!iface)
424         return NULL;
425     assert(iface->lpVtbl == &d3d10_rasterizer_state_vtbl);
426
427     return impl_from_ID3D10RasterizerState(iface);
428 }
429
430 static inline struct d3d10_sampler_state *impl_from_ID3D10SamplerState(ID3D10SamplerState *iface)
431 {
432     return CONTAINING_RECORD(iface, struct d3d10_sampler_state, ID3D10SamplerState_iface);
433 }
434
435 /* IUnknown methods */
436
437 static HRESULT STDMETHODCALLTYPE d3d10_sampler_state_QueryInterface(ID3D10SamplerState *iface,
438         REFIID riid, void **object)
439 {
440     TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
441
442     if (IsEqualGUID(riid, &IID_ID3D10SamplerState)
443             || IsEqualGUID(riid, &IID_ID3D10DeviceChild)
444             || IsEqualGUID(riid, &IID_IUnknown))
445     {
446         IUnknown_AddRef(iface);
447         *object = iface;
448         return S_OK;
449     }
450
451     WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
452
453     *object = NULL;
454     return E_NOINTERFACE;
455 }
456
457 static ULONG STDMETHODCALLTYPE d3d10_sampler_state_AddRef(ID3D10SamplerState *iface)
458 {
459     struct d3d10_sampler_state *This = impl_from_ID3D10SamplerState(iface);
460     ULONG refcount = InterlockedIncrement(&This->refcount);
461
462     TRACE("%p increasing refcount to %u.\n", This, refcount);
463
464     return refcount;
465 }
466
467 static ULONG STDMETHODCALLTYPE d3d10_sampler_state_Release(ID3D10SamplerState *iface)
468 {
469     struct d3d10_sampler_state *state = impl_from_ID3D10SamplerState(iface);
470     ULONG refcount = InterlockedDecrement(&state->refcount);
471
472     TRACE("%p decreasing refcount to %u.\n", state, refcount);
473
474     if (!refcount)
475     {
476         wined3d_sampler_decref(state->wined3d_sampler);
477         wine_rb_remove(&state->device->sampler_states, &state->desc);
478         HeapFree(GetProcessHeap(), 0, state);
479     }
480
481     return refcount;
482 }
483
484 /* ID3D10DeviceChild methods */
485
486 static void STDMETHODCALLTYPE d3d10_sampler_state_GetDevice(ID3D10SamplerState *iface, ID3D10Device **device)
487 {
488     FIXME("iface %p, device %p stub!\n", iface, device);
489 }
490
491 static HRESULT STDMETHODCALLTYPE d3d10_sampler_state_GetPrivateData(ID3D10SamplerState *iface,
492         REFGUID guid, UINT *data_size, void *data)
493 {
494     FIXME("iface %p, guid %s, data_size %p, data %p stub!\n",
495             iface, debugstr_guid(guid), data_size, data);
496
497     return E_NOTIMPL;
498 }
499
500 static HRESULT STDMETHODCALLTYPE d3d10_sampler_state_SetPrivateData(ID3D10SamplerState *iface,
501         REFGUID guid, UINT data_size, const void *data)
502 {
503     FIXME("iface %p, guid %s, data_size %u, data %p stub!\n",
504             iface, debugstr_guid(guid), data_size, data);
505
506     return E_NOTIMPL;
507 }
508
509 static HRESULT STDMETHODCALLTYPE d3d10_sampler_state_SetPrivateDataInterface(ID3D10SamplerState *iface,
510         REFGUID guid, const IUnknown *data)
511 {
512     FIXME("iface %p, guid %s, data %p stub!\n", iface, debugstr_guid(guid), data);
513
514     return E_NOTIMPL;
515 }
516
517 /* ID3D10SamplerState methods */
518
519 static void STDMETHODCALLTYPE d3d10_sampler_state_GetDesc(ID3D10SamplerState *iface,
520         D3D10_SAMPLER_DESC *desc)
521 {
522     struct d3d10_sampler_state *state = impl_from_ID3D10SamplerState(iface);
523
524     TRACE("iface %p, desc %p.\n", iface, desc);
525
526     *desc = state->desc;
527 }
528
529 static const struct ID3D10SamplerStateVtbl d3d10_sampler_state_vtbl =
530 {
531     /* IUnknown methods */
532     d3d10_sampler_state_QueryInterface,
533     d3d10_sampler_state_AddRef,
534     d3d10_sampler_state_Release,
535     /* ID3D10DeviceChild methods */
536     d3d10_sampler_state_GetDevice,
537     d3d10_sampler_state_GetPrivateData,
538     d3d10_sampler_state_SetPrivateData,
539     d3d10_sampler_state_SetPrivateDataInterface,
540     /* ID3D10SamplerState methods */
541     d3d10_sampler_state_GetDesc,
542 };
543
544 HRESULT d3d10_sampler_state_init(struct d3d10_sampler_state *state, struct d3d10_device *device,
545         const D3D10_SAMPLER_DESC *desc)
546 {
547     HRESULT hr;
548
549     state->ID3D10SamplerState_iface.lpVtbl = &d3d10_sampler_state_vtbl;
550     state->refcount = 1;
551     state->device = device;
552     state->desc = *desc;
553
554     if (FAILED(hr = wined3d_sampler_create(state, &state->wined3d_sampler)))
555     {
556         WARN("Failed to create wined3d sampler, hr %#x.\n", hr);
557         return hr;
558     }
559
560     if (wine_rb_put(&device->sampler_states, desc, &state->entry) == -1)
561     {
562         ERR("Failed to insert sampler state entry.\n");
563         wined3d_sampler_decref(state->wined3d_sampler);
564         return E_FAIL;
565     }
566
567     return S_OK;
568 }
569
570 struct d3d10_sampler_state *unsafe_impl_from_ID3D10SamplerState(ID3D10SamplerState *iface)
571 {
572     if (!iface)
573         return NULL;
574     assert(iface->lpVtbl == &d3d10_sampler_state_vtbl);
575
576     return impl_from_ID3D10SamplerState(iface);
577 }