d3d11: Implement ID3D11VertexShader interface.
[wine/multimedia.git] / dlls / d3d11 / shader.c
blobf0aadc8fd0c7d73303a2284c29ab394a69473036
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 d3d10_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 d3d10_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 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 d3d10_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 struct d3d_vertex_shader *unsafe_impl_from_ID3D10VertexShader(ID3D10VertexShader *iface)
413 if (!iface)
414 return NULL;
415 assert(iface->lpVtbl == &d3d10_vertex_shader_vtbl);
417 return impl_from_ID3D10VertexShader(iface);
420 static inline struct d3d10_geometry_shader *impl_from_ID3D10GeometryShader(ID3D10GeometryShader *iface)
422 return CONTAINING_RECORD(iface, struct d3d10_geometry_shader, ID3D10GeometryShader_iface);
425 /* IUnknown methods */
427 static HRESULT STDMETHODCALLTYPE d3d10_geometry_shader_QueryInterface(ID3D10GeometryShader *iface,
428 REFIID riid, void **object)
430 TRACE("iface %p, riid %s, object %p\n", iface, debugstr_guid(riid), object);
432 if (IsEqualGUID(riid, &IID_ID3D10GeometryShader)
433 || IsEqualGUID(riid, &IID_ID3D10DeviceChild)
434 || IsEqualGUID(riid, &IID_IUnknown))
436 IUnknown_AddRef(iface);
437 *object = iface;
438 return S_OK;
441 WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(riid));
443 *object = NULL;
444 return E_NOINTERFACE;
447 static ULONG STDMETHODCALLTYPE d3d10_geometry_shader_AddRef(ID3D10GeometryShader *iface)
449 struct d3d10_geometry_shader *This = impl_from_ID3D10GeometryShader(iface);
450 ULONG refcount = InterlockedIncrement(&This->refcount);
452 TRACE("%p increasing refcount to %u\n", This, refcount);
454 return refcount;
457 static ULONG STDMETHODCALLTYPE d3d10_geometry_shader_Release(ID3D10GeometryShader *iface)
459 struct d3d10_geometry_shader *This = impl_from_ID3D10GeometryShader(iface);
460 ULONG refcount = InterlockedDecrement(&This->refcount);
462 TRACE("%p decreasing refcount to %u\n", This, refcount);
464 if (!refcount)
466 wined3d_mutex_lock();
467 wined3d_shader_decref(This->wined3d_shader);
468 wined3d_mutex_unlock();
471 return refcount;
474 /* ID3D10DeviceChild methods */
476 static void STDMETHODCALLTYPE d3d10_geometry_shader_GetDevice(ID3D10GeometryShader *iface, ID3D10Device **device)
478 FIXME("iface %p, device %p stub!\n", iface, device);
481 static HRESULT STDMETHODCALLTYPE d3d10_geometry_shader_GetPrivateData(ID3D10GeometryShader *iface,
482 REFGUID guid, UINT *data_size, void *data)
484 struct d3d10_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface);
486 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
487 iface, debugstr_guid(guid), data_size, data);
489 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
492 static HRESULT STDMETHODCALLTYPE d3d10_geometry_shader_SetPrivateData(ID3D10GeometryShader *iface,
493 REFGUID guid, UINT data_size, const void *data)
495 struct d3d10_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface);
497 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
498 iface, debugstr_guid(guid), data_size, data);
500 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
503 static HRESULT STDMETHODCALLTYPE d3d10_geometry_shader_SetPrivateDataInterface(ID3D10GeometryShader *iface,
504 REFGUID guid, const IUnknown *data)
506 struct d3d10_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface);
508 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
510 return d3d_set_private_data_interface(&shader->private_store, guid, data);
513 static const struct ID3D10GeometryShaderVtbl d3d10_geometry_shader_vtbl =
515 /* IUnknown methods */
516 d3d10_geometry_shader_QueryInterface,
517 d3d10_geometry_shader_AddRef,
518 d3d10_geometry_shader_Release,
519 /* ID3D10DeviceChild methods */
520 d3d10_geometry_shader_GetDevice,
521 d3d10_geometry_shader_GetPrivateData,
522 d3d10_geometry_shader_SetPrivateData,
523 d3d10_geometry_shader_SetPrivateDataInterface,
526 static void STDMETHODCALLTYPE d3d10_geometry_shader_wined3d_object_destroyed(void *parent)
528 struct d3d10_geometry_shader *shader = parent;
530 wined3d_private_store_cleanup(&shader->private_store);
531 HeapFree(GetProcessHeap(), 0, parent);
534 static const struct wined3d_parent_ops d3d10_geometry_shader_wined3d_parent_ops =
536 d3d10_geometry_shader_wined3d_object_destroyed,
539 HRESULT d3d10_geometry_shader_init(struct d3d10_geometry_shader *shader, struct d3d_device *device,
540 const void *byte_code, SIZE_T byte_code_length)
542 struct wined3d_shader_signature output_signature;
543 struct wined3d_shader_signature input_signature;
544 struct d3d10_shader_info shader_info;
545 struct wined3d_shader_desc desc;
546 HRESULT hr;
548 shader->ID3D10GeometryShader_iface.lpVtbl = &d3d10_geometry_shader_vtbl;
549 shader->refcount = 1;
550 wined3d_mutex_lock();
551 wined3d_private_store_init(&shader->private_store);
553 shader_info.input_signature = &input_signature;
554 shader_info.output_signature = &output_signature;
555 if (FAILED(hr = shader_extract_from_dxbc(byte_code, byte_code_length, &shader_info)))
557 ERR("Failed to extract shader, hr %#x.\n", hr);
558 wined3d_private_store_cleanup(&shader->private_store);
559 wined3d_mutex_unlock();
560 return hr;
563 desc.byte_code = shader_info.shader_code;
564 desc.input_signature = &input_signature;
565 desc.output_signature = &output_signature;
566 desc.max_version = 4;
568 hr = wined3d_shader_create_gs(device->wined3d_device, &desc, shader,
569 &d3d10_geometry_shader_wined3d_parent_ops, &shader->wined3d_shader);
570 shader_free_signature(&input_signature);
571 shader_free_signature(&output_signature);
572 if (FAILED(hr))
574 WARN("Failed to create wined3d geometry shader, hr %#x.\n", hr);
575 wined3d_private_store_cleanup(&shader->private_store);
576 wined3d_mutex_unlock();
577 return E_INVALIDARG;
579 wined3d_mutex_unlock();
581 return S_OK;
584 struct d3d10_geometry_shader *unsafe_impl_from_ID3D10GeometryShader(ID3D10GeometryShader *iface)
586 if (!iface)
587 return NULL;
588 assert(iface->lpVtbl == &d3d10_geometry_shader_vtbl);
590 return impl_from_ID3D10GeometryShader(iface);
593 static inline struct d3d10_pixel_shader *impl_from_ID3D10PixelShader(ID3D10PixelShader *iface)
595 return CONTAINING_RECORD(iface, struct d3d10_pixel_shader, ID3D10PixelShader_iface);
598 /* IUnknown methods */
600 static HRESULT STDMETHODCALLTYPE d3d10_pixel_shader_QueryInterface(ID3D10PixelShader *iface,
601 REFIID riid, void **object)
603 TRACE("iface %p, riid %s, object %p\n", iface, debugstr_guid(riid), object);
605 if (IsEqualGUID(riid, &IID_ID3D10PixelShader)
606 || IsEqualGUID(riid, &IID_ID3D10DeviceChild)
607 || IsEqualGUID(riid, &IID_IUnknown))
609 IUnknown_AddRef(iface);
610 *object = iface;
611 return S_OK;
614 WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(riid));
616 *object = NULL;
617 return E_NOINTERFACE;
620 static ULONG STDMETHODCALLTYPE d3d10_pixel_shader_AddRef(ID3D10PixelShader *iface)
622 struct d3d10_pixel_shader *This = impl_from_ID3D10PixelShader(iface);
623 ULONG refcount = InterlockedIncrement(&This->refcount);
625 TRACE("%p increasing refcount to %u\n", This, refcount);
627 if (refcount == 1)
629 ID3D10Device1_AddRef(This->device);
630 wined3d_mutex_lock();
631 wined3d_shader_incref(This->wined3d_shader);
632 wined3d_mutex_unlock();
635 return refcount;
638 static ULONG STDMETHODCALLTYPE d3d10_pixel_shader_Release(ID3D10PixelShader *iface)
640 struct d3d10_pixel_shader *This = impl_from_ID3D10PixelShader(iface);
641 ULONG refcount = InterlockedDecrement(&This->refcount);
643 TRACE("%p decreasing refcount to %u\n", This, refcount);
645 if (!refcount)
647 ID3D10Device1 *device = This->device;
649 wined3d_mutex_lock();
650 wined3d_shader_decref(This->wined3d_shader);
651 wined3d_mutex_unlock();
652 /* Release the device last, it may cause the wined3d device to be
653 * destroyed. */
654 ID3D10Device1_Release(device);
657 return refcount;
660 /* ID3D10DeviceChild methods */
662 static void STDMETHODCALLTYPE d3d10_pixel_shader_GetDevice(ID3D10PixelShader *iface, ID3D10Device **device)
664 struct d3d10_pixel_shader *shader = impl_from_ID3D10PixelShader(iface);
666 TRACE("iface %p, device %p.\n", iface, device);
668 *device = (ID3D10Device *)shader->device;
669 ID3D10Device_AddRef(*device);
672 static HRESULT STDMETHODCALLTYPE d3d10_pixel_shader_GetPrivateData(ID3D10PixelShader *iface,
673 REFGUID guid, UINT *data_size, void *data)
675 struct d3d10_pixel_shader *shader = impl_from_ID3D10PixelShader(iface);
677 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
678 iface, debugstr_guid(guid), data_size, data);
680 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
683 static HRESULT STDMETHODCALLTYPE d3d10_pixel_shader_SetPrivateData(ID3D10PixelShader *iface,
684 REFGUID guid, UINT data_size, const void *data)
686 struct d3d10_pixel_shader *shader = impl_from_ID3D10PixelShader(iface);
688 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
689 iface, debugstr_guid(guid), data_size, data);
691 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
694 static HRESULT STDMETHODCALLTYPE d3d10_pixel_shader_SetPrivateDataInterface(ID3D10PixelShader *iface,
695 REFGUID guid, const IUnknown *data)
697 struct d3d10_pixel_shader *shader = impl_from_ID3D10PixelShader(iface);
699 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
701 return d3d_set_private_data_interface(&shader->private_store, guid, data);
704 static const struct ID3D10PixelShaderVtbl d3d10_pixel_shader_vtbl =
706 /* IUnknown methods */
707 d3d10_pixel_shader_QueryInterface,
708 d3d10_pixel_shader_AddRef,
709 d3d10_pixel_shader_Release,
710 /* ID3D10DeviceChild methods */
711 d3d10_pixel_shader_GetDevice,
712 d3d10_pixel_shader_GetPrivateData,
713 d3d10_pixel_shader_SetPrivateData,
714 d3d10_pixel_shader_SetPrivateDataInterface,
717 static void STDMETHODCALLTYPE d3d10_pixel_shader_wined3d_object_destroyed(void *parent)
719 struct d3d10_pixel_shader *shader = parent;
721 wined3d_private_store_cleanup(&shader->private_store);
722 HeapFree(GetProcessHeap(), 0, parent);
725 static const struct wined3d_parent_ops d3d10_pixel_shader_wined3d_parent_ops =
727 d3d10_pixel_shader_wined3d_object_destroyed,
730 HRESULT d3d10_pixel_shader_init(struct d3d10_pixel_shader *shader, struct d3d_device *device,
731 const void *byte_code, SIZE_T byte_code_length)
733 struct wined3d_shader_signature output_signature;
734 struct wined3d_shader_signature input_signature;
735 struct d3d10_shader_info shader_info;
736 struct wined3d_shader_desc desc;
737 HRESULT hr;
739 shader->ID3D10PixelShader_iface.lpVtbl = &d3d10_pixel_shader_vtbl;
740 shader->refcount = 1;
741 wined3d_mutex_lock();
742 wined3d_private_store_init(&shader->private_store);
744 shader_info.input_signature = &input_signature;
745 shader_info.output_signature = &output_signature;
746 if (FAILED(hr = shader_extract_from_dxbc(byte_code, byte_code_length, &shader_info)))
748 ERR("Failed to extract shader, hr %#x.\n", hr);
749 wined3d_private_store_cleanup(&shader->private_store);
750 wined3d_mutex_unlock();
751 return hr;
754 desc.byte_code = shader_info.shader_code;
755 desc.input_signature = &input_signature;
756 desc.output_signature = &output_signature;
757 desc.max_version = 4;
759 hr = wined3d_shader_create_ps(device->wined3d_device, &desc, shader,
760 &d3d10_pixel_shader_wined3d_parent_ops, &shader->wined3d_shader);
761 shader_free_signature(&input_signature);
762 shader_free_signature(&output_signature);
763 if (FAILED(hr))
765 WARN("Failed to create wined3d pixel shader, hr %#x.\n", hr);
766 wined3d_private_store_cleanup(&shader->private_store);
767 wined3d_mutex_unlock();
768 return E_INVALIDARG;
770 wined3d_mutex_unlock();
772 shader->device = &device->ID3D10Device1_iface;
773 ID3D10Device1_AddRef(shader->device);
775 return S_OK;
778 struct d3d10_pixel_shader *unsafe_impl_from_ID3D10PixelShader(ID3D10PixelShader *iface)
780 if (!iface)
781 return NULL;
782 assert(iface->lpVtbl == &d3d10_pixel_shader_vtbl);
784 return impl_from_ID3D10PixelShader(iface);