tools: Allow running installed builtin apps even when the 32-bit loader is missing.
[wine.git] / dlls / d3d11 / shader.c
blobc645b0bef46c9afd121ed7d7b49ebf60328c2f5b
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_ID3D11VertexShader(ID3D11VertexShader *iface)
435 if (!iface)
436 return NULL;
437 assert(iface->lpVtbl == &d3d11_vertex_shader_vtbl);
439 return impl_from_ID3D11VertexShader(iface);
442 struct d3d_vertex_shader *unsafe_impl_from_ID3D10VertexShader(ID3D10VertexShader *iface)
444 if (!iface)
445 return NULL;
446 assert(iface->lpVtbl == &d3d10_vertex_shader_vtbl);
448 return impl_from_ID3D10VertexShader(iface);
451 /* ID3D11GeometryShader methods */
453 static inline struct d3d_geometry_shader *impl_from_ID3D11GeometryShader(ID3D11GeometryShader *iface)
455 return CONTAINING_RECORD(iface, struct d3d_geometry_shader, ID3D11GeometryShader_iface);
458 static HRESULT STDMETHODCALLTYPE d3d11_geometry_shader_QueryInterface(ID3D11GeometryShader *iface,
459 REFIID riid, void **object)
461 struct d3d_geometry_shader *shader = impl_from_ID3D11GeometryShader(iface);
463 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
465 if (IsEqualGUID(riid, &IID_ID3D11GeometryShader)
466 || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
467 || IsEqualGUID(riid, &IID_IUnknown))
469 ID3D11GeometryShader_AddRef(iface);
470 *object = iface;
471 return S_OK;
474 if (IsEqualGUID(riid, &IID_ID3D10GeometryShader)
475 || IsEqualGUID(riid, &IID_ID3D10DeviceChild))
477 ID3D10GeometryShader_AddRef(&shader->ID3D10GeometryShader_iface);
478 *object = &shader->ID3D10GeometryShader_iface;
479 return S_OK;
482 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
484 *object = NULL;
485 return E_NOINTERFACE;
488 static ULONG STDMETHODCALLTYPE d3d11_geometry_shader_AddRef(ID3D11GeometryShader *iface)
490 struct d3d_geometry_shader *shader = impl_from_ID3D11GeometryShader(iface);
491 ULONG refcount = InterlockedIncrement(&shader->refcount);
493 TRACE("%p increasing refcount to %u.\n", shader, refcount);
495 return refcount;
498 static ULONG STDMETHODCALLTYPE d3d11_geometry_shader_Release(ID3D11GeometryShader *iface)
500 struct d3d_geometry_shader *shader = impl_from_ID3D11GeometryShader(iface);
501 ULONG refcount = InterlockedDecrement(&shader->refcount);
503 TRACE("%p decreasing refcount to %u.\n", shader, refcount);
505 if (!refcount)
507 ID3D11Device *device = shader->device;
509 wined3d_mutex_lock();
510 wined3d_shader_decref(shader->wined3d_shader);
511 wined3d_mutex_unlock();
513 /* Release the device last, it may cause the wined3d device to be
514 * destroyed. */
515 ID3D11Device_Release(device);
518 return refcount;
521 static void STDMETHODCALLTYPE d3d11_geometry_shader_GetDevice(ID3D11GeometryShader *iface,
522 ID3D11Device **device)
524 struct d3d_geometry_shader *shader = impl_from_ID3D11GeometryShader(iface);
526 TRACE("iface %p, device %p.\n", iface, device);
528 *device = shader->device;
529 ID3D11Device_AddRef(*device);
532 static HRESULT STDMETHODCALLTYPE d3d11_geometry_shader_GetPrivateData(ID3D11GeometryShader *iface,
533 REFGUID guid, UINT *data_size, void *data)
535 struct d3d_geometry_shader *shader = impl_from_ID3D11GeometryShader(iface);
537 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
539 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
542 static HRESULT STDMETHODCALLTYPE d3d11_geometry_shader_SetPrivateData(ID3D11GeometryShader *iface,
543 REFGUID guid, UINT data_size, const void *data)
545 struct d3d_geometry_shader *shader = impl_from_ID3D11GeometryShader(iface);
547 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
549 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
552 static HRESULT STDMETHODCALLTYPE d3d11_geometry_shader_SetPrivateDataInterface(ID3D11GeometryShader *iface,
553 REFGUID guid, const IUnknown *data)
555 struct d3d_geometry_shader *shader = impl_from_ID3D11GeometryShader(iface);
557 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
559 return d3d_set_private_data_interface(&shader->private_store, guid, data);
562 static const struct ID3D11GeometryShaderVtbl d3d11_geometry_shader_vtbl =
564 /* IUnknown methods */
565 d3d11_geometry_shader_QueryInterface,
566 d3d11_geometry_shader_AddRef,
567 d3d11_geometry_shader_Release,
568 /* ID3D11DeviceChild methods */
569 d3d11_geometry_shader_GetDevice,
570 d3d11_geometry_shader_GetPrivateData,
571 d3d11_geometry_shader_SetPrivateData,
572 d3d11_geometry_shader_SetPrivateDataInterface,
575 /* ID3D10GeometryShader methods */
577 static inline struct d3d_geometry_shader *impl_from_ID3D10GeometryShader(ID3D10GeometryShader *iface)
579 return CONTAINING_RECORD(iface, struct d3d_geometry_shader, ID3D10GeometryShader_iface);
582 /* IUnknown methods */
584 static HRESULT STDMETHODCALLTYPE d3d10_geometry_shader_QueryInterface(ID3D10GeometryShader *iface,
585 REFIID riid, void **object)
587 struct d3d_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface);
589 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
591 return d3d11_geometry_shader_QueryInterface(&shader->ID3D11GeometryShader_iface, riid, object);
594 static ULONG STDMETHODCALLTYPE d3d10_geometry_shader_AddRef(ID3D10GeometryShader *iface)
596 struct d3d_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface);
598 TRACE("iface %p.\n", iface);
600 return d3d11_geometry_shader_AddRef(&shader->ID3D11GeometryShader_iface);
603 static ULONG STDMETHODCALLTYPE d3d10_geometry_shader_Release(ID3D10GeometryShader *iface)
605 struct d3d_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface);
607 TRACE("iface %p.\n", iface);
609 return d3d11_geometry_shader_Release(&shader->ID3D11GeometryShader_iface);
612 /* ID3D10DeviceChild methods */
614 static void STDMETHODCALLTYPE d3d10_geometry_shader_GetDevice(ID3D10GeometryShader *iface, ID3D10Device **device)
616 struct d3d_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface);
618 TRACE("iface %p, device %p.\n", iface, device);
620 ID3D11Device_QueryInterface(shader->device, &IID_ID3D10Device, (void **)device);
623 static HRESULT STDMETHODCALLTYPE d3d10_geometry_shader_GetPrivateData(ID3D10GeometryShader *iface,
624 REFGUID guid, UINT *data_size, void *data)
626 struct d3d_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface);
628 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
629 iface, debugstr_guid(guid), data_size, data);
631 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
634 static HRESULT STDMETHODCALLTYPE d3d10_geometry_shader_SetPrivateData(ID3D10GeometryShader *iface,
635 REFGUID guid, UINT data_size, const void *data)
637 struct d3d_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface);
639 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
640 iface, debugstr_guid(guid), data_size, data);
642 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
645 static HRESULT STDMETHODCALLTYPE d3d10_geometry_shader_SetPrivateDataInterface(ID3D10GeometryShader *iface,
646 REFGUID guid, const IUnknown *data)
648 struct d3d_geometry_shader *shader = impl_from_ID3D10GeometryShader(iface);
650 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
652 return d3d_set_private_data_interface(&shader->private_store, guid, data);
655 static const struct ID3D10GeometryShaderVtbl d3d10_geometry_shader_vtbl =
657 /* IUnknown methods */
658 d3d10_geometry_shader_QueryInterface,
659 d3d10_geometry_shader_AddRef,
660 d3d10_geometry_shader_Release,
661 /* ID3D10DeviceChild methods */
662 d3d10_geometry_shader_GetDevice,
663 d3d10_geometry_shader_GetPrivateData,
664 d3d10_geometry_shader_SetPrivateData,
665 d3d10_geometry_shader_SetPrivateDataInterface,
668 static void STDMETHODCALLTYPE d3d_geometry_shader_wined3d_object_destroyed(void *parent)
670 struct d3d_geometry_shader *shader = parent;
672 wined3d_private_store_cleanup(&shader->private_store);
673 HeapFree(GetProcessHeap(), 0, parent);
676 static const struct wined3d_parent_ops d3d_geometry_shader_wined3d_parent_ops =
678 d3d_geometry_shader_wined3d_object_destroyed,
681 static HRESULT d3d_geometry_shader_init(struct d3d_geometry_shader *shader, struct d3d_device *device,
682 const void *byte_code, SIZE_T byte_code_length)
684 struct wined3d_shader_signature output_signature;
685 struct wined3d_shader_signature input_signature;
686 struct d3d_shader_info shader_info;
687 struct wined3d_shader_desc desc;
688 HRESULT hr;
690 shader->ID3D11GeometryShader_iface.lpVtbl = &d3d11_geometry_shader_vtbl;
691 shader->ID3D10GeometryShader_iface.lpVtbl = &d3d10_geometry_shader_vtbl;
692 shader->refcount = 1;
693 wined3d_mutex_lock();
694 wined3d_private_store_init(&shader->private_store);
696 shader_info.input_signature = &input_signature;
697 shader_info.output_signature = &output_signature;
698 if (FAILED(hr = shader_extract_from_dxbc(byte_code, byte_code_length, &shader_info)))
700 ERR("Failed to extract shader, hr %#x.\n", hr);
701 wined3d_private_store_cleanup(&shader->private_store);
702 wined3d_mutex_unlock();
703 return hr;
706 desc.byte_code = shader_info.shader_code;
707 desc.input_signature = &input_signature;
708 desc.output_signature = &output_signature;
709 desc.max_version = 4;
711 hr = wined3d_shader_create_gs(device->wined3d_device, &desc, shader,
712 &d3d_geometry_shader_wined3d_parent_ops, &shader->wined3d_shader);
713 shader_free_signature(&input_signature);
714 shader_free_signature(&output_signature);
715 if (FAILED(hr))
717 WARN("Failed to create wined3d geometry shader, hr %#x.\n", hr);
718 wined3d_private_store_cleanup(&shader->private_store);
719 wined3d_mutex_unlock();
720 return E_INVALIDARG;
722 wined3d_mutex_unlock();
724 shader->device = &device->ID3D11Device_iface;
725 ID3D11Device_AddRef(shader->device);
727 return S_OK;
730 HRESULT d3d_geometry_shader_create(struct d3d_device *device, const void *byte_code, SIZE_T byte_code_length,
731 struct d3d_geometry_shader **shader)
733 struct d3d_geometry_shader *object;
734 HRESULT hr;
736 if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
737 return E_OUTOFMEMORY;
739 if (FAILED(hr = d3d_geometry_shader_init(object, device, byte_code, byte_code_length)))
741 WARN("Failed to initialize geometry shader, hr %#x.\n", hr);
742 HeapFree(GetProcessHeap(), 0, object);
743 return hr;
746 TRACE("Created geometry shader %p.\n", object);
747 *shader = object;
749 return S_OK;
752 struct d3d_geometry_shader *unsafe_impl_from_ID3D11GeometryShader(ID3D11GeometryShader *iface)
754 if (!iface)
755 return NULL;
756 assert(iface->lpVtbl == &d3d11_geometry_shader_vtbl);
758 return impl_from_ID3D11GeometryShader(iface);
761 struct d3d_geometry_shader *unsafe_impl_from_ID3D10GeometryShader(ID3D10GeometryShader *iface)
763 if (!iface)
764 return NULL;
765 assert(iface->lpVtbl == &d3d10_geometry_shader_vtbl);
767 return impl_from_ID3D10GeometryShader(iface);
770 /* ID3D11PixelShader methods */
772 static inline struct d3d_pixel_shader *impl_from_ID3D11PixelShader(ID3D11PixelShader *iface)
774 return CONTAINING_RECORD(iface, struct d3d_pixel_shader, ID3D11PixelShader_iface);
777 static HRESULT STDMETHODCALLTYPE d3d11_pixel_shader_QueryInterface(ID3D11PixelShader *iface,
778 REFIID riid, void **object)
780 struct d3d_pixel_shader *shader = impl_from_ID3D11PixelShader(iface);
782 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
784 if (IsEqualGUID(riid, &IID_ID3D11PixelShader)
785 || IsEqualGUID(riid, &IID_ID3D11DeviceChild)
786 || IsEqualGUID(riid, &IID_IUnknown))
788 ID3D11PixelShader_AddRef(iface);
789 *object = iface;
790 return S_OK;
793 if (IsEqualGUID(riid, &IID_ID3D10PixelShader)
794 || IsEqualGUID(riid, &IID_ID3D10DeviceChild))
796 IUnknown_AddRef(&shader->ID3D10PixelShader_iface);
797 *object = &shader->ID3D10PixelShader_iface;
798 return S_OK;
801 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
803 *object = NULL;
804 return E_NOINTERFACE;
807 static ULONG STDMETHODCALLTYPE d3d11_pixel_shader_AddRef(ID3D11PixelShader *iface)
809 struct d3d_pixel_shader *shader = impl_from_ID3D11PixelShader(iface);
810 ULONG refcount = InterlockedIncrement(&shader->refcount);
812 TRACE("%p increasing refcount to %u.\n", shader, refcount);
814 if (refcount == 1)
816 ID3D11Device_AddRef(shader->device);
817 wined3d_mutex_lock();
818 wined3d_shader_incref(shader->wined3d_shader);
819 wined3d_mutex_unlock();
822 return refcount;
825 static ULONG STDMETHODCALLTYPE d3d11_pixel_shader_Release(ID3D11PixelShader *iface)
827 struct d3d_pixel_shader *shader = impl_from_ID3D11PixelShader(iface);
828 ULONG refcount = InterlockedDecrement(&shader->refcount);
830 TRACE("%p decreasing refcount to %u.\n", shader, refcount);
832 if (!refcount)
834 ID3D11Device *device = shader->device;
836 wined3d_mutex_lock();
837 wined3d_shader_decref(shader->wined3d_shader);
838 wined3d_mutex_unlock();
839 /* Release the device last, it may cause the wined3d device to be
840 * destroyed. */
841 ID3D11Device_Release(device);
844 return refcount;
847 static void STDMETHODCALLTYPE d3d11_pixel_shader_GetDevice(ID3D11PixelShader *iface,
848 ID3D11Device **device)
850 struct d3d_pixel_shader *shader = impl_from_ID3D11PixelShader(iface);
852 TRACE("iface %p, device %p.\n", iface, device);
854 *device = shader->device;
855 ID3D11Device_AddRef(*device);
858 static HRESULT STDMETHODCALLTYPE d3d11_pixel_shader_GetPrivateData(ID3D11PixelShader *iface,
859 REFGUID guid, UINT *data_size, void *data)
861 struct d3d_pixel_shader *shader = impl_from_ID3D11PixelShader(iface);
863 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
865 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
868 static HRESULT STDMETHODCALLTYPE d3d11_pixel_shader_SetPrivateData(ID3D11PixelShader *iface,
869 REFGUID guid, UINT data_size, const void *data)
871 struct d3d_pixel_shader *shader = impl_from_ID3D11PixelShader(iface);
873 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
875 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
878 static HRESULT STDMETHODCALLTYPE d3d11_pixel_shader_SetPrivateDataInterface(ID3D11PixelShader *iface,
879 REFGUID guid, const IUnknown *data)
881 struct d3d_pixel_shader *shader = impl_from_ID3D11PixelShader(iface);
883 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
885 return d3d_set_private_data_interface(&shader->private_store, guid, data);
888 static const struct ID3D11PixelShaderVtbl d3d11_pixel_shader_vtbl =
890 /* IUnknown methods */
891 d3d11_pixel_shader_QueryInterface,
892 d3d11_pixel_shader_AddRef,
893 d3d11_pixel_shader_Release,
894 /* ID3D11DeviceChild methods */
895 d3d11_pixel_shader_GetDevice,
896 d3d11_pixel_shader_GetPrivateData,
897 d3d11_pixel_shader_SetPrivateData,
898 d3d11_pixel_shader_SetPrivateDataInterface,
901 /* ID3D10PixelShader methods */
903 static inline struct d3d_pixel_shader *impl_from_ID3D10PixelShader(ID3D10PixelShader *iface)
905 return CONTAINING_RECORD(iface, struct d3d_pixel_shader, ID3D10PixelShader_iface);
908 /* IUnknown methods */
910 static HRESULT STDMETHODCALLTYPE d3d10_pixel_shader_QueryInterface(ID3D10PixelShader *iface,
911 REFIID riid, void **object)
913 struct d3d_pixel_shader *shader = impl_from_ID3D10PixelShader(iface);
915 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
917 return d3d11_pixel_shader_QueryInterface(&shader->ID3D11PixelShader_iface, riid, object);
920 static ULONG STDMETHODCALLTYPE d3d10_pixel_shader_AddRef(ID3D10PixelShader *iface)
922 struct d3d_pixel_shader *shader = impl_from_ID3D10PixelShader(iface);
924 TRACE("iface %p.\n", iface);
926 return d3d11_pixel_shader_AddRef(&shader->ID3D11PixelShader_iface);
929 static ULONG STDMETHODCALLTYPE d3d10_pixel_shader_Release(ID3D10PixelShader *iface)
931 struct d3d_pixel_shader *shader = impl_from_ID3D10PixelShader(iface);
933 TRACE("iface %p.\n", iface);
935 return d3d11_pixel_shader_Release(&shader->ID3D11PixelShader_iface);
938 /* ID3D10DeviceChild methods */
940 static void STDMETHODCALLTYPE d3d10_pixel_shader_GetDevice(ID3D10PixelShader *iface, ID3D10Device **device)
942 struct d3d_pixel_shader *shader = impl_from_ID3D10PixelShader(iface);
944 TRACE("iface %p, device %p.\n", iface, device);
946 ID3D11Device_QueryInterface(shader->device, &IID_ID3D10Device, (void **)device);
949 static HRESULT STDMETHODCALLTYPE d3d10_pixel_shader_GetPrivateData(ID3D10PixelShader *iface,
950 REFGUID guid, UINT *data_size, void *data)
952 struct d3d_pixel_shader *shader = impl_from_ID3D10PixelShader(iface);
954 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
955 iface, debugstr_guid(guid), data_size, data);
957 return d3d_get_private_data(&shader->private_store, guid, data_size, data);
960 static HRESULT STDMETHODCALLTYPE d3d10_pixel_shader_SetPrivateData(ID3D10PixelShader *iface,
961 REFGUID guid, UINT data_size, const void *data)
963 struct d3d_pixel_shader *shader = impl_from_ID3D10PixelShader(iface);
965 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
966 iface, debugstr_guid(guid), data_size, data);
968 return d3d_set_private_data(&shader->private_store, guid, data_size, data);
971 static HRESULT STDMETHODCALLTYPE d3d10_pixel_shader_SetPrivateDataInterface(ID3D10PixelShader *iface,
972 REFGUID guid, const IUnknown *data)
974 struct d3d_pixel_shader *shader = impl_from_ID3D10PixelShader(iface);
976 TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
978 return d3d_set_private_data_interface(&shader->private_store, guid, data);
981 static const struct ID3D10PixelShaderVtbl d3d10_pixel_shader_vtbl =
983 /* IUnknown methods */
984 d3d10_pixel_shader_QueryInterface,
985 d3d10_pixel_shader_AddRef,
986 d3d10_pixel_shader_Release,
987 /* ID3D10DeviceChild methods */
988 d3d10_pixel_shader_GetDevice,
989 d3d10_pixel_shader_GetPrivateData,
990 d3d10_pixel_shader_SetPrivateData,
991 d3d10_pixel_shader_SetPrivateDataInterface,
994 static void STDMETHODCALLTYPE d3d_pixel_shader_wined3d_object_destroyed(void *parent)
996 struct d3d_pixel_shader *shader = parent;
998 wined3d_private_store_cleanup(&shader->private_store);
999 HeapFree(GetProcessHeap(), 0, parent);
1002 static const struct wined3d_parent_ops d3d_pixel_shader_wined3d_parent_ops =
1004 d3d_pixel_shader_wined3d_object_destroyed,
1007 static HRESULT d3d_pixel_shader_init(struct d3d_pixel_shader *shader, struct d3d_device *device,
1008 const void *byte_code, SIZE_T byte_code_length)
1010 struct wined3d_shader_signature output_signature;
1011 struct wined3d_shader_signature input_signature;
1012 struct d3d_shader_info shader_info;
1013 struct wined3d_shader_desc desc;
1014 HRESULT hr;
1016 shader->ID3D11PixelShader_iface.lpVtbl = &d3d11_pixel_shader_vtbl;
1017 shader->ID3D10PixelShader_iface.lpVtbl = &d3d10_pixel_shader_vtbl;
1018 shader->refcount = 1;
1019 wined3d_mutex_lock();
1020 wined3d_private_store_init(&shader->private_store);
1022 shader_info.input_signature = &input_signature;
1023 shader_info.output_signature = &output_signature;
1024 if (FAILED(hr = shader_extract_from_dxbc(byte_code, byte_code_length, &shader_info)))
1026 ERR("Failed to extract shader, hr %#x.\n", hr);
1027 wined3d_private_store_cleanup(&shader->private_store);
1028 wined3d_mutex_unlock();
1029 return hr;
1032 desc.byte_code = shader_info.shader_code;
1033 desc.input_signature = &input_signature;
1034 desc.output_signature = &output_signature;
1035 desc.max_version = 4;
1037 hr = wined3d_shader_create_ps(device->wined3d_device, &desc, shader,
1038 &d3d_pixel_shader_wined3d_parent_ops, &shader->wined3d_shader);
1039 shader_free_signature(&input_signature);
1040 shader_free_signature(&output_signature);
1041 if (FAILED(hr))
1043 WARN("Failed to create wined3d pixel shader, hr %#x.\n", hr);
1044 wined3d_private_store_cleanup(&shader->private_store);
1045 wined3d_mutex_unlock();
1046 return E_INVALIDARG;
1048 wined3d_mutex_unlock();
1050 shader->device = &device->ID3D11Device_iface;
1051 ID3D11Device_AddRef(shader->device);
1053 return S_OK;
1056 HRESULT d3d_pixel_shader_create(struct d3d_device *device, const void *byte_code, SIZE_T byte_code_length,
1057 struct d3d_pixel_shader **shader)
1059 struct d3d_pixel_shader *object;
1060 HRESULT hr;
1062 if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
1063 return E_OUTOFMEMORY;
1065 if (FAILED(hr = d3d_pixel_shader_init(object, device, byte_code, byte_code_length)))
1067 WARN("Failed to initialize pixel shader, hr %#x.\n", hr);
1068 HeapFree(GetProcessHeap(), 0, object);
1069 return hr;
1072 TRACE("Created pixel shader %p.\n", object);
1073 *shader = object;
1075 return S_OK;
1078 struct d3d_pixel_shader *unsafe_impl_from_ID3D11PixelShader(ID3D11PixelShader *iface)
1080 if (!iface)
1081 return NULL;
1082 assert(iface->lpVtbl == &d3d11_pixel_shader_vtbl);
1084 return impl_from_ID3D11PixelShader(iface);
1087 struct d3d_pixel_shader *unsafe_impl_from_ID3D10PixelShader(ID3D10PixelShader *iface)
1089 if (!iface)
1090 return NULL;
1091 assert(iface->lpVtbl == &d3d10_pixel_shader_vtbl);
1093 return impl_from_ID3D10PixelShader(iface);