2 * Copyright 2009 Henri Verbeet for CodeWeavers
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.
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.
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
21 #include "wine/port.h"
23 #include "d3d11_private.h"
25 WINE_DEFAULT_DEBUG_CHANNEL(d3d11
);
27 /* ID3D11BlendState methods */
29 static HRESULT STDMETHODCALLTYPE
d3d11_blend_state_QueryInterface(ID3D11BlendState
*iface
,
30 REFIID riid
, void **object
)
32 struct d3d_blend_state
*state
= impl_from_ID3D11BlendState(iface
);
34 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
36 if (IsEqualGUID(riid
, &IID_ID3D11BlendState
)
37 || IsEqualGUID(riid
, &IID_ID3D11DeviceChild
)
38 || IsEqualGUID(riid
, &IID_IUnknown
))
40 ID3D11BlendState_AddRef(iface
);
45 if (IsEqualGUID(riid
, &IID_ID3D10BlendState1
)
46 || IsEqualGUID(riid
, &IID_ID3D10BlendState
)
47 || IsEqualGUID(riid
, &IID_ID3D10DeviceChild
))
49 ID3D10BlendState1_AddRef(&state
->ID3D10BlendState1_iface
);
50 *object
= &state
->ID3D10BlendState1_iface
;
54 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
60 static ULONG STDMETHODCALLTYPE
d3d11_blend_state_AddRef(ID3D11BlendState
*iface
)
62 struct d3d_blend_state
*state
= impl_from_ID3D11BlendState(iface
);
63 ULONG refcount
= InterlockedIncrement(&state
->refcount
);
65 TRACE("%p increasing refcount to %u.\n", state
, refcount
);
70 static void d3d_blend_state_cleanup(struct d3d_blend_state
*state
)
72 wined3d_private_store_cleanup(&state
->private_store
);
73 ID3D11Device_Release(state
->device
);
76 static ULONG STDMETHODCALLTYPE
d3d11_blend_state_Release(ID3D11BlendState
*iface
)
78 struct d3d_blend_state
*state
= impl_from_ID3D11BlendState(iface
);
79 ULONG refcount
= InterlockedDecrement(&state
->refcount
);
81 TRACE("%p decreasing refcount to %u.\n", state
, refcount
);
85 struct d3d_device
*device
= impl_from_ID3D11Device(state
->device
);
87 wine_rb_remove(&device
->blend_states
, &state
->entry
);
88 d3d_blend_state_cleanup(state
);
89 wined3d_mutex_unlock();
90 HeapFree(GetProcessHeap(), 0, state
);
96 static void STDMETHODCALLTYPE
d3d11_blend_state_GetDevice(ID3D11BlendState
*iface
,
97 ID3D11Device
**device
)
99 struct d3d_blend_state
*state
= impl_from_ID3D11BlendState(iface
);
101 TRACE("iface %p, device %p.\n", iface
, device
);
103 *device
= state
->device
;
104 ID3D11Device_AddRef(*device
);
107 static HRESULT STDMETHODCALLTYPE
d3d11_blend_state_GetPrivateData(ID3D11BlendState
*iface
,
108 REFGUID guid
, UINT
*data_size
, void *data
)
110 struct d3d_blend_state
*state
= impl_from_ID3D11BlendState(iface
);
112 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
114 return d3d_get_private_data(&state
->private_store
, guid
, data_size
, data
);
117 static HRESULT STDMETHODCALLTYPE
d3d11_blend_state_SetPrivateData(ID3D11BlendState
*iface
,
118 REFGUID guid
, UINT data_size
, const void *data
)
120 struct d3d_blend_state
*state
= impl_from_ID3D11BlendState(iface
);
122 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
124 return d3d_set_private_data(&state
->private_store
, guid
, data_size
, data
);
127 static HRESULT STDMETHODCALLTYPE
d3d11_blend_state_SetPrivateDataInterface(ID3D11BlendState
*iface
,
128 REFGUID guid
, const IUnknown
*data
)
130 struct d3d_blend_state
*state
= impl_from_ID3D11BlendState(iface
);
132 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
134 return d3d_set_private_data_interface(&state
->private_store
, guid
, data
);
137 static void STDMETHODCALLTYPE
d3d11_blend_state_GetDesc(ID3D11BlendState
*iface
, D3D11_BLEND_DESC
*desc
)
139 struct d3d_blend_state
*state
= impl_from_ID3D11BlendState(iface
);
141 TRACE("iface %p, desc %p.\n", iface
, desc
);
146 static const struct ID3D11BlendStateVtbl d3d11_blend_state_vtbl
=
148 /* IUnknown methods */
149 d3d11_blend_state_QueryInterface
,
150 d3d11_blend_state_AddRef
,
151 d3d11_blend_state_Release
,
152 /* ID3D11DeviceChild methods */
153 d3d11_blend_state_GetDevice
,
154 d3d11_blend_state_GetPrivateData
,
155 d3d11_blend_state_SetPrivateData
,
156 d3d11_blend_state_SetPrivateDataInterface
,
157 /* ID3D11BlendState methods */
158 d3d11_blend_state_GetDesc
,
161 /* ID3D10BlendState methods */
163 static inline struct d3d_blend_state
*impl_from_ID3D10BlendState(ID3D10BlendState1
*iface
)
165 return CONTAINING_RECORD(iface
, struct d3d_blend_state
, ID3D10BlendState1_iface
);
168 /* IUnknown methods */
170 static HRESULT STDMETHODCALLTYPE
d3d10_blend_state_QueryInterface(ID3D10BlendState1
*iface
,
171 REFIID riid
, void **object
)
173 struct d3d_blend_state
*state
= impl_from_ID3D10BlendState(iface
);
175 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
177 return d3d11_blend_state_QueryInterface(&state
->ID3D11BlendState_iface
, riid
, object
);
180 static ULONG STDMETHODCALLTYPE
d3d10_blend_state_AddRef(ID3D10BlendState1
*iface
)
182 struct d3d_blend_state
*state
= impl_from_ID3D10BlendState(iface
);
184 TRACE("iface %p.\n", iface
);
186 return d3d11_blend_state_AddRef(&state
->ID3D11BlendState_iface
);
189 static ULONG STDMETHODCALLTYPE
d3d10_blend_state_Release(ID3D10BlendState1
*iface
)
191 struct d3d_blend_state
*state
= impl_from_ID3D10BlendState(iface
);
193 TRACE("iface %p.\n", iface
);
195 return d3d11_blend_state_Release(&state
->ID3D11BlendState_iface
);
198 /* ID3D10DeviceChild methods */
200 static void STDMETHODCALLTYPE
d3d10_blend_state_GetDevice(ID3D10BlendState1
*iface
, ID3D10Device
**device
)
202 struct d3d_blend_state
*state
= impl_from_ID3D10BlendState(iface
);
204 TRACE("iface %p, device %p.\n", iface
, device
);
206 ID3D11Device_QueryInterface(state
->device
, &IID_ID3D10Device
, (void **)device
);
209 static HRESULT STDMETHODCALLTYPE
d3d10_blend_state_GetPrivateData(ID3D10BlendState1
*iface
,
210 REFGUID guid
, UINT
*data_size
, void *data
)
212 struct d3d_blend_state
*state
= impl_from_ID3D10BlendState(iface
);
214 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
215 iface
, debugstr_guid(guid
), data_size
, data
);
217 return d3d_get_private_data(&state
->private_store
, guid
, data_size
, data
);
220 static HRESULT STDMETHODCALLTYPE
d3d10_blend_state_SetPrivateData(ID3D10BlendState1
*iface
,
221 REFGUID guid
, UINT data_size
, const void *data
)
223 struct d3d_blend_state
*state
= impl_from_ID3D10BlendState(iface
);
225 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
226 iface
, debugstr_guid(guid
), data_size
, data
);
228 return d3d_set_private_data(&state
->private_store
, guid
, data_size
, data
);
231 static HRESULT STDMETHODCALLTYPE
d3d10_blend_state_SetPrivateDataInterface(ID3D10BlendState1
*iface
,
232 REFGUID guid
, const IUnknown
*data
)
234 struct d3d_blend_state
*state
= impl_from_ID3D10BlendState(iface
);
236 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
238 return d3d_set_private_data_interface(&state
->private_store
, guid
, data
);
241 /* ID3D10BlendState methods */
243 static void STDMETHODCALLTYPE
d3d10_blend_state_GetDesc(ID3D10BlendState1
*iface
, D3D10_BLEND_DESC
*desc
)
245 struct d3d_blend_state
*state
= impl_from_ID3D10BlendState(iface
);
246 const D3D11_BLEND_DESC
*d3d11_desc
= &state
->desc
;
249 TRACE("iface %p, desc %p.\n", iface
, desc
);
251 desc
->AlphaToCoverageEnable
= d3d11_desc
->AlphaToCoverageEnable
;
252 desc
->SrcBlend
= d3d11_desc
->RenderTarget
[0].SrcBlend
;
253 desc
->DestBlend
= d3d11_desc
->RenderTarget
[0].DestBlend
;
254 desc
->BlendOp
= d3d11_desc
->RenderTarget
[0].BlendOp
;
255 desc
->SrcBlendAlpha
= d3d11_desc
->RenderTarget
[0].SrcBlendAlpha
;
256 desc
->DestBlendAlpha
= d3d11_desc
->RenderTarget
[0].DestBlendAlpha
;
257 desc
->BlendOpAlpha
= d3d11_desc
->RenderTarget
[0].BlendOpAlpha
;
258 for (i
= 0; i
< D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT
; ++i
)
260 desc
->BlendEnable
[i
] = d3d11_desc
->RenderTarget
[i
].BlendEnable
;
261 desc
->RenderTargetWriteMask
[i
] = d3d11_desc
->RenderTarget
[i
].RenderTargetWriteMask
;
265 static void STDMETHODCALLTYPE
d3d10_blend_state_GetDesc1(ID3D10BlendState1
*iface
, D3D10_BLEND_DESC1
*desc
)
267 struct d3d_blend_state
*state
= impl_from_ID3D10BlendState(iface
);
269 TRACE("iface %p, desc %p.\n", iface
, desc
);
271 memcpy(desc
, &state
->desc
, sizeof(*desc
));
274 static const struct ID3D10BlendState1Vtbl d3d10_blend_state_vtbl
=
276 /* IUnknown methods */
277 d3d10_blend_state_QueryInterface
,
278 d3d10_blend_state_AddRef
,
279 d3d10_blend_state_Release
,
280 /* ID3D10DeviceChild methods */
281 d3d10_blend_state_GetDevice
,
282 d3d10_blend_state_GetPrivateData
,
283 d3d10_blend_state_SetPrivateData
,
284 d3d10_blend_state_SetPrivateDataInterface
,
285 /* ID3D10BlendState methods */
286 d3d10_blend_state_GetDesc
,
287 /* ID3D10BlendState1 methods */
288 d3d10_blend_state_GetDesc1
,
291 static HRESULT
d3d_blend_state_init(struct d3d_blend_state
*state
, struct d3d_device
*device
,
292 const D3D11_BLEND_DESC
*desc
)
294 state
->ID3D11BlendState_iface
.lpVtbl
= &d3d11_blend_state_vtbl
;
295 state
->ID3D10BlendState1_iface
.lpVtbl
= &d3d10_blend_state_vtbl
;
297 wined3d_private_store_init(&state
->private_store
);
300 state
->device
= &device
->ID3D11Device_iface
;
301 ID3D11Device_AddRef(state
->device
);
306 HRESULT
d3d_blend_state_create(struct d3d_device
*device
, const D3D11_BLEND_DESC
*desc
,
307 struct d3d_blend_state
**state
)
309 struct d3d_blend_state
*object
;
310 struct wine_rb_entry
*entry
;
311 D3D11_BLEND_DESC tmp_desc
;
318 /* D3D11_RENDER_TARGET_BLEND_DESC has a hole, which is a problem because we use
319 * D3D11_BLEND_DESC as a key in the rbtree. */
320 memset(&tmp_desc
, 0, sizeof(tmp_desc
));
321 tmp_desc
.AlphaToCoverageEnable
= desc
->AlphaToCoverageEnable
;
322 tmp_desc
.IndependentBlendEnable
= desc
->IndependentBlendEnable
;
323 for (i
= 0; i
< D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT
; ++i
)
325 j
= desc
->IndependentBlendEnable
? i
: 0;
326 tmp_desc
.RenderTarget
[i
].BlendEnable
= desc
->RenderTarget
[j
].BlendEnable
;
327 tmp_desc
.RenderTarget
[i
].SrcBlend
= desc
->RenderTarget
[j
].SrcBlend
;
328 tmp_desc
.RenderTarget
[i
].DestBlend
= desc
->RenderTarget
[j
].DestBlend
;
329 tmp_desc
.RenderTarget
[i
].BlendOp
= desc
->RenderTarget
[j
].BlendOp
;
330 tmp_desc
.RenderTarget
[i
].SrcBlendAlpha
= desc
->RenderTarget
[j
].SrcBlendAlpha
;
331 tmp_desc
.RenderTarget
[i
].DestBlendAlpha
= desc
->RenderTarget
[j
].DestBlendAlpha
;
332 tmp_desc
.RenderTarget
[i
].BlendOpAlpha
= desc
->RenderTarget
[j
].BlendOpAlpha
;
333 tmp_desc
.RenderTarget
[i
].RenderTargetWriteMask
= desc
->RenderTarget
[j
].RenderTargetWriteMask
;
335 if (i
> 3 && tmp_desc
.RenderTarget
[i
].RenderTargetWriteMask
!= D3D11_COLOR_WRITE_ENABLE_ALL
)
336 FIXME("Color mask %#x not supported for render target %u.\n",
337 tmp_desc
.RenderTarget
[i
].RenderTargetWriteMask
, i
);
340 /* glSampleCoverage() */
341 if (tmp_desc
.AlphaToCoverageEnable
)
342 FIXME("Ignoring AlphaToCoverageEnable %#x.\n", tmp_desc
.AlphaToCoverageEnable
);
343 /* glEnableIndexedEXT(GL_BLEND, ...) */
344 if (tmp_desc
.IndependentBlendEnable
)
345 FIXME("Per-rendertarget blend not implemented.\n");
347 wined3d_mutex_lock();
348 if ((entry
= wine_rb_get(&device
->blend_states
, &tmp_desc
)))
350 object
= WINE_RB_ENTRY_VALUE(entry
, struct d3d_blend_state
, entry
);
352 TRACE("Returning existing blend state %p.\n", object
);
353 ID3D11BlendState_AddRef(&object
->ID3D11BlendState_iface
);
355 wined3d_mutex_unlock();
360 if (!(object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*object
))))
362 wined3d_mutex_unlock();
363 return E_OUTOFMEMORY
;
366 if (FAILED(hr
= d3d_blend_state_init(object
, device
, &tmp_desc
)))
368 WARN("Failed to initialize blend state, hr %#x.\n", hr
);
369 HeapFree(GetProcessHeap(), 0, object
);
370 wined3d_mutex_unlock();
374 if (wine_rb_put(&device
->blend_states
, desc
, &object
->entry
) == -1)
376 ERR("Failed to insert blend state entry.\n");
377 d3d_blend_state_cleanup(object
);
378 HeapFree(GetProcessHeap(), 0, object
);
379 wined3d_mutex_unlock();
382 wined3d_mutex_unlock();
384 TRACE("Created blend state %p.\n", object
);
390 struct d3d_blend_state
*unsafe_impl_from_ID3D11BlendState(ID3D11BlendState
*iface
)
394 assert(iface
->lpVtbl
== &d3d11_blend_state_vtbl
);
396 return impl_from_ID3D11BlendState(iface
);
399 struct d3d_blend_state
*unsafe_impl_from_ID3D10BlendState(ID3D10BlendState
*iface
)
403 assert(iface
->lpVtbl
== (ID3D10BlendStateVtbl
*)&d3d10_blend_state_vtbl
);
405 return impl_from_ID3D10BlendState((ID3D10BlendState1
*)iface
);
408 /* ID3D11DepthStencilState methods */
410 static HRESULT STDMETHODCALLTYPE
d3d11_depthstencil_state_QueryInterface(ID3D11DepthStencilState
*iface
,
411 REFIID riid
, void **object
)
413 struct d3d_depthstencil_state
*state
= impl_from_ID3D11DepthStencilState(iface
);
415 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
417 if (IsEqualGUID(riid
, &IID_ID3D11DepthStencilState
)
418 || IsEqualGUID(riid
, &IID_ID3D11DeviceChild
)
419 || IsEqualGUID(riid
, &IID_IUnknown
))
421 ID3D11DepthStencilState_AddRef(iface
);
426 if (IsEqualGUID(riid
, &IID_ID3D10DepthStencilState
)
427 || IsEqualGUID(riid
, &IID_ID3D10DeviceChild
))
429 ID3D10DepthStencilState_AddRef(&state
->ID3D10DepthStencilState_iface
);
430 *object
= &state
->ID3D10DepthStencilState_iface
;
434 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
437 return E_NOINTERFACE
;
440 static ULONG STDMETHODCALLTYPE
d3d11_depthstencil_state_AddRef(ID3D11DepthStencilState
*iface
)
442 struct d3d_depthstencil_state
*state
= impl_from_ID3D11DepthStencilState(iface
);
443 ULONG refcount
= InterlockedIncrement(&state
->refcount
);
445 TRACE("%p increasing refcount to %u.\n", state
, refcount
);
450 static void d3d_depthstencil_state_cleanup(struct d3d_depthstencil_state
*state
)
452 wined3d_private_store_cleanup(&state
->private_store
);
453 ID3D11Device_Release(state
->device
);
456 static ULONG STDMETHODCALLTYPE
d3d11_depthstencil_state_Release(ID3D11DepthStencilState
*iface
)
458 struct d3d_depthstencil_state
*state
= impl_from_ID3D11DepthStencilState(iface
);
459 ULONG refcount
= InterlockedDecrement(&state
->refcount
);
461 TRACE("%p decreasing refcount to %u.\n", state
, refcount
);
465 struct d3d_device
*device
= impl_from_ID3D11Device(state
->device
);
466 wined3d_mutex_lock();
467 wine_rb_remove(&device
->depthstencil_states
, &state
->entry
);
468 d3d_depthstencil_state_cleanup(state
);
469 wined3d_mutex_unlock();
470 HeapFree(GetProcessHeap(), 0, state
);
476 static void STDMETHODCALLTYPE
d3d11_depthstencil_state_GetDevice(ID3D11DepthStencilState
*iface
,
477 ID3D11Device
**device
)
479 struct d3d_depthstencil_state
*state
= impl_from_ID3D11DepthStencilState(iface
);
481 TRACE("iface %p, device %p.\n", iface
, device
);
483 *device
= state
->device
;
484 ID3D11Device_AddRef(*device
);
487 static HRESULT STDMETHODCALLTYPE
d3d11_depthstencil_state_GetPrivateData(ID3D11DepthStencilState
*iface
,
488 REFGUID guid
, UINT
*data_size
, void *data
)
490 struct d3d_depthstencil_state
*state
= impl_from_ID3D11DepthStencilState(iface
);
492 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
494 return d3d_get_private_data(&state
->private_store
, guid
, data_size
, data
);
497 static HRESULT STDMETHODCALLTYPE
d3d11_depthstencil_state_SetPrivateData(ID3D11DepthStencilState
*iface
,
498 REFGUID guid
, UINT data_size
, const void *data
)
500 struct d3d_depthstencil_state
*state
= impl_from_ID3D11DepthStencilState(iface
);
502 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
504 return d3d_set_private_data(&state
->private_store
, guid
, data_size
, data
);
507 static HRESULT STDMETHODCALLTYPE
d3d11_depthstencil_state_SetPrivateDataInterface(ID3D11DepthStencilState
*iface
,
508 REFGUID guid
, const IUnknown
*data
)
510 struct d3d_depthstencil_state
*state
= impl_from_ID3D11DepthStencilState(iface
);
512 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
514 return d3d_set_private_data_interface(&state
->private_store
, guid
, data
);
517 static void STDMETHODCALLTYPE
d3d11_depthstencil_state_GetDesc(ID3D11DepthStencilState
*iface
,
518 D3D11_DEPTH_STENCIL_DESC
*desc
)
520 struct d3d_depthstencil_state
*state
= impl_from_ID3D11DepthStencilState(iface
);
522 TRACE("iface %p, desc %p.\n", iface
, desc
);
527 static const struct ID3D11DepthStencilStateVtbl d3d11_depthstencil_state_vtbl
=
529 /* IUnknown methods */
530 d3d11_depthstencil_state_QueryInterface
,
531 d3d11_depthstencil_state_AddRef
,
532 d3d11_depthstencil_state_Release
,
533 /* ID3D11DeviceChild methods */
534 d3d11_depthstencil_state_GetDevice
,
535 d3d11_depthstencil_state_GetPrivateData
,
536 d3d11_depthstencil_state_SetPrivateData
,
537 d3d11_depthstencil_state_SetPrivateDataInterface
,
538 /* ID3D11DepthStencilState methods */
539 d3d11_depthstencil_state_GetDesc
,
542 /* ID3D10DepthStencilState methods */
544 static inline struct d3d_depthstencil_state
*impl_from_ID3D10DepthStencilState(ID3D10DepthStencilState
*iface
)
546 return CONTAINING_RECORD(iface
, struct d3d_depthstencil_state
, ID3D10DepthStencilState_iface
);
549 /* IUnknown methods */
551 static HRESULT STDMETHODCALLTYPE
d3d10_depthstencil_state_QueryInterface(ID3D10DepthStencilState
*iface
,
552 REFIID riid
, void **object
)
554 struct d3d_depthstencil_state
*state
= impl_from_ID3D10DepthStencilState(iface
);
556 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
558 return d3d11_depthstencil_state_QueryInterface(&state
->ID3D11DepthStencilState_iface
, riid
, object
);
561 static ULONG STDMETHODCALLTYPE
d3d10_depthstencil_state_AddRef(ID3D10DepthStencilState
*iface
)
563 struct d3d_depthstencil_state
*state
= impl_from_ID3D10DepthStencilState(iface
);
565 TRACE("iface %p.\n", iface
);
567 return d3d11_depthstencil_state_AddRef(&state
->ID3D11DepthStencilState_iface
);
570 static ULONG STDMETHODCALLTYPE
d3d10_depthstencil_state_Release(ID3D10DepthStencilState
*iface
)
572 struct d3d_depthstencil_state
*state
= impl_from_ID3D10DepthStencilState(iface
);
574 TRACE("iface %p.\n", iface
);
576 return d3d11_depthstencil_state_Release(&state
->ID3D11DepthStencilState_iface
);
579 /* ID3D10DeviceChild methods */
581 static void STDMETHODCALLTYPE
d3d10_depthstencil_state_GetDevice(ID3D10DepthStencilState
*iface
, ID3D10Device
**device
)
583 struct d3d_depthstencil_state
*state
= impl_from_ID3D10DepthStencilState(iface
);
585 TRACE("iface %p, device %p.\n", iface
, device
);
587 ID3D11Device_QueryInterface(state
->device
, &IID_ID3D10Device
, (void **)device
);
590 static HRESULT STDMETHODCALLTYPE
d3d10_depthstencil_state_GetPrivateData(ID3D10DepthStencilState
*iface
,
591 REFGUID guid
, UINT
*data_size
, void *data
)
593 struct d3d_depthstencil_state
*state
= impl_from_ID3D10DepthStencilState(iface
);
595 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
596 iface
, debugstr_guid(guid
), data_size
, data
);
598 return d3d_get_private_data(&state
->private_store
, guid
, data_size
, data
);
601 static HRESULT STDMETHODCALLTYPE
d3d10_depthstencil_state_SetPrivateData(ID3D10DepthStencilState
*iface
,
602 REFGUID guid
, UINT data_size
, const void *data
)
604 struct d3d_depthstencil_state
*state
= impl_from_ID3D10DepthStencilState(iface
);
606 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
607 iface
, debugstr_guid(guid
), data_size
, data
);
609 return d3d_set_private_data(&state
->private_store
, guid
, data_size
, data
);
612 static HRESULT STDMETHODCALLTYPE
d3d10_depthstencil_state_SetPrivateDataInterface(ID3D10DepthStencilState
*iface
,
613 REFGUID guid
, const IUnknown
*data
)
615 struct d3d_depthstencil_state
*state
= impl_from_ID3D10DepthStencilState(iface
);
617 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
619 return d3d_set_private_data_interface(&state
->private_store
, guid
, data
);
622 /* ID3D10DepthStencilState methods */
624 static void STDMETHODCALLTYPE
d3d10_depthstencil_state_GetDesc(ID3D10DepthStencilState
*iface
,
625 D3D10_DEPTH_STENCIL_DESC
*desc
)
627 struct d3d_depthstencil_state
*state
= impl_from_ID3D10DepthStencilState(iface
);
629 TRACE("iface %p, desc %p.\n", iface
, desc
);
631 memcpy(desc
, &state
->desc
, sizeof(*desc
));
634 static const struct ID3D10DepthStencilStateVtbl d3d10_depthstencil_state_vtbl
=
636 /* IUnknown methods */
637 d3d10_depthstencil_state_QueryInterface
,
638 d3d10_depthstencil_state_AddRef
,
639 d3d10_depthstencil_state_Release
,
640 /* ID3D10DeviceChild methods */
641 d3d10_depthstencil_state_GetDevice
,
642 d3d10_depthstencil_state_GetPrivateData
,
643 d3d10_depthstencil_state_SetPrivateData
,
644 d3d10_depthstencil_state_SetPrivateDataInterface
,
645 /* ID3D10DepthStencilState methods */
646 d3d10_depthstencil_state_GetDesc
,
649 static HRESULT
d3d_depthstencil_state_init(struct d3d_depthstencil_state
*state
, struct d3d_device
*device
,
650 const D3D11_DEPTH_STENCIL_DESC
*desc
)
652 state
->ID3D11DepthStencilState_iface
.lpVtbl
= &d3d11_depthstencil_state_vtbl
;
653 state
->ID3D10DepthStencilState_iface
.lpVtbl
= &d3d10_depthstencil_state_vtbl
;
655 wined3d_private_store_init(&state
->private_store
);
658 state
->device
= &device
->ID3D11Device_iface
;
659 ID3D11Device_AddRef(state
->device
);
664 HRESULT
d3d_depthstencil_state_create(struct d3d_device
*device
, const D3D11_DEPTH_STENCIL_DESC
*desc
,
665 struct d3d_depthstencil_state
**state
)
667 struct d3d_depthstencil_state
*object
;
668 D3D11_DEPTH_STENCIL_DESC tmp_desc
;
669 struct wine_rb_entry
*entry
;
675 /* D3D11_DEPTH_STENCIL_DESC has a hole, which is a problem because we use
676 * it as a key in the rbtree. */
677 memset(&tmp_desc
, 0, sizeof(tmp_desc
));
678 tmp_desc
.DepthEnable
= desc
->DepthEnable
;
679 if (desc
->DepthEnable
)
681 tmp_desc
.DepthWriteMask
= desc
->DepthWriteMask
;
682 tmp_desc
.DepthFunc
= desc
->DepthFunc
;
686 tmp_desc
.DepthWriteMask
= D3D11_DEPTH_WRITE_MASK_ALL
;
687 tmp_desc
.DepthFunc
= D3D11_COMPARISON_LESS
;
689 tmp_desc
.StencilEnable
= desc
->StencilEnable
;
690 if (desc
->StencilEnable
)
692 tmp_desc
.StencilReadMask
= desc
->StencilReadMask
;
693 tmp_desc
.StencilWriteMask
= desc
->StencilWriteMask
;
694 tmp_desc
.FrontFace
= desc
->FrontFace
;
695 tmp_desc
.BackFace
= desc
->BackFace
;
699 tmp_desc
.StencilReadMask
= D3D11_DEFAULT_STENCIL_READ_MASK
;
700 tmp_desc
.StencilWriteMask
= D3D11_DEFAULT_STENCIL_WRITE_MASK
;
701 tmp_desc
.FrontFace
.StencilFailOp
= D3D11_STENCIL_OP_KEEP
;
702 tmp_desc
.FrontFace
.StencilDepthFailOp
= D3D11_STENCIL_OP_KEEP
;
703 tmp_desc
.FrontFace
.StencilPassOp
= D3D11_STENCIL_OP_KEEP
;
704 tmp_desc
.FrontFace
.StencilFunc
= D3D11_COMPARISON_ALWAYS
;
705 tmp_desc
.BackFace
.StencilFailOp
= D3D11_STENCIL_OP_KEEP
;
706 tmp_desc
.BackFace
.StencilDepthFailOp
= D3D11_STENCIL_OP_KEEP
;
707 tmp_desc
.BackFace
.StencilPassOp
= D3D11_STENCIL_OP_KEEP
;
708 tmp_desc
.BackFace
.StencilFunc
= D3D11_COMPARISON_ALWAYS
;
711 wined3d_mutex_lock();
712 if ((entry
= wine_rb_get(&device
->depthstencil_states
, &tmp_desc
)))
714 object
= WINE_RB_ENTRY_VALUE(entry
, struct d3d_depthstencil_state
, entry
);
716 TRACE("Returning existing depthstencil state %p.\n", object
);
717 ID3D11DepthStencilState_AddRef(&object
->ID3D11DepthStencilState_iface
);
719 wined3d_mutex_unlock();
724 if (!(object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*object
))))
726 wined3d_mutex_unlock();
727 return E_OUTOFMEMORY
;
730 if (FAILED(hr
= d3d_depthstencil_state_init(object
, device
, &tmp_desc
)))
732 WARN("Failed to initialize depthstencil state, hr %#x.\n", hr
);
733 HeapFree(GetProcessHeap(), 0, object
);
734 wined3d_mutex_unlock();
738 if (wine_rb_put(&device
->depthstencil_states
, desc
, &object
->entry
) == -1)
740 ERR("Failed to insert depthstencil state entry.\n");
741 d3d_depthstencil_state_cleanup(object
);
742 HeapFree(GetProcessHeap(), 0, object
);
743 wined3d_mutex_unlock();
746 wined3d_mutex_unlock();
748 TRACE("Created depthstencil state %p.\n", object
);
754 struct d3d_depthstencil_state
*unsafe_impl_from_ID3D11DepthStencilState(ID3D11DepthStencilState
*iface
)
758 assert(iface
->lpVtbl
== &d3d11_depthstencil_state_vtbl
);
760 return impl_from_ID3D11DepthStencilState(iface
);
763 struct d3d_depthstencil_state
*unsafe_impl_from_ID3D10DepthStencilState(ID3D10DepthStencilState
*iface
)
767 assert(iface
->lpVtbl
== &d3d10_depthstencil_state_vtbl
);
769 return impl_from_ID3D10DepthStencilState(iface
);
772 /* ID3D11RasterizerState methods */
774 static inline struct d3d_rasterizer_state
*impl_from_ID3D11RasterizerState(ID3D11RasterizerState
*iface
)
776 return CONTAINING_RECORD(iface
, struct d3d_rasterizer_state
, ID3D11RasterizerState_iface
);
779 static HRESULT STDMETHODCALLTYPE
d3d11_rasterizer_state_QueryInterface(ID3D11RasterizerState
*iface
,
780 REFIID riid
, void **object
)
782 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState(iface
);
784 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
786 if (IsEqualGUID(riid
, &IID_ID3D11RasterizerState
)
787 || IsEqualGUID(riid
, &IID_ID3D11DeviceChild
)
788 || IsEqualGUID(riid
, &IID_IUnknown
))
790 ID3D11RasterizerState_AddRef(iface
);
795 if (IsEqualGUID(riid
, &IID_ID3D10RasterizerState
)
796 || IsEqualGUID(riid
, &IID_ID3D10DeviceChild
))
798 ID3D10RasterizerState_AddRef(&state
->ID3D10RasterizerState_iface
);
799 *object
= &state
->ID3D10RasterizerState_iface
;
803 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
806 return E_NOINTERFACE
;
809 static ULONG STDMETHODCALLTYPE
d3d11_rasterizer_state_AddRef(ID3D11RasterizerState
*iface
)
811 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState(iface
);
812 ULONG refcount
= InterlockedIncrement(&state
->refcount
);
814 TRACE("%p increasing refcount to %u.\n", state
, refcount
);
818 ID3D11Device_AddRef(state
->device
);
819 wined3d_mutex_lock();
820 wined3d_rasterizer_state_incref(state
->wined3d_state
);
821 wined3d_mutex_unlock();
827 static ULONG STDMETHODCALLTYPE
d3d11_rasterizer_state_Release(ID3D11RasterizerState
*iface
)
829 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState(iface
);
830 ULONG refcount
= InterlockedDecrement(&state
->refcount
);
832 TRACE("%p decreasing refcount to %u.\n", state
, refcount
);
836 ID3D11Device
*device
= state
->device
;
838 wined3d_mutex_lock();
839 wined3d_rasterizer_state_decref(state
->wined3d_state
);
840 wined3d_mutex_unlock();
842 ID3D11Device_Release(device
);
848 static void STDMETHODCALLTYPE
d3d11_rasterizer_state_GetDevice(ID3D11RasterizerState
*iface
,
849 ID3D11Device
**device
)
851 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState(iface
);
853 TRACE("iface %p, device %p.\n", iface
, device
);
855 *device
= state
->device
;
856 ID3D11Device_AddRef(*device
);
859 static HRESULT STDMETHODCALLTYPE
d3d11_rasterizer_state_GetPrivateData(ID3D11RasterizerState
*iface
,
860 REFGUID guid
, UINT
*data_size
, void *data
)
862 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState(iface
);
864 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
866 return d3d_get_private_data(&state
->private_store
, guid
, data_size
, data
);
869 static HRESULT STDMETHODCALLTYPE
d3d11_rasterizer_state_SetPrivateData(ID3D11RasterizerState
*iface
,
870 REFGUID guid
, UINT data_size
, const void *data
)
872 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState(iface
);
874 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
876 return d3d_set_private_data(&state
->private_store
, guid
, data_size
, data
);
879 static HRESULT STDMETHODCALLTYPE
d3d11_rasterizer_state_SetPrivateDataInterface(ID3D11RasterizerState
*iface
,
880 REFGUID guid
, const IUnknown
*data
)
882 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState(iface
);
884 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
886 return d3d_set_private_data_interface(&state
->private_store
, guid
, data
);
889 static void STDMETHODCALLTYPE
d3d11_rasterizer_state_GetDesc(ID3D11RasterizerState
*iface
,
890 D3D11_RASTERIZER_DESC
*desc
)
892 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState(iface
);
894 TRACE("iface %p, desc %p.\n", iface
, desc
);
899 static const struct ID3D11RasterizerStateVtbl d3d11_rasterizer_state_vtbl
=
901 /* IUnknown methods */
902 d3d11_rasterizer_state_QueryInterface
,
903 d3d11_rasterizer_state_AddRef
,
904 d3d11_rasterizer_state_Release
,
905 /* ID3D11DeviceChild methods */
906 d3d11_rasterizer_state_GetDevice
,
907 d3d11_rasterizer_state_GetPrivateData
,
908 d3d11_rasterizer_state_SetPrivateData
,
909 d3d11_rasterizer_state_SetPrivateDataInterface
,
910 /* ID3D11RasterizerState methods */
911 d3d11_rasterizer_state_GetDesc
,
914 /* ID3D10RasterizerState methods */
916 static inline struct d3d_rasterizer_state
*impl_from_ID3D10RasterizerState(ID3D10RasterizerState
*iface
)
918 return CONTAINING_RECORD(iface
, struct d3d_rasterizer_state
, ID3D10RasterizerState_iface
);
921 /* IUnknown methods */
923 static HRESULT STDMETHODCALLTYPE
d3d10_rasterizer_state_QueryInterface(ID3D10RasterizerState
*iface
,
924 REFIID riid
, void **object
)
926 struct d3d_rasterizer_state
*state
= impl_from_ID3D10RasterizerState(iface
);
928 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
930 return d3d11_rasterizer_state_QueryInterface(&state
->ID3D11RasterizerState_iface
, riid
, object
);
933 static ULONG STDMETHODCALLTYPE
d3d10_rasterizer_state_AddRef(ID3D10RasterizerState
*iface
)
935 struct d3d_rasterizer_state
*state
= impl_from_ID3D10RasterizerState(iface
);
937 TRACE("iface %p.\n", iface
);
939 return d3d11_rasterizer_state_AddRef(&state
->ID3D11RasterizerState_iface
);
942 static ULONG STDMETHODCALLTYPE
d3d10_rasterizer_state_Release(ID3D10RasterizerState
*iface
)
944 struct d3d_rasterizer_state
*state
= impl_from_ID3D10RasterizerState(iface
);
946 TRACE("iface %p.\n", state
);
948 return d3d11_rasterizer_state_Release(&state
->ID3D11RasterizerState_iface
);
951 /* ID3D10DeviceChild methods */
953 static void STDMETHODCALLTYPE
d3d10_rasterizer_state_GetDevice(ID3D10RasterizerState
*iface
, ID3D10Device
**device
)
955 struct d3d_rasterizer_state
*state
= impl_from_ID3D10RasterizerState(iface
);
957 TRACE("iface %p, device %p.\n", iface
, device
);
959 ID3D11Device_QueryInterface(state
->device
, &IID_ID3D10Device
, (void **)device
);
962 static HRESULT STDMETHODCALLTYPE
d3d10_rasterizer_state_GetPrivateData(ID3D10RasterizerState
*iface
,
963 REFGUID guid
, UINT
*data_size
, void *data
)
965 struct d3d_rasterizer_state
*state
= impl_from_ID3D10RasterizerState(iface
);
967 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
968 iface
, debugstr_guid(guid
), data_size
, data
);
970 return d3d_get_private_data(&state
->private_store
, guid
, data_size
, data
);
973 static HRESULT STDMETHODCALLTYPE
d3d10_rasterizer_state_SetPrivateData(ID3D10RasterizerState
*iface
,
974 REFGUID guid
, UINT data_size
, const void *data
)
976 struct d3d_rasterizer_state
*state
= impl_from_ID3D10RasterizerState(iface
);
978 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
979 iface
, debugstr_guid(guid
), data_size
, data
);
981 return d3d_set_private_data(&state
->private_store
, guid
, data_size
, data
);
984 static HRESULT STDMETHODCALLTYPE
d3d10_rasterizer_state_SetPrivateDataInterface(ID3D10RasterizerState
*iface
,
985 REFGUID guid
, const IUnknown
*data
)
987 struct d3d_rasterizer_state
*state
= impl_from_ID3D10RasterizerState(iface
);
989 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
991 return d3d_set_private_data_interface(&state
->private_store
, guid
, data
);
994 /* ID3D10RasterizerState methods */
996 static void STDMETHODCALLTYPE
d3d10_rasterizer_state_GetDesc(ID3D10RasterizerState
*iface
,
997 D3D10_RASTERIZER_DESC
*desc
)
999 struct d3d_rasterizer_state
*state
= impl_from_ID3D10RasterizerState(iface
);
1001 TRACE("iface %p, desc %p.\n", iface
, desc
);
1003 memcpy(desc
, &state
->desc
, sizeof(*desc
));
1006 static const struct ID3D10RasterizerStateVtbl d3d10_rasterizer_state_vtbl
=
1008 /* IUnknown methods */
1009 d3d10_rasterizer_state_QueryInterface
,
1010 d3d10_rasterizer_state_AddRef
,
1011 d3d10_rasterizer_state_Release
,
1012 /* ID3D10DeviceChild methods */
1013 d3d10_rasterizer_state_GetDevice
,
1014 d3d10_rasterizer_state_GetPrivateData
,
1015 d3d10_rasterizer_state_SetPrivateData
,
1016 d3d10_rasterizer_state_SetPrivateDataInterface
,
1017 /* ID3D10RasterizerState methods */
1018 d3d10_rasterizer_state_GetDesc
,
1021 static void STDMETHODCALLTYPE
d3d_rasterizer_state_wined3d_object_destroyed(void *parent
)
1023 struct d3d_rasterizer_state
*state
= parent
;
1024 struct d3d_device
*device
= impl_from_ID3D11Device(state
->device
);
1026 wine_rb_remove(&device
->rasterizer_states
, &state
->entry
);
1027 wined3d_private_store_cleanup(&state
->private_store
);
1028 HeapFree(GetProcessHeap(), 0, parent
);
1031 static const struct wined3d_parent_ops d3d_rasterizer_state_wined3d_parent_ops
=
1033 d3d_rasterizer_state_wined3d_object_destroyed
,
1036 static HRESULT
d3d_rasterizer_state_init(struct d3d_rasterizer_state
*state
, struct d3d_device
*device
,
1037 const D3D11_RASTERIZER_DESC
*desc
)
1039 struct wined3d_rasterizer_state_desc wined3d_desc
;
1042 state
->ID3D11RasterizerState_iface
.lpVtbl
= &d3d11_rasterizer_state_vtbl
;
1043 state
->ID3D10RasterizerState_iface
.lpVtbl
= &d3d10_rasterizer_state_vtbl
;
1044 state
->refcount
= 1;
1045 wined3d_private_store_init(&state
->private_store
);
1046 state
->desc
= *desc
;
1048 if (wine_rb_put(&device
->rasterizer_states
, desc
, &state
->entry
) == -1)
1050 ERR("Failed to insert rasterizer state entry.\n");
1051 wined3d_private_store_cleanup(&state
->private_store
);
1055 wined3d_desc
.front_ccw
= desc
->FrontCounterClockwise
;
1057 /* We cannot fail after creating a wined3d_rasterizer_state object. It
1058 * would lead to double free. */
1059 if (FAILED(hr
= wined3d_rasterizer_state_create(device
->wined3d_device
, &wined3d_desc
,
1060 state
, &d3d_rasterizer_state_wined3d_parent_ops
, &state
->wined3d_state
)))
1062 WARN("Failed to create wined3d rasterizer state, hr %#x.\n", hr
);
1063 wined3d_private_store_cleanup(&state
->private_store
);
1064 wine_rb_remove(&device
->rasterizer_states
, &state
->entry
);
1068 ID3D11Device_AddRef(state
->device
= &device
->ID3D11Device_iface
);
1073 HRESULT
d3d_rasterizer_state_create(struct d3d_device
*device
, const D3D11_RASTERIZER_DESC
*desc
,
1074 struct d3d_rasterizer_state
**state
)
1076 struct d3d_rasterizer_state
*object
;
1077 struct wine_rb_entry
*entry
;
1081 return E_INVALIDARG
;
1083 wined3d_mutex_lock();
1084 if ((entry
= wine_rb_get(&device
->rasterizer_states
, desc
)))
1086 object
= WINE_RB_ENTRY_VALUE(entry
, struct d3d_rasterizer_state
, entry
);
1088 TRACE("Returning existing rasterizer state %p.\n", object
);
1089 ID3D11RasterizerState_AddRef(&object
->ID3D11RasterizerState_iface
);
1091 wined3d_mutex_unlock();
1096 if (!(object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*object
))))
1098 wined3d_mutex_unlock();
1099 return E_OUTOFMEMORY
;
1102 hr
= d3d_rasterizer_state_init(object
, device
, desc
);
1103 wined3d_mutex_unlock();
1106 WARN("Failed to initialize rasterizer state, hr %#x.\n", hr
);
1107 HeapFree(GetProcessHeap(), 0, object
);
1111 TRACE("Created rasterizer state %p.\n", object
);
1117 struct d3d_rasterizer_state
*unsafe_impl_from_ID3D11RasterizerState(ID3D11RasterizerState
*iface
)
1121 assert(iface
->lpVtbl
== &d3d11_rasterizer_state_vtbl
);
1123 return impl_from_ID3D11RasterizerState(iface
);
1126 struct d3d_rasterizer_state
*unsafe_impl_from_ID3D10RasterizerState(ID3D10RasterizerState
*iface
)
1130 assert(iface
->lpVtbl
== &d3d10_rasterizer_state_vtbl
);
1132 return impl_from_ID3D10RasterizerState(iface
);
1135 /* ID3D11SampleState methods */
1137 static inline struct d3d_sampler_state
*impl_from_ID3D11SamplerState(ID3D11SamplerState
*iface
)
1139 return CONTAINING_RECORD(iface
, struct d3d_sampler_state
, ID3D11SamplerState_iface
);
1142 static HRESULT STDMETHODCALLTYPE
d3d11_sampler_state_QueryInterface(ID3D11SamplerState
*iface
,
1143 REFIID riid
, void **object
)
1145 struct d3d_sampler_state
*state
= impl_from_ID3D11SamplerState(iface
);
1147 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
1149 if (IsEqualGUID(riid
, &IID_ID3D11SamplerState
)
1150 || IsEqualGUID(riid
, &IID_ID3D11DeviceChild
)
1151 || IsEqualGUID(riid
, &IID_IUnknown
))
1153 ID3D11SamplerState_AddRef(iface
);
1158 if (IsEqualGUID(riid
, &IID_ID3D10SamplerState
)
1159 || IsEqualGUID(riid
, &IID_ID3D10DeviceChild
))
1161 ID3D10SamplerState_AddRef(&state
->ID3D10SamplerState_iface
);
1162 *object
= &state
->ID3D10SamplerState_iface
;
1166 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
1169 return E_NOINTERFACE
;
1172 static ULONG STDMETHODCALLTYPE
d3d11_sampler_state_AddRef(ID3D11SamplerState
*iface
)
1174 struct d3d_sampler_state
*state
= impl_from_ID3D11SamplerState(iface
);
1175 ULONG refcount
= InterlockedIncrement(&state
->refcount
);
1177 TRACE("%p increasing refcount to %u.\n", state
, refcount
);
1181 ID3D11Device_AddRef(state
->device
);
1182 wined3d_mutex_lock();
1183 wined3d_sampler_incref(state
->wined3d_sampler
);
1184 wined3d_mutex_unlock();
1190 static ULONG STDMETHODCALLTYPE
d3d11_sampler_state_Release(ID3D11SamplerState
*iface
)
1192 struct d3d_sampler_state
*state
= impl_from_ID3D11SamplerState(iface
);
1193 ULONG refcount
= InterlockedDecrement(&state
->refcount
);
1195 TRACE("%p decreasing refcount to %u.\n", state
, refcount
);
1199 ID3D11Device
*device
= state
->device
;
1201 wined3d_mutex_lock();
1202 wined3d_sampler_decref(state
->wined3d_sampler
);
1203 wined3d_mutex_unlock();
1205 ID3D11Device_Release(device
);
1211 static void STDMETHODCALLTYPE
d3d11_sampler_state_GetDevice(ID3D11SamplerState
*iface
,
1212 ID3D11Device
**device
)
1214 struct d3d_sampler_state
*state
= impl_from_ID3D11SamplerState(iface
);
1216 TRACE("iface %p, device %p.\n", iface
, device
);
1218 *device
= state
->device
;
1219 ID3D11Device_AddRef(*device
);
1222 static HRESULT STDMETHODCALLTYPE
d3d11_sampler_state_GetPrivateData(ID3D11SamplerState
*iface
,
1223 REFGUID guid
, UINT
*data_size
, void *data
)
1225 struct d3d_sampler_state
*state
= impl_from_ID3D11SamplerState(iface
);
1227 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
1229 return d3d_get_private_data(&state
->private_store
, guid
, data_size
, data
);
1232 static HRESULT STDMETHODCALLTYPE
d3d11_sampler_state_SetPrivateData(ID3D11SamplerState
*iface
,
1233 REFGUID guid
, UINT data_size
, const void *data
)
1235 struct d3d_sampler_state
*state
= impl_from_ID3D11SamplerState(iface
);
1237 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
1239 return d3d_set_private_data(&state
->private_store
, guid
, data_size
, data
);
1242 static HRESULT STDMETHODCALLTYPE
d3d11_sampler_state_SetPrivateDataInterface(ID3D11SamplerState
*iface
,
1243 REFGUID guid
, const IUnknown
*data
)
1245 struct d3d_sampler_state
*state
= impl_from_ID3D11SamplerState(iface
);
1247 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
1249 return d3d_set_private_data_interface(&state
->private_store
, guid
, data
);
1252 static void STDMETHODCALLTYPE
d3d11_sampler_state_GetDesc(ID3D11SamplerState
*iface
,
1253 D3D11_SAMPLER_DESC
*desc
)
1255 struct d3d_sampler_state
*state
= impl_from_ID3D11SamplerState(iface
);
1257 TRACE("iface %p, desc %p.\n", iface
, desc
);
1259 *desc
= state
->desc
;
1262 static const struct ID3D11SamplerStateVtbl d3d11_sampler_state_vtbl
=
1264 /* IUnknown methods */
1265 d3d11_sampler_state_QueryInterface
,
1266 d3d11_sampler_state_AddRef
,
1267 d3d11_sampler_state_Release
,
1268 /* ID3D11DeviceChild methods */
1269 d3d11_sampler_state_GetDevice
,
1270 d3d11_sampler_state_GetPrivateData
,
1271 d3d11_sampler_state_SetPrivateData
,
1272 d3d11_sampler_state_SetPrivateDataInterface
,
1273 /* ID3D11SamplerState methods */
1274 d3d11_sampler_state_GetDesc
,
1277 /* ID3D10SamplerState methods */
1279 static inline struct d3d_sampler_state
*impl_from_ID3D10SamplerState(ID3D10SamplerState
*iface
)
1281 return CONTAINING_RECORD(iface
, struct d3d_sampler_state
, ID3D10SamplerState_iface
);
1284 /* IUnknown methods */
1286 static HRESULT STDMETHODCALLTYPE
d3d10_sampler_state_QueryInterface(ID3D10SamplerState
*iface
,
1287 REFIID riid
, void **object
)
1289 struct d3d_sampler_state
*state
= impl_from_ID3D10SamplerState(iface
);
1291 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
1293 return d3d11_sampler_state_QueryInterface(&state
->ID3D11SamplerState_iface
, riid
, object
);
1296 static ULONG STDMETHODCALLTYPE
d3d10_sampler_state_AddRef(ID3D10SamplerState
*iface
)
1298 struct d3d_sampler_state
*state
= impl_from_ID3D10SamplerState(iface
);
1300 TRACE("iface %p.\n", iface
);
1302 return d3d11_sampler_state_AddRef(&state
->ID3D11SamplerState_iface
);
1305 static ULONG STDMETHODCALLTYPE
d3d10_sampler_state_Release(ID3D10SamplerState
*iface
)
1307 struct d3d_sampler_state
*state
= impl_from_ID3D10SamplerState(iface
);
1309 TRACE("iface %p.\n", iface
);
1311 return d3d11_sampler_state_Release(&state
->ID3D11SamplerState_iface
);
1314 /* ID3D10DeviceChild methods */
1316 static void STDMETHODCALLTYPE
d3d10_sampler_state_GetDevice(ID3D10SamplerState
*iface
, ID3D10Device
**device
)
1318 struct d3d_sampler_state
*state
= impl_from_ID3D10SamplerState(iface
);
1320 TRACE("iface %p, device %p.\n", iface
, device
);
1322 ID3D11Device_QueryInterface(state
->device
, &IID_ID3D10Device
, (void **)device
);
1325 static HRESULT STDMETHODCALLTYPE
d3d10_sampler_state_GetPrivateData(ID3D10SamplerState
*iface
,
1326 REFGUID guid
, UINT
*data_size
, void *data
)
1328 struct d3d_sampler_state
*state
= impl_from_ID3D10SamplerState(iface
);
1330 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
1331 iface
, debugstr_guid(guid
), data_size
, data
);
1333 return d3d_get_private_data(&state
->private_store
, guid
, data_size
, data
);
1336 static HRESULT STDMETHODCALLTYPE
d3d10_sampler_state_SetPrivateData(ID3D10SamplerState
*iface
,
1337 REFGUID guid
, UINT data_size
, const void *data
)
1339 struct d3d_sampler_state
*state
= impl_from_ID3D10SamplerState(iface
);
1341 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
1342 iface
, debugstr_guid(guid
), data_size
, data
);
1344 return d3d_set_private_data(&state
->private_store
, guid
, data_size
, data
);
1347 static HRESULT STDMETHODCALLTYPE
d3d10_sampler_state_SetPrivateDataInterface(ID3D10SamplerState
*iface
,
1348 REFGUID guid
, const IUnknown
*data
)
1350 struct d3d_sampler_state
*state
= impl_from_ID3D10SamplerState(iface
);
1352 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
1354 return d3d_set_private_data_interface(&state
->private_store
, guid
, data
);
1357 /* ID3D10SamplerState methods */
1359 static void STDMETHODCALLTYPE
d3d10_sampler_state_GetDesc(ID3D10SamplerState
*iface
,
1360 D3D10_SAMPLER_DESC
*desc
)
1362 struct d3d_sampler_state
*state
= impl_from_ID3D10SamplerState(iface
);
1364 TRACE("iface %p, desc %p.\n", iface
, desc
);
1366 memcpy(desc
, &state
->desc
, sizeof(*desc
));
1369 static const struct ID3D10SamplerStateVtbl d3d10_sampler_state_vtbl
=
1371 /* IUnknown methods */
1372 d3d10_sampler_state_QueryInterface
,
1373 d3d10_sampler_state_AddRef
,
1374 d3d10_sampler_state_Release
,
1375 /* ID3D10DeviceChild methods */
1376 d3d10_sampler_state_GetDevice
,
1377 d3d10_sampler_state_GetPrivateData
,
1378 d3d10_sampler_state_SetPrivateData
,
1379 d3d10_sampler_state_SetPrivateDataInterface
,
1380 /* ID3D10SamplerState methods */
1381 d3d10_sampler_state_GetDesc
,
1384 static void STDMETHODCALLTYPE
d3d_sampler_wined3d_object_destroyed(void *parent
)
1386 struct d3d_sampler_state
*state
= parent
;
1387 struct d3d_device
*device
= impl_from_ID3D11Device(state
->device
);
1389 wine_rb_remove(&device
->sampler_states
, &state
->entry
);
1390 wined3d_private_store_cleanup(&state
->private_store
);
1391 HeapFree(GetProcessHeap(), 0, parent
);
1394 static const struct wined3d_parent_ops d3d_sampler_wined3d_parent_ops
=
1396 d3d_sampler_wined3d_object_destroyed
,
1399 static enum wined3d_texture_address
wined3d_texture_address_from_d3d11(enum D3D11_TEXTURE_ADDRESS_MODE t
)
1401 return (enum wined3d_texture_address
)t
;
1404 static enum wined3d_texture_filter_type
wined3d_texture_filter_mip_from_d3d11(enum D3D11_FILTER f
)
1406 if (D3D11_DECODE_MIP_FILTER(f
) == D3D11_FILTER_TYPE_LINEAR
)
1407 return WINED3D_TEXF_LINEAR
;
1408 return WINED3D_TEXF_POINT
;
1411 static enum wined3d_texture_filter_type
wined3d_texture_filter_mag_from_d3d11(enum D3D11_FILTER f
)
1413 if (D3D11_DECODE_MAG_FILTER(f
) == D3D11_FILTER_TYPE_LINEAR
)
1414 return WINED3D_TEXF_LINEAR
;
1415 return WINED3D_TEXF_POINT
;
1418 static enum wined3d_texture_filter_type
wined3d_texture_filter_min_from_d3d11(enum D3D11_FILTER f
)
1420 if (D3D11_DECODE_MIN_FILTER(f
) == D3D11_FILTER_TYPE_LINEAR
)
1421 return WINED3D_TEXF_LINEAR
;
1422 return WINED3D_TEXF_POINT
;
1425 static BOOL
wined3d_texture_compare_from_d3d11(enum D3D11_FILTER f
)
1427 return D3D11_DECODE_IS_COMPARISON_FILTER(f
);
1430 static enum wined3d_cmp_func
wined3d_cmp_func_from_d3d11(D3D11_COMPARISON_FUNC f
)
1432 return (enum wined3d_cmp_func
)f
;
1435 static HRESULT
d3d_sampler_state_init(struct d3d_sampler_state
*state
, struct d3d_device
*device
,
1436 const D3D11_SAMPLER_DESC
*desc
)
1438 struct wined3d_sampler_desc wined3d_desc
;
1441 state
->ID3D11SamplerState_iface
.lpVtbl
= &d3d11_sampler_state_vtbl
;
1442 state
->ID3D10SamplerState_iface
.lpVtbl
= &d3d10_sampler_state_vtbl
;
1443 state
->refcount
= 1;
1444 wined3d_private_store_init(&state
->private_store
);
1445 state
->desc
= *desc
;
1447 wined3d_desc
.address_u
= wined3d_texture_address_from_d3d11(desc
->AddressU
);
1448 wined3d_desc
.address_v
= wined3d_texture_address_from_d3d11(desc
->AddressV
);
1449 wined3d_desc
.address_w
= wined3d_texture_address_from_d3d11(desc
->AddressW
);
1450 memcpy(wined3d_desc
.border_color
, desc
->BorderColor
, sizeof(wined3d_desc
.border_color
));
1451 wined3d_desc
.mag_filter
= wined3d_texture_filter_mag_from_d3d11(desc
->Filter
);
1452 wined3d_desc
.min_filter
= wined3d_texture_filter_min_from_d3d11(desc
->Filter
);
1453 wined3d_desc
.mip_filter
= wined3d_texture_filter_mip_from_d3d11(desc
->Filter
);
1454 wined3d_desc
.lod_bias
= desc
->MipLODBias
;
1455 wined3d_desc
.min_lod
= desc
->MinLOD
;
1456 wined3d_desc
.max_lod
= desc
->MaxLOD
;
1457 wined3d_desc
.mip_base_level
= 0;
1458 wined3d_desc
.max_anisotropy
= D3D11_DECODE_IS_ANISOTROPIC_FILTER(desc
->Filter
) ? desc
->MaxAnisotropy
: 1;
1459 wined3d_desc
.compare
= wined3d_texture_compare_from_d3d11(desc
->Filter
);
1460 wined3d_desc
.comparison_func
= wined3d_cmp_func_from_d3d11(desc
->ComparisonFunc
);
1461 wined3d_desc
.srgb_decode
= TRUE
;
1463 if (wine_rb_put(&device
->sampler_states
, desc
, &state
->entry
) == -1)
1465 ERR("Failed to insert sampler state entry.\n");
1466 wined3d_private_store_cleanup(&state
->private_store
);
1470 /* We cannot fail after creating a wined3d_sampler object. It would lead to
1472 if (FAILED(hr
= wined3d_sampler_create(device
->wined3d_device
, &wined3d_desc
,
1473 state
, &d3d_sampler_wined3d_parent_ops
, &state
->wined3d_sampler
)))
1475 WARN("Failed to create wined3d sampler, hr %#x.\n", hr
);
1476 wined3d_private_store_cleanup(&state
->private_store
);
1477 wine_rb_remove(&device
->sampler_states
, &state
->entry
);
1481 state
->device
= &device
->ID3D11Device_iface
;
1482 ID3D11Device_AddRef(state
->device
);
1487 HRESULT
d3d_sampler_state_create(struct d3d_device
*device
, const D3D11_SAMPLER_DESC
*desc
,
1488 struct d3d_sampler_state
**state
)
1490 D3D11_SAMPLER_DESC normalized_desc
;
1491 struct d3d_sampler_state
*object
;
1492 struct wine_rb_entry
*entry
;
1496 return E_INVALIDARG
;
1498 normalized_desc
= *desc
;
1499 if (!D3D11_DECODE_IS_ANISOTROPIC_FILTER(normalized_desc
.Filter
))
1500 normalized_desc
.MaxAnisotropy
= 0;
1501 if (!D3D11_DECODE_IS_COMPARISON_FILTER(normalized_desc
.Filter
))
1502 normalized_desc
.ComparisonFunc
= D3D11_COMPARISON_NEVER
;
1503 if (normalized_desc
.AddressU
!= D3D11_TEXTURE_ADDRESS_BORDER
1504 && normalized_desc
.AddressV
!= D3D11_TEXTURE_ADDRESS_BORDER
1505 && normalized_desc
.AddressW
!= D3D11_TEXTURE_ADDRESS_BORDER
)
1506 memset(&normalized_desc
.BorderColor
, 0, sizeof(normalized_desc
.BorderColor
));
1508 wined3d_mutex_lock();
1509 if ((entry
= wine_rb_get(&device
->sampler_states
, &normalized_desc
)))
1511 object
= WINE_RB_ENTRY_VALUE(entry
, struct d3d_sampler_state
, entry
);
1513 TRACE("Returning existing sampler state %p.\n", object
);
1514 ID3D11SamplerState_AddRef(&object
->ID3D11SamplerState_iface
);
1516 wined3d_mutex_unlock();
1521 if (!(object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*object
))))
1523 wined3d_mutex_unlock();
1524 return E_OUTOFMEMORY
;
1527 hr
= d3d_sampler_state_init(object
, device
, &normalized_desc
);
1528 wined3d_mutex_unlock();
1531 WARN("Failed to initialize sampler state, hr %#x.\n", hr
);
1532 HeapFree(GetProcessHeap(), 0, object
);
1536 TRACE("Created sampler state %p.\n", object
);
1542 struct d3d_sampler_state
*unsafe_impl_from_ID3D11SamplerState(ID3D11SamplerState
*iface
)
1546 assert(iface
->lpVtbl
== &d3d11_sampler_state_vtbl
);
1548 return impl_from_ID3D11SamplerState(iface
);
1551 struct d3d_sampler_state
*unsafe_impl_from_ID3D10SamplerState(ID3D10SamplerState
*iface
)
1555 assert(iface
->lpVtbl
== &d3d10_sampler_state_vtbl
);
1557 return impl_from_ID3D10SamplerState(iface
);