wined3d: Swizzle D3DCOLOR attributes in the GLSL FFP replacement when necessary.
[wine.git] / dlls / d3d11 / shader.c
blob9f618e44d6caa9cf8d765d12ce52697afd9d9d59
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 "config.h"
21 #include "wine/port.h"
23 #include "d3d11_private.h"
25 WINE_DEFAULT_DEBUG_CHANNEL(d3d11);
27 static HRESULT shdr_handler(const char *data, DWORD data_size, DWORD tag, void *ctx)
29 struct wined3d_shader_desc *desc = ctx;
30 HRESULT hr;
32 switch (tag)
34 case TAG_ISGN:
35 if (FAILED(hr = shader_parse_signature(data, data_size, &desc->input_signature)))
36 return hr;
37 break;
39 case TAG_OSGN:
40 if (FAILED(hr = shader_parse_signature(data, data_size, &desc->output_signature)))
41 return hr;
42 break;
44 case TAG_SHDR:
45 case TAG_SHEX:
46 if (desc->byte_code)
47 FIXME("Multiple SHDR/SHEX chunks.\n");
48 desc->byte_code = (const DWORD *)data;
49 break;
51 default:
52 FIXME("Unhandled chunk %s\n", debugstr_an((const char *)&tag, 4));
53 break;
56 return S_OK;
59 static HRESULT shader_extract_from_dxbc(const void *dxbc, SIZE_T dxbc_length, struct wined3d_shader_desc *desc)
61 HRESULT hr;
63 desc->byte_code = NULL;
64 memset(&desc->input_signature, 0, sizeof(desc->input_signature));
65 memset(&desc->output_signature, 0, sizeof(desc->output_signature));
67 hr = parse_dxbc(dxbc, dxbc_length, shdr_handler, desc);
68 if (!desc->byte_code)
69 hr = E_INVALIDARG;
71 if (FAILED(hr))
73 FIXME("Failed to parse shader, hr %#x.\n", hr);
74 shader_free_signature(&desc->input_signature);
75 shader_free_signature(&desc->output_signature);
78 return hr;
81 static const char *shader_get_string(const char *data, size_t data_size, DWORD offset)
83 size_t len, max_len;
85 if (offset >= data_size)
87 WARN("Invalid offset %#x (data size %#lx).\n", offset, (long)data_size);
88 return NULL;
91 max_len = data_size - offset;
92 len = strnlen(data + offset, max_len);
94 if (len == max_len)
95 return NULL;
97 return data + offset;
100 HRESULT shader_parse_signature(const char *data, DWORD data_size, struct wined3d_shader_signature *s)
102 struct wined3d_shader_signature_element *e;
103 const char *ptr = data;
104 unsigned int i;
105 DWORD count;
107 if (!require_space(0, 2, sizeof(DWORD), data_size))
109 WARN("Invalid data size %#x.\n", data_size);
110 return E_INVALIDARG;
113 read_dword(&ptr, &count);
114 TRACE("%u elements\n", count);
116 skip_dword_unknown(&ptr, 1);
118 if (!require_space(ptr - data, count, 6 * sizeof(DWORD), data_size))
120 WARN("Invalid count %#x (data size %#x).\n", count, data_size);
121 return E_INVALIDARG;
124 if (!(e = d3d11_calloc(count, sizeof(*e))))
126 ERR("Failed to allocate input signature memory.\n");
127 return E_OUTOFMEMORY;
130 for (i = 0; i < count; ++i)
132 UINT name_offset;
134 read_dword(&ptr, &name_offset);
135 if (!(e[i].semantic_name = shader_get_string(data, data_size, name_offset)))
137 WARN("Invalid name offset %#x (data size %#x).\n", name_offset, data_size);
138 HeapFree(GetProcessHeap(), 0, e);
139 return E_INVALIDARG;
141 read_dword(&ptr, &e[i].semantic_idx);
142 read_dword(&ptr, &e[i].sysval_semantic);
143 read_dword(&ptr, &e[i].component_type);
144 read_dword(&ptr, &e[i].register_idx);
145 read_dword(&ptr, &e[i].mask);
147 TRACE("semantic: %s, semantic idx: %u, sysval_semantic %#x, "
148 "type %u, register idx: %u, use_mask %#x, input_mask %#x\n",
149 debugstr_a(e[i].semantic_name), e[i].semantic_idx, e[i].sysval_semantic,
150 e[i].component_type, e[i].register_idx, (e[i].mask >> 8) & 0xff, e[i].mask & 0xff);
153 s->elements = e;
154 s->element_count = count;
156 return S_OK;
159 void shader_free_signature(struct wined3d_shader_signature *s)
161 HeapFree(GetProcessHeap(), 0, s->elements);
164 /* ID3D11VertexShader methods */
166 static inline struct d3d_vertex_shader *impl_from_ID3D11VertexShader(ID3D11VertexShader *iface)
168 return CONTAINING_RECORD(iface, struct d3d_vertex_shader, ID3D11VertexShader_iface);
171 static HRESULT STDMETHODCALLTYPE d3d11_vertex_shader_QueryInterface(ID3D11VertexShader *iface,
172 REFIID riid, void **object)
174 struct d3d_vertex_shader *shader = impl_from_ID3D11VertexShader(iface);
176 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
178 if (IsEqualGUID(riid, &IID_ID3D11VertexShader)
179 || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
180 || IsEqualGUID(riid, &IID_IUnknown))
182 ID3D11VertexShader_AddRef(iface);
183 *object = iface;
184 return S_OK;
187 if (IsEqualGUID(riid, &IID_ID3D10VertexShader)
188 || IsEqualGUID(riid, &IID_ID3D10DeviceChild))
190 IUnknown_AddRef(&shader->ID3D10VertexShader_iface);
191 *object = &shader->ID3D10VertexShader_iface;
192 return S_OK;
195 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
197 *object = NULL;
198 return E_NOINTERFACE;
201 static ULONG STDMETHODCALLTYPE d3d11_vertex_shader_AddRef(ID3D11VertexShader *iface)
203 struct d3d_vertex_shader *shader = impl_from_ID3D11VertexShader(iface);
204 ULONG refcount = InterlockedIncrement(&shader->refcount);
206 TRACE("%p increasing refcount to %u.\n", shader, refcount);
208 if (refcount == 1)
210 ID3D11Device_AddRef(shader->device);
211 wined3d_mutex_lock();
212 wined3d_shader_incref(shader->wined3d_shader);
213 wined3d_mutex_unlock();
216 return refcount;
219 static ULONG STDMETHODCALLTYPE d3d11_vertex_shader_Release(ID3D11VertexShader *iface)
221 struct d3d_vertex_shader *shader = impl_from_ID3D11VertexShader(iface);
222 ULONG refcount = InterlockedDecrement(&shader->refcount);
224 TRACE("%p decreasing refcount to %u.\n", shader, refcount);
226 if (!refcount)
228 ID3D11Device *device = shader->device;
230 wined3d_mutex_lock();
231 wined3d_shader_decref(shader->wined3d_shader);
232 wined3d_mutex_unlock();
233 /* Release the device last, it may cause the wined3d device to be
234 * destroyed. */
235 ID3D11Device_Release(device);
238 return refcount;
241 static void STDMETHODCALLTYPE d3d11_vertex_shader_GetDevice(ID3D11VertexShader *iface,
242 ID3D11Device **device)
244 struct d3d_vertex_shader *shader = impl_from_ID3D11VertexShader(iface);
246 TRACE("iface %p, device %p.\n", iface, device);
248 *device = shader->device;
249 ID3D11Device_AddRef(*device);
252 static HRESULT STDMETHODCALLTYPE d3d11_vertex_shader_GetPrivateData(ID3D11VertexShader *iface,
253 REFGUID guid, UINT *data_size, void *data)
255 struct d3d_vertex_shader *shader = impl_from_ID3D11VertexShader(iface);
257 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
259 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
262 static HRESULT STDMETHODCALLTYPE d3d11_vertex_shader_SetPrivateData(ID3D11VertexShader *iface,
263 REFGUID guid, UINT data_size, const void *data)
265 struct d3d_vertex_shader *shader = impl_from_ID3D11VertexShader(iface);
267 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
269 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
272 static HRESULT STDMETHODCALLTYPE d3d11_vertex_shader_SetPrivateDataInterface(ID3D11VertexShader *iface,
273 REFGUID guid, const IUnknown *data)
275 struct d3d_vertex_shader *shader = impl_from_ID3D11VertexShader(iface);
277 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
279 return d3d_set_private_data_interface(&shader->private_store, guid, data);
282 static const struct ID3D11VertexShaderVtbl d3d11_vertex_shader_vtbl =
284 /* IUnknown methods */
285 d3d11_vertex_shader_QueryInterface,
286 d3d11_vertex_shader_AddRef,
287 d3d11_vertex_shader_Release,
288 /* ID3D11DeviceChild methods */
289 d3d11_vertex_shader_GetDevice,
290 d3d11_vertex_shader_GetPrivateData,
291 d3d11_vertex_shader_SetPrivateData,
292 d3d11_vertex_shader_SetPrivateDataInterface,
295 /* ID3D10VertexShader methods */
297 static inline struct d3d_vertex_shader *impl_from_ID3D10VertexShader(ID3D10VertexShader *iface)
299 return CONTAINING_RECORD(iface, struct d3d_vertex_shader, ID3D10VertexShader_iface);
302 /* IUnknown methods */
304 static HRESULT STDMETHODCALLTYPE d3d10_vertex_shader_QueryInterface(ID3D10VertexShader *iface,
305 REFIID riid, void **object)
307 struct d3d_vertex_shader *shader = impl_from_ID3D10VertexShader(iface);
309 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
311 return d3d11_vertex_shader_QueryInterface(&shader->ID3D11VertexShader_iface, riid, object);
314 static ULONG STDMETHODCALLTYPE d3d10_vertex_shader_AddRef(ID3D10VertexShader *iface)
316 struct d3d_vertex_shader *shader = impl_from_ID3D10VertexShader(iface);
318 TRACE("iface %p.\n", iface);
320 return d3d11_vertex_shader_AddRef(&shader->ID3D11VertexShader_iface);
323 static ULONG STDMETHODCALLTYPE d3d10_vertex_shader_Release(ID3D10VertexShader *iface)
325 struct d3d_vertex_shader *shader = impl_from_ID3D10VertexShader(iface);
327 TRACE("iface %p.\n", iface);
329 return d3d11_vertex_shader_Release(&shader->ID3D11VertexShader_iface);
332 /* ID3D10DeviceChild methods */
334 static void STDMETHODCALLTYPE d3d10_vertex_shader_GetDevice(ID3D10VertexShader *iface, ID3D10Device **device)
336 struct d3d_vertex_shader *shader = impl_from_ID3D10VertexShader(iface);
338 TRACE("iface %p, device %p.\n", iface, device);
340 ID3D11Device_QueryInterface(shader->device, &IID_ID3D10Device, (void **)device);
343 static HRESULT STDMETHODCALLTYPE d3d10_vertex_shader_GetPrivateData(ID3D10VertexShader *iface,
344 REFGUID guid, UINT *data_size, void *data)
346 struct d3d_vertex_shader *shader = impl_from_ID3D10VertexShader(iface);
348 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
349 iface, debugstr_guid(guid), data_size, data);
351 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
354 static HRESULT STDMETHODCALLTYPE d3d10_vertex_shader_SetPrivateData(ID3D10VertexShader *iface,
355 REFGUID guid, UINT data_size, const void *data)
357 struct d3d_vertex_shader *shader = impl_from_ID3D10VertexShader(iface);
359 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
360 iface, debugstr_guid(guid), data_size, data);
362 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
365 static HRESULT STDMETHODCALLTYPE d3d10_vertex_shader_SetPrivateDataInterface(ID3D10VertexShader *iface,
366 REFGUID guid, const IUnknown *data)
368 struct d3d_vertex_shader *shader = impl_from_ID3D10VertexShader(iface);
370 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
372 return d3d_set_private_data_interface(&shader->private_store, guid, data);
375 static const struct ID3D10VertexShaderVtbl d3d10_vertex_shader_vtbl =
377 /* IUnknown methods */
378 d3d10_vertex_shader_QueryInterface,
379 d3d10_vertex_shader_AddRef,
380 d3d10_vertex_shader_Release,
381 /* ID3D10DeviceChild methods */
382 d3d10_vertex_shader_GetDevice,
383 d3d10_vertex_shader_GetPrivateData,
384 d3d10_vertex_shader_SetPrivateData,
385 d3d10_vertex_shader_SetPrivateDataInterface,
388 static void STDMETHODCALLTYPE d3d_vertex_shader_wined3d_object_destroyed(void *parent)
390 struct d3d_vertex_shader *shader = parent;
392 wined3d_private_store_cleanup(&shader->private_store);
393 HeapFree(GetProcessHeap(), 0, parent);
396 static const struct wined3d_parent_ops d3d_vertex_shader_wined3d_parent_ops =
398 d3d_vertex_shader_wined3d_object_destroyed,
401 static unsigned int d3d_sm_from_feature_level(D3D_FEATURE_LEVEL feature_level)
403 switch (feature_level)
405 case D3D_FEATURE_LEVEL_11_1:
406 case D3D_FEATURE_LEVEL_11_0:
407 return 5;
408 case D3D_FEATURE_LEVEL_10_1:
409 case D3D_FEATURE_LEVEL_10_0:
410 return 4;
411 case D3D_FEATURE_LEVEL_9_3:
412 return 3;
413 case D3D_FEATURE_LEVEL_9_2:
414 case D3D_FEATURE_LEVEL_9_1:
415 return 2;
416 default:
417 ERR("Unexpected feature_level %#x.\n", feature_level);
419 return 0;
422 static HRESULT d3d_vertex_shader_init(struct d3d_vertex_shader *shader, struct d3d_device *device,
423 const void *byte_code, SIZE_T byte_code_length)
425 struct wined3d_shader_desc desc;
426 HRESULT hr;
428 shader->ID3D11VertexShader_iface.lpVtbl = &d3d11_vertex_shader_vtbl;
429 shader->ID3D10VertexShader_iface.lpVtbl = &d3d10_vertex_shader_vtbl;
430 shader->refcount = 1;
431 wined3d_mutex_lock();
432 wined3d_private_store_init(&shader->private_store);
434 if (FAILED(hr = shader_extract_from_dxbc(byte_code, byte_code_length, &desc)))
436 WARN("Failed to extract shader, hr %#x.\n", hr);
437 wined3d_private_store_cleanup(&shader->private_store);
438 wined3d_mutex_unlock();
439 return hr;
441 desc.max_version = d3d_sm_from_feature_level(device->feature_level);
443 hr = wined3d_shader_create_vs(device->wined3d_device, &desc, shader,
444 &d3d_vertex_shader_wined3d_parent_ops, &shader->wined3d_shader);
445 shader_free_signature(&desc.input_signature);
446 shader_free_signature(&desc.output_signature);
447 if (FAILED(hr))
449 WARN("Failed to create wined3d vertex shader, hr %#x.\n", hr);
450 wined3d_private_store_cleanup(&shader->private_store);
451 wined3d_mutex_unlock();
452 return E_INVALIDARG;
454 wined3d_mutex_unlock();
456 shader->device = &device->ID3D11Device_iface;
457 ID3D11Device_AddRef(shader->device);
459 return S_OK;
462 HRESULT d3d_vertex_shader_create(struct d3d_device *device, const void *byte_code, SIZE_T byte_code_length,
463 struct d3d_vertex_shader **shader)
465 struct d3d_vertex_shader *object;
466 HRESULT hr;
468 if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
469 return E_OUTOFMEMORY;
471 if (FAILED(hr = d3d_vertex_shader_init(object, device, byte_code, byte_code_length)))
473 WARN("Failed to initialize vertex shader, hr %#x.\n", hr);
474 HeapFree(GetProcessHeap(), 0, object);
475 return hr;
478 TRACE("Created vertex shader %p.\n", object);
479 *shader = object;
481 return S_OK;
484 struct d3d_vertex_shader *unsafe_impl_from_ID3D11VertexShader(ID3D11VertexShader *iface)
486 if (!iface)
487 return NULL;
488 assert(iface->lpVtbl == &d3d11_vertex_shader_vtbl);
490 return impl_from_ID3D11VertexShader(iface);
493 struct d3d_vertex_shader *unsafe_impl_from_ID3D10VertexShader(ID3D10VertexShader *iface)
495 if (!iface)
496 return NULL;
497 assert(iface->lpVtbl == &d3d10_vertex_shader_vtbl);
499 return impl_from_ID3D10VertexShader(iface);
502 /* ID3D11HullShader methods */
504 static inline struct d3d11_hull_shader *impl_from_ID3D11HullShader(ID3D11HullShader *iface)
506 return CONTAINING_RECORD(iface, struct d3d11_hull_shader, ID3D11HullShader_iface);
509 static HRESULT STDMETHODCALLTYPE d3d11_hull_shader_QueryInterface(ID3D11HullShader *iface,
510 REFIID riid, void **object)
512 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
514 if (IsEqualGUID(riid, &IID_ID3D11HullShader)
515 || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
516 || IsEqualGUID(riid, &IID_IUnknown))
518 ID3D11HullShader_AddRef(iface);
519 *object = iface;
520 return S_OK;
523 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
525 *object = NULL;
526 return E_NOINTERFACE;
529 static ULONG STDMETHODCALLTYPE d3d11_hull_shader_AddRef(ID3D11HullShader *iface)
531 struct d3d11_hull_shader *shader = impl_from_ID3D11HullShader(iface);
532 ULONG refcount = InterlockedIncrement(&shader->refcount);
534 TRACE("%p increasing refcount to %u.\n", shader, refcount);
536 return refcount;
539 static ULONG STDMETHODCALLTYPE d3d11_hull_shader_Release(ID3D11HullShader *iface)
541 struct d3d11_hull_shader *shader = impl_from_ID3D11HullShader(iface);
542 ULONG refcount = InterlockedDecrement(&shader->refcount);
544 TRACE("%p decreasing refcount to %u.\n", shader, refcount);
546 if (!refcount)
548 ID3D11Device *device = shader->device;
550 wined3d_mutex_lock();
551 wined3d_shader_decref(shader->wined3d_shader);
552 wined3d_mutex_unlock();
554 /* Release the device last, it may cause the wined3d device to be
555 * destroyed. */
556 ID3D11Device_Release(device);
559 return refcount;
562 static void STDMETHODCALLTYPE d3d11_hull_shader_GetDevice(ID3D11HullShader *iface,
563 ID3D11Device **device)
565 struct d3d11_hull_shader *shader = impl_from_ID3D11HullShader(iface);
567 TRACE("iface %p, device %p.\n", iface, device);
569 *device = shader->device;
570 ID3D11Device_AddRef(*device);
573 static HRESULT STDMETHODCALLTYPE d3d11_hull_shader_GetPrivateData(ID3D11HullShader *iface,
574 REFGUID guid, UINT *data_size, void *data)
576 struct d3d11_hull_shader *shader = impl_from_ID3D11HullShader(iface);
578 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
580 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
583 static HRESULT STDMETHODCALLTYPE d3d11_hull_shader_SetPrivateData(ID3D11HullShader *iface,
584 REFGUID guid, UINT data_size, const void *data)
586 struct d3d11_hull_shader *shader = impl_from_ID3D11HullShader(iface);
588 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
590 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
593 static HRESULT STDMETHODCALLTYPE d3d11_hull_shader_SetPrivateDataInterface(ID3D11HullShader *iface,
594 REFGUID guid, const IUnknown *data)
596 struct d3d11_hull_shader *shader = impl_from_ID3D11HullShader(iface);
598 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
600 return d3d_set_private_data_interface(&shader->private_store, guid, data);
603 static const struct ID3D11HullShaderVtbl d3d11_hull_shader_vtbl =
605 /* IUnknown methods */
606 d3d11_hull_shader_QueryInterface,
607 d3d11_hull_shader_AddRef,
608 d3d11_hull_shader_Release,
609 /* ID3D11DeviceChild methods */
610 d3d11_hull_shader_GetDevice,
611 d3d11_hull_shader_GetPrivateData,
612 d3d11_hull_shader_SetPrivateData,
613 d3d11_hull_shader_SetPrivateDataInterface,
616 static void STDMETHODCALLTYPE d3d11_hull_shader_wined3d_object_destroyed(void *parent)
618 struct d3d11_hull_shader *shader = parent;
620 wined3d_private_store_cleanup(&shader->private_store);
621 HeapFree(GetProcessHeap(), 0, parent);
624 static const struct wined3d_parent_ops d3d11_hull_shader_wined3d_parent_ops =
626 d3d11_hull_shader_wined3d_object_destroyed,
629 static HRESULT d3d11_hull_shader_init(struct d3d11_hull_shader *shader, struct d3d_device *device,
630 const void *byte_code, SIZE_T byte_code_length)
632 struct wined3d_shader_desc desc;
633 HRESULT hr;
635 shader->ID3D11HullShader_iface.lpVtbl = &d3d11_hull_shader_vtbl;
636 shader->refcount = 1;
637 wined3d_mutex_lock();
638 wined3d_private_store_init(&shader->private_store);
640 if (FAILED(hr = shader_extract_from_dxbc(byte_code, byte_code_length, &desc)))
642 WARN("Failed to extract shader, hr %#x.\n", hr);
643 wined3d_private_store_cleanup(&shader->private_store);
644 wined3d_mutex_unlock();
645 return hr;
647 desc.max_version = d3d_sm_from_feature_level(device->feature_level);
649 hr = wined3d_shader_create_hs(device->wined3d_device, &desc, shader,
650 &d3d11_hull_shader_wined3d_parent_ops, &shader->wined3d_shader);
651 shader_free_signature(&desc.input_signature);
652 shader_free_signature(&desc.output_signature);
653 if (FAILED(hr))
655 WARN("Failed to create wined3d hull shader, hr %#x.\n", hr);
656 wined3d_private_store_cleanup(&shader->private_store);
657 wined3d_mutex_unlock();
658 return E_INVALIDARG;
660 wined3d_mutex_unlock();
662 shader->device = &device->ID3D11Device_iface;
663 ID3D11Device_AddRef(shader->device);
665 return S_OK;
668 HRESULT d3d11_hull_shader_create(struct d3d_device *device, const void *byte_code, SIZE_T byte_code_length,
669 struct d3d11_hull_shader **shader)
671 struct d3d11_hull_shader *object;
672 HRESULT hr;
674 if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
675 return E_OUTOFMEMORY;
677 if (FAILED(hr = d3d11_hull_shader_init(object, device, byte_code, byte_code_length)))
679 HeapFree(GetProcessHeap(), 0, object);
680 return hr;
683 TRACE("Created hull shader %p.\n", object);
684 *shader = object;
686 return S_OK;
689 /* ID3D11DomainShader methods */
691 static inline struct d3d11_domain_shader *impl_from_ID3D11DomainShader(ID3D11DomainShader *iface)
693 return CONTAINING_RECORD(iface, struct d3d11_domain_shader, ID3D11DomainShader_iface);
696 static HRESULT STDMETHODCALLTYPE d3d11_domain_shader_QueryInterface(ID3D11DomainShader *iface,
697 REFIID riid, void **object)
699 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
701 if (IsEqualGUID(riid, &IID_ID3D11DomainShader)
702 || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
703 || IsEqualGUID(riid, &IID_IUnknown))
705 ID3D11DomainShader_AddRef(iface);
706 *object = iface;
707 return S_OK;
710 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
712 *object = NULL;
713 return E_NOINTERFACE;
716 static ULONG STDMETHODCALLTYPE d3d11_domain_shader_AddRef(ID3D11DomainShader *iface)
718 struct d3d11_domain_shader *shader = impl_from_ID3D11DomainShader(iface);
719 ULONG refcount = InterlockedIncrement(&shader->refcount);
721 TRACE("%p increasing refcount to %u.\n", shader, refcount);
723 return refcount;
726 static ULONG STDMETHODCALLTYPE d3d11_domain_shader_Release(ID3D11DomainShader *iface)
728 struct d3d11_domain_shader *shader = impl_from_ID3D11DomainShader(iface);
729 ULONG refcount = InterlockedDecrement(&shader->refcount);
731 TRACE("%p decreasing refcount to %u.\n", shader, refcount);
733 if (!refcount)
735 ID3D11Device *device = shader->device;
737 wined3d_mutex_lock();
738 wined3d_shader_decref(shader->wined3d_shader);
739 wined3d_mutex_unlock();
741 /* Release the device last, it may cause the wined3d device to be
742 * destroyed. */
743 ID3D11Device_Release(device);
746 return refcount;
749 static void STDMETHODCALLTYPE d3d11_domain_shader_GetDevice(ID3D11DomainShader *iface,
750 ID3D11Device **device)
752 struct d3d11_domain_shader *shader = impl_from_ID3D11DomainShader(iface);
754 TRACE("iface %p, device %p.\n", iface, device);
756 *device = shader->device;
757 ID3D11Device_AddRef(*device);
760 static HRESULT STDMETHODCALLTYPE d3d11_domain_shader_GetPrivateData(ID3D11DomainShader *iface,
761 REFGUID guid, UINT *data_size, void *data)
763 struct d3d11_domain_shader *shader = impl_from_ID3D11DomainShader(iface);
765 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
767 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
770 static HRESULT STDMETHODCALLTYPE d3d11_domain_shader_SetPrivateData(ID3D11DomainShader *iface,
771 REFGUID guid, UINT data_size, const void *data)
773 struct d3d11_domain_shader *shader = impl_from_ID3D11DomainShader(iface);
775 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
777 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
780 static HRESULT STDMETHODCALLTYPE d3d11_domain_shader_SetPrivateDataInterface(ID3D11DomainShader *iface,
781 REFGUID guid, const IUnknown *data)
783 struct d3d11_domain_shader *shader = impl_from_ID3D11DomainShader(iface);
785 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
787 return d3d_set_private_data_interface(&shader->private_store, guid, data);
790 static const struct ID3D11DomainShaderVtbl d3d11_domain_shader_vtbl =
792 /* IUnknown methods */
793 d3d11_domain_shader_QueryInterface,
794 d3d11_domain_shader_AddRef,
795 d3d11_domain_shader_Release,
796 /* ID3D11DeviceChild methods */
797 d3d11_domain_shader_GetDevice,
798 d3d11_domain_shader_GetPrivateData,
799 d3d11_domain_shader_SetPrivateData,
800 d3d11_domain_shader_SetPrivateDataInterface,
803 static void STDMETHODCALLTYPE d3d11_domain_shader_wined3d_object_destroyed(void *parent)
805 struct d3d11_domain_shader *shader = parent;
807 wined3d_private_store_cleanup(&shader->private_store);
808 HeapFree(GetProcessHeap(), 0, parent);
811 static const struct wined3d_parent_ops d3d11_domain_shader_wined3d_parent_ops =
813 d3d11_domain_shader_wined3d_object_destroyed,
816 static HRESULT d3d11_domain_shader_init(struct d3d11_domain_shader *shader, struct d3d_device *device,
817 const void *byte_code, SIZE_T byte_code_length)
819 struct wined3d_shader_desc desc;
820 HRESULT hr;
822 shader->ID3D11DomainShader_iface.lpVtbl = &d3d11_domain_shader_vtbl;
823 shader->refcount = 1;
824 wined3d_mutex_lock();
825 wined3d_private_store_init(&shader->private_store);
827 if (FAILED(hr = shader_extract_from_dxbc(byte_code, byte_code_length, &desc)))
829 WARN("Failed to extract shader, hr %#x.\n", hr);
830 wined3d_private_store_cleanup(&shader->private_store);
831 wined3d_mutex_unlock();
832 return hr;
834 desc.max_version = d3d_sm_from_feature_level(device->feature_level);
836 hr = wined3d_shader_create_ds(device->wined3d_device, &desc, shader,
837 &d3d11_domain_shader_wined3d_parent_ops, &shader->wined3d_shader);
838 shader_free_signature(&desc.input_signature);
839 shader_free_signature(&desc.output_signature);
840 if (FAILED(hr))
842 WARN("Failed to create wined3d domain shader, hr %#x.\n", hr);
843 wined3d_private_store_cleanup(&shader->private_store);
844 wined3d_mutex_unlock();
845 return E_INVALIDARG;
847 wined3d_mutex_unlock();
849 shader->device = &device->ID3D11Device_iface;
850 ID3D11Device_AddRef(shader->device);
852 return S_OK;
855 HRESULT d3d11_domain_shader_create(struct d3d_device *device, const void *byte_code, SIZE_T byte_code_length,
856 struct d3d11_domain_shader **shader)
858 struct d3d11_domain_shader *object;
859 HRESULT hr;
861 if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
862 return E_OUTOFMEMORY;
864 if (FAILED(hr = d3d11_domain_shader_init(object, device, byte_code, byte_code_length)))
866 HeapFree(GetProcessHeap(), 0, object);
867 return hr;
870 TRACE("Created domain shader %p.\n", object);
871 *shader = object;
873 return S_OK;
876 /* ID3D11GeometryShader methods */
878 static inline struct d3d_geometry_shader *impl_from_ID3D11GeometryShader(ID3D11GeometryShader *iface)
880 return CONTAINING_RECORD(iface, struct d3d_geometry_shader, ID3D11GeometryShader_iface);
883 static HRESULT STDMETHODCALLTYPE d3d11_geometry_shader_QueryInterface(ID3D11GeometryShader *iface,
884 REFIID riid, void **object)
886 struct d3d_geometry_shader *shader = impl_from_ID3D11GeometryShader(iface);
888 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
890 if (IsEqualGUID(riid, &IID_ID3D11GeometryShader)
891 || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
892 || IsEqualGUID(riid, &IID_IUnknown))
894 ID3D11GeometryShader_AddRef(iface);
895 *object = iface;
896 return S_OK;
899 if (IsEqualGUID(riid, &IID_ID3D10GeometryShader)
900 || IsEqualGUID(riid, &IID_ID3D10DeviceChild))
902 ID3D10GeometryShader_AddRef(&shader->ID3D10GeometryShader_iface);
903 *object = &shader->ID3D10GeometryShader_iface;
904 return S_OK;
907 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
909 *object = NULL;
910 return E_NOINTERFACE;
913 static ULONG STDMETHODCALLTYPE d3d11_geometry_shader_AddRef(ID3D11GeometryShader *iface)
915 struct d3d_geometry_shader *shader = impl_from_ID3D11GeometryShader(iface);
916 ULONG refcount = InterlockedIncrement(&shader->refcount);
918 TRACE("%p increasing refcount to %u.\n", shader, refcount);
920 return refcount;
923 static ULONG STDMETHODCALLTYPE d3d11_geometry_shader_Release(ID3D11GeometryShader *iface)
925 struct d3d_geometry_shader *shader = impl_from_ID3D11GeometryShader(iface);
926 ULONG refcount = InterlockedDecrement(&shader->refcount);
928 TRACE("%p decreasing refcount to %u.\n", shader, refcount);
930 if (!refcount)
932 ID3D11Device *device = shader->device;
934 wined3d_mutex_lock();
935 wined3d_shader_decref(shader->wined3d_shader);
936 wined3d_mutex_unlock();
938 /* Release the device last, it may cause the wined3d device to be
939 * destroyed. */
940 ID3D11Device_Release(device);
943 return refcount;
946 static void STDMETHODCALLTYPE d3d11_geometry_shader_GetDevice(ID3D11GeometryShader *iface,
947 ID3D11Device **device)
949 struct d3d_geometry_shader *shader = impl_from_ID3D11GeometryShader(iface);
951 TRACE("iface %p, device %p.\n", iface, device);
953 *device = shader->device;
954 ID3D11Device_AddRef(*device);
957 static HRESULT STDMETHODCALLTYPE d3d11_geometry_shader_GetPrivateData(ID3D11GeometryShader *iface,
958 REFGUID guid, UINT *data_size, void *data)
960 struct d3d_geometry_shader *shader = impl_from_ID3D11GeometryShader(iface);
962 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
964 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
967 static HRESULT STDMETHODCALLTYPE d3d11_geometry_shader_SetPrivateData(ID3D11GeometryShader *iface,
968 REFGUID guid, UINT data_size, const void *data)
970 struct d3d_geometry_shader *shader = impl_from_ID3D11GeometryShader(iface);
972 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
974 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
977 static HRESULT STDMETHODCALLTYPE d3d11_geometry_shader_SetPrivateDataInterface(ID3D11GeometryShader *iface,
978 REFGUID guid, const IUnknown *data)
980 struct d3d_geometry_shader *shader = impl_from_ID3D11GeometryShader(iface);
982 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
984 return d3d_set_private_data_interface(&shader->private_store, guid, data);
987 static const struct ID3D11GeometryShaderVtbl d3d11_geometry_shader_vtbl =
989 /* IUnknown methods */
990 d3d11_geometry_shader_QueryInterface,
991 d3d11_geometry_shader_AddRef,
992 d3d11_geometry_shader_Release,
993 /* ID3D11DeviceChild methods */
994 d3d11_geometry_shader_GetDevice,
995 d3d11_geometry_shader_GetPrivateData,
996 d3d11_geometry_shader_SetPrivateData,
997 d3d11_geometry_shader_SetPrivateDataInterface,
1000 /* ID3D10GeometryShader methods */
1002 static inline struct d3d_geometry_shader *impl_from_ID3D10GeometryShader(ID3D10GeometryShader *iface)
1004 return CONTAINING_RECORD(iface, struct d3d_geometry_shader, ID3D10GeometryShader_iface);
1007 /* IUnknown methods */
1009 static HRESULT STDMETHODCALLTYPE d3d10_geometry_shader_QueryInterface(ID3D10GeometryShader *iface,
1010 REFIID riid, void **object)
1012 struct d3d_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface);
1014 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
1016 return d3d11_geometry_shader_QueryInterface(&shader->ID3D11GeometryShader_iface, riid, object);
1019 static ULONG STDMETHODCALLTYPE d3d10_geometry_shader_AddRef(ID3D10GeometryShader *iface)
1021 struct d3d_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface);
1023 TRACE("iface %p.\n", iface);
1025 return d3d11_geometry_shader_AddRef(&shader->ID3D11GeometryShader_iface);
1028 static ULONG STDMETHODCALLTYPE d3d10_geometry_shader_Release(ID3D10GeometryShader *iface)
1030 struct d3d_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface);
1032 TRACE("iface %p.\n", iface);
1034 return d3d11_geometry_shader_Release(&shader->ID3D11GeometryShader_iface);
1037 /* ID3D10DeviceChild methods */
1039 static void STDMETHODCALLTYPE d3d10_geometry_shader_GetDevice(ID3D10GeometryShader *iface, ID3D10Device **device)
1041 struct d3d_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface);
1043 TRACE("iface %p, device %p.\n", iface, device);
1045 ID3D11Device_QueryInterface(shader->device, &IID_ID3D10Device, (void **)device);
1048 static HRESULT STDMETHODCALLTYPE d3d10_geometry_shader_GetPrivateData(ID3D10GeometryShader *iface,
1049 REFGUID guid, UINT *data_size, void *data)
1051 struct d3d_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface);
1053 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
1054 iface, debugstr_guid(guid), data_size, data);
1056 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
1059 static HRESULT STDMETHODCALLTYPE d3d10_geometry_shader_SetPrivateData(ID3D10GeometryShader *iface,
1060 REFGUID guid, UINT data_size, const void *data)
1062 struct d3d_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface);
1064 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
1065 iface, debugstr_guid(guid), data_size, data);
1067 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
1070 static HRESULT STDMETHODCALLTYPE d3d10_geometry_shader_SetPrivateDataInterface(ID3D10GeometryShader *iface,
1071 REFGUID guid, const IUnknown *data)
1073 struct d3d_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface);
1075 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
1077 return d3d_set_private_data_interface(&shader->private_store, guid, data);
1080 static const struct ID3D10GeometryShaderVtbl d3d10_geometry_shader_vtbl =
1082 /* IUnknown methods */
1083 d3d10_geometry_shader_QueryInterface,
1084 d3d10_geometry_shader_AddRef,
1085 d3d10_geometry_shader_Release,
1086 /* ID3D10DeviceChild methods */
1087 d3d10_geometry_shader_GetDevice,
1088 d3d10_geometry_shader_GetPrivateData,
1089 d3d10_geometry_shader_SetPrivateData,
1090 d3d10_geometry_shader_SetPrivateDataInterface,
1093 static void STDMETHODCALLTYPE d3d_geometry_shader_wined3d_object_destroyed(void *parent)
1095 struct d3d_geometry_shader *shader = parent;
1097 wined3d_private_store_cleanup(&shader->private_store);
1098 HeapFree(GetProcessHeap(), 0, parent);
1101 static const struct wined3d_parent_ops d3d_geometry_shader_wined3d_parent_ops =
1103 d3d_geometry_shader_wined3d_object_destroyed,
1106 static HRESULT d3d_geometry_shader_init(struct d3d_geometry_shader *shader, struct d3d_device *device,
1107 const void *byte_code, SIZE_T byte_code_length)
1109 struct wined3d_shader_desc desc;
1110 HRESULT hr;
1112 shader->ID3D11GeometryShader_iface.lpVtbl = &d3d11_geometry_shader_vtbl;
1113 shader->ID3D10GeometryShader_iface.lpVtbl = &d3d10_geometry_shader_vtbl;
1114 shader->refcount = 1;
1115 wined3d_mutex_lock();
1116 wined3d_private_store_init(&shader->private_store);
1118 if (FAILED(hr = shader_extract_from_dxbc(byte_code, byte_code_length, &desc)))
1120 WARN("Failed to extract shader, hr %#x.\n", hr);
1121 wined3d_private_store_cleanup(&shader->private_store);
1122 wined3d_mutex_unlock();
1123 return hr;
1125 desc.max_version = d3d_sm_from_feature_level(device->feature_level);
1127 hr = wined3d_shader_create_gs(device->wined3d_device, &desc, shader,
1128 &d3d_geometry_shader_wined3d_parent_ops, &shader->wined3d_shader);
1129 shader_free_signature(&desc.input_signature);
1130 shader_free_signature(&desc.output_signature);
1131 if (FAILED(hr))
1133 WARN("Failed to create wined3d geometry shader, hr %#x.\n", hr);
1134 wined3d_private_store_cleanup(&shader->private_store);
1135 wined3d_mutex_unlock();
1136 return E_INVALIDARG;
1138 wined3d_mutex_unlock();
1140 shader->device = &device->ID3D11Device_iface;
1141 ID3D11Device_AddRef(shader->device);
1143 return S_OK;
1146 HRESULT d3d_geometry_shader_create(struct d3d_device *device, const void *byte_code, SIZE_T byte_code_length,
1147 struct d3d_geometry_shader **shader)
1149 struct d3d_geometry_shader *object;
1150 HRESULT hr;
1152 if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
1153 return E_OUTOFMEMORY;
1155 if (FAILED(hr = d3d_geometry_shader_init(object, device, byte_code, byte_code_length)))
1157 WARN("Failed to initialize geometry shader, hr %#x.\n", hr);
1158 HeapFree(GetProcessHeap(), 0, object);
1159 return hr;
1162 TRACE("Created geometry shader %p.\n", object);
1163 *shader = object;
1165 return S_OK;
1168 struct d3d_geometry_shader *unsafe_impl_from_ID3D11GeometryShader(ID3D11GeometryShader *iface)
1170 if (!iface)
1171 return NULL;
1172 assert(iface->lpVtbl == &d3d11_geometry_shader_vtbl);
1174 return impl_from_ID3D11GeometryShader(iface);
1177 struct d3d_geometry_shader *unsafe_impl_from_ID3D10GeometryShader(ID3D10GeometryShader *iface)
1179 if (!iface)
1180 return NULL;
1181 assert(iface->lpVtbl == &d3d10_geometry_shader_vtbl);
1183 return impl_from_ID3D10GeometryShader(iface);
1186 /* ID3D11PixelShader methods */
1188 static inline struct d3d_pixel_shader *impl_from_ID3D11PixelShader(ID3D11PixelShader *iface)
1190 return CONTAINING_RECORD(iface, struct d3d_pixel_shader, ID3D11PixelShader_iface);
1193 static HRESULT STDMETHODCALLTYPE d3d11_pixel_shader_QueryInterface(ID3D11PixelShader *iface,
1194 REFIID riid, void **object)
1196 struct d3d_pixel_shader *shader = impl_from_ID3D11PixelShader(iface);
1198 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
1200 if (IsEqualGUID(riid, &IID_ID3D11PixelShader)
1201 || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
1202 || IsEqualGUID(riid, &IID_IUnknown))
1204 ID3D11PixelShader_AddRef(iface);
1205 *object = iface;
1206 return S_OK;
1209 if (IsEqualGUID(riid, &IID_ID3D10PixelShader)
1210 || IsEqualGUID(riid, &IID_ID3D10DeviceChild))
1212 IUnknown_AddRef(&shader->ID3D10PixelShader_iface);
1213 *object = &shader->ID3D10PixelShader_iface;
1214 return S_OK;
1217 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
1219 *object = NULL;
1220 return E_NOINTERFACE;
1223 static ULONG STDMETHODCALLTYPE d3d11_pixel_shader_AddRef(ID3D11PixelShader *iface)
1225 struct d3d_pixel_shader *shader = impl_from_ID3D11PixelShader(iface);
1226 ULONG refcount = InterlockedIncrement(&shader->refcount);
1228 TRACE("%p increasing refcount to %u.\n", shader, refcount);
1230 if (refcount == 1)
1232 ID3D11Device_AddRef(shader->device);
1233 wined3d_mutex_lock();
1234 wined3d_shader_incref(shader->wined3d_shader);
1235 wined3d_mutex_unlock();
1238 return refcount;
1241 static ULONG STDMETHODCALLTYPE d3d11_pixel_shader_Release(ID3D11PixelShader *iface)
1243 struct d3d_pixel_shader *shader = impl_from_ID3D11PixelShader(iface);
1244 ULONG refcount = InterlockedDecrement(&shader->refcount);
1246 TRACE("%p decreasing refcount to %u.\n", shader, refcount);
1248 if (!refcount)
1250 ID3D11Device *device = shader->device;
1252 wined3d_mutex_lock();
1253 wined3d_shader_decref(shader->wined3d_shader);
1254 wined3d_mutex_unlock();
1255 /* Release the device last, it may cause the wined3d device to be
1256 * destroyed. */
1257 ID3D11Device_Release(device);
1260 return refcount;
1263 static void STDMETHODCALLTYPE d3d11_pixel_shader_GetDevice(ID3D11PixelShader *iface,
1264 ID3D11Device **device)
1266 struct d3d_pixel_shader *shader = impl_from_ID3D11PixelShader(iface);
1268 TRACE("iface %p, device %p.\n", iface, device);
1270 *device = shader->device;
1271 ID3D11Device_AddRef(*device);
1274 static HRESULT STDMETHODCALLTYPE d3d11_pixel_shader_GetPrivateData(ID3D11PixelShader *iface,
1275 REFGUID guid, UINT *data_size, void *data)
1277 struct d3d_pixel_shader *shader = impl_from_ID3D11PixelShader(iface);
1279 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
1281 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
1284 static HRESULT STDMETHODCALLTYPE d3d11_pixel_shader_SetPrivateData(ID3D11PixelShader *iface,
1285 REFGUID guid, UINT data_size, const void *data)
1287 struct d3d_pixel_shader *shader = impl_from_ID3D11PixelShader(iface);
1289 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
1291 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
1294 static HRESULT STDMETHODCALLTYPE d3d11_pixel_shader_SetPrivateDataInterface(ID3D11PixelShader *iface,
1295 REFGUID guid, const IUnknown *data)
1297 struct d3d_pixel_shader *shader = impl_from_ID3D11PixelShader(iface);
1299 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
1301 return d3d_set_private_data_interface(&shader->private_store, guid, data);
1304 static const struct ID3D11PixelShaderVtbl d3d11_pixel_shader_vtbl =
1306 /* IUnknown methods */
1307 d3d11_pixel_shader_QueryInterface,
1308 d3d11_pixel_shader_AddRef,
1309 d3d11_pixel_shader_Release,
1310 /* ID3D11DeviceChild methods */
1311 d3d11_pixel_shader_GetDevice,
1312 d3d11_pixel_shader_GetPrivateData,
1313 d3d11_pixel_shader_SetPrivateData,
1314 d3d11_pixel_shader_SetPrivateDataInterface,
1317 /* ID3D10PixelShader methods */
1319 static inline struct d3d_pixel_shader *impl_from_ID3D10PixelShader(ID3D10PixelShader *iface)
1321 return CONTAINING_RECORD(iface, struct d3d_pixel_shader, ID3D10PixelShader_iface);
1324 /* IUnknown methods */
1326 static HRESULT STDMETHODCALLTYPE d3d10_pixel_shader_QueryInterface(ID3D10PixelShader *iface,
1327 REFIID riid, void **object)
1329 struct d3d_pixel_shader *shader = impl_from_ID3D10PixelShader(iface);
1331 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
1333 return d3d11_pixel_shader_QueryInterface(&shader->ID3D11PixelShader_iface, riid, object);
1336 static ULONG STDMETHODCALLTYPE d3d10_pixel_shader_AddRef(ID3D10PixelShader *iface)
1338 struct d3d_pixel_shader *shader = impl_from_ID3D10PixelShader(iface);
1340 TRACE("iface %p.\n", iface);
1342 return d3d11_pixel_shader_AddRef(&shader->ID3D11PixelShader_iface);
1345 static ULONG STDMETHODCALLTYPE d3d10_pixel_shader_Release(ID3D10PixelShader *iface)
1347 struct d3d_pixel_shader *shader = impl_from_ID3D10PixelShader(iface);
1349 TRACE("iface %p.\n", iface);
1351 return d3d11_pixel_shader_Release(&shader->ID3D11PixelShader_iface);
1354 /* ID3D10DeviceChild methods */
1356 static void STDMETHODCALLTYPE d3d10_pixel_shader_GetDevice(ID3D10PixelShader *iface, ID3D10Device **device)
1358 struct d3d_pixel_shader *shader = impl_from_ID3D10PixelShader(iface);
1360 TRACE("iface %p, device %p.\n", iface, device);
1362 ID3D11Device_QueryInterface(shader->device, &IID_ID3D10Device, (void **)device);
1365 static HRESULT STDMETHODCALLTYPE d3d10_pixel_shader_GetPrivateData(ID3D10PixelShader *iface,
1366 REFGUID guid, UINT *data_size, void *data)
1368 struct d3d_pixel_shader *shader = impl_from_ID3D10PixelShader(iface);
1370 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
1371 iface, debugstr_guid(guid), data_size, data);
1373 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
1376 static HRESULT STDMETHODCALLTYPE d3d10_pixel_shader_SetPrivateData(ID3D10PixelShader *iface,
1377 REFGUID guid, UINT data_size, const void *data)
1379 struct d3d_pixel_shader *shader = impl_from_ID3D10PixelShader(iface);
1381 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
1382 iface, debugstr_guid(guid), data_size, data);
1384 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
1387 static HRESULT STDMETHODCALLTYPE d3d10_pixel_shader_SetPrivateDataInterface(ID3D10PixelShader *iface,
1388 REFGUID guid, const IUnknown *data)
1390 struct d3d_pixel_shader *shader = impl_from_ID3D10PixelShader(iface);
1392 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
1394 return d3d_set_private_data_interface(&shader->private_store, guid, data);
1397 static const struct ID3D10PixelShaderVtbl d3d10_pixel_shader_vtbl =
1399 /* IUnknown methods */
1400 d3d10_pixel_shader_QueryInterface,
1401 d3d10_pixel_shader_AddRef,
1402 d3d10_pixel_shader_Release,
1403 /* ID3D10DeviceChild methods */
1404 d3d10_pixel_shader_GetDevice,
1405 d3d10_pixel_shader_GetPrivateData,
1406 d3d10_pixel_shader_SetPrivateData,
1407 d3d10_pixel_shader_SetPrivateDataInterface,
1410 static void STDMETHODCALLTYPE d3d_pixel_shader_wined3d_object_destroyed(void *parent)
1412 struct d3d_pixel_shader *shader = parent;
1414 wined3d_private_store_cleanup(&shader->private_store);
1415 HeapFree(GetProcessHeap(), 0, parent);
1418 static const struct wined3d_parent_ops d3d_pixel_shader_wined3d_parent_ops =
1420 d3d_pixel_shader_wined3d_object_destroyed,
1423 static HRESULT d3d_pixel_shader_init(struct d3d_pixel_shader *shader, struct d3d_device *device,
1424 const void *byte_code, SIZE_T byte_code_length)
1426 struct wined3d_shader_desc desc;
1427 HRESULT hr;
1429 shader->ID3D11PixelShader_iface.lpVtbl = &d3d11_pixel_shader_vtbl;
1430 shader->ID3D10PixelShader_iface.lpVtbl = &d3d10_pixel_shader_vtbl;
1431 shader->refcount = 1;
1432 wined3d_mutex_lock();
1433 wined3d_private_store_init(&shader->private_store);
1435 if (FAILED(hr = shader_extract_from_dxbc(byte_code, byte_code_length, &desc)))
1437 WARN("Failed to extract shader, hr %#x.\n", hr);
1438 wined3d_private_store_cleanup(&shader->private_store);
1439 wined3d_mutex_unlock();
1440 return hr;
1442 desc.max_version = d3d_sm_from_feature_level(device->feature_level);
1444 hr = wined3d_shader_create_ps(device->wined3d_device, &desc, shader,
1445 &d3d_pixel_shader_wined3d_parent_ops, &shader->wined3d_shader);
1446 shader_free_signature(&desc.input_signature);
1447 shader_free_signature(&desc.output_signature);
1448 if (FAILED(hr))
1450 WARN("Failed to create wined3d pixel shader, hr %#x.\n", hr);
1451 wined3d_private_store_cleanup(&shader->private_store);
1452 wined3d_mutex_unlock();
1453 return E_INVALIDARG;
1455 wined3d_mutex_unlock();
1457 shader->device = &device->ID3D11Device_iface;
1458 ID3D11Device_AddRef(shader->device);
1460 return S_OK;
1463 HRESULT d3d_pixel_shader_create(struct d3d_device *device, const void *byte_code, SIZE_T byte_code_length,
1464 struct d3d_pixel_shader **shader)
1466 struct d3d_pixel_shader *object;
1467 HRESULT hr;
1469 if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
1470 return E_OUTOFMEMORY;
1472 if (FAILED(hr = d3d_pixel_shader_init(object, device, byte_code, byte_code_length)))
1474 WARN("Failed to initialize pixel shader, hr %#x.\n", hr);
1475 HeapFree(GetProcessHeap(), 0, object);
1476 return hr;
1479 TRACE("Created pixel shader %p.\n", object);
1480 *shader = object;
1482 return S_OK;
1485 struct d3d_pixel_shader *unsafe_impl_from_ID3D11PixelShader(ID3D11PixelShader *iface)
1487 if (!iface)
1488 return NULL;
1489 assert(iface->lpVtbl == &d3d11_pixel_shader_vtbl);
1491 return impl_from_ID3D11PixelShader(iface);
1494 struct d3d_pixel_shader *unsafe_impl_from_ID3D10PixelShader(ID3D10PixelShader *iface)
1496 if (!iface)
1497 return NULL;
1498 assert(iface->lpVtbl == &d3d10_pixel_shader_vtbl);
1500 return impl_from_ID3D10PixelShader(iface);
1503 /* ID3D11ComputeShader methods */
1505 static inline struct d3d11_compute_shader *impl_from_ID3D11ComputeShader(ID3D11ComputeShader *iface)
1507 return CONTAINING_RECORD(iface, struct d3d11_compute_shader, ID3D11ComputeShader_iface);
1510 static HRESULT STDMETHODCALLTYPE d3d11_compute_shader_QueryInterface(ID3D11ComputeShader *iface,
1511 REFIID riid, void **object)
1513 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
1515 if (IsEqualGUID(riid, &IID_ID3D11ComputeShader)
1516 || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
1517 || IsEqualGUID(riid, &IID_IUnknown))
1519 ID3D11ComputeShader_AddRef(*object = iface);
1520 return S_OK;
1523 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
1525 *object = NULL;
1526 return E_NOINTERFACE;
1529 static ULONG STDMETHODCALLTYPE d3d11_compute_shader_AddRef(ID3D11ComputeShader *iface)
1531 struct d3d11_compute_shader *shader = impl_from_ID3D11ComputeShader(iface);
1532 ULONG refcount = InterlockedIncrement(&shader->refcount);
1534 TRACE("%p increasing refcount to %u.\n", shader, refcount);
1536 return refcount;
1539 static ULONG STDMETHODCALLTYPE d3d11_compute_shader_Release(ID3D11ComputeShader *iface)
1541 struct d3d11_compute_shader *shader = impl_from_ID3D11ComputeShader(iface);
1542 ULONG refcount = InterlockedDecrement(&shader->refcount);
1544 TRACE("%p decreasing refcount to %u.\n", shader, refcount);
1546 if (!refcount)
1548 ID3D11Device *device = shader->device;
1550 wined3d_mutex_lock();
1551 wined3d_shader_decref(shader->wined3d_shader);
1552 wined3d_mutex_unlock();
1554 /* Release the device last, it may cause the wined3d device to be
1555 * destroyed. */
1556 ID3D11Device_Release(device);
1559 return refcount;
1562 static void STDMETHODCALLTYPE d3d11_compute_shader_GetDevice(ID3D11ComputeShader *iface,
1563 ID3D11Device **device)
1565 struct d3d11_compute_shader *shader = impl_from_ID3D11ComputeShader(iface);
1567 TRACE("iface %p, device %p.\n", iface, device);
1569 ID3D11Device_AddRef(*device = shader->device);
1572 static HRESULT STDMETHODCALLTYPE d3d11_compute_shader_GetPrivateData(ID3D11ComputeShader *iface,
1573 REFGUID guid, UINT *data_size, void *data)
1575 struct d3d11_compute_shader *shader = impl_from_ID3D11ComputeShader(iface);
1577 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
1579 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
1582 static HRESULT STDMETHODCALLTYPE d3d11_compute_shader_SetPrivateData(ID3D11ComputeShader *iface,
1583 REFGUID guid, UINT data_size, const void *data)
1585 struct d3d11_compute_shader *shader = impl_from_ID3D11ComputeShader(iface);
1587 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
1589 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
1592 static HRESULT STDMETHODCALLTYPE d3d11_compute_shader_SetPrivateDataInterface(ID3D11ComputeShader *iface,
1593 REFGUID guid, const IUnknown *data)
1595 struct d3d11_compute_shader *shader = impl_from_ID3D11ComputeShader(iface);
1597 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
1599 return d3d_set_private_data_interface(&shader->private_store, guid, data);
1602 static const struct ID3D11ComputeShaderVtbl d3d11_compute_shader_vtbl =
1604 /* IUnknown methods */
1605 d3d11_compute_shader_QueryInterface,
1606 d3d11_compute_shader_AddRef,
1607 d3d11_compute_shader_Release,
1608 /* ID3D11DeviceChild methods */
1609 d3d11_compute_shader_GetDevice,
1610 d3d11_compute_shader_GetPrivateData,
1611 d3d11_compute_shader_SetPrivateData,
1612 d3d11_compute_shader_SetPrivateDataInterface,
1615 static void STDMETHODCALLTYPE d3d11_compute_shader_wined3d_object_destroyed(void *parent)
1617 struct d3d11_compute_shader *shader = parent;
1619 wined3d_private_store_cleanup(&shader->private_store);
1620 HeapFree(GetProcessHeap(), 0, parent);
1623 static const struct wined3d_parent_ops d3d11_compute_shader_wined3d_parent_ops =
1625 d3d11_compute_shader_wined3d_object_destroyed,
1628 static HRESULT d3d11_compute_shader_init(struct d3d11_compute_shader *shader, struct d3d_device *device,
1629 const void *byte_code, SIZE_T byte_code_length)
1631 struct wined3d_shader_desc desc;
1632 HRESULT hr;
1634 shader->ID3D11ComputeShader_iface.lpVtbl = &d3d11_compute_shader_vtbl;
1635 shader->refcount = 1;
1636 wined3d_mutex_lock();
1637 wined3d_private_store_init(&shader->private_store);
1639 if (FAILED(hr = shader_extract_from_dxbc(byte_code, byte_code_length, &desc)))
1641 WARN("Failed to extract shader, hr %#x.\n", hr);
1642 wined3d_private_store_cleanup(&shader->private_store);
1643 wined3d_mutex_unlock();
1644 return hr;
1646 desc.max_version = d3d_sm_from_feature_level(device->feature_level);
1648 hr = wined3d_shader_create_cs(device->wined3d_device, &desc, shader,
1649 &d3d11_compute_shader_wined3d_parent_ops, &shader->wined3d_shader);
1650 shader_free_signature(&desc.input_signature);
1651 shader_free_signature(&desc.output_signature);
1652 if (FAILED(hr))
1654 WARN("Failed to create wined3d compute shader, hr %#x.\n", hr);
1655 wined3d_private_store_cleanup(&shader->private_store);
1656 wined3d_mutex_unlock();
1657 return E_INVALIDARG;
1659 wined3d_mutex_unlock();
1661 ID3D11Device_AddRef(shader->device = &device->ID3D11Device_iface);
1663 return S_OK;
1666 HRESULT d3d11_compute_shader_create(struct d3d_device *device, const void *byte_code, SIZE_T byte_code_length,
1667 struct d3d11_compute_shader **shader)
1669 struct d3d11_compute_shader *object;
1670 HRESULT hr;
1672 if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
1673 return E_OUTOFMEMORY;
1675 if (FAILED(hr = d3d11_compute_shader_init(object, device, byte_code, byte_code_length)))
1677 HeapFree(GetProcessHeap(), 0, object);
1678 return hr;
1681 TRACE("Created compute shader %p.\n", object);
1682 *shader = object;
1684 return S_OK;
1687 /* ID3D11ClassLinkage methods */
1689 static inline struct d3d11_class_linkage *impl_from_ID3D11ClassLinkage(ID3D11ClassLinkage *iface)
1691 return CONTAINING_RECORD(iface, struct d3d11_class_linkage, ID3D11ClassLinkage_iface);
1694 static HRESULT STDMETHODCALLTYPE d3d11_class_linkage_QueryInterface(ID3D11ClassLinkage *iface,
1695 REFIID riid, void **object)
1697 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
1699 if (IsEqualGUID(riid, &IID_ID3D11ClassLinkage)
1700 || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
1701 || IsEqualGUID(riid, &IID_IUnknown))
1703 ID3D11ClassLinkage_AddRef(*object = iface);
1704 return S_OK;
1707 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
1709 *object = NULL;
1710 return E_NOINTERFACE;
1713 static ULONG STDMETHODCALLTYPE d3d11_class_linkage_AddRef(ID3D11ClassLinkage *iface)
1715 struct d3d11_class_linkage *class_linkage = impl_from_ID3D11ClassLinkage(iface);
1716 ULONG refcount = InterlockedIncrement(&class_linkage->refcount);
1718 TRACE("%p increasing refcount to %u.\n", class_linkage, refcount);
1720 return refcount;
1723 static ULONG STDMETHODCALLTYPE d3d11_class_linkage_Release(ID3D11ClassLinkage *iface)
1725 struct d3d11_class_linkage *class_linkage = impl_from_ID3D11ClassLinkage(iface);
1726 ULONG refcount = InterlockedDecrement(&class_linkage->refcount);
1728 TRACE("%p decreasing refcount to %u.\n", class_linkage, refcount);
1730 if (!refcount)
1732 wined3d_private_store_cleanup(&class_linkage->private_store);
1733 HeapFree(GetProcessHeap(), 0, class_linkage);
1736 return refcount;
1739 static void STDMETHODCALLTYPE d3d11_class_linkage_GetDevice(ID3D11ClassLinkage *iface,
1740 ID3D11Device **device)
1742 FIXME("iface %p, device %p stub!\n", iface, device);
1745 static HRESULT STDMETHODCALLTYPE d3d11_class_linkage_GetPrivateData(ID3D11ClassLinkage *iface,
1746 REFGUID guid, UINT *data_size, void *data)
1748 struct d3d11_class_linkage *class_linkage = impl_from_ID3D11ClassLinkage(iface);
1750 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
1752 return d3d_get_private_data(&class_linkage->private_store, guid, data_size, data);
1755 static HRESULT STDMETHODCALLTYPE d3d11_class_linkage_SetPrivateData(ID3D11ClassLinkage *iface,
1756 REFGUID guid, UINT data_size, const void *data)
1758 struct d3d11_class_linkage *class_linkage = impl_from_ID3D11ClassLinkage(iface);
1760 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
1762 return d3d_set_private_data(&class_linkage->private_store, guid, data_size, data);
1765 static HRESULT STDMETHODCALLTYPE d3d11_class_linkage_SetPrivateDataInterface(ID3D11ClassLinkage *iface,
1766 REFGUID guid, const IUnknown *data)
1768 struct d3d11_class_linkage *class_linkage = impl_from_ID3D11ClassLinkage(iface);
1770 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
1772 return d3d_set_private_data_interface(&class_linkage->private_store, guid, data);
1775 static HRESULT STDMETHODCALLTYPE d3d11_class_linkage_GetClassInstance(ID3D11ClassLinkage *iface,
1776 const char *instance_name, UINT instance_index, ID3D11ClassInstance **class_instance)
1778 FIXME("iface %p, instance_name %s, instance_index %u, class_instance %p stub!\n",
1779 iface, debugstr_a(instance_name), instance_index, class_instance);
1781 return E_NOTIMPL;
1784 static HRESULT STDMETHODCALLTYPE d3d11_class_linkage_CreateClassInstance(ID3D11ClassLinkage *iface,
1785 const char *type_name, UINT cb_offset, UINT cb_vector_offset, UINT texture_offset,
1786 UINT sampler_offset, ID3D11ClassInstance **class_instance)
1788 FIXME("iface %p, type_name %s, cb_offset %u, cb_vector_offset %u, texture_offset %u, "
1789 "sampler_offset %u, class_instance %p stub!\n",
1790 iface, debugstr_a(type_name), cb_offset, cb_vector_offset, texture_offset,
1791 sampler_offset, class_instance);
1793 return E_NOTIMPL;
1796 static const struct ID3D11ClassLinkageVtbl d3d11_class_linkage_vtbl =
1798 /* IUnknown methods */
1799 d3d11_class_linkage_QueryInterface,
1800 d3d11_class_linkage_AddRef,
1801 d3d11_class_linkage_Release,
1802 /* ID3D11DeviceChild methods */
1803 d3d11_class_linkage_GetDevice,
1804 d3d11_class_linkage_GetPrivateData,
1805 d3d11_class_linkage_SetPrivateData,
1806 d3d11_class_linkage_SetPrivateDataInterface,
1807 /* ID3D11ClassLinkage methods */
1808 d3d11_class_linkage_GetClassInstance,
1809 d3d11_class_linkage_CreateClassInstance,
1812 HRESULT d3d11_class_linkage_create(struct d3d_device *device, struct d3d11_class_linkage **class_linkage)
1814 struct d3d11_class_linkage *object;
1816 if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
1817 return E_OUTOFMEMORY;
1819 object->ID3D11ClassLinkage_iface.lpVtbl = &d3d11_class_linkage_vtbl;
1820 object->refcount = 1;
1821 wined3d_private_store_init(&object->private_store);
1823 TRACE("Created class linkage %p.\n", object);
1824 *class_linkage = object;
1826 return S_OK;