2 * Copyright 2009 Henri Verbeet for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #include "d3d11_private.h"
22 WINE_DEFAULT_DEBUG_CHANNEL(d3d11
);
24 /* ID3D11BlendState methods */
26 static HRESULT STDMETHODCALLTYPE
d3d11_blend_state_QueryInterface(ID3D11BlendState
*iface
,
27 REFIID riid
, void **object
)
29 struct d3d_blend_state
*state
= impl_from_ID3D11BlendState(iface
);
31 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
33 if (IsEqualGUID(riid
, &IID_ID3D11BlendState
)
34 || IsEqualGUID(riid
, &IID_ID3D11DeviceChild
)
35 || IsEqualGUID(riid
, &IID_IUnknown
))
37 ID3D11BlendState_AddRef(iface
);
42 if (IsEqualGUID(riid
, &IID_ID3D10BlendState1
)
43 || IsEqualGUID(riid
, &IID_ID3D10BlendState
)
44 || IsEqualGUID(riid
, &IID_ID3D10DeviceChild
))
46 ID3D10BlendState1_AddRef(&state
->ID3D10BlendState1_iface
);
47 *object
= &state
->ID3D10BlendState1_iface
;
51 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
57 static ULONG STDMETHODCALLTYPE
d3d11_blend_state_AddRef(ID3D11BlendState
*iface
)
59 struct d3d_blend_state
*state
= impl_from_ID3D11BlendState(iface
);
60 ULONG refcount
= InterlockedIncrement(&state
->refcount
);
62 TRACE("%p increasing refcount to %u.\n", state
, refcount
);
66 ID3D11Device2_AddRef(state
->device
);
68 wined3d_blend_state_incref(state
->wined3d_state
);
69 wined3d_mutex_unlock();
75 static ULONG STDMETHODCALLTYPE
d3d11_blend_state_Release(ID3D11BlendState
*iface
)
77 struct d3d_blend_state
*state
= impl_from_ID3D11BlendState(iface
);
78 ULONG refcount
= InterlockedDecrement(&state
->refcount
);
80 TRACE("%p decreasing refcount to %u.\n", state
, refcount
);
84 ID3D11Device2
*device
= state
->device
;
87 wined3d_blend_state_decref(state
->wined3d_state
);
88 wined3d_mutex_unlock();
90 ID3D11Device2_Release(device
);
96 static void STDMETHODCALLTYPE
d3d11_blend_state_GetDevice(ID3D11BlendState
*iface
,
97 ID3D11Device
**device
)
99 struct d3d_blend_state
*state
= impl_from_ID3D11BlendState(iface
);
101 TRACE("iface %p, device %p.\n", iface
, device
);
103 *device
= (ID3D11Device
*)state
->device
;
104 ID3D11Device_AddRef(*device
);
107 static HRESULT STDMETHODCALLTYPE
d3d11_blend_state_GetPrivateData(ID3D11BlendState
*iface
,
108 REFGUID guid
, UINT
*data_size
, void *data
)
110 struct d3d_blend_state
*state
= impl_from_ID3D11BlendState(iface
);
112 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
114 return d3d_get_private_data(&state
->private_store
, guid
, data_size
, data
);
117 static HRESULT STDMETHODCALLTYPE
d3d11_blend_state_SetPrivateData(ID3D11BlendState
*iface
,
118 REFGUID guid
, UINT data_size
, const void *data
)
120 struct d3d_blend_state
*state
= impl_from_ID3D11BlendState(iface
);
122 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
124 return d3d_set_private_data(&state
->private_store
, guid
, data_size
, data
);
127 static HRESULT STDMETHODCALLTYPE
d3d11_blend_state_SetPrivateDataInterface(ID3D11BlendState
*iface
,
128 REFGUID guid
, const IUnknown
*data
)
130 struct d3d_blend_state
*state
= impl_from_ID3D11BlendState(iface
);
132 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
134 return d3d_set_private_data_interface(&state
->private_store
, guid
, data
);
137 static void STDMETHODCALLTYPE
d3d11_blend_state_GetDesc(ID3D11BlendState
*iface
, D3D11_BLEND_DESC
*desc
)
139 struct d3d_blend_state
*state
= impl_from_ID3D11BlendState(iface
);
141 TRACE("iface %p, desc %p.\n", iface
, desc
);
146 static const struct ID3D11BlendStateVtbl d3d11_blend_state_vtbl
=
148 /* IUnknown methods */
149 d3d11_blend_state_QueryInterface
,
150 d3d11_blend_state_AddRef
,
151 d3d11_blend_state_Release
,
152 /* ID3D11DeviceChild methods */
153 d3d11_blend_state_GetDevice
,
154 d3d11_blend_state_GetPrivateData
,
155 d3d11_blend_state_SetPrivateData
,
156 d3d11_blend_state_SetPrivateDataInterface
,
157 /* ID3D11BlendState methods */
158 d3d11_blend_state_GetDesc
,
161 /* ID3D10BlendState methods */
163 static inline struct d3d_blend_state
*impl_from_ID3D10BlendState(ID3D10BlendState1
*iface
)
165 return CONTAINING_RECORD(iface
, struct d3d_blend_state
, ID3D10BlendState1_iface
);
168 /* IUnknown methods */
170 static HRESULT STDMETHODCALLTYPE
d3d10_blend_state_QueryInterface(ID3D10BlendState1
*iface
,
171 REFIID riid
, void **object
)
173 struct d3d_blend_state
*state
= impl_from_ID3D10BlendState(iface
);
175 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
177 return d3d11_blend_state_QueryInterface(&state
->ID3D11BlendState_iface
, riid
, object
);
180 static ULONG STDMETHODCALLTYPE
d3d10_blend_state_AddRef(ID3D10BlendState1
*iface
)
182 struct d3d_blend_state
*state
= impl_from_ID3D10BlendState(iface
);
184 TRACE("iface %p.\n", iface
);
186 return d3d11_blend_state_AddRef(&state
->ID3D11BlendState_iface
);
189 static ULONG STDMETHODCALLTYPE
d3d10_blend_state_Release(ID3D10BlendState1
*iface
)
191 struct d3d_blend_state
*state
= impl_from_ID3D10BlendState(iface
);
193 TRACE("iface %p.\n", iface
);
195 return d3d11_blend_state_Release(&state
->ID3D11BlendState_iface
);
198 /* ID3D10DeviceChild methods */
200 static void STDMETHODCALLTYPE
d3d10_blend_state_GetDevice(ID3D10BlendState1
*iface
, ID3D10Device
**device
)
202 struct d3d_blend_state
*state
= impl_from_ID3D10BlendState(iface
);
204 TRACE("iface %p, device %p.\n", iface
, device
);
206 ID3D11Device2_QueryInterface(state
->device
, &IID_ID3D10Device
, (void **)device
);
209 static HRESULT STDMETHODCALLTYPE
d3d10_blend_state_GetPrivateData(ID3D10BlendState1
*iface
,
210 REFGUID guid
, UINT
*data_size
, void *data
)
212 struct d3d_blend_state
*state
= impl_from_ID3D10BlendState(iface
);
214 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
215 iface
, debugstr_guid(guid
), data_size
, data
);
217 return d3d_get_private_data(&state
->private_store
, guid
, data_size
, data
);
220 static HRESULT STDMETHODCALLTYPE
d3d10_blend_state_SetPrivateData(ID3D10BlendState1
*iface
,
221 REFGUID guid
, UINT data_size
, const void *data
)
223 struct d3d_blend_state
*state
= impl_from_ID3D10BlendState(iface
);
225 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
226 iface
, debugstr_guid(guid
), data_size
, data
);
228 return d3d_set_private_data(&state
->private_store
, guid
, data_size
, data
);
231 static HRESULT STDMETHODCALLTYPE
d3d10_blend_state_SetPrivateDataInterface(ID3D10BlendState1
*iface
,
232 REFGUID guid
, const IUnknown
*data
)
234 struct d3d_blend_state
*state
= impl_from_ID3D10BlendState(iface
);
236 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
238 return d3d_set_private_data_interface(&state
->private_store
, guid
, data
);
241 /* ID3D10BlendState methods */
243 static void STDMETHODCALLTYPE
d3d10_blend_state_GetDesc(ID3D10BlendState1
*iface
, D3D10_BLEND_DESC
*desc
)
245 struct d3d_blend_state
*state
= impl_from_ID3D10BlendState(iface
);
246 const D3D11_BLEND_DESC
*d3d11_desc
= &state
->desc
;
249 TRACE("iface %p, desc %p.\n", iface
, desc
);
251 desc
->AlphaToCoverageEnable
= d3d11_desc
->AlphaToCoverageEnable
;
252 desc
->SrcBlend
= d3d11_desc
->RenderTarget
[0].SrcBlend
;
253 desc
->DestBlend
= d3d11_desc
->RenderTarget
[0].DestBlend
;
254 desc
->BlendOp
= d3d11_desc
->RenderTarget
[0].BlendOp
;
255 desc
->SrcBlendAlpha
= d3d11_desc
->RenderTarget
[0].SrcBlendAlpha
;
256 desc
->DestBlendAlpha
= d3d11_desc
->RenderTarget
[0].DestBlendAlpha
;
257 desc
->BlendOpAlpha
= d3d11_desc
->RenderTarget
[0].BlendOpAlpha
;
258 for (i
= 0; i
< D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT
; ++i
)
260 desc
->BlendEnable
[i
] = d3d11_desc
->RenderTarget
[i
].BlendEnable
;
261 desc
->RenderTargetWriteMask
[i
] = d3d11_desc
->RenderTarget
[i
].RenderTargetWriteMask
;
265 static void STDMETHODCALLTYPE
d3d10_blend_state_GetDesc1(ID3D10BlendState1
*iface
, D3D10_BLEND_DESC1
*desc
)
267 struct d3d_blend_state
*state
= impl_from_ID3D10BlendState(iface
);
269 TRACE("iface %p, desc %p.\n", iface
, desc
);
271 memcpy(desc
, &state
->desc
, sizeof(*desc
));
274 static const struct ID3D10BlendState1Vtbl d3d10_blend_state_vtbl
=
276 /* IUnknown methods */
277 d3d10_blend_state_QueryInterface
,
278 d3d10_blend_state_AddRef
,
279 d3d10_blend_state_Release
,
280 /* ID3D10DeviceChild methods */
281 d3d10_blend_state_GetDevice
,
282 d3d10_blend_state_GetPrivateData
,
283 d3d10_blend_state_SetPrivateData
,
284 d3d10_blend_state_SetPrivateDataInterface
,
285 /* ID3D10BlendState methods */
286 d3d10_blend_state_GetDesc
,
287 /* ID3D10BlendState1 methods */
288 d3d10_blend_state_GetDesc1
,
291 static void STDMETHODCALLTYPE
d3d_blend_state_wined3d_object_destroyed(void *parent
)
293 struct d3d_blend_state
*state
= parent
;
294 struct d3d_device
*device
= impl_from_ID3D11Device2(state
->device
);
296 wine_rb_remove(&device
->blend_states
, &state
->entry
);
297 wined3d_private_store_cleanup(&state
->private_store
);
301 static const struct wined3d_parent_ops d3d_blend_state_wined3d_parent_ops
=
303 d3d_blend_state_wined3d_object_destroyed
,
306 HRESULT
d3d_blend_state_create(struct d3d_device
*device
, const D3D11_BLEND_DESC
*desc
,
307 struct d3d_blend_state
**state
)
309 struct wined3d_blend_state_desc wined3d_desc
;
310 struct d3d_blend_state
*object
;
311 struct wine_rb_entry
*entry
;
312 D3D11_BLEND_DESC tmp_desc
;
319 /* D3D11_RENDER_TARGET_BLEND_DESC has a hole, which is a problem because we use
320 * D3D11_BLEND_DESC as a key in the rbtree. */
321 memset(&tmp_desc
, 0, sizeof(tmp_desc
));
322 tmp_desc
.AlphaToCoverageEnable
= desc
->AlphaToCoverageEnable
;
323 tmp_desc
.IndependentBlendEnable
= desc
->IndependentBlendEnable
;
324 for (i
= 0; i
< D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT
; ++i
)
326 j
= desc
->IndependentBlendEnable
? i
: 0;
327 tmp_desc
.RenderTarget
[i
].BlendEnable
= desc
->RenderTarget
[j
].BlendEnable
;
328 if (tmp_desc
.RenderTarget
[i
].BlendEnable
)
330 tmp_desc
.RenderTarget
[i
].SrcBlend
= desc
->RenderTarget
[j
].SrcBlend
;
331 tmp_desc
.RenderTarget
[i
].DestBlend
= desc
->RenderTarget
[j
].DestBlend
;
332 tmp_desc
.RenderTarget
[i
].BlendOp
= desc
->RenderTarget
[j
].BlendOp
;
333 tmp_desc
.RenderTarget
[i
].SrcBlendAlpha
= desc
->RenderTarget
[j
].SrcBlendAlpha
;
334 tmp_desc
.RenderTarget
[i
].DestBlendAlpha
= desc
->RenderTarget
[j
].DestBlendAlpha
;
335 tmp_desc
.RenderTarget
[i
].BlendOpAlpha
= desc
->RenderTarget
[j
].BlendOpAlpha
;
339 tmp_desc
.RenderTarget
[i
].SrcBlend
= D3D11_BLEND_ONE
;
340 tmp_desc
.RenderTarget
[i
].DestBlend
= D3D11_BLEND_ZERO
;
341 tmp_desc
.RenderTarget
[i
].BlendOp
= D3D11_BLEND_OP_ADD
;
342 tmp_desc
.RenderTarget
[i
].SrcBlendAlpha
= D3D11_BLEND_ONE
;
343 tmp_desc
.RenderTarget
[i
].DestBlendAlpha
= D3D11_BLEND_ZERO
;
344 tmp_desc
.RenderTarget
[i
].BlendOpAlpha
= D3D11_BLEND_OP_ADD
;
346 tmp_desc
.RenderTarget
[i
].RenderTargetWriteMask
= desc
->RenderTarget
[j
].RenderTargetWriteMask
;
348 if (i
> 3 && tmp_desc
.RenderTarget
[i
].RenderTargetWriteMask
!= D3D11_COLOR_WRITE_ENABLE_ALL
)
349 FIXME("Color mask %#x not supported for render target %u.\n",
350 tmp_desc
.RenderTarget
[i
].RenderTargetWriteMask
, i
);
353 /* glEnableIndexedEXT(GL_BLEND, ...) */
354 if (tmp_desc
.IndependentBlendEnable
)
355 FIXME("Per-rendertarget blend not implemented.\n");
357 wined3d_mutex_lock();
358 if ((entry
= wine_rb_get(&device
->blend_states
, &tmp_desc
)))
360 object
= WINE_RB_ENTRY_VALUE(entry
, struct d3d_blend_state
, entry
);
362 TRACE("Returning existing blend state %p.\n", object
);
363 ID3D11BlendState_AddRef(&object
->ID3D11BlendState_iface
);
365 wined3d_mutex_unlock();
370 if (!(object
= heap_alloc_zero(sizeof(*object
))))
372 wined3d_mutex_unlock();
373 return E_OUTOFMEMORY
;
376 object
->ID3D11BlendState_iface
.lpVtbl
= &d3d11_blend_state_vtbl
;
377 object
->ID3D10BlendState1_iface
.lpVtbl
= &d3d10_blend_state_vtbl
;
378 object
->refcount
= 1;
379 wined3d_private_store_init(&object
->private_store
);
380 object
->desc
= tmp_desc
;
382 if (wine_rb_put(&device
->blend_states
, &tmp_desc
, &object
->entry
) == -1)
384 ERR("Failed to insert blend state entry.\n");
385 wined3d_private_store_cleanup(&object
->private_store
);
387 wined3d_mutex_unlock();
391 wined3d_desc
.alpha_to_coverage
= desc
->AlphaToCoverageEnable
;
392 wined3d_desc
.enable
= desc
->RenderTarget
[0].BlendEnable
;
394 /* We cannot fail after creating a wined3d_blend_state object. It
395 * would lead to double free. */
396 if (FAILED(hr
= wined3d_blend_state_create(device
->wined3d_device
, &wined3d_desc
,
397 object
, &d3d_blend_state_wined3d_parent_ops
, &object
->wined3d_state
)))
399 WARN("Failed to create wined3d blend state, hr %#x.\n", hr
);
400 wined3d_private_store_cleanup(&object
->private_store
);
401 wine_rb_remove(&device
->blend_states
, &object
->entry
);
403 wined3d_mutex_unlock();
406 wined3d_mutex_unlock();
408 ID3D11Device2_AddRef(object
->device
= &device
->ID3D11Device2_iface
);
410 TRACE("Created blend state %p.\n", object
);
416 struct d3d_blend_state
*unsafe_impl_from_ID3D11BlendState(ID3D11BlendState
*iface
)
420 assert(iface
->lpVtbl
== &d3d11_blend_state_vtbl
);
422 return impl_from_ID3D11BlendState(iface
);
425 struct d3d_blend_state
*unsafe_impl_from_ID3D10BlendState(ID3D10BlendState
*iface
)
429 assert(iface
->lpVtbl
== (ID3D10BlendStateVtbl
*)&d3d10_blend_state_vtbl
);
431 return impl_from_ID3D10BlendState((ID3D10BlendState1
*)iface
);
434 /* ID3D11DepthStencilState methods */
436 static HRESULT STDMETHODCALLTYPE
d3d11_depthstencil_state_QueryInterface(ID3D11DepthStencilState
*iface
,
437 REFIID riid
, void **object
)
439 struct d3d_depthstencil_state
*state
= impl_from_ID3D11DepthStencilState(iface
);
441 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
443 if (IsEqualGUID(riid
, &IID_ID3D11DepthStencilState
)
444 || IsEqualGUID(riid
, &IID_ID3D11DeviceChild
)
445 || IsEqualGUID(riid
, &IID_IUnknown
))
447 ID3D11DepthStencilState_AddRef(iface
);
452 if (IsEqualGUID(riid
, &IID_ID3D10DepthStencilState
)
453 || IsEqualGUID(riid
, &IID_ID3D10DeviceChild
))
455 ID3D10DepthStencilState_AddRef(&state
->ID3D10DepthStencilState_iface
);
456 *object
= &state
->ID3D10DepthStencilState_iface
;
460 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
463 return E_NOINTERFACE
;
466 static ULONG STDMETHODCALLTYPE
d3d11_depthstencil_state_AddRef(ID3D11DepthStencilState
*iface
)
468 struct d3d_depthstencil_state
*state
= impl_from_ID3D11DepthStencilState(iface
);
469 ULONG refcount
= InterlockedIncrement(&state
->refcount
);
471 TRACE("%p increasing refcount to %u.\n", state
, refcount
);
476 static void d3d_depthstencil_state_cleanup(struct d3d_depthstencil_state
*state
)
478 wined3d_private_store_cleanup(&state
->private_store
);
479 ID3D11Device2_Release(state
->device
);
482 static ULONG STDMETHODCALLTYPE
d3d11_depthstencil_state_Release(ID3D11DepthStencilState
*iface
)
484 struct d3d_depthstencil_state
*state
= impl_from_ID3D11DepthStencilState(iface
);
485 ULONG refcount
= InterlockedDecrement(&state
->refcount
);
487 TRACE("%p decreasing refcount to %u.\n", state
, refcount
);
491 struct d3d_device
*device
= impl_from_ID3D11Device2(state
->device
);
492 wined3d_mutex_lock();
493 wine_rb_remove(&device
->depthstencil_states
, &state
->entry
);
494 d3d_depthstencil_state_cleanup(state
);
495 wined3d_mutex_unlock();
502 static void STDMETHODCALLTYPE
d3d11_depthstencil_state_GetDevice(ID3D11DepthStencilState
*iface
,
503 ID3D11Device
**device
)
505 struct d3d_depthstencil_state
*state
= impl_from_ID3D11DepthStencilState(iface
);
507 TRACE("iface %p, device %p.\n", iface
, device
);
509 *device
= (ID3D11Device
*)state
->device
;
510 ID3D11Device_AddRef(*device
);
513 static HRESULT STDMETHODCALLTYPE
d3d11_depthstencil_state_GetPrivateData(ID3D11DepthStencilState
*iface
,
514 REFGUID guid
, UINT
*data_size
, void *data
)
516 struct d3d_depthstencil_state
*state
= impl_from_ID3D11DepthStencilState(iface
);
518 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
520 return d3d_get_private_data(&state
->private_store
, guid
, data_size
, data
);
523 static HRESULT STDMETHODCALLTYPE
d3d11_depthstencil_state_SetPrivateData(ID3D11DepthStencilState
*iface
,
524 REFGUID guid
, UINT data_size
, const void *data
)
526 struct d3d_depthstencil_state
*state
= impl_from_ID3D11DepthStencilState(iface
);
528 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
530 return d3d_set_private_data(&state
->private_store
, guid
, data_size
, data
);
533 static HRESULT STDMETHODCALLTYPE
d3d11_depthstencil_state_SetPrivateDataInterface(ID3D11DepthStencilState
*iface
,
534 REFGUID guid
, const IUnknown
*data
)
536 struct d3d_depthstencil_state
*state
= impl_from_ID3D11DepthStencilState(iface
);
538 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
540 return d3d_set_private_data_interface(&state
->private_store
, guid
, data
);
543 static void STDMETHODCALLTYPE
d3d11_depthstencil_state_GetDesc(ID3D11DepthStencilState
*iface
,
544 D3D11_DEPTH_STENCIL_DESC
*desc
)
546 struct d3d_depthstencil_state
*state
= impl_from_ID3D11DepthStencilState(iface
);
548 TRACE("iface %p, desc %p.\n", iface
, desc
);
553 static const struct ID3D11DepthStencilStateVtbl d3d11_depthstencil_state_vtbl
=
555 /* IUnknown methods */
556 d3d11_depthstencil_state_QueryInterface
,
557 d3d11_depthstencil_state_AddRef
,
558 d3d11_depthstencil_state_Release
,
559 /* ID3D11DeviceChild methods */
560 d3d11_depthstencil_state_GetDevice
,
561 d3d11_depthstencil_state_GetPrivateData
,
562 d3d11_depthstencil_state_SetPrivateData
,
563 d3d11_depthstencil_state_SetPrivateDataInterface
,
564 /* ID3D11DepthStencilState methods */
565 d3d11_depthstencil_state_GetDesc
,
568 /* ID3D10DepthStencilState methods */
570 static inline struct d3d_depthstencil_state
*impl_from_ID3D10DepthStencilState(ID3D10DepthStencilState
*iface
)
572 return CONTAINING_RECORD(iface
, struct d3d_depthstencil_state
, ID3D10DepthStencilState_iface
);
575 /* IUnknown methods */
577 static HRESULT STDMETHODCALLTYPE
d3d10_depthstencil_state_QueryInterface(ID3D10DepthStencilState
*iface
,
578 REFIID riid
, void **object
)
580 struct d3d_depthstencil_state
*state
= impl_from_ID3D10DepthStencilState(iface
);
582 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
584 return d3d11_depthstencil_state_QueryInterface(&state
->ID3D11DepthStencilState_iface
, riid
, object
);
587 static ULONG STDMETHODCALLTYPE
d3d10_depthstencil_state_AddRef(ID3D10DepthStencilState
*iface
)
589 struct d3d_depthstencil_state
*state
= impl_from_ID3D10DepthStencilState(iface
);
591 TRACE("iface %p.\n", iface
);
593 return d3d11_depthstencil_state_AddRef(&state
->ID3D11DepthStencilState_iface
);
596 static ULONG STDMETHODCALLTYPE
d3d10_depthstencil_state_Release(ID3D10DepthStencilState
*iface
)
598 struct d3d_depthstencil_state
*state
= impl_from_ID3D10DepthStencilState(iface
);
600 TRACE("iface %p.\n", iface
);
602 return d3d11_depthstencil_state_Release(&state
->ID3D11DepthStencilState_iface
);
605 /* ID3D10DeviceChild methods */
607 static void STDMETHODCALLTYPE
d3d10_depthstencil_state_GetDevice(ID3D10DepthStencilState
*iface
, ID3D10Device
**device
)
609 struct d3d_depthstencil_state
*state
= impl_from_ID3D10DepthStencilState(iface
);
611 TRACE("iface %p, device %p.\n", iface
, device
);
613 ID3D11Device2_QueryInterface(state
->device
, &IID_ID3D10Device
, (void **)device
);
616 static HRESULT STDMETHODCALLTYPE
d3d10_depthstencil_state_GetPrivateData(ID3D10DepthStencilState
*iface
,
617 REFGUID guid
, UINT
*data_size
, void *data
)
619 struct d3d_depthstencil_state
*state
= impl_from_ID3D10DepthStencilState(iface
);
621 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
622 iface
, debugstr_guid(guid
), data_size
, data
);
624 return d3d_get_private_data(&state
->private_store
, guid
, data_size
, data
);
627 static HRESULT STDMETHODCALLTYPE
d3d10_depthstencil_state_SetPrivateData(ID3D10DepthStencilState
*iface
,
628 REFGUID guid
, UINT data_size
, const void *data
)
630 struct d3d_depthstencil_state
*state
= impl_from_ID3D10DepthStencilState(iface
);
632 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
633 iface
, debugstr_guid(guid
), data_size
, data
);
635 return d3d_set_private_data(&state
->private_store
, guid
, data_size
, data
);
638 static HRESULT STDMETHODCALLTYPE
d3d10_depthstencil_state_SetPrivateDataInterface(ID3D10DepthStencilState
*iface
,
639 REFGUID guid
, const IUnknown
*data
)
641 struct d3d_depthstencil_state
*state
= impl_from_ID3D10DepthStencilState(iface
);
643 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
645 return d3d_set_private_data_interface(&state
->private_store
, guid
, data
);
648 /* ID3D10DepthStencilState methods */
650 static void STDMETHODCALLTYPE
d3d10_depthstencil_state_GetDesc(ID3D10DepthStencilState
*iface
,
651 D3D10_DEPTH_STENCIL_DESC
*desc
)
653 struct d3d_depthstencil_state
*state
= impl_from_ID3D10DepthStencilState(iface
);
655 TRACE("iface %p, desc %p.\n", iface
, desc
);
657 memcpy(desc
, &state
->desc
, sizeof(*desc
));
660 static const struct ID3D10DepthStencilStateVtbl d3d10_depthstencil_state_vtbl
=
662 /* IUnknown methods */
663 d3d10_depthstencil_state_QueryInterface
,
664 d3d10_depthstencil_state_AddRef
,
665 d3d10_depthstencil_state_Release
,
666 /* ID3D10DeviceChild methods */
667 d3d10_depthstencil_state_GetDevice
,
668 d3d10_depthstencil_state_GetPrivateData
,
669 d3d10_depthstencil_state_SetPrivateData
,
670 d3d10_depthstencil_state_SetPrivateDataInterface
,
671 /* ID3D10DepthStencilState methods */
672 d3d10_depthstencil_state_GetDesc
,
675 static HRESULT
d3d_depthstencil_state_init(struct d3d_depthstencil_state
*state
, struct d3d_device
*device
,
676 const D3D11_DEPTH_STENCIL_DESC
*desc
)
678 state
->ID3D11DepthStencilState_iface
.lpVtbl
= &d3d11_depthstencil_state_vtbl
;
679 state
->ID3D10DepthStencilState_iface
.lpVtbl
= &d3d10_depthstencil_state_vtbl
;
681 wined3d_private_store_init(&state
->private_store
);
684 ID3D11Device2_AddRef(state
->device
= &device
->ID3D11Device2_iface
);
689 HRESULT
d3d_depthstencil_state_create(struct d3d_device
*device
, const D3D11_DEPTH_STENCIL_DESC
*desc
,
690 struct d3d_depthstencil_state
**state
)
692 struct d3d_depthstencil_state
*object
;
693 D3D11_DEPTH_STENCIL_DESC tmp_desc
;
694 struct wine_rb_entry
*entry
;
700 /* D3D11_DEPTH_STENCIL_DESC has a hole, which is a problem because we use
701 * it as a key in the rbtree. */
702 memset(&tmp_desc
, 0, sizeof(tmp_desc
));
703 tmp_desc
.DepthEnable
= desc
->DepthEnable
;
704 if (desc
->DepthEnable
)
706 tmp_desc
.DepthWriteMask
= desc
->DepthWriteMask
;
707 tmp_desc
.DepthFunc
= desc
->DepthFunc
;
711 tmp_desc
.DepthWriteMask
= D3D11_DEPTH_WRITE_MASK_ALL
;
712 tmp_desc
.DepthFunc
= D3D11_COMPARISON_LESS
;
714 tmp_desc
.StencilEnable
= desc
->StencilEnable
;
715 if (desc
->StencilEnable
)
717 tmp_desc
.StencilReadMask
= desc
->StencilReadMask
;
718 tmp_desc
.StencilWriteMask
= desc
->StencilWriteMask
;
719 tmp_desc
.FrontFace
= desc
->FrontFace
;
720 tmp_desc
.BackFace
= desc
->BackFace
;
724 tmp_desc
.StencilReadMask
= D3D11_DEFAULT_STENCIL_READ_MASK
;
725 tmp_desc
.StencilWriteMask
= D3D11_DEFAULT_STENCIL_WRITE_MASK
;
726 tmp_desc
.FrontFace
.StencilFailOp
= D3D11_STENCIL_OP_KEEP
;
727 tmp_desc
.FrontFace
.StencilDepthFailOp
= D3D11_STENCIL_OP_KEEP
;
728 tmp_desc
.FrontFace
.StencilPassOp
= D3D11_STENCIL_OP_KEEP
;
729 tmp_desc
.FrontFace
.StencilFunc
= D3D11_COMPARISON_ALWAYS
;
730 tmp_desc
.BackFace
.StencilFailOp
= D3D11_STENCIL_OP_KEEP
;
731 tmp_desc
.BackFace
.StencilDepthFailOp
= D3D11_STENCIL_OP_KEEP
;
732 tmp_desc
.BackFace
.StencilPassOp
= D3D11_STENCIL_OP_KEEP
;
733 tmp_desc
.BackFace
.StencilFunc
= D3D11_COMPARISON_ALWAYS
;
736 wined3d_mutex_lock();
737 if ((entry
= wine_rb_get(&device
->depthstencil_states
, &tmp_desc
)))
739 object
= WINE_RB_ENTRY_VALUE(entry
, struct d3d_depthstencil_state
, entry
);
741 TRACE("Returning existing depthstencil state %p.\n", object
);
742 ID3D11DepthStencilState_AddRef(&object
->ID3D11DepthStencilState_iface
);
744 wined3d_mutex_unlock();
749 if (!(object
= heap_alloc_zero(sizeof(*object
))))
751 wined3d_mutex_unlock();
752 return E_OUTOFMEMORY
;
755 if (FAILED(hr
= d3d_depthstencil_state_init(object
, device
, &tmp_desc
)))
757 WARN("Failed to initialize depthstencil state, hr %#x.\n", hr
);
759 wined3d_mutex_unlock();
763 if (wine_rb_put(&device
->depthstencil_states
, &tmp_desc
, &object
->entry
) == -1)
765 ERR("Failed to insert depthstencil state entry.\n");
766 d3d_depthstencil_state_cleanup(object
);
768 wined3d_mutex_unlock();
771 wined3d_mutex_unlock();
773 TRACE("Created depthstencil state %p.\n", object
);
779 struct d3d_depthstencil_state
*unsafe_impl_from_ID3D11DepthStencilState(ID3D11DepthStencilState
*iface
)
783 assert(iface
->lpVtbl
== &d3d11_depthstencil_state_vtbl
);
785 return impl_from_ID3D11DepthStencilState(iface
);
788 struct d3d_depthstencil_state
*unsafe_impl_from_ID3D10DepthStencilState(ID3D10DepthStencilState
*iface
)
792 assert(iface
->lpVtbl
== &d3d10_depthstencil_state_vtbl
);
794 return impl_from_ID3D10DepthStencilState(iface
);
797 /* ID3D11RasterizerState methods */
799 static inline struct d3d_rasterizer_state
*impl_from_ID3D11RasterizerState(ID3D11RasterizerState
*iface
)
801 return CONTAINING_RECORD(iface
, struct d3d_rasterizer_state
, ID3D11RasterizerState_iface
);
804 static HRESULT STDMETHODCALLTYPE
d3d11_rasterizer_state_QueryInterface(ID3D11RasterizerState
*iface
,
805 REFIID riid
, void **object
)
807 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState(iface
);
809 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
811 if (IsEqualGUID(riid
, &IID_ID3D11RasterizerState
)
812 || IsEqualGUID(riid
, &IID_ID3D11DeviceChild
)
813 || IsEqualGUID(riid
, &IID_IUnknown
))
815 ID3D11RasterizerState_AddRef(iface
);
820 if (IsEqualGUID(riid
, &IID_ID3D10RasterizerState
)
821 || IsEqualGUID(riid
, &IID_ID3D10DeviceChild
))
823 ID3D10RasterizerState_AddRef(&state
->ID3D10RasterizerState_iface
);
824 *object
= &state
->ID3D10RasterizerState_iface
;
828 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
831 return E_NOINTERFACE
;
834 static ULONG STDMETHODCALLTYPE
d3d11_rasterizer_state_AddRef(ID3D11RasterizerState
*iface
)
836 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState(iface
);
837 ULONG refcount
= InterlockedIncrement(&state
->refcount
);
839 TRACE("%p increasing refcount to %u.\n", state
, refcount
);
843 ID3D11Device2_AddRef(state
->device
);
844 wined3d_mutex_lock();
845 wined3d_rasterizer_state_incref(state
->wined3d_state
);
846 wined3d_mutex_unlock();
852 static ULONG STDMETHODCALLTYPE
d3d11_rasterizer_state_Release(ID3D11RasterizerState
*iface
)
854 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState(iface
);
855 ULONG refcount
= InterlockedDecrement(&state
->refcount
);
857 TRACE("%p decreasing refcount to %u.\n", state
, refcount
);
861 ID3D11Device2
*device
= state
->device
;
863 wined3d_mutex_lock();
864 wined3d_rasterizer_state_decref(state
->wined3d_state
);
865 wined3d_mutex_unlock();
867 ID3D11Device2_Release(device
);
873 static void STDMETHODCALLTYPE
d3d11_rasterizer_state_GetDevice(ID3D11RasterizerState
*iface
,
874 ID3D11Device
**device
)
876 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState(iface
);
878 TRACE("iface %p, device %p.\n", iface
, device
);
880 *device
= (ID3D11Device
*)state
->device
;
881 ID3D11Device_AddRef(*device
);
884 static HRESULT STDMETHODCALLTYPE
d3d11_rasterizer_state_GetPrivateData(ID3D11RasterizerState
*iface
,
885 REFGUID guid
, UINT
*data_size
, void *data
)
887 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState(iface
);
889 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
891 return d3d_get_private_data(&state
->private_store
, guid
, data_size
, data
);
894 static HRESULT STDMETHODCALLTYPE
d3d11_rasterizer_state_SetPrivateData(ID3D11RasterizerState
*iface
,
895 REFGUID guid
, UINT data_size
, const void *data
)
897 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState(iface
);
899 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
901 return d3d_set_private_data(&state
->private_store
, guid
, data_size
, data
);
904 static HRESULT STDMETHODCALLTYPE
d3d11_rasterizer_state_SetPrivateDataInterface(ID3D11RasterizerState
*iface
,
905 REFGUID guid
, const IUnknown
*data
)
907 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState(iface
);
909 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
911 return d3d_set_private_data_interface(&state
->private_store
, guid
, data
);
914 static void STDMETHODCALLTYPE
d3d11_rasterizer_state_GetDesc(ID3D11RasterizerState
*iface
,
915 D3D11_RASTERIZER_DESC
*desc
)
917 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState(iface
);
919 TRACE("iface %p, desc %p.\n", iface
, desc
);
924 static const struct ID3D11RasterizerStateVtbl d3d11_rasterizer_state_vtbl
=
926 /* IUnknown methods */
927 d3d11_rasterizer_state_QueryInterface
,
928 d3d11_rasterizer_state_AddRef
,
929 d3d11_rasterizer_state_Release
,
930 /* ID3D11DeviceChild methods */
931 d3d11_rasterizer_state_GetDevice
,
932 d3d11_rasterizer_state_GetPrivateData
,
933 d3d11_rasterizer_state_SetPrivateData
,
934 d3d11_rasterizer_state_SetPrivateDataInterface
,
935 /* ID3D11RasterizerState methods */
936 d3d11_rasterizer_state_GetDesc
,
939 /* ID3D10RasterizerState methods */
941 static inline struct d3d_rasterizer_state
*impl_from_ID3D10RasterizerState(ID3D10RasterizerState
*iface
)
943 return CONTAINING_RECORD(iface
, struct d3d_rasterizer_state
, ID3D10RasterizerState_iface
);
946 /* IUnknown methods */
948 static HRESULT STDMETHODCALLTYPE
d3d10_rasterizer_state_QueryInterface(ID3D10RasterizerState
*iface
,
949 REFIID riid
, void **object
)
951 struct d3d_rasterizer_state
*state
= impl_from_ID3D10RasterizerState(iface
);
953 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
955 return d3d11_rasterizer_state_QueryInterface(&state
->ID3D11RasterizerState_iface
, riid
, object
);
958 static ULONG STDMETHODCALLTYPE
d3d10_rasterizer_state_AddRef(ID3D10RasterizerState
*iface
)
960 struct d3d_rasterizer_state
*state
= impl_from_ID3D10RasterizerState(iface
);
962 TRACE("iface %p.\n", iface
);
964 return d3d11_rasterizer_state_AddRef(&state
->ID3D11RasterizerState_iface
);
967 static ULONG STDMETHODCALLTYPE
d3d10_rasterizer_state_Release(ID3D10RasterizerState
*iface
)
969 struct d3d_rasterizer_state
*state
= impl_from_ID3D10RasterizerState(iface
);
971 TRACE("iface %p.\n", state
);
973 return d3d11_rasterizer_state_Release(&state
->ID3D11RasterizerState_iface
);
976 /* ID3D10DeviceChild methods */
978 static void STDMETHODCALLTYPE
d3d10_rasterizer_state_GetDevice(ID3D10RasterizerState
*iface
, ID3D10Device
**device
)
980 struct d3d_rasterizer_state
*state
= impl_from_ID3D10RasterizerState(iface
);
982 TRACE("iface %p, device %p.\n", iface
, device
);
984 ID3D11Device2_QueryInterface(state
->device
, &IID_ID3D10Device
, (void **)device
);
987 static HRESULT STDMETHODCALLTYPE
d3d10_rasterizer_state_GetPrivateData(ID3D10RasterizerState
*iface
,
988 REFGUID guid
, UINT
*data_size
, void *data
)
990 struct d3d_rasterizer_state
*state
= impl_from_ID3D10RasterizerState(iface
);
992 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
993 iface
, debugstr_guid(guid
), data_size
, data
);
995 return d3d_get_private_data(&state
->private_store
, guid
, data_size
, data
);
998 static HRESULT STDMETHODCALLTYPE
d3d10_rasterizer_state_SetPrivateData(ID3D10RasterizerState
*iface
,
999 REFGUID guid
, UINT data_size
, const void *data
)
1001 struct d3d_rasterizer_state
*state
= impl_from_ID3D10RasterizerState(iface
);
1003 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
1004 iface
, debugstr_guid(guid
), data_size
, data
);
1006 return d3d_set_private_data(&state
->private_store
, guid
, data_size
, data
);
1009 static HRESULT STDMETHODCALLTYPE
d3d10_rasterizer_state_SetPrivateDataInterface(ID3D10RasterizerState
*iface
,
1010 REFGUID guid
, const IUnknown
*data
)
1012 struct d3d_rasterizer_state
*state
= impl_from_ID3D10RasterizerState(iface
);
1014 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
1016 return d3d_set_private_data_interface(&state
->private_store
, guid
, data
);
1019 /* ID3D10RasterizerState methods */
1021 static void STDMETHODCALLTYPE
d3d10_rasterizer_state_GetDesc(ID3D10RasterizerState
*iface
,
1022 D3D10_RASTERIZER_DESC
*desc
)
1024 struct d3d_rasterizer_state
*state
= impl_from_ID3D10RasterizerState(iface
);
1026 TRACE("iface %p, desc %p.\n", iface
, desc
);
1028 memcpy(desc
, &state
->desc
, sizeof(*desc
));
1031 static const struct ID3D10RasterizerStateVtbl d3d10_rasterizer_state_vtbl
=
1033 /* IUnknown methods */
1034 d3d10_rasterizer_state_QueryInterface
,
1035 d3d10_rasterizer_state_AddRef
,
1036 d3d10_rasterizer_state_Release
,
1037 /* ID3D10DeviceChild methods */
1038 d3d10_rasterizer_state_GetDevice
,
1039 d3d10_rasterizer_state_GetPrivateData
,
1040 d3d10_rasterizer_state_SetPrivateData
,
1041 d3d10_rasterizer_state_SetPrivateDataInterface
,
1042 /* ID3D10RasterizerState methods */
1043 d3d10_rasterizer_state_GetDesc
,
1046 static void STDMETHODCALLTYPE
d3d_rasterizer_state_wined3d_object_destroyed(void *parent
)
1048 struct d3d_rasterizer_state
*state
= parent
;
1049 struct d3d_device
*device
= impl_from_ID3D11Device2(state
->device
);
1051 wine_rb_remove(&device
->rasterizer_states
, &state
->entry
);
1052 wined3d_private_store_cleanup(&state
->private_store
);
1056 static const struct wined3d_parent_ops d3d_rasterizer_state_wined3d_parent_ops
=
1058 d3d_rasterizer_state_wined3d_object_destroyed
,
1061 static HRESULT
d3d_rasterizer_state_init(struct d3d_rasterizer_state
*state
, struct d3d_device
*device
,
1062 const D3D11_RASTERIZER_DESC
*desc
)
1064 struct wined3d_rasterizer_state_desc wined3d_desc
;
1067 state
->ID3D11RasterizerState_iface
.lpVtbl
= &d3d11_rasterizer_state_vtbl
;
1068 state
->ID3D10RasterizerState_iface
.lpVtbl
= &d3d10_rasterizer_state_vtbl
;
1069 state
->refcount
= 1;
1070 wined3d_private_store_init(&state
->private_store
);
1071 state
->desc
= *desc
;
1073 if (wine_rb_put(&device
->rasterizer_states
, desc
, &state
->entry
) == -1)
1075 ERR("Failed to insert rasterizer state entry.\n");
1076 wined3d_private_store_cleanup(&state
->private_store
);
1080 wined3d_desc
.fill_mode
= desc
->FillMode
;
1081 wined3d_desc
.cull_mode
= desc
->CullMode
;
1082 wined3d_desc
.front_ccw
= desc
->FrontCounterClockwise
;
1083 wined3d_desc
.depth_bias
= desc
->DepthBias
;
1084 wined3d_desc
.depth_bias_clamp
= desc
->DepthBiasClamp
;
1085 wined3d_desc
.scale_bias
= desc
->SlopeScaledDepthBias
;
1086 wined3d_desc
.depth_clip
= desc
->DepthClipEnable
;
1087 wined3d_desc
.scissor
= desc
->ScissorEnable
;
1088 wined3d_desc
.line_antialias
= desc
->AntialiasedLineEnable
;
1090 /* We cannot fail after creating a wined3d_rasterizer_state object. It
1091 * would lead to double free. */
1092 if (FAILED(hr
= wined3d_rasterizer_state_create(device
->wined3d_device
, &wined3d_desc
,
1093 state
, &d3d_rasterizer_state_wined3d_parent_ops
, &state
->wined3d_state
)))
1095 WARN("Failed to create wined3d rasterizer state, hr %#x.\n", hr
);
1096 wined3d_private_store_cleanup(&state
->private_store
);
1097 wine_rb_remove(&device
->rasterizer_states
, &state
->entry
);
1101 ID3D11Device2_AddRef(state
->device
= &device
->ID3D11Device2_iface
);
1106 HRESULT
d3d_rasterizer_state_create(struct d3d_device
*device
, const D3D11_RASTERIZER_DESC
*desc
,
1107 struct d3d_rasterizer_state
**state
)
1109 struct d3d_rasterizer_state
*object
;
1110 struct wine_rb_entry
*entry
;
1114 return E_INVALIDARG
;
1116 wined3d_mutex_lock();
1117 if ((entry
= wine_rb_get(&device
->rasterizer_states
, desc
)))
1119 object
= WINE_RB_ENTRY_VALUE(entry
, struct d3d_rasterizer_state
, entry
);
1121 TRACE("Returning existing rasterizer state %p.\n", object
);
1122 ID3D11RasterizerState_AddRef(&object
->ID3D11RasterizerState_iface
);
1124 wined3d_mutex_unlock();
1129 if (!(object
= heap_alloc_zero(sizeof(*object
))))
1131 wined3d_mutex_unlock();
1132 return E_OUTOFMEMORY
;
1135 hr
= d3d_rasterizer_state_init(object
, device
, desc
);
1136 wined3d_mutex_unlock();
1139 WARN("Failed to initialize rasterizer state, hr %#x.\n", hr
);
1144 TRACE("Created rasterizer state %p.\n", object
);
1150 struct d3d_rasterizer_state
*unsafe_impl_from_ID3D11RasterizerState(ID3D11RasterizerState
*iface
)
1154 assert(iface
->lpVtbl
== &d3d11_rasterizer_state_vtbl
);
1156 return impl_from_ID3D11RasterizerState(iface
);
1159 struct d3d_rasterizer_state
*unsafe_impl_from_ID3D10RasterizerState(ID3D10RasterizerState
*iface
)
1163 assert(iface
->lpVtbl
== &d3d10_rasterizer_state_vtbl
);
1165 return impl_from_ID3D10RasterizerState(iface
);
1168 /* ID3D11SampleState methods */
1170 static inline struct d3d_sampler_state
*impl_from_ID3D11SamplerState(ID3D11SamplerState
*iface
)
1172 return CONTAINING_RECORD(iface
, struct d3d_sampler_state
, ID3D11SamplerState_iface
);
1175 static HRESULT STDMETHODCALLTYPE
d3d11_sampler_state_QueryInterface(ID3D11SamplerState
*iface
,
1176 REFIID riid
, void **object
)
1178 struct d3d_sampler_state
*state
= impl_from_ID3D11SamplerState(iface
);
1180 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
1182 if (IsEqualGUID(riid
, &IID_ID3D11SamplerState
)
1183 || IsEqualGUID(riid
, &IID_ID3D11DeviceChild
)
1184 || IsEqualGUID(riid
, &IID_IUnknown
))
1186 ID3D11SamplerState_AddRef(iface
);
1191 if (IsEqualGUID(riid
, &IID_ID3D10SamplerState
)
1192 || IsEqualGUID(riid
, &IID_ID3D10DeviceChild
))
1194 ID3D10SamplerState_AddRef(&state
->ID3D10SamplerState_iface
);
1195 *object
= &state
->ID3D10SamplerState_iface
;
1199 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
1202 return E_NOINTERFACE
;
1205 static ULONG STDMETHODCALLTYPE
d3d11_sampler_state_AddRef(ID3D11SamplerState
*iface
)
1207 struct d3d_sampler_state
*state
= impl_from_ID3D11SamplerState(iface
);
1208 ULONG refcount
= InterlockedIncrement(&state
->refcount
);
1210 TRACE("%p increasing refcount to %u.\n", state
, refcount
);
1214 ID3D11Device2_AddRef(state
->device
);
1215 wined3d_mutex_lock();
1216 wined3d_sampler_incref(state
->wined3d_sampler
);
1217 wined3d_mutex_unlock();
1223 static ULONG STDMETHODCALLTYPE
d3d11_sampler_state_Release(ID3D11SamplerState
*iface
)
1225 struct d3d_sampler_state
*state
= impl_from_ID3D11SamplerState(iface
);
1226 ULONG refcount
= InterlockedDecrement(&state
->refcount
);
1228 TRACE("%p decreasing refcount to %u.\n", state
, refcount
);
1232 ID3D11Device2
*device
= state
->device
;
1234 wined3d_mutex_lock();
1235 wined3d_sampler_decref(state
->wined3d_sampler
);
1236 wined3d_mutex_unlock();
1238 ID3D11Device2_Release(device
);
1244 static void STDMETHODCALLTYPE
d3d11_sampler_state_GetDevice(ID3D11SamplerState
*iface
,
1245 ID3D11Device
**device
)
1247 struct d3d_sampler_state
*state
= impl_from_ID3D11SamplerState(iface
);
1249 TRACE("iface %p, device %p.\n", iface
, device
);
1251 *device
= (ID3D11Device
*)state
->device
;
1252 ID3D11Device_AddRef(*device
);
1255 static HRESULT STDMETHODCALLTYPE
d3d11_sampler_state_GetPrivateData(ID3D11SamplerState
*iface
,
1256 REFGUID guid
, UINT
*data_size
, void *data
)
1258 struct d3d_sampler_state
*state
= impl_from_ID3D11SamplerState(iface
);
1260 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
1262 return d3d_get_private_data(&state
->private_store
, guid
, data_size
, data
);
1265 static HRESULT STDMETHODCALLTYPE
d3d11_sampler_state_SetPrivateData(ID3D11SamplerState
*iface
,
1266 REFGUID guid
, UINT data_size
, const void *data
)
1268 struct d3d_sampler_state
*state
= impl_from_ID3D11SamplerState(iface
);
1270 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
1272 return d3d_set_private_data(&state
->private_store
, guid
, data_size
, data
);
1275 static HRESULT STDMETHODCALLTYPE
d3d11_sampler_state_SetPrivateDataInterface(ID3D11SamplerState
*iface
,
1276 REFGUID guid
, const IUnknown
*data
)
1278 struct d3d_sampler_state
*state
= impl_from_ID3D11SamplerState(iface
);
1280 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
1282 return d3d_set_private_data_interface(&state
->private_store
, guid
, data
);
1285 static void STDMETHODCALLTYPE
d3d11_sampler_state_GetDesc(ID3D11SamplerState
*iface
,
1286 D3D11_SAMPLER_DESC
*desc
)
1288 struct d3d_sampler_state
*state
= impl_from_ID3D11SamplerState(iface
);
1290 TRACE("iface %p, desc %p.\n", iface
, desc
);
1292 *desc
= state
->desc
;
1295 static const struct ID3D11SamplerStateVtbl d3d11_sampler_state_vtbl
=
1297 /* IUnknown methods */
1298 d3d11_sampler_state_QueryInterface
,
1299 d3d11_sampler_state_AddRef
,
1300 d3d11_sampler_state_Release
,
1301 /* ID3D11DeviceChild methods */
1302 d3d11_sampler_state_GetDevice
,
1303 d3d11_sampler_state_GetPrivateData
,
1304 d3d11_sampler_state_SetPrivateData
,
1305 d3d11_sampler_state_SetPrivateDataInterface
,
1306 /* ID3D11SamplerState methods */
1307 d3d11_sampler_state_GetDesc
,
1310 /* ID3D10SamplerState methods */
1312 static inline struct d3d_sampler_state
*impl_from_ID3D10SamplerState(ID3D10SamplerState
*iface
)
1314 return CONTAINING_RECORD(iface
, struct d3d_sampler_state
, ID3D10SamplerState_iface
);
1317 /* IUnknown methods */
1319 static HRESULT STDMETHODCALLTYPE
d3d10_sampler_state_QueryInterface(ID3D10SamplerState
*iface
,
1320 REFIID riid
, void **object
)
1322 struct d3d_sampler_state
*state
= impl_from_ID3D10SamplerState(iface
);
1324 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
1326 return d3d11_sampler_state_QueryInterface(&state
->ID3D11SamplerState_iface
, riid
, object
);
1329 static ULONG STDMETHODCALLTYPE
d3d10_sampler_state_AddRef(ID3D10SamplerState
*iface
)
1331 struct d3d_sampler_state
*state
= impl_from_ID3D10SamplerState(iface
);
1333 TRACE("iface %p.\n", iface
);
1335 return d3d11_sampler_state_AddRef(&state
->ID3D11SamplerState_iface
);
1338 static ULONG STDMETHODCALLTYPE
d3d10_sampler_state_Release(ID3D10SamplerState
*iface
)
1340 struct d3d_sampler_state
*state
= impl_from_ID3D10SamplerState(iface
);
1342 TRACE("iface %p.\n", iface
);
1344 return d3d11_sampler_state_Release(&state
->ID3D11SamplerState_iface
);
1347 /* ID3D10DeviceChild methods */
1349 static void STDMETHODCALLTYPE
d3d10_sampler_state_GetDevice(ID3D10SamplerState
*iface
, ID3D10Device
**device
)
1351 struct d3d_sampler_state
*state
= impl_from_ID3D10SamplerState(iface
);
1353 TRACE("iface %p, device %p.\n", iface
, device
);
1355 ID3D11Device2_QueryInterface(state
->device
, &IID_ID3D10Device
, (void **)device
);
1358 static HRESULT STDMETHODCALLTYPE
d3d10_sampler_state_GetPrivateData(ID3D10SamplerState
*iface
,
1359 REFGUID guid
, UINT
*data_size
, void *data
)
1361 struct d3d_sampler_state
*state
= impl_from_ID3D10SamplerState(iface
);
1363 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
1364 iface
, debugstr_guid(guid
), data_size
, data
);
1366 return d3d_get_private_data(&state
->private_store
, guid
, data_size
, data
);
1369 static HRESULT STDMETHODCALLTYPE
d3d10_sampler_state_SetPrivateData(ID3D10SamplerState
*iface
,
1370 REFGUID guid
, UINT data_size
, const void *data
)
1372 struct d3d_sampler_state
*state
= impl_from_ID3D10SamplerState(iface
);
1374 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
1375 iface
, debugstr_guid(guid
), data_size
, data
);
1377 return d3d_set_private_data(&state
->private_store
, guid
, data_size
, data
);
1380 static HRESULT STDMETHODCALLTYPE
d3d10_sampler_state_SetPrivateDataInterface(ID3D10SamplerState
*iface
,
1381 REFGUID guid
, const IUnknown
*data
)
1383 struct d3d_sampler_state
*state
= impl_from_ID3D10SamplerState(iface
);
1385 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
1387 return d3d_set_private_data_interface(&state
->private_store
, guid
, data
);
1390 /* ID3D10SamplerState methods */
1392 static void STDMETHODCALLTYPE
d3d10_sampler_state_GetDesc(ID3D10SamplerState
*iface
,
1393 D3D10_SAMPLER_DESC
*desc
)
1395 struct d3d_sampler_state
*state
= impl_from_ID3D10SamplerState(iface
);
1397 TRACE("iface %p, desc %p.\n", iface
, desc
);
1399 memcpy(desc
, &state
->desc
, sizeof(*desc
));
1402 static const struct ID3D10SamplerStateVtbl d3d10_sampler_state_vtbl
=
1404 /* IUnknown methods */
1405 d3d10_sampler_state_QueryInterface
,
1406 d3d10_sampler_state_AddRef
,
1407 d3d10_sampler_state_Release
,
1408 /* ID3D10DeviceChild methods */
1409 d3d10_sampler_state_GetDevice
,
1410 d3d10_sampler_state_GetPrivateData
,
1411 d3d10_sampler_state_SetPrivateData
,
1412 d3d10_sampler_state_SetPrivateDataInterface
,
1413 /* ID3D10SamplerState methods */
1414 d3d10_sampler_state_GetDesc
,
1417 static void STDMETHODCALLTYPE
d3d_sampler_wined3d_object_destroyed(void *parent
)
1419 struct d3d_sampler_state
*state
= parent
;
1420 struct d3d_device
*device
= impl_from_ID3D11Device2(state
->device
);
1422 wine_rb_remove(&device
->sampler_states
, &state
->entry
);
1423 wined3d_private_store_cleanup(&state
->private_store
);
1427 static const struct wined3d_parent_ops d3d_sampler_wined3d_parent_ops
=
1429 d3d_sampler_wined3d_object_destroyed
,
1432 static enum wined3d_texture_address
wined3d_texture_address_from_d3d11(enum D3D11_TEXTURE_ADDRESS_MODE t
)
1434 return (enum wined3d_texture_address
)t
;
1437 static enum wined3d_texture_filter_type
wined3d_texture_filter_mip_from_d3d11(enum D3D11_FILTER f
)
1439 if (D3D11_DECODE_MIP_FILTER(f
) == D3D11_FILTER_TYPE_LINEAR
)
1440 return WINED3D_TEXF_LINEAR
;
1441 return WINED3D_TEXF_POINT
;
1444 static enum wined3d_texture_filter_type
wined3d_texture_filter_mag_from_d3d11(enum D3D11_FILTER f
)
1446 if (D3D11_DECODE_MAG_FILTER(f
) == D3D11_FILTER_TYPE_LINEAR
)
1447 return WINED3D_TEXF_LINEAR
;
1448 return WINED3D_TEXF_POINT
;
1451 static enum wined3d_texture_filter_type
wined3d_texture_filter_min_from_d3d11(enum D3D11_FILTER f
)
1453 if (D3D11_DECODE_MIN_FILTER(f
) == D3D11_FILTER_TYPE_LINEAR
)
1454 return WINED3D_TEXF_LINEAR
;
1455 return WINED3D_TEXF_POINT
;
1458 static BOOL
wined3d_texture_compare_from_d3d11(enum D3D11_FILTER f
)
1460 return D3D11_DECODE_IS_COMPARISON_FILTER(f
);
1463 static enum wined3d_cmp_func
wined3d_cmp_func_from_d3d11(D3D11_COMPARISON_FUNC f
)
1465 return (enum wined3d_cmp_func
)f
;
1468 static HRESULT
d3d_sampler_state_init(struct d3d_sampler_state
*state
, struct d3d_device
*device
,
1469 const D3D11_SAMPLER_DESC
*desc
)
1471 struct wined3d_sampler_desc wined3d_desc
;
1474 state
->ID3D11SamplerState_iface
.lpVtbl
= &d3d11_sampler_state_vtbl
;
1475 state
->ID3D10SamplerState_iface
.lpVtbl
= &d3d10_sampler_state_vtbl
;
1476 state
->refcount
= 1;
1477 wined3d_private_store_init(&state
->private_store
);
1478 state
->desc
= *desc
;
1480 wined3d_desc
.address_u
= wined3d_texture_address_from_d3d11(desc
->AddressU
);
1481 wined3d_desc
.address_v
= wined3d_texture_address_from_d3d11(desc
->AddressV
);
1482 wined3d_desc
.address_w
= wined3d_texture_address_from_d3d11(desc
->AddressW
);
1483 memcpy(wined3d_desc
.border_color
, desc
->BorderColor
, sizeof(wined3d_desc
.border_color
));
1484 wined3d_desc
.mag_filter
= wined3d_texture_filter_mag_from_d3d11(desc
->Filter
);
1485 wined3d_desc
.min_filter
= wined3d_texture_filter_min_from_d3d11(desc
->Filter
);
1486 wined3d_desc
.mip_filter
= wined3d_texture_filter_mip_from_d3d11(desc
->Filter
);
1487 wined3d_desc
.lod_bias
= desc
->MipLODBias
;
1488 wined3d_desc
.min_lod
= desc
->MinLOD
;
1489 wined3d_desc
.max_lod
= desc
->MaxLOD
;
1490 wined3d_desc
.mip_base_level
= 0;
1491 wined3d_desc
.max_anisotropy
= D3D11_DECODE_IS_ANISOTROPIC_FILTER(desc
->Filter
) ? desc
->MaxAnisotropy
: 1;
1492 wined3d_desc
.compare
= wined3d_texture_compare_from_d3d11(desc
->Filter
);
1493 wined3d_desc
.comparison_func
= wined3d_cmp_func_from_d3d11(desc
->ComparisonFunc
);
1494 wined3d_desc
.srgb_decode
= TRUE
;
1496 if (wine_rb_put(&device
->sampler_states
, desc
, &state
->entry
) == -1)
1498 ERR("Failed to insert sampler state entry.\n");
1499 wined3d_private_store_cleanup(&state
->private_store
);
1503 /* We cannot fail after creating a wined3d_sampler object. It would lead to
1505 if (FAILED(hr
= wined3d_sampler_create(device
->wined3d_device
, &wined3d_desc
,
1506 state
, &d3d_sampler_wined3d_parent_ops
, &state
->wined3d_sampler
)))
1508 WARN("Failed to create wined3d sampler, hr %#x.\n", hr
);
1509 wined3d_private_store_cleanup(&state
->private_store
);
1510 wine_rb_remove(&device
->sampler_states
, &state
->entry
);
1514 ID3D11Device2_AddRef(state
->device
= &device
->ID3D11Device2_iface
);
1519 HRESULT
d3d_sampler_state_create(struct d3d_device
*device
, const D3D11_SAMPLER_DESC
*desc
,
1520 struct d3d_sampler_state
**state
)
1522 D3D11_SAMPLER_DESC normalized_desc
;
1523 struct d3d_sampler_state
*object
;
1524 struct wine_rb_entry
*entry
;
1528 return E_INVALIDARG
;
1530 normalized_desc
= *desc
;
1531 if (!D3D11_DECODE_IS_ANISOTROPIC_FILTER(normalized_desc
.Filter
))
1532 normalized_desc
.MaxAnisotropy
= 0;
1533 if (!D3D11_DECODE_IS_COMPARISON_FILTER(normalized_desc
.Filter
))
1534 normalized_desc
.ComparisonFunc
= D3D11_COMPARISON_NEVER
;
1535 if (normalized_desc
.AddressU
!= D3D11_TEXTURE_ADDRESS_BORDER
1536 && normalized_desc
.AddressV
!= D3D11_TEXTURE_ADDRESS_BORDER
1537 && normalized_desc
.AddressW
!= D3D11_TEXTURE_ADDRESS_BORDER
)
1538 memset(&normalized_desc
.BorderColor
, 0, sizeof(normalized_desc
.BorderColor
));
1540 wined3d_mutex_lock();
1541 if ((entry
= wine_rb_get(&device
->sampler_states
, &normalized_desc
)))
1543 object
= WINE_RB_ENTRY_VALUE(entry
, struct d3d_sampler_state
, entry
);
1545 TRACE("Returning existing sampler state %p.\n", object
);
1546 ID3D11SamplerState_AddRef(&object
->ID3D11SamplerState_iface
);
1548 wined3d_mutex_unlock();
1553 if (!(object
= heap_alloc_zero(sizeof(*object
))))
1555 wined3d_mutex_unlock();
1556 return E_OUTOFMEMORY
;
1559 hr
= d3d_sampler_state_init(object
, device
, &normalized_desc
);
1560 wined3d_mutex_unlock();
1563 WARN("Failed to initialize sampler state, hr %#x.\n", hr
);
1568 TRACE("Created sampler state %p.\n", object
);
1574 struct d3d_sampler_state
*unsafe_impl_from_ID3D11SamplerState(ID3D11SamplerState
*iface
)
1578 assert(iface
->lpVtbl
== &d3d11_sampler_state_vtbl
);
1580 return impl_from_ID3D11SamplerState(iface
);
1583 struct d3d_sampler_state
*unsafe_impl_from_ID3D10SamplerState(ID3D10SamplerState
*iface
)
1587 assert(iface
->lpVtbl
== &d3d10_sampler_state_vtbl
);
1589 return impl_from_ID3D10SamplerState(iface
);