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