mf: Subscribe standard quality manager to clock state change events.
[wine/zf.git] / dlls / d3d11 / shader.c
blobd51d8e4e60b36f99f0bfd7023ba961a998faf0db
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"
21 #include "winternl.h"
23 WINE_DEFAULT_DEBUG_CHANNEL(d3d11);
25 /* ID3D11VertexShader methods */
27 static inline struct d3d_vertex_shader *impl_from_ID3D11VertexShader(ID3D11VertexShader *iface)
29 return CONTAINING_RECORD(iface, struct d3d_vertex_shader, ID3D11VertexShader_iface);
32 static HRESULT STDMETHODCALLTYPE d3d11_vertex_shader_QueryInterface(ID3D11VertexShader *iface,
33 REFIID riid, void **object)
35 struct d3d_vertex_shader *shader = impl_from_ID3D11VertexShader(iface);
37 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
39 if (IsEqualGUID(riid, &IID_ID3D11VertexShader)
40 || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
41 || IsEqualGUID(riid, &IID_IUnknown))
43 ID3D11VertexShader_AddRef(iface);
44 *object = iface;
45 return S_OK;
48 if (IsEqualGUID(riid, &IID_ID3D10VertexShader)
49 || IsEqualGUID(riid, &IID_ID3D10DeviceChild))
51 IUnknown_AddRef(&shader->ID3D10VertexShader_iface);
52 *object = &shader->ID3D10VertexShader_iface;
53 return S_OK;
56 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
58 *object = NULL;
59 return E_NOINTERFACE;
62 static ULONG STDMETHODCALLTYPE d3d11_vertex_shader_AddRef(ID3D11VertexShader *iface)
64 struct d3d_vertex_shader *shader = impl_from_ID3D11VertexShader(iface);
65 ULONG refcount = InterlockedIncrement(&shader->refcount);
67 TRACE("%p increasing refcount to %u.\n", shader, refcount);
69 if (refcount == 1)
71 ID3D11Device2_AddRef(shader->device);
72 wined3d_mutex_lock();
73 wined3d_shader_incref(shader->wined3d_shader);
74 wined3d_mutex_unlock();
77 return refcount;
80 static ULONG STDMETHODCALLTYPE d3d11_vertex_shader_Release(ID3D11VertexShader *iface)
82 struct d3d_vertex_shader *shader = impl_from_ID3D11VertexShader(iface);
83 ULONG refcount = InterlockedDecrement(&shader->refcount);
85 TRACE("%p decreasing refcount to %u.\n", shader, refcount);
87 if (!refcount)
89 ID3D11Device2 *device = shader->device;
91 wined3d_mutex_lock();
92 wined3d_shader_decref(shader->wined3d_shader);
93 wined3d_mutex_unlock();
94 /* Release the device last, it may cause the wined3d device to be
95 * destroyed. */
96 ID3D11Device2_Release(device);
99 return refcount;
102 static void STDMETHODCALLTYPE d3d11_vertex_shader_GetDevice(ID3D11VertexShader *iface,
103 ID3D11Device **device)
105 struct d3d_vertex_shader *shader = impl_from_ID3D11VertexShader(iface);
107 TRACE("iface %p, device %p.\n", iface, device);
109 *device = (ID3D11Device *)shader->device;
110 ID3D11Device_AddRef(*device);
113 static HRESULT STDMETHODCALLTYPE d3d11_vertex_shader_GetPrivateData(ID3D11VertexShader *iface,
114 REFGUID guid, UINT *data_size, void *data)
116 struct d3d_vertex_shader *shader = impl_from_ID3D11VertexShader(iface);
118 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
120 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
123 static HRESULT STDMETHODCALLTYPE d3d11_vertex_shader_SetPrivateData(ID3D11VertexShader *iface,
124 REFGUID guid, UINT data_size, const void *data)
126 struct d3d_vertex_shader *shader = impl_from_ID3D11VertexShader(iface);
128 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
130 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
133 static HRESULT STDMETHODCALLTYPE d3d11_vertex_shader_SetPrivateDataInterface(ID3D11VertexShader *iface,
134 REFGUID guid, const IUnknown *data)
136 struct d3d_vertex_shader *shader = impl_from_ID3D11VertexShader(iface);
138 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
140 return d3d_set_private_data_interface(&shader->private_store, guid, data);
143 static const struct ID3D11VertexShaderVtbl d3d11_vertex_shader_vtbl =
145 /* IUnknown methods */
146 d3d11_vertex_shader_QueryInterface,
147 d3d11_vertex_shader_AddRef,
148 d3d11_vertex_shader_Release,
149 /* ID3D11DeviceChild methods */
150 d3d11_vertex_shader_GetDevice,
151 d3d11_vertex_shader_GetPrivateData,
152 d3d11_vertex_shader_SetPrivateData,
153 d3d11_vertex_shader_SetPrivateDataInterface,
156 /* ID3D10VertexShader methods */
158 static inline struct d3d_vertex_shader *impl_from_ID3D10VertexShader(ID3D10VertexShader *iface)
160 return CONTAINING_RECORD(iface, struct d3d_vertex_shader, ID3D10VertexShader_iface);
163 /* IUnknown methods */
165 static HRESULT STDMETHODCALLTYPE d3d10_vertex_shader_QueryInterface(ID3D10VertexShader *iface,
166 REFIID riid, void **object)
168 struct d3d_vertex_shader *shader = impl_from_ID3D10VertexShader(iface);
170 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
172 return d3d11_vertex_shader_QueryInterface(&shader->ID3D11VertexShader_iface, riid, object);
175 static ULONG STDMETHODCALLTYPE d3d10_vertex_shader_AddRef(ID3D10VertexShader *iface)
177 struct d3d_vertex_shader *shader = impl_from_ID3D10VertexShader(iface);
179 TRACE("iface %p.\n", iface);
181 return d3d11_vertex_shader_AddRef(&shader->ID3D11VertexShader_iface);
184 static ULONG STDMETHODCALLTYPE d3d10_vertex_shader_Release(ID3D10VertexShader *iface)
186 struct d3d_vertex_shader *shader = impl_from_ID3D10VertexShader(iface);
188 TRACE("iface %p.\n", iface);
190 return d3d11_vertex_shader_Release(&shader->ID3D11VertexShader_iface);
193 /* ID3D10DeviceChild methods */
195 static void STDMETHODCALLTYPE d3d10_vertex_shader_GetDevice(ID3D10VertexShader *iface, ID3D10Device **device)
197 struct d3d_vertex_shader *shader = impl_from_ID3D10VertexShader(iface);
199 TRACE("iface %p, device %p.\n", iface, device);
201 ID3D11Device2_QueryInterface(shader->device, &IID_ID3D10Device, (void **)device);
204 static HRESULT STDMETHODCALLTYPE d3d10_vertex_shader_GetPrivateData(ID3D10VertexShader *iface,
205 REFGUID guid, UINT *data_size, void *data)
207 struct d3d_vertex_shader *shader = impl_from_ID3D10VertexShader(iface);
209 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
210 iface, debugstr_guid(guid), data_size, data);
212 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
215 static HRESULT STDMETHODCALLTYPE d3d10_vertex_shader_SetPrivateData(ID3D10VertexShader *iface,
216 REFGUID guid, UINT data_size, const void *data)
218 struct d3d_vertex_shader *shader = impl_from_ID3D10VertexShader(iface);
220 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
221 iface, debugstr_guid(guid), data_size, data);
223 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
226 static HRESULT STDMETHODCALLTYPE d3d10_vertex_shader_SetPrivateDataInterface(ID3D10VertexShader *iface,
227 REFGUID guid, const IUnknown *data)
229 struct d3d_vertex_shader *shader = impl_from_ID3D10VertexShader(iface);
231 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
233 return d3d_set_private_data_interface(&shader->private_store, guid, data);
236 static const struct ID3D10VertexShaderVtbl d3d10_vertex_shader_vtbl =
238 /* IUnknown methods */
239 d3d10_vertex_shader_QueryInterface,
240 d3d10_vertex_shader_AddRef,
241 d3d10_vertex_shader_Release,
242 /* ID3D10DeviceChild methods */
243 d3d10_vertex_shader_GetDevice,
244 d3d10_vertex_shader_GetPrivateData,
245 d3d10_vertex_shader_SetPrivateData,
246 d3d10_vertex_shader_SetPrivateDataInterface,
249 static void STDMETHODCALLTYPE d3d_vertex_shader_wined3d_object_destroyed(void *parent)
251 struct d3d_vertex_shader *shader = parent;
253 wined3d_private_store_cleanup(&shader->private_store);
254 heap_free(parent);
257 static const struct wined3d_parent_ops d3d_vertex_shader_wined3d_parent_ops =
259 d3d_vertex_shader_wined3d_object_destroyed,
262 static HRESULT d3d_vertex_shader_init(struct d3d_vertex_shader *shader, struct d3d_device *device,
263 const void *byte_code, SIZE_T byte_code_length)
265 struct wined3d_shader_desc desc;
266 HRESULT hr;
268 shader->ID3D11VertexShader_iface.lpVtbl = &d3d11_vertex_shader_vtbl;
269 shader->ID3D10VertexShader_iface.lpVtbl = &d3d10_vertex_shader_vtbl;
270 shader->refcount = 1;
271 wined3d_mutex_lock();
272 wined3d_private_store_init(&shader->private_store);
274 desc.byte_code = byte_code;
275 desc.byte_code_size = byte_code_length;
276 if (FAILED(hr = wined3d_shader_create_vs(device->wined3d_device, &desc, shader,
277 &d3d_vertex_shader_wined3d_parent_ops, &shader->wined3d_shader)))
279 WARN("Failed to create wined3d vertex shader, hr %#x.\n", hr);
280 wined3d_private_store_cleanup(&shader->private_store);
281 wined3d_mutex_unlock();
282 return E_INVALIDARG;
284 wined3d_mutex_unlock();
286 ID3D11Device2_AddRef(shader->device = &device->ID3D11Device2_iface);
288 return S_OK;
291 HRESULT d3d_vertex_shader_create(struct d3d_device *device, const void *byte_code, SIZE_T byte_code_length,
292 struct d3d_vertex_shader **shader)
294 struct d3d_vertex_shader *object;
295 HRESULT hr;
297 if (!(object = heap_alloc_zero(sizeof(*object))))
298 return E_OUTOFMEMORY;
300 if (FAILED(hr = d3d_vertex_shader_init(object, device, byte_code, byte_code_length)))
302 WARN("Failed to initialize vertex shader, hr %#x.\n", hr);
303 heap_free(object);
304 return hr;
307 TRACE("Created vertex shader %p.\n", object);
308 *shader = object;
310 return S_OK;
313 struct d3d_vertex_shader *unsafe_impl_from_ID3D11VertexShader(ID3D11VertexShader *iface)
315 if (!iface)
316 return NULL;
317 assert(iface->lpVtbl == &d3d11_vertex_shader_vtbl);
319 return impl_from_ID3D11VertexShader(iface);
322 struct d3d_vertex_shader *unsafe_impl_from_ID3D10VertexShader(ID3D10VertexShader *iface)
324 if (!iface)
325 return NULL;
326 assert(iface->lpVtbl == &d3d10_vertex_shader_vtbl);
328 return impl_from_ID3D10VertexShader(iface);
331 /* ID3D11HullShader methods */
333 static inline struct d3d11_hull_shader *impl_from_ID3D11HullShader(ID3D11HullShader *iface)
335 return CONTAINING_RECORD(iface, struct d3d11_hull_shader, ID3D11HullShader_iface);
338 static HRESULT STDMETHODCALLTYPE d3d11_hull_shader_QueryInterface(ID3D11HullShader *iface,
339 REFIID riid, void **object)
341 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
343 if (IsEqualGUID(riid, &IID_ID3D11HullShader)
344 || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
345 || IsEqualGUID(riid, &IID_IUnknown))
347 ID3D11HullShader_AddRef(iface);
348 *object = iface;
349 return S_OK;
352 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
354 *object = NULL;
355 return E_NOINTERFACE;
358 static ULONG STDMETHODCALLTYPE d3d11_hull_shader_AddRef(ID3D11HullShader *iface)
360 struct d3d11_hull_shader *shader = impl_from_ID3D11HullShader(iface);
361 ULONG refcount = InterlockedIncrement(&shader->refcount);
363 TRACE("%p increasing refcount to %u.\n", shader, refcount);
365 if (refcount == 1)
367 ID3D11Device2_AddRef(shader->device);
368 wined3d_mutex_lock();
369 wined3d_shader_incref(shader->wined3d_shader);
370 wined3d_mutex_unlock();
373 return refcount;
376 static ULONG STDMETHODCALLTYPE d3d11_hull_shader_Release(ID3D11HullShader *iface)
378 struct d3d11_hull_shader *shader = impl_from_ID3D11HullShader(iface);
379 ULONG refcount = InterlockedDecrement(&shader->refcount);
381 TRACE("%p decreasing refcount to %u.\n", shader, refcount);
383 if (!refcount)
385 ID3D11Device2 *device = shader->device;
387 wined3d_mutex_lock();
388 wined3d_shader_decref(shader->wined3d_shader);
389 wined3d_mutex_unlock();
391 /* Release the device last, it may cause the wined3d device to be
392 * destroyed. */
393 ID3D11Device2_Release(device);
396 return refcount;
399 static void STDMETHODCALLTYPE d3d11_hull_shader_GetDevice(ID3D11HullShader *iface,
400 ID3D11Device **device)
402 struct d3d11_hull_shader *shader = impl_from_ID3D11HullShader(iface);
404 TRACE("iface %p, device %p.\n", iface, device);
406 *device = (ID3D11Device *)shader->device;
407 ID3D11Device_AddRef(*device);
410 static HRESULT STDMETHODCALLTYPE d3d11_hull_shader_GetPrivateData(ID3D11HullShader *iface,
411 REFGUID guid, UINT *data_size, void *data)
413 struct d3d11_hull_shader *shader = impl_from_ID3D11HullShader(iface);
415 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
417 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
420 static HRESULT STDMETHODCALLTYPE d3d11_hull_shader_SetPrivateData(ID3D11HullShader *iface,
421 REFGUID guid, UINT data_size, const void *data)
423 struct d3d11_hull_shader *shader = impl_from_ID3D11HullShader(iface);
425 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
427 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
430 static HRESULT STDMETHODCALLTYPE d3d11_hull_shader_SetPrivateDataInterface(ID3D11HullShader *iface,
431 REFGUID guid, const IUnknown *data)
433 struct d3d11_hull_shader *shader = impl_from_ID3D11HullShader(iface);
435 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
437 return d3d_set_private_data_interface(&shader->private_store, guid, data);
440 static const struct ID3D11HullShaderVtbl d3d11_hull_shader_vtbl =
442 /* IUnknown methods */
443 d3d11_hull_shader_QueryInterface,
444 d3d11_hull_shader_AddRef,
445 d3d11_hull_shader_Release,
446 /* ID3D11DeviceChild methods */
447 d3d11_hull_shader_GetDevice,
448 d3d11_hull_shader_GetPrivateData,
449 d3d11_hull_shader_SetPrivateData,
450 d3d11_hull_shader_SetPrivateDataInterface,
453 static void STDMETHODCALLTYPE d3d11_hull_shader_wined3d_object_destroyed(void *parent)
455 struct d3d11_hull_shader *shader = parent;
457 wined3d_private_store_cleanup(&shader->private_store);
458 heap_free(parent);
461 static const struct wined3d_parent_ops d3d11_hull_shader_wined3d_parent_ops =
463 d3d11_hull_shader_wined3d_object_destroyed,
466 static HRESULT d3d11_hull_shader_init(struct d3d11_hull_shader *shader, struct d3d_device *device,
467 const void *byte_code, SIZE_T byte_code_length)
469 struct wined3d_shader_desc desc;
470 HRESULT hr;
472 shader->ID3D11HullShader_iface.lpVtbl = &d3d11_hull_shader_vtbl;
473 shader->refcount = 1;
474 wined3d_mutex_lock();
475 wined3d_private_store_init(&shader->private_store);
477 desc.byte_code = byte_code;
478 desc.byte_code_size = byte_code_length;
479 if (FAILED(hr = wined3d_shader_create_hs(device->wined3d_device, &desc, shader,
480 &d3d11_hull_shader_wined3d_parent_ops, &shader->wined3d_shader)))
482 WARN("Failed to create wined3d hull shader, hr %#x.\n", hr);
483 wined3d_private_store_cleanup(&shader->private_store);
484 wined3d_mutex_unlock();
485 return E_INVALIDARG;
487 wined3d_mutex_unlock();
489 ID3D11Device2_AddRef(shader->device = &device->ID3D11Device2_iface);
491 return S_OK;
494 HRESULT d3d11_hull_shader_create(struct d3d_device *device, const void *byte_code, SIZE_T byte_code_length,
495 struct d3d11_hull_shader **shader)
497 struct d3d11_hull_shader *object;
498 HRESULT hr;
500 if (!(object = heap_alloc_zero(sizeof(*object))))
501 return E_OUTOFMEMORY;
503 if (FAILED(hr = d3d11_hull_shader_init(object, device, byte_code, byte_code_length)))
505 heap_free(object);
506 return hr;
509 TRACE("Created hull shader %p.\n", object);
510 *shader = object;
512 return S_OK;
515 struct d3d11_hull_shader *unsafe_impl_from_ID3D11HullShader(ID3D11HullShader *iface)
517 if (!iface)
518 return NULL;
519 assert(iface->lpVtbl == &d3d11_hull_shader_vtbl);
521 return impl_from_ID3D11HullShader(iface);
524 /* ID3D11DomainShader methods */
526 static inline struct d3d11_domain_shader *impl_from_ID3D11DomainShader(ID3D11DomainShader *iface)
528 return CONTAINING_RECORD(iface, struct d3d11_domain_shader, ID3D11DomainShader_iface);
531 static HRESULT STDMETHODCALLTYPE d3d11_domain_shader_QueryInterface(ID3D11DomainShader *iface,
532 REFIID riid, void **object)
534 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
536 if (IsEqualGUID(riid, &IID_ID3D11DomainShader)
537 || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
538 || IsEqualGUID(riid, &IID_IUnknown))
540 ID3D11DomainShader_AddRef(iface);
541 *object = iface;
542 return S_OK;
545 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
547 *object = NULL;
548 return E_NOINTERFACE;
551 static ULONG STDMETHODCALLTYPE d3d11_domain_shader_AddRef(ID3D11DomainShader *iface)
553 struct d3d11_domain_shader *shader = impl_from_ID3D11DomainShader(iface);
554 ULONG refcount = InterlockedIncrement(&shader->refcount);
556 TRACE("%p increasing refcount to %u.\n", shader, refcount);
558 if (refcount == 1)
560 ID3D11Device2_AddRef(shader->device);
561 wined3d_mutex_lock();
562 wined3d_shader_incref(shader->wined3d_shader);
563 wined3d_mutex_unlock();
566 return refcount;
569 static ULONG STDMETHODCALLTYPE d3d11_domain_shader_Release(ID3D11DomainShader *iface)
571 struct d3d11_domain_shader *shader = impl_from_ID3D11DomainShader(iface);
572 ULONG refcount = InterlockedDecrement(&shader->refcount);
574 TRACE("%p decreasing refcount to %u.\n", shader, refcount);
576 if (!refcount)
578 ID3D11Device2 *device = shader->device;
580 wined3d_mutex_lock();
581 wined3d_shader_decref(shader->wined3d_shader);
582 wined3d_mutex_unlock();
584 /* Release the device last, it may cause the wined3d device to be
585 * destroyed. */
586 ID3D11Device2_Release(device);
589 return refcount;
592 static void STDMETHODCALLTYPE d3d11_domain_shader_GetDevice(ID3D11DomainShader *iface,
593 ID3D11Device **device)
595 struct d3d11_domain_shader *shader = impl_from_ID3D11DomainShader(iface);
597 TRACE("iface %p, device %p.\n", iface, device);
599 *device = (ID3D11Device *)shader->device;
600 ID3D11Device_AddRef(*device);
603 static HRESULT STDMETHODCALLTYPE d3d11_domain_shader_GetPrivateData(ID3D11DomainShader *iface,
604 REFGUID guid, UINT *data_size, void *data)
606 struct d3d11_domain_shader *shader = impl_from_ID3D11DomainShader(iface);
608 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
610 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
613 static HRESULT STDMETHODCALLTYPE d3d11_domain_shader_SetPrivateData(ID3D11DomainShader *iface,
614 REFGUID guid, UINT data_size, const void *data)
616 struct d3d11_domain_shader *shader = impl_from_ID3D11DomainShader(iface);
618 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
620 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
623 static HRESULT STDMETHODCALLTYPE d3d11_domain_shader_SetPrivateDataInterface(ID3D11DomainShader *iface,
624 REFGUID guid, const IUnknown *data)
626 struct d3d11_domain_shader *shader = impl_from_ID3D11DomainShader(iface);
628 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
630 return d3d_set_private_data_interface(&shader->private_store, guid, data);
633 static const struct ID3D11DomainShaderVtbl d3d11_domain_shader_vtbl =
635 /* IUnknown methods */
636 d3d11_domain_shader_QueryInterface,
637 d3d11_domain_shader_AddRef,
638 d3d11_domain_shader_Release,
639 /* ID3D11DeviceChild methods */
640 d3d11_domain_shader_GetDevice,
641 d3d11_domain_shader_GetPrivateData,
642 d3d11_domain_shader_SetPrivateData,
643 d3d11_domain_shader_SetPrivateDataInterface,
646 static void STDMETHODCALLTYPE d3d11_domain_shader_wined3d_object_destroyed(void *parent)
648 struct d3d11_domain_shader *shader = parent;
650 wined3d_private_store_cleanup(&shader->private_store);
651 heap_free(parent);
654 static const struct wined3d_parent_ops d3d11_domain_shader_wined3d_parent_ops =
656 d3d11_domain_shader_wined3d_object_destroyed,
659 static HRESULT d3d11_domain_shader_init(struct d3d11_domain_shader *shader, struct d3d_device *device,
660 const void *byte_code, SIZE_T byte_code_length)
662 struct wined3d_shader_desc desc;
663 HRESULT hr;
665 shader->ID3D11DomainShader_iface.lpVtbl = &d3d11_domain_shader_vtbl;
666 shader->refcount = 1;
667 wined3d_mutex_lock();
668 wined3d_private_store_init(&shader->private_store);
670 desc.byte_code = byte_code;
671 desc.byte_code_size = byte_code_length;
672 if (FAILED(hr = wined3d_shader_create_ds(device->wined3d_device, &desc, shader,
673 &d3d11_domain_shader_wined3d_parent_ops, &shader->wined3d_shader)))
675 WARN("Failed to create wined3d domain shader, hr %#x.\n", hr);
676 wined3d_private_store_cleanup(&shader->private_store);
677 wined3d_mutex_unlock();
678 return E_INVALIDARG;
680 wined3d_mutex_unlock();
682 ID3D11Device2_AddRef(shader->device = &device->ID3D11Device2_iface);
684 return S_OK;
687 HRESULT d3d11_domain_shader_create(struct d3d_device *device, const void *byte_code, SIZE_T byte_code_length,
688 struct d3d11_domain_shader **shader)
690 struct d3d11_domain_shader *object;
691 HRESULT hr;
693 if (!(object = heap_alloc_zero(sizeof(*object))))
694 return E_OUTOFMEMORY;
696 if (FAILED(hr = d3d11_domain_shader_init(object, device, byte_code, byte_code_length)))
698 heap_free(object);
699 return hr;
702 TRACE("Created domain shader %p.\n", object);
703 *shader = object;
705 return S_OK;
708 struct d3d11_domain_shader *unsafe_impl_from_ID3D11DomainShader(ID3D11DomainShader *iface)
710 if (!iface)
711 return NULL;
712 assert(iface->lpVtbl == &d3d11_domain_shader_vtbl);
714 return impl_from_ID3D11DomainShader(iface);
717 /* ID3D11GeometryShader methods */
719 static inline struct d3d_geometry_shader *impl_from_ID3D11GeometryShader(ID3D11GeometryShader *iface)
721 return CONTAINING_RECORD(iface, struct d3d_geometry_shader, ID3D11GeometryShader_iface);
724 static HRESULT STDMETHODCALLTYPE d3d11_geometry_shader_QueryInterface(ID3D11GeometryShader *iface,
725 REFIID riid, void **object)
727 struct d3d_geometry_shader *shader = impl_from_ID3D11GeometryShader(iface);
729 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
731 if (IsEqualGUID(riid, &IID_ID3D11GeometryShader)
732 || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
733 || IsEqualGUID(riid, &IID_IUnknown))
735 ID3D11GeometryShader_AddRef(iface);
736 *object = iface;
737 return S_OK;
740 if (IsEqualGUID(riid, &IID_ID3D10GeometryShader)
741 || IsEqualGUID(riid, &IID_ID3D10DeviceChild))
743 ID3D10GeometryShader_AddRef(&shader->ID3D10GeometryShader_iface);
744 *object = &shader->ID3D10GeometryShader_iface;
745 return S_OK;
748 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
750 *object = NULL;
751 return E_NOINTERFACE;
754 static ULONG STDMETHODCALLTYPE d3d11_geometry_shader_AddRef(ID3D11GeometryShader *iface)
756 struct d3d_geometry_shader *shader = impl_from_ID3D11GeometryShader(iface);
757 ULONG refcount = InterlockedIncrement(&shader->refcount);
759 TRACE("%p increasing refcount to %u.\n", shader, refcount);
761 if (refcount == 1)
763 ID3D11Device2_AddRef(shader->device);
764 wined3d_mutex_lock();
765 wined3d_shader_incref(shader->wined3d_shader);
766 wined3d_mutex_unlock();
769 return refcount;
772 static ULONG STDMETHODCALLTYPE d3d11_geometry_shader_Release(ID3D11GeometryShader *iface)
774 struct d3d_geometry_shader *shader = impl_from_ID3D11GeometryShader(iface);
775 ULONG refcount = InterlockedDecrement(&shader->refcount);
777 TRACE("%p decreasing refcount to %u.\n", shader, refcount);
779 if (!refcount)
781 ID3D11Device2 *device = shader->device;
783 wined3d_mutex_lock();
784 wined3d_shader_decref(shader->wined3d_shader);
785 wined3d_mutex_unlock();
787 /* Release the device last, it may cause the wined3d device to be
788 * destroyed. */
789 ID3D11Device2_Release(device);
792 return refcount;
795 static void STDMETHODCALLTYPE d3d11_geometry_shader_GetDevice(ID3D11GeometryShader *iface,
796 ID3D11Device **device)
798 struct d3d_geometry_shader *shader = impl_from_ID3D11GeometryShader(iface);
800 TRACE("iface %p, device %p.\n", iface, device);
802 *device = (ID3D11Device *)shader->device;
803 ID3D11Device_AddRef(*device);
806 static HRESULT STDMETHODCALLTYPE d3d11_geometry_shader_GetPrivateData(ID3D11GeometryShader *iface,
807 REFGUID guid, UINT *data_size, void *data)
809 struct d3d_geometry_shader *shader = impl_from_ID3D11GeometryShader(iface);
811 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
813 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
816 static HRESULT STDMETHODCALLTYPE d3d11_geometry_shader_SetPrivateData(ID3D11GeometryShader *iface,
817 REFGUID guid, UINT data_size, const void *data)
819 struct d3d_geometry_shader *shader = impl_from_ID3D11GeometryShader(iface);
821 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
823 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
826 static HRESULT STDMETHODCALLTYPE d3d11_geometry_shader_SetPrivateDataInterface(ID3D11GeometryShader *iface,
827 REFGUID guid, const IUnknown *data)
829 struct d3d_geometry_shader *shader = impl_from_ID3D11GeometryShader(iface);
831 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
833 return d3d_set_private_data_interface(&shader->private_store, guid, data);
836 static const struct ID3D11GeometryShaderVtbl d3d11_geometry_shader_vtbl =
838 /* IUnknown methods */
839 d3d11_geometry_shader_QueryInterface,
840 d3d11_geometry_shader_AddRef,
841 d3d11_geometry_shader_Release,
842 /* ID3D11DeviceChild methods */
843 d3d11_geometry_shader_GetDevice,
844 d3d11_geometry_shader_GetPrivateData,
845 d3d11_geometry_shader_SetPrivateData,
846 d3d11_geometry_shader_SetPrivateDataInterface,
849 /* ID3D10GeometryShader methods */
851 static inline struct d3d_geometry_shader *impl_from_ID3D10GeometryShader(ID3D10GeometryShader *iface)
853 return CONTAINING_RECORD(iface, struct d3d_geometry_shader, ID3D10GeometryShader_iface);
856 /* IUnknown methods */
858 static HRESULT STDMETHODCALLTYPE d3d10_geometry_shader_QueryInterface(ID3D10GeometryShader *iface,
859 REFIID riid, void **object)
861 struct d3d_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface);
863 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
865 return d3d11_geometry_shader_QueryInterface(&shader->ID3D11GeometryShader_iface, riid, object);
868 static ULONG STDMETHODCALLTYPE d3d10_geometry_shader_AddRef(ID3D10GeometryShader *iface)
870 struct d3d_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface);
872 TRACE("iface %p.\n", iface);
874 return d3d11_geometry_shader_AddRef(&shader->ID3D11GeometryShader_iface);
877 static ULONG STDMETHODCALLTYPE d3d10_geometry_shader_Release(ID3D10GeometryShader *iface)
879 struct d3d_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface);
881 TRACE("iface %p.\n", iface);
883 return d3d11_geometry_shader_Release(&shader->ID3D11GeometryShader_iface);
886 /* ID3D10DeviceChild methods */
888 static void STDMETHODCALLTYPE d3d10_geometry_shader_GetDevice(ID3D10GeometryShader *iface, ID3D10Device **device)
890 struct d3d_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface);
892 TRACE("iface %p, device %p.\n", iface, device);
894 ID3D11Device2_QueryInterface(shader->device, &IID_ID3D10Device, (void **)device);
897 static HRESULT STDMETHODCALLTYPE d3d10_geometry_shader_GetPrivateData(ID3D10GeometryShader *iface,
898 REFGUID guid, UINT *data_size, void *data)
900 struct d3d_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface);
902 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
903 iface, debugstr_guid(guid), data_size, data);
905 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
908 static HRESULT STDMETHODCALLTYPE d3d10_geometry_shader_SetPrivateData(ID3D10GeometryShader *iface,
909 REFGUID guid, UINT data_size, const void *data)
911 struct d3d_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface);
913 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
914 iface, debugstr_guid(guid), data_size, data);
916 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
919 static HRESULT STDMETHODCALLTYPE d3d10_geometry_shader_SetPrivateDataInterface(ID3D10GeometryShader *iface,
920 REFGUID guid, const IUnknown *data)
922 struct d3d_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface);
924 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
926 return d3d_set_private_data_interface(&shader->private_store, guid, data);
929 static const struct ID3D10GeometryShaderVtbl d3d10_geometry_shader_vtbl =
931 /* IUnknown methods */
932 d3d10_geometry_shader_QueryInterface,
933 d3d10_geometry_shader_AddRef,
934 d3d10_geometry_shader_Release,
935 /* ID3D10DeviceChild methods */
936 d3d10_geometry_shader_GetDevice,
937 d3d10_geometry_shader_GetPrivateData,
938 d3d10_geometry_shader_SetPrivateData,
939 d3d10_geometry_shader_SetPrivateDataInterface,
942 static void STDMETHODCALLTYPE d3d_geometry_shader_wined3d_object_destroyed(void *parent)
944 struct d3d_geometry_shader *shader = parent;
946 wined3d_private_store_cleanup(&shader->private_store);
947 heap_free(parent);
950 static const struct wined3d_parent_ops d3d_geometry_shader_wined3d_parent_ops =
952 d3d_geometry_shader_wined3d_object_destroyed,
955 static HRESULT validate_stream_output_entries(const D3D11_SO_DECLARATION_ENTRY *entries, unsigned int entry_count,
956 const unsigned int *buffer_strides, unsigned int buffer_stride_count, D3D_FEATURE_LEVEL feature_level)
958 unsigned int i, j;
960 for (i = 0; i < entry_count; ++i)
962 const D3D11_SO_DECLARATION_ENTRY *e = &entries[i];
964 TRACE("Stream: %u, semantic: %s, semantic idx: %u, start component: %u, "
965 "component count %u, output slot %u.\n",
966 e->Stream, debugstr_a(e->SemanticName), e->SemanticIndex,
967 e->StartComponent, e->ComponentCount, e->OutputSlot);
969 if (e->Stream >= D3D11_SO_STREAM_COUNT)
971 WARN("Invalid stream %u.\n", e->Stream);
972 return E_INVALIDARG;
974 if (e->Stream && feature_level < D3D_FEATURE_LEVEL_11_0)
976 WARN("Invalid stream %u for feature level %#x.\n", e->Stream, feature_level);
977 return E_INVALIDARG;
979 if (e->Stream)
981 FIXME("Streams not implemented yet.\n");
982 return E_INVALIDARG;
984 if (e->OutputSlot >= D3D11_SO_BUFFER_SLOT_COUNT)
986 WARN("Invalid output slot %u.\n", e->OutputSlot);
987 return E_INVALIDARG;
990 if (!e->SemanticName)
992 if (e->SemanticIndex)
994 WARN("Invalid semantic idx %u for stream output gap.\n", e->SemanticIndex);
995 return E_INVALIDARG;
997 if (e->StartComponent || !e->ComponentCount)
999 WARN("Invalid stream output gap %u-%u.\n", e->StartComponent, e->ComponentCount);
1000 return E_INVALIDARG;
1003 else
1005 if (e->StartComponent > 3 || e->ComponentCount > 4 || !e->ComponentCount
1006 || e->StartComponent + e->ComponentCount > 4)
1008 WARN("Invalid component range %u-%u.\n", e->StartComponent, e->ComponentCount);
1009 return E_INVALIDARG;
1014 for (i = 0; i < entry_count; ++i)
1016 const D3D11_SO_DECLARATION_ENTRY *e1 = &entries[i];
1017 if (!e1->SemanticName) /* gap */
1018 continue;
1020 for (j = i + 1; j < entry_count; ++j)
1022 const D3D11_SO_DECLARATION_ENTRY *e2 = &entries[j];
1023 if (!e2->SemanticName) /* gap */
1024 continue;
1026 if (e1->Stream == e2->Stream
1027 && !stricmp(e1->SemanticName, e2->SemanticName)
1028 && e1->SemanticIndex == e2->SemanticIndex
1029 && e1->StartComponent < e2->StartComponent + e2->ComponentCount
1030 && e1->StartComponent + e1->ComponentCount > e2->StartComponent)
1032 WARN("Stream output elements %u and %u overlap.\n", i, j);
1033 return E_INVALIDARG;
1038 for (i = 0; i < D3D11_SO_STREAM_COUNT; ++i)
1040 unsigned int current_stride[D3D11_SO_BUFFER_SLOT_COUNT] = {0};
1041 unsigned int element_count[D3D11_SO_BUFFER_SLOT_COUNT] = {0};
1042 unsigned int gap_count[D3D11_SO_BUFFER_SLOT_COUNT] = {0};
1044 for (j = 0; j < entry_count; ++j)
1046 const D3D11_SO_DECLARATION_ENTRY *e = &entries[j];
1048 if (e->Stream != i)
1049 continue;
1050 current_stride[e->OutputSlot] += 4 * e->ComponentCount;
1051 ++element_count[e->OutputSlot];
1052 if (!e->SemanticName)
1053 ++gap_count[e->OutputSlot];
1056 for (j = 0; j < D3D11_SO_BUFFER_SLOT_COUNT; ++j)
1058 if (!element_count[j])
1059 continue;
1060 if (element_count[j] == gap_count[j])
1062 WARN("Stream %u, output slot %u contains only gaps.\n", i, j);
1063 return E_INVALIDARG;
1065 if (buffer_stride_count)
1067 if (buffer_stride_count <= j)
1069 WARN("Buffer strides are required for all buffer slots.\n");
1070 return E_INVALIDARG;
1072 if (buffer_strides[j] < current_stride[j] || buffer_strides[j] % 4)
1074 WARN("Invalid stride %u for buffer slot %u.\n", buffer_strides[j], j);
1075 return E_INVALIDARG;
1080 if (!i && feature_level < D3D_FEATURE_LEVEL_11_0 && element_count[0] != entry_count)
1082 for (j = 0; j < ARRAY_SIZE(element_count); ++j)
1084 if (element_count[j] > 1)
1086 WARN("Only one element per output slot is allowed.\n");
1087 return E_INVALIDARG;
1093 return S_OK;
1096 static HRESULT d3d_geometry_shader_init(struct d3d_geometry_shader *shader,
1097 struct d3d_device *device, const void *byte_code, SIZE_T byte_code_length,
1098 const D3D11_SO_DECLARATION_ENTRY *so_entries, unsigned int so_entry_count,
1099 const unsigned int *buffer_strides, unsigned int buffer_stride_count,
1100 unsigned int rasterizer_stream)
1102 struct wined3d_stream_output_desc so_desc;
1103 struct wined3d_shader_desc desc;
1104 unsigned int i;
1105 HRESULT hr;
1107 if (so_entry_count > D3D11_SO_STREAM_COUNT * D3D11_SO_OUTPUT_COMPONENT_COUNT)
1109 WARN("Entry count %u is greater than %u.\n",
1110 so_entry_count, D3D11_SO_STREAM_COUNT * D3D11_SO_OUTPUT_COMPONENT_COUNT);
1111 return E_INVALIDARG;
1113 if (so_entries && !so_entry_count)
1115 WARN("Invalid SO entry count %u.\n", so_entry_count);
1116 return E_INVALIDARG;
1118 if (rasterizer_stream != D3D11_SO_NO_RASTERIZED_STREAM && rasterizer_stream >= D3D11_SO_STREAM_COUNT)
1120 WARN("Invalid rasterizer stream %u.\n", rasterizer_stream);
1121 return E_INVALIDARG;
1123 if (device->feature_level < D3D_FEATURE_LEVEL_11_0)
1125 if (rasterizer_stream)
1127 WARN("Invalid rasterizer stream %u for feature level %#x.\n",
1128 rasterizer_stream, device->feature_level);
1129 return E_INVALIDARG;
1131 if (buffer_stride_count && buffer_stride_count != 1)
1133 WARN("Invalid buffer stride count %u for feature level %#x.\n",
1134 buffer_stride_count, device->feature_level);
1135 return E_INVALIDARG;
1139 if (FAILED(hr = validate_stream_output_entries(so_entries, so_entry_count,
1140 buffer_strides, buffer_stride_count, device->feature_level)))
1141 return hr;
1143 desc.byte_code = byte_code;
1144 desc.byte_code_size = byte_code_length;
1146 memset(&so_desc, 0, sizeof(so_desc));
1147 if (so_entries)
1149 so_desc.elements = (const struct wined3d_stream_output_element *)so_entries;
1150 so_desc.element_count = so_entry_count;
1151 for (i = 0; i < min(buffer_stride_count, ARRAY_SIZE(so_desc.buffer_strides)); ++i)
1152 so_desc.buffer_strides[i] = buffer_strides[i];
1153 so_desc.buffer_stride_count = buffer_stride_count;
1154 so_desc.rasterizer_stream_idx = rasterizer_stream;
1157 shader->ID3D11GeometryShader_iface.lpVtbl = &d3d11_geometry_shader_vtbl;
1158 shader->ID3D10GeometryShader_iface.lpVtbl = &d3d10_geometry_shader_vtbl;
1159 shader->refcount = 1;
1160 wined3d_mutex_lock();
1161 wined3d_private_store_init(&shader->private_store);
1163 if (FAILED(hr = wined3d_shader_create_gs(device->wined3d_device, &desc, so_entries ? &so_desc : NULL,
1164 shader, &d3d_geometry_shader_wined3d_parent_ops, &shader->wined3d_shader)))
1166 WARN("Failed to create wined3d geometry shader, hr %#x.\n", hr);
1167 wined3d_private_store_cleanup(&shader->private_store);
1168 wined3d_mutex_unlock();
1169 return E_INVALIDARG;
1171 wined3d_mutex_unlock();
1173 ID3D11Device2_AddRef(shader->device = &device->ID3D11Device2_iface);
1175 return S_OK;
1178 HRESULT d3d_geometry_shader_create(struct d3d_device *device, const void *byte_code, SIZE_T byte_code_length,
1179 const D3D11_SO_DECLARATION_ENTRY *so_entries, unsigned int so_entry_count,
1180 const unsigned int *buffer_strides, unsigned int buffer_stride_count, unsigned int rasterizer_stream,
1181 struct d3d_geometry_shader **shader)
1183 struct d3d_geometry_shader *object;
1184 HRESULT hr;
1186 if (!(object = heap_alloc_zero(sizeof(*object))))
1187 return E_OUTOFMEMORY;
1189 if (FAILED(hr = d3d_geometry_shader_init(object, device, byte_code, byte_code_length,
1190 so_entries, so_entry_count, buffer_strides, buffer_stride_count, rasterizer_stream)))
1192 WARN("Failed to initialize geometry shader, hr %#x.\n", hr);
1193 heap_free(object);
1194 return hr;
1197 TRACE("Created geometry shader %p.\n", object);
1198 *shader = object;
1200 return S_OK;
1203 struct d3d_geometry_shader *unsafe_impl_from_ID3D11GeometryShader(ID3D11GeometryShader *iface)
1205 if (!iface)
1206 return NULL;
1207 assert(iface->lpVtbl == &d3d11_geometry_shader_vtbl);
1209 return impl_from_ID3D11GeometryShader(iface);
1212 struct d3d_geometry_shader *unsafe_impl_from_ID3D10GeometryShader(ID3D10GeometryShader *iface)
1214 if (!iface)
1215 return NULL;
1216 assert(iface->lpVtbl == &d3d10_geometry_shader_vtbl);
1218 return impl_from_ID3D10GeometryShader(iface);
1221 /* ID3D11PixelShader methods */
1223 static inline struct d3d_pixel_shader *impl_from_ID3D11PixelShader(ID3D11PixelShader *iface)
1225 return CONTAINING_RECORD(iface, struct d3d_pixel_shader, ID3D11PixelShader_iface);
1228 static HRESULT STDMETHODCALLTYPE d3d11_pixel_shader_QueryInterface(ID3D11PixelShader *iface,
1229 REFIID riid, void **object)
1231 struct d3d_pixel_shader *shader = impl_from_ID3D11PixelShader(iface);
1233 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
1235 if (IsEqualGUID(riid, &IID_ID3D11PixelShader)
1236 || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
1237 || IsEqualGUID(riid, &IID_IUnknown))
1239 ID3D11PixelShader_AddRef(iface);
1240 *object = iface;
1241 return S_OK;
1244 if (IsEqualGUID(riid, &IID_ID3D10PixelShader)
1245 || IsEqualGUID(riid, &IID_ID3D10DeviceChild))
1247 IUnknown_AddRef(&shader->ID3D10PixelShader_iface);
1248 *object = &shader->ID3D10PixelShader_iface;
1249 return S_OK;
1252 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
1254 *object = NULL;
1255 return E_NOINTERFACE;
1258 static ULONG STDMETHODCALLTYPE d3d11_pixel_shader_AddRef(ID3D11PixelShader *iface)
1260 struct d3d_pixel_shader *shader = impl_from_ID3D11PixelShader(iface);
1261 ULONG refcount = InterlockedIncrement(&shader->refcount);
1263 TRACE("%p increasing refcount to %u.\n", shader, refcount);
1265 if (refcount == 1)
1267 ID3D11Device2_AddRef(shader->device);
1268 wined3d_mutex_lock();
1269 wined3d_shader_incref(shader->wined3d_shader);
1270 wined3d_mutex_unlock();
1273 return refcount;
1276 static ULONG STDMETHODCALLTYPE d3d11_pixel_shader_Release(ID3D11PixelShader *iface)
1278 struct d3d_pixel_shader *shader = impl_from_ID3D11PixelShader(iface);
1279 ULONG refcount = InterlockedDecrement(&shader->refcount);
1281 TRACE("%p decreasing refcount to %u.\n", shader, refcount);
1283 if (!refcount)
1285 ID3D11Device2 *device = shader->device;
1287 wined3d_mutex_lock();
1288 wined3d_shader_decref(shader->wined3d_shader);
1289 wined3d_mutex_unlock();
1290 /* Release the device last, it may cause the wined3d device to be
1291 * destroyed. */
1292 ID3D11Device2_Release(device);
1295 return refcount;
1298 static void STDMETHODCALLTYPE d3d11_pixel_shader_GetDevice(ID3D11PixelShader *iface,
1299 ID3D11Device **device)
1301 struct d3d_pixel_shader *shader = impl_from_ID3D11PixelShader(iface);
1303 TRACE("iface %p, device %p.\n", iface, device);
1305 *device = (ID3D11Device *)shader->device;
1306 ID3D11Device_AddRef(*device);
1309 static HRESULT STDMETHODCALLTYPE d3d11_pixel_shader_GetPrivateData(ID3D11PixelShader *iface,
1310 REFGUID guid, UINT *data_size, void *data)
1312 struct d3d_pixel_shader *shader = impl_from_ID3D11PixelShader(iface);
1314 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
1316 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
1319 static HRESULT STDMETHODCALLTYPE d3d11_pixel_shader_SetPrivateData(ID3D11PixelShader *iface,
1320 REFGUID guid, UINT data_size, const void *data)
1322 struct d3d_pixel_shader *shader = impl_from_ID3D11PixelShader(iface);
1324 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
1326 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
1329 static HRESULT STDMETHODCALLTYPE d3d11_pixel_shader_SetPrivateDataInterface(ID3D11PixelShader *iface,
1330 REFGUID guid, const IUnknown *data)
1332 struct d3d_pixel_shader *shader = impl_from_ID3D11PixelShader(iface);
1334 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
1336 return d3d_set_private_data_interface(&shader->private_store, guid, data);
1339 static const struct ID3D11PixelShaderVtbl d3d11_pixel_shader_vtbl =
1341 /* IUnknown methods */
1342 d3d11_pixel_shader_QueryInterface,
1343 d3d11_pixel_shader_AddRef,
1344 d3d11_pixel_shader_Release,
1345 /* ID3D11DeviceChild methods */
1346 d3d11_pixel_shader_GetDevice,
1347 d3d11_pixel_shader_GetPrivateData,
1348 d3d11_pixel_shader_SetPrivateData,
1349 d3d11_pixel_shader_SetPrivateDataInterface,
1352 /* ID3D10PixelShader methods */
1354 static inline struct d3d_pixel_shader *impl_from_ID3D10PixelShader(ID3D10PixelShader *iface)
1356 return CONTAINING_RECORD(iface, struct d3d_pixel_shader, ID3D10PixelShader_iface);
1359 /* IUnknown methods */
1361 static HRESULT STDMETHODCALLTYPE d3d10_pixel_shader_QueryInterface(ID3D10PixelShader *iface,
1362 REFIID riid, void **object)
1364 struct d3d_pixel_shader *shader = impl_from_ID3D10PixelShader(iface);
1366 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
1368 return d3d11_pixel_shader_QueryInterface(&shader->ID3D11PixelShader_iface, riid, object);
1371 static ULONG STDMETHODCALLTYPE d3d10_pixel_shader_AddRef(ID3D10PixelShader *iface)
1373 struct d3d_pixel_shader *shader = impl_from_ID3D10PixelShader(iface);
1375 TRACE("iface %p.\n", iface);
1377 return d3d11_pixel_shader_AddRef(&shader->ID3D11PixelShader_iface);
1380 static ULONG STDMETHODCALLTYPE d3d10_pixel_shader_Release(ID3D10PixelShader *iface)
1382 struct d3d_pixel_shader *shader = impl_from_ID3D10PixelShader(iface);
1384 TRACE("iface %p.\n", iface);
1386 return d3d11_pixel_shader_Release(&shader->ID3D11PixelShader_iface);
1389 /* ID3D10DeviceChild methods */
1391 static void STDMETHODCALLTYPE d3d10_pixel_shader_GetDevice(ID3D10PixelShader *iface, ID3D10Device **device)
1393 struct d3d_pixel_shader *shader = impl_from_ID3D10PixelShader(iface);
1395 TRACE("iface %p, device %p.\n", iface, device);
1397 ID3D11Device2_QueryInterface(shader->device, &IID_ID3D10Device, (void **)device);
1400 static HRESULT STDMETHODCALLTYPE d3d10_pixel_shader_GetPrivateData(ID3D10PixelShader *iface,
1401 REFGUID guid, UINT *data_size, void *data)
1403 struct d3d_pixel_shader *shader = impl_from_ID3D10PixelShader(iface);
1405 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
1406 iface, debugstr_guid(guid), data_size, data);
1408 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
1411 static HRESULT STDMETHODCALLTYPE d3d10_pixel_shader_SetPrivateData(ID3D10PixelShader *iface,
1412 REFGUID guid, UINT data_size, const void *data)
1414 struct d3d_pixel_shader *shader = impl_from_ID3D10PixelShader(iface);
1416 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
1417 iface, debugstr_guid(guid), data_size, data);
1419 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
1422 static HRESULT STDMETHODCALLTYPE d3d10_pixel_shader_SetPrivateDataInterface(ID3D10PixelShader *iface,
1423 REFGUID guid, const IUnknown *data)
1425 struct d3d_pixel_shader *shader = impl_from_ID3D10PixelShader(iface);
1427 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
1429 return d3d_set_private_data_interface(&shader->private_store, guid, data);
1432 static const struct ID3D10PixelShaderVtbl d3d10_pixel_shader_vtbl =
1434 /* IUnknown methods */
1435 d3d10_pixel_shader_QueryInterface,
1436 d3d10_pixel_shader_AddRef,
1437 d3d10_pixel_shader_Release,
1438 /* ID3D10DeviceChild methods */
1439 d3d10_pixel_shader_GetDevice,
1440 d3d10_pixel_shader_GetPrivateData,
1441 d3d10_pixel_shader_SetPrivateData,
1442 d3d10_pixel_shader_SetPrivateDataInterface,
1445 static void STDMETHODCALLTYPE d3d_pixel_shader_wined3d_object_destroyed(void *parent)
1447 struct d3d_pixel_shader *shader = parent;
1449 wined3d_private_store_cleanup(&shader->private_store);
1450 heap_free(parent);
1453 static const struct wined3d_parent_ops d3d_pixel_shader_wined3d_parent_ops =
1455 d3d_pixel_shader_wined3d_object_destroyed,
1458 static HRESULT d3d_pixel_shader_init(struct d3d_pixel_shader *shader, struct d3d_device *device,
1459 const void *byte_code, SIZE_T byte_code_length)
1461 struct wined3d_shader_desc desc;
1462 HRESULT hr;
1464 shader->ID3D11PixelShader_iface.lpVtbl = &d3d11_pixel_shader_vtbl;
1465 shader->ID3D10PixelShader_iface.lpVtbl = &d3d10_pixel_shader_vtbl;
1466 shader->refcount = 1;
1467 wined3d_mutex_lock();
1468 wined3d_private_store_init(&shader->private_store);
1470 desc.byte_code = byte_code;
1471 desc.byte_code_size = byte_code_length;
1472 if (FAILED(hr = wined3d_shader_create_ps(device->wined3d_device, &desc, shader,
1473 &d3d_pixel_shader_wined3d_parent_ops, &shader->wined3d_shader)))
1475 WARN("Failed to create wined3d pixel shader, hr %#x.\n", hr);
1476 wined3d_private_store_cleanup(&shader->private_store);
1477 wined3d_mutex_unlock();
1478 return E_INVALIDARG;
1480 wined3d_mutex_unlock();
1482 ID3D11Device2_AddRef(shader->device = &device->ID3D11Device2_iface);
1484 return S_OK;
1487 HRESULT d3d_pixel_shader_create(struct d3d_device *device, const void *byte_code, SIZE_T byte_code_length,
1488 struct d3d_pixel_shader **shader)
1490 struct d3d_pixel_shader *object;
1491 HRESULT hr;
1493 if (!(object = heap_alloc_zero(sizeof(*object))))
1494 return E_OUTOFMEMORY;
1496 if (FAILED(hr = d3d_pixel_shader_init(object, device, byte_code, byte_code_length)))
1498 WARN("Failed to initialize pixel shader, hr %#x.\n", hr);
1499 heap_free(object);
1500 return hr;
1503 TRACE("Created pixel shader %p.\n", object);
1504 *shader = object;
1506 return S_OK;
1509 struct d3d_pixel_shader *unsafe_impl_from_ID3D11PixelShader(ID3D11PixelShader *iface)
1511 if (!iface)
1512 return NULL;
1513 assert(iface->lpVtbl == &d3d11_pixel_shader_vtbl);
1515 return impl_from_ID3D11PixelShader(iface);
1518 struct d3d_pixel_shader *unsafe_impl_from_ID3D10PixelShader(ID3D10PixelShader *iface)
1520 if (!iface)
1521 return NULL;
1522 assert(iface->lpVtbl == &d3d10_pixel_shader_vtbl);
1524 return impl_from_ID3D10PixelShader(iface);
1527 /* ID3D11ComputeShader methods */
1529 static inline struct d3d11_compute_shader *impl_from_ID3D11ComputeShader(ID3D11ComputeShader *iface)
1531 return CONTAINING_RECORD(iface, struct d3d11_compute_shader, ID3D11ComputeShader_iface);
1534 static HRESULT STDMETHODCALLTYPE d3d11_compute_shader_QueryInterface(ID3D11ComputeShader *iface,
1535 REFIID riid, void **object)
1537 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
1539 if (IsEqualGUID(riid, &IID_ID3D11ComputeShader)
1540 || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
1541 || IsEqualGUID(riid, &IID_IUnknown))
1543 ID3D11ComputeShader_AddRef(*object = iface);
1544 return S_OK;
1547 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
1549 *object = NULL;
1550 return E_NOINTERFACE;
1553 static ULONG STDMETHODCALLTYPE d3d11_compute_shader_AddRef(ID3D11ComputeShader *iface)
1555 struct d3d11_compute_shader *shader = impl_from_ID3D11ComputeShader(iface);
1556 ULONG refcount = InterlockedIncrement(&shader->refcount);
1558 TRACE("%p increasing refcount to %u.\n", shader, refcount);
1560 if (refcount == 1)
1562 ID3D11Device2_AddRef(shader->device);
1563 wined3d_mutex_lock();
1564 wined3d_shader_incref(shader->wined3d_shader);
1565 wined3d_mutex_unlock();
1568 return refcount;
1571 static ULONG STDMETHODCALLTYPE d3d11_compute_shader_Release(ID3D11ComputeShader *iface)
1573 struct d3d11_compute_shader *shader = impl_from_ID3D11ComputeShader(iface);
1574 ULONG refcount = InterlockedDecrement(&shader->refcount);
1576 TRACE("%p decreasing refcount to %u.\n", shader, refcount);
1578 if (!refcount)
1580 ID3D11Device2 *device = shader->device;
1582 wined3d_mutex_lock();
1583 wined3d_shader_decref(shader->wined3d_shader);
1584 wined3d_mutex_unlock();
1586 /* Release the device last, it may cause the wined3d device to be
1587 * destroyed. */
1588 ID3D11Device2_Release(device);
1591 return refcount;
1594 static void STDMETHODCALLTYPE d3d11_compute_shader_GetDevice(ID3D11ComputeShader *iface,
1595 ID3D11Device **device)
1597 struct d3d11_compute_shader *shader = impl_from_ID3D11ComputeShader(iface);
1599 TRACE("iface %p, device %p.\n", iface, device);
1601 ID3D11Device_AddRef(*device = (ID3D11Device *)shader->device);
1604 static HRESULT STDMETHODCALLTYPE d3d11_compute_shader_GetPrivateData(ID3D11ComputeShader *iface,
1605 REFGUID guid, UINT *data_size, void *data)
1607 struct d3d11_compute_shader *shader = impl_from_ID3D11ComputeShader(iface);
1609 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
1611 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
1614 static HRESULT STDMETHODCALLTYPE d3d11_compute_shader_SetPrivateData(ID3D11ComputeShader *iface,
1615 REFGUID guid, UINT data_size, const void *data)
1617 struct d3d11_compute_shader *shader = impl_from_ID3D11ComputeShader(iface);
1619 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
1621 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
1624 static HRESULT STDMETHODCALLTYPE d3d11_compute_shader_SetPrivateDataInterface(ID3D11ComputeShader *iface,
1625 REFGUID guid, const IUnknown *data)
1627 struct d3d11_compute_shader *shader = impl_from_ID3D11ComputeShader(iface);
1629 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
1631 return d3d_set_private_data_interface(&shader->private_store, guid, data);
1634 static const struct ID3D11ComputeShaderVtbl d3d11_compute_shader_vtbl =
1636 /* IUnknown methods */
1637 d3d11_compute_shader_QueryInterface,
1638 d3d11_compute_shader_AddRef,
1639 d3d11_compute_shader_Release,
1640 /* ID3D11DeviceChild methods */
1641 d3d11_compute_shader_GetDevice,
1642 d3d11_compute_shader_GetPrivateData,
1643 d3d11_compute_shader_SetPrivateData,
1644 d3d11_compute_shader_SetPrivateDataInterface,
1647 static void STDMETHODCALLTYPE d3d11_compute_shader_wined3d_object_destroyed(void *parent)
1649 struct d3d11_compute_shader *shader = parent;
1651 wined3d_private_store_cleanup(&shader->private_store);
1652 heap_free(parent);
1655 static const struct wined3d_parent_ops d3d11_compute_shader_wined3d_parent_ops =
1657 d3d11_compute_shader_wined3d_object_destroyed,
1660 static HRESULT d3d11_compute_shader_init(struct d3d11_compute_shader *shader, struct d3d_device *device,
1661 const void *byte_code, SIZE_T byte_code_length)
1663 struct wined3d_shader_desc desc;
1664 HRESULT hr;
1666 shader->ID3D11ComputeShader_iface.lpVtbl = &d3d11_compute_shader_vtbl;
1667 shader->refcount = 1;
1668 wined3d_mutex_lock();
1669 wined3d_private_store_init(&shader->private_store);
1671 desc.byte_code = byte_code;
1672 desc.byte_code_size = byte_code_length;
1673 if (FAILED(hr = wined3d_shader_create_cs(device->wined3d_device, &desc, shader,
1674 &d3d11_compute_shader_wined3d_parent_ops, &shader->wined3d_shader)))
1676 WARN("Failed to create wined3d compute shader, hr %#x.\n", hr);
1677 wined3d_private_store_cleanup(&shader->private_store);
1678 wined3d_mutex_unlock();
1679 return E_INVALIDARG;
1681 wined3d_mutex_unlock();
1683 ID3D11Device2_AddRef(shader->device = &device->ID3D11Device2_iface);
1685 return S_OK;
1688 HRESULT d3d11_compute_shader_create(struct d3d_device *device, const void *byte_code, SIZE_T byte_code_length,
1689 struct d3d11_compute_shader **shader)
1691 struct d3d11_compute_shader *object;
1692 HRESULT hr;
1694 if (!(object = heap_alloc_zero(sizeof(*object))))
1695 return E_OUTOFMEMORY;
1697 if (FAILED(hr = d3d11_compute_shader_init(object, device, byte_code, byte_code_length)))
1699 heap_free(object);
1700 return hr;
1703 TRACE("Created compute shader %p.\n", object);
1704 *shader = object;
1706 return S_OK;
1709 struct d3d11_compute_shader *unsafe_impl_from_ID3D11ComputeShader(ID3D11ComputeShader *iface)
1711 if (!iface)
1712 return NULL;
1713 assert(iface->lpVtbl == &d3d11_compute_shader_vtbl);
1715 return impl_from_ID3D11ComputeShader(iface);
1718 /* ID3D11ClassLinkage methods */
1720 static inline struct d3d11_class_linkage *impl_from_ID3D11ClassLinkage(ID3D11ClassLinkage *iface)
1722 return CONTAINING_RECORD(iface, struct d3d11_class_linkage, ID3D11ClassLinkage_iface);
1725 static HRESULT STDMETHODCALLTYPE d3d11_class_linkage_QueryInterface(ID3D11ClassLinkage *iface,
1726 REFIID riid, void **object)
1728 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
1730 if (IsEqualGUID(riid, &IID_ID3D11ClassLinkage)
1731 || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
1732 || IsEqualGUID(riid, &IID_IUnknown))
1734 ID3D11ClassLinkage_AddRef(*object = iface);
1735 return S_OK;
1738 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
1740 *object = NULL;
1741 return E_NOINTERFACE;
1744 static ULONG STDMETHODCALLTYPE d3d11_class_linkage_AddRef(ID3D11ClassLinkage *iface)
1746 struct d3d11_class_linkage *class_linkage = impl_from_ID3D11ClassLinkage(iface);
1747 ULONG refcount = InterlockedIncrement(&class_linkage->refcount);
1749 TRACE("%p increasing refcount to %u.\n", class_linkage, refcount);
1751 return refcount;
1754 static ULONG STDMETHODCALLTYPE d3d11_class_linkage_Release(ID3D11ClassLinkage *iface)
1756 struct d3d11_class_linkage *class_linkage = impl_from_ID3D11ClassLinkage(iface);
1757 ULONG refcount = InterlockedDecrement(&class_linkage->refcount);
1759 TRACE("%p decreasing refcount to %u.\n", class_linkage, refcount);
1761 if (!refcount)
1763 ID3D11Device2 *device = class_linkage->device;
1765 wined3d_private_store_cleanup(&class_linkage->private_store);
1766 heap_free(class_linkage);
1768 ID3D11Device2_Release(device);
1771 return refcount;
1774 static void STDMETHODCALLTYPE d3d11_class_linkage_GetDevice(ID3D11ClassLinkage *iface,
1775 ID3D11Device **device)
1777 struct d3d11_class_linkage *class_linkage = impl_from_ID3D11ClassLinkage(iface);
1779 TRACE("iface %p, device %p.\n", iface, device);
1781 ID3D11Device_AddRef(*device = (ID3D11Device *)class_linkage->device);
1784 static HRESULT STDMETHODCALLTYPE d3d11_class_linkage_GetPrivateData(ID3D11ClassLinkage *iface,
1785 REFGUID guid, UINT *data_size, void *data)
1787 struct d3d11_class_linkage *class_linkage = impl_from_ID3D11ClassLinkage(iface);
1789 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
1791 return d3d_get_private_data(&class_linkage->private_store, guid, data_size, data);
1794 static HRESULT STDMETHODCALLTYPE d3d11_class_linkage_SetPrivateData(ID3D11ClassLinkage *iface,
1795 REFGUID guid, UINT data_size, const void *data)
1797 struct d3d11_class_linkage *class_linkage = impl_from_ID3D11ClassLinkage(iface);
1799 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
1801 return d3d_set_private_data(&class_linkage->private_store, guid, data_size, data);
1804 static HRESULT STDMETHODCALLTYPE d3d11_class_linkage_SetPrivateDataInterface(ID3D11ClassLinkage *iface,
1805 REFGUID guid, const IUnknown *data)
1807 struct d3d11_class_linkage *class_linkage = impl_from_ID3D11ClassLinkage(iface);
1809 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
1811 return d3d_set_private_data_interface(&class_linkage->private_store, guid, data);
1814 static HRESULT STDMETHODCALLTYPE d3d11_class_linkage_GetClassInstance(ID3D11ClassLinkage *iface,
1815 const char *instance_name, UINT instance_index, ID3D11ClassInstance **class_instance)
1817 FIXME("iface %p, instance_name %s, instance_index %u, class_instance %p stub!\n",
1818 iface, debugstr_a(instance_name), instance_index, class_instance);
1820 return E_NOTIMPL;
1823 static HRESULT STDMETHODCALLTYPE d3d11_class_linkage_CreateClassInstance(ID3D11ClassLinkage *iface,
1824 const char *type_name, UINT cb_offset, UINT cb_vector_offset, UINT texture_offset,
1825 UINT sampler_offset, ID3D11ClassInstance **class_instance)
1827 FIXME("iface %p, type_name %s, cb_offset %u, cb_vector_offset %u, texture_offset %u, "
1828 "sampler_offset %u, class_instance %p stub!\n",
1829 iface, debugstr_a(type_name), cb_offset, cb_vector_offset, texture_offset,
1830 sampler_offset, class_instance);
1832 return E_NOTIMPL;
1835 static const struct ID3D11ClassLinkageVtbl d3d11_class_linkage_vtbl =
1837 /* IUnknown methods */
1838 d3d11_class_linkage_QueryInterface,
1839 d3d11_class_linkage_AddRef,
1840 d3d11_class_linkage_Release,
1841 /* ID3D11DeviceChild methods */
1842 d3d11_class_linkage_GetDevice,
1843 d3d11_class_linkage_GetPrivateData,
1844 d3d11_class_linkage_SetPrivateData,
1845 d3d11_class_linkage_SetPrivateDataInterface,
1846 /* ID3D11ClassLinkage methods */
1847 d3d11_class_linkage_GetClassInstance,
1848 d3d11_class_linkage_CreateClassInstance,
1851 HRESULT d3d11_class_linkage_create(struct d3d_device *device, struct d3d11_class_linkage **class_linkage)
1853 struct d3d11_class_linkage *object;
1855 if (!(object = heap_alloc_zero(sizeof(*object))))
1856 return E_OUTOFMEMORY;
1858 object->ID3D11ClassLinkage_iface.lpVtbl = &d3d11_class_linkage_vtbl;
1859 object->refcount = 1;
1860 wined3d_private_store_init(&object->private_store);
1862 ID3D11Device2_AddRef(object->device = &device->ID3D11Device2_iface);
1864 TRACE("Created class linkage %p.\n", object);
1865 *class_linkage = object;
1867 return S_OK;