d3d11: Rename d3d10_shader_info to d3d_shader_info.
[wine/multimedia.git] / dlls / d3d11 / shader.c
blobaa3ac5eafe71dbe9941157e3b36ee4970d58b6e1
1 /*
2 * Copyright 2009 Henri Verbeet for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #include "config.h"
21 #include "wine/port.h"
23 #include "d3d11_private.h"
25 WINE_DEFAULT_DEBUG_CHANNEL(d3d11);
27 static HRESULT shdr_handler(const char *data, DWORD data_size, DWORD tag, void *ctx)
29 struct d3d_shader_info *shader_info = ctx;
30 HRESULT hr;
32 switch (tag)
34 case TAG_ISGN:
35 if (FAILED(hr = shader_parse_signature(data, data_size, shader_info->input_signature)))
36 return hr;
37 break;
39 case TAG_OSGN:
40 if (FAILED(hr = shader_parse_signature(data, data_size, shader_info->output_signature)))
41 return hr;
42 break;
44 case TAG_SHDR:
45 shader_info->shader_code = (const DWORD *)data;
46 break;
48 default:
49 FIXME("Unhandled chunk %s\n", debugstr_an((const char *)&tag, 4));
50 break;
53 return S_OK;
56 static HRESULT shader_extract_from_dxbc(const void *dxbc, SIZE_T dxbc_length, struct d3d_shader_info *shader_info)
58 HRESULT hr;
60 shader_info->shader_code = NULL;
61 memset(shader_info->input_signature, 0, sizeof(*shader_info->input_signature));
62 memset(shader_info->output_signature, 0, sizeof(*shader_info->output_signature));
64 hr = parse_dxbc(dxbc, dxbc_length, shdr_handler, shader_info);
65 if (!shader_info->shader_code) hr = E_INVALIDARG;
67 if (FAILED(hr))
69 ERR("Failed to parse shader, hr %#x\n", hr);
70 shader_free_signature(shader_info->input_signature);
71 shader_free_signature(shader_info->output_signature);
74 return hr;
77 HRESULT shader_parse_signature(const char *data, DWORD data_size, struct wined3d_shader_signature *s)
79 struct wined3d_shader_signature_element *e;
80 const char *ptr = data;
81 unsigned int i;
82 DWORD count;
84 read_dword(&ptr, &count);
85 TRACE("%u elements\n", count);
87 skip_dword_unknown(&ptr, 1);
89 e = HeapAlloc(GetProcessHeap(), 0, count * sizeof(*e));
90 if (!e)
92 ERR("Failed to allocate input signature memory.\n");
93 return E_OUTOFMEMORY;
96 for (i = 0; i < count; ++i)
98 UINT name_offset;
100 read_dword(&ptr, &name_offset);
101 e[i].semantic_name = data + name_offset;
102 read_dword(&ptr, &e[i].semantic_idx);
103 read_dword(&ptr, &e[i].sysval_semantic);
104 read_dword(&ptr, &e[i].component_type);
105 read_dword(&ptr, &e[i].register_idx);
106 read_dword(&ptr, &e[i].mask);
108 TRACE("semantic: %s, semantic idx: %u, sysval_semantic %#x, "
109 "type %u, register idx: %u, use_mask %#x, input_mask %#x\n",
110 debugstr_a(e[i].semantic_name), e[i].semantic_idx, e[i].sysval_semantic,
111 e[i].component_type, e[i].register_idx, (e[i].mask >> 8) & 0xff, e[i].mask & 0xff);
114 s->elements = e;
115 s->element_count = count;
117 return S_OK;
120 void shader_free_signature(struct wined3d_shader_signature *s)
122 HeapFree(GetProcessHeap(), 0, s->elements);
125 /* ID3D11VertexShader methods */
127 static inline struct d3d_vertex_shader *impl_from_ID3D11VertexShader(ID3D11VertexShader *iface)
129 return CONTAINING_RECORD(iface, struct d3d_vertex_shader, ID3D11VertexShader_iface);
132 static HRESULT STDMETHODCALLTYPE d3d11_vertex_shader_QueryInterface(ID3D11VertexShader *iface,
133 REFIID riid, void **object)
135 struct d3d_vertex_shader *shader = impl_from_ID3D11VertexShader(iface);
137 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
139 if (IsEqualGUID(riid, &IID_ID3D11VertexShader)
140 || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
141 || IsEqualGUID(riid, &IID_IUnknown))
143 ID3D11VertexShader_AddRef(iface);
144 *object = iface;
145 return S_OK;
148 if (IsEqualGUID(riid, &IID_ID3D10VertexShader)
149 || IsEqualGUID(riid, &IID_ID3D10DeviceChild))
151 IUnknown_AddRef(&shader->ID3D10VertexShader_iface);
152 *object = &shader->ID3D10VertexShader_iface;
153 return S_OK;
156 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
158 *object = NULL;
159 return E_NOINTERFACE;
162 static ULONG STDMETHODCALLTYPE d3d11_vertex_shader_AddRef(ID3D11VertexShader *iface)
164 struct d3d_vertex_shader *shader = impl_from_ID3D11VertexShader(iface);
165 ULONG refcount = InterlockedIncrement(&shader->refcount);
167 TRACE("%p increasing refcount to %u.\n", shader, refcount);
169 if (refcount == 1)
171 ID3D11Device_AddRef(shader->device);
172 wined3d_mutex_lock();
173 wined3d_shader_incref(shader->wined3d_shader);
174 wined3d_mutex_unlock();
177 return refcount;
180 static ULONG STDMETHODCALLTYPE d3d11_vertex_shader_Release(ID3D11VertexShader *iface)
182 struct d3d_vertex_shader *shader = impl_from_ID3D11VertexShader(iface);
183 ULONG refcount = InterlockedDecrement(&shader->refcount);
185 TRACE("%p decreasing refcount to %u.\n", shader, refcount);
187 if (!refcount)
189 ID3D11Device *device = shader->device;
191 wined3d_mutex_lock();
192 wined3d_shader_decref(shader->wined3d_shader);
193 wined3d_mutex_unlock();
194 /* Release the device last, it may cause the wined3d device to be
195 * destroyed. */
196 ID3D11Device_Release(device);
199 return refcount;
202 static void STDMETHODCALLTYPE d3d11_vertex_shader_GetDevice(ID3D11VertexShader *iface,
203 ID3D11Device **device)
205 struct d3d_vertex_shader *shader = impl_from_ID3D11VertexShader(iface);
207 TRACE("iface %p, device %p.\n", iface, device);
209 *device = shader->device;
210 ID3D11Device_AddRef(*device);
213 static HRESULT STDMETHODCALLTYPE d3d11_vertex_shader_GetPrivateData(ID3D11VertexShader *iface,
214 REFGUID guid, UINT *data_size, void *data)
216 struct d3d_vertex_shader *shader = impl_from_ID3D11VertexShader(iface);
218 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
220 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
223 static HRESULT STDMETHODCALLTYPE d3d11_vertex_shader_SetPrivateData(ID3D11VertexShader *iface,
224 REFGUID guid, UINT data_size, const void *data)
226 struct d3d_vertex_shader *shader = impl_from_ID3D11VertexShader(iface);
228 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
230 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
233 static HRESULT STDMETHODCALLTYPE d3d11_vertex_shader_SetPrivateDataInterface(ID3D11VertexShader *iface,
234 REFGUID guid, const IUnknown *data)
236 struct d3d_vertex_shader *shader = impl_from_ID3D11VertexShader(iface);
238 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
240 return d3d_set_private_data_interface(&shader->private_store, guid, data);
243 static const struct ID3D11VertexShaderVtbl d3d11_vertex_shader_vtbl =
245 /* IUnknown methods */
246 d3d11_vertex_shader_QueryInterface,
247 d3d11_vertex_shader_AddRef,
248 d3d11_vertex_shader_Release,
249 /* ID3D11DeviceChild methods */
250 d3d11_vertex_shader_GetDevice,
251 d3d11_vertex_shader_GetPrivateData,
252 d3d11_vertex_shader_SetPrivateData,
253 d3d11_vertex_shader_SetPrivateDataInterface,
256 /* ID3D10VertexShader methods */
258 static inline struct d3d_vertex_shader *impl_from_ID3D10VertexShader(ID3D10VertexShader *iface)
260 return CONTAINING_RECORD(iface, struct d3d_vertex_shader, ID3D10VertexShader_iface);
263 /* IUnknown methods */
265 static HRESULT STDMETHODCALLTYPE d3d10_vertex_shader_QueryInterface(ID3D10VertexShader *iface,
266 REFIID riid, void **object)
268 struct d3d_vertex_shader *shader = impl_from_ID3D10VertexShader(iface);
270 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
272 return d3d11_vertex_shader_QueryInterface(&shader->ID3D11VertexShader_iface, riid, object);
275 static ULONG STDMETHODCALLTYPE d3d10_vertex_shader_AddRef(ID3D10VertexShader *iface)
277 struct d3d_vertex_shader *shader = impl_from_ID3D10VertexShader(iface);
279 TRACE("iface %p.\n", iface);
281 return d3d11_vertex_shader_AddRef(&shader->ID3D11VertexShader_iface);
284 static ULONG STDMETHODCALLTYPE d3d10_vertex_shader_Release(ID3D10VertexShader *iface)
286 struct d3d_vertex_shader *shader = impl_from_ID3D10VertexShader(iface);
288 TRACE("iface %p.\n", iface);
290 return d3d11_vertex_shader_Release(&shader->ID3D11VertexShader_iface);
293 /* ID3D10DeviceChild methods */
295 static void STDMETHODCALLTYPE d3d10_vertex_shader_GetDevice(ID3D10VertexShader *iface, ID3D10Device **device)
297 struct d3d_vertex_shader *shader = impl_from_ID3D10VertexShader(iface);
299 TRACE("iface %p, device %p.\n", iface, device);
301 ID3D11Device_QueryInterface(shader->device, &IID_ID3D10Device, (void **)device);
304 static HRESULT STDMETHODCALLTYPE d3d10_vertex_shader_GetPrivateData(ID3D10VertexShader *iface,
305 REFGUID guid, UINT *data_size, void *data)
307 struct d3d_vertex_shader *shader = impl_from_ID3D10VertexShader(iface);
309 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
310 iface, debugstr_guid(guid), data_size, data);
312 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
315 static HRESULT STDMETHODCALLTYPE d3d10_vertex_shader_SetPrivateData(ID3D10VertexShader *iface,
316 REFGUID guid, UINT data_size, const void *data)
318 struct d3d_vertex_shader *shader = impl_from_ID3D10VertexShader(iface);
320 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
321 iface, debugstr_guid(guid), data_size, data);
323 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
326 static HRESULT STDMETHODCALLTYPE d3d10_vertex_shader_SetPrivateDataInterface(ID3D10VertexShader *iface,
327 REFGUID guid, const IUnknown *data)
329 struct d3d_vertex_shader *shader = impl_from_ID3D10VertexShader(iface);
331 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
333 return d3d_set_private_data_interface(&shader->private_store, guid, data);
336 static const struct ID3D10VertexShaderVtbl d3d10_vertex_shader_vtbl =
338 /* IUnknown methods */
339 d3d10_vertex_shader_QueryInterface,
340 d3d10_vertex_shader_AddRef,
341 d3d10_vertex_shader_Release,
342 /* ID3D10DeviceChild methods */
343 d3d10_vertex_shader_GetDevice,
344 d3d10_vertex_shader_GetPrivateData,
345 d3d10_vertex_shader_SetPrivateData,
346 d3d10_vertex_shader_SetPrivateDataInterface,
349 static void STDMETHODCALLTYPE d3d_vertex_shader_wined3d_object_destroyed(void *parent)
351 struct d3d_vertex_shader *shader = parent;
353 wined3d_private_store_cleanup(&shader->private_store);
354 HeapFree(GetProcessHeap(), 0, parent);
357 static const struct wined3d_parent_ops d3d_vertex_shader_wined3d_parent_ops =
359 d3d_vertex_shader_wined3d_object_destroyed,
362 static HRESULT d3d_vertex_shader_init(struct d3d_vertex_shader *shader, struct d3d_device *device,
363 const void *byte_code, SIZE_T byte_code_length)
365 struct wined3d_shader_signature output_signature;
366 struct wined3d_shader_signature input_signature;
367 struct d3d_shader_info shader_info;
368 struct wined3d_shader_desc desc;
369 HRESULT hr;
371 shader->ID3D11VertexShader_iface.lpVtbl = &d3d11_vertex_shader_vtbl;
372 shader->ID3D10VertexShader_iface.lpVtbl = &d3d10_vertex_shader_vtbl;
373 shader->refcount = 1;
374 wined3d_mutex_lock();
375 wined3d_private_store_init(&shader->private_store);
377 shader_info.input_signature = &input_signature;
378 shader_info.output_signature = &output_signature;
379 if (FAILED(hr = shader_extract_from_dxbc(byte_code, byte_code_length, &shader_info)))
381 ERR("Failed to extract shader, hr %#x.\n", hr);
382 wined3d_private_store_cleanup(&shader->private_store);
383 wined3d_mutex_unlock();
384 return hr;
387 desc.byte_code = shader_info.shader_code;
388 desc.input_signature = &input_signature;
389 desc.output_signature = &output_signature;
390 desc.max_version = 4;
392 hr = wined3d_shader_create_vs(device->wined3d_device, &desc, shader,
393 &d3d_vertex_shader_wined3d_parent_ops, &shader->wined3d_shader);
394 shader_free_signature(&input_signature);
395 shader_free_signature(&output_signature);
396 if (FAILED(hr))
398 WARN("Failed to create wined3d vertex shader, hr %#x.\n", hr);
399 wined3d_private_store_cleanup(&shader->private_store);
400 wined3d_mutex_unlock();
401 return E_INVALIDARG;
403 wined3d_mutex_unlock();
405 shader->device = &device->ID3D11Device_iface;
406 ID3D11Device_AddRef(shader->device);
408 return S_OK;
411 HRESULT d3d_vertex_shader_create(struct d3d_device *device, const void *byte_code, SIZE_T byte_code_length,
412 struct d3d_vertex_shader **shader)
414 struct d3d_vertex_shader *object;
415 HRESULT hr;
417 if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
418 return E_OUTOFMEMORY;
420 if (FAILED(hr = d3d_vertex_shader_init(object, device, byte_code, byte_code_length)))
422 WARN("Failed to initialize vertex shader, hr %#x.\n", hr);
423 HeapFree(GetProcessHeap(), 0, object);
424 return hr;
427 TRACE("Created vertex shader %p.\n", object);
428 *shader = object;
430 return S_OK;
433 struct d3d_vertex_shader *unsafe_impl_from_ID3D10VertexShader(ID3D10VertexShader *iface)
435 if (!iface)
436 return NULL;
437 assert(iface->lpVtbl == &d3d10_vertex_shader_vtbl);
439 return impl_from_ID3D10VertexShader(iface);
442 /* ID3D11GeometryShader methods */
444 static inline struct d3d_geometry_shader *impl_from_ID3D11GeometryShader(ID3D11GeometryShader *iface)
446 return CONTAINING_RECORD(iface, struct d3d_geometry_shader, ID3D11GeometryShader_iface);
449 static HRESULT STDMETHODCALLTYPE d3d11_geometry_shader_QueryInterface(ID3D11GeometryShader *iface,
450 REFIID riid, void **object)
452 struct d3d_geometry_shader *shader = impl_from_ID3D11GeometryShader(iface);
454 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
456 if (IsEqualGUID(riid, &IID_ID3D11GeometryShader)
457 || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
458 || IsEqualGUID(riid, &IID_IUnknown))
460 ID3D11GeometryShader_AddRef(iface);
461 *object = iface;
462 return S_OK;
465 if (IsEqualGUID(riid, &IID_ID3D10GeometryShader)
466 || IsEqualGUID(riid, &IID_ID3D10DeviceChild))
468 ID3D10GeometryShader_AddRef(&shader->ID3D10GeometryShader_iface);
469 *object = &shader->ID3D10GeometryShader_iface;
470 return S_OK;
473 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
475 *object = NULL;
476 return E_NOINTERFACE;
479 static ULONG STDMETHODCALLTYPE d3d11_geometry_shader_AddRef(ID3D11GeometryShader *iface)
481 struct d3d_geometry_shader *shader = impl_from_ID3D11GeometryShader(iface);
482 ULONG refcount = InterlockedIncrement(&shader->refcount);
484 TRACE("%p increasing refcount to %u.\n", shader, refcount);
486 return refcount;
489 static ULONG STDMETHODCALLTYPE d3d11_geometry_shader_Release(ID3D11GeometryShader *iface)
491 struct d3d_geometry_shader *shader = impl_from_ID3D11GeometryShader(iface);
492 ULONG refcount = InterlockedDecrement(&shader->refcount);
494 TRACE("%p decreasing refcount to %u.\n", shader, refcount);
496 if (!refcount)
498 wined3d_mutex_lock();
499 wined3d_shader_decref(shader->wined3d_shader);
500 wined3d_mutex_unlock();
503 return refcount;
506 static void STDMETHODCALLTYPE d3d11_geometry_shader_GetDevice(ID3D11GeometryShader *iface,
507 ID3D11Device **device)
509 FIXME("iface %p, device %p stub!\n", iface, device);
512 static HRESULT STDMETHODCALLTYPE d3d11_geometry_shader_GetPrivateData(ID3D11GeometryShader *iface,
513 REFGUID guid, UINT *data_size, void *data)
515 struct d3d_geometry_shader *shader = impl_from_ID3D11GeometryShader(iface);
517 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
519 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
522 static HRESULT STDMETHODCALLTYPE d3d11_geometry_shader_SetPrivateData(ID3D11GeometryShader *iface,
523 REFGUID guid, UINT data_size, const void *data)
525 struct d3d_geometry_shader *shader = impl_from_ID3D11GeometryShader(iface);
527 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
529 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
532 static HRESULT STDMETHODCALLTYPE d3d11_geometry_shader_SetPrivateDataInterface(ID3D11GeometryShader *iface,
533 REFGUID guid, const IUnknown *data)
535 struct d3d_geometry_shader *shader = impl_from_ID3D11GeometryShader(iface);
537 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
539 return d3d_set_private_data_interface(&shader->private_store, guid, data);
542 static const struct ID3D11GeometryShaderVtbl d3d11_geometry_shader_vtbl =
544 /* IUnknown methods */
545 d3d11_geometry_shader_QueryInterface,
546 d3d11_geometry_shader_AddRef,
547 d3d11_geometry_shader_Release,
548 /* ID3D11DeviceChild methods */
549 d3d11_geometry_shader_GetDevice,
550 d3d11_geometry_shader_GetPrivateData,
551 d3d11_geometry_shader_SetPrivateData,
552 d3d11_geometry_shader_SetPrivateDataInterface,
555 /* ID3D10GeometryShader methods */
557 static inline struct d3d_geometry_shader *impl_from_ID3D10GeometryShader(ID3D10GeometryShader *iface)
559 return CONTAINING_RECORD(iface, struct d3d_geometry_shader, ID3D10GeometryShader_iface);
562 /* IUnknown methods */
564 static HRESULT STDMETHODCALLTYPE d3d10_geometry_shader_QueryInterface(ID3D10GeometryShader *iface,
565 REFIID riid, void **object)
567 struct d3d_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface);
569 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
571 return d3d11_geometry_shader_QueryInterface(&shader->ID3D11GeometryShader_iface, riid, object);
574 static ULONG STDMETHODCALLTYPE d3d10_geometry_shader_AddRef(ID3D10GeometryShader *iface)
576 struct d3d_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface);
578 TRACE("iface %p.\n", iface);
580 return d3d11_geometry_shader_AddRef(&shader->ID3D11GeometryShader_iface);
583 static ULONG STDMETHODCALLTYPE d3d10_geometry_shader_Release(ID3D10GeometryShader *iface)
585 struct d3d_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface);
587 TRACE("iface %p.\n", iface);
589 return d3d11_geometry_shader_Release(&shader->ID3D11GeometryShader_iface);
592 /* ID3D10DeviceChild methods */
594 static void STDMETHODCALLTYPE d3d10_geometry_shader_GetDevice(ID3D10GeometryShader *iface, ID3D10Device **device)
596 FIXME("iface %p, device %p stub!\n", iface, device);
599 static HRESULT STDMETHODCALLTYPE d3d10_geometry_shader_GetPrivateData(ID3D10GeometryShader *iface,
600 REFGUID guid, UINT *data_size, void *data)
602 struct d3d_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface);
604 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
605 iface, debugstr_guid(guid), data_size, data);
607 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
610 static HRESULT STDMETHODCALLTYPE d3d10_geometry_shader_SetPrivateData(ID3D10GeometryShader *iface,
611 REFGUID guid, UINT data_size, const void *data)
613 struct d3d_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface);
615 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
616 iface, debugstr_guid(guid), data_size, data);
618 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
621 static HRESULT STDMETHODCALLTYPE d3d10_geometry_shader_SetPrivateDataInterface(ID3D10GeometryShader *iface,
622 REFGUID guid, const IUnknown *data)
624 struct d3d_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface);
626 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
628 return d3d_set_private_data_interface(&shader->private_store, guid, data);
631 static const struct ID3D10GeometryShaderVtbl d3d10_geometry_shader_vtbl =
633 /* IUnknown methods */
634 d3d10_geometry_shader_QueryInterface,
635 d3d10_geometry_shader_AddRef,
636 d3d10_geometry_shader_Release,
637 /* ID3D10DeviceChild methods */
638 d3d10_geometry_shader_GetDevice,
639 d3d10_geometry_shader_GetPrivateData,
640 d3d10_geometry_shader_SetPrivateData,
641 d3d10_geometry_shader_SetPrivateDataInterface,
644 static void STDMETHODCALLTYPE d3d_geometry_shader_wined3d_object_destroyed(void *parent)
646 struct d3d_geometry_shader *shader = parent;
648 wined3d_private_store_cleanup(&shader->private_store);
649 HeapFree(GetProcessHeap(), 0, parent);
652 static const struct wined3d_parent_ops d3d_geometry_shader_wined3d_parent_ops =
654 d3d_geometry_shader_wined3d_object_destroyed,
657 static HRESULT d3d_geometry_shader_init(struct d3d_geometry_shader *shader, struct d3d_device *device,
658 const void *byte_code, SIZE_T byte_code_length)
660 struct wined3d_shader_signature output_signature;
661 struct wined3d_shader_signature input_signature;
662 struct d3d_shader_info shader_info;
663 struct wined3d_shader_desc desc;
664 HRESULT hr;
666 shader->ID3D11GeometryShader_iface.lpVtbl = &d3d11_geometry_shader_vtbl;
667 shader->ID3D10GeometryShader_iface.lpVtbl = &d3d10_geometry_shader_vtbl;
668 shader->refcount = 1;
669 wined3d_mutex_lock();
670 wined3d_private_store_init(&shader->private_store);
672 shader_info.input_signature = &input_signature;
673 shader_info.output_signature = &output_signature;
674 if (FAILED(hr = shader_extract_from_dxbc(byte_code, byte_code_length, &shader_info)))
676 ERR("Failed to extract shader, hr %#x.\n", hr);
677 wined3d_private_store_cleanup(&shader->private_store);
678 wined3d_mutex_unlock();
679 return hr;
682 desc.byte_code = shader_info.shader_code;
683 desc.input_signature = &input_signature;
684 desc.output_signature = &output_signature;
685 desc.max_version = 4;
687 hr = wined3d_shader_create_gs(device->wined3d_device, &desc, shader,
688 &d3d_geometry_shader_wined3d_parent_ops, &shader->wined3d_shader);
689 shader_free_signature(&input_signature);
690 shader_free_signature(&output_signature);
691 if (FAILED(hr))
693 WARN("Failed to create wined3d geometry shader, hr %#x.\n", hr);
694 wined3d_private_store_cleanup(&shader->private_store);
695 wined3d_mutex_unlock();
696 return E_INVALIDARG;
698 wined3d_mutex_unlock();
700 return S_OK;
703 HRESULT d3d_geometry_shader_create(struct d3d_device *device, const void *byte_code, SIZE_T byte_code_length,
704 struct d3d_geometry_shader **shader)
706 struct d3d_geometry_shader *object;
707 HRESULT hr;
709 if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
710 return E_OUTOFMEMORY;
712 if (FAILED(hr = d3d_geometry_shader_init(object, device, byte_code, byte_code_length)))
714 WARN("Failed to initialize geometry shader, hr %#x.\n", hr);
715 HeapFree(GetProcessHeap(), 0, object);
716 return hr;
719 TRACE("Created geometry shader %p.\n", object);
720 *shader = object;
722 return S_OK;
725 struct d3d_geometry_shader *unsafe_impl_from_ID3D10GeometryShader(ID3D10GeometryShader *iface)
727 if (!iface)
728 return NULL;
729 assert(iface->lpVtbl == &d3d10_geometry_shader_vtbl);
731 return impl_from_ID3D10GeometryShader(iface);
734 /* ID3D11PixelShader methods */
736 static inline struct d3d_pixel_shader *impl_from_ID3D11PixelShader(ID3D11PixelShader *iface)
738 return CONTAINING_RECORD(iface, struct d3d_pixel_shader, ID3D11PixelShader_iface);
741 static HRESULT STDMETHODCALLTYPE d3d11_pixel_shader_QueryInterface(ID3D11PixelShader *iface,
742 REFIID riid, void **object)
744 struct d3d_pixel_shader *shader = impl_from_ID3D11PixelShader(iface);
746 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
748 if (IsEqualGUID(riid, &IID_ID3D11PixelShader)
749 || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
750 || IsEqualGUID(riid, &IID_IUnknown))
752 ID3D11PixelShader_AddRef(iface);
753 *object = iface;
754 return S_OK;
757 if (IsEqualGUID(riid, &IID_ID3D10PixelShader)
758 || IsEqualGUID(riid, &IID_ID3D10DeviceChild))
760 IUnknown_AddRef(&shader->ID3D10PixelShader_iface);
761 *object = &shader->ID3D10PixelShader_iface;
762 return S_OK;
765 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
767 *object = NULL;
768 return E_NOINTERFACE;
771 static ULONG STDMETHODCALLTYPE d3d11_pixel_shader_AddRef(ID3D11PixelShader *iface)
773 struct d3d_pixel_shader *shader = impl_from_ID3D11PixelShader(iface);
774 ULONG refcount = InterlockedIncrement(&shader->refcount);
776 TRACE("%p increasing refcount to %u.\n", shader, refcount);
778 if (refcount == 1)
780 ID3D11Device_AddRef(shader->device);
781 wined3d_mutex_lock();
782 wined3d_shader_incref(shader->wined3d_shader);
783 wined3d_mutex_unlock();
786 return refcount;
789 static ULONG STDMETHODCALLTYPE d3d11_pixel_shader_Release(ID3D11PixelShader *iface)
791 struct d3d_pixel_shader *shader = impl_from_ID3D11PixelShader(iface);
792 ULONG refcount = InterlockedDecrement(&shader->refcount);
794 TRACE("%p decreasing refcount to %u.\n", shader, refcount);
796 if (!refcount)
798 ID3D11Device *device = shader->device;
800 wined3d_mutex_lock();
801 wined3d_shader_decref(shader->wined3d_shader);
802 wined3d_mutex_unlock();
803 /* Release the device last, it may cause the wined3d device to be
804 * destroyed. */
805 ID3D11Device_Release(device);
808 return refcount;
811 static void STDMETHODCALLTYPE d3d11_pixel_shader_GetDevice(ID3D11PixelShader *iface,
812 ID3D11Device **device)
814 struct d3d_pixel_shader *shader = impl_from_ID3D11PixelShader(iface);
816 TRACE("iface %p, device %p.\n", iface, device);
818 *device = shader->device;
819 ID3D11Device_AddRef(*device);
822 static HRESULT STDMETHODCALLTYPE d3d11_pixel_shader_GetPrivateData(ID3D11PixelShader *iface,
823 REFGUID guid, UINT *data_size, void *data)
825 struct d3d_pixel_shader *shader = impl_from_ID3D11PixelShader(iface);
827 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
829 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
832 static HRESULT STDMETHODCALLTYPE d3d11_pixel_shader_SetPrivateData(ID3D11PixelShader *iface,
833 REFGUID guid, UINT data_size, const void *data)
835 struct d3d_pixel_shader *shader = impl_from_ID3D11PixelShader(iface);
837 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
839 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
842 static HRESULT STDMETHODCALLTYPE d3d11_pixel_shader_SetPrivateDataInterface(ID3D11PixelShader *iface,
843 REFGUID guid, const IUnknown *data)
845 struct d3d_pixel_shader *shader = impl_from_ID3D11PixelShader(iface);
847 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
849 return d3d_set_private_data_interface(&shader->private_store, guid, data);
852 static const struct ID3D11PixelShaderVtbl d3d11_pixel_shader_vtbl =
854 /* IUnknown methods */
855 d3d11_pixel_shader_QueryInterface,
856 d3d11_pixel_shader_AddRef,
857 d3d11_pixel_shader_Release,
858 /* ID3D11DeviceChild methods */
859 d3d11_pixel_shader_GetDevice,
860 d3d11_pixel_shader_GetPrivateData,
861 d3d11_pixel_shader_SetPrivateData,
862 d3d11_pixel_shader_SetPrivateDataInterface,
865 /* ID3D10PixelShader methods */
867 static inline struct d3d_pixel_shader *impl_from_ID3D10PixelShader(ID3D10PixelShader *iface)
869 return CONTAINING_RECORD(iface, struct d3d_pixel_shader, ID3D10PixelShader_iface);
872 /* IUnknown methods */
874 static HRESULT STDMETHODCALLTYPE d3d10_pixel_shader_QueryInterface(ID3D10PixelShader *iface,
875 REFIID riid, void **object)
877 struct d3d_pixel_shader *shader = impl_from_ID3D10PixelShader(iface);
879 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
881 return d3d11_pixel_shader_QueryInterface(&shader->ID3D11PixelShader_iface, riid, object);
884 static ULONG STDMETHODCALLTYPE d3d10_pixel_shader_AddRef(ID3D10PixelShader *iface)
886 struct d3d_pixel_shader *shader = impl_from_ID3D10PixelShader(iface);
888 TRACE("iface %p.\n", iface);
890 return d3d11_pixel_shader_AddRef(&shader->ID3D11PixelShader_iface);
893 static ULONG STDMETHODCALLTYPE d3d10_pixel_shader_Release(ID3D10PixelShader *iface)
895 struct d3d_pixel_shader *shader = impl_from_ID3D10PixelShader(iface);
897 TRACE("iface %p.\n", iface);
899 return d3d11_pixel_shader_Release(&shader->ID3D11PixelShader_iface);
902 /* ID3D10DeviceChild methods */
904 static void STDMETHODCALLTYPE d3d10_pixel_shader_GetDevice(ID3D10PixelShader *iface, ID3D10Device **device)
906 struct d3d_pixel_shader *shader = impl_from_ID3D10PixelShader(iface);
908 TRACE("iface %p, device %p.\n", iface, device);
910 ID3D11Device_QueryInterface(shader->device, &IID_ID3D10Device, (void **)device);
913 static HRESULT STDMETHODCALLTYPE d3d10_pixel_shader_GetPrivateData(ID3D10PixelShader *iface,
914 REFGUID guid, UINT *data_size, void *data)
916 struct d3d_pixel_shader *shader = impl_from_ID3D10PixelShader(iface);
918 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
919 iface, debugstr_guid(guid), data_size, data);
921 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
924 static HRESULT STDMETHODCALLTYPE d3d10_pixel_shader_SetPrivateData(ID3D10PixelShader *iface,
925 REFGUID guid, UINT data_size, const void *data)
927 struct d3d_pixel_shader *shader = impl_from_ID3D10PixelShader(iface);
929 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
930 iface, debugstr_guid(guid), data_size, data);
932 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
935 static HRESULT STDMETHODCALLTYPE d3d10_pixel_shader_SetPrivateDataInterface(ID3D10PixelShader *iface,
936 REFGUID guid, const IUnknown *data)
938 struct d3d_pixel_shader *shader = impl_from_ID3D10PixelShader(iface);
940 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
942 return d3d_set_private_data_interface(&shader->private_store, guid, data);
945 static const struct ID3D10PixelShaderVtbl d3d10_pixel_shader_vtbl =
947 /* IUnknown methods */
948 d3d10_pixel_shader_QueryInterface,
949 d3d10_pixel_shader_AddRef,
950 d3d10_pixel_shader_Release,
951 /* ID3D10DeviceChild methods */
952 d3d10_pixel_shader_GetDevice,
953 d3d10_pixel_shader_GetPrivateData,
954 d3d10_pixel_shader_SetPrivateData,
955 d3d10_pixel_shader_SetPrivateDataInterface,
958 static void STDMETHODCALLTYPE d3d_pixel_shader_wined3d_object_destroyed(void *parent)
960 struct d3d_pixel_shader *shader = parent;
962 wined3d_private_store_cleanup(&shader->private_store);
963 HeapFree(GetProcessHeap(), 0, parent);
966 static const struct wined3d_parent_ops d3d_pixel_shader_wined3d_parent_ops =
968 d3d_pixel_shader_wined3d_object_destroyed,
971 static HRESULT d3d_pixel_shader_init(struct d3d_pixel_shader *shader, struct d3d_device *device,
972 const void *byte_code, SIZE_T byte_code_length)
974 struct wined3d_shader_signature output_signature;
975 struct wined3d_shader_signature input_signature;
976 struct d3d_shader_info shader_info;
977 struct wined3d_shader_desc desc;
978 HRESULT hr;
980 shader->ID3D11PixelShader_iface.lpVtbl = &d3d11_pixel_shader_vtbl;
981 shader->ID3D10PixelShader_iface.lpVtbl = &d3d10_pixel_shader_vtbl;
982 shader->refcount = 1;
983 wined3d_mutex_lock();
984 wined3d_private_store_init(&shader->private_store);
986 shader_info.input_signature = &input_signature;
987 shader_info.output_signature = &output_signature;
988 if (FAILED(hr = shader_extract_from_dxbc(byte_code, byte_code_length, &shader_info)))
990 ERR("Failed to extract shader, hr %#x.\n", hr);
991 wined3d_private_store_cleanup(&shader->private_store);
992 wined3d_mutex_unlock();
993 return hr;
996 desc.byte_code = shader_info.shader_code;
997 desc.input_signature = &input_signature;
998 desc.output_signature = &output_signature;
999 desc.max_version = 4;
1001 hr = wined3d_shader_create_ps(device->wined3d_device, &desc, shader,
1002 &d3d_pixel_shader_wined3d_parent_ops, &shader->wined3d_shader);
1003 shader_free_signature(&input_signature);
1004 shader_free_signature(&output_signature);
1005 if (FAILED(hr))
1007 WARN("Failed to create wined3d pixel shader, hr %#x.\n", hr);
1008 wined3d_private_store_cleanup(&shader->private_store);
1009 wined3d_mutex_unlock();
1010 return E_INVALIDARG;
1012 wined3d_mutex_unlock();
1014 shader->device = &device->ID3D11Device_iface;
1015 ID3D11Device_AddRef(shader->device);
1017 return S_OK;
1020 HRESULT d3d_pixel_shader_create(struct d3d_device *device, const void *byte_code, SIZE_T byte_code_length,
1021 struct d3d_pixel_shader **shader)
1023 struct d3d_pixel_shader *object;
1024 HRESULT hr;
1026 if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
1027 return E_OUTOFMEMORY;
1029 if (FAILED(hr = d3d_pixel_shader_init(object, device, byte_code, byte_code_length)))
1031 WARN("Failed to initialize pixel shader, hr %#x.\n", hr);
1032 HeapFree(GetProcessHeap(), 0, object);
1033 return hr;
1036 TRACE("Created pixel shader %p.\n", object);
1037 *shader = object;
1039 return S_OK;
1042 struct d3d_pixel_shader *unsafe_impl_from_ID3D10PixelShader(ID3D10PixelShader *iface)
1044 if (!iface)
1045 return NULL;
1046 assert(iface->lpVtbl == &d3d10_pixel_shader_vtbl);
1048 return impl_from_ID3D10PixelShader(iface);