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 ID3D11Device_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 ID3D11Device
*device
= state
->device
;
90 wined3d_blend_state_decref(state
->wined3d_state
);
91 wined3d_mutex_unlock();
93 ID3D11Device_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
= 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 ID3D11Device_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_ID3D11Device(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 tmp_desc
.RenderTarget
[i
].SrcBlend
= desc
->RenderTarget
[j
].SrcBlend
;
332 tmp_desc
.RenderTarget
[i
].DestBlend
= desc
->RenderTarget
[j
].DestBlend
;
333 tmp_desc
.RenderTarget
[i
].BlendOp
= desc
->RenderTarget
[j
].BlendOp
;
334 tmp_desc
.RenderTarget
[i
].SrcBlendAlpha
= desc
->RenderTarget
[j
].SrcBlendAlpha
;
335 tmp_desc
.RenderTarget
[i
].DestBlendAlpha
= desc
->RenderTarget
[j
].DestBlendAlpha
;
336 tmp_desc
.RenderTarget
[i
].BlendOpAlpha
= desc
->RenderTarget
[j
].BlendOpAlpha
;
337 tmp_desc
.RenderTarget
[i
].RenderTargetWriteMask
= desc
->RenderTarget
[j
].RenderTargetWriteMask
;
339 if (i
> 3 && tmp_desc
.RenderTarget
[i
].RenderTargetWriteMask
!= D3D11_COLOR_WRITE_ENABLE_ALL
)
340 FIXME("Color mask %#x not supported for render target %u.\n",
341 tmp_desc
.RenderTarget
[i
].RenderTargetWriteMask
, i
);
344 /* glEnableIndexedEXT(GL_BLEND, ...) */
345 if (tmp_desc
.IndependentBlendEnable
)
346 FIXME("Per-rendertarget blend not implemented.\n");
348 wined3d_mutex_lock();
349 if ((entry
= wine_rb_get(&device
->blend_states
, &tmp_desc
)))
351 object
= WINE_RB_ENTRY_VALUE(entry
, struct d3d_blend_state
, entry
);
353 TRACE("Returning existing blend state %p.\n", object
);
354 ID3D11BlendState_AddRef(&object
->ID3D11BlendState_iface
);
356 wined3d_mutex_unlock();
361 if (!(object
= heap_alloc_zero(sizeof(*object
))))
363 wined3d_mutex_unlock();
364 return E_OUTOFMEMORY
;
367 object
->ID3D11BlendState_iface
.lpVtbl
= &d3d11_blend_state_vtbl
;
368 object
->ID3D10BlendState1_iface
.lpVtbl
= &d3d10_blend_state_vtbl
;
369 object
->refcount
= 1;
370 wined3d_private_store_init(&object
->private_store
);
371 object
->desc
= tmp_desc
;
373 if (wine_rb_put(&device
->blend_states
, &tmp_desc
, &object
->entry
) == -1)
375 ERR("Failed to insert blend state entry.\n");
376 wined3d_private_store_cleanup(&object
->private_store
);
378 wined3d_mutex_unlock();
382 wined3d_desc
.alpha_to_coverage
= desc
->AlphaToCoverageEnable
;
384 /* We cannot fail after creating a wined3d_blend_state object. It
385 * would lead to double free. */
386 if (FAILED(hr
= wined3d_blend_state_create(device
->wined3d_device
, &wined3d_desc
,
387 object
, &d3d_blend_state_wined3d_parent_ops
, &object
->wined3d_state
)))
389 WARN("Failed to create wined3d blend state, hr %#x.\n", hr
);
390 wined3d_private_store_cleanup(&object
->private_store
);
391 wine_rb_remove(&device
->blend_states
, &object
->entry
);
393 wined3d_mutex_unlock();
396 wined3d_mutex_unlock();
398 ID3D11Device_AddRef(object
->device
= &device
->ID3D11Device_iface
);
400 TRACE("Created blend state %p.\n", object
);
406 struct d3d_blend_state
*unsafe_impl_from_ID3D11BlendState(ID3D11BlendState
*iface
)
410 assert(iface
->lpVtbl
== &d3d11_blend_state_vtbl
);
412 return impl_from_ID3D11BlendState(iface
);
415 struct d3d_blend_state
*unsafe_impl_from_ID3D10BlendState(ID3D10BlendState
*iface
)
419 assert(iface
->lpVtbl
== (ID3D10BlendStateVtbl
*)&d3d10_blend_state_vtbl
);
421 return impl_from_ID3D10BlendState((ID3D10BlendState1
*)iface
);
424 /* ID3D11DepthStencilState methods */
426 static HRESULT STDMETHODCALLTYPE
d3d11_depthstencil_state_QueryInterface(ID3D11DepthStencilState
*iface
,
427 REFIID riid
, void **object
)
429 struct d3d_depthstencil_state
*state
= impl_from_ID3D11DepthStencilState(iface
);
431 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
433 if (IsEqualGUID(riid
, &IID_ID3D11DepthStencilState
)
434 || IsEqualGUID(riid
, &IID_ID3D11DeviceChild
)
435 || IsEqualGUID(riid
, &IID_IUnknown
))
437 ID3D11DepthStencilState_AddRef(iface
);
442 if (IsEqualGUID(riid
, &IID_ID3D10DepthStencilState
)
443 || IsEqualGUID(riid
, &IID_ID3D10DeviceChild
))
445 ID3D10DepthStencilState_AddRef(&state
->ID3D10DepthStencilState_iface
);
446 *object
= &state
->ID3D10DepthStencilState_iface
;
450 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
453 return E_NOINTERFACE
;
456 static ULONG STDMETHODCALLTYPE
d3d11_depthstencil_state_AddRef(ID3D11DepthStencilState
*iface
)
458 struct d3d_depthstencil_state
*state
= impl_from_ID3D11DepthStencilState(iface
);
459 ULONG refcount
= InterlockedIncrement(&state
->refcount
);
461 TRACE("%p increasing refcount to %u.\n", state
, refcount
);
466 static void d3d_depthstencil_state_cleanup(struct d3d_depthstencil_state
*state
)
468 wined3d_private_store_cleanup(&state
->private_store
);
469 ID3D11Device_Release(state
->device
);
472 static ULONG STDMETHODCALLTYPE
d3d11_depthstencil_state_Release(ID3D11DepthStencilState
*iface
)
474 struct d3d_depthstencil_state
*state
= impl_from_ID3D11DepthStencilState(iface
);
475 ULONG refcount
= InterlockedDecrement(&state
->refcount
);
477 TRACE("%p decreasing refcount to %u.\n", state
, refcount
);
481 struct d3d_device
*device
= impl_from_ID3D11Device(state
->device
);
482 wined3d_mutex_lock();
483 wine_rb_remove(&device
->depthstencil_states
, &state
->entry
);
484 d3d_depthstencil_state_cleanup(state
);
485 wined3d_mutex_unlock();
492 static void STDMETHODCALLTYPE
d3d11_depthstencil_state_GetDevice(ID3D11DepthStencilState
*iface
,
493 ID3D11Device
**device
)
495 struct d3d_depthstencil_state
*state
= impl_from_ID3D11DepthStencilState(iface
);
497 TRACE("iface %p, device %p.\n", iface
, device
);
499 *device
= state
->device
;
500 ID3D11Device_AddRef(*device
);
503 static HRESULT STDMETHODCALLTYPE
d3d11_depthstencil_state_GetPrivateData(ID3D11DepthStencilState
*iface
,
504 REFGUID guid
, UINT
*data_size
, void *data
)
506 struct d3d_depthstencil_state
*state
= impl_from_ID3D11DepthStencilState(iface
);
508 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
510 return d3d_get_private_data(&state
->private_store
, guid
, data_size
, data
);
513 static HRESULT STDMETHODCALLTYPE
d3d11_depthstencil_state_SetPrivateData(ID3D11DepthStencilState
*iface
,
514 REFGUID guid
, UINT data_size
, const void *data
)
516 struct d3d_depthstencil_state
*state
= impl_from_ID3D11DepthStencilState(iface
);
518 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
520 return d3d_set_private_data(&state
->private_store
, guid
, data_size
, data
);
523 static HRESULT STDMETHODCALLTYPE
d3d11_depthstencil_state_SetPrivateDataInterface(ID3D11DepthStencilState
*iface
,
524 REFGUID guid
, const IUnknown
*data
)
526 struct d3d_depthstencil_state
*state
= impl_from_ID3D11DepthStencilState(iface
);
528 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
530 return d3d_set_private_data_interface(&state
->private_store
, guid
, data
);
533 static void STDMETHODCALLTYPE
d3d11_depthstencil_state_GetDesc(ID3D11DepthStencilState
*iface
,
534 D3D11_DEPTH_STENCIL_DESC
*desc
)
536 struct d3d_depthstencil_state
*state
= impl_from_ID3D11DepthStencilState(iface
);
538 TRACE("iface %p, desc %p.\n", iface
, desc
);
543 static const struct ID3D11DepthStencilStateVtbl d3d11_depthstencil_state_vtbl
=
545 /* IUnknown methods */
546 d3d11_depthstencil_state_QueryInterface
,
547 d3d11_depthstencil_state_AddRef
,
548 d3d11_depthstencil_state_Release
,
549 /* ID3D11DeviceChild methods */
550 d3d11_depthstencil_state_GetDevice
,
551 d3d11_depthstencil_state_GetPrivateData
,
552 d3d11_depthstencil_state_SetPrivateData
,
553 d3d11_depthstencil_state_SetPrivateDataInterface
,
554 /* ID3D11DepthStencilState methods */
555 d3d11_depthstencil_state_GetDesc
,
558 /* ID3D10DepthStencilState methods */
560 static inline struct d3d_depthstencil_state
*impl_from_ID3D10DepthStencilState(ID3D10DepthStencilState
*iface
)
562 return CONTAINING_RECORD(iface
, struct d3d_depthstencil_state
, ID3D10DepthStencilState_iface
);
565 /* IUnknown methods */
567 static HRESULT STDMETHODCALLTYPE
d3d10_depthstencil_state_QueryInterface(ID3D10DepthStencilState
*iface
,
568 REFIID riid
, void **object
)
570 struct d3d_depthstencil_state
*state
= impl_from_ID3D10DepthStencilState(iface
);
572 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
574 return d3d11_depthstencil_state_QueryInterface(&state
->ID3D11DepthStencilState_iface
, riid
, object
);
577 static ULONG STDMETHODCALLTYPE
d3d10_depthstencil_state_AddRef(ID3D10DepthStencilState
*iface
)
579 struct d3d_depthstencil_state
*state
= impl_from_ID3D10DepthStencilState(iface
);
581 TRACE("iface %p.\n", iface
);
583 return d3d11_depthstencil_state_AddRef(&state
->ID3D11DepthStencilState_iface
);
586 static ULONG STDMETHODCALLTYPE
d3d10_depthstencil_state_Release(ID3D10DepthStencilState
*iface
)
588 struct d3d_depthstencil_state
*state
= impl_from_ID3D10DepthStencilState(iface
);
590 TRACE("iface %p.\n", iface
);
592 return d3d11_depthstencil_state_Release(&state
->ID3D11DepthStencilState_iface
);
595 /* ID3D10DeviceChild methods */
597 static void STDMETHODCALLTYPE
d3d10_depthstencil_state_GetDevice(ID3D10DepthStencilState
*iface
, ID3D10Device
**device
)
599 struct d3d_depthstencil_state
*state
= impl_from_ID3D10DepthStencilState(iface
);
601 TRACE("iface %p, device %p.\n", iface
, device
);
603 ID3D11Device_QueryInterface(state
->device
, &IID_ID3D10Device
, (void **)device
);
606 static HRESULT STDMETHODCALLTYPE
d3d10_depthstencil_state_GetPrivateData(ID3D10DepthStencilState
*iface
,
607 REFGUID guid
, UINT
*data_size
, void *data
)
609 struct d3d_depthstencil_state
*state
= impl_from_ID3D10DepthStencilState(iface
);
611 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
612 iface
, debugstr_guid(guid
), data_size
, data
);
614 return d3d_get_private_data(&state
->private_store
, guid
, data_size
, data
);
617 static HRESULT STDMETHODCALLTYPE
d3d10_depthstencil_state_SetPrivateData(ID3D10DepthStencilState
*iface
,
618 REFGUID guid
, UINT data_size
, const void *data
)
620 struct d3d_depthstencil_state
*state
= impl_from_ID3D10DepthStencilState(iface
);
622 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
623 iface
, debugstr_guid(guid
), data_size
, data
);
625 return d3d_set_private_data(&state
->private_store
, guid
, data_size
, data
);
628 static HRESULT STDMETHODCALLTYPE
d3d10_depthstencil_state_SetPrivateDataInterface(ID3D10DepthStencilState
*iface
,
629 REFGUID guid
, const IUnknown
*data
)
631 struct d3d_depthstencil_state
*state
= impl_from_ID3D10DepthStencilState(iface
);
633 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
635 return d3d_set_private_data_interface(&state
->private_store
, guid
, data
);
638 /* ID3D10DepthStencilState methods */
640 static void STDMETHODCALLTYPE
d3d10_depthstencil_state_GetDesc(ID3D10DepthStencilState
*iface
,
641 D3D10_DEPTH_STENCIL_DESC
*desc
)
643 struct d3d_depthstencil_state
*state
= impl_from_ID3D10DepthStencilState(iface
);
645 TRACE("iface %p, desc %p.\n", iface
, desc
);
647 memcpy(desc
, &state
->desc
, sizeof(*desc
));
650 static const struct ID3D10DepthStencilStateVtbl d3d10_depthstencil_state_vtbl
=
652 /* IUnknown methods */
653 d3d10_depthstencil_state_QueryInterface
,
654 d3d10_depthstencil_state_AddRef
,
655 d3d10_depthstencil_state_Release
,
656 /* ID3D10DeviceChild methods */
657 d3d10_depthstencil_state_GetDevice
,
658 d3d10_depthstencil_state_GetPrivateData
,
659 d3d10_depthstencil_state_SetPrivateData
,
660 d3d10_depthstencil_state_SetPrivateDataInterface
,
661 /* ID3D10DepthStencilState methods */
662 d3d10_depthstencil_state_GetDesc
,
665 static HRESULT
d3d_depthstencil_state_init(struct d3d_depthstencil_state
*state
, struct d3d_device
*device
,
666 const D3D11_DEPTH_STENCIL_DESC
*desc
)
668 state
->ID3D11DepthStencilState_iface
.lpVtbl
= &d3d11_depthstencil_state_vtbl
;
669 state
->ID3D10DepthStencilState_iface
.lpVtbl
= &d3d10_depthstencil_state_vtbl
;
671 wined3d_private_store_init(&state
->private_store
);
674 state
->device
= &device
->ID3D11Device_iface
;
675 ID3D11Device_AddRef(state
->device
);
680 HRESULT
d3d_depthstencil_state_create(struct d3d_device
*device
, const D3D11_DEPTH_STENCIL_DESC
*desc
,
681 struct d3d_depthstencil_state
**state
)
683 struct d3d_depthstencil_state
*object
;
684 D3D11_DEPTH_STENCIL_DESC tmp_desc
;
685 struct wine_rb_entry
*entry
;
691 /* D3D11_DEPTH_STENCIL_DESC has a hole, which is a problem because we use
692 * it as a key in the rbtree. */
693 memset(&tmp_desc
, 0, sizeof(tmp_desc
));
694 tmp_desc
.DepthEnable
= desc
->DepthEnable
;
695 if (desc
->DepthEnable
)
697 tmp_desc
.DepthWriteMask
= desc
->DepthWriteMask
;
698 tmp_desc
.DepthFunc
= desc
->DepthFunc
;
702 tmp_desc
.DepthWriteMask
= D3D11_DEPTH_WRITE_MASK_ALL
;
703 tmp_desc
.DepthFunc
= D3D11_COMPARISON_LESS
;
705 tmp_desc
.StencilEnable
= desc
->StencilEnable
;
706 if (desc
->StencilEnable
)
708 tmp_desc
.StencilReadMask
= desc
->StencilReadMask
;
709 tmp_desc
.StencilWriteMask
= desc
->StencilWriteMask
;
710 tmp_desc
.FrontFace
= desc
->FrontFace
;
711 tmp_desc
.BackFace
= desc
->BackFace
;
715 tmp_desc
.StencilReadMask
= D3D11_DEFAULT_STENCIL_READ_MASK
;
716 tmp_desc
.StencilWriteMask
= D3D11_DEFAULT_STENCIL_WRITE_MASK
;
717 tmp_desc
.FrontFace
.StencilFailOp
= D3D11_STENCIL_OP_KEEP
;
718 tmp_desc
.FrontFace
.StencilDepthFailOp
= D3D11_STENCIL_OP_KEEP
;
719 tmp_desc
.FrontFace
.StencilPassOp
= D3D11_STENCIL_OP_KEEP
;
720 tmp_desc
.FrontFace
.StencilFunc
= D3D11_COMPARISON_ALWAYS
;
721 tmp_desc
.BackFace
.StencilFailOp
= D3D11_STENCIL_OP_KEEP
;
722 tmp_desc
.BackFace
.StencilDepthFailOp
= D3D11_STENCIL_OP_KEEP
;
723 tmp_desc
.BackFace
.StencilPassOp
= D3D11_STENCIL_OP_KEEP
;
724 tmp_desc
.BackFace
.StencilFunc
= D3D11_COMPARISON_ALWAYS
;
727 wined3d_mutex_lock();
728 if ((entry
= wine_rb_get(&device
->depthstencil_states
, &tmp_desc
)))
730 object
= WINE_RB_ENTRY_VALUE(entry
, struct d3d_depthstencil_state
, entry
);
732 TRACE("Returning existing depthstencil state %p.\n", object
);
733 ID3D11DepthStencilState_AddRef(&object
->ID3D11DepthStencilState_iface
);
735 wined3d_mutex_unlock();
740 if (!(object
= heap_alloc_zero(sizeof(*object
))))
742 wined3d_mutex_unlock();
743 return E_OUTOFMEMORY
;
746 if (FAILED(hr
= d3d_depthstencil_state_init(object
, device
, &tmp_desc
)))
748 WARN("Failed to initialize depthstencil state, hr %#x.\n", hr
);
750 wined3d_mutex_unlock();
754 if (wine_rb_put(&device
->depthstencil_states
, desc
, &object
->entry
) == -1)
756 ERR("Failed to insert depthstencil state entry.\n");
757 d3d_depthstencil_state_cleanup(object
);
759 wined3d_mutex_unlock();
762 wined3d_mutex_unlock();
764 TRACE("Created depthstencil state %p.\n", object
);
770 struct d3d_depthstencil_state
*unsafe_impl_from_ID3D11DepthStencilState(ID3D11DepthStencilState
*iface
)
774 assert(iface
->lpVtbl
== &d3d11_depthstencil_state_vtbl
);
776 return impl_from_ID3D11DepthStencilState(iface
);
779 struct d3d_depthstencil_state
*unsafe_impl_from_ID3D10DepthStencilState(ID3D10DepthStencilState
*iface
)
783 assert(iface
->lpVtbl
== &d3d10_depthstencil_state_vtbl
);
785 return impl_from_ID3D10DepthStencilState(iface
);
788 /* ID3D11RasterizerState methods */
790 static inline struct d3d_rasterizer_state
*impl_from_ID3D11RasterizerState(ID3D11RasterizerState
*iface
)
792 return CONTAINING_RECORD(iface
, struct d3d_rasterizer_state
, ID3D11RasterizerState_iface
);
795 static HRESULT STDMETHODCALLTYPE
d3d11_rasterizer_state_QueryInterface(ID3D11RasterizerState
*iface
,
796 REFIID riid
, void **object
)
798 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState(iface
);
800 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
802 if (IsEqualGUID(riid
, &IID_ID3D11RasterizerState
)
803 || IsEqualGUID(riid
, &IID_ID3D11DeviceChild
)
804 || IsEqualGUID(riid
, &IID_IUnknown
))
806 ID3D11RasterizerState_AddRef(iface
);
811 if (IsEqualGUID(riid
, &IID_ID3D10RasterizerState
)
812 || IsEqualGUID(riid
, &IID_ID3D10DeviceChild
))
814 ID3D10RasterizerState_AddRef(&state
->ID3D10RasterizerState_iface
);
815 *object
= &state
->ID3D10RasterizerState_iface
;
819 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
822 return E_NOINTERFACE
;
825 static ULONG STDMETHODCALLTYPE
d3d11_rasterizer_state_AddRef(ID3D11RasterizerState
*iface
)
827 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState(iface
);
828 ULONG refcount
= InterlockedIncrement(&state
->refcount
);
830 TRACE("%p increasing refcount to %u.\n", state
, refcount
);
834 ID3D11Device_AddRef(state
->device
);
835 wined3d_mutex_lock();
836 wined3d_rasterizer_state_incref(state
->wined3d_state
);
837 wined3d_mutex_unlock();
843 static ULONG STDMETHODCALLTYPE
d3d11_rasterizer_state_Release(ID3D11RasterizerState
*iface
)
845 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState(iface
);
846 ULONG refcount
= InterlockedDecrement(&state
->refcount
);
848 TRACE("%p decreasing refcount to %u.\n", state
, refcount
);
852 ID3D11Device
*device
= state
->device
;
854 wined3d_mutex_lock();
855 wined3d_rasterizer_state_decref(state
->wined3d_state
);
856 wined3d_mutex_unlock();
858 ID3D11Device_Release(device
);
864 static void STDMETHODCALLTYPE
d3d11_rasterizer_state_GetDevice(ID3D11RasterizerState
*iface
,
865 ID3D11Device
**device
)
867 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState(iface
);
869 TRACE("iface %p, device %p.\n", iface
, device
);
871 *device
= state
->device
;
872 ID3D11Device_AddRef(*device
);
875 static HRESULT STDMETHODCALLTYPE
d3d11_rasterizer_state_GetPrivateData(ID3D11RasterizerState
*iface
,
876 REFGUID guid
, UINT
*data_size
, void *data
)
878 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState(iface
);
880 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
882 return d3d_get_private_data(&state
->private_store
, guid
, data_size
, data
);
885 static HRESULT STDMETHODCALLTYPE
d3d11_rasterizer_state_SetPrivateData(ID3D11RasterizerState
*iface
,
886 REFGUID guid
, UINT data_size
, const void *data
)
888 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState(iface
);
890 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
892 return d3d_set_private_data(&state
->private_store
, guid
, data_size
, data
);
895 static HRESULT STDMETHODCALLTYPE
d3d11_rasterizer_state_SetPrivateDataInterface(ID3D11RasterizerState
*iface
,
896 REFGUID guid
, const IUnknown
*data
)
898 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState(iface
);
900 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
902 return d3d_set_private_data_interface(&state
->private_store
, guid
, data
);
905 static void STDMETHODCALLTYPE
d3d11_rasterizer_state_GetDesc(ID3D11RasterizerState
*iface
,
906 D3D11_RASTERIZER_DESC
*desc
)
908 struct d3d_rasterizer_state
*state
= impl_from_ID3D11RasterizerState(iface
);
910 TRACE("iface %p, desc %p.\n", iface
, desc
);
915 static const struct ID3D11RasterizerStateVtbl d3d11_rasterizer_state_vtbl
=
917 /* IUnknown methods */
918 d3d11_rasterizer_state_QueryInterface
,
919 d3d11_rasterizer_state_AddRef
,
920 d3d11_rasterizer_state_Release
,
921 /* ID3D11DeviceChild methods */
922 d3d11_rasterizer_state_GetDevice
,
923 d3d11_rasterizer_state_GetPrivateData
,
924 d3d11_rasterizer_state_SetPrivateData
,
925 d3d11_rasterizer_state_SetPrivateDataInterface
,
926 /* ID3D11RasterizerState methods */
927 d3d11_rasterizer_state_GetDesc
,
930 /* ID3D10RasterizerState methods */
932 static inline struct d3d_rasterizer_state
*impl_from_ID3D10RasterizerState(ID3D10RasterizerState
*iface
)
934 return CONTAINING_RECORD(iface
, struct d3d_rasterizer_state
, ID3D10RasterizerState_iface
);
937 /* IUnknown methods */
939 static HRESULT STDMETHODCALLTYPE
d3d10_rasterizer_state_QueryInterface(ID3D10RasterizerState
*iface
,
940 REFIID riid
, void **object
)
942 struct d3d_rasterizer_state
*state
= impl_from_ID3D10RasterizerState(iface
);
944 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
946 return d3d11_rasterizer_state_QueryInterface(&state
->ID3D11RasterizerState_iface
, riid
, object
);
949 static ULONG STDMETHODCALLTYPE
d3d10_rasterizer_state_AddRef(ID3D10RasterizerState
*iface
)
951 struct d3d_rasterizer_state
*state
= impl_from_ID3D10RasterizerState(iface
);
953 TRACE("iface %p.\n", iface
);
955 return d3d11_rasterizer_state_AddRef(&state
->ID3D11RasterizerState_iface
);
958 static ULONG STDMETHODCALLTYPE
d3d10_rasterizer_state_Release(ID3D10RasterizerState
*iface
)
960 struct d3d_rasterizer_state
*state
= impl_from_ID3D10RasterizerState(iface
);
962 TRACE("iface %p.\n", state
);
964 return d3d11_rasterizer_state_Release(&state
->ID3D11RasterizerState_iface
);
967 /* ID3D10DeviceChild methods */
969 static void STDMETHODCALLTYPE
d3d10_rasterizer_state_GetDevice(ID3D10RasterizerState
*iface
, ID3D10Device
**device
)
971 struct d3d_rasterizer_state
*state
= impl_from_ID3D10RasterizerState(iface
);
973 TRACE("iface %p, device %p.\n", iface
, device
);
975 ID3D11Device_QueryInterface(state
->device
, &IID_ID3D10Device
, (void **)device
);
978 static HRESULT STDMETHODCALLTYPE
d3d10_rasterizer_state_GetPrivateData(ID3D10RasterizerState
*iface
,
979 REFGUID guid
, UINT
*data_size
, void *data
)
981 struct d3d_rasterizer_state
*state
= impl_from_ID3D10RasterizerState(iface
);
983 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
984 iface
, debugstr_guid(guid
), data_size
, data
);
986 return d3d_get_private_data(&state
->private_store
, guid
, data_size
, data
);
989 static HRESULT STDMETHODCALLTYPE
d3d10_rasterizer_state_SetPrivateData(ID3D10RasterizerState
*iface
,
990 REFGUID guid
, UINT data_size
, const void *data
)
992 struct d3d_rasterizer_state
*state
= impl_from_ID3D10RasterizerState(iface
);
994 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
995 iface
, debugstr_guid(guid
), data_size
, data
);
997 return d3d_set_private_data(&state
->private_store
, guid
, data_size
, data
);
1000 static HRESULT STDMETHODCALLTYPE
d3d10_rasterizer_state_SetPrivateDataInterface(ID3D10RasterizerState
*iface
,
1001 REFGUID guid
, const IUnknown
*data
)
1003 struct d3d_rasterizer_state
*state
= impl_from_ID3D10RasterizerState(iface
);
1005 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
1007 return d3d_set_private_data_interface(&state
->private_store
, guid
, data
);
1010 /* ID3D10RasterizerState methods */
1012 static void STDMETHODCALLTYPE
d3d10_rasterizer_state_GetDesc(ID3D10RasterizerState
*iface
,
1013 D3D10_RASTERIZER_DESC
*desc
)
1015 struct d3d_rasterizer_state
*state
= impl_from_ID3D10RasterizerState(iface
);
1017 TRACE("iface %p, desc %p.\n", iface
, desc
);
1019 memcpy(desc
, &state
->desc
, sizeof(*desc
));
1022 static const struct ID3D10RasterizerStateVtbl d3d10_rasterizer_state_vtbl
=
1024 /* IUnknown methods */
1025 d3d10_rasterizer_state_QueryInterface
,
1026 d3d10_rasterizer_state_AddRef
,
1027 d3d10_rasterizer_state_Release
,
1028 /* ID3D10DeviceChild methods */
1029 d3d10_rasterizer_state_GetDevice
,
1030 d3d10_rasterizer_state_GetPrivateData
,
1031 d3d10_rasterizer_state_SetPrivateData
,
1032 d3d10_rasterizer_state_SetPrivateDataInterface
,
1033 /* ID3D10RasterizerState methods */
1034 d3d10_rasterizer_state_GetDesc
,
1037 static void STDMETHODCALLTYPE
d3d_rasterizer_state_wined3d_object_destroyed(void *parent
)
1039 struct d3d_rasterizer_state
*state
= parent
;
1040 struct d3d_device
*device
= impl_from_ID3D11Device(state
->device
);
1042 wine_rb_remove(&device
->rasterizer_states
, &state
->entry
);
1043 wined3d_private_store_cleanup(&state
->private_store
);
1047 static const struct wined3d_parent_ops d3d_rasterizer_state_wined3d_parent_ops
=
1049 d3d_rasterizer_state_wined3d_object_destroyed
,
1052 static HRESULT
d3d_rasterizer_state_init(struct d3d_rasterizer_state
*state
, struct d3d_device
*device
,
1053 const D3D11_RASTERIZER_DESC
*desc
)
1055 struct wined3d_rasterizer_state_desc wined3d_desc
;
1058 state
->ID3D11RasterizerState_iface
.lpVtbl
= &d3d11_rasterizer_state_vtbl
;
1059 state
->ID3D10RasterizerState_iface
.lpVtbl
= &d3d10_rasterizer_state_vtbl
;
1060 state
->refcount
= 1;
1061 wined3d_private_store_init(&state
->private_store
);
1062 state
->desc
= *desc
;
1064 if (wine_rb_put(&device
->rasterizer_states
, desc
, &state
->entry
) == -1)
1066 ERR("Failed to insert rasterizer state entry.\n");
1067 wined3d_private_store_cleanup(&state
->private_store
);
1071 wined3d_desc
.front_ccw
= desc
->FrontCounterClockwise
;
1073 /* We cannot fail after creating a wined3d_rasterizer_state object. It
1074 * would lead to double free. */
1075 if (FAILED(hr
= wined3d_rasterizer_state_create(device
->wined3d_device
, &wined3d_desc
,
1076 state
, &d3d_rasterizer_state_wined3d_parent_ops
, &state
->wined3d_state
)))
1078 WARN("Failed to create wined3d rasterizer state, hr %#x.\n", hr
);
1079 wined3d_private_store_cleanup(&state
->private_store
);
1080 wine_rb_remove(&device
->rasterizer_states
, &state
->entry
);
1084 ID3D11Device_AddRef(state
->device
= &device
->ID3D11Device_iface
);
1089 HRESULT
d3d_rasterizer_state_create(struct d3d_device
*device
, const D3D11_RASTERIZER_DESC
*desc
,
1090 struct d3d_rasterizer_state
**state
)
1092 struct d3d_rasterizer_state
*object
;
1093 struct wine_rb_entry
*entry
;
1097 return E_INVALIDARG
;
1099 wined3d_mutex_lock();
1100 if ((entry
= wine_rb_get(&device
->rasterizer_states
, desc
)))
1102 object
= WINE_RB_ENTRY_VALUE(entry
, struct d3d_rasterizer_state
, entry
);
1104 TRACE("Returning existing rasterizer state %p.\n", object
);
1105 ID3D11RasterizerState_AddRef(&object
->ID3D11RasterizerState_iface
);
1107 wined3d_mutex_unlock();
1112 if (!(object
= heap_alloc_zero(sizeof(*object
))))
1114 wined3d_mutex_unlock();
1115 return E_OUTOFMEMORY
;
1118 hr
= d3d_rasterizer_state_init(object
, device
, desc
);
1119 wined3d_mutex_unlock();
1122 WARN("Failed to initialize rasterizer state, hr %#x.\n", hr
);
1127 TRACE("Created rasterizer state %p.\n", object
);
1133 struct d3d_rasterizer_state
*unsafe_impl_from_ID3D11RasterizerState(ID3D11RasterizerState
*iface
)
1137 assert(iface
->lpVtbl
== &d3d11_rasterizer_state_vtbl
);
1139 return impl_from_ID3D11RasterizerState(iface
);
1142 struct d3d_rasterizer_state
*unsafe_impl_from_ID3D10RasterizerState(ID3D10RasterizerState
*iface
)
1146 assert(iface
->lpVtbl
== &d3d10_rasterizer_state_vtbl
);
1148 return impl_from_ID3D10RasterizerState(iface
);
1151 /* ID3D11SampleState methods */
1153 static inline struct d3d_sampler_state
*impl_from_ID3D11SamplerState(ID3D11SamplerState
*iface
)
1155 return CONTAINING_RECORD(iface
, struct d3d_sampler_state
, ID3D11SamplerState_iface
);
1158 static HRESULT STDMETHODCALLTYPE
d3d11_sampler_state_QueryInterface(ID3D11SamplerState
*iface
,
1159 REFIID riid
, void **object
)
1161 struct d3d_sampler_state
*state
= impl_from_ID3D11SamplerState(iface
);
1163 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
1165 if (IsEqualGUID(riid
, &IID_ID3D11SamplerState
)
1166 || IsEqualGUID(riid
, &IID_ID3D11DeviceChild
)
1167 || IsEqualGUID(riid
, &IID_IUnknown
))
1169 ID3D11SamplerState_AddRef(iface
);
1174 if (IsEqualGUID(riid
, &IID_ID3D10SamplerState
)
1175 || IsEqualGUID(riid
, &IID_ID3D10DeviceChild
))
1177 ID3D10SamplerState_AddRef(&state
->ID3D10SamplerState_iface
);
1178 *object
= &state
->ID3D10SamplerState_iface
;
1182 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
1185 return E_NOINTERFACE
;
1188 static ULONG STDMETHODCALLTYPE
d3d11_sampler_state_AddRef(ID3D11SamplerState
*iface
)
1190 struct d3d_sampler_state
*state
= impl_from_ID3D11SamplerState(iface
);
1191 ULONG refcount
= InterlockedIncrement(&state
->refcount
);
1193 TRACE("%p increasing refcount to %u.\n", state
, refcount
);
1197 ID3D11Device_AddRef(state
->device
);
1198 wined3d_mutex_lock();
1199 wined3d_sampler_incref(state
->wined3d_sampler
);
1200 wined3d_mutex_unlock();
1206 static ULONG STDMETHODCALLTYPE
d3d11_sampler_state_Release(ID3D11SamplerState
*iface
)
1208 struct d3d_sampler_state
*state
= impl_from_ID3D11SamplerState(iface
);
1209 ULONG refcount
= InterlockedDecrement(&state
->refcount
);
1211 TRACE("%p decreasing refcount to %u.\n", state
, refcount
);
1215 ID3D11Device
*device
= state
->device
;
1217 wined3d_mutex_lock();
1218 wined3d_sampler_decref(state
->wined3d_sampler
);
1219 wined3d_mutex_unlock();
1221 ID3D11Device_Release(device
);
1227 static void STDMETHODCALLTYPE
d3d11_sampler_state_GetDevice(ID3D11SamplerState
*iface
,
1228 ID3D11Device
**device
)
1230 struct d3d_sampler_state
*state
= impl_from_ID3D11SamplerState(iface
);
1232 TRACE("iface %p, device %p.\n", iface
, device
);
1234 *device
= state
->device
;
1235 ID3D11Device_AddRef(*device
);
1238 static HRESULT STDMETHODCALLTYPE
d3d11_sampler_state_GetPrivateData(ID3D11SamplerState
*iface
,
1239 REFGUID guid
, UINT
*data_size
, void *data
)
1241 struct d3d_sampler_state
*state
= impl_from_ID3D11SamplerState(iface
);
1243 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
1245 return d3d_get_private_data(&state
->private_store
, guid
, data_size
, data
);
1248 static HRESULT STDMETHODCALLTYPE
d3d11_sampler_state_SetPrivateData(ID3D11SamplerState
*iface
,
1249 REFGUID guid
, UINT data_size
, const void *data
)
1251 struct d3d_sampler_state
*state
= impl_from_ID3D11SamplerState(iface
);
1253 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
1255 return d3d_set_private_data(&state
->private_store
, guid
, data_size
, data
);
1258 static HRESULT STDMETHODCALLTYPE
d3d11_sampler_state_SetPrivateDataInterface(ID3D11SamplerState
*iface
,
1259 REFGUID guid
, const IUnknown
*data
)
1261 struct d3d_sampler_state
*state
= impl_from_ID3D11SamplerState(iface
);
1263 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
1265 return d3d_set_private_data_interface(&state
->private_store
, guid
, data
);
1268 static void STDMETHODCALLTYPE
d3d11_sampler_state_GetDesc(ID3D11SamplerState
*iface
,
1269 D3D11_SAMPLER_DESC
*desc
)
1271 struct d3d_sampler_state
*state
= impl_from_ID3D11SamplerState(iface
);
1273 TRACE("iface %p, desc %p.\n", iface
, desc
);
1275 *desc
= state
->desc
;
1278 static const struct ID3D11SamplerStateVtbl d3d11_sampler_state_vtbl
=
1280 /* IUnknown methods */
1281 d3d11_sampler_state_QueryInterface
,
1282 d3d11_sampler_state_AddRef
,
1283 d3d11_sampler_state_Release
,
1284 /* ID3D11DeviceChild methods */
1285 d3d11_sampler_state_GetDevice
,
1286 d3d11_sampler_state_GetPrivateData
,
1287 d3d11_sampler_state_SetPrivateData
,
1288 d3d11_sampler_state_SetPrivateDataInterface
,
1289 /* ID3D11SamplerState methods */
1290 d3d11_sampler_state_GetDesc
,
1293 /* ID3D10SamplerState methods */
1295 static inline struct d3d_sampler_state
*impl_from_ID3D10SamplerState(ID3D10SamplerState
*iface
)
1297 return CONTAINING_RECORD(iface
, struct d3d_sampler_state
, ID3D10SamplerState_iface
);
1300 /* IUnknown methods */
1302 static HRESULT STDMETHODCALLTYPE
d3d10_sampler_state_QueryInterface(ID3D10SamplerState
*iface
,
1303 REFIID riid
, void **object
)
1305 struct d3d_sampler_state
*state
= impl_from_ID3D10SamplerState(iface
);
1307 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
1309 return d3d11_sampler_state_QueryInterface(&state
->ID3D11SamplerState_iface
, riid
, object
);
1312 static ULONG STDMETHODCALLTYPE
d3d10_sampler_state_AddRef(ID3D10SamplerState
*iface
)
1314 struct d3d_sampler_state
*state
= impl_from_ID3D10SamplerState(iface
);
1316 TRACE("iface %p.\n", iface
);
1318 return d3d11_sampler_state_AddRef(&state
->ID3D11SamplerState_iface
);
1321 static ULONG STDMETHODCALLTYPE
d3d10_sampler_state_Release(ID3D10SamplerState
*iface
)
1323 struct d3d_sampler_state
*state
= impl_from_ID3D10SamplerState(iface
);
1325 TRACE("iface %p.\n", iface
);
1327 return d3d11_sampler_state_Release(&state
->ID3D11SamplerState_iface
);
1330 /* ID3D10DeviceChild methods */
1332 static void STDMETHODCALLTYPE
d3d10_sampler_state_GetDevice(ID3D10SamplerState
*iface
, ID3D10Device
**device
)
1334 struct d3d_sampler_state
*state
= impl_from_ID3D10SamplerState(iface
);
1336 TRACE("iface %p, device %p.\n", iface
, device
);
1338 ID3D11Device_QueryInterface(state
->device
, &IID_ID3D10Device
, (void **)device
);
1341 static HRESULT STDMETHODCALLTYPE
d3d10_sampler_state_GetPrivateData(ID3D10SamplerState
*iface
,
1342 REFGUID guid
, UINT
*data_size
, void *data
)
1344 struct d3d_sampler_state
*state
= impl_from_ID3D10SamplerState(iface
);
1346 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
1347 iface
, debugstr_guid(guid
), data_size
, data
);
1349 return d3d_get_private_data(&state
->private_store
, guid
, data_size
, data
);
1352 static HRESULT STDMETHODCALLTYPE
d3d10_sampler_state_SetPrivateData(ID3D10SamplerState
*iface
,
1353 REFGUID guid
, UINT data_size
, const void *data
)
1355 struct d3d_sampler_state
*state
= impl_from_ID3D10SamplerState(iface
);
1357 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
1358 iface
, debugstr_guid(guid
), data_size
, data
);
1360 return d3d_set_private_data(&state
->private_store
, guid
, data_size
, data
);
1363 static HRESULT STDMETHODCALLTYPE
d3d10_sampler_state_SetPrivateDataInterface(ID3D10SamplerState
*iface
,
1364 REFGUID guid
, const IUnknown
*data
)
1366 struct d3d_sampler_state
*state
= impl_from_ID3D10SamplerState(iface
);
1368 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
1370 return d3d_set_private_data_interface(&state
->private_store
, guid
, data
);
1373 /* ID3D10SamplerState methods */
1375 static void STDMETHODCALLTYPE
d3d10_sampler_state_GetDesc(ID3D10SamplerState
*iface
,
1376 D3D10_SAMPLER_DESC
*desc
)
1378 struct d3d_sampler_state
*state
= impl_from_ID3D10SamplerState(iface
);
1380 TRACE("iface %p, desc %p.\n", iface
, desc
);
1382 memcpy(desc
, &state
->desc
, sizeof(*desc
));
1385 static const struct ID3D10SamplerStateVtbl d3d10_sampler_state_vtbl
=
1387 /* IUnknown methods */
1388 d3d10_sampler_state_QueryInterface
,
1389 d3d10_sampler_state_AddRef
,
1390 d3d10_sampler_state_Release
,
1391 /* ID3D10DeviceChild methods */
1392 d3d10_sampler_state_GetDevice
,
1393 d3d10_sampler_state_GetPrivateData
,
1394 d3d10_sampler_state_SetPrivateData
,
1395 d3d10_sampler_state_SetPrivateDataInterface
,
1396 /* ID3D10SamplerState methods */
1397 d3d10_sampler_state_GetDesc
,
1400 static void STDMETHODCALLTYPE
d3d_sampler_wined3d_object_destroyed(void *parent
)
1402 struct d3d_sampler_state
*state
= parent
;
1403 struct d3d_device
*device
= impl_from_ID3D11Device(state
->device
);
1405 wine_rb_remove(&device
->sampler_states
, &state
->entry
);
1406 wined3d_private_store_cleanup(&state
->private_store
);
1410 static const struct wined3d_parent_ops d3d_sampler_wined3d_parent_ops
=
1412 d3d_sampler_wined3d_object_destroyed
,
1415 static enum wined3d_texture_address
wined3d_texture_address_from_d3d11(enum D3D11_TEXTURE_ADDRESS_MODE t
)
1417 return (enum wined3d_texture_address
)t
;
1420 static enum wined3d_texture_filter_type
wined3d_texture_filter_mip_from_d3d11(enum D3D11_FILTER f
)
1422 if (D3D11_DECODE_MIP_FILTER(f
) == D3D11_FILTER_TYPE_LINEAR
)
1423 return WINED3D_TEXF_LINEAR
;
1424 return WINED3D_TEXF_POINT
;
1427 static enum wined3d_texture_filter_type
wined3d_texture_filter_mag_from_d3d11(enum D3D11_FILTER f
)
1429 if (D3D11_DECODE_MAG_FILTER(f
) == D3D11_FILTER_TYPE_LINEAR
)
1430 return WINED3D_TEXF_LINEAR
;
1431 return WINED3D_TEXF_POINT
;
1434 static enum wined3d_texture_filter_type
wined3d_texture_filter_min_from_d3d11(enum D3D11_FILTER f
)
1436 if (D3D11_DECODE_MIN_FILTER(f
) == D3D11_FILTER_TYPE_LINEAR
)
1437 return WINED3D_TEXF_LINEAR
;
1438 return WINED3D_TEXF_POINT
;
1441 static BOOL
wined3d_texture_compare_from_d3d11(enum D3D11_FILTER f
)
1443 return D3D11_DECODE_IS_COMPARISON_FILTER(f
);
1446 static enum wined3d_cmp_func
wined3d_cmp_func_from_d3d11(D3D11_COMPARISON_FUNC f
)
1448 return (enum wined3d_cmp_func
)f
;
1451 static HRESULT
d3d_sampler_state_init(struct d3d_sampler_state
*state
, struct d3d_device
*device
,
1452 const D3D11_SAMPLER_DESC
*desc
)
1454 struct wined3d_sampler_desc wined3d_desc
;
1457 state
->ID3D11SamplerState_iface
.lpVtbl
= &d3d11_sampler_state_vtbl
;
1458 state
->ID3D10SamplerState_iface
.lpVtbl
= &d3d10_sampler_state_vtbl
;
1459 state
->refcount
= 1;
1460 wined3d_private_store_init(&state
->private_store
);
1461 state
->desc
= *desc
;
1463 wined3d_desc
.address_u
= wined3d_texture_address_from_d3d11(desc
->AddressU
);
1464 wined3d_desc
.address_v
= wined3d_texture_address_from_d3d11(desc
->AddressV
);
1465 wined3d_desc
.address_w
= wined3d_texture_address_from_d3d11(desc
->AddressW
);
1466 memcpy(wined3d_desc
.border_color
, desc
->BorderColor
, sizeof(wined3d_desc
.border_color
));
1467 wined3d_desc
.mag_filter
= wined3d_texture_filter_mag_from_d3d11(desc
->Filter
);
1468 wined3d_desc
.min_filter
= wined3d_texture_filter_min_from_d3d11(desc
->Filter
);
1469 wined3d_desc
.mip_filter
= wined3d_texture_filter_mip_from_d3d11(desc
->Filter
);
1470 wined3d_desc
.lod_bias
= desc
->MipLODBias
;
1471 wined3d_desc
.min_lod
= desc
->MinLOD
;
1472 wined3d_desc
.max_lod
= desc
->MaxLOD
;
1473 wined3d_desc
.mip_base_level
= 0;
1474 wined3d_desc
.max_anisotropy
= D3D11_DECODE_IS_ANISOTROPIC_FILTER(desc
->Filter
) ? desc
->MaxAnisotropy
: 1;
1475 wined3d_desc
.compare
= wined3d_texture_compare_from_d3d11(desc
->Filter
);
1476 wined3d_desc
.comparison_func
= wined3d_cmp_func_from_d3d11(desc
->ComparisonFunc
);
1477 wined3d_desc
.srgb_decode
= TRUE
;
1479 if (wine_rb_put(&device
->sampler_states
, desc
, &state
->entry
) == -1)
1481 ERR("Failed to insert sampler state entry.\n");
1482 wined3d_private_store_cleanup(&state
->private_store
);
1486 /* We cannot fail after creating a wined3d_sampler object. It would lead to
1488 if (FAILED(hr
= wined3d_sampler_create(device
->wined3d_device
, &wined3d_desc
,
1489 state
, &d3d_sampler_wined3d_parent_ops
, &state
->wined3d_sampler
)))
1491 WARN("Failed to create wined3d sampler, hr %#x.\n", hr
);
1492 wined3d_private_store_cleanup(&state
->private_store
);
1493 wine_rb_remove(&device
->sampler_states
, &state
->entry
);
1497 state
->device
= &device
->ID3D11Device_iface
;
1498 ID3D11Device_AddRef(state
->device
);
1503 HRESULT
d3d_sampler_state_create(struct d3d_device
*device
, const D3D11_SAMPLER_DESC
*desc
,
1504 struct d3d_sampler_state
**state
)
1506 D3D11_SAMPLER_DESC normalized_desc
;
1507 struct d3d_sampler_state
*object
;
1508 struct wine_rb_entry
*entry
;
1512 return E_INVALIDARG
;
1514 normalized_desc
= *desc
;
1515 if (!D3D11_DECODE_IS_ANISOTROPIC_FILTER(normalized_desc
.Filter
))
1516 normalized_desc
.MaxAnisotropy
= 0;
1517 if (!D3D11_DECODE_IS_COMPARISON_FILTER(normalized_desc
.Filter
))
1518 normalized_desc
.ComparisonFunc
= D3D11_COMPARISON_NEVER
;
1519 if (normalized_desc
.AddressU
!= D3D11_TEXTURE_ADDRESS_BORDER
1520 && normalized_desc
.AddressV
!= D3D11_TEXTURE_ADDRESS_BORDER
1521 && normalized_desc
.AddressW
!= D3D11_TEXTURE_ADDRESS_BORDER
)
1522 memset(&normalized_desc
.BorderColor
, 0, sizeof(normalized_desc
.BorderColor
));
1524 wined3d_mutex_lock();
1525 if ((entry
= wine_rb_get(&device
->sampler_states
, &normalized_desc
)))
1527 object
= WINE_RB_ENTRY_VALUE(entry
, struct d3d_sampler_state
, entry
);
1529 TRACE("Returning existing sampler state %p.\n", object
);
1530 ID3D11SamplerState_AddRef(&object
->ID3D11SamplerState_iface
);
1532 wined3d_mutex_unlock();
1537 if (!(object
= heap_alloc_zero(sizeof(*object
))))
1539 wined3d_mutex_unlock();
1540 return E_OUTOFMEMORY
;
1543 hr
= d3d_sampler_state_init(object
, device
, &normalized_desc
);
1544 wined3d_mutex_unlock();
1547 WARN("Failed to initialize sampler state, hr %#x.\n", hr
);
1552 TRACE("Created sampler state %p.\n", object
);
1558 struct d3d_sampler_state
*unsafe_impl_from_ID3D11SamplerState(ID3D11SamplerState
*iface
)
1562 assert(iface
->lpVtbl
== &d3d11_sampler_state_vtbl
);
1564 return impl_from_ID3D11SamplerState(iface
);
1567 struct d3d_sampler_state
*unsafe_impl_from_ID3D10SamplerState(ID3D10SamplerState
*iface
)
1571 assert(iface
->lpVtbl
== &d3d10_sampler_state_vtbl
);
1573 return impl_from_ID3D10SamplerState(iface
);