2 * Copyright 2009 Henri Verbeet for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "wine/port.h"
23 #include "d3d11_private.h"
25 WINE_DEFAULT_DEBUG_CHANNEL(d3d11
);
27 /* ID3D11BlendState methods */
29 static HRESULT STDMETHODCALLTYPE
d3d11_blend_state_QueryInterface(ID3D11BlendState
*iface
,
30 REFIID riid
, void **object
)
32 struct d3d_blend_state
*state
= impl_from_ID3D11BlendState(iface
);
34 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
36 if (IsEqualGUID(riid
, &IID_ID3D11BlendState
)
37 || IsEqualGUID(riid
, &IID_ID3D11DeviceChild
)
38 || IsEqualGUID(riid
, &IID_IUnknown
))
40 ID3D11BlendState_AddRef(iface
);
45 if (IsEqualGUID(riid
, &IID_ID3D10BlendState1
)
46 || IsEqualGUID(riid
, &IID_ID3D10BlendState
)
47 || IsEqualGUID(riid
, &IID_ID3D10DeviceChild
))
49 ID3D10BlendState1_AddRef(&state
->ID3D10BlendState1_iface
);
50 *object
= &state
->ID3D10BlendState1_iface
;
54 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
60 static ULONG STDMETHODCALLTYPE
d3d11_blend_state_AddRef(ID3D11BlendState
*iface
)
62 struct d3d_blend_state
*state
= impl_from_ID3D11BlendState(iface
);
63 ULONG refcount
= InterlockedIncrement(&state
->refcount
);
65 TRACE("%p increasing refcount to %u.\n", state
, refcount
);
69 ID3D11Device2_AddRef(state
->device
);
71 wined3d_blend_state_incref(state
->wined3d_state
);
72 wined3d_mutex_unlock();
78 static ULONG STDMETHODCALLTYPE
d3d11_blend_state_Release(ID3D11BlendState
*iface
)
80 struct d3d_blend_state
*state
= impl_from_ID3D11BlendState(iface
);
81 ULONG refcount
= InterlockedDecrement(&state
->refcount
);
83 TRACE("%p decreasing refcount to %u.\n", state
, refcount
);
87 ID3D11Device2
*device
= state
->device
;
90 wined3d_blend_state_decref(state
->wined3d_state
);
91 wined3d_mutex_unlock();
93 ID3D11Device2_Release(device
);
99 static void STDMETHODCALLTYPE
d3d11_blend_state_GetDevice(ID3D11BlendState
*iface
,
100 ID3D11Device
**device
)
102 struct d3d_blend_state
*state
= impl_from_ID3D11BlendState(iface
);
104 TRACE("iface %p, device %p.\n", iface
, device
);
106 *device
= (ID3D11Device
*)state
->device
;
107 ID3D11Device_AddRef(*device
);
110 static HRESULT STDMETHODCALLTYPE
d3d11_blend_state_GetPrivateData(ID3D11BlendState
*iface
,
111 REFGUID guid
, UINT
*data_size
, void *data
)
113 struct d3d_blend_state
*state
= impl_from_ID3D11BlendState(iface
);
115 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
117 return d3d_get_private_data(&state
->private_store
, guid
, data_size
, data
);
120 static HRESULT STDMETHODCALLTYPE
d3d11_blend_state_SetPrivateData(ID3D11BlendState
*iface
,
121 REFGUID guid
, UINT data_size
, const void *data
)
123 struct d3d_blend_state
*state
= impl_from_ID3D11BlendState(iface
);
125 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
127 return d3d_set_private_data(&state
->private_store
, guid
, data_size
, data
);
130 static HRESULT STDMETHODCALLTYPE
d3d11_blend_state_SetPrivateDataInterface(ID3D11BlendState
*iface
,
131 REFGUID guid
, const IUnknown
*data
)
133 struct d3d_blend_state
*state
= impl_from_ID3D11BlendState(iface
);
135 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
137 return d3d_set_private_data_interface(&state
->private_store
, guid
, data
);
140 static void STDMETHODCALLTYPE
d3d11_blend_state_GetDesc(ID3D11BlendState
*iface
, D3D11_BLEND_DESC
*desc
)
142 struct d3d_blend_state
*state
= impl_from_ID3D11BlendState(iface
);
144 TRACE("iface %p, desc %p.\n", iface
, desc
);
149 static const struct ID3D11BlendStateVtbl d3d11_blend_state_vtbl
=
151 /* IUnknown methods */
152 d3d11_blend_state_QueryInterface
,
153 d3d11_blend_state_AddRef
,
154 d3d11_blend_state_Release
,
155 /* ID3D11DeviceChild methods */
156 d3d11_blend_state_GetDevice
,
157 d3d11_blend_state_GetPrivateData
,
158 d3d11_blend_state_SetPrivateData
,
159 d3d11_blend_state_SetPrivateDataInterface
,
160 /* ID3D11BlendState methods */
161 d3d11_blend_state_GetDesc
,
164 /* ID3D10BlendState methods */
166 static inline struct d3d_blend_state
*impl_from_ID3D10BlendState(ID3D10BlendState1
*iface
)
168 return CONTAINING_RECORD(iface
, struct d3d_blend_state
, ID3D10BlendState1_iface
);
171 /* IUnknown methods */
173 static HRESULT STDMETHODCALLTYPE
d3d10_blend_state_QueryInterface(ID3D10BlendState1
*iface
,
174 REFIID riid
, void **object
)
176 struct d3d_blend_state
*state
= impl_from_ID3D10BlendState(iface
);
178 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
180 return d3d11_blend_state_QueryInterface(&state
->ID3D11BlendState_iface
, riid
, object
);
183 static ULONG STDMETHODCALLTYPE
d3d10_blend_state_AddRef(ID3D10BlendState1
*iface
)
185 struct d3d_blend_state
*state
= impl_from_ID3D10BlendState(iface
);
187 TRACE("iface %p.\n", iface
);
189 return d3d11_blend_state_AddRef(&state
->ID3D11BlendState_iface
);
192 static ULONG STDMETHODCALLTYPE
d3d10_blend_state_Release(ID3D10BlendState1
*iface
)
194 struct d3d_blend_state
*state
= impl_from_ID3D10BlendState(iface
);
196 TRACE("iface %p.\n", iface
);
198 return d3d11_blend_state_Release(&state
->ID3D11BlendState_iface
);
201 /* ID3D10DeviceChild methods */
203 static void STDMETHODCALLTYPE
d3d10_blend_state_GetDevice(ID3D10BlendState1
*iface
, ID3D10Device
**device
)
205 struct d3d_blend_state
*state
= impl_from_ID3D10BlendState(iface
);
207 TRACE("iface %p, device %p.\n", iface
, device
);
209 ID3D11Device2_QueryInterface(state
->device
, &IID_ID3D10Device
, (void **)device
);
212 static HRESULT STDMETHODCALLTYPE
d3d10_blend_state_GetPrivateData(ID3D10BlendState1
*iface
,
213 REFGUID guid
, UINT
*data_size
, void *data
)
215 struct d3d_blend_state
*state
= impl_from_ID3D10BlendState(iface
);
217 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
218 iface
, debugstr_guid(guid
), data_size
, data
);
220 return d3d_get_private_data(&state
->private_store
, guid
, data_size
, data
);
223 static HRESULT STDMETHODCALLTYPE
d3d10_blend_state_SetPrivateData(ID3D10BlendState1
*iface
,
224 REFGUID guid
, UINT data_size
, const void *data
)
226 struct d3d_blend_state
*state
= impl_from_ID3D10BlendState(iface
);
228 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
229 iface
, debugstr_guid(guid
), data_size
, data
);
231 return d3d_set_private_data(&state
->private_store
, guid
, data_size
, data
);
234 static HRESULT STDMETHODCALLTYPE
d3d10_blend_state_SetPrivateDataInterface(ID3D10BlendState1
*iface
,
235 REFGUID guid
, const IUnknown
*data
)
237 struct d3d_blend_state
*state
= impl_from_ID3D10BlendState(iface
);
239 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
241 return d3d_set_private_data_interface(&state
->private_store
, guid
, data
);
244 /* ID3D10BlendState methods */
246 static void STDMETHODCALLTYPE
d3d10_blend_state_GetDesc(ID3D10BlendState1
*iface
, D3D10_BLEND_DESC
*desc
)
248 struct d3d_blend_state
*state
= impl_from_ID3D10BlendState(iface
);
249 const D3D11_BLEND_DESC
*d3d11_desc
= &state
->desc
;
252 TRACE("iface %p, desc %p.\n", iface
, desc
);
254 desc
->AlphaToCoverageEnable
= d3d11_desc
->AlphaToCoverageEnable
;
255 desc
->SrcBlend
= d3d11_desc
->RenderTarget
[0].SrcBlend
;
256 desc
->DestBlend
= d3d11_desc
->RenderTarget
[0].DestBlend
;
257 desc
->BlendOp
= d3d11_desc
->RenderTarget
[0].BlendOp
;
258 desc
->SrcBlendAlpha
= d3d11_desc
->RenderTarget
[0].SrcBlendAlpha
;
259 desc
->DestBlendAlpha
= d3d11_desc
->RenderTarget
[0].DestBlendAlpha
;
260 desc
->BlendOpAlpha
= d3d11_desc
->RenderTarget
[0].BlendOpAlpha
;
261 for (i
= 0; i
< D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT
; ++i
)
263 desc
->BlendEnable
[i
] = d3d11_desc
->RenderTarget
[i
].BlendEnable
;
264 desc
->RenderTargetWriteMask
[i
] = d3d11_desc
->RenderTarget
[i
].RenderTargetWriteMask
;
268 static void STDMETHODCALLTYPE
d3d10_blend_state_GetDesc1(ID3D10BlendState1
*iface
, D3D10_BLEND_DESC1
*desc
)
270 struct d3d_blend_state
*state
= impl_from_ID3D10BlendState(iface
);
272 TRACE("iface %p, desc %p.\n", iface
, desc
);
274 memcpy(desc
, &state
->desc
, sizeof(*desc
));
277 static const struct ID3D10BlendState1Vtbl d3d10_blend_state_vtbl
=
279 /* IUnknown methods */
280 d3d10_blend_state_QueryInterface
,
281 d3d10_blend_state_AddRef
,
282 d3d10_blend_state_Release
,
283 /* ID3D10DeviceChild methods */
284 d3d10_blend_state_GetDevice
,
285 d3d10_blend_state_GetPrivateData
,
286 d3d10_blend_state_SetPrivateData
,
287 d3d10_blend_state_SetPrivateDataInterface
,
288 /* ID3D10BlendState methods */
289 d3d10_blend_state_GetDesc
,
290 /* ID3D10BlendState1 methods */
291 d3d10_blend_state_GetDesc1
,
294 static void STDMETHODCALLTYPE
d3d_blend_state_wined3d_object_destroyed(void *parent
)
296 struct d3d_blend_state
*state
= parent
;
297 struct d3d_device
*device
= impl_from_ID3D11Device2(state
->device
);
299 wine_rb_remove(&device
->blend_states
, &state
->entry
);
300 wined3d_private_store_cleanup(&state
->private_store
);
304 static const struct wined3d_parent_ops d3d_blend_state_wined3d_parent_ops
=
306 d3d_blend_state_wined3d_object_destroyed
,
309 HRESULT
d3d_blend_state_create(struct d3d_device
*device
, const D3D11_BLEND_DESC
*desc
,
310 struct d3d_blend_state
**state
)
312 struct wined3d_blend_state_desc wined3d_desc
;
313 struct d3d_blend_state
*object
;
314 struct wine_rb_entry
*entry
;
315 D3D11_BLEND_DESC tmp_desc
;
322 /* D3D11_RENDER_TARGET_BLEND_DESC has a hole, which is a problem because we use
323 * D3D11_BLEND_DESC as a key in the rbtree. */
324 memset(&tmp_desc
, 0, sizeof(tmp_desc
));
325 tmp_desc
.AlphaToCoverageEnable
= desc
->AlphaToCoverageEnable
;
326 tmp_desc
.IndependentBlendEnable
= desc
->IndependentBlendEnable
;
327 for (i
= 0; i
< D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT
; ++i
)
329 j
= desc
->IndependentBlendEnable
? i
: 0;
330 tmp_desc
.RenderTarget
[i
].BlendEnable
= desc
->RenderTarget
[j
].BlendEnable
;
331 if (tmp_desc
.RenderTarget
[i
].BlendEnable
)
333 tmp_desc
.RenderTarget
[i
].SrcBlend
= desc
->RenderTarget
[j
].SrcBlend
;
334 tmp_desc
.RenderTarget
[i
].DestBlend
= desc
->RenderTarget
[j
].DestBlend
;
335 tmp_desc
.RenderTarget
[i
].BlendOp
= desc
->RenderTarget
[j
].BlendOp
;
336 tmp_desc
.RenderTarget
[i
].SrcBlendAlpha
= desc
->RenderTarget
[j
].SrcBlendAlpha
;
337 tmp_desc
.RenderTarget
[i
].DestBlendAlpha
= desc
->RenderTarget
[j
].DestBlendAlpha
;
338 tmp_desc
.RenderTarget
[i
].BlendOpAlpha
= desc
->RenderTarget
[j
].BlendOpAlpha
;
342 tmp_desc
.RenderTarget
[i
].SrcBlend
= D3D11_BLEND_ONE
;
343 tmp_desc
.RenderTarget
[i
].DestBlend
= D3D11_BLEND_ZERO
;
344 tmp_desc
.RenderTarget
[i
].BlendOp
= D3D11_BLEND_OP_ADD
;
345 tmp_desc
.RenderTarget
[i
].SrcBlendAlpha
= D3D11_BLEND_ONE
;
346 tmp_desc
.RenderTarget
[i
].DestBlendAlpha
= D3D11_BLEND_ZERO
;
347 tmp_desc
.RenderTarget
[i
].BlendOpAlpha
= D3D11_BLEND_OP_ADD
;
349 tmp_desc
.RenderTarget
[i
].RenderTargetWriteMask
= desc
->RenderTarget
[j
].RenderTargetWriteMask
;
351 if (i
> 3 && tmp_desc
.RenderTarget
[i
].RenderTargetWriteMask
!= D3D11_COLOR_WRITE_ENABLE_ALL
)
352 FIXME("Color mask %#x not supported for render target %u.\n",
353 tmp_desc
.RenderTarget
[i
].RenderTargetWriteMask
, i
);
356 /* glEnableIndexedEXT(GL_BLEND, ...) */
357 if (tmp_desc
.IndependentBlendEnable
)
358 FIXME("Per-rendertarget blend not implemented.\n");
360 wined3d_mutex_lock();
361 if ((entry
= wine_rb_get(&device
->blend_states
, &tmp_desc
)))
363 object
= WINE_RB_ENTRY_VALUE(entry
, struct d3d_blend_state
, entry
);
365 TRACE("Returning existing blend state %p.\n", object
);
366 ID3D11BlendState_AddRef(&object
->ID3D11BlendState_iface
);
368 wined3d_mutex_unlock();
373 if (!(object
= heap_alloc_zero(sizeof(*object
))))
375 wined3d_mutex_unlock();
376 return E_OUTOFMEMORY
;
379 object
->ID3D11BlendState_iface
.lpVtbl
= &d3d11_blend_state_vtbl
;
380 object
->ID3D10BlendState1_iface
.lpVtbl
= &d3d10_blend_state_vtbl
;
381 object
->refcount
= 1;
382 wined3d_private_store_init(&object
->private_store
);
383 object
->desc
= tmp_desc
;
385 if (wine_rb_put(&device
->blend_states
, &tmp_desc
, &object
->entry
) == -1)
387 ERR("Failed to insert blend state entry.\n");
388 wined3d_private_store_cleanup(&object
->private_store
);
390 wined3d_mutex_unlock();
394 wined3d_desc
.alpha_to_coverage
= desc
->AlphaToCoverageEnable
;
396 /* We cannot fail after creating a wined3d_blend_state object. It
397 * would lead to double free. */
398 if (FAILED(hr
= wined3d_blend_state_create(device
->wined3d_device
, &wined3d_desc
,
399 object
, &d3d_blend_state_wined3d_parent_ops
, &object
->wined3d_state
)))
401 WARN("Failed to create wined3d blend state, hr %#x.\n", hr
);
402 wined3d_private_store_cleanup(&object
->private_store
);
403 wine_rb_remove(&device
->blend_states
, &object
->entry
);
405 wined3d_mutex_unlock();
408 wined3d_mutex_unlock();
410 ID3D11Device2_AddRef(object
->device
= &device
->ID3D11Device2_iface
);
412 TRACE("Created blend state %p.\n", object
);
418 struct d3d_blend_state
*unsafe_impl_from_ID3D11BlendState(ID3D11BlendState
*iface
)
422 assert(iface
->lpVtbl
== &d3d11_blend_state_vtbl
);
424 return impl_from_ID3D11BlendState(iface
);
427 struct d3d_blend_state
*unsafe_impl_from_ID3D10BlendState(ID3D10BlendState
*iface
)
431 assert(iface
->lpVtbl
== (ID3D10BlendStateVtbl
*)&d3d10_blend_state_vtbl
);
433 return impl_from_ID3D10BlendState((ID3D10BlendState1
*)iface
);
436 /* ID3D11DepthStencilState methods */
438 static HRESULT STDMETHODCALLTYPE
d3d11_depthstencil_state_QueryInterface(ID3D11DepthStencilState
*iface
,
439 REFIID riid
, void **object
)
441 struct d3d_depthstencil_state
*state
= impl_from_ID3D11DepthStencilState(iface
);
443 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
445 if (IsEqualGUID(riid
, &IID_ID3D11DepthStencilState
)
446 || IsEqualGUID(riid
, &IID_ID3D11DeviceChild
)
447 || IsEqualGUID(riid
, &IID_IUnknown
))
449 ID3D11DepthStencilState_AddRef(iface
);
454 if (IsEqualGUID(riid
, &IID_ID3D10DepthStencilState
)
455 || IsEqualGUID(riid
, &IID_ID3D10DeviceChild
))
457 ID3D10DepthStencilState_AddRef(&state
->ID3D10DepthStencilState_iface
);
458 *object
= &state
->ID3D10DepthStencilState_iface
;
462 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
465 return E_NOINTERFACE
;
468 static ULONG STDMETHODCALLTYPE
d3d11_depthstencil_state_AddRef(ID3D11DepthStencilState
*iface
)
470 struct d3d_depthstencil_state
*state
= impl_from_ID3D11DepthStencilState(iface
);
471 ULONG refcount
= InterlockedIncrement(&state
->refcount
);
473 TRACE("%p increasing refcount to %u.\n", state
, refcount
);
478 static void d3d_depthstencil_state_cleanup(struct d3d_depthstencil_state
*state
)
480 wined3d_private_store_cleanup(&state
->private_store
);
481 ID3D11Device2_Release(state
->device
);
484 static ULONG STDMETHODCALLTYPE
d3d11_depthstencil_state_Release(ID3D11DepthStencilState
*iface
)
486 struct d3d_depthstencil_state
*state
= impl_from_ID3D11DepthStencilState(iface
);
487 ULONG refcount
= InterlockedDecrement(&state
->refcount
);
489 TRACE("%p decreasing refcount to %u.\n", state
, refcount
);
493 struct d3d_device
*device
= impl_from_ID3D11Device2(state
->device
);
494 wined3d_mutex_lock();
495 wine_rb_remove(&device
->depthstencil_states
, &state
->entry
);
496 d3d_depthstencil_state_cleanup(state
);
497 wined3d_mutex_unlock();
504 static void STDMETHODCALLTYPE
d3d11_depthstencil_state_GetDevice(ID3D11DepthStencilState
*iface
,
505 ID3D11Device
**device
)
507 struct d3d_depthstencil_state
*state
= impl_from_ID3D11DepthStencilState(iface
);
509 TRACE("iface %p, device %p.\n", iface
, device
);
511 *device
= (ID3D11Device
*)state
->device
;
512 ID3D11Device_AddRef(*device
);
515 static HRESULT STDMETHODCALLTYPE
d3d11_depthstencil_state_GetPrivateData(ID3D11DepthStencilState
*iface
,
516 REFGUID guid
, UINT
*data_size
, void *data
)
518 struct d3d_depthstencil_state
*state
= impl_from_ID3D11DepthStencilState(iface
);
520 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
522 return d3d_get_private_data(&state
->private_store
, guid
, data_size
, data
);
525 static HRESULT STDMETHODCALLTYPE
d3d11_depthstencil_state_SetPrivateData(ID3D11DepthStencilState
*iface
,
526 REFGUID guid
, UINT data_size
, const void *data
)
528 struct d3d_depthstencil_state
*state
= impl_from_ID3D11DepthStencilState(iface
);
530 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
532 return d3d_set_private_data(&state
->private_store
, guid
, data_size
, data
);
535 static HRESULT STDMETHODCALLTYPE
d3d11_depthstencil_state_SetPrivateDataInterface(ID3D11DepthStencilState
*iface
,
536 REFGUID guid
, const IUnknown
*data
)
538 struct d3d_depthstencil_state
*state
= impl_from_ID3D11DepthStencilState(iface
);
540 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
542 return d3d_set_private_data_interface(&state
->private_store
, guid
, data
);
545 static void STDMETHODCALLTYPE
d3d11_depthstencil_state_GetDesc(ID3D11DepthStencilState
*iface
,
546 D3D11_DEPTH_STENCIL_DESC
*desc
)
548 struct d3d_depthstencil_state
*state
= impl_from_ID3D11DepthStencilState(iface
);
550 TRACE("iface %p, desc %p.\n", iface
, desc
);
555 static const struct ID3D11DepthStencilStateVtbl d3d11_depthstencil_state_vtbl
=
557 /* IUnknown methods */
558 d3d11_depthstencil_state_QueryInterface
,
559 d3d11_depthstencil_state_AddRef
,
560 d3d11_depthstencil_state_Release
,
561 /* ID3D11DeviceChild methods */
562 d3d11_depthstencil_state_GetDevice
,
563 d3d11_depthstencil_state_GetPrivateData
,
564 d3d11_depthstencil_state_SetPrivateData
,
565 d3d11_depthstencil_state_SetPrivateDataInterface
,
566 /* ID3D11DepthStencilState methods */
567 d3d11_depthstencil_state_GetDesc
,
570 /* ID3D10DepthStencilState methods */
572 static inline struct d3d_depthstencil_state
*impl_from_ID3D10DepthStencilState(ID3D10DepthStencilState
*iface
)
574 return CONTAINING_RECORD(iface
, struct d3d_depthstencil_state
, ID3D10DepthStencilState_iface
);
577 /* IUnknown methods */
579 static HRESULT STDMETHODCALLTYPE
d3d10_depthstencil_state_QueryInterface(ID3D10DepthStencilState
*iface
,
580 REFIID riid
, void **object
)
582 struct d3d_depthstencil_state
*state
= impl_from_ID3D10DepthStencilState(iface
);
584 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
586 return d3d11_depthstencil_state_QueryInterface(&state
->ID3D11DepthStencilState_iface
, riid
, object
);
589 static ULONG STDMETHODCALLTYPE
d3d10_depthstencil_state_AddRef(ID3D10DepthStencilState
*iface
)
591 struct d3d_depthstencil_state
*state
= impl_from_ID3D10DepthStencilState(iface
);
593 TRACE("iface %p.\n", iface
);
595 return d3d11_depthstencil_state_AddRef(&state
->ID3D11DepthStencilState_iface
);
598 static ULONG STDMETHODCALLTYPE
d3d10_depthstencil_state_Release(ID3D10DepthStencilState
*iface
)
600 struct d3d_depthstencil_state
*state
= impl_from_ID3D10DepthStencilState(iface
);
602 TRACE("iface %p.\n", iface
);
604 return d3d11_depthstencil_state_Release(&state
->ID3D11DepthStencilState_iface
);
607 /* ID3D10DeviceChild methods */
609 static void STDMETHODCALLTYPE
d3d10_depthstencil_state_GetDevice(ID3D10DepthStencilState
*iface
, ID3D10Device
**device
)
611 struct d3d_depthstencil_state
*state
= impl_from_ID3D10DepthStencilState(iface
);
613 TRACE("iface %p, device %p.\n", iface
, device
);
615 ID3D11Device2_QueryInterface(state
->device
, &IID_ID3D10Device
, (void **)device
);
618 static HRESULT STDMETHODCALLTYPE
d3d10_depthstencil_state_GetPrivateData(ID3D10DepthStencilState
*iface
,
619 REFGUID guid
, UINT
*data_size
, void *data
)
621 struct d3d_depthstencil_state
*state
= impl_from_ID3D10DepthStencilState(iface
);
623 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
624 iface
, debugstr_guid(guid
), data_size
, data
);
626 return d3d_get_private_data(&state
->private_store
, guid
, data_size
, data
);
629 static HRESULT STDMETHODCALLTYPE
d3d10_depthstencil_state_SetPrivateData(ID3D10DepthStencilState
*iface
,
630 REFGUID guid
, UINT data_size
, const void *data
)
632 struct d3d_depthstencil_state
*state
= impl_from_ID3D10DepthStencilState(iface
);
634 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
635 iface
, debugstr_guid(guid
), data_size
, data
);
637 return d3d_set_private_data(&state
->private_store
, guid
, data_size
, data
);
640 static HRESULT STDMETHODCALLTYPE
d3d10_depthstencil_state_SetPrivateDataInterface(ID3D10DepthStencilState
*iface
,
641 REFGUID guid
, const IUnknown
*data
)
643 struct d3d_depthstencil_state
*state
= impl_from_ID3D10DepthStencilState(iface
);
645 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
647 return d3d_set_private_data_interface(&state
->private_store
, guid
, data
);
650 /* ID3D10DepthStencilState methods */
652 static void STDMETHODCALLTYPE
d3d10_depthstencil_state_GetDesc(ID3D10DepthStencilState
*iface
,
653 D3D10_DEPTH_STENCIL_DESC
*desc
)
655 struct d3d_depthstencil_state
*state
= impl_from_ID3D10DepthStencilState(iface
);
657 TRACE("iface %p, desc %p.\n", iface
, desc
);
659 memcpy(desc
, &state
->desc
, sizeof(*desc
));
662 static const struct ID3D10DepthStencilStateVtbl d3d10_depthstencil_state_vtbl
=
664 /* IUnknown methods */
665 d3d10_depthstencil_state_QueryInterface
,
666 d3d10_depthstencil_state_AddRef
,
667 d3d10_depthstencil_state_Release
,
668 /* ID3D10DeviceChild methods */
669 d3d10_depthstencil_state_GetDevice
,
670 d3d10_depthstencil_state_GetPrivateData
,
671 d3d10_depthstencil_state_SetPrivateData
,
672 d3d10_depthstencil_state_SetPrivateDataInterface
,
673 /* ID3D10DepthStencilState methods */
674 d3d10_depthstencil_state_GetDesc
,
677 static HRESULT
d3d_depthstencil_state_init(struct d3d_depthstencil_state
*state
, struct d3d_device
*device
,
678 const D3D11_DEPTH_STENCIL_DESC
*desc
)
680 state
->ID3D11DepthStencilState_iface
.lpVtbl
= &d3d11_depthstencil_state_vtbl
;
681 state
->ID3D10DepthStencilState_iface
.lpVtbl
= &d3d10_depthstencil_state_vtbl
;
683 wined3d_private_store_init(&state
->private_store
);
686 ID3D11Device2_AddRef(state
->device
= &device
->ID3D11Device2_iface
);
691 HRESULT
d3d_depthstencil_state_create(struct d3d_device
*device
, const D3D11_DEPTH_STENCIL_DESC
*desc
,
692 struct d3d_depthstencil_state
**state
)
694 struct d3d_depthstencil_state
*object
;
695 D3D11_DEPTH_STENCIL_DESC tmp_desc
;
696 struct wine_rb_entry
*entry
;
702 /* D3D11_DEPTH_STENCIL_DESC has a hole, which is a problem because we use
703 * it as a key in the rbtree. */
704 memset(&tmp_desc
, 0, sizeof(tmp_desc
));
705 tmp_desc
.DepthEnable
= desc
->DepthEnable
;
706 if (desc
->DepthEnable
)
708 tmp_desc
.DepthWriteMask
= desc
->DepthWriteMask
;
709 tmp_desc
.DepthFunc
= desc
->DepthFunc
;
713 tmp_desc
.DepthWriteMask
= D3D11_DEPTH_WRITE_MASK_ALL
;
714 tmp_desc
.DepthFunc
= D3D11_COMPARISON_LESS
;
716 tmp_desc
.StencilEnable
= desc
->StencilEnable
;
717 if (desc
->StencilEnable
)
719 tmp_desc
.StencilReadMask
= desc
->StencilReadMask
;
720 tmp_desc
.StencilWriteMask
= desc
->StencilWriteMask
;
721 tmp_desc
.FrontFace
= desc
->FrontFace
;
722 tmp_desc
.BackFace
= desc
->BackFace
;
726 tmp_desc
.StencilReadMask
= D3D11_DEFAULT_STENCIL_READ_MASK
;
727 tmp_desc
.StencilWriteMask
= D3D11_DEFAULT_STENCIL_WRITE_MASK
;
728 tmp_desc
.FrontFace
.StencilFailOp
= D3D11_STENCIL_OP_KEEP
;
729 tmp_desc
.FrontFace
.StencilDepthFailOp
= D3D11_STENCIL_OP_KEEP
;
730 tmp_desc
.FrontFace
.StencilPassOp
= D3D11_STENCIL_OP_KEEP
;
731 tmp_desc
.FrontFace
.StencilFunc
= D3D11_COMPARISON_ALWAYS
;
732 tmp_desc
.BackFace
.StencilFailOp
= D3D11_STENCIL_OP_KEEP
;
733 tmp_desc
.BackFace
.StencilDepthFailOp
= D3D11_STENCIL_OP_KEEP
;
734 tmp_desc
.BackFace
.StencilPassOp
= D3D11_STENCIL_OP_KEEP
;
735 tmp_desc
.BackFace
.StencilFunc
= D3D11_COMPARISON_ALWAYS
;
738 wined3d_mutex_lock();
739 if ((entry
= wine_rb_get(&device
->depthstencil_states
, &tmp_desc
)))
741 object
= WINE_RB_ENTRY_VALUE(entry
, struct d3d_depthstencil_state
, entry
);
743 TRACE("Returning existing depthstencil state %p.\n", object
);
744 ID3D11DepthStencilState_AddRef(&object
->ID3D11DepthStencilState_iface
);
746 wined3d_mutex_unlock();
751 if (!(object
= heap_alloc_zero(sizeof(*object
))))
753 wined3d_mutex_unlock();
754 return E_OUTOFMEMORY
;
757 if (FAILED(hr
= d3d_depthstencil_state_init(object
, device
, &tmp_desc
)))
759 WARN("Failed to initialize depthstencil state, hr %#x.\n", hr
);
761 wined3d_mutex_unlock();
765 if (wine_rb_put(&device
->depthstencil_states
, &tmp_desc
, &object
->entry
) == -1)
767 ERR("Failed to insert depthstencil state entry.\n");
768 d3d_depthstencil_state_cleanup(object
);
770 wined3d_mutex_unlock();
773 wined3d_mutex_unlock();
775 TRACE("Created depthstencil state %p.\n", object
);
781 struct d3d_depthstencil_state
*unsafe_impl_from_ID3D11DepthStencilState(ID3D11DepthStencilState
*iface
)
785 assert(iface
->lpVtbl
== &d3d11_depthstencil_state_vtbl
);
787 return impl_from_ID3D11DepthStencilState(iface
);
790 struct d3d_depthstencil_state
*unsafe_impl_from_ID3D10DepthStencilState(ID3D10DepthStencilState
*iface
)
794 assert(iface
->lpVtbl
== &d3d10_depthstencil_state_vtbl
);
796 return impl_from_ID3D10DepthStencilState(iface
);
799 /* ID3D11RasterizerState methods */
801 static inline struct d3d_rasterizer_state
*impl_from_ID3D11RasterizerState(ID3D11RasterizerState
*iface
)
803 return CONTAINING_RECORD(iface
, struct d3d_rasterizer_state
, ID3D11RasterizerState_iface
);
806 static HRESULT STDMETHODCALLTYPE
d3d11_rasterizer_state_QueryInterface(ID3D11RasterizerState
*iface
,
807 REFIID riid
, void **object
)
809 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState(iface
);
811 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
813 if (IsEqualGUID(riid
, &IID_ID3D11RasterizerState
)
814 || IsEqualGUID(riid
, &IID_ID3D11DeviceChild
)
815 || IsEqualGUID(riid
, &IID_IUnknown
))
817 ID3D11RasterizerState_AddRef(iface
);
822 if (IsEqualGUID(riid
, &IID_ID3D10RasterizerState
)
823 || IsEqualGUID(riid
, &IID_ID3D10DeviceChild
))
825 ID3D10RasterizerState_AddRef(&state
->ID3D10RasterizerState_iface
);
826 *object
= &state
->ID3D10RasterizerState_iface
;
830 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
833 return E_NOINTERFACE
;
836 static ULONG STDMETHODCALLTYPE
d3d11_rasterizer_state_AddRef(ID3D11RasterizerState
*iface
)
838 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState(iface
);
839 ULONG refcount
= InterlockedIncrement(&state
->refcount
);
841 TRACE("%p increasing refcount to %u.\n", state
, refcount
);
845 ID3D11Device2_AddRef(state
->device
);
846 wined3d_mutex_lock();
847 wined3d_rasterizer_state_incref(state
->wined3d_state
);
848 wined3d_mutex_unlock();
854 static ULONG STDMETHODCALLTYPE
d3d11_rasterizer_state_Release(ID3D11RasterizerState
*iface
)
856 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState(iface
);
857 ULONG refcount
= InterlockedDecrement(&state
->refcount
);
859 TRACE("%p decreasing refcount to %u.\n", state
, refcount
);
863 ID3D11Device2
*device
= state
->device
;
865 wined3d_mutex_lock();
866 wined3d_rasterizer_state_decref(state
->wined3d_state
);
867 wined3d_mutex_unlock();
869 ID3D11Device2_Release(device
);
875 static void STDMETHODCALLTYPE
d3d11_rasterizer_state_GetDevice(ID3D11RasterizerState
*iface
,
876 ID3D11Device
**device
)
878 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState(iface
);
880 TRACE("iface %p, device %p.\n", iface
, device
);
882 *device
= (ID3D11Device
*)state
->device
;
883 ID3D11Device_AddRef(*device
);
886 static HRESULT STDMETHODCALLTYPE
d3d11_rasterizer_state_GetPrivateData(ID3D11RasterizerState
*iface
,
887 REFGUID guid
, UINT
*data_size
, void *data
)
889 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState(iface
);
891 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
893 return d3d_get_private_data(&state
->private_store
, guid
, data_size
, data
);
896 static HRESULT STDMETHODCALLTYPE
d3d11_rasterizer_state_SetPrivateData(ID3D11RasterizerState
*iface
,
897 REFGUID guid
, UINT data_size
, const void *data
)
899 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState(iface
);
901 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
903 return d3d_set_private_data(&state
->private_store
, guid
, data_size
, data
);
906 static HRESULT STDMETHODCALLTYPE
d3d11_rasterizer_state_SetPrivateDataInterface(ID3D11RasterizerState
*iface
,
907 REFGUID guid
, const IUnknown
*data
)
909 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState(iface
);
911 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
913 return d3d_set_private_data_interface(&state
->private_store
, guid
, data
);
916 static void STDMETHODCALLTYPE
d3d11_rasterizer_state_GetDesc(ID3D11RasterizerState
*iface
,
917 D3D11_RASTERIZER_DESC
*desc
)
919 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState(iface
);
921 TRACE("iface %p, desc %p.\n", iface
, desc
);
926 static const struct ID3D11RasterizerStateVtbl d3d11_rasterizer_state_vtbl
=
928 /* IUnknown methods */
929 d3d11_rasterizer_state_QueryInterface
,
930 d3d11_rasterizer_state_AddRef
,
931 d3d11_rasterizer_state_Release
,
932 /* ID3D11DeviceChild methods */
933 d3d11_rasterizer_state_GetDevice
,
934 d3d11_rasterizer_state_GetPrivateData
,
935 d3d11_rasterizer_state_SetPrivateData
,
936 d3d11_rasterizer_state_SetPrivateDataInterface
,
937 /* ID3D11RasterizerState methods */
938 d3d11_rasterizer_state_GetDesc
,
941 /* ID3D10RasterizerState methods */
943 static inline struct d3d_rasterizer_state
*impl_from_ID3D10RasterizerState(ID3D10RasterizerState
*iface
)
945 return CONTAINING_RECORD(iface
, struct d3d_rasterizer_state
, ID3D10RasterizerState_iface
);
948 /* IUnknown methods */
950 static HRESULT STDMETHODCALLTYPE
d3d10_rasterizer_state_QueryInterface(ID3D10RasterizerState
*iface
,
951 REFIID riid
, void **object
)
953 struct d3d_rasterizer_state
*state
= impl_from_ID3D10RasterizerState(iface
);
955 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
957 return d3d11_rasterizer_state_QueryInterface(&state
->ID3D11RasterizerState_iface
, riid
, object
);
960 static ULONG STDMETHODCALLTYPE
d3d10_rasterizer_state_AddRef(ID3D10RasterizerState
*iface
)
962 struct d3d_rasterizer_state
*state
= impl_from_ID3D10RasterizerState(iface
);
964 TRACE("iface %p.\n", iface
);
966 return d3d11_rasterizer_state_AddRef(&state
->ID3D11RasterizerState_iface
);
969 static ULONG STDMETHODCALLTYPE
d3d10_rasterizer_state_Release(ID3D10RasterizerState
*iface
)
971 struct d3d_rasterizer_state
*state
= impl_from_ID3D10RasterizerState(iface
);
973 TRACE("iface %p.\n", state
);
975 return d3d11_rasterizer_state_Release(&state
->ID3D11RasterizerState_iface
);
978 /* ID3D10DeviceChild methods */
980 static void STDMETHODCALLTYPE
d3d10_rasterizer_state_GetDevice(ID3D10RasterizerState
*iface
, ID3D10Device
**device
)
982 struct d3d_rasterizer_state
*state
= impl_from_ID3D10RasterizerState(iface
);
984 TRACE("iface %p, device %p.\n", iface
, device
);
986 ID3D11Device2_QueryInterface(state
->device
, &IID_ID3D10Device
, (void **)device
);
989 static HRESULT STDMETHODCALLTYPE
d3d10_rasterizer_state_GetPrivateData(ID3D10RasterizerState
*iface
,
990 REFGUID guid
, UINT
*data_size
, void *data
)
992 struct d3d_rasterizer_state
*state
= impl_from_ID3D10RasterizerState(iface
);
994 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
995 iface
, debugstr_guid(guid
), data_size
, data
);
997 return d3d_get_private_data(&state
->private_store
, guid
, data_size
, data
);
1000 static HRESULT STDMETHODCALLTYPE
d3d10_rasterizer_state_SetPrivateData(ID3D10RasterizerState
*iface
,
1001 REFGUID guid
, UINT data_size
, const void *data
)
1003 struct d3d_rasterizer_state
*state
= impl_from_ID3D10RasterizerState(iface
);
1005 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
1006 iface
, debugstr_guid(guid
), data_size
, data
);
1008 return d3d_set_private_data(&state
->private_store
, guid
, data_size
, data
);
1011 static HRESULT STDMETHODCALLTYPE
d3d10_rasterizer_state_SetPrivateDataInterface(ID3D10RasterizerState
*iface
,
1012 REFGUID guid
, const IUnknown
*data
)
1014 struct d3d_rasterizer_state
*state
= impl_from_ID3D10RasterizerState(iface
);
1016 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
1018 return d3d_set_private_data_interface(&state
->private_store
, guid
, data
);
1021 /* ID3D10RasterizerState methods */
1023 static void STDMETHODCALLTYPE
d3d10_rasterizer_state_GetDesc(ID3D10RasterizerState
*iface
,
1024 D3D10_RASTERIZER_DESC
*desc
)
1026 struct d3d_rasterizer_state
*state
= impl_from_ID3D10RasterizerState(iface
);
1028 TRACE("iface %p, desc %p.\n", iface
, desc
);
1030 memcpy(desc
, &state
->desc
, sizeof(*desc
));
1033 static const struct ID3D10RasterizerStateVtbl d3d10_rasterizer_state_vtbl
=
1035 /* IUnknown methods */
1036 d3d10_rasterizer_state_QueryInterface
,
1037 d3d10_rasterizer_state_AddRef
,
1038 d3d10_rasterizer_state_Release
,
1039 /* ID3D10DeviceChild methods */
1040 d3d10_rasterizer_state_GetDevice
,
1041 d3d10_rasterizer_state_GetPrivateData
,
1042 d3d10_rasterizer_state_SetPrivateData
,
1043 d3d10_rasterizer_state_SetPrivateDataInterface
,
1044 /* ID3D10RasterizerState methods */
1045 d3d10_rasterizer_state_GetDesc
,
1048 static void STDMETHODCALLTYPE
d3d_rasterizer_state_wined3d_object_destroyed(void *parent
)
1050 struct d3d_rasterizer_state
*state
= parent
;
1051 struct d3d_device
*device
= impl_from_ID3D11Device2(state
->device
);
1053 wine_rb_remove(&device
->rasterizer_states
, &state
->entry
);
1054 wined3d_private_store_cleanup(&state
->private_store
);
1058 static const struct wined3d_parent_ops d3d_rasterizer_state_wined3d_parent_ops
=
1060 d3d_rasterizer_state_wined3d_object_destroyed
,
1063 static HRESULT
d3d_rasterizer_state_init(struct d3d_rasterizer_state
*state
, struct d3d_device
*device
,
1064 const D3D11_RASTERIZER_DESC
*desc
)
1066 struct wined3d_rasterizer_state_desc wined3d_desc
;
1069 state
->ID3D11RasterizerState_iface
.lpVtbl
= &d3d11_rasterizer_state_vtbl
;
1070 state
->ID3D10RasterizerState_iface
.lpVtbl
= &d3d10_rasterizer_state_vtbl
;
1071 state
->refcount
= 1;
1072 wined3d_private_store_init(&state
->private_store
);
1073 state
->desc
= *desc
;
1075 if (wine_rb_put(&device
->rasterizer_states
, desc
, &state
->entry
) == -1)
1077 ERR("Failed to insert rasterizer state entry.\n");
1078 wined3d_private_store_cleanup(&state
->private_store
);
1082 wined3d_desc
.front_ccw
= desc
->FrontCounterClockwise
;
1083 wined3d_desc
.depth_clip
= desc
->DepthClipEnable
;
1085 /* We cannot fail after creating a wined3d_rasterizer_state object. It
1086 * would lead to double free. */
1087 if (FAILED(hr
= wined3d_rasterizer_state_create(device
->wined3d_device
, &wined3d_desc
,
1088 state
, &d3d_rasterizer_state_wined3d_parent_ops
, &state
->wined3d_state
)))
1090 WARN("Failed to create wined3d rasterizer state, hr %#x.\n", hr
);
1091 wined3d_private_store_cleanup(&state
->private_store
);
1092 wine_rb_remove(&device
->rasterizer_states
, &state
->entry
);
1096 ID3D11Device2_AddRef(state
->device
= &device
->ID3D11Device2_iface
);
1101 HRESULT
d3d_rasterizer_state_create(struct d3d_device
*device
, const D3D11_RASTERIZER_DESC
*desc
,
1102 struct d3d_rasterizer_state
**state
)
1104 struct d3d_rasterizer_state
*object
;
1105 struct wine_rb_entry
*entry
;
1109 return E_INVALIDARG
;
1111 wined3d_mutex_lock();
1112 if ((entry
= wine_rb_get(&device
->rasterizer_states
, desc
)))
1114 object
= WINE_RB_ENTRY_VALUE(entry
, struct d3d_rasterizer_state
, entry
);
1116 TRACE("Returning existing rasterizer state %p.\n", object
);
1117 ID3D11RasterizerState_AddRef(&object
->ID3D11RasterizerState_iface
);
1119 wined3d_mutex_unlock();
1124 if (!(object
= heap_alloc_zero(sizeof(*object
))))
1126 wined3d_mutex_unlock();
1127 return E_OUTOFMEMORY
;
1130 hr
= d3d_rasterizer_state_init(object
, device
, desc
);
1131 wined3d_mutex_unlock();
1134 WARN("Failed to initialize rasterizer state, hr %#x.\n", hr
);
1139 TRACE("Created rasterizer state %p.\n", object
);
1145 struct d3d_rasterizer_state
*unsafe_impl_from_ID3D11RasterizerState(ID3D11RasterizerState
*iface
)
1149 assert(iface
->lpVtbl
== &d3d11_rasterizer_state_vtbl
);
1151 return impl_from_ID3D11RasterizerState(iface
);
1154 struct d3d_rasterizer_state
*unsafe_impl_from_ID3D10RasterizerState(ID3D10RasterizerState
*iface
)
1158 assert(iface
->lpVtbl
== &d3d10_rasterizer_state_vtbl
);
1160 return impl_from_ID3D10RasterizerState(iface
);
1163 /* ID3D11SampleState methods */
1165 static inline struct d3d_sampler_state
*impl_from_ID3D11SamplerState(ID3D11SamplerState
*iface
)
1167 return CONTAINING_RECORD(iface
, struct d3d_sampler_state
, ID3D11SamplerState_iface
);
1170 static HRESULT STDMETHODCALLTYPE
d3d11_sampler_state_QueryInterface(ID3D11SamplerState
*iface
,
1171 REFIID riid
, void **object
)
1173 struct d3d_sampler_state
*state
= impl_from_ID3D11SamplerState(iface
);
1175 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
1177 if (IsEqualGUID(riid
, &IID_ID3D11SamplerState
)
1178 || IsEqualGUID(riid
, &IID_ID3D11DeviceChild
)
1179 || IsEqualGUID(riid
, &IID_IUnknown
))
1181 ID3D11SamplerState_AddRef(iface
);
1186 if (IsEqualGUID(riid
, &IID_ID3D10SamplerState
)
1187 || IsEqualGUID(riid
, &IID_ID3D10DeviceChild
))
1189 ID3D10SamplerState_AddRef(&state
->ID3D10SamplerState_iface
);
1190 *object
= &state
->ID3D10SamplerState_iface
;
1194 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
1197 return E_NOINTERFACE
;
1200 static ULONG STDMETHODCALLTYPE
d3d11_sampler_state_AddRef(ID3D11SamplerState
*iface
)
1202 struct d3d_sampler_state
*state
= impl_from_ID3D11SamplerState(iface
);
1203 ULONG refcount
= InterlockedIncrement(&state
->refcount
);
1205 TRACE("%p increasing refcount to %u.\n", state
, refcount
);
1209 ID3D11Device2_AddRef(state
->device
);
1210 wined3d_mutex_lock();
1211 wined3d_sampler_incref(state
->wined3d_sampler
);
1212 wined3d_mutex_unlock();
1218 static ULONG STDMETHODCALLTYPE
d3d11_sampler_state_Release(ID3D11SamplerState
*iface
)
1220 struct d3d_sampler_state
*state
= impl_from_ID3D11SamplerState(iface
);
1221 ULONG refcount
= InterlockedDecrement(&state
->refcount
);
1223 TRACE("%p decreasing refcount to %u.\n", state
, refcount
);
1227 ID3D11Device2
*device
= state
->device
;
1229 wined3d_mutex_lock();
1230 wined3d_sampler_decref(state
->wined3d_sampler
);
1231 wined3d_mutex_unlock();
1233 ID3D11Device2_Release(device
);
1239 static void STDMETHODCALLTYPE
d3d11_sampler_state_GetDevice(ID3D11SamplerState
*iface
,
1240 ID3D11Device
**device
)
1242 struct d3d_sampler_state
*state
= impl_from_ID3D11SamplerState(iface
);
1244 TRACE("iface %p, device %p.\n", iface
, device
);
1246 *device
= (ID3D11Device
*)state
->device
;
1247 ID3D11Device_AddRef(*device
);
1250 static HRESULT STDMETHODCALLTYPE
d3d11_sampler_state_GetPrivateData(ID3D11SamplerState
*iface
,
1251 REFGUID guid
, UINT
*data_size
, void *data
)
1253 struct d3d_sampler_state
*state
= impl_from_ID3D11SamplerState(iface
);
1255 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
1257 return d3d_get_private_data(&state
->private_store
, guid
, data_size
, data
);
1260 static HRESULT STDMETHODCALLTYPE
d3d11_sampler_state_SetPrivateData(ID3D11SamplerState
*iface
,
1261 REFGUID guid
, UINT data_size
, const void *data
)
1263 struct d3d_sampler_state
*state
= impl_from_ID3D11SamplerState(iface
);
1265 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
1267 return d3d_set_private_data(&state
->private_store
, guid
, data_size
, data
);
1270 static HRESULT STDMETHODCALLTYPE
d3d11_sampler_state_SetPrivateDataInterface(ID3D11SamplerState
*iface
,
1271 REFGUID guid
, const IUnknown
*data
)
1273 struct d3d_sampler_state
*state
= impl_from_ID3D11SamplerState(iface
);
1275 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
1277 return d3d_set_private_data_interface(&state
->private_store
, guid
, data
);
1280 static void STDMETHODCALLTYPE
d3d11_sampler_state_GetDesc(ID3D11SamplerState
*iface
,
1281 D3D11_SAMPLER_DESC
*desc
)
1283 struct d3d_sampler_state
*state
= impl_from_ID3D11SamplerState(iface
);
1285 TRACE("iface %p, desc %p.\n", iface
, desc
);
1287 *desc
= state
->desc
;
1290 static const struct ID3D11SamplerStateVtbl d3d11_sampler_state_vtbl
=
1292 /* IUnknown methods */
1293 d3d11_sampler_state_QueryInterface
,
1294 d3d11_sampler_state_AddRef
,
1295 d3d11_sampler_state_Release
,
1296 /* ID3D11DeviceChild methods */
1297 d3d11_sampler_state_GetDevice
,
1298 d3d11_sampler_state_GetPrivateData
,
1299 d3d11_sampler_state_SetPrivateData
,
1300 d3d11_sampler_state_SetPrivateDataInterface
,
1301 /* ID3D11SamplerState methods */
1302 d3d11_sampler_state_GetDesc
,
1305 /* ID3D10SamplerState methods */
1307 static inline struct d3d_sampler_state
*impl_from_ID3D10SamplerState(ID3D10SamplerState
*iface
)
1309 return CONTAINING_RECORD(iface
, struct d3d_sampler_state
, ID3D10SamplerState_iface
);
1312 /* IUnknown methods */
1314 static HRESULT STDMETHODCALLTYPE
d3d10_sampler_state_QueryInterface(ID3D10SamplerState
*iface
,
1315 REFIID riid
, void **object
)
1317 struct d3d_sampler_state
*state
= impl_from_ID3D10SamplerState(iface
);
1319 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
1321 return d3d11_sampler_state_QueryInterface(&state
->ID3D11SamplerState_iface
, riid
, object
);
1324 static ULONG STDMETHODCALLTYPE
d3d10_sampler_state_AddRef(ID3D10SamplerState
*iface
)
1326 struct d3d_sampler_state
*state
= impl_from_ID3D10SamplerState(iface
);
1328 TRACE("iface %p.\n", iface
);
1330 return d3d11_sampler_state_AddRef(&state
->ID3D11SamplerState_iface
);
1333 static ULONG STDMETHODCALLTYPE
d3d10_sampler_state_Release(ID3D10SamplerState
*iface
)
1335 struct d3d_sampler_state
*state
= impl_from_ID3D10SamplerState(iface
);
1337 TRACE("iface %p.\n", iface
);
1339 return d3d11_sampler_state_Release(&state
->ID3D11SamplerState_iface
);
1342 /* ID3D10DeviceChild methods */
1344 static void STDMETHODCALLTYPE
d3d10_sampler_state_GetDevice(ID3D10SamplerState
*iface
, ID3D10Device
**device
)
1346 struct d3d_sampler_state
*state
= impl_from_ID3D10SamplerState(iface
);
1348 TRACE("iface %p, device %p.\n", iface
, device
);
1350 ID3D11Device2_QueryInterface(state
->device
, &IID_ID3D10Device
, (void **)device
);
1353 static HRESULT STDMETHODCALLTYPE
d3d10_sampler_state_GetPrivateData(ID3D10SamplerState
*iface
,
1354 REFGUID guid
, UINT
*data_size
, void *data
)
1356 struct d3d_sampler_state
*state
= impl_from_ID3D10SamplerState(iface
);
1358 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
1359 iface
, debugstr_guid(guid
), data_size
, data
);
1361 return d3d_get_private_data(&state
->private_store
, guid
, data_size
, data
);
1364 static HRESULT STDMETHODCALLTYPE
d3d10_sampler_state_SetPrivateData(ID3D10SamplerState
*iface
,
1365 REFGUID guid
, UINT data_size
, const void *data
)
1367 struct d3d_sampler_state
*state
= impl_from_ID3D10SamplerState(iface
);
1369 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
1370 iface
, debugstr_guid(guid
), data_size
, data
);
1372 return d3d_set_private_data(&state
->private_store
, guid
, data_size
, data
);
1375 static HRESULT STDMETHODCALLTYPE
d3d10_sampler_state_SetPrivateDataInterface(ID3D10SamplerState
*iface
,
1376 REFGUID guid
, const IUnknown
*data
)
1378 struct d3d_sampler_state
*state
= impl_from_ID3D10SamplerState(iface
);
1380 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
1382 return d3d_set_private_data_interface(&state
->private_store
, guid
, data
);
1385 /* ID3D10SamplerState methods */
1387 static void STDMETHODCALLTYPE
d3d10_sampler_state_GetDesc(ID3D10SamplerState
*iface
,
1388 D3D10_SAMPLER_DESC
*desc
)
1390 struct d3d_sampler_state
*state
= impl_from_ID3D10SamplerState(iface
);
1392 TRACE("iface %p, desc %p.\n", iface
, desc
);
1394 memcpy(desc
, &state
->desc
, sizeof(*desc
));
1397 static const struct ID3D10SamplerStateVtbl d3d10_sampler_state_vtbl
=
1399 /* IUnknown methods */
1400 d3d10_sampler_state_QueryInterface
,
1401 d3d10_sampler_state_AddRef
,
1402 d3d10_sampler_state_Release
,
1403 /* ID3D10DeviceChild methods */
1404 d3d10_sampler_state_GetDevice
,
1405 d3d10_sampler_state_GetPrivateData
,
1406 d3d10_sampler_state_SetPrivateData
,
1407 d3d10_sampler_state_SetPrivateDataInterface
,
1408 /* ID3D10SamplerState methods */
1409 d3d10_sampler_state_GetDesc
,
1412 static void STDMETHODCALLTYPE
d3d_sampler_wined3d_object_destroyed(void *parent
)
1414 struct d3d_sampler_state
*state
= parent
;
1415 struct d3d_device
*device
= impl_from_ID3D11Device2(state
->device
);
1417 wine_rb_remove(&device
->sampler_states
, &state
->entry
);
1418 wined3d_private_store_cleanup(&state
->private_store
);
1422 static const struct wined3d_parent_ops d3d_sampler_wined3d_parent_ops
=
1424 d3d_sampler_wined3d_object_destroyed
,
1427 static enum wined3d_texture_address
wined3d_texture_address_from_d3d11(enum D3D11_TEXTURE_ADDRESS_MODE t
)
1429 return (enum wined3d_texture_address
)t
;
1432 static enum wined3d_texture_filter_type
wined3d_texture_filter_mip_from_d3d11(enum D3D11_FILTER f
)
1434 if (D3D11_DECODE_MIP_FILTER(f
) == D3D11_FILTER_TYPE_LINEAR
)
1435 return WINED3D_TEXF_LINEAR
;
1436 return WINED3D_TEXF_POINT
;
1439 static enum wined3d_texture_filter_type
wined3d_texture_filter_mag_from_d3d11(enum D3D11_FILTER f
)
1441 if (D3D11_DECODE_MAG_FILTER(f
) == D3D11_FILTER_TYPE_LINEAR
)
1442 return WINED3D_TEXF_LINEAR
;
1443 return WINED3D_TEXF_POINT
;
1446 static enum wined3d_texture_filter_type
wined3d_texture_filter_min_from_d3d11(enum D3D11_FILTER f
)
1448 if (D3D11_DECODE_MIN_FILTER(f
) == D3D11_FILTER_TYPE_LINEAR
)
1449 return WINED3D_TEXF_LINEAR
;
1450 return WINED3D_TEXF_POINT
;
1453 static BOOL
wined3d_texture_compare_from_d3d11(enum D3D11_FILTER f
)
1455 return D3D11_DECODE_IS_COMPARISON_FILTER(f
);
1458 static enum wined3d_cmp_func
wined3d_cmp_func_from_d3d11(D3D11_COMPARISON_FUNC f
)
1460 return (enum wined3d_cmp_func
)f
;
1463 static HRESULT
d3d_sampler_state_init(struct d3d_sampler_state
*state
, struct d3d_device
*device
,
1464 const D3D11_SAMPLER_DESC
*desc
)
1466 struct wined3d_sampler_desc wined3d_desc
;
1469 state
->ID3D11SamplerState_iface
.lpVtbl
= &d3d11_sampler_state_vtbl
;
1470 state
->ID3D10SamplerState_iface
.lpVtbl
= &d3d10_sampler_state_vtbl
;
1471 state
->refcount
= 1;
1472 wined3d_private_store_init(&state
->private_store
);
1473 state
->desc
= *desc
;
1475 wined3d_desc
.address_u
= wined3d_texture_address_from_d3d11(desc
->AddressU
);
1476 wined3d_desc
.address_v
= wined3d_texture_address_from_d3d11(desc
->AddressV
);
1477 wined3d_desc
.address_w
= wined3d_texture_address_from_d3d11(desc
->AddressW
);
1478 memcpy(wined3d_desc
.border_color
, desc
->BorderColor
, sizeof(wined3d_desc
.border_color
));
1479 wined3d_desc
.mag_filter
= wined3d_texture_filter_mag_from_d3d11(desc
->Filter
);
1480 wined3d_desc
.min_filter
= wined3d_texture_filter_min_from_d3d11(desc
->Filter
);
1481 wined3d_desc
.mip_filter
= wined3d_texture_filter_mip_from_d3d11(desc
->Filter
);
1482 wined3d_desc
.lod_bias
= desc
->MipLODBias
;
1483 wined3d_desc
.min_lod
= desc
->MinLOD
;
1484 wined3d_desc
.max_lod
= desc
->MaxLOD
;
1485 wined3d_desc
.mip_base_level
= 0;
1486 wined3d_desc
.max_anisotropy
= D3D11_DECODE_IS_ANISOTROPIC_FILTER(desc
->Filter
) ? desc
->MaxAnisotropy
: 1;
1487 wined3d_desc
.compare
= wined3d_texture_compare_from_d3d11(desc
->Filter
);
1488 wined3d_desc
.comparison_func
= wined3d_cmp_func_from_d3d11(desc
->ComparisonFunc
);
1489 wined3d_desc
.srgb_decode
= TRUE
;
1491 if (wine_rb_put(&device
->sampler_states
, desc
, &state
->entry
) == -1)
1493 ERR("Failed to insert sampler state entry.\n");
1494 wined3d_private_store_cleanup(&state
->private_store
);
1498 /* We cannot fail after creating a wined3d_sampler object. It would lead to
1500 if (FAILED(hr
= wined3d_sampler_create(device
->wined3d_device
, &wined3d_desc
,
1501 state
, &d3d_sampler_wined3d_parent_ops
, &state
->wined3d_sampler
)))
1503 WARN("Failed to create wined3d sampler, hr %#x.\n", hr
);
1504 wined3d_private_store_cleanup(&state
->private_store
);
1505 wine_rb_remove(&device
->sampler_states
, &state
->entry
);
1509 ID3D11Device2_AddRef(state
->device
= &device
->ID3D11Device2_iface
);
1514 HRESULT
d3d_sampler_state_create(struct d3d_device
*device
, const D3D11_SAMPLER_DESC
*desc
,
1515 struct d3d_sampler_state
**state
)
1517 D3D11_SAMPLER_DESC normalized_desc
;
1518 struct d3d_sampler_state
*object
;
1519 struct wine_rb_entry
*entry
;
1523 return E_INVALIDARG
;
1525 normalized_desc
= *desc
;
1526 if (!D3D11_DECODE_IS_ANISOTROPIC_FILTER(normalized_desc
.Filter
))
1527 normalized_desc
.MaxAnisotropy
= 0;
1528 if (!D3D11_DECODE_IS_COMPARISON_FILTER(normalized_desc
.Filter
))
1529 normalized_desc
.ComparisonFunc
= D3D11_COMPARISON_NEVER
;
1530 if (normalized_desc
.AddressU
!= D3D11_TEXTURE_ADDRESS_BORDER
1531 && normalized_desc
.AddressV
!= D3D11_TEXTURE_ADDRESS_BORDER
1532 && normalized_desc
.AddressW
!= D3D11_TEXTURE_ADDRESS_BORDER
)
1533 memset(&normalized_desc
.BorderColor
, 0, sizeof(normalized_desc
.BorderColor
));
1535 wined3d_mutex_lock();
1536 if ((entry
= wine_rb_get(&device
->sampler_states
, &normalized_desc
)))
1538 object
= WINE_RB_ENTRY_VALUE(entry
, struct d3d_sampler_state
, entry
);
1540 TRACE("Returning existing sampler state %p.\n", object
);
1541 ID3D11SamplerState_AddRef(&object
->ID3D11SamplerState_iface
);
1543 wined3d_mutex_unlock();
1548 if (!(object
= heap_alloc_zero(sizeof(*object
))))
1550 wined3d_mutex_unlock();
1551 return E_OUTOFMEMORY
;
1554 hr
= d3d_sampler_state_init(object
, device
, &normalized_desc
);
1555 wined3d_mutex_unlock();
1558 WARN("Failed to initialize sampler state, hr %#x.\n", hr
);
1563 TRACE("Created sampler state %p.\n", object
);
1569 struct d3d_sampler_state
*unsafe_impl_from_ID3D11SamplerState(ID3D11SamplerState
*iface
)
1573 assert(iface
->lpVtbl
== &d3d11_sampler_state_vtbl
);
1575 return impl_from_ID3D11SamplerState(iface
);
1578 struct d3d_sampler_state
*unsafe_impl_from_ID3D10SamplerState(ID3D10SamplerState
*iface
)
1582 assert(iface
->lpVtbl
== &d3d10_sampler_state_vtbl
);
1584 return impl_from_ID3D10SamplerState(iface
);