po: Update Lithuanian translation.
[wine.git] / dlls / d3d11 / shader.c
blob1da1293adce08b6431b4e8633c5a5deae9983ec7
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 struct aon9_header
29 DWORD chunk_size;
30 DWORD shader_version;
31 DWORD unknown;
32 DWORD byte_code_offset;
35 struct shader_handler_context
37 D3D_FEATURE_LEVEL feature_level;
38 struct wined3d_shader_desc *desc;
41 static HRESULT shdr_handler(const char *data, DWORD data_size, DWORD tag, void *context)
43 const struct shader_handler_context *ctx = context;
44 struct wined3d_shader_desc *desc = ctx->desc;
45 HRESULT hr;
47 switch (tag)
49 case TAG_ISGN:
50 if (ctx->feature_level <= D3D_FEATURE_LEVEL_9_3)
52 TRACE("Skipping shader input signature on feature level %#x.\n", ctx->feature_level);
53 break;
55 if (FAILED(hr = shader_parse_signature(data, data_size, &desc->input_signature)))
56 return hr;
57 break;
59 case TAG_OSGN:
60 if (ctx->feature_level <= D3D_FEATURE_LEVEL_9_3)
62 TRACE("Skipping shader output signature on feature level %#x.\n", ctx->feature_level);
63 break;
65 if (FAILED(hr = shader_parse_signature(data, data_size, &desc->output_signature)))
66 return hr;
67 break;
69 case TAG_SHDR:
70 case TAG_SHEX:
71 if (ctx->feature_level <= D3D_FEATURE_LEVEL_9_3)
73 TRACE("Skipping SM4+ shader code on feature level %#x.\n", ctx->feature_level);
74 break;
76 if (desc->byte_code)
77 FIXME("Multiple shader code chunks.\n");
78 desc->byte_code = (const DWORD *)data;
79 break;
81 case TAG_AON9:
82 if (ctx->feature_level <= D3D_FEATURE_LEVEL_9_3)
84 const struct aon9_header *header = (const struct aon9_header *)data;
85 unsigned int unknown_dword_count;
86 const char *byte_code;
88 if (data_size < sizeof(*header))
90 WARN("Invalid Aon9 data size %#x.\n", data_size);
91 return E_FAIL;
93 byte_code = data + header->byte_code_offset;
94 unknown_dword_count = (header->byte_code_offset - sizeof(*header)) / sizeof(DWORD);
96 if (data_size - 2 * sizeof(DWORD) < header->byte_code_offset)
98 WARN("Invalid byte code offset %#x (size %#x).\n", header->byte_code_offset, data_size);
99 return E_FAIL;
101 FIXME("Skipping %u unknown DWORDs.\n", unknown_dword_count);
103 if (desc->byte_code)
104 FIXME("Multiple shader code chunks.\n");
105 desc->byte_code = (const DWORD *)byte_code;
106 TRACE("Feature level 9 shader version 0%08x, 0%08x.\n", header->shader_version, *desc->byte_code);
108 else
110 TRACE("Skipping feature level 9 shader code on feature level %#x.\n", ctx->feature_level);
112 break;
114 default:
115 FIXME("Unhandled chunk %s.\n", debugstr_an((const char *)&tag, 4));
116 break;
119 return S_OK;
122 static HRESULT shader_extract_from_dxbc(const void *dxbc, SIZE_T dxbc_length, struct wined3d_shader_desc *desc,
123 D3D_FEATURE_LEVEL feature_level)
125 struct shader_handler_context ctx = {feature_level, desc};
126 HRESULT hr;
128 desc->byte_code = NULL;
129 memset(&desc->input_signature, 0, sizeof(desc->input_signature));
130 memset(&desc->output_signature, 0, sizeof(desc->output_signature));
132 hr = parse_dxbc(dxbc, dxbc_length, shdr_handler, &ctx);
133 if (!desc->byte_code)
134 hr = E_INVALIDARG;
136 if (FAILED(hr))
138 FIXME("Failed to parse shader, hr %#x.\n", hr);
139 shader_free_signature(&desc->input_signature);
140 shader_free_signature(&desc->output_signature);
143 return hr;
146 static const char *shader_get_string(const char *data, size_t data_size, DWORD offset)
148 size_t len, max_len;
150 if (offset >= data_size)
152 WARN("Invalid offset %#x (data size %#lx).\n", offset, (long)data_size);
153 return NULL;
156 max_len = data_size - offset;
157 len = strnlen(data + offset, max_len);
159 if (len == max_len)
160 return NULL;
162 return data + offset;
165 HRESULT shader_parse_signature(const char *data, DWORD data_size, struct wined3d_shader_signature *s)
167 struct wined3d_shader_signature_element *e;
168 const char *ptr = data;
169 unsigned int i;
170 DWORD count;
172 if (!require_space(0, 2, sizeof(DWORD), data_size))
174 WARN("Invalid data size %#x.\n", data_size);
175 return E_INVALIDARG;
178 read_dword(&ptr, &count);
179 TRACE("%u elements\n", count);
181 skip_dword_unknown(&ptr, 1);
183 if (!require_space(ptr - data, count, 6 * sizeof(DWORD), data_size))
185 WARN("Invalid count %#x (data size %#x).\n", count, data_size);
186 return E_INVALIDARG;
189 if (!(e = d3d11_calloc(count, sizeof(*e))))
191 ERR("Failed to allocate input signature memory.\n");
192 return E_OUTOFMEMORY;
195 for (i = 0; i < count; ++i)
197 UINT name_offset;
199 read_dword(&ptr, &name_offset);
200 if (!(e[i].semantic_name = shader_get_string(data, data_size, name_offset)))
202 WARN("Invalid name offset %#x (data size %#x).\n", name_offset, data_size);
203 HeapFree(GetProcessHeap(), 0, e);
204 return E_INVALIDARG;
206 read_dword(&ptr, &e[i].semantic_idx);
207 read_dword(&ptr, &e[i].sysval_semantic);
208 read_dword(&ptr, &e[i].component_type);
209 read_dword(&ptr, &e[i].register_idx);
210 read_dword(&ptr, &e[i].mask);
212 TRACE("semantic: %s, semantic idx: %u, sysval_semantic %#x, "
213 "type %u, register idx: %u, use_mask %#x, input_mask %#x\n",
214 debugstr_a(e[i].semantic_name), e[i].semantic_idx, e[i].sysval_semantic,
215 e[i].component_type, e[i].register_idx, (e[i].mask >> 8) & 0xff, e[i].mask & 0xff);
218 s->elements = e;
219 s->element_count = count;
221 return S_OK;
224 void shader_free_signature(struct wined3d_shader_signature *s)
226 HeapFree(GetProcessHeap(), 0, s->elements);
229 /* ID3D11VertexShader methods */
231 static inline struct d3d_vertex_shader *impl_from_ID3D11VertexShader(ID3D11VertexShader *iface)
233 return CONTAINING_RECORD(iface, struct d3d_vertex_shader, ID3D11VertexShader_iface);
236 static HRESULT STDMETHODCALLTYPE d3d11_vertex_shader_QueryInterface(ID3D11VertexShader *iface,
237 REFIID riid, void **object)
239 struct d3d_vertex_shader *shader = impl_from_ID3D11VertexShader(iface);
241 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
243 if (IsEqualGUID(riid, &IID_ID3D11VertexShader)
244 || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
245 || IsEqualGUID(riid, &IID_IUnknown))
247 ID3D11VertexShader_AddRef(iface);
248 *object = iface;
249 return S_OK;
252 if (IsEqualGUID(riid, &IID_ID3D10VertexShader)
253 || IsEqualGUID(riid, &IID_ID3D10DeviceChild))
255 IUnknown_AddRef(&shader->ID3D10VertexShader_iface);
256 *object = &shader->ID3D10VertexShader_iface;
257 return S_OK;
260 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
262 *object = NULL;
263 return E_NOINTERFACE;
266 static ULONG STDMETHODCALLTYPE d3d11_vertex_shader_AddRef(ID3D11VertexShader *iface)
268 struct d3d_vertex_shader *shader = impl_from_ID3D11VertexShader(iface);
269 ULONG refcount = InterlockedIncrement(&shader->refcount);
271 TRACE("%p increasing refcount to %u.\n", shader, refcount);
273 if (refcount == 1)
275 ID3D11Device_AddRef(shader->device);
276 wined3d_mutex_lock();
277 wined3d_shader_incref(shader->wined3d_shader);
278 wined3d_mutex_unlock();
281 return refcount;
284 static ULONG STDMETHODCALLTYPE d3d11_vertex_shader_Release(ID3D11VertexShader *iface)
286 struct d3d_vertex_shader *shader = impl_from_ID3D11VertexShader(iface);
287 ULONG refcount = InterlockedDecrement(&shader->refcount);
289 TRACE("%p decreasing refcount to %u.\n", shader, refcount);
291 if (!refcount)
293 ID3D11Device *device = shader->device;
295 wined3d_mutex_lock();
296 wined3d_shader_decref(shader->wined3d_shader);
297 wined3d_mutex_unlock();
298 /* Release the device last, it may cause the wined3d device to be
299 * destroyed. */
300 ID3D11Device_Release(device);
303 return refcount;
306 static void STDMETHODCALLTYPE d3d11_vertex_shader_GetDevice(ID3D11VertexShader *iface,
307 ID3D11Device **device)
309 struct d3d_vertex_shader *shader = impl_from_ID3D11VertexShader(iface);
311 TRACE("iface %p, device %p.\n", iface, device);
313 *device = shader->device;
314 ID3D11Device_AddRef(*device);
317 static HRESULT STDMETHODCALLTYPE d3d11_vertex_shader_GetPrivateData(ID3D11VertexShader *iface,
318 REFGUID guid, UINT *data_size, void *data)
320 struct d3d_vertex_shader *shader = impl_from_ID3D11VertexShader(iface);
322 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
324 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
327 static HRESULT STDMETHODCALLTYPE d3d11_vertex_shader_SetPrivateData(ID3D11VertexShader *iface,
328 REFGUID guid, UINT data_size, const void *data)
330 struct d3d_vertex_shader *shader = impl_from_ID3D11VertexShader(iface);
332 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
334 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
337 static HRESULT STDMETHODCALLTYPE d3d11_vertex_shader_SetPrivateDataInterface(ID3D11VertexShader *iface,
338 REFGUID guid, const IUnknown *data)
340 struct d3d_vertex_shader *shader = impl_from_ID3D11VertexShader(iface);
342 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
344 return d3d_set_private_data_interface(&shader->private_store, guid, data);
347 static const struct ID3D11VertexShaderVtbl d3d11_vertex_shader_vtbl =
349 /* IUnknown methods */
350 d3d11_vertex_shader_QueryInterface,
351 d3d11_vertex_shader_AddRef,
352 d3d11_vertex_shader_Release,
353 /* ID3D11DeviceChild methods */
354 d3d11_vertex_shader_GetDevice,
355 d3d11_vertex_shader_GetPrivateData,
356 d3d11_vertex_shader_SetPrivateData,
357 d3d11_vertex_shader_SetPrivateDataInterface,
360 /* ID3D10VertexShader methods */
362 static inline struct d3d_vertex_shader *impl_from_ID3D10VertexShader(ID3D10VertexShader *iface)
364 return CONTAINING_RECORD(iface, struct d3d_vertex_shader, ID3D10VertexShader_iface);
367 /* IUnknown methods */
369 static HRESULT STDMETHODCALLTYPE d3d10_vertex_shader_QueryInterface(ID3D10VertexShader *iface,
370 REFIID riid, void **object)
372 struct d3d_vertex_shader *shader = impl_from_ID3D10VertexShader(iface);
374 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
376 return d3d11_vertex_shader_QueryInterface(&shader->ID3D11VertexShader_iface, riid, object);
379 static ULONG STDMETHODCALLTYPE d3d10_vertex_shader_AddRef(ID3D10VertexShader *iface)
381 struct d3d_vertex_shader *shader = impl_from_ID3D10VertexShader(iface);
383 TRACE("iface %p.\n", iface);
385 return d3d11_vertex_shader_AddRef(&shader->ID3D11VertexShader_iface);
388 static ULONG STDMETHODCALLTYPE d3d10_vertex_shader_Release(ID3D10VertexShader *iface)
390 struct d3d_vertex_shader *shader = impl_from_ID3D10VertexShader(iface);
392 TRACE("iface %p.\n", iface);
394 return d3d11_vertex_shader_Release(&shader->ID3D11VertexShader_iface);
397 /* ID3D10DeviceChild methods */
399 static void STDMETHODCALLTYPE d3d10_vertex_shader_GetDevice(ID3D10VertexShader *iface, ID3D10Device **device)
401 struct d3d_vertex_shader *shader = impl_from_ID3D10VertexShader(iface);
403 TRACE("iface %p, device %p.\n", iface, device);
405 ID3D11Device_QueryInterface(shader->device, &IID_ID3D10Device, (void **)device);
408 static HRESULT STDMETHODCALLTYPE d3d10_vertex_shader_GetPrivateData(ID3D10VertexShader *iface,
409 REFGUID guid, UINT *data_size, void *data)
411 struct d3d_vertex_shader *shader = impl_from_ID3D10VertexShader(iface);
413 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
414 iface, debugstr_guid(guid), data_size, data);
416 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
419 static HRESULT STDMETHODCALLTYPE d3d10_vertex_shader_SetPrivateData(ID3D10VertexShader *iface,
420 REFGUID guid, UINT data_size, const void *data)
422 struct d3d_vertex_shader *shader = impl_from_ID3D10VertexShader(iface);
424 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
425 iface, debugstr_guid(guid), data_size, data);
427 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
430 static HRESULT STDMETHODCALLTYPE d3d10_vertex_shader_SetPrivateDataInterface(ID3D10VertexShader *iface,
431 REFGUID guid, const IUnknown *data)
433 struct d3d_vertex_shader *shader = impl_from_ID3D10VertexShader(iface);
435 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
437 return d3d_set_private_data_interface(&shader->private_store, guid, data);
440 static const struct ID3D10VertexShaderVtbl d3d10_vertex_shader_vtbl =
442 /* IUnknown methods */
443 d3d10_vertex_shader_QueryInterface,
444 d3d10_vertex_shader_AddRef,
445 d3d10_vertex_shader_Release,
446 /* ID3D10DeviceChild methods */
447 d3d10_vertex_shader_GetDevice,
448 d3d10_vertex_shader_GetPrivateData,
449 d3d10_vertex_shader_SetPrivateData,
450 d3d10_vertex_shader_SetPrivateDataInterface,
453 static void STDMETHODCALLTYPE d3d_vertex_shader_wined3d_object_destroyed(void *parent)
455 struct d3d_vertex_shader *shader = parent;
457 wined3d_private_store_cleanup(&shader->private_store);
458 HeapFree(GetProcessHeap(), 0, parent);
461 static const struct wined3d_parent_ops d3d_vertex_shader_wined3d_parent_ops =
463 d3d_vertex_shader_wined3d_object_destroyed,
466 static unsigned int d3d_sm_from_feature_level(D3D_FEATURE_LEVEL feature_level)
468 switch (feature_level)
470 case D3D_FEATURE_LEVEL_11_1:
471 case D3D_FEATURE_LEVEL_11_0:
472 return 5;
473 case D3D_FEATURE_LEVEL_10_1:
474 case D3D_FEATURE_LEVEL_10_0:
475 return 4;
476 case D3D_FEATURE_LEVEL_9_3:
477 return 3;
478 case D3D_FEATURE_LEVEL_9_2:
479 case D3D_FEATURE_LEVEL_9_1:
480 return 2;
481 default:
482 ERR("Unexpected feature_level %#x.\n", feature_level);
484 return 0;
487 static HRESULT d3d_vertex_shader_init(struct d3d_vertex_shader *shader, struct d3d_device *device,
488 const void *byte_code, SIZE_T byte_code_length)
490 struct wined3d_shader_desc desc;
491 HRESULT hr;
493 shader->ID3D11VertexShader_iface.lpVtbl = &d3d11_vertex_shader_vtbl;
494 shader->ID3D10VertexShader_iface.lpVtbl = &d3d10_vertex_shader_vtbl;
495 shader->refcount = 1;
496 wined3d_mutex_lock();
497 wined3d_private_store_init(&shader->private_store);
499 if (FAILED(hr = shader_extract_from_dxbc(byte_code, byte_code_length, &desc, device->feature_level)))
501 WARN("Failed to extract shader, hr %#x.\n", hr);
502 wined3d_private_store_cleanup(&shader->private_store);
503 wined3d_mutex_unlock();
504 return hr;
506 desc.max_version = d3d_sm_from_feature_level(device->feature_level);
508 hr = wined3d_shader_create_vs(device->wined3d_device, &desc, shader,
509 &d3d_vertex_shader_wined3d_parent_ops, &shader->wined3d_shader);
510 shader_free_signature(&desc.input_signature);
511 shader_free_signature(&desc.output_signature);
512 if (FAILED(hr))
514 WARN("Failed to create wined3d vertex shader, hr %#x.\n", hr);
515 wined3d_private_store_cleanup(&shader->private_store);
516 wined3d_mutex_unlock();
517 return E_INVALIDARG;
519 wined3d_mutex_unlock();
521 shader->device = &device->ID3D11Device_iface;
522 ID3D11Device_AddRef(shader->device);
524 return S_OK;
527 HRESULT d3d_vertex_shader_create(struct d3d_device *device, const void *byte_code, SIZE_T byte_code_length,
528 struct d3d_vertex_shader **shader)
530 struct d3d_vertex_shader *object;
531 HRESULT hr;
533 if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
534 return E_OUTOFMEMORY;
536 if (FAILED(hr = d3d_vertex_shader_init(object, device, byte_code, byte_code_length)))
538 WARN("Failed to initialize vertex shader, hr %#x.\n", hr);
539 HeapFree(GetProcessHeap(), 0, object);
540 return hr;
543 TRACE("Created vertex shader %p.\n", object);
544 *shader = object;
546 return S_OK;
549 struct d3d_vertex_shader *unsafe_impl_from_ID3D11VertexShader(ID3D11VertexShader *iface)
551 if (!iface)
552 return NULL;
553 assert(iface->lpVtbl == &d3d11_vertex_shader_vtbl);
555 return impl_from_ID3D11VertexShader(iface);
558 struct d3d_vertex_shader *unsafe_impl_from_ID3D10VertexShader(ID3D10VertexShader *iface)
560 if (!iface)
561 return NULL;
562 assert(iface->lpVtbl == &d3d10_vertex_shader_vtbl);
564 return impl_from_ID3D10VertexShader(iface);
567 /* ID3D11HullShader methods */
569 static inline struct d3d11_hull_shader *impl_from_ID3D11HullShader(ID3D11HullShader *iface)
571 return CONTAINING_RECORD(iface, struct d3d11_hull_shader, ID3D11HullShader_iface);
574 static HRESULT STDMETHODCALLTYPE d3d11_hull_shader_QueryInterface(ID3D11HullShader *iface,
575 REFIID riid, void **object)
577 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
579 if (IsEqualGUID(riid, &IID_ID3D11HullShader)
580 || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
581 || IsEqualGUID(riid, &IID_IUnknown))
583 ID3D11HullShader_AddRef(iface);
584 *object = iface;
585 return S_OK;
588 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
590 *object = NULL;
591 return E_NOINTERFACE;
594 static ULONG STDMETHODCALLTYPE d3d11_hull_shader_AddRef(ID3D11HullShader *iface)
596 struct d3d11_hull_shader *shader = impl_from_ID3D11HullShader(iface);
597 ULONG refcount = InterlockedIncrement(&shader->refcount);
599 TRACE("%p increasing refcount to %u.\n", shader, refcount);
601 return refcount;
604 static ULONG STDMETHODCALLTYPE d3d11_hull_shader_Release(ID3D11HullShader *iface)
606 struct d3d11_hull_shader *shader = impl_from_ID3D11HullShader(iface);
607 ULONG refcount = InterlockedDecrement(&shader->refcount);
609 TRACE("%p decreasing refcount to %u.\n", shader, refcount);
611 if (!refcount)
613 ID3D11Device *device = shader->device;
615 wined3d_mutex_lock();
616 wined3d_shader_decref(shader->wined3d_shader);
617 wined3d_mutex_unlock();
619 /* Release the device last, it may cause the wined3d device to be
620 * destroyed. */
621 ID3D11Device_Release(device);
624 return refcount;
627 static void STDMETHODCALLTYPE d3d11_hull_shader_GetDevice(ID3D11HullShader *iface,
628 ID3D11Device **device)
630 struct d3d11_hull_shader *shader = impl_from_ID3D11HullShader(iface);
632 TRACE("iface %p, device %p.\n", iface, device);
634 *device = shader->device;
635 ID3D11Device_AddRef(*device);
638 static HRESULT STDMETHODCALLTYPE d3d11_hull_shader_GetPrivateData(ID3D11HullShader *iface,
639 REFGUID guid, UINT *data_size, void *data)
641 struct d3d11_hull_shader *shader = impl_from_ID3D11HullShader(iface);
643 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
645 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
648 static HRESULT STDMETHODCALLTYPE d3d11_hull_shader_SetPrivateData(ID3D11HullShader *iface,
649 REFGUID guid, UINT data_size, const void *data)
651 struct d3d11_hull_shader *shader = impl_from_ID3D11HullShader(iface);
653 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
655 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
658 static HRESULT STDMETHODCALLTYPE d3d11_hull_shader_SetPrivateDataInterface(ID3D11HullShader *iface,
659 REFGUID guid, const IUnknown *data)
661 struct d3d11_hull_shader *shader = impl_from_ID3D11HullShader(iface);
663 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
665 return d3d_set_private_data_interface(&shader->private_store, guid, data);
668 static const struct ID3D11HullShaderVtbl d3d11_hull_shader_vtbl =
670 /* IUnknown methods */
671 d3d11_hull_shader_QueryInterface,
672 d3d11_hull_shader_AddRef,
673 d3d11_hull_shader_Release,
674 /* ID3D11DeviceChild methods */
675 d3d11_hull_shader_GetDevice,
676 d3d11_hull_shader_GetPrivateData,
677 d3d11_hull_shader_SetPrivateData,
678 d3d11_hull_shader_SetPrivateDataInterface,
681 static void STDMETHODCALLTYPE d3d11_hull_shader_wined3d_object_destroyed(void *parent)
683 struct d3d11_hull_shader *shader = parent;
685 wined3d_private_store_cleanup(&shader->private_store);
686 HeapFree(GetProcessHeap(), 0, parent);
689 static const struct wined3d_parent_ops d3d11_hull_shader_wined3d_parent_ops =
691 d3d11_hull_shader_wined3d_object_destroyed,
694 static HRESULT d3d11_hull_shader_init(struct d3d11_hull_shader *shader, struct d3d_device *device,
695 const void *byte_code, SIZE_T byte_code_length)
697 struct wined3d_shader_desc desc;
698 HRESULT hr;
700 shader->ID3D11HullShader_iface.lpVtbl = &d3d11_hull_shader_vtbl;
701 shader->refcount = 1;
702 wined3d_mutex_lock();
703 wined3d_private_store_init(&shader->private_store);
705 if (FAILED(hr = shader_extract_from_dxbc(byte_code, byte_code_length, &desc, device->feature_level)))
707 WARN("Failed to extract shader, hr %#x.\n", hr);
708 wined3d_private_store_cleanup(&shader->private_store);
709 wined3d_mutex_unlock();
710 return hr;
712 desc.max_version = d3d_sm_from_feature_level(device->feature_level);
714 hr = wined3d_shader_create_hs(device->wined3d_device, &desc, shader,
715 &d3d11_hull_shader_wined3d_parent_ops, &shader->wined3d_shader);
716 shader_free_signature(&desc.input_signature);
717 shader_free_signature(&desc.output_signature);
718 if (FAILED(hr))
720 WARN("Failed to create wined3d hull shader, hr %#x.\n", hr);
721 wined3d_private_store_cleanup(&shader->private_store);
722 wined3d_mutex_unlock();
723 return E_INVALIDARG;
725 wined3d_mutex_unlock();
727 shader->device = &device->ID3D11Device_iface;
728 ID3D11Device_AddRef(shader->device);
730 return S_OK;
733 HRESULT d3d11_hull_shader_create(struct d3d_device *device, const void *byte_code, SIZE_T byte_code_length,
734 struct d3d11_hull_shader **shader)
736 struct d3d11_hull_shader *object;
737 HRESULT hr;
739 if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
740 return E_OUTOFMEMORY;
742 if (FAILED(hr = d3d11_hull_shader_init(object, device, byte_code, byte_code_length)))
744 HeapFree(GetProcessHeap(), 0, object);
745 return hr;
748 TRACE("Created hull shader %p.\n", object);
749 *shader = object;
751 return S_OK;
754 /* ID3D11DomainShader methods */
756 static inline struct d3d11_domain_shader *impl_from_ID3D11DomainShader(ID3D11DomainShader *iface)
758 return CONTAINING_RECORD(iface, struct d3d11_domain_shader, ID3D11DomainShader_iface);
761 static HRESULT STDMETHODCALLTYPE d3d11_domain_shader_QueryInterface(ID3D11DomainShader *iface,
762 REFIID riid, void **object)
764 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
766 if (IsEqualGUID(riid, &IID_ID3D11DomainShader)
767 || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
768 || IsEqualGUID(riid, &IID_IUnknown))
770 ID3D11DomainShader_AddRef(iface);
771 *object = iface;
772 return S_OK;
775 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
777 *object = NULL;
778 return E_NOINTERFACE;
781 static ULONG STDMETHODCALLTYPE d3d11_domain_shader_AddRef(ID3D11DomainShader *iface)
783 struct d3d11_domain_shader *shader = impl_from_ID3D11DomainShader(iface);
784 ULONG refcount = InterlockedIncrement(&shader->refcount);
786 TRACE("%p increasing refcount to %u.\n", shader, refcount);
788 return refcount;
791 static ULONG STDMETHODCALLTYPE d3d11_domain_shader_Release(ID3D11DomainShader *iface)
793 struct d3d11_domain_shader *shader = impl_from_ID3D11DomainShader(iface);
794 ULONG refcount = InterlockedDecrement(&shader->refcount);
796 TRACE("%p decreasing refcount to %u.\n", shader, refcount);
798 if (!refcount)
800 ID3D11Device *device = shader->device;
802 wined3d_mutex_lock();
803 wined3d_shader_decref(shader->wined3d_shader);
804 wined3d_mutex_unlock();
806 /* Release the device last, it may cause the wined3d device to be
807 * destroyed. */
808 ID3D11Device_Release(device);
811 return refcount;
814 static void STDMETHODCALLTYPE d3d11_domain_shader_GetDevice(ID3D11DomainShader *iface,
815 ID3D11Device **device)
817 struct d3d11_domain_shader *shader = impl_from_ID3D11DomainShader(iface);
819 TRACE("iface %p, device %p.\n", iface, device);
821 *device = shader->device;
822 ID3D11Device_AddRef(*device);
825 static HRESULT STDMETHODCALLTYPE d3d11_domain_shader_GetPrivateData(ID3D11DomainShader *iface,
826 REFGUID guid, UINT *data_size, void *data)
828 struct d3d11_domain_shader *shader = impl_from_ID3D11DomainShader(iface);
830 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
832 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
835 static HRESULT STDMETHODCALLTYPE d3d11_domain_shader_SetPrivateData(ID3D11DomainShader *iface,
836 REFGUID guid, UINT data_size, const void *data)
838 struct d3d11_domain_shader *shader = impl_from_ID3D11DomainShader(iface);
840 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
842 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
845 static HRESULT STDMETHODCALLTYPE d3d11_domain_shader_SetPrivateDataInterface(ID3D11DomainShader *iface,
846 REFGUID guid, const IUnknown *data)
848 struct d3d11_domain_shader *shader = impl_from_ID3D11DomainShader(iface);
850 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
852 return d3d_set_private_data_interface(&shader->private_store, guid, data);
855 static const struct ID3D11DomainShaderVtbl d3d11_domain_shader_vtbl =
857 /* IUnknown methods */
858 d3d11_domain_shader_QueryInterface,
859 d3d11_domain_shader_AddRef,
860 d3d11_domain_shader_Release,
861 /* ID3D11DeviceChild methods */
862 d3d11_domain_shader_GetDevice,
863 d3d11_domain_shader_GetPrivateData,
864 d3d11_domain_shader_SetPrivateData,
865 d3d11_domain_shader_SetPrivateDataInterface,
868 static void STDMETHODCALLTYPE d3d11_domain_shader_wined3d_object_destroyed(void *parent)
870 struct d3d11_domain_shader *shader = parent;
872 wined3d_private_store_cleanup(&shader->private_store);
873 HeapFree(GetProcessHeap(), 0, parent);
876 static const struct wined3d_parent_ops d3d11_domain_shader_wined3d_parent_ops =
878 d3d11_domain_shader_wined3d_object_destroyed,
881 static HRESULT d3d11_domain_shader_init(struct d3d11_domain_shader *shader, struct d3d_device *device,
882 const void *byte_code, SIZE_T byte_code_length)
884 struct wined3d_shader_desc desc;
885 HRESULT hr;
887 shader->ID3D11DomainShader_iface.lpVtbl = &d3d11_domain_shader_vtbl;
888 shader->refcount = 1;
889 wined3d_mutex_lock();
890 wined3d_private_store_init(&shader->private_store);
892 if (FAILED(hr = shader_extract_from_dxbc(byte_code, byte_code_length, &desc, device->feature_level)))
894 WARN("Failed to extract shader, hr %#x.\n", hr);
895 wined3d_private_store_cleanup(&shader->private_store);
896 wined3d_mutex_unlock();
897 return hr;
899 desc.max_version = d3d_sm_from_feature_level(device->feature_level);
901 hr = wined3d_shader_create_ds(device->wined3d_device, &desc, shader,
902 &d3d11_domain_shader_wined3d_parent_ops, &shader->wined3d_shader);
903 shader_free_signature(&desc.input_signature);
904 shader_free_signature(&desc.output_signature);
905 if (FAILED(hr))
907 WARN("Failed to create wined3d domain shader, hr %#x.\n", hr);
908 wined3d_private_store_cleanup(&shader->private_store);
909 wined3d_mutex_unlock();
910 return E_INVALIDARG;
912 wined3d_mutex_unlock();
914 shader->device = &device->ID3D11Device_iface;
915 ID3D11Device_AddRef(shader->device);
917 return S_OK;
920 HRESULT d3d11_domain_shader_create(struct d3d_device *device, const void *byte_code, SIZE_T byte_code_length,
921 struct d3d11_domain_shader **shader)
923 struct d3d11_domain_shader *object;
924 HRESULT hr;
926 if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
927 return E_OUTOFMEMORY;
929 if (FAILED(hr = d3d11_domain_shader_init(object, device, byte_code, byte_code_length)))
931 HeapFree(GetProcessHeap(), 0, object);
932 return hr;
935 TRACE("Created domain shader %p.\n", object);
936 *shader = object;
938 return S_OK;
941 /* ID3D11GeometryShader methods */
943 static inline struct d3d_geometry_shader *impl_from_ID3D11GeometryShader(ID3D11GeometryShader *iface)
945 return CONTAINING_RECORD(iface, struct d3d_geometry_shader, ID3D11GeometryShader_iface);
948 static HRESULT STDMETHODCALLTYPE d3d11_geometry_shader_QueryInterface(ID3D11GeometryShader *iface,
949 REFIID riid, void **object)
951 struct d3d_geometry_shader *shader = impl_from_ID3D11GeometryShader(iface);
953 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
955 if (IsEqualGUID(riid, &IID_ID3D11GeometryShader)
956 || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
957 || IsEqualGUID(riid, &IID_IUnknown))
959 ID3D11GeometryShader_AddRef(iface);
960 *object = iface;
961 return S_OK;
964 if (IsEqualGUID(riid, &IID_ID3D10GeometryShader)
965 || IsEqualGUID(riid, &IID_ID3D10DeviceChild))
967 ID3D10GeometryShader_AddRef(&shader->ID3D10GeometryShader_iface);
968 *object = &shader->ID3D10GeometryShader_iface;
969 return S_OK;
972 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
974 *object = NULL;
975 return E_NOINTERFACE;
978 static ULONG STDMETHODCALLTYPE d3d11_geometry_shader_AddRef(ID3D11GeometryShader *iface)
980 struct d3d_geometry_shader *shader = impl_from_ID3D11GeometryShader(iface);
981 ULONG refcount = InterlockedIncrement(&shader->refcount);
983 TRACE("%p increasing refcount to %u.\n", shader, refcount);
985 return refcount;
988 static ULONG STDMETHODCALLTYPE d3d11_geometry_shader_Release(ID3D11GeometryShader *iface)
990 struct d3d_geometry_shader *shader = impl_from_ID3D11GeometryShader(iface);
991 ULONG refcount = InterlockedDecrement(&shader->refcount);
993 TRACE("%p decreasing refcount to %u.\n", shader, refcount);
995 if (!refcount)
997 ID3D11Device *device = shader->device;
999 wined3d_mutex_lock();
1000 wined3d_shader_decref(shader->wined3d_shader);
1001 wined3d_mutex_unlock();
1003 /* Release the device last, it may cause the wined3d device to be
1004 * destroyed. */
1005 ID3D11Device_Release(device);
1008 return refcount;
1011 static void STDMETHODCALLTYPE d3d11_geometry_shader_GetDevice(ID3D11GeometryShader *iface,
1012 ID3D11Device **device)
1014 struct d3d_geometry_shader *shader = impl_from_ID3D11GeometryShader(iface);
1016 TRACE("iface %p, device %p.\n", iface, device);
1018 *device = shader->device;
1019 ID3D11Device_AddRef(*device);
1022 static HRESULT STDMETHODCALLTYPE d3d11_geometry_shader_GetPrivateData(ID3D11GeometryShader *iface,
1023 REFGUID guid, UINT *data_size, void *data)
1025 struct d3d_geometry_shader *shader = impl_from_ID3D11GeometryShader(iface);
1027 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
1029 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
1032 static HRESULT STDMETHODCALLTYPE d3d11_geometry_shader_SetPrivateData(ID3D11GeometryShader *iface,
1033 REFGUID guid, UINT data_size, const void *data)
1035 struct d3d_geometry_shader *shader = impl_from_ID3D11GeometryShader(iface);
1037 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
1039 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
1042 static HRESULT STDMETHODCALLTYPE d3d11_geometry_shader_SetPrivateDataInterface(ID3D11GeometryShader *iface,
1043 REFGUID guid, const IUnknown *data)
1045 struct d3d_geometry_shader *shader = impl_from_ID3D11GeometryShader(iface);
1047 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
1049 return d3d_set_private_data_interface(&shader->private_store, guid, data);
1052 static const struct ID3D11GeometryShaderVtbl d3d11_geometry_shader_vtbl =
1054 /* IUnknown methods */
1055 d3d11_geometry_shader_QueryInterface,
1056 d3d11_geometry_shader_AddRef,
1057 d3d11_geometry_shader_Release,
1058 /* ID3D11DeviceChild methods */
1059 d3d11_geometry_shader_GetDevice,
1060 d3d11_geometry_shader_GetPrivateData,
1061 d3d11_geometry_shader_SetPrivateData,
1062 d3d11_geometry_shader_SetPrivateDataInterface,
1065 /* ID3D10GeometryShader methods */
1067 static inline struct d3d_geometry_shader *impl_from_ID3D10GeometryShader(ID3D10GeometryShader *iface)
1069 return CONTAINING_RECORD(iface, struct d3d_geometry_shader, ID3D10GeometryShader_iface);
1072 /* IUnknown methods */
1074 static HRESULT STDMETHODCALLTYPE d3d10_geometry_shader_QueryInterface(ID3D10GeometryShader *iface,
1075 REFIID riid, void **object)
1077 struct d3d_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface);
1079 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
1081 return d3d11_geometry_shader_QueryInterface(&shader->ID3D11GeometryShader_iface, riid, object);
1084 static ULONG STDMETHODCALLTYPE d3d10_geometry_shader_AddRef(ID3D10GeometryShader *iface)
1086 struct d3d_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface);
1088 TRACE("iface %p.\n", iface);
1090 return d3d11_geometry_shader_AddRef(&shader->ID3D11GeometryShader_iface);
1093 static ULONG STDMETHODCALLTYPE d3d10_geometry_shader_Release(ID3D10GeometryShader *iface)
1095 struct d3d_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface);
1097 TRACE("iface %p.\n", iface);
1099 return d3d11_geometry_shader_Release(&shader->ID3D11GeometryShader_iface);
1102 /* ID3D10DeviceChild methods */
1104 static void STDMETHODCALLTYPE d3d10_geometry_shader_GetDevice(ID3D10GeometryShader *iface, ID3D10Device **device)
1106 struct d3d_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface);
1108 TRACE("iface %p, device %p.\n", iface, device);
1110 ID3D11Device_QueryInterface(shader->device, &IID_ID3D10Device, (void **)device);
1113 static HRESULT STDMETHODCALLTYPE d3d10_geometry_shader_GetPrivateData(ID3D10GeometryShader *iface,
1114 REFGUID guid, UINT *data_size, void *data)
1116 struct d3d_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface);
1118 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
1119 iface, debugstr_guid(guid), data_size, data);
1121 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
1124 static HRESULT STDMETHODCALLTYPE d3d10_geometry_shader_SetPrivateData(ID3D10GeometryShader *iface,
1125 REFGUID guid, UINT data_size, const void *data)
1127 struct d3d_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface);
1129 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
1130 iface, debugstr_guid(guid), data_size, data);
1132 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
1135 static HRESULT STDMETHODCALLTYPE d3d10_geometry_shader_SetPrivateDataInterface(ID3D10GeometryShader *iface,
1136 REFGUID guid, const IUnknown *data)
1138 struct d3d_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface);
1140 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
1142 return d3d_set_private_data_interface(&shader->private_store, guid, data);
1145 static const struct ID3D10GeometryShaderVtbl d3d10_geometry_shader_vtbl =
1147 /* IUnknown methods */
1148 d3d10_geometry_shader_QueryInterface,
1149 d3d10_geometry_shader_AddRef,
1150 d3d10_geometry_shader_Release,
1151 /* ID3D10DeviceChild methods */
1152 d3d10_geometry_shader_GetDevice,
1153 d3d10_geometry_shader_GetPrivateData,
1154 d3d10_geometry_shader_SetPrivateData,
1155 d3d10_geometry_shader_SetPrivateDataInterface,
1158 static void STDMETHODCALLTYPE d3d_geometry_shader_wined3d_object_destroyed(void *parent)
1160 struct d3d_geometry_shader *shader = parent;
1162 wined3d_private_store_cleanup(&shader->private_store);
1163 HeapFree(GetProcessHeap(), 0, parent);
1166 static const struct wined3d_parent_ops d3d_geometry_shader_wined3d_parent_ops =
1168 d3d_geometry_shader_wined3d_object_destroyed,
1171 static HRESULT d3d_geometry_shader_init(struct d3d_geometry_shader *shader, struct d3d_device *device,
1172 const void *byte_code, SIZE_T byte_code_length)
1174 struct wined3d_shader_desc desc;
1175 HRESULT hr;
1177 shader->ID3D11GeometryShader_iface.lpVtbl = &d3d11_geometry_shader_vtbl;
1178 shader->ID3D10GeometryShader_iface.lpVtbl = &d3d10_geometry_shader_vtbl;
1179 shader->refcount = 1;
1180 wined3d_mutex_lock();
1181 wined3d_private_store_init(&shader->private_store);
1183 if (FAILED(hr = shader_extract_from_dxbc(byte_code, byte_code_length, &desc, device->feature_level)))
1185 WARN("Failed to extract shader, hr %#x.\n", hr);
1186 wined3d_private_store_cleanup(&shader->private_store);
1187 wined3d_mutex_unlock();
1188 return hr;
1190 desc.max_version = d3d_sm_from_feature_level(device->feature_level);
1192 hr = wined3d_shader_create_gs(device->wined3d_device, &desc, shader,
1193 &d3d_geometry_shader_wined3d_parent_ops, &shader->wined3d_shader);
1194 shader_free_signature(&desc.input_signature);
1195 shader_free_signature(&desc.output_signature);
1196 if (FAILED(hr))
1198 WARN("Failed to create wined3d geometry shader, hr %#x.\n", hr);
1199 wined3d_private_store_cleanup(&shader->private_store);
1200 wined3d_mutex_unlock();
1201 return E_INVALIDARG;
1203 wined3d_mutex_unlock();
1205 shader->device = &device->ID3D11Device_iface;
1206 ID3D11Device_AddRef(shader->device);
1208 return S_OK;
1211 HRESULT d3d_geometry_shader_create(struct d3d_device *device, const void *byte_code, SIZE_T byte_code_length,
1212 struct d3d_geometry_shader **shader)
1214 struct d3d_geometry_shader *object;
1215 HRESULT hr;
1217 if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
1218 return E_OUTOFMEMORY;
1220 if (FAILED(hr = d3d_geometry_shader_init(object, device, byte_code, byte_code_length)))
1222 WARN("Failed to initialize geometry shader, hr %#x.\n", hr);
1223 HeapFree(GetProcessHeap(), 0, object);
1224 return hr;
1227 TRACE("Created geometry shader %p.\n", object);
1228 *shader = object;
1230 return S_OK;
1233 struct d3d_geometry_shader *unsafe_impl_from_ID3D11GeometryShader(ID3D11GeometryShader *iface)
1235 if (!iface)
1236 return NULL;
1237 assert(iface->lpVtbl == &d3d11_geometry_shader_vtbl);
1239 return impl_from_ID3D11GeometryShader(iface);
1242 struct d3d_geometry_shader *unsafe_impl_from_ID3D10GeometryShader(ID3D10GeometryShader *iface)
1244 if (!iface)
1245 return NULL;
1246 assert(iface->lpVtbl == &d3d10_geometry_shader_vtbl);
1248 return impl_from_ID3D10GeometryShader(iface);
1251 /* ID3D11PixelShader methods */
1253 static inline struct d3d_pixel_shader *impl_from_ID3D11PixelShader(ID3D11PixelShader *iface)
1255 return CONTAINING_RECORD(iface, struct d3d_pixel_shader, ID3D11PixelShader_iface);
1258 static HRESULT STDMETHODCALLTYPE d3d11_pixel_shader_QueryInterface(ID3D11PixelShader *iface,
1259 REFIID riid, void **object)
1261 struct d3d_pixel_shader *shader = impl_from_ID3D11PixelShader(iface);
1263 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
1265 if (IsEqualGUID(riid, &IID_ID3D11PixelShader)
1266 || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
1267 || IsEqualGUID(riid, &IID_IUnknown))
1269 ID3D11PixelShader_AddRef(iface);
1270 *object = iface;
1271 return S_OK;
1274 if (IsEqualGUID(riid, &IID_ID3D10PixelShader)
1275 || IsEqualGUID(riid, &IID_ID3D10DeviceChild))
1277 IUnknown_AddRef(&shader->ID3D10PixelShader_iface);
1278 *object = &shader->ID3D10PixelShader_iface;
1279 return S_OK;
1282 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
1284 *object = NULL;
1285 return E_NOINTERFACE;
1288 static ULONG STDMETHODCALLTYPE d3d11_pixel_shader_AddRef(ID3D11PixelShader *iface)
1290 struct d3d_pixel_shader *shader = impl_from_ID3D11PixelShader(iface);
1291 ULONG refcount = InterlockedIncrement(&shader->refcount);
1293 TRACE("%p increasing refcount to %u.\n", shader, refcount);
1295 if (refcount == 1)
1297 ID3D11Device_AddRef(shader->device);
1298 wined3d_mutex_lock();
1299 wined3d_shader_incref(shader->wined3d_shader);
1300 wined3d_mutex_unlock();
1303 return refcount;
1306 static ULONG STDMETHODCALLTYPE d3d11_pixel_shader_Release(ID3D11PixelShader *iface)
1308 struct d3d_pixel_shader *shader = impl_from_ID3D11PixelShader(iface);
1309 ULONG refcount = InterlockedDecrement(&shader->refcount);
1311 TRACE("%p decreasing refcount to %u.\n", shader, refcount);
1313 if (!refcount)
1315 ID3D11Device *device = shader->device;
1317 wined3d_mutex_lock();
1318 wined3d_shader_decref(shader->wined3d_shader);
1319 wined3d_mutex_unlock();
1320 /* Release the device last, it may cause the wined3d device to be
1321 * destroyed. */
1322 ID3D11Device_Release(device);
1325 return refcount;
1328 static void STDMETHODCALLTYPE d3d11_pixel_shader_GetDevice(ID3D11PixelShader *iface,
1329 ID3D11Device **device)
1331 struct d3d_pixel_shader *shader = impl_from_ID3D11PixelShader(iface);
1333 TRACE("iface %p, device %p.\n", iface, device);
1335 *device = shader->device;
1336 ID3D11Device_AddRef(*device);
1339 static HRESULT STDMETHODCALLTYPE d3d11_pixel_shader_GetPrivateData(ID3D11PixelShader *iface,
1340 REFGUID guid, UINT *data_size, void *data)
1342 struct d3d_pixel_shader *shader = impl_from_ID3D11PixelShader(iface);
1344 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
1346 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
1349 static HRESULT STDMETHODCALLTYPE d3d11_pixel_shader_SetPrivateData(ID3D11PixelShader *iface,
1350 REFGUID guid, UINT data_size, const void *data)
1352 struct d3d_pixel_shader *shader = impl_from_ID3D11PixelShader(iface);
1354 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
1356 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
1359 static HRESULT STDMETHODCALLTYPE d3d11_pixel_shader_SetPrivateDataInterface(ID3D11PixelShader *iface,
1360 REFGUID guid, const IUnknown *data)
1362 struct d3d_pixel_shader *shader = impl_from_ID3D11PixelShader(iface);
1364 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
1366 return d3d_set_private_data_interface(&shader->private_store, guid, data);
1369 static const struct ID3D11PixelShaderVtbl d3d11_pixel_shader_vtbl =
1371 /* IUnknown methods */
1372 d3d11_pixel_shader_QueryInterface,
1373 d3d11_pixel_shader_AddRef,
1374 d3d11_pixel_shader_Release,
1375 /* ID3D11DeviceChild methods */
1376 d3d11_pixel_shader_GetDevice,
1377 d3d11_pixel_shader_GetPrivateData,
1378 d3d11_pixel_shader_SetPrivateData,
1379 d3d11_pixel_shader_SetPrivateDataInterface,
1382 /* ID3D10PixelShader methods */
1384 static inline struct d3d_pixel_shader *impl_from_ID3D10PixelShader(ID3D10PixelShader *iface)
1386 return CONTAINING_RECORD(iface, struct d3d_pixel_shader, ID3D10PixelShader_iface);
1389 /* IUnknown methods */
1391 static HRESULT STDMETHODCALLTYPE d3d10_pixel_shader_QueryInterface(ID3D10PixelShader *iface,
1392 REFIID riid, void **object)
1394 struct d3d_pixel_shader *shader = impl_from_ID3D10PixelShader(iface);
1396 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
1398 return d3d11_pixel_shader_QueryInterface(&shader->ID3D11PixelShader_iface, riid, object);
1401 static ULONG STDMETHODCALLTYPE d3d10_pixel_shader_AddRef(ID3D10PixelShader *iface)
1403 struct d3d_pixel_shader *shader = impl_from_ID3D10PixelShader(iface);
1405 TRACE("iface %p.\n", iface);
1407 return d3d11_pixel_shader_AddRef(&shader->ID3D11PixelShader_iface);
1410 static ULONG STDMETHODCALLTYPE d3d10_pixel_shader_Release(ID3D10PixelShader *iface)
1412 struct d3d_pixel_shader *shader = impl_from_ID3D10PixelShader(iface);
1414 TRACE("iface %p.\n", iface);
1416 return d3d11_pixel_shader_Release(&shader->ID3D11PixelShader_iface);
1419 /* ID3D10DeviceChild methods */
1421 static void STDMETHODCALLTYPE d3d10_pixel_shader_GetDevice(ID3D10PixelShader *iface, ID3D10Device **device)
1423 struct d3d_pixel_shader *shader = impl_from_ID3D10PixelShader(iface);
1425 TRACE("iface %p, device %p.\n", iface, device);
1427 ID3D11Device_QueryInterface(shader->device, &IID_ID3D10Device, (void **)device);
1430 static HRESULT STDMETHODCALLTYPE d3d10_pixel_shader_GetPrivateData(ID3D10PixelShader *iface,
1431 REFGUID guid, UINT *data_size, void *data)
1433 struct d3d_pixel_shader *shader = impl_from_ID3D10PixelShader(iface);
1435 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
1436 iface, debugstr_guid(guid), data_size, data);
1438 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
1441 static HRESULT STDMETHODCALLTYPE d3d10_pixel_shader_SetPrivateData(ID3D10PixelShader *iface,
1442 REFGUID guid, UINT data_size, const void *data)
1444 struct d3d_pixel_shader *shader = impl_from_ID3D10PixelShader(iface);
1446 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
1447 iface, debugstr_guid(guid), data_size, data);
1449 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
1452 static HRESULT STDMETHODCALLTYPE d3d10_pixel_shader_SetPrivateDataInterface(ID3D10PixelShader *iface,
1453 REFGUID guid, const IUnknown *data)
1455 struct d3d_pixel_shader *shader = impl_from_ID3D10PixelShader(iface);
1457 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
1459 return d3d_set_private_data_interface(&shader->private_store, guid, data);
1462 static const struct ID3D10PixelShaderVtbl d3d10_pixel_shader_vtbl =
1464 /* IUnknown methods */
1465 d3d10_pixel_shader_QueryInterface,
1466 d3d10_pixel_shader_AddRef,
1467 d3d10_pixel_shader_Release,
1468 /* ID3D10DeviceChild methods */
1469 d3d10_pixel_shader_GetDevice,
1470 d3d10_pixel_shader_GetPrivateData,
1471 d3d10_pixel_shader_SetPrivateData,
1472 d3d10_pixel_shader_SetPrivateDataInterface,
1475 static void STDMETHODCALLTYPE d3d_pixel_shader_wined3d_object_destroyed(void *parent)
1477 struct d3d_pixel_shader *shader = parent;
1479 wined3d_private_store_cleanup(&shader->private_store);
1480 HeapFree(GetProcessHeap(), 0, parent);
1483 static const struct wined3d_parent_ops d3d_pixel_shader_wined3d_parent_ops =
1485 d3d_pixel_shader_wined3d_object_destroyed,
1488 static HRESULT d3d_pixel_shader_init(struct d3d_pixel_shader *shader, struct d3d_device *device,
1489 const void *byte_code, SIZE_T byte_code_length)
1491 struct wined3d_shader_desc desc;
1492 HRESULT hr;
1494 shader->ID3D11PixelShader_iface.lpVtbl = &d3d11_pixel_shader_vtbl;
1495 shader->ID3D10PixelShader_iface.lpVtbl = &d3d10_pixel_shader_vtbl;
1496 shader->refcount = 1;
1497 wined3d_mutex_lock();
1498 wined3d_private_store_init(&shader->private_store);
1500 if (FAILED(hr = shader_extract_from_dxbc(byte_code, byte_code_length, &desc, device->feature_level)))
1502 WARN("Failed to extract shader, hr %#x.\n", hr);
1503 wined3d_private_store_cleanup(&shader->private_store);
1504 wined3d_mutex_unlock();
1505 return hr;
1507 desc.max_version = d3d_sm_from_feature_level(device->feature_level);
1509 hr = wined3d_shader_create_ps(device->wined3d_device, &desc, shader,
1510 &d3d_pixel_shader_wined3d_parent_ops, &shader->wined3d_shader);
1511 shader_free_signature(&desc.input_signature);
1512 shader_free_signature(&desc.output_signature);
1513 if (FAILED(hr))
1515 WARN("Failed to create wined3d pixel shader, hr %#x.\n", hr);
1516 wined3d_private_store_cleanup(&shader->private_store);
1517 wined3d_mutex_unlock();
1518 return E_INVALIDARG;
1520 wined3d_mutex_unlock();
1522 shader->device = &device->ID3D11Device_iface;
1523 ID3D11Device_AddRef(shader->device);
1525 return S_OK;
1528 HRESULT d3d_pixel_shader_create(struct d3d_device *device, const void *byte_code, SIZE_T byte_code_length,
1529 struct d3d_pixel_shader **shader)
1531 struct d3d_pixel_shader *object;
1532 HRESULT hr;
1534 if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
1535 return E_OUTOFMEMORY;
1537 if (FAILED(hr = d3d_pixel_shader_init(object, device, byte_code, byte_code_length)))
1539 WARN("Failed to initialize pixel shader, hr %#x.\n", hr);
1540 HeapFree(GetProcessHeap(), 0, object);
1541 return hr;
1544 TRACE("Created pixel shader %p.\n", object);
1545 *shader = object;
1547 return S_OK;
1550 struct d3d_pixel_shader *unsafe_impl_from_ID3D11PixelShader(ID3D11PixelShader *iface)
1552 if (!iface)
1553 return NULL;
1554 assert(iface->lpVtbl == &d3d11_pixel_shader_vtbl);
1556 return impl_from_ID3D11PixelShader(iface);
1559 struct d3d_pixel_shader *unsafe_impl_from_ID3D10PixelShader(ID3D10PixelShader *iface)
1561 if (!iface)
1562 return NULL;
1563 assert(iface->lpVtbl == &d3d10_pixel_shader_vtbl);
1565 return impl_from_ID3D10PixelShader(iface);
1568 /* ID3D11ComputeShader methods */
1570 static inline struct d3d11_compute_shader *impl_from_ID3D11ComputeShader(ID3D11ComputeShader *iface)
1572 return CONTAINING_RECORD(iface, struct d3d11_compute_shader, ID3D11ComputeShader_iface);
1575 static HRESULT STDMETHODCALLTYPE d3d11_compute_shader_QueryInterface(ID3D11ComputeShader *iface,
1576 REFIID riid, void **object)
1578 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
1580 if (IsEqualGUID(riid, &IID_ID3D11ComputeShader)
1581 || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
1582 || IsEqualGUID(riid, &IID_IUnknown))
1584 ID3D11ComputeShader_AddRef(*object = iface);
1585 return S_OK;
1588 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
1590 *object = NULL;
1591 return E_NOINTERFACE;
1594 static ULONG STDMETHODCALLTYPE d3d11_compute_shader_AddRef(ID3D11ComputeShader *iface)
1596 struct d3d11_compute_shader *shader = impl_from_ID3D11ComputeShader(iface);
1597 ULONG refcount = InterlockedIncrement(&shader->refcount);
1599 TRACE("%p increasing refcount to %u.\n", shader, refcount);
1601 return refcount;
1604 static ULONG STDMETHODCALLTYPE d3d11_compute_shader_Release(ID3D11ComputeShader *iface)
1606 struct d3d11_compute_shader *shader = impl_from_ID3D11ComputeShader(iface);
1607 ULONG refcount = InterlockedDecrement(&shader->refcount);
1609 TRACE("%p decreasing refcount to %u.\n", shader, refcount);
1611 if (!refcount)
1613 ID3D11Device *device = shader->device;
1615 wined3d_mutex_lock();
1616 wined3d_shader_decref(shader->wined3d_shader);
1617 wined3d_mutex_unlock();
1619 /* Release the device last, it may cause the wined3d device to be
1620 * destroyed. */
1621 ID3D11Device_Release(device);
1624 return refcount;
1627 static void STDMETHODCALLTYPE d3d11_compute_shader_GetDevice(ID3D11ComputeShader *iface,
1628 ID3D11Device **device)
1630 struct d3d11_compute_shader *shader = impl_from_ID3D11ComputeShader(iface);
1632 TRACE("iface %p, device %p.\n", iface, device);
1634 ID3D11Device_AddRef(*device = shader->device);
1637 static HRESULT STDMETHODCALLTYPE d3d11_compute_shader_GetPrivateData(ID3D11ComputeShader *iface,
1638 REFGUID guid, UINT *data_size, void *data)
1640 struct d3d11_compute_shader *shader = impl_from_ID3D11ComputeShader(iface);
1642 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
1644 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
1647 static HRESULT STDMETHODCALLTYPE d3d11_compute_shader_SetPrivateData(ID3D11ComputeShader *iface,
1648 REFGUID guid, UINT data_size, const void *data)
1650 struct d3d11_compute_shader *shader = impl_from_ID3D11ComputeShader(iface);
1652 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
1654 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
1657 static HRESULT STDMETHODCALLTYPE d3d11_compute_shader_SetPrivateDataInterface(ID3D11ComputeShader *iface,
1658 REFGUID guid, const IUnknown *data)
1660 struct d3d11_compute_shader *shader = impl_from_ID3D11ComputeShader(iface);
1662 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
1664 return d3d_set_private_data_interface(&shader->private_store, guid, data);
1667 static const struct ID3D11ComputeShaderVtbl d3d11_compute_shader_vtbl =
1669 /* IUnknown methods */
1670 d3d11_compute_shader_QueryInterface,
1671 d3d11_compute_shader_AddRef,
1672 d3d11_compute_shader_Release,
1673 /* ID3D11DeviceChild methods */
1674 d3d11_compute_shader_GetDevice,
1675 d3d11_compute_shader_GetPrivateData,
1676 d3d11_compute_shader_SetPrivateData,
1677 d3d11_compute_shader_SetPrivateDataInterface,
1680 static void STDMETHODCALLTYPE d3d11_compute_shader_wined3d_object_destroyed(void *parent)
1682 struct d3d11_compute_shader *shader = parent;
1684 wined3d_private_store_cleanup(&shader->private_store);
1685 HeapFree(GetProcessHeap(), 0, parent);
1688 static const struct wined3d_parent_ops d3d11_compute_shader_wined3d_parent_ops =
1690 d3d11_compute_shader_wined3d_object_destroyed,
1693 static HRESULT d3d11_compute_shader_init(struct d3d11_compute_shader *shader, struct d3d_device *device,
1694 const void *byte_code, SIZE_T byte_code_length)
1696 struct wined3d_shader_desc desc;
1697 HRESULT hr;
1699 shader->ID3D11ComputeShader_iface.lpVtbl = &d3d11_compute_shader_vtbl;
1700 shader->refcount = 1;
1701 wined3d_mutex_lock();
1702 wined3d_private_store_init(&shader->private_store);
1704 if (FAILED(hr = shader_extract_from_dxbc(byte_code, byte_code_length, &desc, device->feature_level)))
1706 WARN("Failed to extract shader, hr %#x.\n", hr);
1707 wined3d_private_store_cleanup(&shader->private_store);
1708 wined3d_mutex_unlock();
1709 return hr;
1711 desc.max_version = d3d_sm_from_feature_level(device->feature_level);
1713 hr = wined3d_shader_create_cs(device->wined3d_device, &desc, shader,
1714 &d3d11_compute_shader_wined3d_parent_ops, &shader->wined3d_shader);
1715 shader_free_signature(&desc.input_signature);
1716 shader_free_signature(&desc.output_signature);
1717 if (FAILED(hr))
1719 WARN("Failed to create wined3d compute shader, hr %#x.\n", hr);
1720 wined3d_private_store_cleanup(&shader->private_store);
1721 wined3d_mutex_unlock();
1722 return E_INVALIDARG;
1724 wined3d_mutex_unlock();
1726 ID3D11Device_AddRef(shader->device = &device->ID3D11Device_iface);
1728 return S_OK;
1731 HRESULT d3d11_compute_shader_create(struct d3d_device *device, const void *byte_code, SIZE_T byte_code_length,
1732 struct d3d11_compute_shader **shader)
1734 struct d3d11_compute_shader *object;
1735 HRESULT hr;
1737 if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
1738 return E_OUTOFMEMORY;
1740 if (FAILED(hr = d3d11_compute_shader_init(object, device, byte_code, byte_code_length)))
1742 HeapFree(GetProcessHeap(), 0, object);
1743 return hr;
1746 TRACE("Created compute shader %p.\n", object);
1747 *shader = object;
1749 return S_OK;
1752 /* ID3D11ClassLinkage methods */
1754 static inline struct d3d11_class_linkage *impl_from_ID3D11ClassLinkage(ID3D11ClassLinkage *iface)
1756 return CONTAINING_RECORD(iface, struct d3d11_class_linkage, ID3D11ClassLinkage_iface);
1759 static HRESULT STDMETHODCALLTYPE d3d11_class_linkage_QueryInterface(ID3D11ClassLinkage *iface,
1760 REFIID riid, void **object)
1762 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
1764 if (IsEqualGUID(riid, &IID_ID3D11ClassLinkage)
1765 || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
1766 || IsEqualGUID(riid, &IID_IUnknown))
1768 ID3D11ClassLinkage_AddRef(*object = iface);
1769 return S_OK;
1772 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
1774 *object = NULL;
1775 return E_NOINTERFACE;
1778 static ULONG STDMETHODCALLTYPE d3d11_class_linkage_AddRef(ID3D11ClassLinkage *iface)
1780 struct d3d11_class_linkage *class_linkage = impl_from_ID3D11ClassLinkage(iface);
1781 ULONG refcount = InterlockedIncrement(&class_linkage->refcount);
1783 TRACE("%p increasing refcount to %u.\n", class_linkage, refcount);
1785 return refcount;
1788 static ULONG STDMETHODCALLTYPE d3d11_class_linkage_Release(ID3D11ClassLinkage *iface)
1790 struct d3d11_class_linkage *class_linkage = impl_from_ID3D11ClassLinkage(iface);
1791 ULONG refcount = InterlockedDecrement(&class_linkage->refcount);
1793 TRACE("%p decreasing refcount to %u.\n", class_linkage, refcount);
1795 if (!refcount)
1797 wined3d_private_store_cleanup(&class_linkage->private_store);
1798 HeapFree(GetProcessHeap(), 0, class_linkage);
1801 return refcount;
1804 static void STDMETHODCALLTYPE d3d11_class_linkage_GetDevice(ID3D11ClassLinkage *iface,
1805 ID3D11Device **device)
1807 FIXME("iface %p, device %p stub!\n", iface, device);
1810 static HRESULT STDMETHODCALLTYPE d3d11_class_linkage_GetPrivateData(ID3D11ClassLinkage *iface,
1811 REFGUID guid, UINT *data_size, void *data)
1813 struct d3d11_class_linkage *class_linkage = impl_from_ID3D11ClassLinkage(iface);
1815 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
1817 return d3d_get_private_data(&class_linkage->private_store, guid, data_size, data);
1820 static HRESULT STDMETHODCALLTYPE d3d11_class_linkage_SetPrivateData(ID3D11ClassLinkage *iface,
1821 REFGUID guid, UINT data_size, const void *data)
1823 struct d3d11_class_linkage *class_linkage = impl_from_ID3D11ClassLinkage(iface);
1825 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
1827 return d3d_set_private_data(&class_linkage->private_store, guid, data_size, data);
1830 static HRESULT STDMETHODCALLTYPE d3d11_class_linkage_SetPrivateDataInterface(ID3D11ClassLinkage *iface,
1831 REFGUID guid, const IUnknown *data)
1833 struct d3d11_class_linkage *class_linkage = impl_from_ID3D11ClassLinkage(iface);
1835 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
1837 return d3d_set_private_data_interface(&class_linkage->private_store, guid, data);
1840 static HRESULT STDMETHODCALLTYPE d3d11_class_linkage_GetClassInstance(ID3D11ClassLinkage *iface,
1841 const char *instance_name, UINT instance_index, ID3D11ClassInstance **class_instance)
1843 FIXME("iface %p, instance_name %s, instance_index %u, class_instance %p stub!\n",
1844 iface, debugstr_a(instance_name), instance_index, class_instance);
1846 return E_NOTIMPL;
1849 static HRESULT STDMETHODCALLTYPE d3d11_class_linkage_CreateClassInstance(ID3D11ClassLinkage *iface,
1850 const char *type_name, UINT cb_offset, UINT cb_vector_offset, UINT texture_offset,
1851 UINT sampler_offset, ID3D11ClassInstance **class_instance)
1853 FIXME("iface %p, type_name %s, cb_offset %u, cb_vector_offset %u, texture_offset %u, "
1854 "sampler_offset %u, class_instance %p stub!\n",
1855 iface, debugstr_a(type_name), cb_offset, cb_vector_offset, texture_offset,
1856 sampler_offset, class_instance);
1858 return E_NOTIMPL;
1861 static const struct ID3D11ClassLinkageVtbl d3d11_class_linkage_vtbl =
1863 /* IUnknown methods */
1864 d3d11_class_linkage_QueryInterface,
1865 d3d11_class_linkage_AddRef,
1866 d3d11_class_linkage_Release,
1867 /* ID3D11DeviceChild methods */
1868 d3d11_class_linkage_GetDevice,
1869 d3d11_class_linkage_GetPrivateData,
1870 d3d11_class_linkage_SetPrivateData,
1871 d3d11_class_linkage_SetPrivateDataInterface,
1872 /* ID3D11ClassLinkage methods */
1873 d3d11_class_linkage_GetClassInstance,
1874 d3d11_class_linkage_CreateClassInstance,
1877 HRESULT d3d11_class_linkage_create(struct d3d_device *device, struct d3d11_class_linkage **class_linkage)
1879 struct d3d11_class_linkage *object;
1881 if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
1882 return E_OUTOFMEMORY;
1884 object->ID3D11ClassLinkage_iface.lpVtbl = &d3d11_class_linkage_vtbl;
1885 object->refcount = 1;
1886 wined3d_private_store_init(&object->private_store);
1888 TRACE("Created class linkage %p.\n", object);
1889 *class_linkage = object;
1891 return S_OK;