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
20 #include "d3d11_private.h"
22 WINE_DEFAULT_DEBUG_CHANNEL(d3d11
);
24 /* ID3D11BlendState methods */
26 static HRESULT STDMETHODCALLTYPE
d3d11_blend_state_QueryInterface(ID3D11BlendState
*iface
,
27 REFIID riid
, void **object
)
29 struct d3d_blend_state
*state
= impl_from_ID3D11BlendState(iface
);
31 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
33 if (IsEqualGUID(riid
, &IID_ID3D11BlendState
)
34 || IsEqualGUID(riid
, &IID_ID3D11DeviceChild
)
35 || IsEqualGUID(riid
, &IID_IUnknown
))
37 ID3D11BlendState_AddRef(iface
);
42 if (IsEqualGUID(riid
, &IID_ID3D10BlendState1
)
43 || IsEqualGUID(riid
, &IID_ID3D10BlendState
)
44 || IsEqualGUID(riid
, &IID_ID3D10DeviceChild
))
46 ID3D10BlendState1_AddRef(&state
->ID3D10BlendState1_iface
);
47 *object
= &state
->ID3D10BlendState1_iface
;
51 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
57 static ULONG STDMETHODCALLTYPE
d3d11_blend_state_AddRef(ID3D11BlendState
*iface
)
59 struct d3d_blend_state
*state
= impl_from_ID3D11BlendState(iface
);
60 ULONG refcount
= InterlockedIncrement(&state
->refcount
);
62 TRACE("%p increasing refcount to %u.\n", state
, refcount
);
66 ID3D11Device2_AddRef(state
->device
);
68 wined3d_blend_state_incref(state
->wined3d_state
);
69 wined3d_mutex_unlock();
75 static ULONG STDMETHODCALLTYPE
d3d11_blend_state_Release(ID3D11BlendState
*iface
)
77 struct d3d_blend_state
*state
= impl_from_ID3D11BlendState(iface
);
78 ULONG refcount
= InterlockedDecrement(&state
->refcount
);
80 TRACE("%p decreasing refcount to %u.\n", state
, refcount
);
84 ID3D11Device2
*device
= state
->device
;
87 wined3d_blend_state_decref(state
->wined3d_state
);
88 wined3d_mutex_unlock();
90 ID3D11Device2_Release(device
);
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
= (ID3D11Device
*)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 ID3D11Device2_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 D3D10_BLEND
d3d10_blend_from_d3d11(D3D11_BLEND factor
)
245 return (D3D10_BLEND
)factor
;
248 static D3D10_BLEND_OP
d3d10_blend_op_from_d3d11(D3D11_BLEND_OP op
)
250 return (D3D10_BLEND_OP
)op
;
253 static void STDMETHODCALLTYPE
d3d10_blend_state_GetDesc(ID3D10BlendState1
*iface
, D3D10_BLEND_DESC
*desc
)
255 struct d3d_blend_state
*state
= impl_from_ID3D10BlendState(iface
);
256 const D3D11_BLEND_DESC
*d3d11_desc
= &state
->desc
;
259 TRACE("iface %p, desc %p.\n", iface
, desc
);
261 desc
->AlphaToCoverageEnable
= d3d11_desc
->AlphaToCoverageEnable
;
262 desc
->SrcBlend
= d3d10_blend_from_d3d11(d3d11_desc
->RenderTarget
[0].SrcBlend
);
263 desc
->DestBlend
= d3d10_blend_from_d3d11(d3d11_desc
->RenderTarget
[0].DestBlend
);
264 desc
->BlendOp
= d3d10_blend_op_from_d3d11(d3d11_desc
->RenderTarget
[0].BlendOp
);
265 desc
->SrcBlendAlpha
= d3d10_blend_from_d3d11(d3d11_desc
->RenderTarget
[0].SrcBlendAlpha
);
266 desc
->DestBlendAlpha
= d3d10_blend_from_d3d11(d3d11_desc
->RenderTarget
[0].DestBlendAlpha
);
267 desc
->BlendOpAlpha
= d3d10_blend_op_from_d3d11(d3d11_desc
->RenderTarget
[0].BlendOpAlpha
);
268 for (i
= 0; i
< D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT
; ++i
)
270 desc
->BlendEnable
[i
] = d3d11_desc
->RenderTarget
[i
].BlendEnable
;
271 desc
->RenderTargetWriteMask
[i
] = d3d11_desc
->RenderTarget
[i
].RenderTargetWriteMask
;
275 static void STDMETHODCALLTYPE
d3d10_blend_state_GetDesc1(ID3D10BlendState1
*iface
, D3D10_BLEND_DESC1
*desc
)
277 struct d3d_blend_state
*state
= impl_from_ID3D10BlendState(iface
);
279 TRACE("iface %p, desc %p.\n", iface
, desc
);
281 memcpy(desc
, &state
->desc
, sizeof(*desc
));
284 static const struct ID3D10BlendState1Vtbl d3d10_blend_state_vtbl
=
286 /* IUnknown methods */
287 d3d10_blend_state_QueryInterface
,
288 d3d10_blend_state_AddRef
,
289 d3d10_blend_state_Release
,
290 /* ID3D10DeviceChild methods */
291 d3d10_blend_state_GetDevice
,
292 d3d10_blend_state_GetPrivateData
,
293 d3d10_blend_state_SetPrivateData
,
294 d3d10_blend_state_SetPrivateDataInterface
,
295 /* ID3D10BlendState methods */
296 d3d10_blend_state_GetDesc
,
297 /* ID3D10BlendState1 methods */
298 d3d10_blend_state_GetDesc1
,
301 static void STDMETHODCALLTYPE
d3d_blend_state_wined3d_object_destroyed(void *parent
)
303 struct d3d_blend_state
*state
= parent
;
304 struct d3d_device
*device
= impl_from_ID3D11Device2(state
->device
);
306 wine_rb_remove(&device
->blend_states
, &state
->entry
);
307 wined3d_private_store_cleanup(&state
->private_store
);
311 static const struct wined3d_parent_ops d3d_blend_state_wined3d_parent_ops
=
313 d3d_blend_state_wined3d_object_destroyed
,
316 static enum wined3d_blend
wined3d_blend_from_d3d11(D3D11_BLEND factor
)
318 return (enum wined3d_blend
)factor
;
321 static enum wined3d_blend_op
wined3d_blend_op_from_d3d11(D3D11_BLEND_OP op
)
323 return (enum wined3d_blend_op
)op
;
326 HRESULT
d3d_blend_state_create(struct d3d_device
*device
, const D3D11_BLEND_DESC
*desc
,
327 struct d3d_blend_state
**state
)
329 struct wined3d_blend_state_desc wined3d_desc
;
330 struct d3d_blend_state
*object
;
331 struct wine_rb_entry
*entry
;
332 D3D11_BLEND_DESC tmp_desc
;
339 /* D3D11_RENDER_TARGET_BLEND_DESC has a hole, which is a problem because we use
340 * D3D11_BLEND_DESC as a key in the rbtree. */
341 memset(&tmp_desc
, 0, sizeof(tmp_desc
));
342 tmp_desc
.AlphaToCoverageEnable
= desc
->AlphaToCoverageEnable
;
343 tmp_desc
.IndependentBlendEnable
= desc
->IndependentBlendEnable
;
344 for (i
= 0; i
< D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT
; ++i
)
346 j
= desc
->IndependentBlendEnable
? i
: 0;
347 tmp_desc
.RenderTarget
[i
].BlendEnable
= desc
->RenderTarget
[j
].BlendEnable
;
348 if (tmp_desc
.RenderTarget
[i
].BlendEnable
)
350 tmp_desc
.RenderTarget
[i
].SrcBlend
= desc
->RenderTarget
[j
].SrcBlend
;
351 tmp_desc
.RenderTarget
[i
].DestBlend
= desc
->RenderTarget
[j
].DestBlend
;
352 tmp_desc
.RenderTarget
[i
].BlendOp
= desc
->RenderTarget
[j
].BlendOp
;
353 tmp_desc
.RenderTarget
[i
].SrcBlendAlpha
= desc
->RenderTarget
[j
].SrcBlendAlpha
;
354 tmp_desc
.RenderTarget
[i
].DestBlendAlpha
= desc
->RenderTarget
[j
].DestBlendAlpha
;
355 tmp_desc
.RenderTarget
[i
].BlendOpAlpha
= desc
->RenderTarget
[j
].BlendOpAlpha
;
359 tmp_desc
.RenderTarget
[i
].SrcBlend
= D3D11_BLEND_ONE
;
360 tmp_desc
.RenderTarget
[i
].DestBlend
= D3D11_BLEND_ZERO
;
361 tmp_desc
.RenderTarget
[i
].BlendOp
= D3D11_BLEND_OP_ADD
;
362 tmp_desc
.RenderTarget
[i
].SrcBlendAlpha
= D3D11_BLEND_ONE
;
363 tmp_desc
.RenderTarget
[i
].DestBlendAlpha
= D3D11_BLEND_ZERO
;
364 tmp_desc
.RenderTarget
[i
].BlendOpAlpha
= D3D11_BLEND_OP_ADD
;
366 tmp_desc
.RenderTarget
[i
].RenderTargetWriteMask
= desc
->RenderTarget
[j
].RenderTargetWriteMask
;
369 wined3d_mutex_lock();
370 if ((entry
= wine_rb_get(&device
->blend_states
, &tmp_desc
)))
372 object
= WINE_RB_ENTRY_VALUE(entry
, struct d3d_blend_state
, entry
);
374 TRACE("Returning existing blend state %p.\n", object
);
375 ID3D11BlendState_AddRef(&object
->ID3D11BlendState_iface
);
377 wined3d_mutex_unlock();
382 if (!(object
= heap_alloc_zero(sizeof(*object
))))
384 wined3d_mutex_unlock();
385 return E_OUTOFMEMORY
;
388 object
->ID3D11BlendState_iface
.lpVtbl
= &d3d11_blend_state_vtbl
;
389 object
->ID3D10BlendState1_iface
.lpVtbl
= &d3d10_blend_state_vtbl
;
390 object
->refcount
= 1;
391 wined3d_private_store_init(&object
->private_store
);
392 object
->desc
= tmp_desc
;
394 if (wine_rb_put(&device
->blend_states
, &tmp_desc
, &object
->entry
) == -1)
396 ERR("Failed to insert blend state entry.\n");
397 wined3d_private_store_cleanup(&object
->private_store
);
399 wined3d_mutex_unlock();
403 wined3d_desc
.alpha_to_coverage
= desc
->AlphaToCoverageEnable
;
404 wined3d_desc
.independent
= desc
->IndependentBlendEnable
;
405 for (i
= 0; i
< D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT
; ++i
)
407 wined3d_desc
.rt
[i
].enable
= desc
->RenderTarget
[i
].BlendEnable
;
408 wined3d_desc
.rt
[i
].src
= wined3d_blend_from_d3d11(desc
->RenderTarget
[i
].SrcBlend
);
409 wined3d_desc
.rt
[i
].dst
= wined3d_blend_from_d3d11(desc
->RenderTarget
[i
].DestBlend
);
410 wined3d_desc
.rt
[i
].op
= wined3d_blend_op_from_d3d11(desc
->RenderTarget
[i
].BlendOp
);
411 wined3d_desc
.rt
[i
].src_alpha
= wined3d_blend_from_d3d11(desc
->RenderTarget
[i
].SrcBlendAlpha
);
412 wined3d_desc
.rt
[i
].dst_alpha
= wined3d_blend_from_d3d11(desc
->RenderTarget
[i
].DestBlendAlpha
);
413 wined3d_desc
.rt
[i
].op_alpha
= wined3d_blend_op_from_d3d11(desc
->RenderTarget
[i
].BlendOpAlpha
);
414 wined3d_desc
.rt
[i
].writemask
= desc
->RenderTarget
[i
].RenderTargetWriteMask
;
417 /* We cannot fail after creating a wined3d_blend_state object. It
418 * would lead to double free. */
419 if (FAILED(hr
= wined3d_blend_state_create(device
->wined3d_device
, &wined3d_desc
,
420 object
, &d3d_blend_state_wined3d_parent_ops
, &object
->wined3d_state
)))
422 WARN("Failed to create wined3d blend state, hr %#x.\n", hr
);
423 wined3d_private_store_cleanup(&object
->private_store
);
424 wine_rb_remove(&device
->blend_states
, &object
->entry
);
426 wined3d_mutex_unlock();
429 wined3d_mutex_unlock();
431 ID3D11Device2_AddRef(object
->device
= &device
->ID3D11Device2_iface
);
433 TRACE("Created blend state %p.\n", object
);
439 struct d3d_blend_state
*unsafe_impl_from_ID3D11BlendState(ID3D11BlendState
*iface
)
443 assert(iface
->lpVtbl
== &d3d11_blend_state_vtbl
);
445 return impl_from_ID3D11BlendState(iface
);
448 struct d3d_blend_state
*unsafe_impl_from_ID3D10BlendState(ID3D10BlendState
*iface
)
452 assert(iface
->lpVtbl
== (ID3D10BlendStateVtbl
*)&d3d10_blend_state_vtbl
);
454 return impl_from_ID3D10BlendState((ID3D10BlendState1
*)iface
);
457 /* ID3D11DepthStencilState methods */
459 static HRESULT STDMETHODCALLTYPE
d3d11_depthstencil_state_QueryInterface(ID3D11DepthStencilState
*iface
,
460 REFIID riid
, void **object
)
462 struct d3d_depthstencil_state
*state
= impl_from_ID3D11DepthStencilState(iface
);
464 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
466 if (IsEqualGUID(riid
, &IID_ID3D11DepthStencilState
)
467 || IsEqualGUID(riid
, &IID_ID3D11DeviceChild
)
468 || IsEqualGUID(riid
, &IID_IUnknown
))
470 ID3D11DepthStencilState_AddRef(iface
);
475 if (IsEqualGUID(riid
, &IID_ID3D10DepthStencilState
)
476 || IsEqualGUID(riid
, &IID_ID3D10DeviceChild
))
478 ID3D10DepthStencilState_AddRef(&state
->ID3D10DepthStencilState_iface
);
479 *object
= &state
->ID3D10DepthStencilState_iface
;
483 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
486 return E_NOINTERFACE
;
489 static ULONG STDMETHODCALLTYPE
d3d11_depthstencil_state_AddRef(ID3D11DepthStencilState
*iface
)
491 struct d3d_depthstencil_state
*state
= impl_from_ID3D11DepthStencilState(iface
);
492 ULONG refcount
= InterlockedIncrement(&state
->refcount
);
494 TRACE("%p increasing refcount to %u.\n", state
, refcount
);
498 ID3D11Device2_AddRef(state
->device
);
499 wined3d_mutex_lock();
500 wined3d_depth_stencil_state_incref(state
->wined3d_state
);
501 wined3d_mutex_unlock();
507 static ULONG STDMETHODCALLTYPE
d3d11_depthstencil_state_Release(ID3D11DepthStencilState
*iface
)
509 struct d3d_depthstencil_state
*state
= impl_from_ID3D11DepthStencilState(iface
);
510 ULONG refcount
= InterlockedDecrement(&state
->refcount
);
512 TRACE("%p decreasing refcount to %u.\n", state
, refcount
);
516 ID3D11Device2
*device
= state
->device
;
518 wined3d_mutex_lock();
519 wined3d_depth_stencil_state_decref(state
->wined3d_state
);
520 wined3d_mutex_unlock();
521 ID3D11Device2_Release(device
);
527 static void STDMETHODCALLTYPE
d3d11_depthstencil_state_GetDevice(ID3D11DepthStencilState
*iface
,
528 ID3D11Device
**device
)
530 struct d3d_depthstencil_state
*state
= impl_from_ID3D11DepthStencilState(iface
);
532 TRACE("iface %p, device %p.\n", iface
, device
);
534 *device
= (ID3D11Device
*)state
->device
;
535 ID3D11Device_AddRef(*device
);
538 static HRESULT STDMETHODCALLTYPE
d3d11_depthstencil_state_GetPrivateData(ID3D11DepthStencilState
*iface
,
539 REFGUID guid
, UINT
*data_size
, void *data
)
541 struct d3d_depthstencil_state
*state
= impl_from_ID3D11DepthStencilState(iface
);
543 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
545 return d3d_get_private_data(&state
->private_store
, guid
, data_size
, data
);
548 static HRESULT STDMETHODCALLTYPE
d3d11_depthstencil_state_SetPrivateData(ID3D11DepthStencilState
*iface
,
549 REFGUID guid
, UINT data_size
, const void *data
)
551 struct d3d_depthstencil_state
*state
= impl_from_ID3D11DepthStencilState(iface
);
553 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
555 return d3d_set_private_data(&state
->private_store
, guid
, data_size
, data
);
558 static HRESULT STDMETHODCALLTYPE
d3d11_depthstencil_state_SetPrivateDataInterface(ID3D11DepthStencilState
*iface
,
559 REFGUID guid
, const IUnknown
*data
)
561 struct d3d_depthstencil_state
*state
= impl_from_ID3D11DepthStencilState(iface
);
563 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
565 return d3d_set_private_data_interface(&state
->private_store
, guid
, data
);
568 static void STDMETHODCALLTYPE
d3d11_depthstencil_state_GetDesc(ID3D11DepthStencilState
*iface
,
569 D3D11_DEPTH_STENCIL_DESC
*desc
)
571 struct d3d_depthstencil_state
*state
= impl_from_ID3D11DepthStencilState(iface
);
573 TRACE("iface %p, desc %p.\n", iface
, desc
);
578 static const struct ID3D11DepthStencilStateVtbl d3d11_depthstencil_state_vtbl
=
580 /* IUnknown methods */
581 d3d11_depthstencil_state_QueryInterface
,
582 d3d11_depthstencil_state_AddRef
,
583 d3d11_depthstencil_state_Release
,
584 /* ID3D11DeviceChild methods */
585 d3d11_depthstencil_state_GetDevice
,
586 d3d11_depthstencil_state_GetPrivateData
,
587 d3d11_depthstencil_state_SetPrivateData
,
588 d3d11_depthstencil_state_SetPrivateDataInterface
,
589 /* ID3D11DepthStencilState methods */
590 d3d11_depthstencil_state_GetDesc
,
593 /* ID3D10DepthStencilState methods */
595 static inline struct d3d_depthstencil_state
*impl_from_ID3D10DepthStencilState(ID3D10DepthStencilState
*iface
)
597 return CONTAINING_RECORD(iface
, struct d3d_depthstencil_state
, ID3D10DepthStencilState_iface
);
600 /* IUnknown methods */
602 static HRESULT STDMETHODCALLTYPE
d3d10_depthstencil_state_QueryInterface(ID3D10DepthStencilState
*iface
,
603 REFIID riid
, void **object
)
605 struct d3d_depthstencil_state
*state
= impl_from_ID3D10DepthStencilState(iface
);
607 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
609 return d3d11_depthstencil_state_QueryInterface(&state
->ID3D11DepthStencilState_iface
, riid
, object
);
612 static ULONG STDMETHODCALLTYPE
d3d10_depthstencil_state_AddRef(ID3D10DepthStencilState
*iface
)
614 struct d3d_depthstencil_state
*state
= impl_from_ID3D10DepthStencilState(iface
);
616 TRACE("iface %p.\n", iface
);
618 return d3d11_depthstencil_state_AddRef(&state
->ID3D11DepthStencilState_iface
);
621 static ULONG STDMETHODCALLTYPE
d3d10_depthstencil_state_Release(ID3D10DepthStencilState
*iface
)
623 struct d3d_depthstencil_state
*state
= impl_from_ID3D10DepthStencilState(iface
);
625 TRACE("iface %p.\n", iface
);
627 return d3d11_depthstencil_state_Release(&state
->ID3D11DepthStencilState_iface
);
630 /* ID3D10DeviceChild methods */
632 static void STDMETHODCALLTYPE
d3d10_depthstencil_state_GetDevice(ID3D10DepthStencilState
*iface
, ID3D10Device
**device
)
634 struct d3d_depthstencil_state
*state
= impl_from_ID3D10DepthStencilState(iface
);
636 TRACE("iface %p, device %p.\n", iface
, device
);
638 ID3D11Device2_QueryInterface(state
->device
, &IID_ID3D10Device
, (void **)device
);
641 static HRESULT STDMETHODCALLTYPE
d3d10_depthstencil_state_GetPrivateData(ID3D10DepthStencilState
*iface
,
642 REFGUID guid
, UINT
*data_size
, void *data
)
644 struct d3d_depthstencil_state
*state
= impl_from_ID3D10DepthStencilState(iface
);
646 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
647 iface
, debugstr_guid(guid
), data_size
, data
);
649 return d3d_get_private_data(&state
->private_store
, guid
, data_size
, data
);
652 static HRESULT STDMETHODCALLTYPE
d3d10_depthstencil_state_SetPrivateData(ID3D10DepthStencilState
*iface
,
653 REFGUID guid
, UINT data_size
, const void *data
)
655 struct d3d_depthstencil_state
*state
= impl_from_ID3D10DepthStencilState(iface
);
657 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
658 iface
, debugstr_guid(guid
), data_size
, data
);
660 return d3d_set_private_data(&state
->private_store
, guid
, data_size
, data
);
663 static HRESULT STDMETHODCALLTYPE
d3d10_depthstencil_state_SetPrivateDataInterface(ID3D10DepthStencilState
*iface
,
664 REFGUID guid
, const IUnknown
*data
)
666 struct d3d_depthstencil_state
*state
= impl_from_ID3D10DepthStencilState(iface
);
668 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
670 return d3d_set_private_data_interface(&state
->private_store
, guid
, data
);
673 /* ID3D10DepthStencilState methods */
675 static void STDMETHODCALLTYPE
d3d10_depthstencil_state_GetDesc(ID3D10DepthStencilState
*iface
,
676 D3D10_DEPTH_STENCIL_DESC
*desc
)
678 struct d3d_depthstencil_state
*state
= impl_from_ID3D10DepthStencilState(iface
);
680 TRACE("iface %p, desc %p.\n", iface
, desc
);
682 memcpy(desc
, &state
->desc
, sizeof(*desc
));
685 static const struct ID3D10DepthStencilStateVtbl d3d10_depthstencil_state_vtbl
=
687 /* IUnknown methods */
688 d3d10_depthstencil_state_QueryInterface
,
689 d3d10_depthstencil_state_AddRef
,
690 d3d10_depthstencil_state_Release
,
691 /* ID3D10DeviceChild methods */
692 d3d10_depthstencil_state_GetDevice
,
693 d3d10_depthstencil_state_GetPrivateData
,
694 d3d10_depthstencil_state_SetPrivateData
,
695 d3d10_depthstencil_state_SetPrivateDataInterface
,
696 /* ID3D10DepthStencilState methods */
697 d3d10_depthstencil_state_GetDesc
,
700 static void STDMETHODCALLTYPE
d3d_depthstencil_state_wined3d_object_destroyed(void *parent
)
702 struct d3d_depthstencil_state
*state
= parent
;
703 struct d3d_device
*device
= impl_from_ID3D11Device2(state
->device
);
705 wine_rb_remove(&device
->depthstencil_states
, &state
->entry
);
706 wined3d_private_store_cleanup(&state
->private_store
);
710 static const struct wined3d_parent_ops d3d_depthstencil_state_wined3d_parent_ops
=
712 d3d_depthstencil_state_wined3d_object_destroyed
,
715 HRESULT
d3d_depthstencil_state_create(struct d3d_device
*device
, const D3D11_DEPTH_STENCIL_DESC
*desc
,
716 struct d3d_depthstencil_state
**state
)
718 struct wined3d_depth_stencil_state_desc wined3d_desc
;
719 struct d3d_depthstencil_state
*object
;
720 D3D11_DEPTH_STENCIL_DESC tmp_desc
;
721 struct wine_rb_entry
*entry
;
727 /* D3D11_DEPTH_STENCIL_DESC has a hole, which is a problem because we use
728 * it as a key in the rbtree. */
729 memset(&tmp_desc
, 0, sizeof(tmp_desc
));
730 tmp_desc
.DepthEnable
= desc
->DepthEnable
;
731 if (desc
->DepthEnable
)
733 tmp_desc
.DepthWriteMask
= desc
->DepthWriteMask
;
734 tmp_desc
.DepthFunc
= desc
->DepthFunc
;
738 tmp_desc
.DepthWriteMask
= D3D11_DEPTH_WRITE_MASK_ALL
;
739 tmp_desc
.DepthFunc
= D3D11_COMPARISON_LESS
;
741 tmp_desc
.StencilEnable
= desc
->StencilEnable
;
742 if (desc
->StencilEnable
)
744 tmp_desc
.StencilReadMask
= desc
->StencilReadMask
;
745 tmp_desc
.StencilWriteMask
= desc
->StencilWriteMask
;
746 tmp_desc
.FrontFace
= desc
->FrontFace
;
747 tmp_desc
.BackFace
= desc
->BackFace
;
751 tmp_desc
.StencilReadMask
= D3D11_DEFAULT_STENCIL_READ_MASK
;
752 tmp_desc
.StencilWriteMask
= D3D11_DEFAULT_STENCIL_WRITE_MASK
;
753 tmp_desc
.FrontFace
.StencilFailOp
= D3D11_STENCIL_OP_KEEP
;
754 tmp_desc
.FrontFace
.StencilDepthFailOp
= D3D11_STENCIL_OP_KEEP
;
755 tmp_desc
.FrontFace
.StencilPassOp
= D3D11_STENCIL_OP_KEEP
;
756 tmp_desc
.FrontFace
.StencilFunc
= D3D11_COMPARISON_ALWAYS
;
757 tmp_desc
.BackFace
.StencilFailOp
= D3D11_STENCIL_OP_KEEP
;
758 tmp_desc
.BackFace
.StencilDepthFailOp
= D3D11_STENCIL_OP_KEEP
;
759 tmp_desc
.BackFace
.StencilPassOp
= D3D11_STENCIL_OP_KEEP
;
760 tmp_desc
.BackFace
.StencilFunc
= D3D11_COMPARISON_ALWAYS
;
763 wined3d_mutex_lock();
764 if ((entry
= wine_rb_get(&device
->depthstencil_states
, &tmp_desc
)))
766 object
= WINE_RB_ENTRY_VALUE(entry
, struct d3d_depthstencil_state
, entry
);
768 TRACE("Returning existing depthstencil state %p.\n", object
);
769 ID3D11DepthStencilState_AddRef(&object
->ID3D11DepthStencilState_iface
);
771 wined3d_mutex_unlock();
776 if (!(object
= heap_alloc_zero(sizeof(*object
))))
778 wined3d_mutex_unlock();
779 return E_OUTOFMEMORY
;
782 object
->ID3D11DepthStencilState_iface
.lpVtbl
= &d3d11_depthstencil_state_vtbl
;
783 object
->ID3D10DepthStencilState_iface
.lpVtbl
= &d3d10_depthstencil_state_vtbl
;
784 object
->refcount
= 1;
785 wined3d_private_store_init(&object
->private_store
);
786 object
->desc
= tmp_desc
;
788 if (wine_rb_put(&device
->depthstencil_states
, &tmp_desc
, &object
->entry
) == -1)
790 ERR("Failed to insert depth/stencil state entry.\n");
791 wined3d_private_store_cleanup(&object
->private_store
);
793 wined3d_mutex_unlock();
797 wined3d_desc
.depth
= desc
->DepthEnable
;
798 wined3d_desc
.depth_write
= desc
->DepthWriteMask
;
799 wined3d_desc
.depth_func
= desc
->DepthFunc
;
800 wined3d_desc
.stencil
= desc
->StencilEnable
;
801 wined3d_desc
.stencil_read_mask
= desc
->StencilReadMask
;
802 wined3d_desc
.stencil_write_mask
= desc
->StencilWriteMask
;
803 wined3d_desc
.front
.fail_op
= desc
->FrontFace
.StencilFailOp
;
804 wined3d_desc
.front
.depth_fail_op
= desc
->FrontFace
.StencilDepthFailOp
;
805 wined3d_desc
.front
.pass_op
= desc
->FrontFace
.StencilPassOp
;
806 wined3d_desc
.front
.func
= desc
->FrontFace
.StencilFunc
;
807 wined3d_desc
.back
.fail_op
= desc
->BackFace
.StencilFailOp
;
808 wined3d_desc
.back
.depth_fail_op
= desc
->BackFace
.StencilDepthFailOp
;
809 wined3d_desc
.back
.pass_op
= desc
->BackFace
.StencilPassOp
;
810 wined3d_desc
.back
.func
= desc
->BackFace
.StencilFunc
;
812 /* We cannot fail after creating a wined3d_depth_stencil_state object. It
813 * would lead to double free. */
814 if (FAILED(hr
= wined3d_depth_stencil_state_create(device
->wined3d_device
, &wined3d_desc
,
815 object
, &d3d_depthstencil_state_wined3d_parent_ops
, &object
->wined3d_state
)))
817 WARN("Failed to create wined3d depth/stencil state, hr %#x.\n", hr
);
818 wined3d_private_store_cleanup(&object
->private_store
);
819 wine_rb_remove(&device
->depthstencil_states
, &object
->entry
);
821 wined3d_mutex_unlock();
824 wined3d_mutex_unlock();
826 ID3D11Device2_AddRef(object
->device
= &device
->ID3D11Device2_iface
);
828 TRACE("Created depth/stencil state %p.\n", object
);
834 struct d3d_depthstencil_state
*unsafe_impl_from_ID3D11DepthStencilState(ID3D11DepthStencilState
*iface
)
838 assert(iface
->lpVtbl
== &d3d11_depthstencil_state_vtbl
);
840 return impl_from_ID3D11DepthStencilState(iface
);
843 struct d3d_depthstencil_state
*unsafe_impl_from_ID3D10DepthStencilState(ID3D10DepthStencilState
*iface
)
847 assert(iface
->lpVtbl
== &d3d10_depthstencil_state_vtbl
);
849 return impl_from_ID3D10DepthStencilState(iface
);
852 /* ID3D11RasterizerState methods */
854 static inline struct d3d_rasterizer_state
*impl_from_ID3D11RasterizerState(ID3D11RasterizerState
*iface
)
856 return CONTAINING_RECORD(iface
, struct d3d_rasterizer_state
, ID3D11RasterizerState_iface
);
859 static HRESULT STDMETHODCALLTYPE
d3d11_rasterizer_state_QueryInterface(ID3D11RasterizerState
*iface
,
860 REFIID riid
, void **object
)
862 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState(iface
);
864 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
866 if (IsEqualGUID(riid
, &IID_ID3D11RasterizerState
)
867 || IsEqualGUID(riid
, &IID_ID3D11DeviceChild
)
868 || IsEqualGUID(riid
, &IID_IUnknown
))
870 ID3D11RasterizerState_AddRef(iface
);
875 if (IsEqualGUID(riid
, &IID_ID3D10RasterizerState
)
876 || IsEqualGUID(riid
, &IID_ID3D10DeviceChild
))
878 ID3D10RasterizerState_AddRef(&state
->ID3D10RasterizerState_iface
);
879 *object
= &state
->ID3D10RasterizerState_iface
;
883 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
886 return E_NOINTERFACE
;
889 static ULONG STDMETHODCALLTYPE
d3d11_rasterizer_state_AddRef(ID3D11RasterizerState
*iface
)
891 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState(iface
);
892 ULONG refcount
= InterlockedIncrement(&state
->refcount
);
894 TRACE("%p increasing refcount to %u.\n", state
, refcount
);
898 ID3D11Device2_AddRef(state
->device
);
899 wined3d_mutex_lock();
900 wined3d_rasterizer_state_incref(state
->wined3d_state
);
901 wined3d_mutex_unlock();
907 static ULONG STDMETHODCALLTYPE
d3d11_rasterizer_state_Release(ID3D11RasterizerState
*iface
)
909 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState(iface
);
910 ULONG refcount
= InterlockedDecrement(&state
->refcount
);
912 TRACE("%p decreasing refcount to %u.\n", state
, refcount
);
916 ID3D11Device2
*device
= state
->device
;
918 wined3d_mutex_lock();
919 wined3d_rasterizer_state_decref(state
->wined3d_state
);
920 wined3d_mutex_unlock();
922 ID3D11Device2_Release(device
);
928 static void STDMETHODCALLTYPE
d3d11_rasterizer_state_GetDevice(ID3D11RasterizerState
*iface
,
929 ID3D11Device
**device
)
931 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState(iface
);
933 TRACE("iface %p, device %p.\n", iface
, device
);
935 *device
= (ID3D11Device
*)state
->device
;
936 ID3D11Device_AddRef(*device
);
939 static HRESULT STDMETHODCALLTYPE
d3d11_rasterizer_state_GetPrivateData(ID3D11RasterizerState
*iface
,
940 REFGUID guid
, UINT
*data_size
, void *data
)
942 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState(iface
);
944 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
946 return d3d_get_private_data(&state
->private_store
, guid
, data_size
, data
);
949 static HRESULT STDMETHODCALLTYPE
d3d11_rasterizer_state_SetPrivateData(ID3D11RasterizerState
*iface
,
950 REFGUID guid
, UINT data_size
, const void *data
)
952 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState(iface
);
954 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
956 return d3d_set_private_data(&state
->private_store
, guid
, data_size
, data
);
959 static HRESULT STDMETHODCALLTYPE
d3d11_rasterizer_state_SetPrivateDataInterface(ID3D11RasterizerState
*iface
,
960 REFGUID guid
, const IUnknown
*data
)
962 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState(iface
);
964 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
966 return d3d_set_private_data_interface(&state
->private_store
, guid
, data
);
969 static void STDMETHODCALLTYPE
d3d11_rasterizer_state_GetDesc(ID3D11RasterizerState
*iface
,
970 D3D11_RASTERIZER_DESC
*desc
)
972 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState(iface
);
974 TRACE("iface %p, desc %p.\n", iface
, desc
);
979 static const struct ID3D11RasterizerStateVtbl d3d11_rasterizer_state_vtbl
=
981 /* IUnknown methods */
982 d3d11_rasterizer_state_QueryInterface
,
983 d3d11_rasterizer_state_AddRef
,
984 d3d11_rasterizer_state_Release
,
985 /* ID3D11DeviceChild methods */
986 d3d11_rasterizer_state_GetDevice
,
987 d3d11_rasterizer_state_GetPrivateData
,
988 d3d11_rasterizer_state_SetPrivateData
,
989 d3d11_rasterizer_state_SetPrivateDataInterface
,
990 /* ID3D11RasterizerState methods */
991 d3d11_rasterizer_state_GetDesc
,
994 /* ID3D10RasterizerState methods */
996 static inline struct d3d_rasterizer_state
*impl_from_ID3D10RasterizerState(ID3D10RasterizerState
*iface
)
998 return CONTAINING_RECORD(iface
, struct d3d_rasterizer_state
, ID3D10RasterizerState_iface
);
1001 /* IUnknown methods */
1003 static HRESULT STDMETHODCALLTYPE
d3d10_rasterizer_state_QueryInterface(ID3D10RasterizerState
*iface
,
1004 REFIID riid
, void **object
)
1006 struct d3d_rasterizer_state
*state
= impl_from_ID3D10RasterizerState(iface
);
1008 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
1010 return d3d11_rasterizer_state_QueryInterface(&state
->ID3D11RasterizerState_iface
, riid
, object
);
1013 static ULONG STDMETHODCALLTYPE
d3d10_rasterizer_state_AddRef(ID3D10RasterizerState
*iface
)
1015 struct d3d_rasterizer_state
*state
= impl_from_ID3D10RasterizerState(iface
);
1017 TRACE("iface %p.\n", iface
);
1019 return d3d11_rasterizer_state_AddRef(&state
->ID3D11RasterizerState_iface
);
1022 static ULONG STDMETHODCALLTYPE
d3d10_rasterizer_state_Release(ID3D10RasterizerState
*iface
)
1024 struct d3d_rasterizer_state
*state
= impl_from_ID3D10RasterizerState(iface
);
1026 TRACE("iface %p.\n", state
);
1028 return d3d11_rasterizer_state_Release(&state
->ID3D11RasterizerState_iface
);
1031 /* ID3D10DeviceChild methods */
1033 static void STDMETHODCALLTYPE
d3d10_rasterizer_state_GetDevice(ID3D10RasterizerState
*iface
, ID3D10Device
**device
)
1035 struct d3d_rasterizer_state
*state
= impl_from_ID3D10RasterizerState(iface
);
1037 TRACE("iface %p, device %p.\n", iface
, device
);
1039 ID3D11Device2_QueryInterface(state
->device
, &IID_ID3D10Device
, (void **)device
);
1042 static HRESULT STDMETHODCALLTYPE
d3d10_rasterizer_state_GetPrivateData(ID3D10RasterizerState
*iface
,
1043 REFGUID guid
, UINT
*data_size
, void *data
)
1045 struct d3d_rasterizer_state
*state
= impl_from_ID3D10RasterizerState(iface
);
1047 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
1048 iface
, debugstr_guid(guid
), data_size
, data
);
1050 return d3d_get_private_data(&state
->private_store
, guid
, data_size
, data
);
1053 static HRESULT STDMETHODCALLTYPE
d3d10_rasterizer_state_SetPrivateData(ID3D10RasterizerState
*iface
,
1054 REFGUID guid
, UINT data_size
, const void *data
)
1056 struct d3d_rasterizer_state
*state
= impl_from_ID3D10RasterizerState(iface
);
1058 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
1059 iface
, debugstr_guid(guid
), data_size
, data
);
1061 return d3d_set_private_data(&state
->private_store
, guid
, data_size
, data
);
1064 static HRESULT STDMETHODCALLTYPE
d3d10_rasterizer_state_SetPrivateDataInterface(ID3D10RasterizerState
*iface
,
1065 REFGUID guid
, const IUnknown
*data
)
1067 struct d3d_rasterizer_state
*state
= impl_from_ID3D10RasterizerState(iface
);
1069 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
1071 return d3d_set_private_data_interface(&state
->private_store
, guid
, data
);
1074 /* ID3D10RasterizerState methods */
1076 static void STDMETHODCALLTYPE
d3d10_rasterizer_state_GetDesc(ID3D10RasterizerState
*iface
,
1077 D3D10_RASTERIZER_DESC
*desc
)
1079 struct d3d_rasterizer_state
*state
= impl_from_ID3D10RasterizerState(iface
);
1081 TRACE("iface %p, desc %p.\n", iface
, desc
);
1083 memcpy(desc
, &state
->desc
, sizeof(*desc
));
1086 static const struct ID3D10RasterizerStateVtbl d3d10_rasterizer_state_vtbl
=
1088 /* IUnknown methods */
1089 d3d10_rasterizer_state_QueryInterface
,
1090 d3d10_rasterizer_state_AddRef
,
1091 d3d10_rasterizer_state_Release
,
1092 /* ID3D10DeviceChild methods */
1093 d3d10_rasterizer_state_GetDevice
,
1094 d3d10_rasterizer_state_GetPrivateData
,
1095 d3d10_rasterizer_state_SetPrivateData
,
1096 d3d10_rasterizer_state_SetPrivateDataInterface
,
1097 /* ID3D10RasterizerState methods */
1098 d3d10_rasterizer_state_GetDesc
,
1101 static void STDMETHODCALLTYPE
d3d_rasterizer_state_wined3d_object_destroyed(void *parent
)
1103 struct d3d_rasterizer_state
*state
= parent
;
1104 struct d3d_device
*device
= impl_from_ID3D11Device2(state
->device
);
1106 wine_rb_remove(&device
->rasterizer_states
, &state
->entry
);
1107 wined3d_private_store_cleanup(&state
->private_store
);
1111 static const struct wined3d_parent_ops d3d_rasterizer_state_wined3d_parent_ops
=
1113 d3d_rasterizer_state_wined3d_object_destroyed
,
1116 static enum wined3d_fill_mode
wined3d_fill_mode_from_d3d11(D3D11_FILL_MODE mode
)
1118 return (enum wined3d_fill_mode
)mode
;
1121 static enum wined3d_cull
wined3d_cull_from_d3d11(D3D11_CULL_MODE mode
)
1123 return (enum wined3d_cull
)mode
;
1126 static HRESULT
d3d_rasterizer_state_init(struct d3d_rasterizer_state
*state
, struct d3d_device
*device
,
1127 const D3D11_RASTERIZER_DESC
*desc
)
1129 struct wined3d_rasterizer_state_desc wined3d_desc
;
1132 state
->ID3D11RasterizerState_iface
.lpVtbl
= &d3d11_rasterizer_state_vtbl
;
1133 state
->ID3D10RasterizerState_iface
.lpVtbl
= &d3d10_rasterizer_state_vtbl
;
1134 state
->refcount
= 1;
1135 wined3d_private_store_init(&state
->private_store
);
1136 state
->desc
= *desc
;
1138 if (wine_rb_put(&device
->rasterizer_states
, desc
, &state
->entry
) == -1)
1140 ERR("Failed to insert rasterizer state entry.\n");
1141 wined3d_private_store_cleanup(&state
->private_store
);
1145 wined3d_desc
.fill_mode
= wined3d_fill_mode_from_d3d11(desc
->FillMode
);
1146 wined3d_desc
.cull_mode
= wined3d_cull_from_d3d11(desc
->CullMode
);
1147 wined3d_desc
.front_ccw
= desc
->FrontCounterClockwise
;
1148 wined3d_desc
.depth_bias
= desc
->DepthBias
;
1149 wined3d_desc
.depth_bias_clamp
= desc
->DepthBiasClamp
;
1150 wined3d_desc
.scale_bias
= desc
->SlopeScaledDepthBias
;
1151 wined3d_desc
.depth_clip
= desc
->DepthClipEnable
;
1152 wined3d_desc
.scissor
= desc
->ScissorEnable
;
1153 wined3d_desc
.line_antialias
= desc
->AntialiasedLineEnable
;
1155 /* We cannot fail after creating a wined3d_rasterizer_state object. It
1156 * would lead to double free. */
1157 if (FAILED(hr
= wined3d_rasterizer_state_create(device
->wined3d_device
, &wined3d_desc
,
1158 state
, &d3d_rasterizer_state_wined3d_parent_ops
, &state
->wined3d_state
)))
1160 WARN("Failed to create wined3d rasterizer state, hr %#x.\n", hr
);
1161 wined3d_private_store_cleanup(&state
->private_store
);
1162 wine_rb_remove(&device
->rasterizer_states
, &state
->entry
);
1166 ID3D11Device2_AddRef(state
->device
= &device
->ID3D11Device2_iface
);
1171 HRESULT
d3d_rasterizer_state_create(struct d3d_device
*device
, const D3D11_RASTERIZER_DESC
*desc
,
1172 struct d3d_rasterizer_state
**state
)
1174 struct d3d_rasterizer_state
*object
;
1175 struct wine_rb_entry
*entry
;
1179 return E_INVALIDARG
;
1181 wined3d_mutex_lock();
1182 if ((entry
= wine_rb_get(&device
->rasterizer_states
, desc
)))
1184 object
= WINE_RB_ENTRY_VALUE(entry
, struct d3d_rasterizer_state
, entry
);
1186 TRACE("Returning existing rasterizer state %p.\n", object
);
1187 ID3D11RasterizerState_AddRef(&object
->ID3D11RasterizerState_iface
);
1189 wined3d_mutex_unlock();
1194 if (!(object
= heap_alloc_zero(sizeof(*object
))))
1196 wined3d_mutex_unlock();
1197 return E_OUTOFMEMORY
;
1200 hr
= d3d_rasterizer_state_init(object
, device
, desc
);
1201 wined3d_mutex_unlock();
1204 WARN("Failed to initialize rasterizer state, hr %#x.\n", hr
);
1209 TRACE("Created rasterizer state %p.\n", object
);
1215 struct d3d_rasterizer_state
*unsafe_impl_from_ID3D11RasterizerState(ID3D11RasterizerState
*iface
)
1219 assert(iface
->lpVtbl
== &d3d11_rasterizer_state_vtbl
);
1221 return impl_from_ID3D11RasterizerState(iface
);
1224 struct d3d_rasterizer_state
*unsafe_impl_from_ID3D10RasterizerState(ID3D10RasterizerState
*iface
)
1228 assert(iface
->lpVtbl
== &d3d10_rasterizer_state_vtbl
);
1230 return impl_from_ID3D10RasterizerState(iface
);
1233 /* ID3D11SampleState methods */
1235 static inline struct d3d_sampler_state
*impl_from_ID3D11SamplerState(ID3D11SamplerState
*iface
)
1237 return CONTAINING_RECORD(iface
, struct d3d_sampler_state
, ID3D11SamplerState_iface
);
1240 static HRESULT STDMETHODCALLTYPE
d3d11_sampler_state_QueryInterface(ID3D11SamplerState
*iface
,
1241 REFIID riid
, void **object
)
1243 struct d3d_sampler_state
*state
= impl_from_ID3D11SamplerState(iface
);
1245 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
1247 if (IsEqualGUID(riid
, &IID_ID3D11SamplerState
)
1248 || IsEqualGUID(riid
, &IID_ID3D11DeviceChild
)
1249 || IsEqualGUID(riid
, &IID_IUnknown
))
1251 ID3D11SamplerState_AddRef(iface
);
1256 if (IsEqualGUID(riid
, &IID_ID3D10SamplerState
)
1257 || IsEqualGUID(riid
, &IID_ID3D10DeviceChild
))
1259 ID3D10SamplerState_AddRef(&state
->ID3D10SamplerState_iface
);
1260 *object
= &state
->ID3D10SamplerState_iface
;
1264 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
1267 return E_NOINTERFACE
;
1270 static ULONG STDMETHODCALLTYPE
d3d11_sampler_state_AddRef(ID3D11SamplerState
*iface
)
1272 struct d3d_sampler_state
*state
= impl_from_ID3D11SamplerState(iface
);
1273 ULONG refcount
= InterlockedIncrement(&state
->refcount
);
1275 TRACE("%p increasing refcount to %u.\n", state
, refcount
);
1279 ID3D11Device2_AddRef(state
->device
);
1280 wined3d_mutex_lock();
1281 wined3d_sampler_incref(state
->wined3d_sampler
);
1282 wined3d_mutex_unlock();
1288 static ULONG STDMETHODCALLTYPE
d3d11_sampler_state_Release(ID3D11SamplerState
*iface
)
1290 struct d3d_sampler_state
*state
= impl_from_ID3D11SamplerState(iface
);
1291 ULONG refcount
= InterlockedDecrement(&state
->refcount
);
1293 TRACE("%p decreasing refcount to %u.\n", state
, refcount
);
1297 ID3D11Device2
*device
= state
->device
;
1299 wined3d_mutex_lock();
1300 wined3d_sampler_decref(state
->wined3d_sampler
);
1301 wined3d_mutex_unlock();
1303 ID3D11Device2_Release(device
);
1309 static void STDMETHODCALLTYPE
d3d11_sampler_state_GetDevice(ID3D11SamplerState
*iface
,
1310 ID3D11Device
**device
)
1312 struct d3d_sampler_state
*state
= impl_from_ID3D11SamplerState(iface
);
1314 TRACE("iface %p, device %p.\n", iface
, device
);
1316 *device
= (ID3D11Device
*)state
->device
;
1317 ID3D11Device_AddRef(*device
);
1320 static HRESULT STDMETHODCALLTYPE
d3d11_sampler_state_GetPrivateData(ID3D11SamplerState
*iface
,
1321 REFGUID guid
, UINT
*data_size
, void *data
)
1323 struct d3d_sampler_state
*state
= impl_from_ID3D11SamplerState(iface
);
1325 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
1327 return d3d_get_private_data(&state
->private_store
, guid
, data_size
, data
);
1330 static HRESULT STDMETHODCALLTYPE
d3d11_sampler_state_SetPrivateData(ID3D11SamplerState
*iface
,
1331 REFGUID guid
, UINT data_size
, const void *data
)
1333 struct d3d_sampler_state
*state
= impl_from_ID3D11SamplerState(iface
);
1335 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
1337 return d3d_set_private_data(&state
->private_store
, guid
, data_size
, data
);
1340 static HRESULT STDMETHODCALLTYPE
d3d11_sampler_state_SetPrivateDataInterface(ID3D11SamplerState
*iface
,
1341 REFGUID guid
, const IUnknown
*data
)
1343 struct d3d_sampler_state
*state
= impl_from_ID3D11SamplerState(iface
);
1345 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
1347 return d3d_set_private_data_interface(&state
->private_store
, guid
, data
);
1350 static void STDMETHODCALLTYPE
d3d11_sampler_state_GetDesc(ID3D11SamplerState
*iface
,
1351 D3D11_SAMPLER_DESC
*desc
)
1353 struct d3d_sampler_state
*state
= impl_from_ID3D11SamplerState(iface
);
1355 TRACE("iface %p, desc %p.\n", iface
, desc
);
1357 *desc
= state
->desc
;
1360 static const struct ID3D11SamplerStateVtbl d3d11_sampler_state_vtbl
=
1362 /* IUnknown methods */
1363 d3d11_sampler_state_QueryInterface
,
1364 d3d11_sampler_state_AddRef
,
1365 d3d11_sampler_state_Release
,
1366 /* ID3D11DeviceChild methods */
1367 d3d11_sampler_state_GetDevice
,
1368 d3d11_sampler_state_GetPrivateData
,
1369 d3d11_sampler_state_SetPrivateData
,
1370 d3d11_sampler_state_SetPrivateDataInterface
,
1371 /* ID3D11SamplerState methods */
1372 d3d11_sampler_state_GetDesc
,
1375 /* ID3D10SamplerState methods */
1377 static inline struct d3d_sampler_state
*impl_from_ID3D10SamplerState(ID3D10SamplerState
*iface
)
1379 return CONTAINING_RECORD(iface
, struct d3d_sampler_state
, ID3D10SamplerState_iface
);
1382 /* IUnknown methods */
1384 static HRESULT STDMETHODCALLTYPE
d3d10_sampler_state_QueryInterface(ID3D10SamplerState
*iface
,
1385 REFIID riid
, void **object
)
1387 struct d3d_sampler_state
*state
= impl_from_ID3D10SamplerState(iface
);
1389 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
1391 return d3d11_sampler_state_QueryInterface(&state
->ID3D11SamplerState_iface
, riid
, object
);
1394 static ULONG STDMETHODCALLTYPE
d3d10_sampler_state_AddRef(ID3D10SamplerState
*iface
)
1396 struct d3d_sampler_state
*state
= impl_from_ID3D10SamplerState(iface
);
1398 TRACE("iface %p.\n", iface
);
1400 return d3d11_sampler_state_AddRef(&state
->ID3D11SamplerState_iface
);
1403 static ULONG STDMETHODCALLTYPE
d3d10_sampler_state_Release(ID3D10SamplerState
*iface
)
1405 struct d3d_sampler_state
*state
= impl_from_ID3D10SamplerState(iface
);
1407 TRACE("iface %p.\n", iface
);
1409 return d3d11_sampler_state_Release(&state
->ID3D11SamplerState_iface
);
1412 /* ID3D10DeviceChild methods */
1414 static void STDMETHODCALLTYPE
d3d10_sampler_state_GetDevice(ID3D10SamplerState
*iface
, ID3D10Device
**device
)
1416 struct d3d_sampler_state
*state
= impl_from_ID3D10SamplerState(iface
);
1418 TRACE("iface %p, device %p.\n", iface
, device
);
1420 ID3D11Device2_QueryInterface(state
->device
, &IID_ID3D10Device
, (void **)device
);
1423 static HRESULT STDMETHODCALLTYPE
d3d10_sampler_state_GetPrivateData(ID3D10SamplerState
*iface
,
1424 REFGUID guid
, UINT
*data_size
, void *data
)
1426 struct d3d_sampler_state
*state
= impl_from_ID3D10SamplerState(iface
);
1428 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
1429 iface
, debugstr_guid(guid
), data_size
, data
);
1431 return d3d_get_private_data(&state
->private_store
, guid
, data_size
, data
);
1434 static HRESULT STDMETHODCALLTYPE
d3d10_sampler_state_SetPrivateData(ID3D10SamplerState
*iface
,
1435 REFGUID guid
, UINT data_size
, const void *data
)
1437 struct d3d_sampler_state
*state
= impl_from_ID3D10SamplerState(iface
);
1439 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
1440 iface
, debugstr_guid(guid
), data_size
, data
);
1442 return d3d_set_private_data(&state
->private_store
, guid
, data_size
, data
);
1445 static HRESULT STDMETHODCALLTYPE
d3d10_sampler_state_SetPrivateDataInterface(ID3D10SamplerState
*iface
,
1446 REFGUID guid
, const IUnknown
*data
)
1448 struct d3d_sampler_state
*state
= impl_from_ID3D10SamplerState(iface
);
1450 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
1452 return d3d_set_private_data_interface(&state
->private_store
, guid
, data
);
1455 /* ID3D10SamplerState methods */
1457 static void STDMETHODCALLTYPE
d3d10_sampler_state_GetDesc(ID3D10SamplerState
*iface
,
1458 D3D10_SAMPLER_DESC
*desc
)
1460 struct d3d_sampler_state
*state
= impl_from_ID3D10SamplerState(iface
);
1462 TRACE("iface %p, desc %p.\n", iface
, desc
);
1464 memcpy(desc
, &state
->desc
, sizeof(*desc
));
1467 static const struct ID3D10SamplerStateVtbl d3d10_sampler_state_vtbl
=
1469 /* IUnknown methods */
1470 d3d10_sampler_state_QueryInterface
,
1471 d3d10_sampler_state_AddRef
,
1472 d3d10_sampler_state_Release
,
1473 /* ID3D10DeviceChild methods */
1474 d3d10_sampler_state_GetDevice
,
1475 d3d10_sampler_state_GetPrivateData
,
1476 d3d10_sampler_state_SetPrivateData
,
1477 d3d10_sampler_state_SetPrivateDataInterface
,
1478 /* ID3D10SamplerState methods */
1479 d3d10_sampler_state_GetDesc
,
1482 static void STDMETHODCALLTYPE
d3d_sampler_wined3d_object_destroyed(void *parent
)
1484 struct d3d_sampler_state
*state
= parent
;
1485 struct d3d_device
*device
= impl_from_ID3D11Device2(state
->device
);
1487 wine_rb_remove(&device
->sampler_states
, &state
->entry
);
1488 wined3d_private_store_cleanup(&state
->private_store
);
1492 static const struct wined3d_parent_ops d3d_sampler_wined3d_parent_ops
=
1494 d3d_sampler_wined3d_object_destroyed
,
1497 static enum wined3d_texture_address
wined3d_texture_address_from_d3d11(enum D3D11_TEXTURE_ADDRESS_MODE t
)
1499 return (enum wined3d_texture_address
)t
;
1502 static enum wined3d_texture_filter_type
wined3d_texture_filter_mip_from_d3d11(enum D3D11_FILTER f
)
1504 if (D3D11_DECODE_MIP_FILTER(f
) == D3D11_FILTER_TYPE_LINEAR
)
1505 return WINED3D_TEXF_LINEAR
;
1506 return WINED3D_TEXF_POINT
;
1509 static enum wined3d_texture_filter_type
wined3d_texture_filter_mag_from_d3d11(enum D3D11_FILTER f
)
1511 if (D3D11_DECODE_MAG_FILTER(f
) == D3D11_FILTER_TYPE_LINEAR
)
1512 return WINED3D_TEXF_LINEAR
;
1513 return WINED3D_TEXF_POINT
;
1516 static enum wined3d_texture_filter_type
wined3d_texture_filter_min_from_d3d11(enum D3D11_FILTER f
)
1518 if (D3D11_DECODE_MIN_FILTER(f
) == D3D11_FILTER_TYPE_LINEAR
)
1519 return WINED3D_TEXF_LINEAR
;
1520 return WINED3D_TEXF_POINT
;
1523 static BOOL
wined3d_texture_compare_from_d3d11(enum D3D11_FILTER f
)
1525 return D3D11_DECODE_IS_COMPARISON_FILTER(f
);
1528 static enum wined3d_cmp_func
wined3d_cmp_func_from_d3d11(D3D11_COMPARISON_FUNC f
)
1530 return (enum wined3d_cmp_func
)f
;
1533 static HRESULT
d3d_sampler_state_init(struct d3d_sampler_state
*state
, struct d3d_device
*device
,
1534 const D3D11_SAMPLER_DESC
*desc
)
1536 struct wined3d_sampler_desc wined3d_desc
;
1539 state
->ID3D11SamplerState_iface
.lpVtbl
= &d3d11_sampler_state_vtbl
;
1540 state
->ID3D10SamplerState_iface
.lpVtbl
= &d3d10_sampler_state_vtbl
;
1541 state
->refcount
= 1;
1542 wined3d_private_store_init(&state
->private_store
);
1543 state
->desc
= *desc
;
1545 wined3d_desc
.address_u
= wined3d_texture_address_from_d3d11(desc
->AddressU
);
1546 wined3d_desc
.address_v
= wined3d_texture_address_from_d3d11(desc
->AddressV
);
1547 wined3d_desc
.address_w
= wined3d_texture_address_from_d3d11(desc
->AddressW
);
1548 memcpy(wined3d_desc
.border_color
, desc
->BorderColor
, sizeof(wined3d_desc
.border_color
));
1549 wined3d_desc
.mag_filter
= wined3d_texture_filter_mag_from_d3d11(desc
->Filter
);
1550 wined3d_desc
.min_filter
= wined3d_texture_filter_min_from_d3d11(desc
->Filter
);
1551 wined3d_desc
.mip_filter
= wined3d_texture_filter_mip_from_d3d11(desc
->Filter
);
1552 wined3d_desc
.lod_bias
= desc
->MipLODBias
;
1553 wined3d_desc
.min_lod
= desc
->MinLOD
;
1554 wined3d_desc
.max_lod
= max(desc
->MinLOD
, desc
->MaxLOD
);
1555 wined3d_desc
.mip_base_level
= 0;
1556 wined3d_desc
.max_anisotropy
= D3D11_DECODE_IS_ANISOTROPIC_FILTER(desc
->Filter
) ? desc
->MaxAnisotropy
: 1;
1557 wined3d_desc
.compare
= wined3d_texture_compare_from_d3d11(desc
->Filter
);
1558 wined3d_desc
.comparison_func
= wined3d_cmp_func_from_d3d11(desc
->ComparisonFunc
);
1559 wined3d_desc
.srgb_decode
= TRUE
;
1561 if (wine_rb_put(&device
->sampler_states
, desc
, &state
->entry
) == -1)
1563 ERR("Failed to insert sampler state entry.\n");
1564 wined3d_private_store_cleanup(&state
->private_store
);
1568 /* We cannot fail after creating a wined3d_sampler object. It would lead to
1570 if (FAILED(hr
= wined3d_sampler_create(device
->wined3d_device
, &wined3d_desc
,
1571 state
, &d3d_sampler_wined3d_parent_ops
, &state
->wined3d_sampler
)))
1573 WARN("Failed to create wined3d sampler, hr %#x.\n", hr
);
1574 wined3d_private_store_cleanup(&state
->private_store
);
1575 wine_rb_remove(&device
->sampler_states
, &state
->entry
);
1579 ID3D11Device2_AddRef(state
->device
= &device
->ID3D11Device2_iface
);
1584 HRESULT
d3d_sampler_state_create(struct d3d_device
*device
, const D3D11_SAMPLER_DESC
*desc
,
1585 struct d3d_sampler_state
**state
)
1587 D3D11_SAMPLER_DESC normalized_desc
;
1588 struct d3d_sampler_state
*object
;
1589 struct wine_rb_entry
*entry
;
1593 return E_INVALIDARG
;
1595 normalized_desc
= *desc
;
1596 if (!D3D11_DECODE_IS_ANISOTROPIC_FILTER(normalized_desc
.Filter
))
1597 normalized_desc
.MaxAnisotropy
= 0;
1598 if (!D3D11_DECODE_IS_COMPARISON_FILTER(normalized_desc
.Filter
))
1599 normalized_desc
.ComparisonFunc
= D3D11_COMPARISON_NEVER
;
1600 if (normalized_desc
.AddressU
!= D3D11_TEXTURE_ADDRESS_BORDER
1601 && normalized_desc
.AddressV
!= D3D11_TEXTURE_ADDRESS_BORDER
1602 && normalized_desc
.AddressW
!= D3D11_TEXTURE_ADDRESS_BORDER
)
1603 memset(&normalized_desc
.BorderColor
, 0, sizeof(normalized_desc
.BorderColor
));
1605 wined3d_mutex_lock();
1606 if ((entry
= wine_rb_get(&device
->sampler_states
, &normalized_desc
)))
1608 object
= WINE_RB_ENTRY_VALUE(entry
, struct d3d_sampler_state
, entry
);
1610 TRACE("Returning existing sampler state %p.\n", object
);
1611 ID3D11SamplerState_AddRef(&object
->ID3D11SamplerState_iface
);
1613 wined3d_mutex_unlock();
1618 if (!(object
= heap_alloc_zero(sizeof(*object
))))
1620 wined3d_mutex_unlock();
1621 return E_OUTOFMEMORY
;
1624 hr
= d3d_sampler_state_init(object
, device
, &normalized_desc
);
1625 wined3d_mutex_unlock();
1628 WARN("Failed to initialize sampler state, hr %#x.\n", hr
);
1633 TRACE("Created sampler state %p.\n", object
);
1639 struct d3d_sampler_state
*unsafe_impl_from_ID3D11SamplerState(ID3D11SamplerState
*iface
)
1643 assert(iface
->lpVtbl
== &d3d11_sampler_state_vtbl
);
1645 return impl_from_ID3D11SamplerState(iface
);
1648 struct d3d_sampler_state
*unsafe_impl_from_ID3D10SamplerState(ID3D10SamplerState
*iface
)
1652 assert(iface
->lpVtbl
== &d3d10_sampler_state_vtbl
);
1654 return impl_from_ID3D10SamplerState(iface
);