atl80: Added AtlComModuleRegisterServer implementation (based on AtlModuleRegisterSer...
[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 *state = impl_from_ID3D10RasterizerState(iface);
345     ULONG refcount = InterlockedDecrement(&state->refcount);
346
347     TRACE("%p decreasing refcount to %u.\n", state, refcount);
348
349     if (!refcount)
350     {
351         wine_rb_remove(&state->device->rasterizer_states, &state->desc);
352         HeapFree(GetProcessHeap(), 0, state);
353     }
354
355     return refcount;
356 }
357
358 /* ID3D10DeviceChild methods */
359
360 static void STDMETHODCALLTYPE d3d10_rasterizer_state_GetDevice(ID3D10RasterizerState *iface, ID3D10Device **device)
361 {
362     FIXME("iface %p, device %p stub!\n", iface, device);
363 }
364
365 static HRESULT STDMETHODCALLTYPE d3d10_rasterizer_state_GetPrivateData(ID3D10RasterizerState *iface,
366         REFGUID guid, UINT *data_size, void *data)
367 {
368     FIXME("iface %p, guid %s, data_size %p, data %p stub!\n",
369             iface, debugstr_guid(guid), data_size, data);
370
371     return E_NOTIMPL;
372 }
373
374 static HRESULT STDMETHODCALLTYPE d3d10_rasterizer_state_SetPrivateData(ID3D10RasterizerState *iface,
375         REFGUID guid, UINT data_size, const void *data)
376 {
377     FIXME("iface %p, guid %s, data_size %u, data %p stub!\n",
378             iface, debugstr_guid(guid), data_size, data);
379
380     return E_NOTIMPL;
381 }
382
383 static HRESULT STDMETHODCALLTYPE d3d10_rasterizer_state_SetPrivateDataInterface(ID3D10RasterizerState *iface,
384         REFGUID guid, const IUnknown *data)
385 {
386     FIXME("iface %p, guid %s, data %p stub!\n", iface, debugstr_guid(guid), data);
387
388     return E_NOTIMPL;
389 }
390
391 /* ID3D10RasterizerState methods */
392
393 static void STDMETHODCALLTYPE d3d10_rasterizer_state_GetDesc(ID3D10RasterizerState *iface,
394         D3D10_RASTERIZER_DESC *desc)
395 {
396     struct d3d10_rasterizer_state *state = impl_from_ID3D10RasterizerState(iface);
397
398     TRACE("iface %p, desc %p.\n", iface, desc);
399
400     *desc = state->desc;
401 }
402
403 static const struct ID3D10RasterizerStateVtbl d3d10_rasterizer_state_vtbl =
404 {
405     /* IUnknown methods */
406     d3d10_rasterizer_state_QueryInterface,
407     d3d10_rasterizer_state_AddRef,
408     d3d10_rasterizer_state_Release,
409     /* ID3D10DeviceChild methods */
410     d3d10_rasterizer_state_GetDevice,
411     d3d10_rasterizer_state_GetPrivateData,
412     d3d10_rasterizer_state_SetPrivateData,
413     d3d10_rasterizer_state_SetPrivateDataInterface,
414     /* ID3D10RasterizerState methods */
415     d3d10_rasterizer_state_GetDesc,
416 };
417
418 HRESULT d3d10_rasterizer_state_init(struct d3d10_rasterizer_state *state, struct d3d10_device *device,
419         const D3D10_RASTERIZER_DESC *desc)
420 {
421     state->ID3D10RasterizerState_iface.lpVtbl = &d3d10_rasterizer_state_vtbl;
422     state->refcount = 1;
423     state->device = device;
424     state->desc = *desc;
425
426     if (wine_rb_put(&device->rasterizer_states, desc, &state->entry) == -1)
427     {
428         ERR("Failed to insert rasterizer state entry.\n");
429         return E_FAIL;
430     }
431
432     return S_OK;
433 }
434
435 struct d3d10_rasterizer_state *unsafe_impl_from_ID3D10RasterizerState(ID3D10RasterizerState *iface)
436 {
437     if (!iface)
438         return NULL;
439     assert(iface->lpVtbl == &d3d10_rasterizer_state_vtbl);
440
441     return impl_from_ID3D10RasterizerState(iface);
442 }
443
444 static inline struct d3d10_sampler_state *impl_from_ID3D10SamplerState(ID3D10SamplerState *iface)
445 {
446     return CONTAINING_RECORD(iface, struct d3d10_sampler_state, ID3D10SamplerState_iface);
447 }
448
449 /* IUnknown methods */
450
451 static HRESULT STDMETHODCALLTYPE d3d10_sampler_state_QueryInterface(ID3D10SamplerState *iface,
452         REFIID riid, void **object)
453 {
454     TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
455
456     if (IsEqualGUID(riid, &IID_ID3D10SamplerState)
457             || IsEqualGUID(riid, &IID_ID3D10DeviceChild)
458             || IsEqualGUID(riid, &IID_IUnknown))
459     {
460         IUnknown_AddRef(iface);
461         *object = iface;
462         return S_OK;
463     }
464
465     WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
466
467     *object = NULL;
468     return E_NOINTERFACE;
469 }
470
471 static ULONG STDMETHODCALLTYPE d3d10_sampler_state_AddRef(ID3D10SamplerState *iface)
472 {
473     struct d3d10_sampler_state *This = impl_from_ID3D10SamplerState(iface);
474     ULONG refcount = InterlockedIncrement(&This->refcount);
475
476     TRACE("%p increasing refcount to %u.\n", This, refcount);
477
478     return refcount;
479 }
480
481 static ULONG STDMETHODCALLTYPE d3d10_sampler_state_Release(ID3D10SamplerState *iface)
482 {
483     struct d3d10_sampler_state *state = impl_from_ID3D10SamplerState(iface);
484     ULONG refcount = InterlockedDecrement(&state->refcount);
485
486     TRACE("%p decreasing refcount to %u.\n", state, refcount);
487
488     if (!refcount)
489     {
490         wined3d_sampler_decref(state->wined3d_sampler);
491         wine_rb_remove(&state->device->sampler_states, &state->desc);
492         HeapFree(GetProcessHeap(), 0, state);
493     }
494
495     return refcount;
496 }
497
498 /* ID3D10DeviceChild methods */
499
500 static void STDMETHODCALLTYPE d3d10_sampler_state_GetDevice(ID3D10SamplerState *iface, ID3D10Device **device)
501 {
502     FIXME("iface %p, device %p stub!\n", iface, device);
503 }
504
505 static HRESULT STDMETHODCALLTYPE d3d10_sampler_state_GetPrivateData(ID3D10SamplerState *iface,
506         REFGUID guid, UINT *data_size, void *data)
507 {
508     FIXME("iface %p, guid %s, data_size %p, data %p stub!\n",
509             iface, debugstr_guid(guid), data_size, data);
510
511     return E_NOTIMPL;
512 }
513
514 static HRESULT STDMETHODCALLTYPE d3d10_sampler_state_SetPrivateData(ID3D10SamplerState *iface,
515         REFGUID guid, UINT data_size, const void *data)
516 {
517     FIXME("iface %p, guid %s, data_size %u, data %p stub!\n",
518             iface, debugstr_guid(guid), data_size, data);
519
520     return E_NOTIMPL;
521 }
522
523 static HRESULT STDMETHODCALLTYPE d3d10_sampler_state_SetPrivateDataInterface(ID3D10SamplerState *iface,
524         REFGUID guid, const IUnknown *data)
525 {
526     FIXME("iface %p, guid %s, data %p stub!\n", iface, debugstr_guid(guid), data);
527
528     return E_NOTIMPL;
529 }
530
531 /* ID3D10SamplerState methods */
532
533 static void STDMETHODCALLTYPE d3d10_sampler_state_GetDesc(ID3D10SamplerState *iface,
534         D3D10_SAMPLER_DESC *desc)
535 {
536     struct d3d10_sampler_state *state = impl_from_ID3D10SamplerState(iface);
537
538     TRACE("iface %p, desc %p.\n", iface, desc);
539
540     *desc = state->desc;
541 }
542
543 static const struct ID3D10SamplerStateVtbl d3d10_sampler_state_vtbl =
544 {
545     /* IUnknown methods */
546     d3d10_sampler_state_QueryInterface,
547     d3d10_sampler_state_AddRef,
548     d3d10_sampler_state_Release,
549     /* ID3D10DeviceChild methods */
550     d3d10_sampler_state_GetDevice,
551     d3d10_sampler_state_GetPrivateData,
552     d3d10_sampler_state_SetPrivateData,
553     d3d10_sampler_state_SetPrivateDataInterface,
554     /* ID3D10SamplerState methods */
555     d3d10_sampler_state_GetDesc,
556 };
557
558 HRESULT d3d10_sampler_state_init(struct d3d10_sampler_state *state, struct d3d10_device *device,
559         const D3D10_SAMPLER_DESC *desc)
560 {
561     HRESULT hr;
562
563     state->ID3D10SamplerState_iface.lpVtbl = &d3d10_sampler_state_vtbl;
564     state->refcount = 1;
565     state->device = device;
566     state->desc = *desc;
567
568     if (FAILED(hr = wined3d_sampler_create(state, &state->wined3d_sampler)))
569     {
570         WARN("Failed to create wined3d sampler, hr %#x.\n", hr);
571         return hr;
572     }
573
574     if (wine_rb_put(&device->sampler_states, desc, &state->entry) == -1)
575     {
576         ERR("Failed to insert sampler state entry.\n");
577         wined3d_sampler_decref(state->wined3d_sampler);
578         return E_FAIL;
579     }
580
581     return S_OK;
582 }
583
584 struct d3d10_sampler_state *unsafe_impl_from_ID3D10SamplerState(ID3D10SamplerState *iface)
585 {
586     if (!iface)
587         return NULL;
588     assert(iface->lpVtbl == &d3d10_sampler_state_vtbl);
589
590     return impl_from_ID3D10SamplerState(iface);
591 }