opengl32: Use RtlSetLastWin32Error instead of SetLastError.
[wine.git] / dlls / d3d11 / shader.c
blob31e3aae3582b1e803e0986937a371310f9f5c1a3
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 %lu.\n", shader, refcount);
69 if (refcount == 1)
71 ID3D11Device2_AddRef(shader->device);
72 wined3d_shader_incref(shader->wined3d_shader);
75 return refcount;
78 static ULONG STDMETHODCALLTYPE d3d11_vertex_shader_Release(ID3D11VertexShader *iface)
80 struct d3d_vertex_shader *shader = impl_from_ID3D11VertexShader(iface);
81 ULONG refcount = InterlockedDecrement(&shader->refcount);
83 TRACE("%p decreasing refcount to %lu.\n", shader, refcount);
85 if (!refcount)
87 ID3D11Device2 *device = shader->device;
89 wined3d_shader_decref(shader->wined3d_shader);
90 /* Release the device last, it may cause the wined3d device to be
91 * destroyed. */
92 ID3D11Device2_Release(device);
95 return refcount;
98 static void STDMETHODCALLTYPE d3d11_vertex_shader_GetDevice(ID3D11VertexShader *iface,
99 ID3D11Device **device)
101 struct d3d_vertex_shader *shader = impl_from_ID3D11VertexShader(iface);
103 TRACE("iface %p, device %p.\n", iface, device);
105 *device = (ID3D11Device *)shader->device;
106 ID3D11Device_AddRef(*device);
109 static HRESULT STDMETHODCALLTYPE d3d11_vertex_shader_GetPrivateData(ID3D11VertexShader *iface,
110 REFGUID guid, UINT *data_size, void *data)
112 struct d3d_vertex_shader *shader = impl_from_ID3D11VertexShader(iface);
114 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
116 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
119 static HRESULT STDMETHODCALLTYPE d3d11_vertex_shader_SetPrivateData(ID3D11VertexShader *iface,
120 REFGUID guid, UINT data_size, const void *data)
122 struct d3d_vertex_shader *shader = impl_from_ID3D11VertexShader(iface);
124 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
126 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
129 static HRESULT STDMETHODCALLTYPE d3d11_vertex_shader_SetPrivateDataInterface(ID3D11VertexShader *iface,
130 REFGUID guid, const IUnknown *data)
132 struct d3d_vertex_shader *shader = impl_from_ID3D11VertexShader(iface);
134 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
136 return d3d_set_private_data_interface(&shader->private_store, guid, data);
139 static const struct ID3D11VertexShaderVtbl d3d11_vertex_shader_vtbl =
141 /* IUnknown methods */
142 d3d11_vertex_shader_QueryInterface,
143 d3d11_vertex_shader_AddRef,
144 d3d11_vertex_shader_Release,
145 /* ID3D11DeviceChild methods */
146 d3d11_vertex_shader_GetDevice,
147 d3d11_vertex_shader_GetPrivateData,
148 d3d11_vertex_shader_SetPrivateData,
149 d3d11_vertex_shader_SetPrivateDataInterface,
152 /* ID3D10VertexShader methods */
154 static inline struct d3d_vertex_shader *impl_from_ID3D10VertexShader(ID3D10VertexShader *iface)
156 return CONTAINING_RECORD(iface, struct d3d_vertex_shader, ID3D10VertexShader_iface);
159 /* IUnknown methods */
161 static HRESULT STDMETHODCALLTYPE d3d10_vertex_shader_QueryInterface(ID3D10VertexShader *iface,
162 REFIID riid, void **object)
164 struct d3d_vertex_shader *shader = impl_from_ID3D10VertexShader(iface);
166 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
168 return d3d11_vertex_shader_QueryInterface(&shader->ID3D11VertexShader_iface, riid, object);
171 static ULONG STDMETHODCALLTYPE d3d10_vertex_shader_AddRef(ID3D10VertexShader *iface)
173 struct d3d_vertex_shader *shader = impl_from_ID3D10VertexShader(iface);
175 TRACE("iface %p.\n", iface);
177 return d3d11_vertex_shader_AddRef(&shader->ID3D11VertexShader_iface);
180 static ULONG STDMETHODCALLTYPE d3d10_vertex_shader_Release(ID3D10VertexShader *iface)
182 struct d3d_vertex_shader *shader = impl_from_ID3D10VertexShader(iface);
184 TRACE("iface %p.\n", iface);
186 return d3d11_vertex_shader_Release(&shader->ID3D11VertexShader_iface);
189 /* ID3D10DeviceChild methods */
191 static void STDMETHODCALLTYPE d3d10_vertex_shader_GetDevice(ID3D10VertexShader *iface, ID3D10Device **device)
193 struct d3d_vertex_shader *shader = impl_from_ID3D10VertexShader(iface);
195 TRACE("iface %p, device %p.\n", iface, device);
197 ID3D11Device2_QueryInterface(shader->device, &IID_ID3D10Device, (void **)device);
200 static HRESULT STDMETHODCALLTYPE d3d10_vertex_shader_GetPrivateData(ID3D10VertexShader *iface,
201 REFGUID guid, UINT *data_size, void *data)
203 struct d3d_vertex_shader *shader = impl_from_ID3D10VertexShader(iface);
205 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
206 iface, debugstr_guid(guid), data_size, data);
208 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
211 static HRESULT STDMETHODCALLTYPE d3d10_vertex_shader_SetPrivateData(ID3D10VertexShader *iface,
212 REFGUID guid, UINT data_size, const void *data)
214 struct d3d_vertex_shader *shader = impl_from_ID3D10VertexShader(iface);
216 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
217 iface, debugstr_guid(guid), data_size, data);
219 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
222 static HRESULT STDMETHODCALLTYPE d3d10_vertex_shader_SetPrivateDataInterface(ID3D10VertexShader *iface,
223 REFGUID guid, const IUnknown *data)
225 struct d3d_vertex_shader *shader = impl_from_ID3D10VertexShader(iface);
227 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
229 return d3d_set_private_data_interface(&shader->private_store, guid, data);
232 static const struct ID3D10VertexShaderVtbl d3d10_vertex_shader_vtbl =
234 /* IUnknown methods */
235 d3d10_vertex_shader_QueryInterface,
236 d3d10_vertex_shader_AddRef,
237 d3d10_vertex_shader_Release,
238 /* ID3D10DeviceChild methods */
239 d3d10_vertex_shader_GetDevice,
240 d3d10_vertex_shader_GetPrivateData,
241 d3d10_vertex_shader_SetPrivateData,
242 d3d10_vertex_shader_SetPrivateDataInterface,
245 static void STDMETHODCALLTYPE d3d_vertex_shader_wined3d_object_destroyed(void *parent)
247 struct d3d_vertex_shader *shader = parent;
249 wined3d_private_store_cleanup(&shader->private_store);
250 free(parent);
253 static const struct wined3d_parent_ops d3d_vertex_shader_wined3d_parent_ops =
255 d3d_vertex_shader_wined3d_object_destroyed,
258 static HRESULT d3d_vertex_shader_init(struct d3d_vertex_shader *shader, struct d3d_device *device,
259 const void *byte_code, SIZE_T byte_code_length)
261 struct wined3d_shader_desc desc;
262 HRESULT hr;
264 shader->ID3D11VertexShader_iface.lpVtbl = &d3d11_vertex_shader_vtbl;
265 shader->ID3D10VertexShader_iface.lpVtbl = &d3d10_vertex_shader_vtbl;
266 shader->refcount = 1;
267 wined3d_mutex_lock();
268 wined3d_private_store_init(&shader->private_store);
270 desc.byte_code = byte_code;
271 desc.byte_code_size = byte_code_length;
272 if (FAILED(hr = wined3d_shader_create_vs(device->wined3d_device, &desc, shader,
273 &d3d_vertex_shader_wined3d_parent_ops, &shader->wined3d_shader)))
275 WARN("Failed to create wined3d vertex shader, hr %#lx.\n", hr);
276 wined3d_private_store_cleanup(&shader->private_store);
277 wined3d_mutex_unlock();
278 return E_INVALIDARG;
280 wined3d_mutex_unlock();
282 ID3D11Device2_AddRef(shader->device = &device->ID3D11Device2_iface);
284 return S_OK;
287 HRESULT d3d_vertex_shader_create(struct d3d_device *device, const void *byte_code, SIZE_T byte_code_length,
288 struct d3d_vertex_shader **shader)
290 struct d3d_vertex_shader *object;
291 HRESULT hr;
293 if (!(object = calloc(1, sizeof(*object))))
294 return E_OUTOFMEMORY;
296 if (FAILED(hr = d3d_vertex_shader_init(object, device, byte_code, byte_code_length)))
298 WARN("Failed to initialise vertex shader, hr %#lx.\n", hr);
299 free(object);
300 return hr;
303 TRACE("Created vertex shader %p.\n", object);
304 *shader = object;
306 return S_OK;
309 struct d3d_vertex_shader *unsafe_impl_from_ID3D11VertexShader(ID3D11VertexShader *iface)
311 if (!iface)
312 return NULL;
313 assert(iface->lpVtbl == &d3d11_vertex_shader_vtbl);
315 return impl_from_ID3D11VertexShader(iface);
318 struct d3d_vertex_shader *unsafe_impl_from_ID3D10VertexShader(ID3D10VertexShader *iface)
320 if (!iface)
321 return NULL;
322 assert(iface->lpVtbl == &d3d10_vertex_shader_vtbl);
324 return impl_from_ID3D10VertexShader(iface);
327 /* ID3D11HullShader methods */
329 static inline struct d3d11_hull_shader *impl_from_ID3D11HullShader(ID3D11HullShader *iface)
331 return CONTAINING_RECORD(iface, struct d3d11_hull_shader, ID3D11HullShader_iface);
334 static HRESULT STDMETHODCALLTYPE d3d11_hull_shader_QueryInterface(ID3D11HullShader *iface,
335 REFIID riid, void **object)
337 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
339 if (IsEqualGUID(riid, &IID_ID3D11HullShader)
340 || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
341 || IsEqualGUID(riid, &IID_IUnknown))
343 ID3D11HullShader_AddRef(iface);
344 *object = iface;
345 return S_OK;
348 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
350 *object = NULL;
351 return E_NOINTERFACE;
354 static ULONG STDMETHODCALLTYPE d3d11_hull_shader_AddRef(ID3D11HullShader *iface)
356 struct d3d11_hull_shader *shader = impl_from_ID3D11HullShader(iface);
357 ULONG refcount = InterlockedIncrement(&shader->refcount);
359 TRACE("%p increasing refcount to %lu.\n", shader, refcount);
361 if (refcount == 1)
363 ID3D11Device2_AddRef(shader->device);
364 wined3d_shader_incref(shader->wined3d_shader);
367 return refcount;
370 static ULONG STDMETHODCALLTYPE d3d11_hull_shader_Release(ID3D11HullShader *iface)
372 struct d3d11_hull_shader *shader = impl_from_ID3D11HullShader(iface);
373 ULONG refcount = InterlockedDecrement(&shader->refcount);
375 TRACE("%p decreasing refcount to %lu.\n", shader, refcount);
377 if (!refcount)
379 ID3D11Device2 *device = shader->device;
380 wined3d_shader_decref(shader->wined3d_shader);
381 /* Release the device last, it may cause the wined3d device to be
382 * destroyed. */
383 ID3D11Device2_Release(device);
386 return refcount;
389 static void STDMETHODCALLTYPE d3d11_hull_shader_GetDevice(ID3D11HullShader *iface,
390 ID3D11Device **device)
392 struct d3d11_hull_shader *shader = impl_from_ID3D11HullShader(iface);
394 TRACE("iface %p, device %p.\n", iface, device);
396 *device = (ID3D11Device *)shader->device;
397 ID3D11Device_AddRef(*device);
400 static HRESULT STDMETHODCALLTYPE d3d11_hull_shader_GetPrivateData(ID3D11HullShader *iface,
401 REFGUID guid, UINT *data_size, void *data)
403 struct d3d11_hull_shader *shader = impl_from_ID3D11HullShader(iface);
405 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
407 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
410 static HRESULT STDMETHODCALLTYPE d3d11_hull_shader_SetPrivateData(ID3D11HullShader *iface,
411 REFGUID guid, UINT data_size, const void *data)
413 struct d3d11_hull_shader *shader = impl_from_ID3D11HullShader(iface);
415 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
417 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
420 static HRESULT STDMETHODCALLTYPE d3d11_hull_shader_SetPrivateDataInterface(ID3D11HullShader *iface,
421 REFGUID guid, const IUnknown *data)
423 struct d3d11_hull_shader *shader = impl_from_ID3D11HullShader(iface);
425 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
427 return d3d_set_private_data_interface(&shader->private_store, guid, data);
430 static const struct ID3D11HullShaderVtbl d3d11_hull_shader_vtbl =
432 /* IUnknown methods */
433 d3d11_hull_shader_QueryInterface,
434 d3d11_hull_shader_AddRef,
435 d3d11_hull_shader_Release,
436 /* ID3D11DeviceChild methods */
437 d3d11_hull_shader_GetDevice,
438 d3d11_hull_shader_GetPrivateData,
439 d3d11_hull_shader_SetPrivateData,
440 d3d11_hull_shader_SetPrivateDataInterface,
443 static void STDMETHODCALLTYPE d3d11_hull_shader_wined3d_object_destroyed(void *parent)
445 struct d3d11_hull_shader *shader = parent;
447 wined3d_private_store_cleanup(&shader->private_store);
448 free(parent);
451 static const struct wined3d_parent_ops d3d11_hull_shader_wined3d_parent_ops =
453 d3d11_hull_shader_wined3d_object_destroyed,
456 static HRESULT d3d11_hull_shader_init(struct d3d11_hull_shader *shader, struct d3d_device *device,
457 const void *byte_code, SIZE_T byte_code_length)
459 struct wined3d_shader_desc desc;
460 HRESULT hr;
462 shader->ID3D11HullShader_iface.lpVtbl = &d3d11_hull_shader_vtbl;
463 shader->refcount = 1;
464 wined3d_mutex_lock();
465 wined3d_private_store_init(&shader->private_store);
467 desc.byte_code = byte_code;
468 desc.byte_code_size = byte_code_length;
469 if (FAILED(hr = wined3d_shader_create_hs(device->wined3d_device, &desc, shader,
470 &d3d11_hull_shader_wined3d_parent_ops, &shader->wined3d_shader)))
472 WARN("Failed to create wined3d hull shader, hr %#lx.\n", hr);
473 wined3d_private_store_cleanup(&shader->private_store);
474 wined3d_mutex_unlock();
475 return E_INVALIDARG;
477 wined3d_mutex_unlock();
479 ID3D11Device2_AddRef(shader->device = &device->ID3D11Device2_iface);
481 return S_OK;
484 HRESULT d3d11_hull_shader_create(struct d3d_device *device, const void *byte_code, SIZE_T byte_code_length,
485 struct d3d11_hull_shader **shader)
487 struct d3d11_hull_shader *object;
488 HRESULT hr;
490 if (!(object = calloc(1, sizeof(*object))))
491 return E_OUTOFMEMORY;
493 if (FAILED(hr = d3d11_hull_shader_init(object, device, byte_code, byte_code_length)))
495 free(object);
496 return hr;
499 TRACE("Created hull shader %p.\n", object);
500 *shader = object;
502 return S_OK;
505 struct d3d11_hull_shader *unsafe_impl_from_ID3D11HullShader(ID3D11HullShader *iface)
507 if (!iface)
508 return NULL;
509 assert(iface->lpVtbl == &d3d11_hull_shader_vtbl);
511 return impl_from_ID3D11HullShader(iface);
514 /* ID3D11DomainShader methods */
516 static inline struct d3d11_domain_shader *impl_from_ID3D11DomainShader(ID3D11DomainShader *iface)
518 return CONTAINING_RECORD(iface, struct d3d11_domain_shader, ID3D11DomainShader_iface);
521 static HRESULT STDMETHODCALLTYPE d3d11_domain_shader_QueryInterface(ID3D11DomainShader *iface,
522 REFIID riid, void **object)
524 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
526 if (IsEqualGUID(riid, &IID_ID3D11DomainShader)
527 || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
528 || IsEqualGUID(riid, &IID_IUnknown))
530 ID3D11DomainShader_AddRef(iface);
531 *object = iface;
532 return S_OK;
535 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
537 *object = NULL;
538 return E_NOINTERFACE;
541 static ULONG STDMETHODCALLTYPE d3d11_domain_shader_AddRef(ID3D11DomainShader *iface)
543 struct d3d11_domain_shader *shader = impl_from_ID3D11DomainShader(iface);
544 ULONG refcount = InterlockedIncrement(&shader->refcount);
546 TRACE("%p increasing refcount to %lu.\n", shader, refcount);
548 if (refcount == 1)
550 ID3D11Device2_AddRef(shader->device);
551 wined3d_shader_incref(shader->wined3d_shader);
554 return refcount;
557 static ULONG STDMETHODCALLTYPE d3d11_domain_shader_Release(ID3D11DomainShader *iface)
559 struct d3d11_domain_shader *shader = impl_from_ID3D11DomainShader(iface);
560 ULONG refcount = InterlockedDecrement(&shader->refcount);
562 TRACE("%p decreasing refcount to %lu.\n", shader, refcount);
564 if (!refcount)
566 ID3D11Device2 *device = shader->device;
567 wined3d_shader_decref(shader->wined3d_shader);
568 /* Release the device last, it may cause the wined3d device to be
569 * destroyed. */
570 ID3D11Device2_Release(device);
573 return refcount;
576 static void STDMETHODCALLTYPE d3d11_domain_shader_GetDevice(ID3D11DomainShader *iface,
577 ID3D11Device **device)
579 struct d3d11_domain_shader *shader = impl_from_ID3D11DomainShader(iface);
581 TRACE("iface %p, device %p.\n", iface, device);
583 *device = (ID3D11Device *)shader->device;
584 ID3D11Device_AddRef(*device);
587 static HRESULT STDMETHODCALLTYPE d3d11_domain_shader_GetPrivateData(ID3D11DomainShader *iface,
588 REFGUID guid, UINT *data_size, void *data)
590 struct d3d11_domain_shader *shader = impl_from_ID3D11DomainShader(iface);
592 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
594 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
597 static HRESULT STDMETHODCALLTYPE d3d11_domain_shader_SetPrivateData(ID3D11DomainShader *iface,
598 REFGUID guid, UINT data_size, const void *data)
600 struct d3d11_domain_shader *shader = impl_from_ID3D11DomainShader(iface);
602 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
604 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
607 static HRESULT STDMETHODCALLTYPE d3d11_domain_shader_SetPrivateDataInterface(ID3D11DomainShader *iface,
608 REFGUID guid, const IUnknown *data)
610 struct d3d11_domain_shader *shader = impl_from_ID3D11DomainShader(iface);
612 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
614 return d3d_set_private_data_interface(&shader->private_store, guid, data);
617 static const struct ID3D11DomainShaderVtbl d3d11_domain_shader_vtbl =
619 /* IUnknown methods */
620 d3d11_domain_shader_QueryInterface,
621 d3d11_domain_shader_AddRef,
622 d3d11_domain_shader_Release,
623 /* ID3D11DeviceChild methods */
624 d3d11_domain_shader_GetDevice,
625 d3d11_domain_shader_GetPrivateData,
626 d3d11_domain_shader_SetPrivateData,
627 d3d11_domain_shader_SetPrivateDataInterface,
630 static void STDMETHODCALLTYPE d3d11_domain_shader_wined3d_object_destroyed(void *parent)
632 struct d3d11_domain_shader *shader = parent;
634 wined3d_private_store_cleanup(&shader->private_store);
635 free(parent);
638 static const struct wined3d_parent_ops d3d11_domain_shader_wined3d_parent_ops =
640 d3d11_domain_shader_wined3d_object_destroyed,
643 static HRESULT d3d11_domain_shader_init(struct d3d11_domain_shader *shader, struct d3d_device *device,
644 const void *byte_code, SIZE_T byte_code_length)
646 struct wined3d_shader_desc desc;
647 HRESULT hr;
649 shader->ID3D11DomainShader_iface.lpVtbl = &d3d11_domain_shader_vtbl;
650 shader->refcount = 1;
651 wined3d_mutex_lock();
652 wined3d_private_store_init(&shader->private_store);
654 desc.byte_code = byte_code;
655 desc.byte_code_size = byte_code_length;
656 if (FAILED(hr = wined3d_shader_create_ds(device->wined3d_device, &desc, shader,
657 &d3d11_domain_shader_wined3d_parent_ops, &shader->wined3d_shader)))
659 WARN("Failed to create wined3d domain shader, hr %#lx.\n", hr);
660 wined3d_private_store_cleanup(&shader->private_store);
661 wined3d_mutex_unlock();
662 return E_INVALIDARG;
664 wined3d_mutex_unlock();
666 ID3D11Device2_AddRef(shader->device = &device->ID3D11Device2_iface);
668 return S_OK;
671 HRESULT d3d11_domain_shader_create(struct d3d_device *device, const void *byte_code, SIZE_T byte_code_length,
672 struct d3d11_domain_shader **shader)
674 struct d3d11_domain_shader *object;
675 HRESULT hr;
677 if (!(object = calloc(1, sizeof(*object))))
678 return E_OUTOFMEMORY;
680 if (FAILED(hr = d3d11_domain_shader_init(object, device, byte_code, byte_code_length)))
682 free(object);
683 return hr;
686 TRACE("Created domain shader %p.\n", object);
687 *shader = object;
689 return S_OK;
692 struct d3d11_domain_shader *unsafe_impl_from_ID3D11DomainShader(ID3D11DomainShader *iface)
694 if (!iface)
695 return NULL;
696 assert(iface->lpVtbl == &d3d11_domain_shader_vtbl);
698 return impl_from_ID3D11DomainShader(iface);
701 /* ID3D11GeometryShader methods */
703 static inline struct d3d_geometry_shader *impl_from_ID3D11GeometryShader(ID3D11GeometryShader *iface)
705 return CONTAINING_RECORD(iface, struct d3d_geometry_shader, ID3D11GeometryShader_iface);
708 static HRESULT STDMETHODCALLTYPE d3d11_geometry_shader_QueryInterface(ID3D11GeometryShader *iface,
709 REFIID riid, void **object)
711 struct d3d_geometry_shader *shader = impl_from_ID3D11GeometryShader(iface);
713 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
715 if (IsEqualGUID(riid, &IID_ID3D11GeometryShader)
716 || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
717 || IsEqualGUID(riid, &IID_IUnknown))
719 ID3D11GeometryShader_AddRef(iface);
720 *object = iface;
721 return S_OK;
724 if (IsEqualGUID(riid, &IID_ID3D10GeometryShader)
725 || IsEqualGUID(riid, &IID_ID3D10DeviceChild))
727 ID3D10GeometryShader_AddRef(&shader->ID3D10GeometryShader_iface);
728 *object = &shader->ID3D10GeometryShader_iface;
729 return S_OK;
732 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
734 *object = NULL;
735 return E_NOINTERFACE;
738 static ULONG STDMETHODCALLTYPE d3d11_geometry_shader_AddRef(ID3D11GeometryShader *iface)
740 struct d3d_geometry_shader *shader = impl_from_ID3D11GeometryShader(iface);
741 ULONG refcount = InterlockedIncrement(&shader->refcount);
743 TRACE("%p increasing refcount to %lu.\n", shader, refcount);
745 if (refcount == 1)
747 ID3D11Device2_AddRef(shader->device);
748 wined3d_shader_incref(shader->wined3d_shader);
751 return refcount;
754 static ULONG STDMETHODCALLTYPE d3d11_geometry_shader_Release(ID3D11GeometryShader *iface)
756 struct d3d_geometry_shader *shader = impl_from_ID3D11GeometryShader(iface);
757 ULONG refcount = InterlockedDecrement(&shader->refcount);
759 TRACE("%p decreasing refcount to %lu.\n", shader, refcount);
761 if (!refcount)
763 ID3D11Device2 *device = shader->device;
764 wined3d_shader_decref(shader->wined3d_shader);
765 /* Release the device last, it may cause the wined3d device to be
766 * destroyed. */
767 ID3D11Device2_Release(device);
770 return refcount;
773 static void STDMETHODCALLTYPE d3d11_geometry_shader_GetDevice(ID3D11GeometryShader *iface,
774 ID3D11Device **device)
776 struct d3d_geometry_shader *shader = impl_from_ID3D11GeometryShader(iface);
778 TRACE("iface %p, device %p.\n", iface, device);
780 *device = (ID3D11Device *)shader->device;
781 ID3D11Device_AddRef(*device);
784 static HRESULT STDMETHODCALLTYPE d3d11_geometry_shader_GetPrivateData(ID3D11GeometryShader *iface,
785 REFGUID guid, UINT *data_size, void *data)
787 struct d3d_geometry_shader *shader = impl_from_ID3D11GeometryShader(iface);
789 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
791 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
794 static HRESULT STDMETHODCALLTYPE d3d11_geometry_shader_SetPrivateData(ID3D11GeometryShader *iface,
795 REFGUID guid, UINT data_size, const void *data)
797 struct d3d_geometry_shader *shader = impl_from_ID3D11GeometryShader(iface);
799 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
801 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
804 static HRESULT STDMETHODCALLTYPE d3d11_geometry_shader_SetPrivateDataInterface(ID3D11GeometryShader *iface,
805 REFGUID guid, const IUnknown *data)
807 struct d3d_geometry_shader *shader = impl_from_ID3D11GeometryShader(iface);
809 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
811 return d3d_set_private_data_interface(&shader->private_store, guid, data);
814 static const struct ID3D11GeometryShaderVtbl d3d11_geometry_shader_vtbl =
816 /* IUnknown methods */
817 d3d11_geometry_shader_QueryInterface,
818 d3d11_geometry_shader_AddRef,
819 d3d11_geometry_shader_Release,
820 /* ID3D11DeviceChild methods */
821 d3d11_geometry_shader_GetDevice,
822 d3d11_geometry_shader_GetPrivateData,
823 d3d11_geometry_shader_SetPrivateData,
824 d3d11_geometry_shader_SetPrivateDataInterface,
827 /* ID3D10GeometryShader methods */
829 static inline struct d3d_geometry_shader *impl_from_ID3D10GeometryShader(ID3D10GeometryShader *iface)
831 return CONTAINING_RECORD(iface, struct d3d_geometry_shader, ID3D10GeometryShader_iface);
834 /* IUnknown methods */
836 static HRESULT STDMETHODCALLTYPE d3d10_geometry_shader_QueryInterface(ID3D10GeometryShader *iface,
837 REFIID riid, void **object)
839 struct d3d_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface);
841 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
843 return d3d11_geometry_shader_QueryInterface(&shader->ID3D11GeometryShader_iface, riid, object);
846 static ULONG STDMETHODCALLTYPE d3d10_geometry_shader_AddRef(ID3D10GeometryShader *iface)
848 struct d3d_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface);
850 TRACE("iface %p.\n", iface);
852 return d3d11_geometry_shader_AddRef(&shader->ID3D11GeometryShader_iface);
855 static ULONG STDMETHODCALLTYPE d3d10_geometry_shader_Release(ID3D10GeometryShader *iface)
857 struct d3d_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface);
859 TRACE("iface %p.\n", iface);
861 return d3d11_geometry_shader_Release(&shader->ID3D11GeometryShader_iface);
864 /* ID3D10DeviceChild methods */
866 static void STDMETHODCALLTYPE d3d10_geometry_shader_GetDevice(ID3D10GeometryShader *iface, ID3D10Device **device)
868 struct d3d_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface);
870 TRACE("iface %p, device %p.\n", iface, device);
872 ID3D11Device2_QueryInterface(shader->device, &IID_ID3D10Device, (void **)device);
875 static HRESULT STDMETHODCALLTYPE d3d10_geometry_shader_GetPrivateData(ID3D10GeometryShader *iface,
876 REFGUID guid, UINT *data_size, void *data)
878 struct d3d_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface);
880 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
881 iface, debugstr_guid(guid), data_size, data);
883 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
886 static HRESULT STDMETHODCALLTYPE d3d10_geometry_shader_SetPrivateData(ID3D10GeometryShader *iface,
887 REFGUID guid, UINT data_size, const void *data)
889 struct d3d_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface);
891 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
892 iface, debugstr_guid(guid), data_size, data);
894 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
897 static HRESULT STDMETHODCALLTYPE d3d10_geometry_shader_SetPrivateDataInterface(ID3D10GeometryShader *iface,
898 REFGUID guid, const IUnknown *data)
900 struct d3d_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface);
902 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
904 return d3d_set_private_data_interface(&shader->private_store, guid, data);
907 static const struct ID3D10GeometryShaderVtbl d3d10_geometry_shader_vtbl =
909 /* IUnknown methods */
910 d3d10_geometry_shader_QueryInterface,
911 d3d10_geometry_shader_AddRef,
912 d3d10_geometry_shader_Release,
913 /* ID3D10DeviceChild methods */
914 d3d10_geometry_shader_GetDevice,
915 d3d10_geometry_shader_GetPrivateData,
916 d3d10_geometry_shader_SetPrivateData,
917 d3d10_geometry_shader_SetPrivateDataInterface,
920 static void STDMETHODCALLTYPE d3d_geometry_shader_wined3d_object_destroyed(void *parent)
922 struct d3d_geometry_shader *shader = parent;
924 wined3d_private_store_cleanup(&shader->private_store);
925 free(parent);
928 static const struct wined3d_parent_ops d3d_geometry_shader_wined3d_parent_ops =
930 d3d_geometry_shader_wined3d_object_destroyed,
933 static HRESULT validate_stream_output_entries(const D3D11_SO_DECLARATION_ENTRY *entries, unsigned int entry_count,
934 const unsigned int *buffer_strides, unsigned int buffer_stride_count, D3D_FEATURE_LEVEL feature_level)
936 unsigned int i, j;
938 for (i = 0; i < entry_count; ++i)
940 const D3D11_SO_DECLARATION_ENTRY *e = &entries[i];
942 TRACE("Stream: %u, semantic: %s, semantic idx: %u, start component: %u, "
943 "component count %u, output slot %u.\n",
944 e->Stream, debugstr_a(e->SemanticName), e->SemanticIndex,
945 e->StartComponent, e->ComponentCount, e->OutputSlot);
947 if (e->Stream >= D3D11_SO_STREAM_COUNT)
949 WARN("Invalid stream %u.\n", e->Stream);
950 return E_INVALIDARG;
952 if (e->Stream && feature_level < D3D_FEATURE_LEVEL_11_0)
954 WARN("Invalid stream %u for feature level %#x.\n", e->Stream, feature_level);
955 return E_INVALIDARG;
957 if (e->Stream)
959 FIXME("Streams not implemented yet.\n");
960 return E_INVALIDARG;
962 if (e->OutputSlot >= D3D11_SO_BUFFER_SLOT_COUNT)
964 WARN("Invalid output slot %u.\n", e->OutputSlot);
965 return E_INVALIDARG;
968 if (!e->SemanticName)
970 if (e->SemanticIndex)
972 WARN("Invalid semantic idx %u for stream output gap.\n", e->SemanticIndex);
973 return E_INVALIDARG;
975 if (e->StartComponent || !e->ComponentCount)
977 WARN("Invalid stream output gap %u-%u.\n", e->StartComponent, e->ComponentCount);
978 return E_INVALIDARG;
981 else
983 if (e->StartComponent > 3 || e->ComponentCount > 4 || !e->ComponentCount
984 || e->StartComponent + e->ComponentCount > 4)
986 WARN("Invalid component range %u-%u.\n", e->StartComponent, e->ComponentCount);
987 return E_INVALIDARG;
992 for (i = 0; i < entry_count; ++i)
994 const D3D11_SO_DECLARATION_ENTRY *e1 = &entries[i];
995 if (!e1->SemanticName) /* gap */
996 continue;
998 for (j = i + 1; j < entry_count; ++j)
1000 const D3D11_SO_DECLARATION_ENTRY *e2 = &entries[j];
1001 if (!e2->SemanticName) /* gap */
1002 continue;
1004 if (e1->Stream == e2->Stream
1005 && !stricmp(e1->SemanticName, e2->SemanticName)
1006 && e1->SemanticIndex == e2->SemanticIndex
1007 && e1->StartComponent < e2->StartComponent + e2->ComponentCount
1008 && e1->StartComponent + e1->ComponentCount > e2->StartComponent)
1010 WARN("Stream output elements %u and %u overlap.\n", i, j);
1011 return E_INVALIDARG;
1016 for (i = 0; i < D3D11_SO_STREAM_COUNT; ++i)
1018 unsigned int current_stride[D3D11_SO_BUFFER_SLOT_COUNT] = {0};
1019 unsigned int element_count[D3D11_SO_BUFFER_SLOT_COUNT] = {0};
1020 unsigned int gap_count[D3D11_SO_BUFFER_SLOT_COUNT] = {0};
1022 for (j = 0; j < entry_count; ++j)
1024 const D3D11_SO_DECLARATION_ENTRY *e = &entries[j];
1026 if (e->Stream != i)
1027 continue;
1028 current_stride[e->OutputSlot] += 4 * e->ComponentCount;
1029 ++element_count[e->OutputSlot];
1030 if (!e->SemanticName)
1031 ++gap_count[e->OutputSlot];
1034 for (j = 0; j < D3D11_SO_BUFFER_SLOT_COUNT; ++j)
1036 if (!element_count[j])
1037 continue;
1038 if (element_count[j] == gap_count[j])
1040 WARN("Stream %u, output slot %u contains only gaps.\n", i, j);
1041 return E_INVALIDARG;
1043 if (buffer_stride_count)
1045 if (buffer_stride_count <= j)
1047 WARN("Buffer strides are required for all buffer slots.\n");
1048 return E_INVALIDARG;
1050 if (buffer_strides[j] < current_stride[j] || buffer_strides[j] % 4)
1052 WARN("Invalid stride %u for buffer slot %u.\n", buffer_strides[j], j);
1053 return E_INVALIDARG;
1058 if (!i && feature_level < D3D_FEATURE_LEVEL_11_0 && element_count[0] != entry_count)
1060 for (j = 0; j < ARRAY_SIZE(element_count); ++j)
1062 if (element_count[j] > 1)
1064 WARN("Only one element per output slot is allowed.\n");
1065 return E_INVALIDARG;
1071 return S_OK;
1074 static HRESULT d3d_geometry_shader_init(struct d3d_geometry_shader *shader,
1075 struct d3d_device *device, const void *byte_code, SIZE_T byte_code_length,
1076 const D3D11_SO_DECLARATION_ENTRY *so_entries, unsigned int so_entry_count,
1077 const unsigned int *buffer_strides, unsigned int buffer_stride_count,
1078 unsigned int rasterizer_stream)
1080 struct wined3d_stream_output_desc so_desc;
1081 struct wined3d_shader_desc desc;
1082 unsigned int i;
1083 HRESULT hr;
1085 if (so_entry_count > D3D11_SO_STREAM_COUNT * D3D11_SO_OUTPUT_COMPONENT_COUNT)
1087 WARN("Entry count %u is greater than %u.\n",
1088 so_entry_count, D3D11_SO_STREAM_COUNT * D3D11_SO_OUTPUT_COMPONENT_COUNT);
1089 return E_INVALIDARG;
1091 if (so_entries && !so_entry_count)
1093 WARN("Invalid SO entry count %u.\n", so_entry_count);
1094 return E_INVALIDARG;
1096 if (rasterizer_stream != D3D11_SO_NO_RASTERIZED_STREAM && rasterizer_stream >= D3D11_SO_STREAM_COUNT)
1098 WARN("Invalid rasterizer stream %u.\n", rasterizer_stream);
1099 return E_INVALIDARG;
1101 if (device->state->feature_level < D3D_FEATURE_LEVEL_11_0)
1103 if (rasterizer_stream)
1105 WARN("Invalid rasterizer stream %u for feature level %#x.\n",
1106 rasterizer_stream, device->state->feature_level);
1107 return E_INVALIDARG;
1109 if (buffer_stride_count && buffer_stride_count != 1)
1111 WARN("Invalid buffer stride count %u for feature level %#x.\n",
1112 buffer_stride_count, device->state->feature_level);
1113 return E_INVALIDARG;
1117 if (FAILED(hr = validate_stream_output_entries(so_entries, so_entry_count,
1118 buffer_strides, buffer_stride_count, device->state->feature_level)))
1119 return hr;
1121 desc.byte_code = byte_code;
1122 desc.byte_code_size = byte_code_length;
1124 memset(&so_desc, 0, sizeof(so_desc));
1125 if (so_entries)
1127 so_desc.elements = (const struct wined3d_stream_output_element *)so_entries;
1128 so_desc.element_count = so_entry_count;
1129 for (i = 0; i < min(buffer_stride_count, ARRAY_SIZE(so_desc.buffer_strides)); ++i)
1130 so_desc.buffer_strides[i] = buffer_strides[i];
1131 so_desc.buffer_stride_count = buffer_stride_count;
1132 so_desc.rasterizer_stream_idx = rasterizer_stream;
1135 shader->ID3D11GeometryShader_iface.lpVtbl = &d3d11_geometry_shader_vtbl;
1136 shader->ID3D10GeometryShader_iface.lpVtbl = &d3d10_geometry_shader_vtbl;
1137 shader->refcount = 1;
1138 wined3d_mutex_lock();
1139 wined3d_private_store_init(&shader->private_store);
1141 if (FAILED(hr = wined3d_shader_create_gs(device->wined3d_device, &desc, so_entries ? &so_desc : NULL,
1142 shader, &d3d_geometry_shader_wined3d_parent_ops, &shader->wined3d_shader)))
1144 WARN("Failed to create wined3d geometry shader, hr %#lx.\n", hr);
1145 wined3d_private_store_cleanup(&shader->private_store);
1146 wined3d_mutex_unlock();
1147 return E_INVALIDARG;
1149 wined3d_mutex_unlock();
1151 ID3D11Device2_AddRef(shader->device = &device->ID3D11Device2_iface);
1153 return S_OK;
1156 HRESULT d3d_geometry_shader_create(struct d3d_device *device, const void *byte_code, SIZE_T byte_code_length,
1157 const D3D11_SO_DECLARATION_ENTRY *so_entries, unsigned int so_entry_count,
1158 const unsigned int *buffer_strides, unsigned int buffer_stride_count, unsigned int rasterizer_stream,
1159 struct d3d_geometry_shader **shader)
1161 struct d3d_geometry_shader *object;
1162 HRESULT hr;
1164 if (!(object = calloc(1, sizeof(*object))))
1165 return E_OUTOFMEMORY;
1167 if (FAILED(hr = d3d_geometry_shader_init(object, device, byte_code, byte_code_length,
1168 so_entries, so_entry_count, buffer_strides, buffer_stride_count, rasterizer_stream)))
1170 WARN("Failed to initialise geometry shader, hr %#lx.\n", hr);
1171 free(object);
1172 return hr;
1175 TRACE("Created geometry shader %p.\n", object);
1176 *shader = object;
1178 return S_OK;
1181 struct d3d_geometry_shader *unsafe_impl_from_ID3D11GeometryShader(ID3D11GeometryShader *iface)
1183 if (!iface)
1184 return NULL;
1185 assert(iface->lpVtbl == &d3d11_geometry_shader_vtbl);
1187 return impl_from_ID3D11GeometryShader(iface);
1190 struct d3d_geometry_shader *unsafe_impl_from_ID3D10GeometryShader(ID3D10GeometryShader *iface)
1192 if (!iface)
1193 return NULL;
1194 assert(iface->lpVtbl == &d3d10_geometry_shader_vtbl);
1196 return impl_from_ID3D10GeometryShader(iface);
1199 /* ID3D11PixelShader methods */
1201 static inline struct d3d_pixel_shader *impl_from_ID3D11PixelShader(ID3D11PixelShader *iface)
1203 return CONTAINING_RECORD(iface, struct d3d_pixel_shader, ID3D11PixelShader_iface);
1206 static HRESULT STDMETHODCALLTYPE d3d11_pixel_shader_QueryInterface(ID3D11PixelShader *iface,
1207 REFIID riid, void **object)
1209 struct d3d_pixel_shader *shader = impl_from_ID3D11PixelShader(iface);
1211 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
1213 if (IsEqualGUID(riid, &IID_ID3D11PixelShader)
1214 || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
1215 || IsEqualGUID(riid, &IID_IUnknown))
1217 ID3D11PixelShader_AddRef(iface);
1218 *object = iface;
1219 return S_OK;
1222 if (IsEqualGUID(riid, &IID_ID3D10PixelShader)
1223 || IsEqualGUID(riid, &IID_ID3D10DeviceChild))
1225 IUnknown_AddRef(&shader->ID3D10PixelShader_iface);
1226 *object = &shader->ID3D10PixelShader_iface;
1227 return S_OK;
1230 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
1232 *object = NULL;
1233 return E_NOINTERFACE;
1236 static ULONG STDMETHODCALLTYPE d3d11_pixel_shader_AddRef(ID3D11PixelShader *iface)
1238 struct d3d_pixel_shader *shader = impl_from_ID3D11PixelShader(iface);
1239 ULONG refcount = InterlockedIncrement(&shader->refcount);
1241 TRACE("%p increasing refcount to %lu.\n", shader, refcount);
1243 if (refcount == 1)
1245 ID3D11Device2_AddRef(shader->device);
1246 wined3d_shader_incref(shader->wined3d_shader);
1249 return refcount;
1252 static ULONG STDMETHODCALLTYPE d3d11_pixel_shader_Release(ID3D11PixelShader *iface)
1254 struct d3d_pixel_shader *shader = impl_from_ID3D11PixelShader(iface);
1255 ULONG refcount = InterlockedDecrement(&shader->refcount);
1257 TRACE("%p decreasing refcount to %lu.\n", shader, refcount);
1259 if (!refcount)
1261 ID3D11Device2 *device = shader->device;
1262 wined3d_shader_decref(shader->wined3d_shader);
1263 /* Release the device last, it may cause the wined3d device to be
1264 * destroyed. */
1265 ID3D11Device2_Release(device);
1268 return refcount;
1271 static void STDMETHODCALLTYPE d3d11_pixel_shader_GetDevice(ID3D11PixelShader *iface,
1272 ID3D11Device **device)
1274 struct d3d_pixel_shader *shader = impl_from_ID3D11PixelShader(iface);
1276 TRACE("iface %p, device %p.\n", iface, device);
1278 *device = (ID3D11Device *)shader->device;
1279 ID3D11Device_AddRef(*device);
1282 static HRESULT STDMETHODCALLTYPE d3d11_pixel_shader_GetPrivateData(ID3D11PixelShader *iface,
1283 REFGUID guid, UINT *data_size, void *data)
1285 struct d3d_pixel_shader *shader = impl_from_ID3D11PixelShader(iface);
1287 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
1289 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
1292 static HRESULT STDMETHODCALLTYPE d3d11_pixel_shader_SetPrivateData(ID3D11PixelShader *iface,
1293 REFGUID guid, UINT data_size, const void *data)
1295 struct d3d_pixel_shader *shader = impl_from_ID3D11PixelShader(iface);
1297 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
1299 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
1302 static HRESULT STDMETHODCALLTYPE d3d11_pixel_shader_SetPrivateDataInterface(ID3D11PixelShader *iface,
1303 REFGUID guid, const IUnknown *data)
1305 struct d3d_pixel_shader *shader = impl_from_ID3D11PixelShader(iface);
1307 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
1309 return d3d_set_private_data_interface(&shader->private_store, guid, data);
1312 static const struct ID3D11PixelShaderVtbl d3d11_pixel_shader_vtbl =
1314 /* IUnknown methods */
1315 d3d11_pixel_shader_QueryInterface,
1316 d3d11_pixel_shader_AddRef,
1317 d3d11_pixel_shader_Release,
1318 /* ID3D11DeviceChild methods */
1319 d3d11_pixel_shader_GetDevice,
1320 d3d11_pixel_shader_GetPrivateData,
1321 d3d11_pixel_shader_SetPrivateData,
1322 d3d11_pixel_shader_SetPrivateDataInterface,
1325 /* ID3D10PixelShader methods */
1327 static inline struct d3d_pixel_shader *impl_from_ID3D10PixelShader(ID3D10PixelShader *iface)
1329 return CONTAINING_RECORD(iface, struct d3d_pixel_shader, ID3D10PixelShader_iface);
1332 /* IUnknown methods */
1334 static HRESULT STDMETHODCALLTYPE d3d10_pixel_shader_QueryInterface(ID3D10PixelShader *iface,
1335 REFIID riid, void **object)
1337 struct d3d_pixel_shader *shader = impl_from_ID3D10PixelShader(iface);
1339 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
1341 return d3d11_pixel_shader_QueryInterface(&shader->ID3D11PixelShader_iface, riid, object);
1344 static ULONG STDMETHODCALLTYPE d3d10_pixel_shader_AddRef(ID3D10PixelShader *iface)
1346 struct d3d_pixel_shader *shader = impl_from_ID3D10PixelShader(iface);
1348 TRACE("iface %p.\n", iface);
1350 return d3d11_pixel_shader_AddRef(&shader->ID3D11PixelShader_iface);
1353 static ULONG STDMETHODCALLTYPE d3d10_pixel_shader_Release(ID3D10PixelShader *iface)
1355 struct d3d_pixel_shader *shader = impl_from_ID3D10PixelShader(iface);
1357 TRACE("iface %p.\n", iface);
1359 return d3d11_pixel_shader_Release(&shader->ID3D11PixelShader_iface);
1362 /* ID3D10DeviceChild methods */
1364 static void STDMETHODCALLTYPE d3d10_pixel_shader_GetDevice(ID3D10PixelShader *iface, ID3D10Device **device)
1366 struct d3d_pixel_shader *shader = impl_from_ID3D10PixelShader(iface);
1368 TRACE("iface %p, device %p.\n", iface, device);
1370 ID3D11Device2_QueryInterface(shader->device, &IID_ID3D10Device, (void **)device);
1373 static HRESULT STDMETHODCALLTYPE d3d10_pixel_shader_GetPrivateData(ID3D10PixelShader *iface,
1374 REFGUID guid, UINT *data_size, void *data)
1376 struct d3d_pixel_shader *shader = impl_from_ID3D10PixelShader(iface);
1378 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
1379 iface, debugstr_guid(guid), data_size, data);
1381 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
1384 static HRESULT STDMETHODCALLTYPE d3d10_pixel_shader_SetPrivateData(ID3D10PixelShader *iface,
1385 REFGUID guid, UINT data_size, const void *data)
1387 struct d3d_pixel_shader *shader = impl_from_ID3D10PixelShader(iface);
1389 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
1390 iface, debugstr_guid(guid), data_size, data);
1392 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
1395 static HRESULT STDMETHODCALLTYPE d3d10_pixel_shader_SetPrivateDataInterface(ID3D10PixelShader *iface,
1396 REFGUID guid, const IUnknown *data)
1398 struct d3d_pixel_shader *shader = impl_from_ID3D10PixelShader(iface);
1400 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
1402 return d3d_set_private_data_interface(&shader->private_store, guid, data);
1405 static const struct ID3D10PixelShaderVtbl d3d10_pixel_shader_vtbl =
1407 /* IUnknown methods */
1408 d3d10_pixel_shader_QueryInterface,
1409 d3d10_pixel_shader_AddRef,
1410 d3d10_pixel_shader_Release,
1411 /* ID3D10DeviceChild methods */
1412 d3d10_pixel_shader_GetDevice,
1413 d3d10_pixel_shader_GetPrivateData,
1414 d3d10_pixel_shader_SetPrivateData,
1415 d3d10_pixel_shader_SetPrivateDataInterface,
1418 static void STDMETHODCALLTYPE d3d_pixel_shader_wined3d_object_destroyed(void *parent)
1420 struct d3d_pixel_shader *shader = parent;
1422 wined3d_private_store_cleanup(&shader->private_store);
1423 free(parent);
1426 static const struct wined3d_parent_ops d3d_pixel_shader_wined3d_parent_ops =
1428 d3d_pixel_shader_wined3d_object_destroyed,
1431 static HRESULT d3d_pixel_shader_init(struct d3d_pixel_shader *shader, struct d3d_device *device,
1432 const void *byte_code, SIZE_T byte_code_length)
1434 struct wined3d_shader_desc desc;
1435 HRESULT hr;
1437 shader->ID3D11PixelShader_iface.lpVtbl = &d3d11_pixel_shader_vtbl;
1438 shader->ID3D10PixelShader_iface.lpVtbl = &d3d10_pixel_shader_vtbl;
1439 shader->refcount = 1;
1440 wined3d_mutex_lock();
1441 wined3d_private_store_init(&shader->private_store);
1443 desc.byte_code = byte_code;
1444 desc.byte_code_size = byte_code_length;
1445 if (FAILED(hr = wined3d_shader_create_ps(device->wined3d_device, &desc, shader,
1446 &d3d_pixel_shader_wined3d_parent_ops, &shader->wined3d_shader)))
1448 WARN("Failed to create wined3d pixel shader, hr %#lx.\n", hr);
1449 wined3d_private_store_cleanup(&shader->private_store);
1450 wined3d_mutex_unlock();
1451 return E_INVALIDARG;
1453 wined3d_mutex_unlock();
1455 ID3D11Device2_AddRef(shader->device = &device->ID3D11Device2_iface);
1457 return S_OK;
1460 HRESULT d3d_pixel_shader_create(struct d3d_device *device, const void *byte_code, SIZE_T byte_code_length,
1461 struct d3d_pixel_shader **shader)
1463 struct d3d_pixel_shader *object;
1464 HRESULT hr;
1466 if (!(object = calloc(1, sizeof(*object))))
1467 return E_OUTOFMEMORY;
1469 if (FAILED(hr = d3d_pixel_shader_init(object, device, byte_code, byte_code_length)))
1471 WARN("Failed to initialise pixel shader, hr %#lx.\n", hr);
1472 free(object);
1473 return hr;
1476 TRACE("Created pixel shader %p.\n", object);
1477 *shader = object;
1479 return S_OK;
1482 struct d3d_pixel_shader *unsafe_impl_from_ID3D11PixelShader(ID3D11PixelShader *iface)
1484 if (!iface)
1485 return NULL;
1486 assert(iface->lpVtbl == &d3d11_pixel_shader_vtbl);
1488 return impl_from_ID3D11PixelShader(iface);
1491 struct d3d_pixel_shader *unsafe_impl_from_ID3D10PixelShader(ID3D10PixelShader *iface)
1493 if (!iface)
1494 return NULL;
1495 assert(iface->lpVtbl == &d3d10_pixel_shader_vtbl);
1497 return impl_from_ID3D10PixelShader(iface);
1500 /* ID3D11ComputeShader methods */
1502 static inline struct d3d11_compute_shader *impl_from_ID3D11ComputeShader(ID3D11ComputeShader *iface)
1504 return CONTAINING_RECORD(iface, struct d3d11_compute_shader, ID3D11ComputeShader_iface);
1507 static HRESULT STDMETHODCALLTYPE d3d11_compute_shader_QueryInterface(ID3D11ComputeShader *iface,
1508 REFIID riid, void **object)
1510 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
1512 if (IsEqualGUID(riid, &IID_ID3D11ComputeShader)
1513 || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
1514 || IsEqualGUID(riid, &IID_IUnknown))
1516 ID3D11ComputeShader_AddRef(*object = iface);
1517 return S_OK;
1520 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
1522 *object = NULL;
1523 return E_NOINTERFACE;
1526 static ULONG STDMETHODCALLTYPE d3d11_compute_shader_AddRef(ID3D11ComputeShader *iface)
1528 struct d3d11_compute_shader *shader = impl_from_ID3D11ComputeShader(iface);
1529 ULONG refcount = InterlockedIncrement(&shader->refcount);
1531 TRACE("%p increasing refcount to %lu.\n", shader, refcount);
1533 if (refcount == 1)
1535 ID3D11Device2_AddRef(shader->device);
1536 wined3d_shader_incref(shader->wined3d_shader);
1539 return refcount;
1542 static ULONG STDMETHODCALLTYPE d3d11_compute_shader_Release(ID3D11ComputeShader *iface)
1544 struct d3d11_compute_shader *shader = impl_from_ID3D11ComputeShader(iface);
1545 ULONG refcount = InterlockedDecrement(&shader->refcount);
1547 TRACE("%p decreasing refcount to %lu.\n", shader, refcount);
1549 if (!refcount)
1551 ID3D11Device2 *device = shader->device;
1552 wined3d_shader_decref(shader->wined3d_shader);
1553 /* Release the device last, it may cause the wined3d device to be
1554 * destroyed. */
1555 ID3D11Device2_Release(device);
1558 return refcount;
1561 static void STDMETHODCALLTYPE d3d11_compute_shader_GetDevice(ID3D11ComputeShader *iface,
1562 ID3D11Device **device)
1564 struct d3d11_compute_shader *shader = impl_from_ID3D11ComputeShader(iface);
1566 TRACE("iface %p, device %p.\n", iface, device);
1568 ID3D11Device_AddRef(*device = (ID3D11Device *)shader->device);
1571 static HRESULT STDMETHODCALLTYPE d3d11_compute_shader_GetPrivateData(ID3D11ComputeShader *iface,
1572 REFGUID guid, UINT *data_size, void *data)
1574 struct d3d11_compute_shader *shader = impl_from_ID3D11ComputeShader(iface);
1576 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
1578 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
1581 static HRESULT STDMETHODCALLTYPE d3d11_compute_shader_SetPrivateData(ID3D11ComputeShader *iface,
1582 REFGUID guid, UINT data_size, const void *data)
1584 struct d3d11_compute_shader *shader = impl_from_ID3D11ComputeShader(iface);
1586 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
1588 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
1591 static HRESULT STDMETHODCALLTYPE d3d11_compute_shader_SetPrivateDataInterface(ID3D11ComputeShader *iface,
1592 REFGUID guid, const IUnknown *data)
1594 struct d3d11_compute_shader *shader = impl_from_ID3D11ComputeShader(iface);
1596 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
1598 return d3d_set_private_data_interface(&shader->private_store, guid, data);
1601 static const struct ID3D11ComputeShaderVtbl d3d11_compute_shader_vtbl =
1603 /* IUnknown methods */
1604 d3d11_compute_shader_QueryInterface,
1605 d3d11_compute_shader_AddRef,
1606 d3d11_compute_shader_Release,
1607 /* ID3D11DeviceChild methods */
1608 d3d11_compute_shader_GetDevice,
1609 d3d11_compute_shader_GetPrivateData,
1610 d3d11_compute_shader_SetPrivateData,
1611 d3d11_compute_shader_SetPrivateDataInterface,
1614 static void STDMETHODCALLTYPE d3d11_compute_shader_wined3d_object_destroyed(void *parent)
1616 struct d3d11_compute_shader *shader = parent;
1618 wined3d_private_store_cleanup(&shader->private_store);
1619 free(parent);
1622 static const struct wined3d_parent_ops d3d11_compute_shader_wined3d_parent_ops =
1624 d3d11_compute_shader_wined3d_object_destroyed,
1627 static HRESULT d3d11_compute_shader_init(struct d3d11_compute_shader *shader, struct d3d_device *device,
1628 const void *byte_code, SIZE_T byte_code_length)
1630 struct wined3d_shader_desc desc;
1631 HRESULT hr;
1633 shader->ID3D11ComputeShader_iface.lpVtbl = &d3d11_compute_shader_vtbl;
1634 shader->refcount = 1;
1635 wined3d_mutex_lock();
1636 wined3d_private_store_init(&shader->private_store);
1638 desc.byte_code = byte_code;
1639 desc.byte_code_size = byte_code_length;
1640 if (FAILED(hr = wined3d_shader_create_cs(device->wined3d_device, &desc, shader,
1641 &d3d11_compute_shader_wined3d_parent_ops, &shader->wined3d_shader)))
1643 WARN("Failed to create wined3d compute shader, hr %#lx.\n", hr);
1644 wined3d_private_store_cleanup(&shader->private_store);
1645 wined3d_mutex_unlock();
1646 return E_INVALIDARG;
1648 wined3d_mutex_unlock();
1650 ID3D11Device2_AddRef(shader->device = &device->ID3D11Device2_iface);
1652 return S_OK;
1655 HRESULT d3d11_compute_shader_create(struct d3d_device *device, const void *byte_code, SIZE_T byte_code_length,
1656 struct d3d11_compute_shader **shader)
1658 struct d3d11_compute_shader *object;
1659 HRESULT hr;
1661 if (!(object = calloc(1, sizeof(*object))))
1662 return E_OUTOFMEMORY;
1664 if (FAILED(hr = d3d11_compute_shader_init(object, device, byte_code, byte_code_length)))
1666 free(object);
1667 return hr;
1670 TRACE("Created compute shader %p.\n", object);
1671 *shader = object;
1673 return S_OK;
1676 struct d3d11_compute_shader *unsafe_impl_from_ID3D11ComputeShader(ID3D11ComputeShader *iface)
1678 if (!iface)
1679 return NULL;
1680 assert(iface->lpVtbl == &d3d11_compute_shader_vtbl);
1682 return impl_from_ID3D11ComputeShader(iface);
1685 /* ID3D11ClassLinkage methods */
1687 static inline struct d3d11_class_linkage *impl_from_ID3D11ClassLinkage(ID3D11ClassLinkage *iface)
1689 return CONTAINING_RECORD(iface, struct d3d11_class_linkage, ID3D11ClassLinkage_iface);
1692 static HRESULT STDMETHODCALLTYPE d3d11_class_linkage_QueryInterface(ID3D11ClassLinkage *iface,
1693 REFIID riid, void **object)
1695 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
1697 if (IsEqualGUID(riid, &IID_ID3D11ClassLinkage)
1698 || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
1699 || IsEqualGUID(riid, &IID_IUnknown))
1701 ID3D11ClassLinkage_AddRef(*object = iface);
1702 return S_OK;
1705 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
1707 *object = NULL;
1708 return E_NOINTERFACE;
1711 static ULONG STDMETHODCALLTYPE d3d11_class_linkage_AddRef(ID3D11ClassLinkage *iface)
1713 struct d3d11_class_linkage *class_linkage = impl_from_ID3D11ClassLinkage(iface);
1714 ULONG refcount = InterlockedIncrement(&class_linkage->refcount);
1716 TRACE("%p increasing refcount to %lu.\n", class_linkage, refcount);
1718 return refcount;
1721 static ULONG STDMETHODCALLTYPE d3d11_class_linkage_Release(ID3D11ClassLinkage *iface)
1723 struct d3d11_class_linkage *class_linkage = impl_from_ID3D11ClassLinkage(iface);
1724 ULONG refcount = InterlockedDecrement(&class_linkage->refcount);
1726 TRACE("%p decreasing refcount to %lu.\n", class_linkage, refcount);
1728 if (!refcount)
1730 ID3D11Device2 *device = class_linkage->device;
1732 wined3d_private_store_cleanup(&class_linkage->private_store);
1733 free(class_linkage);
1735 ID3D11Device2_Release(device);
1738 return refcount;
1741 static void STDMETHODCALLTYPE d3d11_class_linkage_GetDevice(ID3D11ClassLinkage *iface,
1742 ID3D11Device **device)
1744 struct d3d11_class_linkage *class_linkage = impl_from_ID3D11ClassLinkage(iface);
1746 TRACE("iface %p, device %p.\n", iface, device);
1748 ID3D11Device_AddRef(*device = (ID3D11Device *)class_linkage->device);
1751 static HRESULT STDMETHODCALLTYPE d3d11_class_linkage_GetPrivateData(ID3D11ClassLinkage *iface,
1752 REFGUID guid, UINT *data_size, void *data)
1754 struct d3d11_class_linkage *class_linkage = impl_from_ID3D11ClassLinkage(iface);
1756 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
1758 return d3d_get_private_data(&class_linkage->private_store, guid, data_size, data);
1761 static HRESULT STDMETHODCALLTYPE d3d11_class_linkage_SetPrivateData(ID3D11ClassLinkage *iface,
1762 REFGUID guid, UINT data_size, const void *data)
1764 struct d3d11_class_linkage *class_linkage = impl_from_ID3D11ClassLinkage(iface);
1766 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
1768 return d3d_set_private_data(&class_linkage->private_store, guid, data_size, data);
1771 static HRESULT STDMETHODCALLTYPE d3d11_class_linkage_SetPrivateDataInterface(ID3D11ClassLinkage *iface,
1772 REFGUID guid, const IUnknown *data)
1774 struct d3d11_class_linkage *class_linkage = impl_from_ID3D11ClassLinkage(iface);
1776 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
1778 return d3d_set_private_data_interface(&class_linkage->private_store, guid, data);
1781 static HRESULT STDMETHODCALLTYPE d3d11_class_linkage_GetClassInstance(ID3D11ClassLinkage *iface,
1782 const char *instance_name, UINT instance_index, ID3D11ClassInstance **class_instance)
1784 FIXME("iface %p, instance_name %s, instance_index %u, class_instance %p stub!\n",
1785 iface, debugstr_a(instance_name), instance_index, class_instance);
1787 return E_NOTIMPL;
1790 static HRESULT STDMETHODCALLTYPE d3d11_class_linkage_CreateClassInstance(ID3D11ClassLinkage *iface,
1791 const char *type_name, UINT cb_offset, UINT cb_vector_offset, UINT texture_offset,
1792 UINT sampler_offset, ID3D11ClassInstance **class_instance)
1794 FIXME("iface %p, type_name %s, cb_offset %u, cb_vector_offset %u, texture_offset %u, "
1795 "sampler_offset %u, class_instance %p stub!\n",
1796 iface, debugstr_a(type_name), cb_offset, cb_vector_offset, texture_offset,
1797 sampler_offset, class_instance);
1799 return E_NOTIMPL;
1802 static const struct ID3D11ClassLinkageVtbl d3d11_class_linkage_vtbl =
1804 /* IUnknown methods */
1805 d3d11_class_linkage_QueryInterface,
1806 d3d11_class_linkage_AddRef,
1807 d3d11_class_linkage_Release,
1808 /* ID3D11DeviceChild methods */
1809 d3d11_class_linkage_GetDevice,
1810 d3d11_class_linkage_GetPrivateData,
1811 d3d11_class_linkage_SetPrivateData,
1812 d3d11_class_linkage_SetPrivateDataInterface,
1813 /* ID3D11ClassLinkage methods */
1814 d3d11_class_linkage_GetClassInstance,
1815 d3d11_class_linkage_CreateClassInstance,
1818 HRESULT d3d11_class_linkage_create(struct d3d_device *device, struct d3d11_class_linkage **class_linkage)
1820 struct d3d11_class_linkage *object;
1822 if (!(object = calloc(1, sizeof(*object))))
1823 return E_OUTOFMEMORY;
1825 object->ID3D11ClassLinkage_iface.lpVtbl = &d3d11_class_linkage_vtbl;
1826 object->refcount = 1;
1827 wined3d_private_store_init(&object->private_store);
1829 ID3D11Device2_AddRef(object->device = &device->ID3D11Device2_iface);
1831 TRACE("Created class linkage %p.\n", object);
1832 *class_linkage = object;
1834 return S_OK;