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 /* ID3D11BlendState1 methods */
26 static HRESULT STDMETHODCALLTYPE
d3d11_blend_state_QueryInterface(ID3D11BlendState1
*iface
,
27 REFIID riid
, void **object
)
29 struct d3d_blend_state
*state
= impl_from_ID3D11BlendState1(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_ID3D11BlendState1
)
35 || IsEqualGUID(riid
, &IID_ID3D11DeviceChild
)
36 || IsEqualGUID(riid
, &IID_IUnknown
))
38 ID3D11BlendState1_AddRef(iface
);
43 if (IsEqualGUID(riid
, &IID_ID3D10BlendState1
)
44 || IsEqualGUID(riid
, &IID_ID3D10BlendState
)
45 || IsEqualGUID(riid
, &IID_ID3D10DeviceChild
))
47 ID3D10BlendState1_AddRef(&state
->ID3D10BlendState1_iface
);
48 *object
= &state
->ID3D10BlendState1_iface
;
52 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
58 static ULONG STDMETHODCALLTYPE
d3d11_blend_state_AddRef(ID3D11BlendState1
*iface
)
60 struct d3d_blend_state
*state
= impl_from_ID3D11BlendState1(iface
);
61 ULONG refcount
= InterlockedIncrement(&state
->refcount
);
63 TRACE("%p increasing refcount to %lu.\n", state
, refcount
);
67 ID3D11Device2_AddRef(state
->device
);
68 wined3d_blend_state_incref(state
->wined3d_state
);
74 static ULONG STDMETHODCALLTYPE
d3d11_blend_state_Release(ID3D11BlendState1
*iface
)
76 struct d3d_blend_state
*state
= impl_from_ID3D11BlendState1(iface
);
77 ULONG refcount
= InterlockedDecrement(&state
->refcount
);
79 TRACE("%p decreasing refcount to %lu.\n", state
, refcount
);
83 ID3D11Device2
*device
= state
->device
;
84 wined3d_blend_state_decref(state
->wined3d_state
);
85 ID3D11Device2_Release(device
);
91 static void STDMETHODCALLTYPE
d3d11_blend_state_GetDevice(ID3D11BlendState1
*iface
,
92 ID3D11Device
**device
)
94 struct d3d_blend_state
*state
= impl_from_ID3D11BlendState1(iface
);
96 TRACE("iface %p, device %p.\n", iface
, device
);
98 *device
= (ID3D11Device
*)state
->device
;
99 ID3D11Device_AddRef(*device
);
102 static HRESULT STDMETHODCALLTYPE
d3d11_blend_state_GetPrivateData(ID3D11BlendState1
*iface
,
103 REFGUID guid
, UINT
*data_size
, void *data
)
105 struct d3d_blend_state
*state
= impl_from_ID3D11BlendState1(iface
);
107 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
109 return d3d_get_private_data(&state
->private_store
, guid
, data_size
, data
);
112 static HRESULT STDMETHODCALLTYPE
d3d11_blend_state_SetPrivateData(ID3D11BlendState1
*iface
,
113 REFGUID guid
, UINT data_size
, const void *data
)
115 struct d3d_blend_state
*state
= impl_from_ID3D11BlendState1(iface
);
117 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
119 return d3d_set_private_data(&state
->private_store
, guid
, data_size
, data
);
122 static HRESULT STDMETHODCALLTYPE
d3d11_blend_state_SetPrivateDataInterface(ID3D11BlendState1
*iface
,
123 REFGUID guid
, const IUnknown
*data
)
125 struct d3d_blend_state
*state
= impl_from_ID3D11BlendState1(iface
);
127 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
129 return d3d_set_private_data_interface(&state
->private_store
, guid
, data
);
132 static void STDMETHODCALLTYPE
d3d11_blend_state_GetDesc(ID3D11BlendState1
*iface
, D3D11_BLEND_DESC
*desc
)
134 struct d3d_blend_state
*state
= impl_from_ID3D11BlendState1(iface
);
135 const D3D11_BLEND_DESC1
*d3d11_desc
= &state
->desc
;
138 TRACE("iface %p, desc %p.\n", iface
, desc
);
140 desc
->AlphaToCoverageEnable
= d3d11_desc
->AlphaToCoverageEnable
;
141 desc
->IndependentBlendEnable
= d3d11_desc
->IndependentBlendEnable
;
142 for (i
= 0; i
< D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT
; ++i
)
144 desc
->RenderTarget
[i
].BlendEnable
= d3d11_desc
->RenderTarget
[i
].BlendEnable
;
145 desc
->RenderTarget
[i
].SrcBlend
= d3d11_desc
->RenderTarget
[i
].SrcBlend
;
146 desc
->RenderTarget
[i
].DestBlend
= d3d11_desc
->RenderTarget
[i
].DestBlend
;
147 desc
->RenderTarget
[i
].BlendOp
= d3d11_desc
->RenderTarget
[i
].BlendOp
;
148 desc
->RenderTarget
[i
].SrcBlendAlpha
= d3d11_desc
->RenderTarget
[i
].SrcBlendAlpha
;
149 desc
->RenderTarget
[i
].DestBlendAlpha
= d3d11_desc
->RenderTarget
[i
].DestBlendAlpha
;
150 desc
->RenderTarget
[i
].BlendOpAlpha
= d3d11_desc
->RenderTarget
[i
].BlendOpAlpha
;
151 desc
->RenderTarget
[i
].RenderTargetWriteMask
= d3d11_desc
->RenderTarget
[i
].RenderTargetWriteMask
;
155 static void STDMETHODCALLTYPE
d3d11_blend_state_GetDesc1(ID3D11BlendState1
*iface
, D3D11_BLEND_DESC1
*desc
)
157 struct d3d_blend_state
*state
= impl_from_ID3D11BlendState1(iface
);
159 TRACE("iface %p, desc %p.\n", iface
, desc
);
164 static const struct ID3D11BlendState1Vtbl d3d11_blend_state_vtbl
=
166 /* IUnknown methods */
167 d3d11_blend_state_QueryInterface
,
168 d3d11_blend_state_AddRef
,
169 d3d11_blend_state_Release
,
170 /* ID3D11DeviceChild methods */
171 d3d11_blend_state_GetDevice
,
172 d3d11_blend_state_GetPrivateData
,
173 d3d11_blend_state_SetPrivateData
,
174 d3d11_blend_state_SetPrivateDataInterface
,
175 /* ID3D11BlendState methods */
176 d3d11_blend_state_GetDesc
,
177 /* ID3D11BlendState1 methods */
178 d3d11_blend_state_GetDesc1
,
181 /* ID3D10BlendState methods */
183 static inline struct d3d_blend_state
*impl_from_ID3D10BlendState(ID3D10BlendState1
*iface
)
185 return CONTAINING_RECORD(iface
, struct d3d_blend_state
, ID3D10BlendState1_iface
);
188 /* IUnknown methods */
190 static HRESULT STDMETHODCALLTYPE
d3d10_blend_state_QueryInterface(ID3D10BlendState1
*iface
,
191 REFIID riid
, void **object
)
193 struct d3d_blend_state
*state
= impl_from_ID3D10BlendState(iface
);
195 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
197 return d3d11_blend_state_QueryInterface(&state
->ID3D11BlendState1_iface
, riid
, object
);
200 static ULONG STDMETHODCALLTYPE
d3d10_blend_state_AddRef(ID3D10BlendState1
*iface
)
202 struct d3d_blend_state
*state
= impl_from_ID3D10BlendState(iface
);
204 TRACE("iface %p.\n", iface
);
206 return d3d11_blend_state_AddRef(&state
->ID3D11BlendState1_iface
);
209 static ULONG STDMETHODCALLTYPE
d3d10_blend_state_Release(ID3D10BlendState1
*iface
)
211 struct d3d_blend_state
*state
= impl_from_ID3D10BlendState(iface
);
213 TRACE("iface %p.\n", iface
);
215 return d3d11_blend_state_Release(&state
->ID3D11BlendState1_iface
);
218 /* ID3D10DeviceChild methods */
220 static void STDMETHODCALLTYPE
d3d10_blend_state_GetDevice(ID3D10BlendState1
*iface
, ID3D10Device
**device
)
222 struct d3d_blend_state
*state
= impl_from_ID3D10BlendState(iface
);
224 TRACE("iface %p, device %p.\n", iface
, device
);
226 ID3D11Device2_QueryInterface(state
->device
, &IID_ID3D10Device
, (void **)device
);
229 static HRESULT STDMETHODCALLTYPE
d3d10_blend_state_GetPrivateData(ID3D10BlendState1
*iface
,
230 REFGUID guid
, UINT
*data_size
, void *data
)
232 struct d3d_blend_state
*state
= impl_from_ID3D10BlendState(iface
);
234 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
235 iface
, debugstr_guid(guid
), data_size
, data
);
237 return d3d_get_private_data(&state
->private_store
, guid
, data_size
, data
);
240 static HRESULT STDMETHODCALLTYPE
d3d10_blend_state_SetPrivateData(ID3D10BlendState1
*iface
,
241 REFGUID guid
, UINT data_size
, const void *data
)
243 struct d3d_blend_state
*state
= impl_from_ID3D10BlendState(iface
);
245 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
246 iface
, debugstr_guid(guid
), data_size
, data
);
248 return d3d_set_private_data(&state
->private_store
, guid
, data_size
, data
);
251 static HRESULT STDMETHODCALLTYPE
d3d10_blend_state_SetPrivateDataInterface(ID3D10BlendState1
*iface
,
252 REFGUID guid
, const IUnknown
*data
)
254 struct d3d_blend_state
*state
= impl_from_ID3D10BlendState(iface
);
256 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
258 return d3d_set_private_data_interface(&state
->private_store
, guid
, data
);
261 /* ID3D10BlendState methods */
263 static D3D10_BLEND
d3d10_blend_from_d3d11(D3D11_BLEND factor
)
265 return (D3D10_BLEND
)factor
;
268 static D3D10_BLEND_OP
d3d10_blend_op_from_d3d11(D3D11_BLEND_OP op
)
270 return (D3D10_BLEND_OP
)op
;
273 static void STDMETHODCALLTYPE
d3d10_blend_state_GetDesc(ID3D10BlendState1
*iface
, D3D10_BLEND_DESC
*desc
)
275 struct d3d_blend_state
*state
= impl_from_ID3D10BlendState(iface
);
276 const D3D11_BLEND_DESC1
*d3d11_desc
= &state
->desc
;
279 TRACE("iface %p, desc %p.\n", iface
, desc
);
281 desc
->AlphaToCoverageEnable
= d3d11_desc
->AlphaToCoverageEnable
;
282 desc
->SrcBlend
= d3d10_blend_from_d3d11(d3d11_desc
->RenderTarget
[0].SrcBlend
);
283 desc
->DestBlend
= d3d10_blend_from_d3d11(d3d11_desc
->RenderTarget
[0].DestBlend
);
284 desc
->BlendOp
= d3d10_blend_op_from_d3d11(d3d11_desc
->RenderTarget
[0].BlendOp
);
285 desc
->SrcBlendAlpha
= d3d10_blend_from_d3d11(d3d11_desc
->RenderTarget
[0].SrcBlendAlpha
);
286 desc
->DestBlendAlpha
= d3d10_blend_from_d3d11(d3d11_desc
->RenderTarget
[0].DestBlendAlpha
);
287 desc
->BlendOpAlpha
= d3d10_blend_op_from_d3d11(d3d11_desc
->RenderTarget
[0].BlendOpAlpha
);
288 for (i
= 0; i
< D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT
; ++i
)
290 desc
->BlendEnable
[i
] = d3d11_desc
->RenderTarget
[i
].BlendEnable
;
291 desc
->RenderTargetWriteMask
[i
] = d3d11_desc
->RenderTarget
[i
].RenderTargetWriteMask
;
295 static void STDMETHODCALLTYPE
d3d10_blend_state_GetDesc1(ID3D10BlendState1
*iface
, D3D10_BLEND_DESC1
*desc
)
297 struct d3d_blend_state
*state
= impl_from_ID3D10BlendState(iface
);
299 TRACE("iface %p, desc %p.\n", iface
, desc
);
301 d3d11_blend_state_GetDesc(&state
->ID3D11BlendState1_iface
, (D3D11_BLEND_DESC
*)desc
);
304 static const struct ID3D10BlendState1Vtbl d3d10_blend_state_vtbl
=
306 /* IUnknown methods */
307 d3d10_blend_state_QueryInterface
,
308 d3d10_blend_state_AddRef
,
309 d3d10_blend_state_Release
,
310 /* ID3D10DeviceChild methods */
311 d3d10_blend_state_GetDevice
,
312 d3d10_blend_state_GetPrivateData
,
313 d3d10_blend_state_SetPrivateData
,
314 d3d10_blend_state_SetPrivateDataInterface
,
315 /* ID3D10BlendState methods */
316 d3d10_blend_state_GetDesc
,
317 /* ID3D10BlendState1 methods */
318 d3d10_blend_state_GetDesc1
,
321 static void STDMETHODCALLTYPE
d3d_blend_state_wined3d_object_destroyed(void *parent
)
323 struct d3d_blend_state
*state
= parent
;
324 struct d3d_device
*device
= impl_from_ID3D11Device2(state
->device
);
326 wine_rb_remove(&device
->blend_states
, &state
->entry
);
327 wined3d_private_store_cleanup(&state
->private_store
);
331 static const struct wined3d_parent_ops d3d_blend_state_wined3d_parent_ops
=
333 d3d_blend_state_wined3d_object_destroyed
,
336 static enum wined3d_blend
wined3d_blend_from_d3d11(D3D11_BLEND factor
)
338 return (enum wined3d_blend
)factor
;
341 static enum wined3d_blend_op
wined3d_blend_op_from_d3d11(D3D11_BLEND_OP op
)
343 return (enum wined3d_blend_op
)op
;
346 HRESULT
d3d_blend_state_create(struct d3d_device
*device
, const D3D11_BLEND_DESC1
*desc
,
347 struct d3d_blend_state
**state
)
349 struct wined3d_blend_state_desc wined3d_desc
;
350 struct d3d_blend_state
*object
;
351 struct wine_rb_entry
*entry
;
352 D3D11_BLEND_DESC1 tmp_desc
;
359 /* D3D11_RENDER_TARGET_BLEND_DESC1 has a hole, which is a problem because we use
360 * D3D11_BLEND_DESC1 as a key in the rbtree. */
361 memset(&tmp_desc
, 0, sizeof(tmp_desc
));
362 tmp_desc
.AlphaToCoverageEnable
= desc
->AlphaToCoverageEnable
;
363 tmp_desc
.IndependentBlendEnable
= desc
->IndependentBlendEnable
;
364 for (i
= 0; i
< D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT
; ++i
)
366 j
= desc
->IndependentBlendEnable
? i
: 0;
367 tmp_desc
.RenderTarget
[i
].BlendEnable
= desc
->RenderTarget
[j
].BlendEnable
;
368 if (tmp_desc
.RenderTarget
[i
].BlendEnable
)
370 tmp_desc
.RenderTarget
[i
].SrcBlend
= desc
->RenderTarget
[j
].SrcBlend
;
371 tmp_desc
.RenderTarget
[i
].DestBlend
= desc
->RenderTarget
[j
].DestBlend
;
372 tmp_desc
.RenderTarget
[i
].BlendOp
= desc
->RenderTarget
[j
].BlendOp
;
373 tmp_desc
.RenderTarget
[i
].SrcBlendAlpha
= desc
->RenderTarget
[j
].SrcBlendAlpha
;
374 tmp_desc
.RenderTarget
[i
].DestBlendAlpha
= desc
->RenderTarget
[j
].DestBlendAlpha
;
375 tmp_desc
.RenderTarget
[i
].BlendOpAlpha
= desc
->RenderTarget
[j
].BlendOpAlpha
;
379 tmp_desc
.RenderTarget
[i
].SrcBlend
= D3D11_BLEND_ONE
;
380 tmp_desc
.RenderTarget
[i
].DestBlend
= D3D11_BLEND_ZERO
;
381 tmp_desc
.RenderTarget
[i
].BlendOp
= D3D11_BLEND_OP_ADD
;
382 tmp_desc
.RenderTarget
[i
].SrcBlendAlpha
= D3D11_BLEND_ONE
;
383 tmp_desc
.RenderTarget
[i
].DestBlendAlpha
= D3D11_BLEND_ZERO
;
384 tmp_desc
.RenderTarget
[i
].BlendOpAlpha
= D3D11_BLEND_OP_ADD
;
387 tmp_desc
.RenderTarget
[i
].LogicOpEnable
= desc
->RenderTarget
[j
].LogicOpEnable
;
388 if (tmp_desc
.RenderTarget
[i
].LogicOpEnable
)
389 tmp_desc
.RenderTarget
[i
].LogicOp
= desc
->RenderTarget
[j
].LogicOp
;
391 tmp_desc
.RenderTarget
[i
].LogicOp
= D3D11_LOGIC_OP_NOOP
;
393 tmp_desc
.RenderTarget
[i
].RenderTargetWriteMask
= desc
->RenderTarget
[j
].RenderTargetWriteMask
;
396 wined3d_mutex_lock();
397 if ((entry
= wine_rb_get(&device
->blend_states
, &tmp_desc
)))
399 object
= WINE_RB_ENTRY_VALUE(entry
, struct d3d_blend_state
, entry
);
401 TRACE("Returning existing blend state %p.\n", object
);
402 ID3D11BlendState1_AddRef(&object
->ID3D11BlendState1_iface
);
404 wined3d_mutex_unlock();
409 if (!(object
= calloc(1, sizeof(*object
))))
411 wined3d_mutex_unlock();
412 return E_OUTOFMEMORY
;
415 object
->ID3D11BlendState1_iface
.lpVtbl
= &d3d11_blend_state_vtbl
;
416 object
->ID3D10BlendState1_iface
.lpVtbl
= &d3d10_blend_state_vtbl
;
417 object
->refcount
= 1;
418 wined3d_private_store_init(&object
->private_store
);
419 object
->desc
= tmp_desc
;
421 if (wine_rb_put(&device
->blend_states
, &tmp_desc
, &object
->entry
) == -1)
423 ERR("Failed to insert blend state entry.\n");
424 wined3d_private_store_cleanup(&object
->private_store
);
426 wined3d_mutex_unlock();
430 wined3d_desc
.alpha_to_coverage
= desc
->AlphaToCoverageEnable
;
431 wined3d_desc
.independent
= desc
->IndependentBlendEnable
;
432 for (i
= 0; i
< D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT
; ++i
)
434 wined3d_desc
.rt
[i
].enable
= desc
->RenderTarget
[i
].BlendEnable
;
435 wined3d_desc
.rt
[i
].src
= wined3d_blend_from_d3d11(desc
->RenderTarget
[i
].SrcBlend
);
436 wined3d_desc
.rt
[i
].dst
= wined3d_blend_from_d3d11(desc
->RenderTarget
[i
].DestBlend
);
437 wined3d_desc
.rt
[i
].op
= wined3d_blend_op_from_d3d11(desc
->RenderTarget
[i
].BlendOp
);
438 wined3d_desc
.rt
[i
].src_alpha
= wined3d_blend_from_d3d11(desc
->RenderTarget
[i
].SrcBlendAlpha
);
439 wined3d_desc
.rt
[i
].dst_alpha
= wined3d_blend_from_d3d11(desc
->RenderTarget
[i
].DestBlendAlpha
);
440 wined3d_desc
.rt
[i
].op_alpha
= wined3d_blend_op_from_d3d11(desc
->RenderTarget
[i
].BlendOpAlpha
);
441 wined3d_desc
.rt
[i
].writemask
= desc
->RenderTarget
[i
].RenderTargetWriteMask
;
444 if (desc
->RenderTarget
[0].LogicOpEnable
&& desc
->RenderTarget
[0].LogicOp
!= D3D11_LOGIC_OP_NOOP
)
445 FIXME("Ignoring logic op %#x.\n", desc
->RenderTarget
[0].LogicOp
);
447 /* We cannot fail after creating a wined3d_blend_state object. It
448 * would lead to double free. */
449 if (FAILED(hr
= wined3d_blend_state_create(device
->wined3d_device
, &wined3d_desc
,
450 object
, &d3d_blend_state_wined3d_parent_ops
, &object
->wined3d_state
)))
452 WARN("Failed to create wined3d blend state, hr %#lx.\n", hr
);
453 wined3d_private_store_cleanup(&object
->private_store
);
454 wine_rb_remove(&device
->blend_states
, &object
->entry
);
456 wined3d_mutex_unlock();
459 wined3d_mutex_unlock();
461 ID3D11Device2_AddRef(object
->device
= &device
->ID3D11Device2_iface
);
463 TRACE("Created blend state %p.\n", object
);
469 struct d3d_blend_state
*unsafe_impl_from_ID3D11BlendState(ID3D11BlendState
*iface
)
473 assert(iface
->lpVtbl
== (ID3D11BlendStateVtbl
*)&d3d11_blend_state_vtbl
);
475 return impl_from_ID3D11BlendState1((ID3D11BlendState1
*)iface
);
478 struct d3d_blend_state
*unsafe_impl_from_ID3D10BlendState(ID3D10BlendState
*iface
)
482 assert(iface
->lpVtbl
== (ID3D10BlendStateVtbl
*)&d3d10_blend_state_vtbl
);
484 return impl_from_ID3D10BlendState((ID3D10BlendState1
*)iface
);
487 /* ID3D11DepthStencilState methods */
489 static HRESULT STDMETHODCALLTYPE
d3d11_depthstencil_state_QueryInterface(ID3D11DepthStencilState
*iface
,
490 REFIID riid
, void **object
)
492 struct d3d_depthstencil_state
*state
= impl_from_ID3D11DepthStencilState(iface
);
494 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
496 if (IsEqualGUID(riid
, &IID_ID3D11DepthStencilState
)
497 || IsEqualGUID(riid
, &IID_ID3D11DeviceChild
)
498 || IsEqualGUID(riid
, &IID_IUnknown
))
500 ID3D11DepthStencilState_AddRef(iface
);
505 if (IsEqualGUID(riid
, &IID_ID3D10DepthStencilState
)
506 || IsEqualGUID(riid
, &IID_ID3D10DeviceChild
))
508 ID3D10DepthStencilState_AddRef(&state
->ID3D10DepthStencilState_iface
);
509 *object
= &state
->ID3D10DepthStencilState_iface
;
513 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
516 return E_NOINTERFACE
;
519 static ULONG STDMETHODCALLTYPE
d3d11_depthstencil_state_AddRef(ID3D11DepthStencilState
*iface
)
521 struct d3d_depthstencil_state
*state
= impl_from_ID3D11DepthStencilState(iface
);
522 ULONG refcount
= InterlockedIncrement(&state
->refcount
);
524 TRACE("%p increasing refcount to %lu.\n", state
, refcount
);
528 ID3D11Device2_AddRef(state
->device
);
529 wined3d_depth_stencil_state_incref(state
->wined3d_state
);
535 static ULONG STDMETHODCALLTYPE
d3d11_depthstencil_state_Release(ID3D11DepthStencilState
*iface
)
537 struct d3d_depthstencil_state
*state
= impl_from_ID3D11DepthStencilState(iface
);
538 ULONG refcount
= InterlockedDecrement(&state
->refcount
);
540 TRACE("%p decreasing refcount to %lu.\n", state
, refcount
);
544 ID3D11Device2
*device
= state
->device
;
546 wined3d_depth_stencil_state_decref(state
->wined3d_state
);
547 ID3D11Device2_Release(device
);
553 static void STDMETHODCALLTYPE
d3d11_depthstencil_state_GetDevice(ID3D11DepthStencilState
*iface
,
554 ID3D11Device
**device
)
556 struct d3d_depthstencil_state
*state
= impl_from_ID3D11DepthStencilState(iface
);
558 TRACE("iface %p, device %p.\n", iface
, device
);
560 *device
= (ID3D11Device
*)state
->device
;
561 ID3D11Device_AddRef(*device
);
564 static HRESULT STDMETHODCALLTYPE
d3d11_depthstencil_state_GetPrivateData(ID3D11DepthStencilState
*iface
,
565 REFGUID guid
, UINT
*data_size
, void *data
)
567 struct d3d_depthstencil_state
*state
= impl_from_ID3D11DepthStencilState(iface
);
569 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
571 return d3d_get_private_data(&state
->private_store
, guid
, data_size
, data
);
574 static HRESULT STDMETHODCALLTYPE
d3d11_depthstencil_state_SetPrivateData(ID3D11DepthStencilState
*iface
,
575 REFGUID guid
, UINT data_size
, const void *data
)
577 struct d3d_depthstencil_state
*state
= impl_from_ID3D11DepthStencilState(iface
);
579 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
581 return d3d_set_private_data(&state
->private_store
, guid
, data_size
, data
);
584 static HRESULT STDMETHODCALLTYPE
d3d11_depthstencil_state_SetPrivateDataInterface(ID3D11DepthStencilState
*iface
,
585 REFGUID guid
, const IUnknown
*data
)
587 struct d3d_depthstencil_state
*state
= impl_from_ID3D11DepthStencilState(iface
);
589 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
591 return d3d_set_private_data_interface(&state
->private_store
, guid
, data
);
594 static void STDMETHODCALLTYPE
d3d11_depthstencil_state_GetDesc(ID3D11DepthStencilState
*iface
,
595 D3D11_DEPTH_STENCIL_DESC
*desc
)
597 struct d3d_depthstencil_state
*state
= impl_from_ID3D11DepthStencilState(iface
);
599 TRACE("iface %p, desc %p.\n", iface
, desc
);
604 static const struct ID3D11DepthStencilStateVtbl d3d11_depthstencil_state_vtbl
=
606 /* IUnknown methods */
607 d3d11_depthstencil_state_QueryInterface
,
608 d3d11_depthstencil_state_AddRef
,
609 d3d11_depthstencil_state_Release
,
610 /* ID3D11DeviceChild methods */
611 d3d11_depthstencil_state_GetDevice
,
612 d3d11_depthstencil_state_GetPrivateData
,
613 d3d11_depthstencil_state_SetPrivateData
,
614 d3d11_depthstencil_state_SetPrivateDataInterface
,
615 /* ID3D11DepthStencilState methods */
616 d3d11_depthstencil_state_GetDesc
,
619 /* ID3D10DepthStencilState methods */
621 static inline struct d3d_depthstencil_state
*impl_from_ID3D10DepthStencilState(ID3D10DepthStencilState
*iface
)
623 return CONTAINING_RECORD(iface
, struct d3d_depthstencil_state
, ID3D10DepthStencilState_iface
);
626 /* IUnknown methods */
628 static HRESULT STDMETHODCALLTYPE
d3d10_depthstencil_state_QueryInterface(ID3D10DepthStencilState
*iface
,
629 REFIID riid
, void **object
)
631 struct d3d_depthstencil_state
*state
= impl_from_ID3D10DepthStencilState(iface
);
633 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
635 return d3d11_depthstencil_state_QueryInterface(&state
->ID3D11DepthStencilState_iface
, riid
, object
);
638 static ULONG STDMETHODCALLTYPE
d3d10_depthstencil_state_AddRef(ID3D10DepthStencilState
*iface
)
640 struct d3d_depthstencil_state
*state
= impl_from_ID3D10DepthStencilState(iface
);
642 TRACE("iface %p.\n", iface
);
644 return d3d11_depthstencil_state_AddRef(&state
->ID3D11DepthStencilState_iface
);
647 static ULONG STDMETHODCALLTYPE
d3d10_depthstencil_state_Release(ID3D10DepthStencilState
*iface
)
649 struct d3d_depthstencil_state
*state
= impl_from_ID3D10DepthStencilState(iface
);
651 TRACE("iface %p.\n", iface
);
653 return d3d11_depthstencil_state_Release(&state
->ID3D11DepthStencilState_iface
);
656 /* ID3D10DeviceChild methods */
658 static void STDMETHODCALLTYPE
d3d10_depthstencil_state_GetDevice(ID3D10DepthStencilState
*iface
, ID3D10Device
**device
)
660 struct d3d_depthstencil_state
*state
= impl_from_ID3D10DepthStencilState(iface
);
662 TRACE("iface %p, device %p.\n", iface
, device
);
664 ID3D11Device2_QueryInterface(state
->device
, &IID_ID3D10Device
, (void **)device
);
667 static HRESULT STDMETHODCALLTYPE
d3d10_depthstencil_state_GetPrivateData(ID3D10DepthStencilState
*iface
,
668 REFGUID guid
, UINT
*data_size
, void *data
)
670 struct d3d_depthstencil_state
*state
= impl_from_ID3D10DepthStencilState(iface
);
672 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
673 iface
, debugstr_guid(guid
), data_size
, data
);
675 return d3d_get_private_data(&state
->private_store
, guid
, data_size
, data
);
678 static HRESULT STDMETHODCALLTYPE
d3d10_depthstencil_state_SetPrivateData(ID3D10DepthStencilState
*iface
,
679 REFGUID guid
, UINT data_size
, const void *data
)
681 struct d3d_depthstencil_state
*state
= impl_from_ID3D10DepthStencilState(iface
);
683 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
684 iface
, debugstr_guid(guid
), data_size
, data
);
686 return d3d_set_private_data(&state
->private_store
, guid
, data_size
, data
);
689 static HRESULT STDMETHODCALLTYPE
d3d10_depthstencil_state_SetPrivateDataInterface(ID3D10DepthStencilState
*iface
,
690 REFGUID guid
, const IUnknown
*data
)
692 struct d3d_depthstencil_state
*state
= impl_from_ID3D10DepthStencilState(iface
);
694 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
696 return d3d_set_private_data_interface(&state
->private_store
, guid
, data
);
699 /* ID3D10DepthStencilState methods */
701 static void STDMETHODCALLTYPE
d3d10_depthstencil_state_GetDesc(ID3D10DepthStencilState
*iface
,
702 D3D10_DEPTH_STENCIL_DESC
*desc
)
704 struct d3d_depthstencil_state
*state
= impl_from_ID3D10DepthStencilState(iface
);
706 TRACE("iface %p, desc %p.\n", iface
, desc
);
708 memcpy(desc
, &state
->desc
, sizeof(*desc
));
711 static const struct ID3D10DepthStencilStateVtbl d3d10_depthstencil_state_vtbl
=
713 /* IUnknown methods */
714 d3d10_depthstencil_state_QueryInterface
,
715 d3d10_depthstencil_state_AddRef
,
716 d3d10_depthstencil_state_Release
,
717 /* ID3D10DeviceChild methods */
718 d3d10_depthstencil_state_GetDevice
,
719 d3d10_depthstencil_state_GetPrivateData
,
720 d3d10_depthstencil_state_SetPrivateData
,
721 d3d10_depthstencil_state_SetPrivateDataInterface
,
722 /* ID3D10DepthStencilState methods */
723 d3d10_depthstencil_state_GetDesc
,
726 static void STDMETHODCALLTYPE
d3d_depthstencil_state_wined3d_object_destroyed(void *parent
)
728 struct d3d_depthstencil_state
*state
= parent
;
729 struct d3d_device
*device
= impl_from_ID3D11Device2(state
->device
);
731 wine_rb_remove(&device
->depthstencil_states
, &state
->entry
);
732 wined3d_private_store_cleanup(&state
->private_store
);
736 static const struct wined3d_parent_ops d3d_depthstencil_state_wined3d_parent_ops
=
738 d3d_depthstencil_state_wined3d_object_destroyed
,
741 static enum wined3d_cmp_func
wined3d_cmp_func_from_d3d11(D3D11_COMPARISON_FUNC func
)
743 return (enum wined3d_cmp_func
)func
;
746 static enum wined3d_stencil_op
wined3d_stencil_op_from_d3d11(D3D11_STENCIL_OP stencil_op
)
748 return (enum wined3d_stencil_op
)stencil_op
;
751 HRESULT
d3d_depthstencil_state_create(struct d3d_device
*device
, const D3D11_DEPTH_STENCIL_DESC
*desc
,
752 struct d3d_depthstencil_state
**state
)
754 struct wined3d_depth_stencil_state_desc wined3d_desc
;
755 struct d3d_depthstencil_state
*object
;
756 D3D11_DEPTH_STENCIL_DESC tmp_desc
;
757 struct wine_rb_entry
*entry
;
763 /* D3D11_DEPTH_STENCIL_DESC has a hole, which is a problem because we use
764 * it as a key in the rbtree. */
765 memset(&tmp_desc
, 0, sizeof(tmp_desc
));
766 tmp_desc
.DepthEnable
= desc
->DepthEnable
;
767 if (desc
->DepthEnable
)
769 tmp_desc
.DepthWriteMask
= desc
->DepthWriteMask
;
770 tmp_desc
.DepthFunc
= desc
->DepthFunc
;
774 tmp_desc
.DepthWriteMask
= D3D11_DEPTH_WRITE_MASK_ALL
;
775 tmp_desc
.DepthFunc
= D3D11_COMPARISON_LESS
;
777 tmp_desc
.StencilEnable
= desc
->StencilEnable
;
778 if (desc
->StencilEnable
)
780 tmp_desc
.StencilReadMask
= desc
->StencilReadMask
;
781 tmp_desc
.StencilWriteMask
= desc
->StencilWriteMask
;
782 tmp_desc
.FrontFace
= desc
->FrontFace
;
783 tmp_desc
.BackFace
= desc
->BackFace
;
787 tmp_desc
.StencilReadMask
= D3D11_DEFAULT_STENCIL_READ_MASK
;
788 tmp_desc
.StencilWriteMask
= D3D11_DEFAULT_STENCIL_WRITE_MASK
;
789 tmp_desc
.FrontFace
.StencilFailOp
= D3D11_STENCIL_OP_KEEP
;
790 tmp_desc
.FrontFace
.StencilDepthFailOp
= D3D11_STENCIL_OP_KEEP
;
791 tmp_desc
.FrontFace
.StencilPassOp
= D3D11_STENCIL_OP_KEEP
;
792 tmp_desc
.FrontFace
.StencilFunc
= D3D11_COMPARISON_ALWAYS
;
793 tmp_desc
.BackFace
.StencilFailOp
= D3D11_STENCIL_OP_KEEP
;
794 tmp_desc
.BackFace
.StencilDepthFailOp
= D3D11_STENCIL_OP_KEEP
;
795 tmp_desc
.BackFace
.StencilPassOp
= D3D11_STENCIL_OP_KEEP
;
796 tmp_desc
.BackFace
.StencilFunc
= D3D11_COMPARISON_ALWAYS
;
799 wined3d_mutex_lock();
800 if ((entry
= wine_rb_get(&device
->depthstencil_states
, &tmp_desc
)))
802 object
= WINE_RB_ENTRY_VALUE(entry
, struct d3d_depthstencil_state
, entry
);
804 TRACE("Returning existing depthstencil state %p.\n", object
);
805 ID3D11DepthStencilState_AddRef(&object
->ID3D11DepthStencilState_iface
);
807 wined3d_mutex_unlock();
812 if (!(object
= calloc(1, sizeof(*object
))))
814 wined3d_mutex_unlock();
815 return E_OUTOFMEMORY
;
818 object
->ID3D11DepthStencilState_iface
.lpVtbl
= &d3d11_depthstencil_state_vtbl
;
819 object
->ID3D10DepthStencilState_iface
.lpVtbl
= &d3d10_depthstencil_state_vtbl
;
820 object
->refcount
= 1;
821 wined3d_private_store_init(&object
->private_store
);
822 object
->desc
= tmp_desc
;
824 if (wine_rb_put(&device
->depthstencil_states
, &tmp_desc
, &object
->entry
) == -1)
826 ERR("Failed to insert depth/stencil state entry.\n");
827 wined3d_private_store_cleanup(&object
->private_store
);
829 wined3d_mutex_unlock();
833 wined3d_desc
.depth
= desc
->DepthEnable
;
834 wined3d_desc
.depth_write
= desc
->DepthWriteMask
;
835 wined3d_desc
.depth_func
= wined3d_cmp_func_from_d3d11(desc
->DepthFunc
);
836 wined3d_desc
.stencil
= desc
->StencilEnable
;
837 wined3d_desc
.stencil_read_mask
= desc
->StencilReadMask
;
838 wined3d_desc
.stencil_write_mask
= desc
->StencilWriteMask
;
839 wined3d_desc
.front
.fail_op
= wined3d_stencil_op_from_d3d11(desc
->FrontFace
.StencilFailOp
);
840 wined3d_desc
.front
.depth_fail_op
= wined3d_stencil_op_from_d3d11(desc
->FrontFace
.StencilDepthFailOp
);
841 wined3d_desc
.front
.pass_op
= wined3d_stencil_op_from_d3d11(desc
->FrontFace
.StencilPassOp
);
842 wined3d_desc
.front
.func
= wined3d_cmp_func_from_d3d11(desc
->FrontFace
.StencilFunc
);
843 wined3d_desc
.back
.fail_op
= wined3d_stencil_op_from_d3d11(desc
->BackFace
.StencilFailOp
);
844 wined3d_desc
.back
.depth_fail_op
= wined3d_stencil_op_from_d3d11(desc
->BackFace
.StencilDepthFailOp
);
845 wined3d_desc
.back
.pass_op
= wined3d_stencil_op_from_d3d11(desc
->BackFace
.StencilPassOp
);
846 wined3d_desc
.back
.func
= wined3d_cmp_func_from_d3d11(desc
->BackFace
.StencilFunc
);
848 /* We cannot fail after creating a wined3d_depth_stencil_state object. It
849 * would lead to double free. */
850 if (FAILED(hr
= wined3d_depth_stencil_state_create(device
->wined3d_device
, &wined3d_desc
,
851 object
, &d3d_depthstencil_state_wined3d_parent_ops
, &object
->wined3d_state
)))
853 WARN("Failed to create wined3d depth/stencil state, hr %#lx.\n", hr
);
854 wined3d_private_store_cleanup(&object
->private_store
);
855 wine_rb_remove(&device
->depthstencil_states
, &object
->entry
);
857 wined3d_mutex_unlock();
860 wined3d_mutex_unlock();
862 ID3D11Device2_AddRef(object
->device
= &device
->ID3D11Device2_iface
);
864 TRACE("Created depth/stencil state %p.\n", object
);
870 struct d3d_depthstencil_state
*unsafe_impl_from_ID3D11DepthStencilState(ID3D11DepthStencilState
*iface
)
874 assert(iface
->lpVtbl
== &d3d11_depthstencil_state_vtbl
);
876 return impl_from_ID3D11DepthStencilState(iface
);
879 struct d3d_depthstencil_state
*unsafe_impl_from_ID3D10DepthStencilState(ID3D10DepthStencilState
*iface
)
883 assert(iface
->lpVtbl
== &d3d10_depthstencil_state_vtbl
);
885 return impl_from_ID3D10DepthStencilState(iface
);
888 /* ID3D11RasterizerState methods */
890 static inline struct d3d_rasterizer_state
*impl_from_ID3D11RasterizerState1(ID3D11RasterizerState1
*iface
)
892 return CONTAINING_RECORD(iface
, struct d3d_rasterizer_state
, ID3D11RasterizerState1_iface
);
895 static HRESULT STDMETHODCALLTYPE
d3d11_rasterizer_state_QueryInterface(ID3D11RasterizerState1
*iface
,
896 REFIID riid
, void **object
)
898 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState1(iface
);
900 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
902 if (IsEqualGUID(riid
, &IID_ID3D11RasterizerState
)
903 || IsEqualGUID(riid
, &IID_ID3D11RasterizerState1
)
904 || IsEqualGUID(riid
, &IID_ID3D11DeviceChild
)
905 || IsEqualGUID(riid
, &IID_IUnknown
))
907 ID3D11RasterizerState1_AddRef(iface
);
912 if (IsEqualGUID(riid
, &IID_ID3D10RasterizerState
)
913 || IsEqualGUID(riid
, &IID_ID3D10DeviceChild
))
915 ID3D10RasterizerState_AddRef(&state
->ID3D10RasterizerState_iface
);
916 *object
= &state
->ID3D10RasterizerState_iface
;
920 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
923 return E_NOINTERFACE
;
926 static ULONG STDMETHODCALLTYPE
d3d11_rasterizer_state_AddRef(ID3D11RasterizerState1
*iface
)
928 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState1(iface
);
929 ULONG refcount
= InterlockedIncrement(&state
->refcount
);
931 TRACE("%p increasing refcount to %lu.\n", state
, refcount
);
935 ID3D11Device2_AddRef(state
->device
);
936 wined3d_rasterizer_state_incref(state
->wined3d_state
);
942 static ULONG STDMETHODCALLTYPE
d3d11_rasterizer_state_Release(ID3D11RasterizerState1
*iface
)
944 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState1(iface
);
945 ULONG refcount
= InterlockedDecrement(&state
->refcount
);
947 TRACE("%p decreasing refcount to %lu.\n", state
, refcount
);
951 ID3D11Device2
*device
= state
->device
;
952 wined3d_rasterizer_state_decref(state
->wined3d_state
);
953 ID3D11Device2_Release(device
);
959 static void STDMETHODCALLTYPE
d3d11_rasterizer_state_GetDevice(ID3D11RasterizerState1
*iface
,
960 ID3D11Device
**device
)
962 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState1(iface
);
964 TRACE("iface %p, device %p.\n", iface
, device
);
966 *device
= (ID3D11Device
*)state
->device
;
967 ID3D11Device_AddRef(*device
);
970 static HRESULT STDMETHODCALLTYPE
d3d11_rasterizer_state_GetPrivateData(ID3D11RasterizerState1
*iface
,
971 REFGUID guid
, UINT
*data_size
, void *data
)
973 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState1(iface
);
975 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
977 return d3d_get_private_data(&state
->private_store
, guid
, data_size
, data
);
980 static HRESULT STDMETHODCALLTYPE
d3d11_rasterizer_state_SetPrivateData(ID3D11RasterizerState1
*iface
,
981 REFGUID guid
, UINT data_size
, const void *data
)
983 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState1(iface
);
985 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
987 return d3d_set_private_data(&state
->private_store
, guid
, data_size
, data
);
990 static HRESULT STDMETHODCALLTYPE
d3d11_rasterizer_state_SetPrivateDataInterface(ID3D11RasterizerState1
*iface
,
991 REFGUID guid
, const IUnknown
*data
)
993 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState1(iface
);
995 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
997 return d3d_set_private_data_interface(&state
->private_store
, guid
, data
);
1000 static void STDMETHODCALLTYPE
d3d11_rasterizer_state_GetDesc(ID3D11RasterizerState1
*iface
,
1001 D3D11_RASTERIZER_DESC
*desc
)
1003 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState1(iface
);
1005 TRACE("iface %p, desc %p.\n", iface
, desc
);
1007 memcpy(desc
, &state
->desc
, sizeof(*desc
));
1010 static void STDMETHODCALLTYPE
d3d11_rasterizer_state_GetDesc1(ID3D11RasterizerState1
*iface
,
1011 D3D11_RASTERIZER_DESC1
*desc
)
1013 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState1(iface
);
1015 TRACE("iface %p, desc %p.\n", iface
, desc
);
1017 *desc
= state
->desc
;
1020 static const struct ID3D11RasterizerState1Vtbl d3d11_rasterizer_state_vtbl
=
1022 /* IUnknown methods */
1023 d3d11_rasterizer_state_QueryInterface
,
1024 d3d11_rasterizer_state_AddRef
,
1025 d3d11_rasterizer_state_Release
,
1026 /* ID3D11DeviceChild methods */
1027 d3d11_rasterizer_state_GetDevice
,
1028 d3d11_rasterizer_state_GetPrivateData
,
1029 d3d11_rasterizer_state_SetPrivateData
,
1030 d3d11_rasterizer_state_SetPrivateDataInterface
,
1031 /* ID3D11RasterizerState methods */
1032 d3d11_rasterizer_state_GetDesc
,
1033 /* ID3D11RasterizerState1 methods */
1034 d3d11_rasterizer_state_GetDesc1
,
1037 /* ID3D10RasterizerState methods */
1039 static inline struct d3d_rasterizer_state
*impl_from_ID3D10RasterizerState(ID3D10RasterizerState
*iface
)
1041 return CONTAINING_RECORD(iface
, struct d3d_rasterizer_state
, ID3D10RasterizerState_iface
);
1044 /* IUnknown methods */
1046 static HRESULT STDMETHODCALLTYPE
d3d10_rasterizer_state_QueryInterface(ID3D10RasterizerState
*iface
,
1047 REFIID riid
, void **object
)
1049 struct d3d_rasterizer_state
*state
= impl_from_ID3D10RasterizerState(iface
);
1051 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
1053 return d3d11_rasterizer_state_QueryInterface(&state
->ID3D11RasterizerState1_iface
, riid
, object
);
1056 static ULONG STDMETHODCALLTYPE
d3d10_rasterizer_state_AddRef(ID3D10RasterizerState
*iface
)
1058 struct d3d_rasterizer_state
*state
= impl_from_ID3D10RasterizerState(iface
);
1060 TRACE("iface %p.\n", iface
);
1062 return d3d11_rasterizer_state_AddRef(&state
->ID3D11RasterizerState1_iface
);
1065 static ULONG STDMETHODCALLTYPE
d3d10_rasterizer_state_Release(ID3D10RasterizerState
*iface
)
1067 struct d3d_rasterizer_state
*state
= impl_from_ID3D10RasterizerState(iface
);
1069 TRACE("iface %p.\n", state
);
1071 return d3d11_rasterizer_state_Release(&state
->ID3D11RasterizerState1_iface
);
1074 /* ID3D10DeviceChild methods */
1076 static void STDMETHODCALLTYPE
d3d10_rasterizer_state_GetDevice(ID3D10RasterizerState
*iface
, ID3D10Device
**device
)
1078 struct d3d_rasterizer_state
*state
= impl_from_ID3D10RasterizerState(iface
);
1080 TRACE("iface %p, device %p.\n", iface
, device
);
1082 ID3D11Device2_QueryInterface(state
->device
, &IID_ID3D10Device
, (void **)device
);
1085 static HRESULT STDMETHODCALLTYPE
d3d10_rasterizer_state_GetPrivateData(ID3D10RasterizerState
*iface
,
1086 REFGUID guid
, UINT
*data_size
, void *data
)
1088 struct d3d_rasterizer_state
*state
= impl_from_ID3D10RasterizerState(iface
);
1090 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
1091 iface
, debugstr_guid(guid
), data_size
, data
);
1093 return d3d_get_private_data(&state
->private_store
, guid
, data_size
, data
);
1096 static HRESULT STDMETHODCALLTYPE
d3d10_rasterizer_state_SetPrivateData(ID3D10RasterizerState
*iface
,
1097 REFGUID guid
, UINT data_size
, const void *data
)
1099 struct d3d_rasterizer_state
*state
= impl_from_ID3D10RasterizerState(iface
);
1101 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
1102 iface
, debugstr_guid(guid
), data_size
, data
);
1104 return d3d_set_private_data(&state
->private_store
, guid
, data_size
, data
);
1107 static HRESULT STDMETHODCALLTYPE
d3d10_rasterizer_state_SetPrivateDataInterface(ID3D10RasterizerState
*iface
,
1108 REFGUID guid
, const IUnknown
*data
)
1110 struct d3d_rasterizer_state
*state
= impl_from_ID3D10RasterizerState(iface
);
1112 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
1114 return d3d_set_private_data_interface(&state
->private_store
, guid
, data
);
1117 /* ID3D10RasterizerState methods */
1119 static void STDMETHODCALLTYPE
d3d10_rasterizer_state_GetDesc(ID3D10RasterizerState
*iface
,
1120 D3D10_RASTERIZER_DESC
*desc
)
1122 struct d3d_rasterizer_state
*state
= impl_from_ID3D10RasterizerState(iface
);
1124 TRACE("iface %p, desc %p.\n", iface
, desc
);
1126 memcpy(desc
, &state
->desc
, sizeof(*desc
));
1129 static const struct ID3D10RasterizerStateVtbl d3d10_rasterizer_state_vtbl
=
1131 /* IUnknown methods */
1132 d3d10_rasterizer_state_QueryInterface
,
1133 d3d10_rasterizer_state_AddRef
,
1134 d3d10_rasterizer_state_Release
,
1135 /* ID3D10DeviceChild methods */
1136 d3d10_rasterizer_state_GetDevice
,
1137 d3d10_rasterizer_state_GetPrivateData
,
1138 d3d10_rasterizer_state_SetPrivateData
,
1139 d3d10_rasterizer_state_SetPrivateDataInterface
,
1140 /* ID3D10RasterizerState methods */
1141 d3d10_rasterizer_state_GetDesc
,
1144 static void STDMETHODCALLTYPE
d3d_rasterizer_state_wined3d_object_destroyed(void *parent
)
1146 struct d3d_rasterizer_state
*state
= parent
;
1147 struct d3d_device
*device
= impl_from_ID3D11Device2(state
->device
);
1149 wine_rb_remove(&device
->rasterizer_states
, &state
->entry
);
1150 wined3d_private_store_cleanup(&state
->private_store
);
1154 static const struct wined3d_parent_ops d3d_rasterizer_state_wined3d_parent_ops
=
1156 d3d_rasterizer_state_wined3d_object_destroyed
,
1159 static enum wined3d_fill_mode
wined3d_fill_mode_from_d3d11(D3D11_FILL_MODE mode
)
1161 return (enum wined3d_fill_mode
)mode
;
1164 static enum wined3d_cull
wined3d_cull_from_d3d11(D3D11_CULL_MODE mode
)
1166 return (enum wined3d_cull
)mode
;
1169 static HRESULT
d3d_rasterizer_state_init(struct d3d_rasterizer_state
*state
, struct d3d_device
*device
,
1170 const D3D11_RASTERIZER_DESC1
*desc
)
1172 struct wined3d_rasterizer_state_desc wined3d_desc
;
1175 state
->ID3D11RasterizerState1_iface
.lpVtbl
= &d3d11_rasterizer_state_vtbl
;
1176 state
->ID3D10RasterizerState_iface
.lpVtbl
= &d3d10_rasterizer_state_vtbl
;
1177 state
->refcount
= 1;
1178 wined3d_private_store_init(&state
->private_store
);
1179 state
->desc
= *desc
;
1181 if (wine_rb_put(&device
->rasterizer_states
, desc
, &state
->entry
) == -1)
1183 ERR("Failed to insert rasterizer state entry.\n");
1184 wined3d_private_store_cleanup(&state
->private_store
);
1188 wined3d_desc
.fill_mode
= wined3d_fill_mode_from_d3d11(desc
->FillMode
);
1189 wined3d_desc
.cull_mode
= wined3d_cull_from_d3d11(desc
->CullMode
);
1190 wined3d_desc
.front_ccw
= desc
->FrontCounterClockwise
;
1191 wined3d_desc
.depth_bias
= desc
->DepthBias
;
1192 wined3d_desc
.depth_bias_clamp
= desc
->DepthBiasClamp
;
1193 wined3d_desc
.scale_bias
= desc
->SlopeScaledDepthBias
;
1194 wined3d_desc
.depth_clip
= desc
->DepthClipEnable
;
1195 wined3d_desc
.scissor
= desc
->ScissorEnable
;
1196 wined3d_desc
.line_antialias
= desc
->AntialiasedLineEnable
;
1198 if (desc
->MultisampleEnable
)
1200 static unsigned int once
;
1202 FIXME("Ignoring MultisampleEnable %#x.\n", desc
->MultisampleEnable
);
1205 if (desc
->ForcedSampleCount
)
1207 static unsigned int once
;
1209 FIXME("Ignoring ForcedSampleCount %#x.\n", desc
->ForcedSampleCount
);
1212 /* We cannot fail after creating a wined3d_rasterizer_state object. It
1213 * would lead to double free. */
1214 if (FAILED(hr
= wined3d_rasterizer_state_create(device
->wined3d_device
, &wined3d_desc
,
1215 state
, &d3d_rasterizer_state_wined3d_parent_ops
, &state
->wined3d_state
)))
1217 WARN("Failed to create wined3d rasteriser state, hr %#lx.\n", hr
);
1218 wined3d_private_store_cleanup(&state
->private_store
);
1219 wine_rb_remove(&device
->rasterizer_states
, &state
->entry
);
1223 ID3D11Device2_AddRef(state
->device
= &device
->ID3D11Device2_iface
);
1228 HRESULT
d3d_rasterizer_state_create(struct d3d_device
*device
, const D3D11_RASTERIZER_DESC1
*desc
,
1229 struct d3d_rasterizer_state
**state
)
1231 struct d3d_rasterizer_state
*object
;
1232 struct wine_rb_entry
*entry
;
1235 wined3d_mutex_lock();
1236 if ((entry
= wine_rb_get(&device
->rasterizer_states
, desc
)))
1238 object
= WINE_RB_ENTRY_VALUE(entry
, struct d3d_rasterizer_state
, entry
);
1240 TRACE("Returning existing rasterizer state %p.\n", object
);
1241 ID3D11RasterizerState1_AddRef(&object
->ID3D11RasterizerState1_iface
);
1243 wined3d_mutex_unlock();
1248 if (!(object
= calloc(1, sizeof(*object
))))
1250 wined3d_mutex_unlock();
1251 return E_OUTOFMEMORY
;
1254 hr
= d3d_rasterizer_state_init(object
, device
, desc
);
1255 wined3d_mutex_unlock();
1258 WARN("Failed to initialise rasterizer state, hr %#lx.\n", hr
);
1263 TRACE("Created rasterizer state %p.\n", object
);
1269 struct d3d_rasterizer_state
*unsafe_impl_from_ID3D11RasterizerState(ID3D11RasterizerState
*iface
)
1273 assert(iface
->lpVtbl
== (ID3D11RasterizerStateVtbl
*)&d3d11_rasterizer_state_vtbl
);
1275 return impl_from_ID3D11RasterizerState1((ID3D11RasterizerState1
*)iface
);
1278 struct d3d_rasterizer_state
*unsafe_impl_from_ID3D10RasterizerState(ID3D10RasterizerState
*iface
)
1282 assert(iface
->lpVtbl
== &d3d10_rasterizer_state_vtbl
);
1284 return impl_from_ID3D10RasterizerState(iface
);
1287 /* ID3D11SampleState methods */
1289 static inline struct d3d_sampler_state
*impl_from_ID3D11SamplerState(ID3D11SamplerState
*iface
)
1291 return CONTAINING_RECORD(iface
, struct d3d_sampler_state
, ID3D11SamplerState_iface
);
1294 static HRESULT STDMETHODCALLTYPE
d3d11_sampler_state_QueryInterface(ID3D11SamplerState
*iface
,
1295 REFIID riid
, void **object
)
1297 struct d3d_sampler_state
*state
= impl_from_ID3D11SamplerState(iface
);
1299 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
1301 if (IsEqualGUID(riid
, &IID_ID3D11SamplerState
)
1302 || IsEqualGUID(riid
, &IID_ID3D11DeviceChild
)
1303 || IsEqualGUID(riid
, &IID_IUnknown
))
1305 ID3D11SamplerState_AddRef(iface
);
1310 if (IsEqualGUID(riid
, &IID_ID3D10SamplerState
)
1311 || IsEqualGUID(riid
, &IID_ID3D10DeviceChild
))
1313 ID3D10SamplerState_AddRef(&state
->ID3D10SamplerState_iface
);
1314 *object
= &state
->ID3D10SamplerState_iface
;
1318 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
1321 return E_NOINTERFACE
;
1324 static ULONG STDMETHODCALLTYPE
d3d11_sampler_state_AddRef(ID3D11SamplerState
*iface
)
1326 struct d3d_sampler_state
*state
= impl_from_ID3D11SamplerState(iface
);
1327 ULONG refcount
= InterlockedIncrement(&state
->refcount
);
1329 TRACE("%p increasing refcount to %lu.\n", state
, refcount
);
1333 ID3D11Device2_AddRef(state
->device
);
1334 wined3d_sampler_incref(state
->wined3d_sampler
);
1340 static ULONG STDMETHODCALLTYPE
d3d11_sampler_state_Release(ID3D11SamplerState
*iface
)
1342 struct d3d_sampler_state
*state
= impl_from_ID3D11SamplerState(iface
);
1343 ULONG refcount
= InterlockedDecrement(&state
->refcount
);
1345 TRACE("%p decreasing refcount to %lu.\n", state
, refcount
);
1349 ID3D11Device2
*device
= state
->device
;
1350 wined3d_sampler_decref(state
->wined3d_sampler
);
1351 ID3D11Device2_Release(device
);
1357 static void STDMETHODCALLTYPE
d3d11_sampler_state_GetDevice(ID3D11SamplerState
*iface
,
1358 ID3D11Device
**device
)
1360 struct d3d_sampler_state
*state
= impl_from_ID3D11SamplerState(iface
);
1362 TRACE("iface %p, device %p.\n", iface
, device
);
1364 *device
= (ID3D11Device
*)state
->device
;
1365 ID3D11Device_AddRef(*device
);
1368 static HRESULT STDMETHODCALLTYPE
d3d11_sampler_state_GetPrivateData(ID3D11SamplerState
*iface
,
1369 REFGUID guid
, UINT
*data_size
, void *data
)
1371 struct d3d_sampler_state
*state
= impl_from_ID3D11SamplerState(iface
);
1373 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
1375 return d3d_get_private_data(&state
->private_store
, guid
, data_size
, data
);
1378 static HRESULT STDMETHODCALLTYPE
d3d11_sampler_state_SetPrivateData(ID3D11SamplerState
*iface
,
1379 REFGUID guid
, UINT data_size
, const void *data
)
1381 struct d3d_sampler_state
*state
= impl_from_ID3D11SamplerState(iface
);
1383 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
1385 return d3d_set_private_data(&state
->private_store
, guid
, data_size
, data
);
1388 static HRESULT STDMETHODCALLTYPE
d3d11_sampler_state_SetPrivateDataInterface(ID3D11SamplerState
*iface
,
1389 REFGUID guid
, const IUnknown
*data
)
1391 struct d3d_sampler_state
*state
= impl_from_ID3D11SamplerState(iface
);
1393 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
1395 return d3d_set_private_data_interface(&state
->private_store
, guid
, data
);
1398 static void STDMETHODCALLTYPE
d3d11_sampler_state_GetDesc(ID3D11SamplerState
*iface
,
1399 D3D11_SAMPLER_DESC
*desc
)
1401 struct d3d_sampler_state
*state
= impl_from_ID3D11SamplerState(iface
);
1403 TRACE("iface %p, desc %p.\n", iface
, desc
);
1405 *desc
= state
->desc
;
1408 static const struct ID3D11SamplerStateVtbl d3d11_sampler_state_vtbl
=
1410 /* IUnknown methods */
1411 d3d11_sampler_state_QueryInterface
,
1412 d3d11_sampler_state_AddRef
,
1413 d3d11_sampler_state_Release
,
1414 /* ID3D11DeviceChild methods */
1415 d3d11_sampler_state_GetDevice
,
1416 d3d11_sampler_state_GetPrivateData
,
1417 d3d11_sampler_state_SetPrivateData
,
1418 d3d11_sampler_state_SetPrivateDataInterface
,
1419 /* ID3D11SamplerState methods */
1420 d3d11_sampler_state_GetDesc
,
1423 /* ID3D10SamplerState methods */
1425 static inline struct d3d_sampler_state
*impl_from_ID3D10SamplerState(ID3D10SamplerState
*iface
)
1427 return CONTAINING_RECORD(iface
, struct d3d_sampler_state
, ID3D10SamplerState_iface
);
1430 /* IUnknown methods */
1432 static HRESULT STDMETHODCALLTYPE
d3d10_sampler_state_QueryInterface(ID3D10SamplerState
*iface
,
1433 REFIID riid
, void **object
)
1435 struct d3d_sampler_state
*state
= impl_from_ID3D10SamplerState(iface
);
1437 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
1439 return d3d11_sampler_state_QueryInterface(&state
->ID3D11SamplerState_iface
, riid
, object
);
1442 static ULONG STDMETHODCALLTYPE
d3d10_sampler_state_AddRef(ID3D10SamplerState
*iface
)
1444 struct d3d_sampler_state
*state
= impl_from_ID3D10SamplerState(iface
);
1446 TRACE("iface %p.\n", iface
);
1448 return d3d11_sampler_state_AddRef(&state
->ID3D11SamplerState_iface
);
1451 static ULONG STDMETHODCALLTYPE
d3d10_sampler_state_Release(ID3D10SamplerState
*iface
)
1453 struct d3d_sampler_state
*state
= impl_from_ID3D10SamplerState(iface
);
1455 TRACE("iface %p.\n", iface
);
1457 return d3d11_sampler_state_Release(&state
->ID3D11SamplerState_iface
);
1460 /* ID3D10DeviceChild methods */
1462 static void STDMETHODCALLTYPE
d3d10_sampler_state_GetDevice(ID3D10SamplerState
*iface
, ID3D10Device
**device
)
1464 struct d3d_sampler_state
*state
= impl_from_ID3D10SamplerState(iface
);
1466 TRACE("iface %p, device %p.\n", iface
, device
);
1468 ID3D11Device2_QueryInterface(state
->device
, &IID_ID3D10Device
, (void **)device
);
1471 static HRESULT STDMETHODCALLTYPE
d3d10_sampler_state_GetPrivateData(ID3D10SamplerState
*iface
,
1472 REFGUID guid
, UINT
*data_size
, void *data
)
1474 struct d3d_sampler_state
*state
= impl_from_ID3D10SamplerState(iface
);
1476 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
1477 iface
, debugstr_guid(guid
), data_size
, data
);
1479 return d3d_get_private_data(&state
->private_store
, guid
, data_size
, data
);
1482 static HRESULT STDMETHODCALLTYPE
d3d10_sampler_state_SetPrivateData(ID3D10SamplerState
*iface
,
1483 REFGUID guid
, UINT data_size
, const void *data
)
1485 struct d3d_sampler_state
*state
= impl_from_ID3D10SamplerState(iface
);
1487 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
1488 iface
, debugstr_guid(guid
), data_size
, data
);
1490 return d3d_set_private_data(&state
->private_store
, guid
, data_size
, data
);
1493 static HRESULT STDMETHODCALLTYPE
d3d10_sampler_state_SetPrivateDataInterface(ID3D10SamplerState
*iface
,
1494 REFGUID guid
, const IUnknown
*data
)
1496 struct d3d_sampler_state
*state
= impl_from_ID3D10SamplerState(iface
);
1498 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
1500 return d3d_set_private_data_interface(&state
->private_store
, guid
, data
);
1503 /* ID3D10SamplerState methods */
1505 static void STDMETHODCALLTYPE
d3d10_sampler_state_GetDesc(ID3D10SamplerState
*iface
,
1506 D3D10_SAMPLER_DESC
*desc
)
1508 struct d3d_sampler_state
*state
= impl_from_ID3D10SamplerState(iface
);
1510 TRACE("iface %p, desc %p.\n", iface
, desc
);
1512 memcpy(desc
, &state
->desc
, sizeof(*desc
));
1515 static const struct ID3D10SamplerStateVtbl d3d10_sampler_state_vtbl
=
1517 /* IUnknown methods */
1518 d3d10_sampler_state_QueryInterface
,
1519 d3d10_sampler_state_AddRef
,
1520 d3d10_sampler_state_Release
,
1521 /* ID3D10DeviceChild methods */
1522 d3d10_sampler_state_GetDevice
,
1523 d3d10_sampler_state_GetPrivateData
,
1524 d3d10_sampler_state_SetPrivateData
,
1525 d3d10_sampler_state_SetPrivateDataInterface
,
1526 /* ID3D10SamplerState methods */
1527 d3d10_sampler_state_GetDesc
,
1530 static void STDMETHODCALLTYPE
d3d_sampler_wined3d_object_destroyed(void *parent
)
1532 struct d3d_sampler_state
*state
= parent
;
1533 struct d3d_device
*device
= impl_from_ID3D11Device2(state
->device
);
1535 wine_rb_remove(&device
->sampler_states
, &state
->entry
);
1536 wined3d_private_store_cleanup(&state
->private_store
);
1540 static const struct wined3d_parent_ops d3d_sampler_wined3d_parent_ops
=
1542 d3d_sampler_wined3d_object_destroyed
,
1545 static enum wined3d_texture_address
wined3d_texture_address_from_d3d11(enum D3D11_TEXTURE_ADDRESS_MODE t
)
1547 return (enum wined3d_texture_address
)t
;
1550 static enum wined3d_texture_filter_type
wined3d_texture_filter_mip_from_d3d11(enum D3D11_FILTER f
)
1552 if (D3D11_DECODE_MIP_FILTER(f
) == D3D11_FILTER_TYPE_LINEAR
)
1553 return WINED3D_TEXF_LINEAR
;
1554 return WINED3D_TEXF_POINT
;
1557 static enum wined3d_texture_filter_type
wined3d_texture_filter_mag_from_d3d11(enum D3D11_FILTER f
)
1559 if (D3D11_DECODE_MAG_FILTER(f
) == D3D11_FILTER_TYPE_LINEAR
)
1560 return WINED3D_TEXF_LINEAR
;
1561 return WINED3D_TEXF_POINT
;
1564 static enum wined3d_texture_filter_type
wined3d_texture_filter_min_from_d3d11(enum D3D11_FILTER f
)
1566 if (D3D11_DECODE_MIN_FILTER(f
) == D3D11_FILTER_TYPE_LINEAR
)
1567 return WINED3D_TEXF_LINEAR
;
1568 return WINED3D_TEXF_POINT
;
1571 static BOOL
wined3d_texture_compare_from_d3d11(enum D3D11_FILTER f
)
1573 return D3D11_DECODE_IS_COMPARISON_FILTER(f
);
1576 static HRESULT
d3d_sampler_state_init(struct d3d_sampler_state
*state
, struct d3d_device
*device
,
1577 const D3D11_SAMPLER_DESC
*desc
)
1579 struct wined3d_sampler_desc wined3d_desc
;
1582 state
->ID3D11SamplerState_iface
.lpVtbl
= &d3d11_sampler_state_vtbl
;
1583 state
->ID3D10SamplerState_iface
.lpVtbl
= &d3d10_sampler_state_vtbl
;
1584 state
->refcount
= 1;
1585 wined3d_private_store_init(&state
->private_store
);
1586 state
->desc
= *desc
;
1588 wined3d_desc
.address_u
= wined3d_texture_address_from_d3d11(desc
->AddressU
);
1589 wined3d_desc
.address_v
= wined3d_texture_address_from_d3d11(desc
->AddressV
);
1590 wined3d_desc
.address_w
= wined3d_texture_address_from_d3d11(desc
->AddressW
);
1591 memcpy(wined3d_desc
.border_color
, desc
->BorderColor
, sizeof(wined3d_desc
.border_color
));
1592 wined3d_desc
.mag_filter
= wined3d_texture_filter_mag_from_d3d11(desc
->Filter
);
1593 wined3d_desc
.min_filter
= wined3d_texture_filter_min_from_d3d11(desc
->Filter
);
1594 wined3d_desc
.mip_filter
= wined3d_texture_filter_mip_from_d3d11(desc
->Filter
);
1595 wined3d_desc
.lod_bias
= desc
->MipLODBias
;
1596 wined3d_desc
.min_lod
= desc
->MinLOD
;
1597 wined3d_desc
.max_lod
= max(desc
->MinLOD
, desc
->MaxLOD
);
1598 wined3d_desc
.mip_base_level
= 0;
1599 wined3d_desc
.max_anisotropy
= D3D11_DECODE_IS_ANISOTROPIC_FILTER(desc
->Filter
) ? desc
->MaxAnisotropy
: 1;
1600 wined3d_desc
.compare
= wined3d_texture_compare_from_d3d11(desc
->Filter
);
1601 wined3d_desc
.comparison_func
= wined3d_cmp_func_from_d3d11(desc
->ComparisonFunc
);
1602 wined3d_desc
.srgb_decode
= TRUE
;
1604 if (wine_rb_put(&device
->sampler_states
, desc
, &state
->entry
) == -1)
1606 ERR("Failed to insert sampler state entry.\n");
1607 wined3d_private_store_cleanup(&state
->private_store
);
1611 /* We cannot fail after creating a wined3d_sampler object. It would lead to
1613 if (FAILED(hr
= wined3d_sampler_create(device
->wined3d_device
, &wined3d_desc
,
1614 state
, &d3d_sampler_wined3d_parent_ops
, &state
->wined3d_sampler
)))
1616 WARN("Failed to create wined3d sampler, hr %#lx.\n", hr
);
1617 wined3d_private_store_cleanup(&state
->private_store
);
1618 wine_rb_remove(&device
->sampler_states
, &state
->entry
);
1622 ID3D11Device2_AddRef(state
->device
= &device
->ID3D11Device2_iface
);
1627 HRESULT
d3d_sampler_state_create(struct d3d_device
*device
, const D3D11_SAMPLER_DESC
*desc
,
1628 struct d3d_sampler_state
**state
)
1630 D3D11_SAMPLER_DESC normalized_desc
;
1631 struct d3d_sampler_state
*object
;
1632 struct wine_rb_entry
*entry
;
1636 return E_INVALIDARG
;
1638 normalized_desc
= *desc
;
1639 if (!D3D11_DECODE_IS_ANISOTROPIC_FILTER(normalized_desc
.Filter
))
1640 normalized_desc
.MaxAnisotropy
= 0;
1641 if (!D3D11_DECODE_IS_COMPARISON_FILTER(normalized_desc
.Filter
))
1642 normalized_desc
.ComparisonFunc
= D3D11_COMPARISON_NEVER
;
1643 if (normalized_desc
.AddressU
!= D3D11_TEXTURE_ADDRESS_BORDER
1644 && normalized_desc
.AddressV
!= D3D11_TEXTURE_ADDRESS_BORDER
1645 && normalized_desc
.AddressW
!= D3D11_TEXTURE_ADDRESS_BORDER
)
1646 memset(&normalized_desc
.BorderColor
, 0, sizeof(normalized_desc
.BorderColor
));
1648 wined3d_mutex_lock();
1649 if ((entry
= wine_rb_get(&device
->sampler_states
, &normalized_desc
)))
1651 object
= WINE_RB_ENTRY_VALUE(entry
, struct d3d_sampler_state
, entry
);
1653 TRACE("Returning existing sampler state %p.\n", object
);
1654 ID3D11SamplerState_AddRef(&object
->ID3D11SamplerState_iface
);
1656 wined3d_mutex_unlock();
1661 if (!(object
= calloc(1, sizeof(*object
))))
1663 wined3d_mutex_unlock();
1664 return E_OUTOFMEMORY
;
1667 hr
= d3d_sampler_state_init(object
, device
, &normalized_desc
);
1668 wined3d_mutex_unlock();
1671 WARN("Failed to initialise sampler state, hr %#lx.\n", hr
);
1676 TRACE("Created sampler state %p.\n", object
);
1682 struct d3d_sampler_state
*unsafe_impl_from_ID3D11SamplerState(ID3D11SamplerState
*iface
)
1686 assert(iface
->lpVtbl
== &d3d11_sampler_state_vtbl
);
1688 return impl_from_ID3D11SamplerState(iface
);
1691 struct d3d_sampler_state
*unsafe_impl_from_ID3D10SamplerState(ID3D10SamplerState
*iface
)
1695 assert(iface
->lpVtbl
== &d3d10_sampler_state_vtbl
);
1697 return impl_from_ID3D10SamplerState(iface
);