combase: Add stub for RoGetApartmentIdentifier.
[wine.git] / dlls / d3d11 / shader.c
blobde0607d2d455b93774c88adc7bbbbd5f51d08bc2
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 (desc->input_signature.elements)
57 FIXME("Multiple input signatures.\n");
58 break;
60 if (FAILED(hr = shader_parse_signature(tag, data, data_size, &desc->input_signature)))
61 return hr;
62 break;
64 case TAG_OSGN:
65 case TAG_OSG5:
66 if (ctx->feature_level <= D3D_FEATURE_LEVEL_9_3)
68 TRACE("Skipping shader output signature on feature level %#x.\n", ctx->feature_level);
69 break;
71 if (desc->output_signature.elements)
73 FIXME("Multiple output signatures.\n");
74 break;
76 if (FAILED(hr = shader_parse_signature(tag, data, data_size, &desc->output_signature)))
77 return hr;
78 break;
80 case TAG_PCSG:
81 if (desc->patch_constant_signature.elements)
83 FIXME("Multiple patch constant signatures.\n");
84 break;
86 if (FAILED(hr = shader_parse_signature(tag, data, data_size, &desc->patch_constant_signature)))
87 return hr;
88 break;
90 case TAG_SHDR:
91 case TAG_SHEX:
92 if (ctx->feature_level <= D3D_FEATURE_LEVEL_9_3)
94 TRACE("Skipping SM4+ shader code on feature level %#x.\n", ctx->feature_level);
95 break;
97 if (desc->byte_code)
98 FIXME("Multiple shader code chunks.\n");
99 desc->byte_code = (const DWORD *)data;
100 desc->byte_code_size = data_size;
101 desc->format = WINED3D_SHADER_BYTE_CODE_FORMAT_SM4;
102 break;
104 case TAG_AON9:
105 if (ctx->feature_level <= D3D_FEATURE_LEVEL_9_3)
107 const struct aon9_header *header = (const struct aon9_header *)data;
108 unsigned int unknown_dword_count;
109 const char *byte_code;
111 if (data_size < sizeof(*header))
113 WARN("Invalid Aon9 data size %#x.\n", data_size);
114 return E_FAIL;
116 byte_code = data + header->byte_code_offset;
117 unknown_dword_count = (header->byte_code_offset - sizeof(*header)) / sizeof(DWORD);
119 if (data_size - 2 * sizeof(DWORD) < header->byte_code_offset)
121 WARN("Invalid byte code offset %#x (size %#x).\n", header->byte_code_offset, data_size);
122 return E_FAIL;
124 FIXME("Skipping %u unknown DWORDs.\n", unknown_dword_count);
126 if (desc->byte_code)
127 FIXME("Multiple shader code chunks.\n");
128 desc->byte_code = (const DWORD *)byte_code;
129 desc->byte_code_size = data_size - header->byte_code_offset;
130 desc->format = WINED3D_SHADER_BYTE_CODE_FORMAT_SM1;
131 TRACE("Feature level 9 shader version 0%08x, 0%08x.\n", header->shader_version, *desc->byte_code);
133 else
135 TRACE("Skipping feature level 9 shader code on feature level %#x.\n", ctx->feature_level);
137 break;
139 case TAG_RDEF:
140 case TAG_STAT:
141 break;
143 default:
144 FIXME("Unhandled chunk %s.\n", debugstr_an((const char *)&tag, 4));
145 break;
148 return S_OK;
151 static void free_shader_desc(struct wined3d_shader_desc *desc)
153 shader_free_signature(&desc->input_signature);
154 shader_free_signature(&desc->output_signature);
155 shader_free_signature(&desc->patch_constant_signature);
158 static HRESULT shader_extract_from_dxbc(const void *dxbc, SIZE_T dxbc_length,
159 struct wined3d_shader_desc *desc, D3D_FEATURE_LEVEL feature_level)
161 struct shader_handler_context ctx = {feature_level, desc};
162 HRESULT hr;
164 desc->byte_code = NULL;
165 desc->byte_code_size = 0;
166 memset(&desc->input_signature, 0, sizeof(desc->input_signature));
167 memset(&desc->output_signature, 0, sizeof(desc->output_signature));
168 memset(&desc->patch_constant_signature, 0, sizeof(desc->patch_constant_signature));
170 hr = parse_dxbc(dxbc, dxbc_length, shdr_handler, &ctx);
171 if (!desc->byte_code)
172 hr = E_INVALIDARG;
174 if (FAILED(hr))
176 FIXME("Failed to parse shader, hr %#x.\n", hr);
177 free_shader_desc(desc);
180 return hr;
183 static const char *shader_get_string(const char *data, size_t data_size, DWORD offset)
185 size_t len, max_len;
187 if (offset >= data_size)
189 WARN("Invalid offset %#x (data size %#lx).\n", offset, (long)data_size);
190 return NULL;
193 max_len = data_size - offset;
194 len = strnlen(data + offset, max_len);
196 if (len == max_len)
197 return NULL;
199 return data + offset;
202 HRESULT shader_parse_signature(DWORD tag, const char *data, DWORD data_size,
203 struct wined3d_shader_signature *s)
205 struct wined3d_shader_signature_element *e;
206 const char *ptr = data;
207 unsigned int i;
208 DWORD count;
210 if (!require_space(0, 2, sizeof(DWORD), data_size))
212 WARN("Invalid data size %#x.\n", data_size);
213 return E_INVALIDARG;
216 read_dword(&ptr, &count);
217 TRACE("%u elements.\n", count);
219 skip_dword_unknown(&ptr, 1); /* It seems to always be 0x00000008. */
221 if (!require_space(ptr - data, count, 6 * sizeof(DWORD), data_size))
223 WARN("Invalid count %#x (data size %#x).\n", count, data_size);
224 return E_INVALIDARG;
227 if (!(e = heap_calloc(count, sizeof(*e))))
229 ERR("Failed to allocate input signature memory.\n");
230 return E_OUTOFMEMORY;
233 for (i = 0; i < count; ++i)
235 DWORD name_offset;
237 if (tag == TAG_OSG5)
238 read_dword(&ptr, &e[i].stream_idx);
239 else
240 e[i].stream_idx = 0;
241 read_dword(&ptr, &name_offset);
242 if (!(e[i].semantic_name = shader_get_string(data, data_size, name_offset)))
244 WARN("Invalid name offset %#x (data size %#x).\n", name_offset, data_size);
245 heap_free(e);
246 return E_INVALIDARG;
248 read_dword(&ptr, &e[i].semantic_idx);
249 read_dword(&ptr, &e[i].sysval_semantic);
250 read_dword(&ptr, &e[i].component_type);
251 read_dword(&ptr, &e[i].register_idx);
252 read_dword(&ptr, &e[i].mask);
254 TRACE("Stream: %u, semantic: %s, semantic idx: %u, sysval_semantic %#x, "
255 "type %u, register idx: %u, use_mask %#x, input_mask %#x.\n",
256 e[i].stream_idx, debugstr_a(e[i].semantic_name), e[i].semantic_idx, e[i].sysval_semantic,
257 e[i].component_type, e[i].register_idx, (e[i].mask >> 8) & 0xff, e[i].mask & 0xff);
260 s->elements = e;
261 s->element_count = count;
263 return S_OK;
266 struct wined3d_shader_signature_element *shader_find_signature_element(const struct wined3d_shader_signature *s,
267 const char *semantic_name, unsigned int semantic_idx, unsigned int stream_idx)
269 struct wined3d_shader_signature_element *e = s->elements;
270 unsigned int i;
272 for (i = 0; i < s->element_count; ++i)
274 if (!strcasecmp(e[i].semantic_name, semantic_name) && e[i].semantic_idx == semantic_idx
275 && e[i].stream_idx == stream_idx)
276 return &e[i];
279 return NULL;
282 void shader_free_signature(struct wined3d_shader_signature *s)
284 heap_free(s->elements);
287 /* ID3D11VertexShader methods */
289 static inline struct d3d_vertex_shader *impl_from_ID3D11VertexShader(ID3D11VertexShader *iface)
291 return CONTAINING_RECORD(iface, struct d3d_vertex_shader, ID3D11VertexShader_iface);
294 static HRESULT STDMETHODCALLTYPE d3d11_vertex_shader_QueryInterface(ID3D11VertexShader *iface,
295 REFIID riid, void **object)
297 struct d3d_vertex_shader *shader = impl_from_ID3D11VertexShader(iface);
299 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
301 if (IsEqualGUID(riid, &IID_ID3D11VertexShader)
302 || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
303 || IsEqualGUID(riid, &IID_IUnknown))
305 ID3D11VertexShader_AddRef(iface);
306 *object = iface;
307 return S_OK;
310 if (IsEqualGUID(riid, &IID_ID3D10VertexShader)
311 || IsEqualGUID(riid, &IID_ID3D10DeviceChild))
313 IUnknown_AddRef(&shader->ID3D10VertexShader_iface);
314 *object = &shader->ID3D10VertexShader_iface;
315 return S_OK;
318 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
320 *object = NULL;
321 return E_NOINTERFACE;
324 static ULONG STDMETHODCALLTYPE d3d11_vertex_shader_AddRef(ID3D11VertexShader *iface)
326 struct d3d_vertex_shader *shader = impl_from_ID3D11VertexShader(iface);
327 ULONG refcount = InterlockedIncrement(&shader->refcount);
329 TRACE("%p increasing refcount to %u.\n", shader, refcount);
331 if (refcount == 1)
333 ID3D11Device1_AddRef(shader->device);
334 wined3d_mutex_lock();
335 wined3d_shader_incref(shader->wined3d_shader);
336 wined3d_mutex_unlock();
339 return refcount;
342 static ULONG STDMETHODCALLTYPE d3d11_vertex_shader_Release(ID3D11VertexShader *iface)
344 struct d3d_vertex_shader *shader = impl_from_ID3D11VertexShader(iface);
345 ULONG refcount = InterlockedDecrement(&shader->refcount);
347 TRACE("%p decreasing refcount to %u.\n", shader, refcount);
349 if (!refcount)
351 ID3D11Device1 *device = shader->device;
353 wined3d_mutex_lock();
354 wined3d_shader_decref(shader->wined3d_shader);
355 wined3d_mutex_unlock();
356 /* Release the device last, it may cause the wined3d device to be
357 * destroyed. */
358 ID3D11Device1_Release(device);
361 return refcount;
364 static void STDMETHODCALLTYPE d3d11_vertex_shader_GetDevice(ID3D11VertexShader *iface,
365 ID3D11Device **device)
367 struct d3d_vertex_shader *shader = impl_from_ID3D11VertexShader(iface);
369 TRACE("iface %p, device %p.\n", iface, device);
371 *device = (ID3D11Device *)shader->device;
372 ID3D11Device_AddRef(*device);
375 static HRESULT STDMETHODCALLTYPE d3d11_vertex_shader_GetPrivateData(ID3D11VertexShader *iface,
376 REFGUID guid, UINT *data_size, void *data)
378 struct d3d_vertex_shader *shader = impl_from_ID3D11VertexShader(iface);
380 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
382 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
385 static HRESULT STDMETHODCALLTYPE d3d11_vertex_shader_SetPrivateData(ID3D11VertexShader *iface,
386 REFGUID guid, UINT data_size, const void *data)
388 struct d3d_vertex_shader *shader = impl_from_ID3D11VertexShader(iface);
390 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
392 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
395 static HRESULT STDMETHODCALLTYPE d3d11_vertex_shader_SetPrivateDataInterface(ID3D11VertexShader *iface,
396 REFGUID guid, const IUnknown *data)
398 struct d3d_vertex_shader *shader = impl_from_ID3D11VertexShader(iface);
400 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
402 return d3d_set_private_data_interface(&shader->private_store, guid, data);
405 static const struct ID3D11VertexShaderVtbl d3d11_vertex_shader_vtbl =
407 /* IUnknown methods */
408 d3d11_vertex_shader_QueryInterface,
409 d3d11_vertex_shader_AddRef,
410 d3d11_vertex_shader_Release,
411 /* ID3D11DeviceChild methods */
412 d3d11_vertex_shader_GetDevice,
413 d3d11_vertex_shader_GetPrivateData,
414 d3d11_vertex_shader_SetPrivateData,
415 d3d11_vertex_shader_SetPrivateDataInterface,
418 /* ID3D10VertexShader methods */
420 static inline struct d3d_vertex_shader *impl_from_ID3D10VertexShader(ID3D10VertexShader *iface)
422 return CONTAINING_RECORD(iface, struct d3d_vertex_shader, ID3D10VertexShader_iface);
425 /* IUnknown methods */
427 static HRESULT STDMETHODCALLTYPE d3d10_vertex_shader_QueryInterface(ID3D10VertexShader *iface,
428 REFIID riid, void **object)
430 struct d3d_vertex_shader *shader = impl_from_ID3D10VertexShader(iface);
432 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
434 return d3d11_vertex_shader_QueryInterface(&shader->ID3D11VertexShader_iface, riid, object);
437 static ULONG STDMETHODCALLTYPE d3d10_vertex_shader_AddRef(ID3D10VertexShader *iface)
439 struct d3d_vertex_shader *shader = impl_from_ID3D10VertexShader(iface);
441 TRACE("iface %p.\n", iface);
443 return d3d11_vertex_shader_AddRef(&shader->ID3D11VertexShader_iface);
446 static ULONG STDMETHODCALLTYPE d3d10_vertex_shader_Release(ID3D10VertexShader *iface)
448 struct d3d_vertex_shader *shader = impl_from_ID3D10VertexShader(iface);
450 TRACE("iface %p.\n", iface);
452 return d3d11_vertex_shader_Release(&shader->ID3D11VertexShader_iface);
455 /* ID3D10DeviceChild methods */
457 static void STDMETHODCALLTYPE d3d10_vertex_shader_GetDevice(ID3D10VertexShader *iface, ID3D10Device **device)
459 struct d3d_vertex_shader *shader = impl_from_ID3D10VertexShader(iface);
461 TRACE("iface %p, device %p.\n", iface, device);
463 ID3D11Device1_QueryInterface(shader->device, &IID_ID3D10Device, (void **)device);
466 static HRESULT STDMETHODCALLTYPE d3d10_vertex_shader_GetPrivateData(ID3D10VertexShader *iface,
467 REFGUID guid, UINT *data_size, void *data)
469 struct d3d_vertex_shader *shader = impl_from_ID3D10VertexShader(iface);
471 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
472 iface, debugstr_guid(guid), data_size, data);
474 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
477 static HRESULT STDMETHODCALLTYPE d3d10_vertex_shader_SetPrivateData(ID3D10VertexShader *iface,
478 REFGUID guid, UINT data_size, const void *data)
480 struct d3d_vertex_shader *shader = impl_from_ID3D10VertexShader(iface);
482 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
483 iface, debugstr_guid(guid), data_size, data);
485 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
488 static HRESULT STDMETHODCALLTYPE d3d10_vertex_shader_SetPrivateDataInterface(ID3D10VertexShader *iface,
489 REFGUID guid, const IUnknown *data)
491 struct d3d_vertex_shader *shader = impl_from_ID3D10VertexShader(iface);
493 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
495 return d3d_set_private_data_interface(&shader->private_store, guid, data);
498 static const struct ID3D10VertexShaderVtbl d3d10_vertex_shader_vtbl =
500 /* IUnknown methods */
501 d3d10_vertex_shader_QueryInterface,
502 d3d10_vertex_shader_AddRef,
503 d3d10_vertex_shader_Release,
504 /* ID3D10DeviceChild methods */
505 d3d10_vertex_shader_GetDevice,
506 d3d10_vertex_shader_GetPrivateData,
507 d3d10_vertex_shader_SetPrivateData,
508 d3d10_vertex_shader_SetPrivateDataInterface,
511 static void STDMETHODCALLTYPE d3d_vertex_shader_wined3d_object_destroyed(void *parent)
513 struct d3d_vertex_shader *shader = parent;
515 wined3d_private_store_cleanup(&shader->private_store);
516 heap_free(parent);
519 static const struct wined3d_parent_ops d3d_vertex_shader_wined3d_parent_ops =
521 d3d_vertex_shader_wined3d_object_destroyed,
524 static unsigned int d3d_sm_from_feature_level(D3D_FEATURE_LEVEL feature_level)
526 switch (feature_level)
528 case D3D_FEATURE_LEVEL_11_1:
529 case D3D_FEATURE_LEVEL_11_0:
530 return 5;
531 case D3D_FEATURE_LEVEL_10_1:
532 case D3D_FEATURE_LEVEL_10_0:
533 return 4;
534 case D3D_FEATURE_LEVEL_9_3:
535 return 3;
536 case D3D_FEATURE_LEVEL_9_2:
537 case D3D_FEATURE_LEVEL_9_1:
538 return 2;
539 default:
540 ERR("Unexpected feature_level %#x.\n", feature_level);
542 return 0;
545 static HRESULT d3d_vertex_shader_init(struct d3d_vertex_shader *shader, struct d3d_device *device,
546 const void *byte_code, SIZE_T byte_code_length)
548 struct wined3d_shader_desc desc;
549 HRESULT hr;
551 shader->ID3D11VertexShader_iface.lpVtbl = &d3d11_vertex_shader_vtbl;
552 shader->ID3D10VertexShader_iface.lpVtbl = &d3d10_vertex_shader_vtbl;
553 shader->refcount = 1;
554 wined3d_mutex_lock();
555 wined3d_private_store_init(&shader->private_store);
557 if (FAILED(hr = shader_extract_from_dxbc(byte_code, byte_code_length, &desc, device->feature_level)))
559 WARN("Failed to extract shader, hr %#x.\n", hr);
560 wined3d_private_store_cleanup(&shader->private_store);
561 wined3d_mutex_unlock();
562 return hr;
564 desc.max_version = d3d_sm_from_feature_level(device->feature_level);
566 hr = wined3d_shader_create_vs(device->wined3d_device, &desc, shader,
567 &d3d_vertex_shader_wined3d_parent_ops, &shader->wined3d_shader);
568 free_shader_desc(&desc);
569 if (FAILED(hr))
571 WARN("Failed to create wined3d vertex shader, hr %#x.\n", hr);
572 wined3d_private_store_cleanup(&shader->private_store);
573 wined3d_mutex_unlock();
574 return E_INVALIDARG;
576 wined3d_mutex_unlock();
578 shader->device = &device->ID3D11Device1_iface;
579 ID3D11Device1_AddRef(shader->device);
581 return S_OK;
584 HRESULT d3d_vertex_shader_create(struct d3d_device *device, const void *byte_code, SIZE_T byte_code_length,
585 struct d3d_vertex_shader **shader)
587 struct d3d_vertex_shader *object;
588 HRESULT hr;
590 if (!(object = heap_alloc_zero(sizeof(*object))))
591 return E_OUTOFMEMORY;
593 if (FAILED(hr = d3d_vertex_shader_init(object, device, byte_code, byte_code_length)))
595 WARN("Failed to initialize vertex shader, hr %#x.\n", hr);
596 heap_free(object);
597 return hr;
600 TRACE("Created vertex shader %p.\n", object);
601 *shader = object;
603 return S_OK;
606 struct d3d_vertex_shader *unsafe_impl_from_ID3D11VertexShader(ID3D11VertexShader *iface)
608 if (!iface)
609 return NULL;
610 assert(iface->lpVtbl == &d3d11_vertex_shader_vtbl);
612 return impl_from_ID3D11VertexShader(iface);
615 struct d3d_vertex_shader *unsafe_impl_from_ID3D10VertexShader(ID3D10VertexShader *iface)
617 if (!iface)
618 return NULL;
619 assert(iface->lpVtbl == &d3d10_vertex_shader_vtbl);
621 return impl_from_ID3D10VertexShader(iface);
624 /* ID3D11HullShader methods */
626 static inline struct d3d11_hull_shader *impl_from_ID3D11HullShader(ID3D11HullShader *iface)
628 return CONTAINING_RECORD(iface, struct d3d11_hull_shader, ID3D11HullShader_iface);
631 static HRESULT STDMETHODCALLTYPE d3d11_hull_shader_QueryInterface(ID3D11HullShader *iface,
632 REFIID riid, void **object)
634 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
636 if (IsEqualGUID(riid, &IID_ID3D11HullShader)
637 || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
638 || IsEqualGUID(riid, &IID_IUnknown))
640 ID3D11HullShader_AddRef(iface);
641 *object = iface;
642 return S_OK;
645 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
647 *object = NULL;
648 return E_NOINTERFACE;
651 static ULONG STDMETHODCALLTYPE d3d11_hull_shader_AddRef(ID3D11HullShader *iface)
653 struct d3d11_hull_shader *shader = impl_from_ID3D11HullShader(iface);
654 ULONG refcount = InterlockedIncrement(&shader->refcount);
656 TRACE("%p increasing refcount to %u.\n", shader, refcount);
658 if (refcount == 1)
660 ID3D11Device1_AddRef(shader->device);
661 wined3d_mutex_lock();
662 wined3d_shader_incref(shader->wined3d_shader);
663 wined3d_mutex_unlock();
666 return refcount;
669 static ULONG STDMETHODCALLTYPE d3d11_hull_shader_Release(ID3D11HullShader *iface)
671 struct d3d11_hull_shader *shader = impl_from_ID3D11HullShader(iface);
672 ULONG refcount = InterlockedDecrement(&shader->refcount);
674 TRACE("%p decreasing refcount to %u.\n", shader, refcount);
676 if (!refcount)
678 ID3D11Device1 *device = shader->device;
680 wined3d_mutex_lock();
681 wined3d_shader_decref(shader->wined3d_shader);
682 wined3d_mutex_unlock();
684 /* Release the device last, it may cause the wined3d device to be
685 * destroyed. */
686 ID3D11Device1_Release(device);
689 return refcount;
692 static void STDMETHODCALLTYPE d3d11_hull_shader_GetDevice(ID3D11HullShader *iface,
693 ID3D11Device **device)
695 struct d3d11_hull_shader *shader = impl_from_ID3D11HullShader(iface);
697 TRACE("iface %p, device %p.\n", iface, device);
699 *device = (ID3D11Device *)shader->device;
700 ID3D11Device_AddRef(*device);
703 static HRESULT STDMETHODCALLTYPE d3d11_hull_shader_GetPrivateData(ID3D11HullShader *iface,
704 REFGUID guid, UINT *data_size, void *data)
706 struct d3d11_hull_shader *shader = impl_from_ID3D11HullShader(iface);
708 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
710 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
713 static HRESULT STDMETHODCALLTYPE d3d11_hull_shader_SetPrivateData(ID3D11HullShader *iface,
714 REFGUID guid, UINT data_size, const void *data)
716 struct d3d11_hull_shader *shader = impl_from_ID3D11HullShader(iface);
718 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
720 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
723 static HRESULT STDMETHODCALLTYPE d3d11_hull_shader_SetPrivateDataInterface(ID3D11HullShader *iface,
724 REFGUID guid, const IUnknown *data)
726 struct d3d11_hull_shader *shader = impl_from_ID3D11HullShader(iface);
728 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
730 return d3d_set_private_data_interface(&shader->private_store, guid, data);
733 static const struct ID3D11HullShaderVtbl d3d11_hull_shader_vtbl =
735 /* IUnknown methods */
736 d3d11_hull_shader_QueryInterface,
737 d3d11_hull_shader_AddRef,
738 d3d11_hull_shader_Release,
739 /* ID3D11DeviceChild methods */
740 d3d11_hull_shader_GetDevice,
741 d3d11_hull_shader_GetPrivateData,
742 d3d11_hull_shader_SetPrivateData,
743 d3d11_hull_shader_SetPrivateDataInterface,
746 static void STDMETHODCALLTYPE d3d11_hull_shader_wined3d_object_destroyed(void *parent)
748 struct d3d11_hull_shader *shader = parent;
750 wined3d_private_store_cleanup(&shader->private_store);
751 heap_free(parent);
754 static const struct wined3d_parent_ops d3d11_hull_shader_wined3d_parent_ops =
756 d3d11_hull_shader_wined3d_object_destroyed,
759 static HRESULT d3d11_hull_shader_init(struct d3d11_hull_shader *shader, struct d3d_device *device,
760 const void *byte_code, SIZE_T byte_code_length)
762 struct wined3d_shader_desc desc;
763 HRESULT hr;
765 shader->ID3D11HullShader_iface.lpVtbl = &d3d11_hull_shader_vtbl;
766 shader->refcount = 1;
767 wined3d_mutex_lock();
768 wined3d_private_store_init(&shader->private_store);
770 if (FAILED(hr = shader_extract_from_dxbc(byte_code, byte_code_length, &desc, device->feature_level)))
772 WARN("Failed to extract shader, hr %#x.\n", hr);
773 wined3d_private_store_cleanup(&shader->private_store);
774 wined3d_mutex_unlock();
775 return hr;
777 desc.max_version = d3d_sm_from_feature_level(device->feature_level);
779 hr = wined3d_shader_create_hs(device->wined3d_device, &desc, shader,
780 &d3d11_hull_shader_wined3d_parent_ops, &shader->wined3d_shader);
781 free_shader_desc(&desc);
782 if (FAILED(hr))
784 WARN("Failed to create wined3d hull shader, hr %#x.\n", hr);
785 wined3d_private_store_cleanup(&shader->private_store);
786 wined3d_mutex_unlock();
787 return E_INVALIDARG;
789 wined3d_mutex_unlock();
791 shader->device = &device->ID3D11Device1_iface;
792 ID3D11Device1_AddRef(shader->device);
794 return S_OK;
797 HRESULT d3d11_hull_shader_create(struct d3d_device *device, const void *byte_code, SIZE_T byte_code_length,
798 struct d3d11_hull_shader **shader)
800 struct d3d11_hull_shader *object;
801 HRESULT hr;
803 if (!(object = heap_alloc_zero(sizeof(*object))))
804 return E_OUTOFMEMORY;
806 if (FAILED(hr = d3d11_hull_shader_init(object, device, byte_code, byte_code_length)))
808 heap_free(object);
809 return hr;
812 TRACE("Created hull shader %p.\n", object);
813 *shader = object;
815 return S_OK;
818 struct d3d11_hull_shader *unsafe_impl_from_ID3D11HullShader(ID3D11HullShader *iface)
820 if (!iface)
821 return NULL;
822 assert(iface->lpVtbl == &d3d11_hull_shader_vtbl);
824 return impl_from_ID3D11HullShader(iface);
827 /* ID3D11DomainShader methods */
829 static inline struct d3d11_domain_shader *impl_from_ID3D11DomainShader(ID3D11DomainShader *iface)
831 return CONTAINING_RECORD(iface, struct d3d11_domain_shader, ID3D11DomainShader_iface);
834 static HRESULT STDMETHODCALLTYPE d3d11_domain_shader_QueryInterface(ID3D11DomainShader *iface,
835 REFIID riid, void **object)
837 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
839 if (IsEqualGUID(riid, &IID_ID3D11DomainShader)
840 || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
841 || IsEqualGUID(riid, &IID_IUnknown))
843 ID3D11DomainShader_AddRef(iface);
844 *object = iface;
845 return S_OK;
848 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
850 *object = NULL;
851 return E_NOINTERFACE;
854 static ULONG STDMETHODCALLTYPE d3d11_domain_shader_AddRef(ID3D11DomainShader *iface)
856 struct d3d11_domain_shader *shader = impl_from_ID3D11DomainShader(iface);
857 ULONG refcount = InterlockedIncrement(&shader->refcount);
859 TRACE("%p increasing refcount to %u.\n", shader, refcount);
861 if (refcount == 1)
863 ID3D11Device1_AddRef(shader->device);
864 wined3d_mutex_lock();
865 wined3d_shader_incref(shader->wined3d_shader);
866 wined3d_mutex_unlock();
869 return refcount;
872 static ULONG STDMETHODCALLTYPE d3d11_domain_shader_Release(ID3D11DomainShader *iface)
874 struct d3d11_domain_shader *shader = impl_from_ID3D11DomainShader(iface);
875 ULONG refcount = InterlockedDecrement(&shader->refcount);
877 TRACE("%p decreasing refcount to %u.\n", shader, refcount);
879 if (!refcount)
881 ID3D11Device1 *device = shader->device;
883 wined3d_mutex_lock();
884 wined3d_shader_decref(shader->wined3d_shader);
885 wined3d_mutex_unlock();
887 /* Release the device last, it may cause the wined3d device to be
888 * destroyed. */
889 ID3D11Device1_Release(device);
892 return refcount;
895 static void STDMETHODCALLTYPE d3d11_domain_shader_GetDevice(ID3D11DomainShader *iface,
896 ID3D11Device **device)
898 struct d3d11_domain_shader *shader = impl_from_ID3D11DomainShader(iface);
900 TRACE("iface %p, device %p.\n", iface, device);
902 *device = (ID3D11Device *)shader->device;
903 ID3D11Device_AddRef(*device);
906 static HRESULT STDMETHODCALLTYPE d3d11_domain_shader_GetPrivateData(ID3D11DomainShader *iface,
907 REFGUID guid, UINT *data_size, void *data)
909 struct d3d11_domain_shader *shader = impl_from_ID3D11DomainShader(iface);
911 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
913 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
916 static HRESULT STDMETHODCALLTYPE d3d11_domain_shader_SetPrivateData(ID3D11DomainShader *iface,
917 REFGUID guid, UINT data_size, const void *data)
919 struct d3d11_domain_shader *shader = impl_from_ID3D11DomainShader(iface);
921 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
923 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
926 static HRESULT STDMETHODCALLTYPE d3d11_domain_shader_SetPrivateDataInterface(ID3D11DomainShader *iface,
927 REFGUID guid, const IUnknown *data)
929 struct d3d11_domain_shader *shader = impl_from_ID3D11DomainShader(iface);
931 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
933 return d3d_set_private_data_interface(&shader->private_store, guid, data);
936 static const struct ID3D11DomainShaderVtbl d3d11_domain_shader_vtbl =
938 /* IUnknown methods */
939 d3d11_domain_shader_QueryInterface,
940 d3d11_domain_shader_AddRef,
941 d3d11_domain_shader_Release,
942 /* ID3D11DeviceChild methods */
943 d3d11_domain_shader_GetDevice,
944 d3d11_domain_shader_GetPrivateData,
945 d3d11_domain_shader_SetPrivateData,
946 d3d11_domain_shader_SetPrivateDataInterface,
949 static void STDMETHODCALLTYPE d3d11_domain_shader_wined3d_object_destroyed(void *parent)
951 struct d3d11_domain_shader *shader = parent;
953 wined3d_private_store_cleanup(&shader->private_store);
954 heap_free(parent);
957 static const struct wined3d_parent_ops d3d11_domain_shader_wined3d_parent_ops =
959 d3d11_domain_shader_wined3d_object_destroyed,
962 static HRESULT d3d11_domain_shader_init(struct d3d11_domain_shader *shader, struct d3d_device *device,
963 const void *byte_code, SIZE_T byte_code_length)
965 struct wined3d_shader_desc desc;
966 HRESULT hr;
968 shader->ID3D11DomainShader_iface.lpVtbl = &d3d11_domain_shader_vtbl;
969 shader->refcount = 1;
970 wined3d_mutex_lock();
971 wined3d_private_store_init(&shader->private_store);
973 if (FAILED(hr = shader_extract_from_dxbc(byte_code, byte_code_length, &desc, device->feature_level)))
975 WARN("Failed to extract shader, hr %#x.\n", hr);
976 wined3d_private_store_cleanup(&shader->private_store);
977 wined3d_mutex_unlock();
978 return hr;
980 desc.max_version = d3d_sm_from_feature_level(device->feature_level);
982 hr = wined3d_shader_create_ds(device->wined3d_device, &desc, shader,
983 &d3d11_domain_shader_wined3d_parent_ops, &shader->wined3d_shader);
984 free_shader_desc(&desc);
985 if (FAILED(hr))
987 WARN("Failed to create wined3d domain shader, hr %#x.\n", hr);
988 wined3d_private_store_cleanup(&shader->private_store);
989 wined3d_mutex_unlock();
990 return E_INVALIDARG;
992 wined3d_mutex_unlock();
994 shader->device = &device->ID3D11Device1_iface;
995 ID3D11Device1_AddRef(shader->device);
997 return S_OK;
1000 HRESULT d3d11_domain_shader_create(struct d3d_device *device, const void *byte_code, SIZE_T byte_code_length,
1001 struct d3d11_domain_shader **shader)
1003 struct d3d11_domain_shader *object;
1004 HRESULT hr;
1006 if (!(object = heap_alloc_zero(sizeof(*object))))
1007 return E_OUTOFMEMORY;
1009 if (FAILED(hr = d3d11_domain_shader_init(object, device, byte_code, byte_code_length)))
1011 heap_free(object);
1012 return hr;
1015 TRACE("Created domain shader %p.\n", object);
1016 *shader = object;
1018 return S_OK;
1021 struct d3d11_domain_shader *unsafe_impl_from_ID3D11DomainShader(ID3D11DomainShader *iface)
1023 if (!iface)
1024 return NULL;
1025 assert(iface->lpVtbl == &d3d11_domain_shader_vtbl);
1027 return impl_from_ID3D11DomainShader(iface);
1030 /* ID3D11GeometryShader methods */
1032 static inline struct d3d_geometry_shader *impl_from_ID3D11GeometryShader(ID3D11GeometryShader *iface)
1034 return CONTAINING_RECORD(iface, struct d3d_geometry_shader, ID3D11GeometryShader_iface);
1037 static HRESULT STDMETHODCALLTYPE d3d11_geometry_shader_QueryInterface(ID3D11GeometryShader *iface,
1038 REFIID riid, void **object)
1040 struct d3d_geometry_shader *shader = impl_from_ID3D11GeometryShader(iface);
1042 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
1044 if (IsEqualGUID(riid, &IID_ID3D11GeometryShader)
1045 || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
1046 || IsEqualGUID(riid, &IID_IUnknown))
1048 ID3D11GeometryShader_AddRef(iface);
1049 *object = iface;
1050 return S_OK;
1053 if (IsEqualGUID(riid, &IID_ID3D10GeometryShader)
1054 || IsEqualGUID(riid, &IID_ID3D10DeviceChild))
1056 ID3D10GeometryShader_AddRef(&shader->ID3D10GeometryShader_iface);
1057 *object = &shader->ID3D10GeometryShader_iface;
1058 return S_OK;
1061 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
1063 *object = NULL;
1064 return E_NOINTERFACE;
1067 static ULONG STDMETHODCALLTYPE d3d11_geometry_shader_AddRef(ID3D11GeometryShader *iface)
1069 struct d3d_geometry_shader *shader = impl_from_ID3D11GeometryShader(iface);
1070 ULONG refcount = InterlockedIncrement(&shader->refcount);
1072 TRACE("%p increasing refcount to %u.\n", shader, refcount);
1074 if (refcount == 1)
1076 ID3D11Device1_AddRef(shader->device);
1077 wined3d_mutex_lock();
1078 wined3d_shader_incref(shader->wined3d_shader);
1079 wined3d_mutex_unlock();
1082 return refcount;
1085 static ULONG STDMETHODCALLTYPE d3d11_geometry_shader_Release(ID3D11GeometryShader *iface)
1087 struct d3d_geometry_shader *shader = impl_from_ID3D11GeometryShader(iface);
1088 ULONG refcount = InterlockedDecrement(&shader->refcount);
1090 TRACE("%p decreasing refcount to %u.\n", shader, refcount);
1092 if (!refcount)
1094 ID3D11Device1 *device = shader->device;
1096 wined3d_mutex_lock();
1097 wined3d_shader_decref(shader->wined3d_shader);
1098 wined3d_mutex_unlock();
1100 /* Release the device last, it may cause the wined3d device to be
1101 * destroyed. */
1102 ID3D11Device1_Release(device);
1105 return refcount;
1108 static void STDMETHODCALLTYPE d3d11_geometry_shader_GetDevice(ID3D11GeometryShader *iface,
1109 ID3D11Device **device)
1111 struct d3d_geometry_shader *shader = impl_from_ID3D11GeometryShader(iface);
1113 TRACE("iface %p, device %p.\n", iface, device);
1115 *device = (ID3D11Device *)shader->device;
1116 ID3D11Device_AddRef(*device);
1119 static HRESULT STDMETHODCALLTYPE d3d11_geometry_shader_GetPrivateData(ID3D11GeometryShader *iface,
1120 REFGUID guid, UINT *data_size, void *data)
1122 struct d3d_geometry_shader *shader = impl_from_ID3D11GeometryShader(iface);
1124 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
1126 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
1129 static HRESULT STDMETHODCALLTYPE d3d11_geometry_shader_SetPrivateData(ID3D11GeometryShader *iface,
1130 REFGUID guid, UINT data_size, const void *data)
1132 struct d3d_geometry_shader *shader = impl_from_ID3D11GeometryShader(iface);
1134 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
1136 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
1139 static HRESULT STDMETHODCALLTYPE d3d11_geometry_shader_SetPrivateDataInterface(ID3D11GeometryShader *iface,
1140 REFGUID guid, const IUnknown *data)
1142 struct d3d_geometry_shader *shader = impl_from_ID3D11GeometryShader(iface);
1144 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
1146 return d3d_set_private_data_interface(&shader->private_store, guid, data);
1149 static const struct ID3D11GeometryShaderVtbl d3d11_geometry_shader_vtbl =
1151 /* IUnknown methods */
1152 d3d11_geometry_shader_QueryInterface,
1153 d3d11_geometry_shader_AddRef,
1154 d3d11_geometry_shader_Release,
1155 /* ID3D11DeviceChild methods */
1156 d3d11_geometry_shader_GetDevice,
1157 d3d11_geometry_shader_GetPrivateData,
1158 d3d11_geometry_shader_SetPrivateData,
1159 d3d11_geometry_shader_SetPrivateDataInterface,
1162 /* ID3D10GeometryShader methods */
1164 static inline struct d3d_geometry_shader *impl_from_ID3D10GeometryShader(ID3D10GeometryShader *iface)
1166 return CONTAINING_RECORD(iface, struct d3d_geometry_shader, ID3D10GeometryShader_iface);
1169 /* IUnknown methods */
1171 static HRESULT STDMETHODCALLTYPE d3d10_geometry_shader_QueryInterface(ID3D10GeometryShader *iface,
1172 REFIID riid, void **object)
1174 struct d3d_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface);
1176 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
1178 return d3d11_geometry_shader_QueryInterface(&shader->ID3D11GeometryShader_iface, riid, object);
1181 static ULONG STDMETHODCALLTYPE d3d10_geometry_shader_AddRef(ID3D10GeometryShader *iface)
1183 struct d3d_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface);
1185 TRACE("iface %p.\n", iface);
1187 return d3d11_geometry_shader_AddRef(&shader->ID3D11GeometryShader_iface);
1190 static ULONG STDMETHODCALLTYPE d3d10_geometry_shader_Release(ID3D10GeometryShader *iface)
1192 struct d3d_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface);
1194 TRACE("iface %p.\n", iface);
1196 return d3d11_geometry_shader_Release(&shader->ID3D11GeometryShader_iface);
1199 /* ID3D10DeviceChild methods */
1201 static void STDMETHODCALLTYPE d3d10_geometry_shader_GetDevice(ID3D10GeometryShader *iface, ID3D10Device **device)
1203 struct d3d_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface);
1205 TRACE("iface %p, device %p.\n", iface, device);
1207 ID3D11Device1_QueryInterface(shader->device, &IID_ID3D10Device, (void **)device);
1210 static HRESULT STDMETHODCALLTYPE d3d10_geometry_shader_GetPrivateData(ID3D10GeometryShader *iface,
1211 REFGUID guid, UINT *data_size, void *data)
1213 struct d3d_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface);
1215 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
1216 iface, debugstr_guid(guid), data_size, data);
1218 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
1221 static HRESULT STDMETHODCALLTYPE d3d10_geometry_shader_SetPrivateData(ID3D10GeometryShader *iface,
1222 REFGUID guid, UINT data_size, const void *data)
1224 struct d3d_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface);
1226 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
1227 iface, debugstr_guid(guid), data_size, data);
1229 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
1232 static HRESULT STDMETHODCALLTYPE d3d10_geometry_shader_SetPrivateDataInterface(ID3D10GeometryShader *iface,
1233 REFGUID guid, const IUnknown *data)
1235 struct d3d_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface);
1237 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
1239 return d3d_set_private_data_interface(&shader->private_store, guid, data);
1242 static const struct ID3D10GeometryShaderVtbl d3d10_geometry_shader_vtbl =
1244 /* IUnknown methods */
1245 d3d10_geometry_shader_QueryInterface,
1246 d3d10_geometry_shader_AddRef,
1247 d3d10_geometry_shader_Release,
1248 /* ID3D10DeviceChild methods */
1249 d3d10_geometry_shader_GetDevice,
1250 d3d10_geometry_shader_GetPrivateData,
1251 d3d10_geometry_shader_SetPrivateData,
1252 d3d10_geometry_shader_SetPrivateDataInterface,
1255 static void STDMETHODCALLTYPE d3d_geometry_shader_wined3d_object_destroyed(void *parent)
1257 struct d3d_geometry_shader *shader = parent;
1259 wined3d_private_store_cleanup(&shader->private_store);
1260 heap_free(parent);
1263 static const struct wined3d_parent_ops d3d_geometry_shader_wined3d_parent_ops =
1265 d3d_geometry_shader_wined3d_object_destroyed,
1268 static HRESULT wined3d_so_elements_from_d3d11_so_entries(struct wined3d_stream_output_element *elements,
1269 const D3D11_SO_DECLARATION_ENTRY *entries, unsigned int entry_count,
1270 const unsigned int *buffer_strides, unsigned int buffer_stride_count,
1271 const struct wined3d_shader_signature *os, D3D_FEATURE_LEVEL feature_level)
1273 unsigned int i, j, mask;
1275 for (i = 0; i < entry_count; ++i)
1277 struct wined3d_stream_output_element *e = &elements[i];
1278 const D3D11_SO_DECLARATION_ENTRY *f = &entries[i];
1279 struct wined3d_shader_signature_element *output;
1281 TRACE("Stream: %u, semantic: %s, semantic idx: %u, start component: %u, "
1282 "component count %u, output slot %u.\n",
1283 f->Stream, debugstr_a(f->SemanticName), f->SemanticIndex,
1284 f->StartComponent, f->ComponentCount, f->OutputSlot);
1286 if (f->Stream >= D3D11_SO_STREAM_COUNT)
1288 WARN("Invalid stream %u.\n", f->Stream);
1289 return E_INVALIDARG;
1291 if (f->Stream && feature_level < D3D_FEATURE_LEVEL_11_0)
1293 WARN("Invalid stream %u for feature level %#x.\n", f->Stream, feature_level);
1294 return E_INVALIDARG;
1296 if (f->Stream)
1298 FIXME("Streams not implemented yet.\n");
1299 return E_INVALIDARG;
1301 if (f->OutputSlot >= D3D11_SO_BUFFER_SLOT_COUNT)
1303 WARN("Invalid output slot %u.\n", f->OutputSlot);
1304 return E_INVALIDARG;
1307 e->stream_idx = f->Stream;
1308 e->component_idx = f->StartComponent;
1309 e->component_count = f->ComponentCount;
1310 e->output_slot = f->OutputSlot;
1312 if (!f->SemanticName)
1314 if (f->SemanticIndex)
1316 WARN("Invalid semantic idx %u for stream output gap.\n", f->SemanticIndex);
1317 return E_INVALIDARG;
1319 if (e->component_idx || !e->component_count)
1321 WARN("Invalid stream output gap %u-%u.\n", e->component_idx, e->component_count);
1322 return E_INVALIDARG;
1325 e->register_idx = WINED3D_STREAM_OUTPUT_GAP;
1327 else if ((output = shader_find_signature_element(os, f->SemanticName, f->SemanticIndex, f->Stream)))
1329 if (e->component_idx > 3 || e->component_count > 4 || !e->component_count
1330 || e->component_idx + e->component_count > 4)
1332 WARN("Invalid component range %u-%u.\n", e->component_idx, e->component_count);
1333 return E_INVALIDARG;
1336 for (j = 0; j < 4; ++j)
1338 if ((1u << j) & output->mask)
1339 break;
1341 e->component_idx += j;
1342 mask = ((1u << e->component_count) - 1) << e->component_idx;
1343 if ((output->mask & 0xff & mask) != mask)
1345 WARN("Invalid component range %u-%u (mask %#x), output mask %#x.\n",
1346 e->component_idx, e->component_count, mask, output->mask & 0xff);
1347 return E_INVALIDARG;
1350 e->register_idx = output->register_idx;
1351 TRACE("Register idx: %u, register component idx %u, register mask %#x.\n",
1352 e->register_idx, e->component_idx, mask);
1354 else
1356 WARN("Failed to find output signature element for stream output entry.\n");
1357 return E_INVALIDARG;
1361 for (i = 0; i < entry_count; ++i)
1363 const struct wined3d_stream_output_element *e1 = &elements[i];
1364 if (e1->register_idx == WINED3D_STREAM_OUTPUT_GAP)
1365 continue;
1367 for (j = i + 1; j < entry_count; ++j)
1369 const struct wined3d_stream_output_element *e2 = &elements[j];
1371 if (e1->register_idx == e2->register_idx
1372 && e1->component_idx < e2->component_idx + e2->component_count
1373 && e1->component_idx + e1->component_count > e2->component_idx)
1375 WARN("Stream output elements %u and %u overlap.\n", i, j);
1376 return E_INVALIDARG;
1381 for (i = 0; i < D3D11_SO_STREAM_COUNT; ++i)
1383 unsigned int current_stride[D3D11_SO_BUFFER_SLOT_COUNT] = {0};
1384 unsigned int element_count[D3D11_SO_BUFFER_SLOT_COUNT] = {0};
1385 unsigned int gap_count[D3D11_SO_BUFFER_SLOT_COUNT] = {0};
1387 for (j = 0; j < entry_count; ++j)
1389 const struct wined3d_stream_output_element *e = &elements[j];
1391 if (e->stream_idx != i)
1392 continue;
1393 current_stride[e->output_slot] += 4 * e->component_count;
1394 ++element_count[e->output_slot];
1395 if (e->register_idx == WINED3D_STREAM_OUTPUT_GAP)
1396 ++gap_count[e->output_slot];
1399 for (j = 0; j < D3D11_SO_BUFFER_SLOT_COUNT; ++j)
1401 if (!element_count[j])
1402 continue;
1403 if (element_count[j] == gap_count[j])
1405 WARN("Stream %u, output slot %u contains only gaps.\n", i, j);
1406 return E_INVALIDARG;
1408 if (buffer_stride_count)
1410 if (buffer_stride_count <= j)
1412 WARN("Buffer strides are required for all buffer slots.\n");
1413 return E_INVALIDARG;
1415 if (buffer_strides[j] < current_stride[j] || buffer_strides[j] % 4)
1417 WARN("Invalid stride %u for buffer slot %u.\n", buffer_strides[j], j);
1418 return E_INVALIDARG;
1423 if (!i && feature_level < D3D_FEATURE_LEVEL_11_0 && element_count[0] != entry_count)
1425 for (j = 0; j < ARRAY_SIZE(element_count); ++j)
1427 if (element_count[j] > 1)
1429 WARN("Only one element per output slot is allowed.\n");
1430 return E_INVALIDARG;
1436 return S_OK;
1439 static HRESULT d3d_geometry_shader_init(struct d3d_geometry_shader *shader,
1440 struct d3d_device *device, const void *byte_code, SIZE_T byte_code_length,
1441 const D3D11_SO_DECLARATION_ENTRY *so_entries, unsigned int so_entry_count,
1442 const unsigned int *buffer_strides, unsigned int buffer_stride_count,
1443 unsigned int rasterizer_stream)
1445 struct wined3d_stream_output_desc so_desc;
1446 struct wined3d_shader_desc desc;
1447 unsigned int i;
1448 HRESULT hr;
1450 if (so_entry_count > D3D11_SO_STREAM_COUNT * D3D11_SO_OUTPUT_COMPONENT_COUNT)
1452 WARN("Entry count %u is greater than %u.\n",
1453 so_entry_count, D3D11_SO_STREAM_COUNT * D3D11_SO_OUTPUT_COMPONENT_COUNT);
1454 return E_INVALIDARG;
1456 if (so_entries && !so_entry_count)
1458 WARN("Invalid SO entry count %u.\n", so_entry_count);
1459 return E_INVALIDARG;
1461 if (rasterizer_stream != D3D11_SO_NO_RASTERIZED_STREAM && rasterizer_stream >= D3D11_SO_STREAM_COUNT)
1463 WARN("Invalid rasterizer stream %u.\n", rasterizer_stream);
1464 return E_INVALIDARG;
1466 if (device->feature_level < D3D_FEATURE_LEVEL_11_0)
1468 if (rasterizer_stream)
1470 WARN("Invalid rasterizer stream %u for feature level %#x.\n",
1471 rasterizer_stream, device->feature_level);
1472 return E_INVALIDARG;
1474 if (buffer_stride_count && buffer_stride_count != 1)
1476 WARN("Invalid buffer stride count %u for feature level %#x.\n",
1477 buffer_stride_count, device->feature_level);
1478 return E_INVALIDARG;
1482 if (FAILED(hr = shader_extract_from_dxbc(byte_code, byte_code_length, &desc, device->feature_level)))
1484 WARN("Failed to extract shader, hr %#x.\n", hr);
1485 return hr;
1487 desc.max_version = d3d_sm_from_feature_level(device->feature_level);
1489 memset(&so_desc, 0, sizeof(so_desc));
1490 if (so_entries)
1492 so_desc.element_count = so_entry_count;
1493 for (i = 0; i < min(buffer_stride_count, ARRAY_SIZE(so_desc.buffer_strides)); ++i)
1494 so_desc.buffer_strides[i] = buffer_strides[i];
1495 so_desc.buffer_stride_count = buffer_stride_count;
1496 so_desc.rasterizer_stream_idx = rasterizer_stream;
1498 if (!(so_desc.elements = heap_calloc(so_entry_count, sizeof(*so_desc.elements))))
1500 ERR("Failed to allocate wined3d stream output element array memory.\n");
1501 free_shader_desc(&desc);
1502 return E_OUTOFMEMORY;
1504 if (FAILED(hr = wined3d_so_elements_from_d3d11_so_entries(so_desc.elements,
1505 so_entries, so_entry_count, buffer_strides, buffer_stride_count,
1506 &desc.output_signature, device->feature_level)))
1508 heap_free(so_desc.elements);
1509 free_shader_desc(&desc);
1510 return hr;
1514 shader->ID3D11GeometryShader_iface.lpVtbl = &d3d11_geometry_shader_vtbl;
1515 shader->ID3D10GeometryShader_iface.lpVtbl = &d3d10_geometry_shader_vtbl;
1516 shader->refcount = 1;
1517 wined3d_mutex_lock();
1518 wined3d_private_store_init(&shader->private_store);
1520 hr = wined3d_shader_create_gs(device->wined3d_device, &desc, so_entries ? &so_desc : NULL,
1521 shader, &d3d_geometry_shader_wined3d_parent_ops, &shader->wined3d_shader);
1522 heap_free(so_desc.elements);
1523 free_shader_desc(&desc);
1524 if (FAILED(hr))
1526 WARN("Failed to create wined3d geometry shader, hr %#x.\n", hr);
1527 wined3d_private_store_cleanup(&shader->private_store);
1528 wined3d_mutex_unlock();
1529 return E_INVALIDARG;
1531 wined3d_mutex_unlock();
1533 shader->device = &device->ID3D11Device1_iface;
1534 ID3D11Device1_AddRef(shader->device);
1536 return S_OK;
1539 HRESULT d3d_geometry_shader_create(struct d3d_device *device, const void *byte_code, SIZE_T byte_code_length,
1540 const D3D11_SO_DECLARATION_ENTRY *so_entries, unsigned int so_entry_count,
1541 const unsigned int *buffer_strides, unsigned int buffer_stride_count, unsigned int rasterizer_stream,
1542 struct d3d_geometry_shader **shader)
1544 struct d3d_geometry_shader *object;
1545 HRESULT hr;
1547 if (!(object = heap_alloc_zero(sizeof(*object))))
1548 return E_OUTOFMEMORY;
1550 if (FAILED(hr = d3d_geometry_shader_init(object, device, byte_code, byte_code_length,
1551 so_entries, so_entry_count, buffer_strides, buffer_stride_count, rasterizer_stream)))
1553 WARN("Failed to initialize geometry shader, hr %#x.\n", hr);
1554 heap_free(object);
1555 return hr;
1558 TRACE("Created geometry shader %p.\n", object);
1559 *shader = object;
1561 return S_OK;
1564 struct d3d_geometry_shader *unsafe_impl_from_ID3D11GeometryShader(ID3D11GeometryShader *iface)
1566 if (!iface)
1567 return NULL;
1568 assert(iface->lpVtbl == &d3d11_geometry_shader_vtbl);
1570 return impl_from_ID3D11GeometryShader(iface);
1573 struct d3d_geometry_shader *unsafe_impl_from_ID3D10GeometryShader(ID3D10GeometryShader *iface)
1575 if (!iface)
1576 return NULL;
1577 assert(iface->lpVtbl == &d3d10_geometry_shader_vtbl);
1579 return impl_from_ID3D10GeometryShader(iface);
1582 /* ID3D11PixelShader methods */
1584 static inline struct d3d_pixel_shader *impl_from_ID3D11PixelShader(ID3D11PixelShader *iface)
1586 return CONTAINING_RECORD(iface, struct d3d_pixel_shader, ID3D11PixelShader_iface);
1589 static HRESULT STDMETHODCALLTYPE d3d11_pixel_shader_QueryInterface(ID3D11PixelShader *iface,
1590 REFIID riid, void **object)
1592 struct d3d_pixel_shader *shader = impl_from_ID3D11PixelShader(iface);
1594 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
1596 if (IsEqualGUID(riid, &IID_ID3D11PixelShader)
1597 || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
1598 || IsEqualGUID(riid, &IID_IUnknown))
1600 ID3D11PixelShader_AddRef(iface);
1601 *object = iface;
1602 return S_OK;
1605 if (IsEqualGUID(riid, &IID_ID3D10PixelShader)
1606 || IsEqualGUID(riid, &IID_ID3D10DeviceChild))
1608 IUnknown_AddRef(&shader->ID3D10PixelShader_iface);
1609 *object = &shader->ID3D10PixelShader_iface;
1610 return S_OK;
1613 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
1615 *object = NULL;
1616 return E_NOINTERFACE;
1619 static ULONG STDMETHODCALLTYPE d3d11_pixel_shader_AddRef(ID3D11PixelShader *iface)
1621 struct d3d_pixel_shader *shader = impl_from_ID3D11PixelShader(iface);
1622 ULONG refcount = InterlockedIncrement(&shader->refcount);
1624 TRACE("%p increasing refcount to %u.\n", shader, refcount);
1626 if (refcount == 1)
1628 ID3D11Device1_AddRef(shader->device);
1629 wined3d_mutex_lock();
1630 wined3d_shader_incref(shader->wined3d_shader);
1631 wined3d_mutex_unlock();
1634 return refcount;
1637 static ULONG STDMETHODCALLTYPE d3d11_pixel_shader_Release(ID3D11PixelShader *iface)
1639 struct d3d_pixel_shader *shader = impl_from_ID3D11PixelShader(iface);
1640 ULONG refcount = InterlockedDecrement(&shader->refcount);
1642 TRACE("%p decreasing refcount to %u.\n", shader, refcount);
1644 if (!refcount)
1646 ID3D11Device1 *device = shader->device;
1648 wined3d_mutex_lock();
1649 wined3d_shader_decref(shader->wined3d_shader);
1650 wined3d_mutex_unlock();
1651 /* Release the device last, it may cause the wined3d device to be
1652 * destroyed. */
1653 ID3D11Device1_Release(device);
1656 return refcount;
1659 static void STDMETHODCALLTYPE d3d11_pixel_shader_GetDevice(ID3D11PixelShader *iface,
1660 ID3D11Device **device)
1662 struct d3d_pixel_shader *shader = impl_from_ID3D11PixelShader(iface);
1664 TRACE("iface %p, device %p.\n", iface, device);
1666 *device = (ID3D11Device *)shader->device;
1667 ID3D11Device_AddRef(*device);
1670 static HRESULT STDMETHODCALLTYPE d3d11_pixel_shader_GetPrivateData(ID3D11PixelShader *iface,
1671 REFGUID guid, UINT *data_size, void *data)
1673 struct d3d_pixel_shader *shader = impl_from_ID3D11PixelShader(iface);
1675 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
1677 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
1680 static HRESULT STDMETHODCALLTYPE d3d11_pixel_shader_SetPrivateData(ID3D11PixelShader *iface,
1681 REFGUID guid, UINT data_size, const void *data)
1683 struct d3d_pixel_shader *shader = impl_from_ID3D11PixelShader(iface);
1685 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
1687 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
1690 static HRESULT STDMETHODCALLTYPE d3d11_pixel_shader_SetPrivateDataInterface(ID3D11PixelShader *iface,
1691 REFGUID guid, const IUnknown *data)
1693 struct d3d_pixel_shader *shader = impl_from_ID3D11PixelShader(iface);
1695 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
1697 return d3d_set_private_data_interface(&shader->private_store, guid, data);
1700 static const struct ID3D11PixelShaderVtbl d3d11_pixel_shader_vtbl =
1702 /* IUnknown methods */
1703 d3d11_pixel_shader_QueryInterface,
1704 d3d11_pixel_shader_AddRef,
1705 d3d11_pixel_shader_Release,
1706 /* ID3D11DeviceChild methods */
1707 d3d11_pixel_shader_GetDevice,
1708 d3d11_pixel_shader_GetPrivateData,
1709 d3d11_pixel_shader_SetPrivateData,
1710 d3d11_pixel_shader_SetPrivateDataInterface,
1713 /* ID3D10PixelShader methods */
1715 static inline struct d3d_pixel_shader *impl_from_ID3D10PixelShader(ID3D10PixelShader *iface)
1717 return CONTAINING_RECORD(iface, struct d3d_pixel_shader, ID3D10PixelShader_iface);
1720 /* IUnknown methods */
1722 static HRESULT STDMETHODCALLTYPE d3d10_pixel_shader_QueryInterface(ID3D10PixelShader *iface,
1723 REFIID riid, void **object)
1725 struct d3d_pixel_shader *shader = impl_from_ID3D10PixelShader(iface);
1727 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
1729 return d3d11_pixel_shader_QueryInterface(&shader->ID3D11PixelShader_iface, riid, object);
1732 static ULONG STDMETHODCALLTYPE d3d10_pixel_shader_AddRef(ID3D10PixelShader *iface)
1734 struct d3d_pixel_shader *shader = impl_from_ID3D10PixelShader(iface);
1736 TRACE("iface %p.\n", iface);
1738 return d3d11_pixel_shader_AddRef(&shader->ID3D11PixelShader_iface);
1741 static ULONG STDMETHODCALLTYPE d3d10_pixel_shader_Release(ID3D10PixelShader *iface)
1743 struct d3d_pixel_shader *shader = impl_from_ID3D10PixelShader(iface);
1745 TRACE("iface %p.\n", iface);
1747 return d3d11_pixel_shader_Release(&shader->ID3D11PixelShader_iface);
1750 /* ID3D10DeviceChild methods */
1752 static void STDMETHODCALLTYPE d3d10_pixel_shader_GetDevice(ID3D10PixelShader *iface, ID3D10Device **device)
1754 struct d3d_pixel_shader *shader = impl_from_ID3D10PixelShader(iface);
1756 TRACE("iface %p, device %p.\n", iface, device);
1758 ID3D11Device1_QueryInterface(shader->device, &IID_ID3D10Device, (void **)device);
1761 static HRESULT STDMETHODCALLTYPE d3d10_pixel_shader_GetPrivateData(ID3D10PixelShader *iface,
1762 REFGUID guid, UINT *data_size, void *data)
1764 struct d3d_pixel_shader *shader = impl_from_ID3D10PixelShader(iface);
1766 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
1767 iface, debugstr_guid(guid), data_size, data);
1769 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
1772 static HRESULT STDMETHODCALLTYPE d3d10_pixel_shader_SetPrivateData(ID3D10PixelShader *iface,
1773 REFGUID guid, UINT data_size, const void *data)
1775 struct d3d_pixel_shader *shader = impl_from_ID3D10PixelShader(iface);
1777 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
1778 iface, debugstr_guid(guid), data_size, data);
1780 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
1783 static HRESULT STDMETHODCALLTYPE d3d10_pixel_shader_SetPrivateDataInterface(ID3D10PixelShader *iface,
1784 REFGUID guid, const IUnknown *data)
1786 struct d3d_pixel_shader *shader = impl_from_ID3D10PixelShader(iface);
1788 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
1790 return d3d_set_private_data_interface(&shader->private_store, guid, data);
1793 static const struct ID3D10PixelShaderVtbl d3d10_pixel_shader_vtbl =
1795 /* IUnknown methods */
1796 d3d10_pixel_shader_QueryInterface,
1797 d3d10_pixel_shader_AddRef,
1798 d3d10_pixel_shader_Release,
1799 /* ID3D10DeviceChild methods */
1800 d3d10_pixel_shader_GetDevice,
1801 d3d10_pixel_shader_GetPrivateData,
1802 d3d10_pixel_shader_SetPrivateData,
1803 d3d10_pixel_shader_SetPrivateDataInterface,
1806 static void STDMETHODCALLTYPE d3d_pixel_shader_wined3d_object_destroyed(void *parent)
1808 struct d3d_pixel_shader *shader = parent;
1810 wined3d_private_store_cleanup(&shader->private_store);
1811 heap_free(parent);
1814 static const struct wined3d_parent_ops d3d_pixel_shader_wined3d_parent_ops =
1816 d3d_pixel_shader_wined3d_object_destroyed,
1819 static HRESULT d3d_pixel_shader_init(struct d3d_pixel_shader *shader, struct d3d_device *device,
1820 const void *byte_code, SIZE_T byte_code_length)
1822 struct wined3d_shader_desc desc;
1823 HRESULT hr;
1825 shader->ID3D11PixelShader_iface.lpVtbl = &d3d11_pixel_shader_vtbl;
1826 shader->ID3D10PixelShader_iface.lpVtbl = &d3d10_pixel_shader_vtbl;
1827 shader->refcount = 1;
1828 wined3d_mutex_lock();
1829 wined3d_private_store_init(&shader->private_store);
1831 if (FAILED(hr = shader_extract_from_dxbc(byte_code, byte_code_length, &desc, device->feature_level)))
1833 WARN("Failed to extract shader, hr %#x.\n", hr);
1834 wined3d_private_store_cleanup(&shader->private_store);
1835 wined3d_mutex_unlock();
1836 return hr;
1838 desc.max_version = d3d_sm_from_feature_level(device->feature_level);
1840 hr = wined3d_shader_create_ps(device->wined3d_device, &desc, shader,
1841 &d3d_pixel_shader_wined3d_parent_ops, &shader->wined3d_shader);
1842 free_shader_desc(&desc);
1843 if (FAILED(hr))
1845 WARN("Failed to create wined3d pixel shader, hr %#x.\n", hr);
1846 wined3d_private_store_cleanup(&shader->private_store);
1847 wined3d_mutex_unlock();
1848 return E_INVALIDARG;
1850 wined3d_mutex_unlock();
1852 shader->device = &device->ID3D11Device1_iface;
1853 ID3D11Device1_AddRef(shader->device);
1855 return S_OK;
1858 HRESULT d3d_pixel_shader_create(struct d3d_device *device, const void *byte_code, SIZE_T byte_code_length,
1859 struct d3d_pixel_shader **shader)
1861 struct d3d_pixel_shader *object;
1862 HRESULT hr;
1864 if (!(object = heap_alloc_zero(sizeof(*object))))
1865 return E_OUTOFMEMORY;
1867 if (FAILED(hr = d3d_pixel_shader_init(object, device, byte_code, byte_code_length)))
1869 WARN("Failed to initialize pixel shader, hr %#x.\n", hr);
1870 heap_free(object);
1871 return hr;
1874 TRACE("Created pixel shader %p.\n", object);
1875 *shader = object;
1877 return S_OK;
1880 struct d3d_pixel_shader *unsafe_impl_from_ID3D11PixelShader(ID3D11PixelShader *iface)
1882 if (!iface)
1883 return NULL;
1884 assert(iface->lpVtbl == &d3d11_pixel_shader_vtbl);
1886 return impl_from_ID3D11PixelShader(iface);
1889 struct d3d_pixel_shader *unsafe_impl_from_ID3D10PixelShader(ID3D10PixelShader *iface)
1891 if (!iface)
1892 return NULL;
1893 assert(iface->lpVtbl == &d3d10_pixel_shader_vtbl);
1895 return impl_from_ID3D10PixelShader(iface);
1898 /* ID3D11ComputeShader methods */
1900 static inline struct d3d11_compute_shader *impl_from_ID3D11ComputeShader(ID3D11ComputeShader *iface)
1902 return CONTAINING_RECORD(iface, struct d3d11_compute_shader, ID3D11ComputeShader_iface);
1905 static HRESULT STDMETHODCALLTYPE d3d11_compute_shader_QueryInterface(ID3D11ComputeShader *iface,
1906 REFIID riid, void **object)
1908 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
1910 if (IsEqualGUID(riid, &IID_ID3D11ComputeShader)
1911 || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
1912 || IsEqualGUID(riid, &IID_IUnknown))
1914 ID3D11ComputeShader_AddRef(*object = iface);
1915 return S_OK;
1918 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
1920 *object = NULL;
1921 return E_NOINTERFACE;
1924 static ULONG STDMETHODCALLTYPE d3d11_compute_shader_AddRef(ID3D11ComputeShader *iface)
1926 struct d3d11_compute_shader *shader = impl_from_ID3D11ComputeShader(iface);
1927 ULONG refcount = InterlockedIncrement(&shader->refcount);
1929 TRACE("%p increasing refcount to %u.\n", shader, refcount);
1931 if (refcount == 1)
1933 ID3D11Device1_AddRef(shader->device);
1934 wined3d_mutex_lock();
1935 wined3d_shader_incref(shader->wined3d_shader);
1936 wined3d_mutex_unlock();
1939 return refcount;
1942 static ULONG STDMETHODCALLTYPE d3d11_compute_shader_Release(ID3D11ComputeShader *iface)
1944 struct d3d11_compute_shader *shader = impl_from_ID3D11ComputeShader(iface);
1945 ULONG refcount = InterlockedDecrement(&shader->refcount);
1947 TRACE("%p decreasing refcount to %u.\n", shader, refcount);
1949 if (!refcount)
1951 ID3D11Device1 *device = shader->device;
1953 wined3d_mutex_lock();
1954 wined3d_shader_decref(shader->wined3d_shader);
1955 wined3d_mutex_unlock();
1957 /* Release the device last, it may cause the wined3d device to be
1958 * destroyed. */
1959 ID3D11Device1_Release(device);
1962 return refcount;
1965 static void STDMETHODCALLTYPE d3d11_compute_shader_GetDevice(ID3D11ComputeShader *iface,
1966 ID3D11Device **device)
1968 struct d3d11_compute_shader *shader = impl_from_ID3D11ComputeShader(iface);
1970 TRACE("iface %p, device %p.\n", iface, device);
1972 ID3D11Device_AddRef(*device = (ID3D11Device *)shader->device);
1975 static HRESULT STDMETHODCALLTYPE d3d11_compute_shader_GetPrivateData(ID3D11ComputeShader *iface,
1976 REFGUID guid, UINT *data_size, void *data)
1978 struct d3d11_compute_shader *shader = impl_from_ID3D11ComputeShader(iface);
1980 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
1982 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
1985 static HRESULT STDMETHODCALLTYPE d3d11_compute_shader_SetPrivateData(ID3D11ComputeShader *iface,
1986 REFGUID guid, UINT data_size, const void *data)
1988 struct d3d11_compute_shader *shader = impl_from_ID3D11ComputeShader(iface);
1990 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
1992 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
1995 static HRESULT STDMETHODCALLTYPE d3d11_compute_shader_SetPrivateDataInterface(ID3D11ComputeShader *iface,
1996 REFGUID guid, const IUnknown *data)
1998 struct d3d11_compute_shader *shader = impl_from_ID3D11ComputeShader(iface);
2000 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
2002 return d3d_set_private_data_interface(&shader->private_store, guid, data);
2005 static const struct ID3D11ComputeShaderVtbl d3d11_compute_shader_vtbl =
2007 /* IUnknown methods */
2008 d3d11_compute_shader_QueryInterface,
2009 d3d11_compute_shader_AddRef,
2010 d3d11_compute_shader_Release,
2011 /* ID3D11DeviceChild methods */
2012 d3d11_compute_shader_GetDevice,
2013 d3d11_compute_shader_GetPrivateData,
2014 d3d11_compute_shader_SetPrivateData,
2015 d3d11_compute_shader_SetPrivateDataInterface,
2018 static void STDMETHODCALLTYPE d3d11_compute_shader_wined3d_object_destroyed(void *parent)
2020 struct d3d11_compute_shader *shader = parent;
2022 wined3d_private_store_cleanup(&shader->private_store);
2023 heap_free(parent);
2026 static const struct wined3d_parent_ops d3d11_compute_shader_wined3d_parent_ops =
2028 d3d11_compute_shader_wined3d_object_destroyed,
2031 static HRESULT d3d11_compute_shader_init(struct d3d11_compute_shader *shader, struct d3d_device *device,
2032 const void *byte_code, SIZE_T byte_code_length)
2034 struct wined3d_shader_desc desc;
2035 HRESULT hr;
2037 shader->ID3D11ComputeShader_iface.lpVtbl = &d3d11_compute_shader_vtbl;
2038 shader->refcount = 1;
2039 wined3d_mutex_lock();
2040 wined3d_private_store_init(&shader->private_store);
2042 if (FAILED(hr = shader_extract_from_dxbc(byte_code, byte_code_length, &desc, device->feature_level)))
2044 WARN("Failed to extract shader, hr %#x.\n", hr);
2045 wined3d_private_store_cleanup(&shader->private_store);
2046 wined3d_mutex_unlock();
2047 return hr;
2049 desc.max_version = d3d_sm_from_feature_level(device->feature_level);
2051 hr = wined3d_shader_create_cs(device->wined3d_device, &desc, shader,
2052 &d3d11_compute_shader_wined3d_parent_ops, &shader->wined3d_shader);
2053 free_shader_desc(&desc);
2054 if (FAILED(hr))
2056 WARN("Failed to create wined3d compute shader, hr %#x.\n", hr);
2057 wined3d_private_store_cleanup(&shader->private_store);
2058 wined3d_mutex_unlock();
2059 return E_INVALIDARG;
2061 wined3d_mutex_unlock();
2063 ID3D11Device1_AddRef(shader->device = &device->ID3D11Device1_iface);
2065 return S_OK;
2068 HRESULT d3d11_compute_shader_create(struct d3d_device *device, const void *byte_code, SIZE_T byte_code_length,
2069 struct d3d11_compute_shader **shader)
2071 struct d3d11_compute_shader *object;
2072 HRESULT hr;
2074 if (!(object = heap_alloc_zero(sizeof(*object))))
2075 return E_OUTOFMEMORY;
2077 if (FAILED(hr = d3d11_compute_shader_init(object, device, byte_code, byte_code_length)))
2079 heap_free(object);
2080 return hr;
2083 TRACE("Created compute shader %p.\n", object);
2084 *shader = object;
2086 return S_OK;
2089 struct d3d11_compute_shader *unsafe_impl_from_ID3D11ComputeShader(ID3D11ComputeShader *iface)
2091 if (!iface)
2092 return NULL;
2093 assert(iface->lpVtbl == &d3d11_compute_shader_vtbl);
2095 return impl_from_ID3D11ComputeShader(iface);
2098 /* ID3D11ClassLinkage methods */
2100 static inline struct d3d11_class_linkage *impl_from_ID3D11ClassLinkage(ID3D11ClassLinkage *iface)
2102 return CONTAINING_RECORD(iface, struct d3d11_class_linkage, ID3D11ClassLinkage_iface);
2105 static HRESULT STDMETHODCALLTYPE d3d11_class_linkage_QueryInterface(ID3D11ClassLinkage *iface,
2106 REFIID riid, void **object)
2108 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
2110 if (IsEqualGUID(riid, &IID_ID3D11ClassLinkage)
2111 || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
2112 || IsEqualGUID(riid, &IID_IUnknown))
2114 ID3D11ClassLinkage_AddRef(*object = iface);
2115 return S_OK;
2118 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
2120 *object = NULL;
2121 return E_NOINTERFACE;
2124 static ULONG STDMETHODCALLTYPE d3d11_class_linkage_AddRef(ID3D11ClassLinkage *iface)
2126 struct d3d11_class_linkage *class_linkage = impl_from_ID3D11ClassLinkage(iface);
2127 ULONG refcount = InterlockedIncrement(&class_linkage->refcount);
2129 TRACE("%p increasing refcount to %u.\n", class_linkage, refcount);
2131 return refcount;
2134 static ULONG STDMETHODCALLTYPE d3d11_class_linkage_Release(ID3D11ClassLinkage *iface)
2136 struct d3d11_class_linkage *class_linkage = impl_from_ID3D11ClassLinkage(iface);
2137 ULONG refcount = InterlockedDecrement(&class_linkage->refcount);
2139 TRACE("%p decreasing refcount to %u.\n", class_linkage, refcount);
2141 if (!refcount)
2143 ID3D11Device1 *device = class_linkage->device;
2145 wined3d_private_store_cleanup(&class_linkage->private_store);
2146 heap_free(class_linkage);
2148 ID3D11Device1_Release(device);
2151 return refcount;
2154 static void STDMETHODCALLTYPE d3d11_class_linkage_GetDevice(ID3D11ClassLinkage *iface,
2155 ID3D11Device **device)
2157 struct d3d11_class_linkage *class_linkage = impl_from_ID3D11ClassLinkage(iface);
2159 TRACE("iface %p, device %p.\n", iface, device);
2161 ID3D11Device_AddRef(*device = (ID3D11Device *)class_linkage->device);
2164 static HRESULT STDMETHODCALLTYPE d3d11_class_linkage_GetPrivateData(ID3D11ClassLinkage *iface,
2165 REFGUID guid, UINT *data_size, void *data)
2167 struct d3d11_class_linkage *class_linkage = impl_from_ID3D11ClassLinkage(iface);
2169 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
2171 return d3d_get_private_data(&class_linkage->private_store, guid, data_size, data);
2174 static HRESULT STDMETHODCALLTYPE d3d11_class_linkage_SetPrivateData(ID3D11ClassLinkage *iface,
2175 REFGUID guid, UINT data_size, const void *data)
2177 struct d3d11_class_linkage *class_linkage = impl_from_ID3D11ClassLinkage(iface);
2179 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
2181 return d3d_set_private_data(&class_linkage->private_store, guid, data_size, data);
2184 static HRESULT STDMETHODCALLTYPE d3d11_class_linkage_SetPrivateDataInterface(ID3D11ClassLinkage *iface,
2185 REFGUID guid, const IUnknown *data)
2187 struct d3d11_class_linkage *class_linkage = impl_from_ID3D11ClassLinkage(iface);
2189 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
2191 return d3d_set_private_data_interface(&class_linkage->private_store, guid, data);
2194 static HRESULT STDMETHODCALLTYPE d3d11_class_linkage_GetClassInstance(ID3D11ClassLinkage *iface,
2195 const char *instance_name, UINT instance_index, ID3D11ClassInstance **class_instance)
2197 FIXME("iface %p, instance_name %s, instance_index %u, class_instance %p stub!\n",
2198 iface, debugstr_a(instance_name), instance_index, class_instance);
2200 return E_NOTIMPL;
2203 static HRESULT STDMETHODCALLTYPE d3d11_class_linkage_CreateClassInstance(ID3D11ClassLinkage *iface,
2204 const char *type_name, UINT cb_offset, UINT cb_vector_offset, UINT texture_offset,
2205 UINT sampler_offset, ID3D11ClassInstance **class_instance)
2207 FIXME("iface %p, type_name %s, cb_offset %u, cb_vector_offset %u, texture_offset %u, "
2208 "sampler_offset %u, class_instance %p stub!\n",
2209 iface, debugstr_a(type_name), cb_offset, cb_vector_offset, texture_offset,
2210 sampler_offset, class_instance);
2212 return E_NOTIMPL;
2215 static const struct ID3D11ClassLinkageVtbl d3d11_class_linkage_vtbl =
2217 /* IUnknown methods */
2218 d3d11_class_linkage_QueryInterface,
2219 d3d11_class_linkage_AddRef,
2220 d3d11_class_linkage_Release,
2221 /* ID3D11DeviceChild methods */
2222 d3d11_class_linkage_GetDevice,
2223 d3d11_class_linkage_GetPrivateData,
2224 d3d11_class_linkage_SetPrivateData,
2225 d3d11_class_linkage_SetPrivateDataInterface,
2226 /* ID3D11ClassLinkage methods */
2227 d3d11_class_linkage_GetClassInstance,
2228 d3d11_class_linkage_CreateClassInstance,
2231 HRESULT d3d11_class_linkage_create(struct d3d_device *device, struct d3d11_class_linkage **class_linkage)
2233 struct d3d11_class_linkage *object;
2235 if (!(object = heap_alloc_zero(sizeof(*object))))
2236 return E_OUTOFMEMORY;
2238 object->ID3D11ClassLinkage_iface.lpVtbl = &d3d11_class_linkage_vtbl;
2239 object->refcount = 1;
2240 wined3d_private_store_init(&object->private_store);
2242 ID3D11Device1_AddRef(object->device = &device->ID3D11Device1_iface);
2244 TRACE("Created class linkage %p.\n", object);
2245 *class_linkage = object;
2247 return S_OK;