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
);
67 wined3d_blend_state_incref(state
->wined3d_state
);
73 static ULONG STDMETHODCALLTYPE
d3d11_blend_state_Release(ID3D11BlendState
*iface
)
75 struct d3d_blend_state
*state
= impl_from_ID3D11BlendState(iface
);
76 ULONG refcount
= InterlockedDecrement(&state
->refcount
);
78 TRACE("%p decreasing refcount to %u.\n", state
, refcount
);
82 ID3D11Device2
*device
= state
->device
;
83 wined3d_blend_state_decref(state
->wined3d_state
);
84 ID3D11Device2_Release(device
);
90 static void STDMETHODCALLTYPE
d3d11_blend_state_GetDevice(ID3D11BlendState
*iface
,
91 ID3D11Device
**device
)
93 struct d3d_blend_state
*state
= impl_from_ID3D11BlendState(iface
);
95 TRACE("iface %p, device %p.\n", iface
, device
);
97 *device
= (ID3D11Device
*)state
->device
;
98 ID3D11Device_AddRef(*device
);
101 static HRESULT STDMETHODCALLTYPE
d3d11_blend_state_GetPrivateData(ID3D11BlendState
*iface
,
102 REFGUID guid
, UINT
*data_size
, void *data
)
104 struct d3d_blend_state
*state
= impl_from_ID3D11BlendState(iface
);
106 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
108 return d3d_get_private_data(&state
->private_store
, guid
, data_size
, data
);
111 static HRESULT STDMETHODCALLTYPE
d3d11_blend_state_SetPrivateData(ID3D11BlendState
*iface
,
112 REFGUID guid
, UINT data_size
, const void *data
)
114 struct d3d_blend_state
*state
= impl_from_ID3D11BlendState(iface
);
116 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
118 return d3d_set_private_data(&state
->private_store
, guid
, data_size
, data
);
121 static HRESULT STDMETHODCALLTYPE
d3d11_blend_state_SetPrivateDataInterface(ID3D11BlendState
*iface
,
122 REFGUID guid
, const IUnknown
*data
)
124 struct d3d_blend_state
*state
= impl_from_ID3D11BlendState(iface
);
126 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
128 return d3d_set_private_data_interface(&state
->private_store
, guid
, data
);
131 static void STDMETHODCALLTYPE
d3d11_blend_state_GetDesc(ID3D11BlendState
*iface
, D3D11_BLEND_DESC
*desc
)
133 struct d3d_blend_state
*state
= impl_from_ID3D11BlendState(iface
);
135 TRACE("iface %p, desc %p.\n", iface
, desc
);
140 static const struct ID3D11BlendStateVtbl d3d11_blend_state_vtbl
=
142 /* IUnknown methods */
143 d3d11_blend_state_QueryInterface
,
144 d3d11_blend_state_AddRef
,
145 d3d11_blend_state_Release
,
146 /* ID3D11DeviceChild methods */
147 d3d11_blend_state_GetDevice
,
148 d3d11_blend_state_GetPrivateData
,
149 d3d11_blend_state_SetPrivateData
,
150 d3d11_blend_state_SetPrivateDataInterface
,
151 /* ID3D11BlendState methods */
152 d3d11_blend_state_GetDesc
,
155 /* ID3D10BlendState methods */
157 static inline struct d3d_blend_state
*impl_from_ID3D10BlendState(ID3D10BlendState1
*iface
)
159 return CONTAINING_RECORD(iface
, struct d3d_blend_state
, ID3D10BlendState1_iface
);
162 /* IUnknown methods */
164 static HRESULT STDMETHODCALLTYPE
d3d10_blend_state_QueryInterface(ID3D10BlendState1
*iface
,
165 REFIID riid
, void **object
)
167 struct d3d_blend_state
*state
= impl_from_ID3D10BlendState(iface
);
169 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
171 return d3d11_blend_state_QueryInterface(&state
->ID3D11BlendState_iface
, riid
, object
);
174 static ULONG STDMETHODCALLTYPE
d3d10_blend_state_AddRef(ID3D10BlendState1
*iface
)
176 struct d3d_blend_state
*state
= impl_from_ID3D10BlendState(iface
);
178 TRACE("iface %p.\n", iface
);
180 return d3d11_blend_state_AddRef(&state
->ID3D11BlendState_iface
);
183 static ULONG STDMETHODCALLTYPE
d3d10_blend_state_Release(ID3D10BlendState1
*iface
)
185 struct d3d_blend_state
*state
= impl_from_ID3D10BlendState(iface
);
187 TRACE("iface %p.\n", iface
);
189 return d3d11_blend_state_Release(&state
->ID3D11BlendState_iface
);
192 /* ID3D10DeviceChild methods */
194 static void STDMETHODCALLTYPE
d3d10_blend_state_GetDevice(ID3D10BlendState1
*iface
, ID3D10Device
**device
)
196 struct d3d_blend_state
*state
= impl_from_ID3D10BlendState(iface
);
198 TRACE("iface %p, device %p.\n", iface
, device
);
200 ID3D11Device2_QueryInterface(state
->device
, &IID_ID3D10Device
, (void **)device
);
203 static HRESULT STDMETHODCALLTYPE
d3d10_blend_state_GetPrivateData(ID3D10BlendState1
*iface
,
204 REFGUID guid
, UINT
*data_size
, void *data
)
206 struct d3d_blend_state
*state
= impl_from_ID3D10BlendState(iface
);
208 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
209 iface
, debugstr_guid(guid
), data_size
, data
);
211 return d3d_get_private_data(&state
->private_store
, guid
, data_size
, data
);
214 static HRESULT STDMETHODCALLTYPE
d3d10_blend_state_SetPrivateData(ID3D10BlendState1
*iface
,
215 REFGUID guid
, UINT data_size
, const void *data
)
217 struct d3d_blend_state
*state
= impl_from_ID3D10BlendState(iface
);
219 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
220 iface
, debugstr_guid(guid
), data_size
, data
);
222 return d3d_set_private_data(&state
->private_store
, guid
, data_size
, data
);
225 static HRESULT STDMETHODCALLTYPE
d3d10_blend_state_SetPrivateDataInterface(ID3D10BlendState1
*iface
,
226 REFGUID guid
, const IUnknown
*data
)
228 struct d3d_blend_state
*state
= impl_from_ID3D10BlendState(iface
);
230 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
232 return d3d_set_private_data_interface(&state
->private_store
, guid
, data
);
235 /* ID3D10BlendState methods */
237 static D3D10_BLEND
d3d10_blend_from_d3d11(D3D11_BLEND factor
)
239 return (D3D10_BLEND
)factor
;
242 static D3D10_BLEND_OP
d3d10_blend_op_from_d3d11(D3D11_BLEND_OP op
)
244 return (D3D10_BLEND_OP
)op
;
247 static void STDMETHODCALLTYPE
d3d10_blend_state_GetDesc(ID3D10BlendState1
*iface
, D3D10_BLEND_DESC
*desc
)
249 struct d3d_blend_state
*state
= impl_from_ID3D10BlendState(iface
);
250 const D3D11_BLEND_DESC
*d3d11_desc
= &state
->desc
;
253 TRACE("iface %p, desc %p.\n", iface
, desc
);
255 desc
->AlphaToCoverageEnable
= d3d11_desc
->AlphaToCoverageEnable
;
256 desc
->SrcBlend
= d3d10_blend_from_d3d11(d3d11_desc
->RenderTarget
[0].SrcBlend
);
257 desc
->DestBlend
= d3d10_blend_from_d3d11(d3d11_desc
->RenderTarget
[0].DestBlend
);
258 desc
->BlendOp
= d3d10_blend_op_from_d3d11(d3d11_desc
->RenderTarget
[0].BlendOp
);
259 desc
->SrcBlendAlpha
= d3d10_blend_from_d3d11(d3d11_desc
->RenderTarget
[0].SrcBlendAlpha
);
260 desc
->DestBlendAlpha
= d3d10_blend_from_d3d11(d3d11_desc
->RenderTarget
[0].DestBlendAlpha
);
261 desc
->BlendOpAlpha
= d3d10_blend_op_from_d3d11(d3d11_desc
->RenderTarget
[0].BlendOpAlpha
);
262 for (i
= 0; i
< D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT
; ++i
)
264 desc
->BlendEnable
[i
] = d3d11_desc
->RenderTarget
[i
].BlendEnable
;
265 desc
->RenderTargetWriteMask
[i
] = d3d11_desc
->RenderTarget
[i
].RenderTargetWriteMask
;
269 static void STDMETHODCALLTYPE
d3d10_blend_state_GetDesc1(ID3D10BlendState1
*iface
, D3D10_BLEND_DESC1
*desc
)
271 struct d3d_blend_state
*state
= impl_from_ID3D10BlendState(iface
);
273 TRACE("iface %p, desc %p.\n", iface
, desc
);
275 memcpy(desc
, &state
->desc
, sizeof(*desc
));
278 static const struct ID3D10BlendState1Vtbl d3d10_blend_state_vtbl
=
280 /* IUnknown methods */
281 d3d10_blend_state_QueryInterface
,
282 d3d10_blend_state_AddRef
,
283 d3d10_blend_state_Release
,
284 /* ID3D10DeviceChild methods */
285 d3d10_blend_state_GetDevice
,
286 d3d10_blend_state_GetPrivateData
,
287 d3d10_blend_state_SetPrivateData
,
288 d3d10_blend_state_SetPrivateDataInterface
,
289 /* ID3D10BlendState methods */
290 d3d10_blend_state_GetDesc
,
291 /* ID3D10BlendState1 methods */
292 d3d10_blend_state_GetDesc1
,
295 static void STDMETHODCALLTYPE
d3d_blend_state_wined3d_object_destroyed(void *parent
)
297 struct d3d_blend_state
*state
= parent
;
298 struct d3d_device
*device
= impl_from_ID3D11Device2(state
->device
);
300 wine_rb_remove(&device
->blend_states
, &state
->entry
);
301 wined3d_private_store_cleanup(&state
->private_store
);
305 static const struct wined3d_parent_ops d3d_blend_state_wined3d_parent_ops
=
307 d3d_blend_state_wined3d_object_destroyed
,
310 static enum wined3d_blend
wined3d_blend_from_d3d11(D3D11_BLEND factor
)
312 return (enum wined3d_blend
)factor
;
315 static enum wined3d_blend_op
wined3d_blend_op_from_d3d11(D3D11_BLEND_OP op
)
317 return (enum wined3d_blend_op
)op
;
320 HRESULT
d3d_blend_state_create(struct d3d_device
*device
, const D3D11_BLEND_DESC
*desc
,
321 struct d3d_blend_state
**state
)
323 struct wined3d_blend_state_desc wined3d_desc
;
324 struct d3d_blend_state
*object
;
325 struct wine_rb_entry
*entry
;
326 D3D11_BLEND_DESC tmp_desc
;
333 /* D3D11_RENDER_TARGET_BLEND_DESC has a hole, which is a problem because we use
334 * D3D11_BLEND_DESC as a key in the rbtree. */
335 memset(&tmp_desc
, 0, sizeof(tmp_desc
));
336 tmp_desc
.AlphaToCoverageEnable
= desc
->AlphaToCoverageEnable
;
337 tmp_desc
.IndependentBlendEnable
= desc
->IndependentBlendEnable
;
338 for (i
= 0; i
< D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT
; ++i
)
340 j
= desc
->IndependentBlendEnable
? i
: 0;
341 tmp_desc
.RenderTarget
[i
].BlendEnable
= desc
->RenderTarget
[j
].BlendEnable
;
342 if (tmp_desc
.RenderTarget
[i
].BlendEnable
)
344 tmp_desc
.RenderTarget
[i
].SrcBlend
= desc
->RenderTarget
[j
].SrcBlend
;
345 tmp_desc
.RenderTarget
[i
].DestBlend
= desc
->RenderTarget
[j
].DestBlend
;
346 tmp_desc
.RenderTarget
[i
].BlendOp
= desc
->RenderTarget
[j
].BlendOp
;
347 tmp_desc
.RenderTarget
[i
].SrcBlendAlpha
= desc
->RenderTarget
[j
].SrcBlendAlpha
;
348 tmp_desc
.RenderTarget
[i
].DestBlendAlpha
= desc
->RenderTarget
[j
].DestBlendAlpha
;
349 tmp_desc
.RenderTarget
[i
].BlendOpAlpha
= desc
->RenderTarget
[j
].BlendOpAlpha
;
353 tmp_desc
.RenderTarget
[i
].SrcBlend
= D3D11_BLEND_ONE
;
354 tmp_desc
.RenderTarget
[i
].DestBlend
= D3D11_BLEND_ZERO
;
355 tmp_desc
.RenderTarget
[i
].BlendOp
= D3D11_BLEND_OP_ADD
;
356 tmp_desc
.RenderTarget
[i
].SrcBlendAlpha
= D3D11_BLEND_ONE
;
357 tmp_desc
.RenderTarget
[i
].DestBlendAlpha
= D3D11_BLEND_ZERO
;
358 tmp_desc
.RenderTarget
[i
].BlendOpAlpha
= D3D11_BLEND_OP_ADD
;
360 tmp_desc
.RenderTarget
[i
].RenderTargetWriteMask
= desc
->RenderTarget
[j
].RenderTargetWriteMask
;
363 wined3d_mutex_lock();
364 if ((entry
= wine_rb_get(&device
->blend_states
, &tmp_desc
)))
366 object
= WINE_RB_ENTRY_VALUE(entry
, struct d3d_blend_state
, entry
);
368 TRACE("Returning existing blend state %p.\n", object
);
369 ID3D11BlendState_AddRef(&object
->ID3D11BlendState_iface
);
371 wined3d_mutex_unlock();
376 if (!(object
= heap_alloc_zero(sizeof(*object
))))
378 wined3d_mutex_unlock();
379 return E_OUTOFMEMORY
;
382 object
->ID3D11BlendState_iface
.lpVtbl
= &d3d11_blend_state_vtbl
;
383 object
->ID3D10BlendState1_iface
.lpVtbl
= &d3d10_blend_state_vtbl
;
384 object
->refcount
= 1;
385 wined3d_private_store_init(&object
->private_store
);
386 object
->desc
= tmp_desc
;
388 if (wine_rb_put(&device
->blend_states
, &tmp_desc
, &object
->entry
) == -1)
390 ERR("Failed to insert blend state entry.\n");
391 wined3d_private_store_cleanup(&object
->private_store
);
393 wined3d_mutex_unlock();
397 wined3d_desc
.alpha_to_coverage
= desc
->AlphaToCoverageEnable
;
398 wined3d_desc
.independent
= desc
->IndependentBlendEnable
;
399 for (i
= 0; i
< D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT
; ++i
)
401 wined3d_desc
.rt
[i
].enable
= desc
->RenderTarget
[i
].BlendEnable
;
402 wined3d_desc
.rt
[i
].src
= wined3d_blend_from_d3d11(desc
->RenderTarget
[i
].SrcBlend
);
403 wined3d_desc
.rt
[i
].dst
= wined3d_blend_from_d3d11(desc
->RenderTarget
[i
].DestBlend
);
404 wined3d_desc
.rt
[i
].op
= wined3d_blend_op_from_d3d11(desc
->RenderTarget
[i
].BlendOp
);
405 wined3d_desc
.rt
[i
].src_alpha
= wined3d_blend_from_d3d11(desc
->RenderTarget
[i
].SrcBlendAlpha
);
406 wined3d_desc
.rt
[i
].dst_alpha
= wined3d_blend_from_d3d11(desc
->RenderTarget
[i
].DestBlendAlpha
);
407 wined3d_desc
.rt
[i
].op_alpha
= wined3d_blend_op_from_d3d11(desc
->RenderTarget
[i
].BlendOpAlpha
);
408 wined3d_desc
.rt
[i
].writemask
= desc
->RenderTarget
[i
].RenderTargetWriteMask
;
411 /* We cannot fail after creating a wined3d_blend_state object. It
412 * would lead to double free. */
413 if (FAILED(hr
= wined3d_blend_state_create(device
->wined3d_device
, &wined3d_desc
,
414 object
, &d3d_blend_state_wined3d_parent_ops
, &object
->wined3d_state
)))
416 WARN("Failed to create wined3d blend state, hr %#x.\n", hr
);
417 wined3d_private_store_cleanup(&object
->private_store
);
418 wine_rb_remove(&device
->blend_states
, &object
->entry
);
420 wined3d_mutex_unlock();
423 wined3d_mutex_unlock();
425 ID3D11Device2_AddRef(object
->device
= &device
->ID3D11Device2_iface
);
427 TRACE("Created blend state %p.\n", object
);
433 struct d3d_blend_state
*unsafe_impl_from_ID3D11BlendState(ID3D11BlendState
*iface
)
437 assert(iface
->lpVtbl
== &d3d11_blend_state_vtbl
);
439 return impl_from_ID3D11BlendState(iface
);
442 struct d3d_blend_state
*unsafe_impl_from_ID3D10BlendState(ID3D10BlendState
*iface
)
446 assert(iface
->lpVtbl
== (ID3D10BlendStateVtbl
*)&d3d10_blend_state_vtbl
);
448 return impl_from_ID3D10BlendState((ID3D10BlendState1
*)iface
);
451 /* ID3D11DepthStencilState methods */
453 static HRESULT STDMETHODCALLTYPE
d3d11_depthstencil_state_QueryInterface(ID3D11DepthStencilState
*iface
,
454 REFIID riid
, void **object
)
456 struct d3d_depthstencil_state
*state
= impl_from_ID3D11DepthStencilState(iface
);
458 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
460 if (IsEqualGUID(riid
, &IID_ID3D11DepthStencilState
)
461 || IsEqualGUID(riid
, &IID_ID3D11DeviceChild
)
462 || IsEqualGUID(riid
, &IID_IUnknown
))
464 ID3D11DepthStencilState_AddRef(iface
);
469 if (IsEqualGUID(riid
, &IID_ID3D10DepthStencilState
)
470 || IsEqualGUID(riid
, &IID_ID3D10DeviceChild
))
472 ID3D10DepthStencilState_AddRef(&state
->ID3D10DepthStencilState_iface
);
473 *object
= &state
->ID3D10DepthStencilState_iface
;
477 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
480 return E_NOINTERFACE
;
483 static ULONG STDMETHODCALLTYPE
d3d11_depthstencil_state_AddRef(ID3D11DepthStencilState
*iface
)
485 struct d3d_depthstencil_state
*state
= impl_from_ID3D11DepthStencilState(iface
);
486 ULONG refcount
= InterlockedIncrement(&state
->refcount
);
488 TRACE("%p increasing refcount to %u.\n", state
, refcount
);
492 ID3D11Device2_AddRef(state
->device
);
493 wined3d_depth_stencil_state_incref(state
->wined3d_state
);
499 static ULONG STDMETHODCALLTYPE
d3d11_depthstencil_state_Release(ID3D11DepthStencilState
*iface
)
501 struct d3d_depthstencil_state
*state
= impl_from_ID3D11DepthStencilState(iface
);
502 ULONG refcount
= InterlockedDecrement(&state
->refcount
);
504 TRACE("%p decreasing refcount to %u.\n", state
, refcount
);
508 ID3D11Device2
*device
= state
->device
;
510 wined3d_depth_stencil_state_decref(state
->wined3d_state
);
511 ID3D11Device2_Release(device
);
517 static void STDMETHODCALLTYPE
d3d11_depthstencil_state_GetDevice(ID3D11DepthStencilState
*iface
,
518 ID3D11Device
**device
)
520 struct d3d_depthstencil_state
*state
= impl_from_ID3D11DepthStencilState(iface
);
522 TRACE("iface %p, device %p.\n", iface
, device
);
524 *device
= (ID3D11Device
*)state
->device
;
525 ID3D11Device_AddRef(*device
);
528 static HRESULT STDMETHODCALLTYPE
d3d11_depthstencil_state_GetPrivateData(ID3D11DepthStencilState
*iface
,
529 REFGUID guid
, UINT
*data_size
, void *data
)
531 struct d3d_depthstencil_state
*state
= impl_from_ID3D11DepthStencilState(iface
);
533 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
535 return d3d_get_private_data(&state
->private_store
, guid
, data_size
, data
);
538 static HRESULT STDMETHODCALLTYPE
d3d11_depthstencil_state_SetPrivateData(ID3D11DepthStencilState
*iface
,
539 REFGUID guid
, UINT data_size
, const void *data
)
541 struct d3d_depthstencil_state
*state
= impl_from_ID3D11DepthStencilState(iface
);
543 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
545 return d3d_set_private_data(&state
->private_store
, guid
, data_size
, data
);
548 static HRESULT STDMETHODCALLTYPE
d3d11_depthstencil_state_SetPrivateDataInterface(ID3D11DepthStencilState
*iface
,
549 REFGUID guid
, const IUnknown
*data
)
551 struct d3d_depthstencil_state
*state
= impl_from_ID3D11DepthStencilState(iface
);
553 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
555 return d3d_set_private_data_interface(&state
->private_store
, guid
, data
);
558 static void STDMETHODCALLTYPE
d3d11_depthstencil_state_GetDesc(ID3D11DepthStencilState
*iface
,
559 D3D11_DEPTH_STENCIL_DESC
*desc
)
561 struct d3d_depthstencil_state
*state
= impl_from_ID3D11DepthStencilState(iface
);
563 TRACE("iface %p, desc %p.\n", iface
, desc
);
568 static const struct ID3D11DepthStencilStateVtbl d3d11_depthstencil_state_vtbl
=
570 /* IUnknown methods */
571 d3d11_depthstencil_state_QueryInterface
,
572 d3d11_depthstencil_state_AddRef
,
573 d3d11_depthstencil_state_Release
,
574 /* ID3D11DeviceChild methods */
575 d3d11_depthstencil_state_GetDevice
,
576 d3d11_depthstencil_state_GetPrivateData
,
577 d3d11_depthstencil_state_SetPrivateData
,
578 d3d11_depthstencil_state_SetPrivateDataInterface
,
579 /* ID3D11DepthStencilState methods */
580 d3d11_depthstencil_state_GetDesc
,
583 /* ID3D10DepthStencilState methods */
585 static inline struct d3d_depthstencil_state
*impl_from_ID3D10DepthStencilState(ID3D10DepthStencilState
*iface
)
587 return CONTAINING_RECORD(iface
, struct d3d_depthstencil_state
, ID3D10DepthStencilState_iface
);
590 /* IUnknown methods */
592 static HRESULT STDMETHODCALLTYPE
d3d10_depthstencil_state_QueryInterface(ID3D10DepthStencilState
*iface
,
593 REFIID riid
, void **object
)
595 struct d3d_depthstencil_state
*state
= impl_from_ID3D10DepthStencilState(iface
);
597 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
599 return d3d11_depthstencil_state_QueryInterface(&state
->ID3D11DepthStencilState_iface
, riid
, object
);
602 static ULONG STDMETHODCALLTYPE
d3d10_depthstencil_state_AddRef(ID3D10DepthStencilState
*iface
)
604 struct d3d_depthstencil_state
*state
= impl_from_ID3D10DepthStencilState(iface
);
606 TRACE("iface %p.\n", iface
);
608 return d3d11_depthstencil_state_AddRef(&state
->ID3D11DepthStencilState_iface
);
611 static ULONG STDMETHODCALLTYPE
d3d10_depthstencil_state_Release(ID3D10DepthStencilState
*iface
)
613 struct d3d_depthstencil_state
*state
= impl_from_ID3D10DepthStencilState(iface
);
615 TRACE("iface %p.\n", iface
);
617 return d3d11_depthstencil_state_Release(&state
->ID3D11DepthStencilState_iface
);
620 /* ID3D10DeviceChild methods */
622 static void STDMETHODCALLTYPE
d3d10_depthstencil_state_GetDevice(ID3D10DepthStencilState
*iface
, ID3D10Device
**device
)
624 struct d3d_depthstencil_state
*state
= impl_from_ID3D10DepthStencilState(iface
);
626 TRACE("iface %p, device %p.\n", iface
, device
);
628 ID3D11Device2_QueryInterface(state
->device
, &IID_ID3D10Device
, (void **)device
);
631 static HRESULT STDMETHODCALLTYPE
d3d10_depthstencil_state_GetPrivateData(ID3D10DepthStencilState
*iface
,
632 REFGUID guid
, UINT
*data_size
, void *data
)
634 struct d3d_depthstencil_state
*state
= impl_from_ID3D10DepthStencilState(iface
);
636 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
637 iface
, debugstr_guid(guid
), data_size
, data
);
639 return d3d_get_private_data(&state
->private_store
, guid
, data_size
, data
);
642 static HRESULT STDMETHODCALLTYPE
d3d10_depthstencil_state_SetPrivateData(ID3D10DepthStencilState
*iface
,
643 REFGUID guid
, UINT data_size
, const void *data
)
645 struct d3d_depthstencil_state
*state
= impl_from_ID3D10DepthStencilState(iface
);
647 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
648 iface
, debugstr_guid(guid
), data_size
, data
);
650 return d3d_set_private_data(&state
->private_store
, guid
, data_size
, data
);
653 static HRESULT STDMETHODCALLTYPE
d3d10_depthstencil_state_SetPrivateDataInterface(ID3D10DepthStencilState
*iface
,
654 REFGUID guid
, const IUnknown
*data
)
656 struct d3d_depthstencil_state
*state
= impl_from_ID3D10DepthStencilState(iface
);
658 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
660 return d3d_set_private_data_interface(&state
->private_store
, guid
, data
);
663 /* ID3D10DepthStencilState methods */
665 static void STDMETHODCALLTYPE
d3d10_depthstencil_state_GetDesc(ID3D10DepthStencilState
*iface
,
666 D3D10_DEPTH_STENCIL_DESC
*desc
)
668 struct d3d_depthstencil_state
*state
= impl_from_ID3D10DepthStencilState(iface
);
670 TRACE("iface %p, desc %p.\n", iface
, desc
);
672 memcpy(desc
, &state
->desc
, sizeof(*desc
));
675 static const struct ID3D10DepthStencilStateVtbl d3d10_depthstencil_state_vtbl
=
677 /* IUnknown methods */
678 d3d10_depthstencil_state_QueryInterface
,
679 d3d10_depthstencil_state_AddRef
,
680 d3d10_depthstencil_state_Release
,
681 /* ID3D10DeviceChild methods */
682 d3d10_depthstencil_state_GetDevice
,
683 d3d10_depthstencil_state_GetPrivateData
,
684 d3d10_depthstencil_state_SetPrivateData
,
685 d3d10_depthstencil_state_SetPrivateDataInterface
,
686 /* ID3D10DepthStencilState methods */
687 d3d10_depthstencil_state_GetDesc
,
690 static void STDMETHODCALLTYPE
d3d_depthstencil_state_wined3d_object_destroyed(void *parent
)
692 struct d3d_depthstencil_state
*state
= parent
;
693 struct d3d_device
*device
= impl_from_ID3D11Device2(state
->device
);
695 wine_rb_remove(&device
->depthstencil_states
, &state
->entry
);
696 wined3d_private_store_cleanup(&state
->private_store
);
700 static const struct wined3d_parent_ops d3d_depthstencil_state_wined3d_parent_ops
=
702 d3d_depthstencil_state_wined3d_object_destroyed
,
705 HRESULT
d3d_depthstencil_state_create(struct d3d_device
*device
, const D3D11_DEPTH_STENCIL_DESC
*desc
,
706 struct d3d_depthstencil_state
**state
)
708 struct wined3d_depth_stencil_state_desc wined3d_desc
;
709 struct d3d_depthstencil_state
*object
;
710 D3D11_DEPTH_STENCIL_DESC tmp_desc
;
711 struct wine_rb_entry
*entry
;
717 /* D3D11_DEPTH_STENCIL_DESC has a hole, which is a problem because we use
718 * it as a key in the rbtree. */
719 memset(&tmp_desc
, 0, sizeof(tmp_desc
));
720 tmp_desc
.DepthEnable
= desc
->DepthEnable
;
721 if (desc
->DepthEnable
)
723 tmp_desc
.DepthWriteMask
= desc
->DepthWriteMask
;
724 tmp_desc
.DepthFunc
= desc
->DepthFunc
;
728 tmp_desc
.DepthWriteMask
= D3D11_DEPTH_WRITE_MASK_ALL
;
729 tmp_desc
.DepthFunc
= D3D11_COMPARISON_LESS
;
731 tmp_desc
.StencilEnable
= desc
->StencilEnable
;
732 if (desc
->StencilEnable
)
734 tmp_desc
.StencilReadMask
= desc
->StencilReadMask
;
735 tmp_desc
.StencilWriteMask
= desc
->StencilWriteMask
;
736 tmp_desc
.FrontFace
= desc
->FrontFace
;
737 tmp_desc
.BackFace
= desc
->BackFace
;
741 tmp_desc
.StencilReadMask
= D3D11_DEFAULT_STENCIL_READ_MASK
;
742 tmp_desc
.StencilWriteMask
= D3D11_DEFAULT_STENCIL_WRITE_MASK
;
743 tmp_desc
.FrontFace
.StencilFailOp
= D3D11_STENCIL_OP_KEEP
;
744 tmp_desc
.FrontFace
.StencilDepthFailOp
= D3D11_STENCIL_OP_KEEP
;
745 tmp_desc
.FrontFace
.StencilPassOp
= D3D11_STENCIL_OP_KEEP
;
746 tmp_desc
.FrontFace
.StencilFunc
= D3D11_COMPARISON_ALWAYS
;
747 tmp_desc
.BackFace
.StencilFailOp
= D3D11_STENCIL_OP_KEEP
;
748 tmp_desc
.BackFace
.StencilDepthFailOp
= D3D11_STENCIL_OP_KEEP
;
749 tmp_desc
.BackFace
.StencilPassOp
= D3D11_STENCIL_OP_KEEP
;
750 tmp_desc
.BackFace
.StencilFunc
= D3D11_COMPARISON_ALWAYS
;
753 wined3d_mutex_lock();
754 if ((entry
= wine_rb_get(&device
->depthstencil_states
, &tmp_desc
)))
756 object
= WINE_RB_ENTRY_VALUE(entry
, struct d3d_depthstencil_state
, entry
);
758 TRACE("Returning existing depthstencil state %p.\n", object
);
759 ID3D11DepthStencilState_AddRef(&object
->ID3D11DepthStencilState_iface
);
761 wined3d_mutex_unlock();
766 if (!(object
= heap_alloc_zero(sizeof(*object
))))
768 wined3d_mutex_unlock();
769 return E_OUTOFMEMORY
;
772 object
->ID3D11DepthStencilState_iface
.lpVtbl
= &d3d11_depthstencil_state_vtbl
;
773 object
->ID3D10DepthStencilState_iface
.lpVtbl
= &d3d10_depthstencil_state_vtbl
;
774 object
->refcount
= 1;
775 wined3d_private_store_init(&object
->private_store
);
776 object
->desc
= tmp_desc
;
778 if (wine_rb_put(&device
->depthstencil_states
, &tmp_desc
, &object
->entry
) == -1)
780 ERR("Failed to insert depth/stencil state entry.\n");
781 wined3d_private_store_cleanup(&object
->private_store
);
783 wined3d_mutex_unlock();
787 wined3d_desc
.depth
= desc
->DepthEnable
;
788 wined3d_desc
.depth_write
= desc
->DepthWriteMask
;
789 wined3d_desc
.depth_func
= desc
->DepthFunc
;
790 wined3d_desc
.stencil
= desc
->StencilEnable
;
791 wined3d_desc
.stencil_read_mask
= desc
->StencilReadMask
;
792 wined3d_desc
.stencil_write_mask
= desc
->StencilWriteMask
;
793 wined3d_desc
.front
.fail_op
= desc
->FrontFace
.StencilFailOp
;
794 wined3d_desc
.front
.depth_fail_op
= desc
->FrontFace
.StencilDepthFailOp
;
795 wined3d_desc
.front
.pass_op
= desc
->FrontFace
.StencilPassOp
;
796 wined3d_desc
.front
.func
= desc
->FrontFace
.StencilFunc
;
797 wined3d_desc
.back
.fail_op
= desc
->BackFace
.StencilFailOp
;
798 wined3d_desc
.back
.depth_fail_op
= desc
->BackFace
.StencilDepthFailOp
;
799 wined3d_desc
.back
.pass_op
= desc
->BackFace
.StencilPassOp
;
800 wined3d_desc
.back
.func
= desc
->BackFace
.StencilFunc
;
802 /* We cannot fail after creating a wined3d_depth_stencil_state object. It
803 * would lead to double free. */
804 if (FAILED(hr
= wined3d_depth_stencil_state_create(device
->wined3d_device
, &wined3d_desc
,
805 object
, &d3d_depthstencil_state_wined3d_parent_ops
, &object
->wined3d_state
)))
807 WARN("Failed to create wined3d depth/stencil state, hr %#x.\n", hr
);
808 wined3d_private_store_cleanup(&object
->private_store
);
809 wine_rb_remove(&device
->depthstencil_states
, &object
->entry
);
811 wined3d_mutex_unlock();
814 wined3d_mutex_unlock();
816 ID3D11Device2_AddRef(object
->device
= &device
->ID3D11Device2_iface
);
818 TRACE("Created depth/stencil state %p.\n", object
);
824 struct d3d_depthstencil_state
*unsafe_impl_from_ID3D11DepthStencilState(ID3D11DepthStencilState
*iface
)
828 assert(iface
->lpVtbl
== &d3d11_depthstencil_state_vtbl
);
830 return impl_from_ID3D11DepthStencilState(iface
);
833 struct d3d_depthstencil_state
*unsafe_impl_from_ID3D10DepthStencilState(ID3D10DepthStencilState
*iface
)
837 assert(iface
->lpVtbl
== &d3d10_depthstencil_state_vtbl
);
839 return impl_from_ID3D10DepthStencilState(iface
);
842 /* ID3D11RasterizerState methods */
844 static inline struct d3d_rasterizer_state
*impl_from_ID3D11RasterizerState1(ID3D11RasterizerState1
*iface
)
846 return CONTAINING_RECORD(iface
, struct d3d_rasterizer_state
, ID3D11RasterizerState1_iface
);
849 static HRESULT STDMETHODCALLTYPE
d3d11_rasterizer_state_QueryInterface(ID3D11RasterizerState1
*iface
,
850 REFIID riid
, void **object
)
852 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState1(iface
);
854 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
856 if (IsEqualGUID(riid
, &IID_ID3D11RasterizerState
)
857 || IsEqualGUID(riid
, &IID_ID3D11RasterizerState1
)
858 || IsEqualGUID(riid
, &IID_ID3D11DeviceChild
)
859 || IsEqualGUID(riid
, &IID_IUnknown
))
861 ID3D11RasterizerState1_AddRef(iface
);
866 if (IsEqualGUID(riid
, &IID_ID3D10RasterizerState
)
867 || IsEqualGUID(riid
, &IID_ID3D10DeviceChild
))
869 ID3D10RasterizerState_AddRef(&state
->ID3D10RasterizerState_iface
);
870 *object
= &state
->ID3D10RasterizerState_iface
;
874 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
877 return E_NOINTERFACE
;
880 static ULONG STDMETHODCALLTYPE
d3d11_rasterizer_state_AddRef(ID3D11RasterizerState1
*iface
)
882 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState1(iface
);
883 ULONG refcount
= InterlockedIncrement(&state
->refcount
);
885 TRACE("%p increasing refcount to %u.\n", state
, refcount
);
889 ID3D11Device2_AddRef(state
->device
);
890 wined3d_rasterizer_state_incref(state
->wined3d_state
);
896 static ULONG STDMETHODCALLTYPE
d3d11_rasterizer_state_Release(ID3D11RasterizerState1
*iface
)
898 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState1(iface
);
899 ULONG refcount
= InterlockedDecrement(&state
->refcount
);
901 TRACE("%p decreasing refcount to %u.\n", state
, refcount
);
905 ID3D11Device2
*device
= state
->device
;
906 wined3d_rasterizer_state_decref(state
->wined3d_state
);
907 ID3D11Device2_Release(device
);
913 static void STDMETHODCALLTYPE
d3d11_rasterizer_state_GetDevice(ID3D11RasterizerState1
*iface
,
914 ID3D11Device
**device
)
916 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState1(iface
);
918 TRACE("iface %p, device %p.\n", iface
, device
);
920 *device
= (ID3D11Device
*)state
->device
;
921 ID3D11Device_AddRef(*device
);
924 static HRESULT STDMETHODCALLTYPE
d3d11_rasterizer_state_GetPrivateData(ID3D11RasterizerState1
*iface
,
925 REFGUID guid
, UINT
*data_size
, void *data
)
927 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState1(iface
);
929 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
931 return d3d_get_private_data(&state
->private_store
, guid
, data_size
, data
);
934 static HRESULT STDMETHODCALLTYPE
d3d11_rasterizer_state_SetPrivateData(ID3D11RasterizerState1
*iface
,
935 REFGUID guid
, UINT data_size
, const void *data
)
937 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState1(iface
);
939 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
941 return d3d_set_private_data(&state
->private_store
, guid
, data_size
, data
);
944 static HRESULT STDMETHODCALLTYPE
d3d11_rasterizer_state_SetPrivateDataInterface(ID3D11RasterizerState1
*iface
,
945 REFGUID guid
, const IUnknown
*data
)
947 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState1(iface
);
949 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
951 return d3d_set_private_data_interface(&state
->private_store
, guid
, data
);
954 static void STDMETHODCALLTYPE
d3d11_rasterizer_state_GetDesc(ID3D11RasterizerState1
*iface
,
955 D3D11_RASTERIZER_DESC
*desc
)
957 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState1(iface
);
959 TRACE("iface %p, desc %p.\n", iface
, desc
);
961 memcpy(desc
, &state
->desc
, sizeof(*desc
));
964 static void STDMETHODCALLTYPE
d3d11_rasterizer_state_GetDesc1(ID3D11RasterizerState1
*iface
,
965 D3D11_RASTERIZER_DESC1
*desc
)
967 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState1(iface
);
969 TRACE("iface %p, desc %p.\n", iface
, desc
);
974 static const struct ID3D11RasterizerState1Vtbl d3d11_rasterizer_state_vtbl
=
976 /* IUnknown methods */
977 d3d11_rasterizer_state_QueryInterface
,
978 d3d11_rasterizer_state_AddRef
,
979 d3d11_rasterizer_state_Release
,
980 /* ID3D11DeviceChild methods */
981 d3d11_rasterizer_state_GetDevice
,
982 d3d11_rasterizer_state_GetPrivateData
,
983 d3d11_rasterizer_state_SetPrivateData
,
984 d3d11_rasterizer_state_SetPrivateDataInterface
,
985 /* ID3D11RasterizerState methods */
986 d3d11_rasterizer_state_GetDesc
,
987 /* ID3D11RasterizerState1 methods */
988 d3d11_rasterizer_state_GetDesc1
,
991 /* ID3D10RasterizerState methods */
993 static inline struct d3d_rasterizer_state
*impl_from_ID3D10RasterizerState(ID3D10RasterizerState
*iface
)
995 return CONTAINING_RECORD(iface
, struct d3d_rasterizer_state
, ID3D10RasterizerState_iface
);
998 /* IUnknown methods */
1000 static HRESULT STDMETHODCALLTYPE
d3d10_rasterizer_state_QueryInterface(ID3D10RasterizerState
*iface
,
1001 REFIID riid
, void **object
)
1003 struct d3d_rasterizer_state
*state
= impl_from_ID3D10RasterizerState(iface
);
1005 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
1007 return d3d11_rasterizer_state_QueryInterface(&state
->ID3D11RasterizerState1_iface
, riid
, object
);
1010 static ULONG STDMETHODCALLTYPE
d3d10_rasterizer_state_AddRef(ID3D10RasterizerState
*iface
)
1012 struct d3d_rasterizer_state
*state
= impl_from_ID3D10RasterizerState(iface
);
1014 TRACE("iface %p.\n", iface
);
1016 return d3d11_rasterizer_state_AddRef(&state
->ID3D11RasterizerState1_iface
);
1019 static ULONG STDMETHODCALLTYPE
d3d10_rasterizer_state_Release(ID3D10RasterizerState
*iface
)
1021 struct d3d_rasterizer_state
*state
= impl_from_ID3D10RasterizerState(iface
);
1023 TRACE("iface %p.\n", state
);
1025 return d3d11_rasterizer_state_Release(&state
->ID3D11RasterizerState1_iface
);
1028 /* ID3D10DeviceChild methods */
1030 static void STDMETHODCALLTYPE
d3d10_rasterizer_state_GetDevice(ID3D10RasterizerState
*iface
, ID3D10Device
**device
)
1032 struct d3d_rasterizer_state
*state
= impl_from_ID3D10RasterizerState(iface
);
1034 TRACE("iface %p, device %p.\n", iface
, device
);
1036 ID3D11Device2_QueryInterface(state
->device
, &IID_ID3D10Device
, (void **)device
);
1039 static HRESULT STDMETHODCALLTYPE
d3d10_rasterizer_state_GetPrivateData(ID3D10RasterizerState
*iface
,
1040 REFGUID guid
, UINT
*data_size
, void *data
)
1042 struct d3d_rasterizer_state
*state
= impl_from_ID3D10RasterizerState(iface
);
1044 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
1045 iface
, debugstr_guid(guid
), data_size
, data
);
1047 return d3d_get_private_data(&state
->private_store
, guid
, data_size
, data
);
1050 static HRESULT STDMETHODCALLTYPE
d3d10_rasterizer_state_SetPrivateData(ID3D10RasterizerState
*iface
,
1051 REFGUID guid
, UINT data_size
, const void *data
)
1053 struct d3d_rasterizer_state
*state
= impl_from_ID3D10RasterizerState(iface
);
1055 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
1056 iface
, debugstr_guid(guid
), data_size
, data
);
1058 return d3d_set_private_data(&state
->private_store
, guid
, data_size
, data
);
1061 static HRESULT STDMETHODCALLTYPE
d3d10_rasterizer_state_SetPrivateDataInterface(ID3D10RasterizerState
*iface
,
1062 REFGUID guid
, const IUnknown
*data
)
1064 struct d3d_rasterizer_state
*state
= impl_from_ID3D10RasterizerState(iface
);
1066 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
1068 return d3d_set_private_data_interface(&state
->private_store
, guid
, data
);
1071 /* ID3D10RasterizerState methods */
1073 static void STDMETHODCALLTYPE
d3d10_rasterizer_state_GetDesc(ID3D10RasterizerState
*iface
,
1074 D3D10_RASTERIZER_DESC
*desc
)
1076 struct d3d_rasterizer_state
*state
= impl_from_ID3D10RasterizerState(iface
);
1078 TRACE("iface %p, desc %p.\n", iface
, desc
);
1080 memcpy(desc
, &state
->desc
, sizeof(*desc
));
1083 static const struct ID3D10RasterizerStateVtbl d3d10_rasterizer_state_vtbl
=
1085 /* IUnknown methods */
1086 d3d10_rasterizer_state_QueryInterface
,
1087 d3d10_rasterizer_state_AddRef
,
1088 d3d10_rasterizer_state_Release
,
1089 /* ID3D10DeviceChild methods */
1090 d3d10_rasterizer_state_GetDevice
,
1091 d3d10_rasterizer_state_GetPrivateData
,
1092 d3d10_rasterizer_state_SetPrivateData
,
1093 d3d10_rasterizer_state_SetPrivateDataInterface
,
1094 /* ID3D10RasterizerState methods */
1095 d3d10_rasterizer_state_GetDesc
,
1098 static void STDMETHODCALLTYPE
d3d_rasterizer_state_wined3d_object_destroyed(void *parent
)
1100 struct d3d_rasterizer_state
*state
= parent
;
1101 struct d3d_device
*device
= impl_from_ID3D11Device2(state
->device
);
1103 wine_rb_remove(&device
->rasterizer_states
, &state
->entry
);
1104 wined3d_private_store_cleanup(&state
->private_store
);
1108 static const struct wined3d_parent_ops d3d_rasterizer_state_wined3d_parent_ops
=
1110 d3d_rasterizer_state_wined3d_object_destroyed
,
1113 static enum wined3d_fill_mode
wined3d_fill_mode_from_d3d11(D3D11_FILL_MODE mode
)
1115 return (enum wined3d_fill_mode
)mode
;
1118 static enum wined3d_cull
wined3d_cull_from_d3d11(D3D11_CULL_MODE mode
)
1120 return (enum wined3d_cull
)mode
;
1123 static HRESULT
d3d_rasterizer_state_init(struct d3d_rasterizer_state
*state
, struct d3d_device
*device
,
1124 const D3D11_RASTERIZER_DESC1
*desc
)
1126 struct wined3d_rasterizer_state_desc wined3d_desc
;
1129 state
->ID3D11RasterizerState1_iface
.lpVtbl
= &d3d11_rasterizer_state_vtbl
;
1130 state
->ID3D10RasterizerState_iface
.lpVtbl
= &d3d10_rasterizer_state_vtbl
;
1131 state
->refcount
= 1;
1132 wined3d_private_store_init(&state
->private_store
);
1133 state
->desc
= *desc
;
1135 if (wine_rb_put(&device
->rasterizer_states
, desc
, &state
->entry
) == -1)
1137 ERR("Failed to insert rasterizer state entry.\n");
1138 wined3d_private_store_cleanup(&state
->private_store
);
1142 wined3d_desc
.fill_mode
= wined3d_fill_mode_from_d3d11(desc
->FillMode
);
1143 wined3d_desc
.cull_mode
= wined3d_cull_from_d3d11(desc
->CullMode
);
1144 wined3d_desc
.front_ccw
= desc
->FrontCounterClockwise
;
1145 wined3d_desc
.depth_bias
= desc
->DepthBias
;
1146 wined3d_desc
.depth_bias_clamp
= desc
->DepthBiasClamp
;
1147 wined3d_desc
.scale_bias
= desc
->SlopeScaledDepthBias
;
1148 wined3d_desc
.depth_clip
= desc
->DepthClipEnable
;
1149 wined3d_desc
.scissor
= desc
->ScissorEnable
;
1150 wined3d_desc
.line_antialias
= desc
->AntialiasedLineEnable
;
1152 if (desc
->MultisampleEnable
)
1154 static unsigned int once
;
1156 FIXME("Ignoring MultisampleEnable %#x.\n", desc
->MultisampleEnable
);
1159 if (desc
->ForcedSampleCount
)
1161 static unsigned int once
;
1163 FIXME("Ignoring ForcedSampleCount %#x.\n", desc
->ForcedSampleCount
);
1166 /* We cannot fail after creating a wined3d_rasterizer_state object. It
1167 * would lead to double free. */
1168 if (FAILED(hr
= wined3d_rasterizer_state_create(device
->wined3d_device
, &wined3d_desc
,
1169 state
, &d3d_rasterizer_state_wined3d_parent_ops
, &state
->wined3d_state
)))
1171 WARN("Failed to create wined3d rasterizer state, hr %#x.\n", hr
);
1172 wined3d_private_store_cleanup(&state
->private_store
);
1173 wine_rb_remove(&device
->rasterizer_states
, &state
->entry
);
1177 ID3D11Device2_AddRef(state
->device
= &device
->ID3D11Device2_iface
);
1182 HRESULT
d3d_rasterizer_state_create(struct d3d_device
*device
, const D3D11_RASTERIZER_DESC1
*desc
,
1183 struct d3d_rasterizer_state
**state
)
1185 struct d3d_rasterizer_state
*object
;
1186 struct wine_rb_entry
*entry
;
1189 wined3d_mutex_lock();
1190 if ((entry
= wine_rb_get(&device
->rasterizer_states
, desc
)))
1192 object
= WINE_RB_ENTRY_VALUE(entry
, struct d3d_rasterizer_state
, entry
);
1194 TRACE("Returning existing rasterizer state %p.\n", object
);
1195 ID3D11RasterizerState1_AddRef(&object
->ID3D11RasterizerState1_iface
);
1197 wined3d_mutex_unlock();
1202 if (!(object
= heap_alloc_zero(sizeof(*object
))))
1204 wined3d_mutex_unlock();
1205 return E_OUTOFMEMORY
;
1208 hr
= d3d_rasterizer_state_init(object
, device
, desc
);
1209 wined3d_mutex_unlock();
1212 WARN("Failed to initialize rasterizer state, hr %#x.\n", hr
);
1217 TRACE("Created rasterizer state %p.\n", object
);
1223 struct d3d_rasterizer_state
*unsafe_impl_from_ID3D11RasterizerState(ID3D11RasterizerState
*iface
)
1227 assert(iface
->lpVtbl
== (ID3D11RasterizerStateVtbl
*)&d3d11_rasterizer_state_vtbl
);
1229 return impl_from_ID3D11RasterizerState1((ID3D11RasterizerState1
*)iface
);
1232 struct d3d_rasterizer_state
*unsafe_impl_from_ID3D10RasterizerState(ID3D10RasterizerState
*iface
)
1236 assert(iface
->lpVtbl
== &d3d10_rasterizer_state_vtbl
);
1238 return impl_from_ID3D10RasterizerState(iface
);
1241 /* ID3D11SampleState methods */
1243 static inline struct d3d_sampler_state
*impl_from_ID3D11SamplerState(ID3D11SamplerState
*iface
)
1245 return CONTAINING_RECORD(iface
, struct d3d_sampler_state
, ID3D11SamplerState_iface
);
1248 static HRESULT STDMETHODCALLTYPE
d3d11_sampler_state_QueryInterface(ID3D11SamplerState
*iface
,
1249 REFIID riid
, void **object
)
1251 struct d3d_sampler_state
*state
= impl_from_ID3D11SamplerState(iface
);
1253 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
1255 if (IsEqualGUID(riid
, &IID_ID3D11SamplerState
)
1256 || IsEqualGUID(riid
, &IID_ID3D11DeviceChild
)
1257 || IsEqualGUID(riid
, &IID_IUnknown
))
1259 ID3D11SamplerState_AddRef(iface
);
1264 if (IsEqualGUID(riid
, &IID_ID3D10SamplerState
)
1265 || IsEqualGUID(riid
, &IID_ID3D10DeviceChild
))
1267 ID3D10SamplerState_AddRef(&state
->ID3D10SamplerState_iface
);
1268 *object
= &state
->ID3D10SamplerState_iface
;
1272 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
1275 return E_NOINTERFACE
;
1278 static ULONG STDMETHODCALLTYPE
d3d11_sampler_state_AddRef(ID3D11SamplerState
*iface
)
1280 struct d3d_sampler_state
*state
= impl_from_ID3D11SamplerState(iface
);
1281 ULONG refcount
= InterlockedIncrement(&state
->refcount
);
1283 TRACE("%p increasing refcount to %u.\n", state
, refcount
);
1287 ID3D11Device2_AddRef(state
->device
);
1288 wined3d_sampler_incref(state
->wined3d_sampler
);
1294 static ULONG STDMETHODCALLTYPE
d3d11_sampler_state_Release(ID3D11SamplerState
*iface
)
1296 struct d3d_sampler_state
*state
= impl_from_ID3D11SamplerState(iface
);
1297 ULONG refcount
= InterlockedDecrement(&state
->refcount
);
1299 TRACE("%p decreasing refcount to %u.\n", state
, refcount
);
1303 ID3D11Device2
*device
= state
->device
;
1304 wined3d_sampler_decref(state
->wined3d_sampler
);
1305 ID3D11Device2_Release(device
);
1311 static void STDMETHODCALLTYPE
d3d11_sampler_state_GetDevice(ID3D11SamplerState
*iface
,
1312 ID3D11Device
**device
)
1314 struct d3d_sampler_state
*state
= impl_from_ID3D11SamplerState(iface
);
1316 TRACE("iface %p, device %p.\n", iface
, device
);
1318 *device
= (ID3D11Device
*)state
->device
;
1319 ID3D11Device_AddRef(*device
);
1322 static HRESULT STDMETHODCALLTYPE
d3d11_sampler_state_GetPrivateData(ID3D11SamplerState
*iface
,
1323 REFGUID guid
, UINT
*data_size
, void *data
)
1325 struct d3d_sampler_state
*state
= impl_from_ID3D11SamplerState(iface
);
1327 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
1329 return d3d_get_private_data(&state
->private_store
, guid
, data_size
, data
);
1332 static HRESULT STDMETHODCALLTYPE
d3d11_sampler_state_SetPrivateData(ID3D11SamplerState
*iface
,
1333 REFGUID guid
, UINT data_size
, const void *data
)
1335 struct d3d_sampler_state
*state
= impl_from_ID3D11SamplerState(iface
);
1337 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
1339 return d3d_set_private_data(&state
->private_store
, guid
, data_size
, data
);
1342 static HRESULT STDMETHODCALLTYPE
d3d11_sampler_state_SetPrivateDataInterface(ID3D11SamplerState
*iface
,
1343 REFGUID guid
, const IUnknown
*data
)
1345 struct d3d_sampler_state
*state
= impl_from_ID3D11SamplerState(iface
);
1347 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
1349 return d3d_set_private_data_interface(&state
->private_store
, guid
, data
);
1352 static void STDMETHODCALLTYPE
d3d11_sampler_state_GetDesc(ID3D11SamplerState
*iface
,
1353 D3D11_SAMPLER_DESC
*desc
)
1355 struct d3d_sampler_state
*state
= impl_from_ID3D11SamplerState(iface
);
1357 TRACE("iface %p, desc %p.\n", iface
, desc
);
1359 *desc
= state
->desc
;
1362 static const struct ID3D11SamplerStateVtbl d3d11_sampler_state_vtbl
=
1364 /* IUnknown methods */
1365 d3d11_sampler_state_QueryInterface
,
1366 d3d11_sampler_state_AddRef
,
1367 d3d11_sampler_state_Release
,
1368 /* ID3D11DeviceChild methods */
1369 d3d11_sampler_state_GetDevice
,
1370 d3d11_sampler_state_GetPrivateData
,
1371 d3d11_sampler_state_SetPrivateData
,
1372 d3d11_sampler_state_SetPrivateDataInterface
,
1373 /* ID3D11SamplerState methods */
1374 d3d11_sampler_state_GetDesc
,
1377 /* ID3D10SamplerState methods */
1379 static inline struct d3d_sampler_state
*impl_from_ID3D10SamplerState(ID3D10SamplerState
*iface
)
1381 return CONTAINING_RECORD(iface
, struct d3d_sampler_state
, ID3D10SamplerState_iface
);
1384 /* IUnknown methods */
1386 static HRESULT STDMETHODCALLTYPE
d3d10_sampler_state_QueryInterface(ID3D10SamplerState
*iface
,
1387 REFIID riid
, void **object
)
1389 struct d3d_sampler_state
*state
= impl_from_ID3D10SamplerState(iface
);
1391 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
1393 return d3d11_sampler_state_QueryInterface(&state
->ID3D11SamplerState_iface
, riid
, object
);
1396 static ULONG STDMETHODCALLTYPE
d3d10_sampler_state_AddRef(ID3D10SamplerState
*iface
)
1398 struct d3d_sampler_state
*state
= impl_from_ID3D10SamplerState(iface
);
1400 TRACE("iface %p.\n", iface
);
1402 return d3d11_sampler_state_AddRef(&state
->ID3D11SamplerState_iface
);
1405 static ULONG STDMETHODCALLTYPE
d3d10_sampler_state_Release(ID3D10SamplerState
*iface
)
1407 struct d3d_sampler_state
*state
= impl_from_ID3D10SamplerState(iface
);
1409 TRACE("iface %p.\n", iface
);
1411 return d3d11_sampler_state_Release(&state
->ID3D11SamplerState_iface
);
1414 /* ID3D10DeviceChild methods */
1416 static void STDMETHODCALLTYPE
d3d10_sampler_state_GetDevice(ID3D10SamplerState
*iface
, ID3D10Device
**device
)
1418 struct d3d_sampler_state
*state
= impl_from_ID3D10SamplerState(iface
);
1420 TRACE("iface %p, device %p.\n", iface
, device
);
1422 ID3D11Device2_QueryInterface(state
->device
, &IID_ID3D10Device
, (void **)device
);
1425 static HRESULT STDMETHODCALLTYPE
d3d10_sampler_state_GetPrivateData(ID3D10SamplerState
*iface
,
1426 REFGUID guid
, UINT
*data_size
, void *data
)
1428 struct d3d_sampler_state
*state
= impl_from_ID3D10SamplerState(iface
);
1430 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
1431 iface
, debugstr_guid(guid
), data_size
, data
);
1433 return d3d_get_private_data(&state
->private_store
, guid
, data_size
, data
);
1436 static HRESULT STDMETHODCALLTYPE
d3d10_sampler_state_SetPrivateData(ID3D10SamplerState
*iface
,
1437 REFGUID guid
, UINT data_size
, const void *data
)
1439 struct d3d_sampler_state
*state
= impl_from_ID3D10SamplerState(iface
);
1441 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
1442 iface
, debugstr_guid(guid
), data_size
, data
);
1444 return d3d_set_private_data(&state
->private_store
, guid
, data_size
, data
);
1447 static HRESULT STDMETHODCALLTYPE
d3d10_sampler_state_SetPrivateDataInterface(ID3D10SamplerState
*iface
,
1448 REFGUID guid
, const IUnknown
*data
)
1450 struct d3d_sampler_state
*state
= impl_from_ID3D10SamplerState(iface
);
1452 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
1454 return d3d_set_private_data_interface(&state
->private_store
, guid
, data
);
1457 /* ID3D10SamplerState methods */
1459 static void STDMETHODCALLTYPE
d3d10_sampler_state_GetDesc(ID3D10SamplerState
*iface
,
1460 D3D10_SAMPLER_DESC
*desc
)
1462 struct d3d_sampler_state
*state
= impl_from_ID3D10SamplerState(iface
);
1464 TRACE("iface %p, desc %p.\n", iface
, desc
);
1466 memcpy(desc
, &state
->desc
, sizeof(*desc
));
1469 static const struct ID3D10SamplerStateVtbl d3d10_sampler_state_vtbl
=
1471 /* IUnknown methods */
1472 d3d10_sampler_state_QueryInterface
,
1473 d3d10_sampler_state_AddRef
,
1474 d3d10_sampler_state_Release
,
1475 /* ID3D10DeviceChild methods */
1476 d3d10_sampler_state_GetDevice
,
1477 d3d10_sampler_state_GetPrivateData
,
1478 d3d10_sampler_state_SetPrivateData
,
1479 d3d10_sampler_state_SetPrivateDataInterface
,
1480 /* ID3D10SamplerState methods */
1481 d3d10_sampler_state_GetDesc
,
1484 static void STDMETHODCALLTYPE
d3d_sampler_wined3d_object_destroyed(void *parent
)
1486 struct d3d_sampler_state
*state
= parent
;
1487 struct d3d_device
*device
= impl_from_ID3D11Device2(state
->device
);
1489 wine_rb_remove(&device
->sampler_states
, &state
->entry
);
1490 wined3d_private_store_cleanup(&state
->private_store
);
1494 static const struct wined3d_parent_ops d3d_sampler_wined3d_parent_ops
=
1496 d3d_sampler_wined3d_object_destroyed
,
1499 static enum wined3d_texture_address
wined3d_texture_address_from_d3d11(enum D3D11_TEXTURE_ADDRESS_MODE t
)
1501 return (enum wined3d_texture_address
)t
;
1504 static enum wined3d_texture_filter_type
wined3d_texture_filter_mip_from_d3d11(enum D3D11_FILTER f
)
1506 if (D3D11_DECODE_MIP_FILTER(f
) == D3D11_FILTER_TYPE_LINEAR
)
1507 return WINED3D_TEXF_LINEAR
;
1508 return WINED3D_TEXF_POINT
;
1511 static enum wined3d_texture_filter_type
wined3d_texture_filter_mag_from_d3d11(enum D3D11_FILTER f
)
1513 if (D3D11_DECODE_MAG_FILTER(f
) == D3D11_FILTER_TYPE_LINEAR
)
1514 return WINED3D_TEXF_LINEAR
;
1515 return WINED3D_TEXF_POINT
;
1518 static enum wined3d_texture_filter_type
wined3d_texture_filter_min_from_d3d11(enum D3D11_FILTER f
)
1520 if (D3D11_DECODE_MIN_FILTER(f
) == D3D11_FILTER_TYPE_LINEAR
)
1521 return WINED3D_TEXF_LINEAR
;
1522 return WINED3D_TEXF_POINT
;
1525 static BOOL
wined3d_texture_compare_from_d3d11(enum D3D11_FILTER f
)
1527 return D3D11_DECODE_IS_COMPARISON_FILTER(f
);
1530 static enum wined3d_cmp_func
wined3d_cmp_func_from_d3d11(D3D11_COMPARISON_FUNC f
)
1532 return (enum wined3d_cmp_func
)f
;
1535 static HRESULT
d3d_sampler_state_init(struct d3d_sampler_state
*state
, struct d3d_device
*device
,
1536 const D3D11_SAMPLER_DESC
*desc
)
1538 struct wined3d_sampler_desc wined3d_desc
;
1541 state
->ID3D11SamplerState_iface
.lpVtbl
= &d3d11_sampler_state_vtbl
;
1542 state
->ID3D10SamplerState_iface
.lpVtbl
= &d3d10_sampler_state_vtbl
;
1543 state
->refcount
= 1;
1544 wined3d_private_store_init(&state
->private_store
);
1545 state
->desc
= *desc
;
1547 wined3d_desc
.address_u
= wined3d_texture_address_from_d3d11(desc
->AddressU
);
1548 wined3d_desc
.address_v
= wined3d_texture_address_from_d3d11(desc
->AddressV
);
1549 wined3d_desc
.address_w
= wined3d_texture_address_from_d3d11(desc
->AddressW
);
1550 memcpy(wined3d_desc
.border_color
, desc
->BorderColor
, sizeof(wined3d_desc
.border_color
));
1551 wined3d_desc
.mag_filter
= wined3d_texture_filter_mag_from_d3d11(desc
->Filter
);
1552 wined3d_desc
.min_filter
= wined3d_texture_filter_min_from_d3d11(desc
->Filter
);
1553 wined3d_desc
.mip_filter
= wined3d_texture_filter_mip_from_d3d11(desc
->Filter
);
1554 wined3d_desc
.lod_bias
= desc
->MipLODBias
;
1555 wined3d_desc
.min_lod
= desc
->MinLOD
;
1556 wined3d_desc
.max_lod
= max(desc
->MinLOD
, desc
->MaxLOD
);
1557 wined3d_desc
.mip_base_level
= 0;
1558 wined3d_desc
.max_anisotropy
= D3D11_DECODE_IS_ANISOTROPIC_FILTER(desc
->Filter
) ? desc
->MaxAnisotropy
: 1;
1559 wined3d_desc
.compare
= wined3d_texture_compare_from_d3d11(desc
->Filter
);
1560 wined3d_desc
.comparison_func
= wined3d_cmp_func_from_d3d11(desc
->ComparisonFunc
);
1561 wined3d_desc
.srgb_decode
= TRUE
;
1563 if (wine_rb_put(&device
->sampler_states
, desc
, &state
->entry
) == -1)
1565 ERR("Failed to insert sampler state entry.\n");
1566 wined3d_private_store_cleanup(&state
->private_store
);
1570 /* We cannot fail after creating a wined3d_sampler object. It would lead to
1572 if (FAILED(hr
= wined3d_sampler_create(device
->wined3d_device
, &wined3d_desc
,
1573 state
, &d3d_sampler_wined3d_parent_ops
, &state
->wined3d_sampler
)))
1575 WARN("Failed to create wined3d sampler, hr %#x.\n", hr
);
1576 wined3d_private_store_cleanup(&state
->private_store
);
1577 wine_rb_remove(&device
->sampler_states
, &state
->entry
);
1581 ID3D11Device2_AddRef(state
->device
= &device
->ID3D11Device2_iface
);
1586 HRESULT
d3d_sampler_state_create(struct d3d_device
*device
, const D3D11_SAMPLER_DESC
*desc
,
1587 struct d3d_sampler_state
**state
)
1589 D3D11_SAMPLER_DESC normalized_desc
;
1590 struct d3d_sampler_state
*object
;
1591 struct wine_rb_entry
*entry
;
1595 return E_INVALIDARG
;
1597 normalized_desc
= *desc
;
1598 if (!D3D11_DECODE_IS_ANISOTROPIC_FILTER(normalized_desc
.Filter
))
1599 normalized_desc
.MaxAnisotropy
= 0;
1600 if (!D3D11_DECODE_IS_COMPARISON_FILTER(normalized_desc
.Filter
))
1601 normalized_desc
.ComparisonFunc
= D3D11_COMPARISON_NEVER
;
1602 if (normalized_desc
.AddressU
!= D3D11_TEXTURE_ADDRESS_BORDER
1603 && normalized_desc
.AddressV
!= D3D11_TEXTURE_ADDRESS_BORDER
1604 && normalized_desc
.AddressW
!= D3D11_TEXTURE_ADDRESS_BORDER
)
1605 memset(&normalized_desc
.BorderColor
, 0, sizeof(normalized_desc
.BorderColor
));
1607 wined3d_mutex_lock();
1608 if ((entry
= wine_rb_get(&device
->sampler_states
, &normalized_desc
)))
1610 object
= WINE_RB_ENTRY_VALUE(entry
, struct d3d_sampler_state
, entry
);
1612 TRACE("Returning existing sampler state %p.\n", object
);
1613 ID3D11SamplerState_AddRef(&object
->ID3D11SamplerState_iface
);
1615 wined3d_mutex_unlock();
1620 if (!(object
= heap_alloc_zero(sizeof(*object
))))
1622 wined3d_mutex_unlock();
1623 return E_OUTOFMEMORY
;
1626 hr
= d3d_sampler_state_init(object
, device
, &normalized_desc
);
1627 wined3d_mutex_unlock();
1630 WARN("Failed to initialize sampler state, hr %#x.\n", hr
);
1635 TRACE("Created sampler state %p.\n", object
);
1641 struct d3d_sampler_state
*unsafe_impl_from_ID3D11SamplerState(ID3D11SamplerState
*iface
)
1645 assert(iface
->lpVtbl
== &d3d11_sampler_state_vtbl
);
1647 return impl_from_ID3D11SamplerState(iface
);
1650 struct d3d_sampler_state
*unsafe_impl_from_ID3D10SamplerState(ID3D10SamplerState
*iface
)
1654 assert(iface
->lpVtbl
== &d3d10_sampler_state_vtbl
);
1656 return impl_from_ID3D10SamplerState(iface
);