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
21 #include "wine/port.h"
23 #include "d3d11_private.h"
25 WINE_DEFAULT_DEBUG_CHANNEL(d3d11
);
32 DWORD byte_code_offset
;
35 struct shader_handler_context
37 D3D_FEATURE_LEVEL feature_level
;
38 struct wined3d_shader_desc
*desc
;
41 static HRESULT
shdr_handler(const char *data
, DWORD data_size
, DWORD tag
, void *context
)
43 const struct shader_handler_context
*ctx
= context
;
44 struct wined3d_shader_desc
*desc
= ctx
->desc
;
50 if (ctx
->feature_level
<= D3D_FEATURE_LEVEL_9_3
)
52 TRACE("Skipping shader input signature on feature level %#x.\n", ctx
->feature_level
);
55 if (desc
->input_signature
.elements
)
57 FIXME("Multiple input signatures.\n");
60 if (FAILED(hr
= shader_parse_signature(tag
, data
, data_size
, &desc
->input_signature
)))
66 if (ctx
->feature_level
<= D3D_FEATURE_LEVEL_9_3
)
68 TRACE("Skipping shader output signature on feature level %#x.\n", ctx
->feature_level
);
71 if (desc
->output_signature
.elements
)
73 FIXME("Multiple output signatures.\n");
76 if (FAILED(hr
= shader_parse_signature(tag
, data
, data_size
, &desc
->output_signature
)))
81 if (desc
->patch_constant_signature
.elements
)
83 FIXME("Multiple patch constant signatures.\n");
86 if (FAILED(hr
= shader_parse_signature(tag
, data
, data_size
, &desc
->patch_constant_signature
)))
92 if (ctx
->feature_level
<= D3D_FEATURE_LEVEL_9_3
)
94 TRACE("Skipping SM4+ shader code on feature level %#x.\n", ctx
->feature_level
);
98 FIXME("Multiple shader code chunks.\n");
99 desc
->byte_code
= (const DWORD
*)data
;
100 desc
->byte_code_size
= data_size
;
101 desc
->format
= WINED3D_SHADER_BYTE_CODE_FORMAT_SM4
;
105 if (ctx
->feature_level
<= D3D_FEATURE_LEVEL_9_3
)
107 const struct aon9_header
*header
= (const struct aon9_header
*)data
;
108 unsigned int unknown_dword_count
;
109 const char *byte_code
;
111 if (data_size
< sizeof(*header
))
113 WARN("Invalid Aon9 data size %#x.\n", data_size
);
116 byte_code
= data
+ header
->byte_code_offset
;
117 unknown_dword_count
= (header
->byte_code_offset
- sizeof(*header
)) / sizeof(DWORD
);
119 if (data_size
- 2 * sizeof(DWORD
) < header
->byte_code_offset
)
121 WARN("Invalid byte code offset %#x (size %#x).\n", header
->byte_code_offset
, data_size
);
124 FIXME("Skipping %u unknown DWORDs.\n", unknown_dword_count
);
127 FIXME("Multiple shader code chunks.\n");
128 desc
->byte_code
= (const DWORD
*)byte_code
;
129 desc
->byte_code_size
= data_size
- header
->byte_code_offset
;
130 desc
->format
= WINED3D_SHADER_BYTE_CODE_FORMAT_SM1
;
131 TRACE("Feature level 9 shader version 0%08x, 0%08x.\n", header
->shader_version
, *desc
->byte_code
);
135 TRACE("Skipping feature level 9 shader code on feature level %#x.\n", ctx
->feature_level
);
144 FIXME("Unhandled chunk %s.\n", debugstr_an((const char *)&tag
, 4));
151 static void free_shader_desc(struct wined3d_shader_desc
*desc
)
153 shader_free_signature(&desc
->input_signature
);
154 shader_free_signature(&desc
->output_signature
);
155 shader_free_signature(&desc
->patch_constant_signature
);
158 static HRESULT
shader_extract_from_dxbc(const void *dxbc
, SIZE_T dxbc_length
,
159 struct wined3d_shader_desc
*desc
, D3D_FEATURE_LEVEL feature_level
)
161 struct shader_handler_context ctx
= {feature_level
, desc
};
164 desc
->byte_code
= NULL
;
165 desc
->byte_code_size
= 0;
166 memset(&desc
->input_signature
, 0, sizeof(desc
->input_signature
));
167 memset(&desc
->output_signature
, 0, sizeof(desc
->output_signature
));
168 memset(&desc
->patch_constant_signature
, 0, sizeof(desc
->patch_constant_signature
));
170 hr
= parse_dxbc(dxbc
, dxbc_length
, shdr_handler
, &ctx
);
171 if (!desc
->byte_code
)
176 FIXME("Failed to parse shader, hr %#x.\n", hr
);
177 free_shader_desc(desc
);
183 static const char *shader_get_string(const char *data
, size_t data_size
, DWORD offset
)
187 if (offset
>= data_size
)
189 WARN("Invalid offset %#x (data size %#lx).\n", offset
, (long)data_size
);
193 max_len
= data_size
- offset
;
194 len
= strnlen(data
+ offset
, max_len
);
199 return data
+ offset
;
202 HRESULT
shader_parse_signature(DWORD tag
, const char *data
, DWORD data_size
,
203 struct wined3d_shader_signature
*s
)
205 struct wined3d_shader_signature_element
*e
;
206 const char *ptr
= data
;
210 if (!require_space(0, 2, sizeof(DWORD
), data_size
))
212 WARN("Invalid data size %#x.\n", data_size
);
216 read_dword(&ptr
, &count
);
217 TRACE("%u elements.\n", count
);
219 skip_dword_unknown(&ptr
, 1); /* It seems to always be 0x00000008. */
221 if (!require_space(ptr
- data
, count
, 6 * sizeof(DWORD
), data_size
))
223 WARN("Invalid count %#x (data size %#x).\n", count
, data_size
);
227 if (!(e
= heap_calloc(count
, sizeof(*e
))))
229 ERR("Failed to allocate input signature memory.\n");
230 return E_OUTOFMEMORY
;
233 for (i
= 0; i
< count
; ++i
)
238 read_dword(&ptr
, &e
[i
].stream_idx
);
241 read_dword(&ptr
, &name_offset
);
242 if (!(e
[i
].semantic_name
= shader_get_string(data
, data_size
, name_offset
)))
244 WARN("Invalid name offset %#x (data size %#x).\n", name_offset
, data_size
);
248 read_dword(&ptr
, &e
[i
].semantic_idx
);
249 read_dword(&ptr
, &e
[i
].sysval_semantic
);
250 read_dword(&ptr
, &e
[i
].component_type
);
251 read_dword(&ptr
, &e
[i
].register_idx
);
252 read_dword(&ptr
, &e
[i
].mask
);
254 TRACE("Stream: %u, semantic: %s, semantic idx: %u, sysval_semantic %#x, "
255 "type %u, register idx: %u, use_mask %#x, input_mask %#x.\n",
256 e
[i
].stream_idx
, debugstr_a(e
[i
].semantic_name
), e
[i
].semantic_idx
, e
[i
].sysval_semantic
,
257 e
[i
].component_type
, e
[i
].register_idx
, (e
[i
].mask
>> 8) & 0xff, e
[i
].mask
& 0xff);
261 s
->element_count
= count
;
266 struct wined3d_shader_signature_element
*shader_find_signature_element(const struct wined3d_shader_signature
*s
,
267 const char *semantic_name
, unsigned int semantic_idx
, unsigned int stream_idx
)
269 struct wined3d_shader_signature_element
*e
= s
->elements
;
272 for (i
= 0; i
< s
->element_count
; ++i
)
274 if (!strcasecmp(e
[i
].semantic_name
, semantic_name
) && e
[i
].semantic_idx
== semantic_idx
275 && e
[i
].stream_idx
== stream_idx
)
282 void shader_free_signature(struct wined3d_shader_signature
*s
)
284 heap_free(s
->elements
);
287 /* ID3D11VertexShader methods */
289 static inline struct d3d_vertex_shader
*impl_from_ID3D11VertexShader(ID3D11VertexShader
*iface
)
291 return CONTAINING_RECORD(iface
, struct d3d_vertex_shader
, ID3D11VertexShader_iface
);
294 static HRESULT STDMETHODCALLTYPE
d3d11_vertex_shader_QueryInterface(ID3D11VertexShader
*iface
,
295 REFIID riid
, void **object
)
297 struct d3d_vertex_shader
*shader
= impl_from_ID3D11VertexShader(iface
);
299 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
301 if (IsEqualGUID(riid
, &IID_ID3D11VertexShader
)
302 || IsEqualGUID(riid
, &IID_ID3D11DeviceChild
)
303 || IsEqualGUID(riid
, &IID_IUnknown
))
305 ID3D11VertexShader_AddRef(iface
);
310 if (IsEqualGUID(riid
, &IID_ID3D10VertexShader
)
311 || IsEqualGUID(riid
, &IID_ID3D10DeviceChild
))
313 IUnknown_AddRef(&shader
->ID3D10VertexShader_iface
);
314 *object
= &shader
->ID3D10VertexShader_iface
;
318 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
321 return E_NOINTERFACE
;
324 static ULONG STDMETHODCALLTYPE
d3d11_vertex_shader_AddRef(ID3D11VertexShader
*iface
)
326 struct d3d_vertex_shader
*shader
= impl_from_ID3D11VertexShader(iface
);
327 ULONG refcount
= InterlockedIncrement(&shader
->refcount
);
329 TRACE("%p increasing refcount to %u.\n", shader
, refcount
);
333 ID3D11Device2_AddRef(shader
->device
);
334 wined3d_mutex_lock();
335 wined3d_shader_incref(shader
->wined3d_shader
);
336 wined3d_mutex_unlock();
342 static ULONG STDMETHODCALLTYPE
d3d11_vertex_shader_Release(ID3D11VertexShader
*iface
)
344 struct d3d_vertex_shader
*shader
= impl_from_ID3D11VertexShader(iface
);
345 ULONG refcount
= InterlockedDecrement(&shader
->refcount
);
347 TRACE("%p decreasing refcount to %u.\n", shader
, refcount
);
351 ID3D11Device2
*device
= shader
->device
;
353 wined3d_mutex_lock();
354 wined3d_shader_decref(shader
->wined3d_shader
);
355 wined3d_mutex_unlock();
356 /* Release the device last, it may cause the wined3d device to be
358 ID3D11Device2_Release(device
);
364 static void STDMETHODCALLTYPE
d3d11_vertex_shader_GetDevice(ID3D11VertexShader
*iface
,
365 ID3D11Device
**device
)
367 struct d3d_vertex_shader
*shader
= impl_from_ID3D11VertexShader(iface
);
369 TRACE("iface %p, device %p.\n", iface
, device
);
371 *device
= (ID3D11Device
*)shader
->device
;
372 ID3D11Device_AddRef(*device
);
375 static HRESULT STDMETHODCALLTYPE
d3d11_vertex_shader_GetPrivateData(ID3D11VertexShader
*iface
,
376 REFGUID guid
, UINT
*data_size
, void *data
)
378 struct d3d_vertex_shader
*shader
= impl_from_ID3D11VertexShader(iface
);
380 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
382 return d3d_get_private_data(&shader
->private_store
, guid
, data_size
, data
);
385 static HRESULT STDMETHODCALLTYPE
d3d11_vertex_shader_SetPrivateData(ID3D11VertexShader
*iface
,
386 REFGUID guid
, UINT data_size
, const void *data
)
388 struct d3d_vertex_shader
*shader
= impl_from_ID3D11VertexShader(iface
);
390 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
392 return d3d_set_private_data(&shader
->private_store
, guid
, data_size
, data
);
395 static HRESULT STDMETHODCALLTYPE
d3d11_vertex_shader_SetPrivateDataInterface(ID3D11VertexShader
*iface
,
396 REFGUID guid
, const IUnknown
*data
)
398 struct d3d_vertex_shader
*shader
= impl_from_ID3D11VertexShader(iface
);
400 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
402 return d3d_set_private_data_interface(&shader
->private_store
, guid
, data
);
405 static const struct ID3D11VertexShaderVtbl d3d11_vertex_shader_vtbl
=
407 /* IUnknown methods */
408 d3d11_vertex_shader_QueryInterface
,
409 d3d11_vertex_shader_AddRef
,
410 d3d11_vertex_shader_Release
,
411 /* ID3D11DeviceChild methods */
412 d3d11_vertex_shader_GetDevice
,
413 d3d11_vertex_shader_GetPrivateData
,
414 d3d11_vertex_shader_SetPrivateData
,
415 d3d11_vertex_shader_SetPrivateDataInterface
,
418 /* ID3D10VertexShader methods */
420 static inline struct d3d_vertex_shader
*impl_from_ID3D10VertexShader(ID3D10VertexShader
*iface
)
422 return CONTAINING_RECORD(iface
, struct d3d_vertex_shader
, ID3D10VertexShader_iface
);
425 /* IUnknown methods */
427 static HRESULT STDMETHODCALLTYPE
d3d10_vertex_shader_QueryInterface(ID3D10VertexShader
*iface
,
428 REFIID riid
, void **object
)
430 struct d3d_vertex_shader
*shader
= impl_from_ID3D10VertexShader(iface
);
432 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
434 return d3d11_vertex_shader_QueryInterface(&shader
->ID3D11VertexShader_iface
, riid
, object
);
437 static ULONG STDMETHODCALLTYPE
d3d10_vertex_shader_AddRef(ID3D10VertexShader
*iface
)
439 struct d3d_vertex_shader
*shader
= impl_from_ID3D10VertexShader(iface
);
441 TRACE("iface %p.\n", iface
);
443 return d3d11_vertex_shader_AddRef(&shader
->ID3D11VertexShader_iface
);
446 static ULONG STDMETHODCALLTYPE
d3d10_vertex_shader_Release(ID3D10VertexShader
*iface
)
448 struct d3d_vertex_shader
*shader
= impl_from_ID3D10VertexShader(iface
);
450 TRACE("iface %p.\n", iface
);
452 return d3d11_vertex_shader_Release(&shader
->ID3D11VertexShader_iface
);
455 /* ID3D10DeviceChild methods */
457 static void STDMETHODCALLTYPE
d3d10_vertex_shader_GetDevice(ID3D10VertexShader
*iface
, ID3D10Device
**device
)
459 struct d3d_vertex_shader
*shader
= impl_from_ID3D10VertexShader(iface
);
461 TRACE("iface %p, device %p.\n", iface
, device
);
463 ID3D11Device2_QueryInterface(shader
->device
, &IID_ID3D10Device
, (void **)device
);
466 static HRESULT STDMETHODCALLTYPE
d3d10_vertex_shader_GetPrivateData(ID3D10VertexShader
*iface
,
467 REFGUID guid
, UINT
*data_size
, void *data
)
469 struct d3d_vertex_shader
*shader
= impl_from_ID3D10VertexShader(iface
);
471 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
472 iface
, debugstr_guid(guid
), data_size
, data
);
474 return d3d_get_private_data(&shader
->private_store
, guid
, data_size
, data
);
477 static HRESULT STDMETHODCALLTYPE
d3d10_vertex_shader_SetPrivateData(ID3D10VertexShader
*iface
,
478 REFGUID guid
, UINT data_size
, const void *data
)
480 struct d3d_vertex_shader
*shader
= impl_from_ID3D10VertexShader(iface
);
482 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
483 iface
, debugstr_guid(guid
), data_size
, data
);
485 return d3d_set_private_data(&shader
->private_store
, guid
, data_size
, data
);
488 static HRESULT STDMETHODCALLTYPE
d3d10_vertex_shader_SetPrivateDataInterface(ID3D10VertexShader
*iface
,
489 REFGUID guid
, const IUnknown
*data
)
491 struct d3d_vertex_shader
*shader
= impl_from_ID3D10VertexShader(iface
);
493 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
495 return d3d_set_private_data_interface(&shader
->private_store
, guid
, data
);
498 static const struct ID3D10VertexShaderVtbl d3d10_vertex_shader_vtbl
=
500 /* IUnknown methods */
501 d3d10_vertex_shader_QueryInterface
,
502 d3d10_vertex_shader_AddRef
,
503 d3d10_vertex_shader_Release
,
504 /* ID3D10DeviceChild methods */
505 d3d10_vertex_shader_GetDevice
,
506 d3d10_vertex_shader_GetPrivateData
,
507 d3d10_vertex_shader_SetPrivateData
,
508 d3d10_vertex_shader_SetPrivateDataInterface
,
511 static void STDMETHODCALLTYPE
d3d_vertex_shader_wined3d_object_destroyed(void *parent
)
513 struct d3d_vertex_shader
*shader
= parent
;
515 wined3d_private_store_cleanup(&shader
->private_store
);
519 static const struct wined3d_parent_ops d3d_vertex_shader_wined3d_parent_ops
=
521 d3d_vertex_shader_wined3d_object_destroyed
,
524 static unsigned int d3d_sm_from_feature_level(D3D_FEATURE_LEVEL feature_level
)
526 switch (feature_level
)
528 case D3D_FEATURE_LEVEL_11_1
:
529 case D3D_FEATURE_LEVEL_11_0
:
531 case D3D_FEATURE_LEVEL_10_1
:
532 case D3D_FEATURE_LEVEL_10_0
:
534 case D3D_FEATURE_LEVEL_9_3
:
536 case D3D_FEATURE_LEVEL_9_2
:
537 case D3D_FEATURE_LEVEL_9_1
:
540 ERR("Unexpected feature_level %#x.\n", feature_level
);
545 static HRESULT
d3d_vertex_shader_init(struct d3d_vertex_shader
*shader
, struct d3d_device
*device
,
546 const void *byte_code
, SIZE_T byte_code_length
)
548 struct wined3d_shader_desc desc
;
551 shader
->ID3D11VertexShader_iface
.lpVtbl
= &d3d11_vertex_shader_vtbl
;
552 shader
->ID3D10VertexShader_iface
.lpVtbl
= &d3d10_vertex_shader_vtbl
;
553 shader
->refcount
= 1;
554 wined3d_mutex_lock();
555 wined3d_private_store_init(&shader
->private_store
);
557 if (FAILED(hr
= shader_extract_from_dxbc(byte_code
, byte_code_length
, &desc
, device
->feature_level
)))
559 WARN("Failed to extract shader, hr %#x.\n", hr
);
560 wined3d_private_store_cleanup(&shader
->private_store
);
561 wined3d_mutex_unlock();
564 desc
.max_version
= d3d_sm_from_feature_level(device
->feature_level
);
566 hr
= wined3d_shader_create_vs(device
->wined3d_device
, &desc
, shader
,
567 &d3d_vertex_shader_wined3d_parent_ops
, &shader
->wined3d_shader
);
568 free_shader_desc(&desc
);
571 WARN("Failed to create wined3d vertex shader, hr %#x.\n", hr
);
572 wined3d_private_store_cleanup(&shader
->private_store
);
573 wined3d_mutex_unlock();
576 wined3d_mutex_unlock();
578 ID3D11Device2_AddRef(shader
->device
= &device
->ID3D11Device2_iface
);
583 HRESULT
d3d_vertex_shader_create(struct d3d_device
*device
, const void *byte_code
, SIZE_T byte_code_length
,
584 struct d3d_vertex_shader
**shader
)
586 struct d3d_vertex_shader
*object
;
589 if (!(object
= heap_alloc_zero(sizeof(*object
))))
590 return E_OUTOFMEMORY
;
592 if (FAILED(hr
= d3d_vertex_shader_init(object
, device
, byte_code
, byte_code_length
)))
594 WARN("Failed to initialize vertex shader, hr %#x.\n", hr
);
599 TRACE("Created vertex shader %p.\n", object
);
605 struct d3d_vertex_shader
*unsafe_impl_from_ID3D11VertexShader(ID3D11VertexShader
*iface
)
609 assert(iface
->lpVtbl
== &d3d11_vertex_shader_vtbl
);
611 return impl_from_ID3D11VertexShader(iface
);
614 struct d3d_vertex_shader
*unsafe_impl_from_ID3D10VertexShader(ID3D10VertexShader
*iface
)
618 assert(iface
->lpVtbl
== &d3d10_vertex_shader_vtbl
);
620 return impl_from_ID3D10VertexShader(iface
);
623 /* ID3D11HullShader methods */
625 static inline struct d3d11_hull_shader
*impl_from_ID3D11HullShader(ID3D11HullShader
*iface
)
627 return CONTAINING_RECORD(iface
, struct d3d11_hull_shader
, ID3D11HullShader_iface
);
630 static HRESULT STDMETHODCALLTYPE
d3d11_hull_shader_QueryInterface(ID3D11HullShader
*iface
,
631 REFIID riid
, void **object
)
633 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
635 if (IsEqualGUID(riid
, &IID_ID3D11HullShader
)
636 || IsEqualGUID(riid
, &IID_ID3D11DeviceChild
)
637 || IsEqualGUID(riid
, &IID_IUnknown
))
639 ID3D11HullShader_AddRef(iface
);
644 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
647 return E_NOINTERFACE
;
650 static ULONG STDMETHODCALLTYPE
d3d11_hull_shader_AddRef(ID3D11HullShader
*iface
)
652 struct d3d11_hull_shader
*shader
= impl_from_ID3D11HullShader(iface
);
653 ULONG refcount
= InterlockedIncrement(&shader
->refcount
);
655 TRACE("%p increasing refcount to %u.\n", shader
, refcount
);
659 ID3D11Device2_AddRef(shader
->device
);
660 wined3d_mutex_lock();
661 wined3d_shader_incref(shader
->wined3d_shader
);
662 wined3d_mutex_unlock();
668 static ULONG STDMETHODCALLTYPE
d3d11_hull_shader_Release(ID3D11HullShader
*iface
)
670 struct d3d11_hull_shader
*shader
= impl_from_ID3D11HullShader(iface
);
671 ULONG refcount
= InterlockedDecrement(&shader
->refcount
);
673 TRACE("%p decreasing refcount to %u.\n", shader
, refcount
);
677 ID3D11Device2
*device
= shader
->device
;
679 wined3d_mutex_lock();
680 wined3d_shader_decref(shader
->wined3d_shader
);
681 wined3d_mutex_unlock();
683 /* Release the device last, it may cause the wined3d device to be
685 ID3D11Device2_Release(device
);
691 static void STDMETHODCALLTYPE
d3d11_hull_shader_GetDevice(ID3D11HullShader
*iface
,
692 ID3D11Device
**device
)
694 struct d3d11_hull_shader
*shader
= impl_from_ID3D11HullShader(iface
);
696 TRACE("iface %p, device %p.\n", iface
, device
);
698 *device
= (ID3D11Device
*)shader
->device
;
699 ID3D11Device_AddRef(*device
);
702 static HRESULT STDMETHODCALLTYPE
d3d11_hull_shader_GetPrivateData(ID3D11HullShader
*iface
,
703 REFGUID guid
, UINT
*data_size
, void *data
)
705 struct d3d11_hull_shader
*shader
= impl_from_ID3D11HullShader(iface
);
707 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
709 return d3d_get_private_data(&shader
->private_store
, guid
, data_size
, data
);
712 static HRESULT STDMETHODCALLTYPE
d3d11_hull_shader_SetPrivateData(ID3D11HullShader
*iface
,
713 REFGUID guid
, UINT data_size
, const void *data
)
715 struct d3d11_hull_shader
*shader
= impl_from_ID3D11HullShader(iface
);
717 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
719 return d3d_set_private_data(&shader
->private_store
, guid
, data_size
, data
);
722 static HRESULT STDMETHODCALLTYPE
d3d11_hull_shader_SetPrivateDataInterface(ID3D11HullShader
*iface
,
723 REFGUID guid
, const IUnknown
*data
)
725 struct d3d11_hull_shader
*shader
= impl_from_ID3D11HullShader(iface
);
727 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
729 return d3d_set_private_data_interface(&shader
->private_store
, guid
, data
);
732 static const struct ID3D11HullShaderVtbl d3d11_hull_shader_vtbl
=
734 /* IUnknown methods */
735 d3d11_hull_shader_QueryInterface
,
736 d3d11_hull_shader_AddRef
,
737 d3d11_hull_shader_Release
,
738 /* ID3D11DeviceChild methods */
739 d3d11_hull_shader_GetDevice
,
740 d3d11_hull_shader_GetPrivateData
,
741 d3d11_hull_shader_SetPrivateData
,
742 d3d11_hull_shader_SetPrivateDataInterface
,
745 static void STDMETHODCALLTYPE
d3d11_hull_shader_wined3d_object_destroyed(void *parent
)
747 struct d3d11_hull_shader
*shader
= parent
;
749 wined3d_private_store_cleanup(&shader
->private_store
);
753 static const struct wined3d_parent_ops d3d11_hull_shader_wined3d_parent_ops
=
755 d3d11_hull_shader_wined3d_object_destroyed
,
758 static HRESULT
d3d11_hull_shader_init(struct d3d11_hull_shader
*shader
, struct d3d_device
*device
,
759 const void *byte_code
, SIZE_T byte_code_length
)
761 struct wined3d_shader_desc desc
;
764 shader
->ID3D11HullShader_iface
.lpVtbl
= &d3d11_hull_shader_vtbl
;
765 shader
->refcount
= 1;
766 wined3d_mutex_lock();
767 wined3d_private_store_init(&shader
->private_store
);
769 if (FAILED(hr
= shader_extract_from_dxbc(byte_code
, byte_code_length
, &desc
, device
->feature_level
)))
771 WARN("Failed to extract shader, hr %#x.\n", hr
);
772 wined3d_private_store_cleanup(&shader
->private_store
);
773 wined3d_mutex_unlock();
776 desc
.max_version
= d3d_sm_from_feature_level(device
->feature_level
);
778 hr
= wined3d_shader_create_hs(device
->wined3d_device
, &desc
, shader
,
779 &d3d11_hull_shader_wined3d_parent_ops
, &shader
->wined3d_shader
);
780 free_shader_desc(&desc
);
783 WARN("Failed to create wined3d hull shader, hr %#x.\n", hr
);
784 wined3d_private_store_cleanup(&shader
->private_store
);
785 wined3d_mutex_unlock();
788 wined3d_mutex_unlock();
790 ID3D11Device2_AddRef(shader
->device
= &device
->ID3D11Device2_iface
);
795 HRESULT
d3d11_hull_shader_create(struct d3d_device
*device
, const void *byte_code
, SIZE_T byte_code_length
,
796 struct d3d11_hull_shader
**shader
)
798 struct d3d11_hull_shader
*object
;
801 if (!(object
= heap_alloc_zero(sizeof(*object
))))
802 return E_OUTOFMEMORY
;
804 if (FAILED(hr
= d3d11_hull_shader_init(object
, device
, byte_code
, byte_code_length
)))
810 TRACE("Created hull shader %p.\n", object
);
816 struct d3d11_hull_shader
*unsafe_impl_from_ID3D11HullShader(ID3D11HullShader
*iface
)
820 assert(iface
->lpVtbl
== &d3d11_hull_shader_vtbl
);
822 return impl_from_ID3D11HullShader(iface
);
825 /* ID3D11DomainShader methods */
827 static inline struct d3d11_domain_shader
*impl_from_ID3D11DomainShader(ID3D11DomainShader
*iface
)
829 return CONTAINING_RECORD(iface
, struct d3d11_domain_shader
, ID3D11DomainShader_iface
);
832 static HRESULT STDMETHODCALLTYPE
d3d11_domain_shader_QueryInterface(ID3D11DomainShader
*iface
,
833 REFIID riid
, void **object
)
835 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
837 if (IsEqualGUID(riid
, &IID_ID3D11DomainShader
)
838 || IsEqualGUID(riid
, &IID_ID3D11DeviceChild
)
839 || IsEqualGUID(riid
, &IID_IUnknown
))
841 ID3D11DomainShader_AddRef(iface
);
846 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
849 return E_NOINTERFACE
;
852 static ULONG STDMETHODCALLTYPE
d3d11_domain_shader_AddRef(ID3D11DomainShader
*iface
)
854 struct d3d11_domain_shader
*shader
= impl_from_ID3D11DomainShader(iface
);
855 ULONG refcount
= InterlockedIncrement(&shader
->refcount
);
857 TRACE("%p increasing refcount to %u.\n", shader
, refcount
);
861 ID3D11Device2_AddRef(shader
->device
);
862 wined3d_mutex_lock();
863 wined3d_shader_incref(shader
->wined3d_shader
);
864 wined3d_mutex_unlock();
870 static ULONG STDMETHODCALLTYPE
d3d11_domain_shader_Release(ID3D11DomainShader
*iface
)
872 struct d3d11_domain_shader
*shader
= impl_from_ID3D11DomainShader(iface
);
873 ULONG refcount
= InterlockedDecrement(&shader
->refcount
);
875 TRACE("%p decreasing refcount to %u.\n", shader
, refcount
);
879 ID3D11Device2
*device
= shader
->device
;
881 wined3d_mutex_lock();
882 wined3d_shader_decref(shader
->wined3d_shader
);
883 wined3d_mutex_unlock();
885 /* Release the device last, it may cause the wined3d device to be
887 ID3D11Device2_Release(device
);
893 static void STDMETHODCALLTYPE
d3d11_domain_shader_GetDevice(ID3D11DomainShader
*iface
,
894 ID3D11Device
**device
)
896 struct d3d11_domain_shader
*shader
= impl_from_ID3D11DomainShader(iface
);
898 TRACE("iface %p, device %p.\n", iface
, device
);
900 *device
= (ID3D11Device
*)shader
->device
;
901 ID3D11Device_AddRef(*device
);
904 static HRESULT STDMETHODCALLTYPE
d3d11_domain_shader_GetPrivateData(ID3D11DomainShader
*iface
,
905 REFGUID guid
, UINT
*data_size
, void *data
)
907 struct d3d11_domain_shader
*shader
= impl_from_ID3D11DomainShader(iface
);
909 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
911 return d3d_get_private_data(&shader
->private_store
, guid
, data_size
, data
);
914 static HRESULT STDMETHODCALLTYPE
d3d11_domain_shader_SetPrivateData(ID3D11DomainShader
*iface
,
915 REFGUID guid
, UINT data_size
, const void *data
)
917 struct d3d11_domain_shader
*shader
= impl_from_ID3D11DomainShader(iface
);
919 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
921 return d3d_set_private_data(&shader
->private_store
, guid
, data_size
, data
);
924 static HRESULT STDMETHODCALLTYPE
d3d11_domain_shader_SetPrivateDataInterface(ID3D11DomainShader
*iface
,
925 REFGUID guid
, const IUnknown
*data
)
927 struct d3d11_domain_shader
*shader
= impl_from_ID3D11DomainShader(iface
);
929 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
931 return d3d_set_private_data_interface(&shader
->private_store
, guid
, data
);
934 static const struct ID3D11DomainShaderVtbl d3d11_domain_shader_vtbl
=
936 /* IUnknown methods */
937 d3d11_domain_shader_QueryInterface
,
938 d3d11_domain_shader_AddRef
,
939 d3d11_domain_shader_Release
,
940 /* ID3D11DeviceChild methods */
941 d3d11_domain_shader_GetDevice
,
942 d3d11_domain_shader_GetPrivateData
,
943 d3d11_domain_shader_SetPrivateData
,
944 d3d11_domain_shader_SetPrivateDataInterface
,
947 static void STDMETHODCALLTYPE
d3d11_domain_shader_wined3d_object_destroyed(void *parent
)
949 struct d3d11_domain_shader
*shader
= parent
;
951 wined3d_private_store_cleanup(&shader
->private_store
);
955 static const struct wined3d_parent_ops d3d11_domain_shader_wined3d_parent_ops
=
957 d3d11_domain_shader_wined3d_object_destroyed
,
960 static HRESULT
d3d11_domain_shader_init(struct d3d11_domain_shader
*shader
, struct d3d_device
*device
,
961 const void *byte_code
, SIZE_T byte_code_length
)
963 struct wined3d_shader_desc desc
;
966 shader
->ID3D11DomainShader_iface
.lpVtbl
= &d3d11_domain_shader_vtbl
;
967 shader
->refcount
= 1;
968 wined3d_mutex_lock();
969 wined3d_private_store_init(&shader
->private_store
);
971 if (FAILED(hr
= shader_extract_from_dxbc(byte_code
, byte_code_length
, &desc
, device
->feature_level
)))
973 WARN("Failed to extract shader, hr %#x.\n", hr
);
974 wined3d_private_store_cleanup(&shader
->private_store
);
975 wined3d_mutex_unlock();
978 desc
.max_version
= d3d_sm_from_feature_level(device
->feature_level
);
980 hr
= wined3d_shader_create_ds(device
->wined3d_device
, &desc
, shader
,
981 &d3d11_domain_shader_wined3d_parent_ops
, &shader
->wined3d_shader
);
982 free_shader_desc(&desc
);
985 WARN("Failed to create wined3d domain shader, hr %#x.\n", hr
);
986 wined3d_private_store_cleanup(&shader
->private_store
);
987 wined3d_mutex_unlock();
990 wined3d_mutex_unlock();
992 ID3D11Device2_AddRef(shader
->device
= &device
->ID3D11Device2_iface
);
997 HRESULT
d3d11_domain_shader_create(struct d3d_device
*device
, const void *byte_code
, SIZE_T byte_code_length
,
998 struct d3d11_domain_shader
**shader
)
1000 struct d3d11_domain_shader
*object
;
1003 if (!(object
= heap_alloc_zero(sizeof(*object
))))
1004 return E_OUTOFMEMORY
;
1006 if (FAILED(hr
= d3d11_domain_shader_init(object
, device
, byte_code
, byte_code_length
)))
1012 TRACE("Created domain shader %p.\n", object
);
1018 struct d3d11_domain_shader
*unsafe_impl_from_ID3D11DomainShader(ID3D11DomainShader
*iface
)
1022 assert(iface
->lpVtbl
== &d3d11_domain_shader_vtbl
);
1024 return impl_from_ID3D11DomainShader(iface
);
1027 /* ID3D11GeometryShader methods */
1029 static inline struct d3d_geometry_shader
*impl_from_ID3D11GeometryShader(ID3D11GeometryShader
*iface
)
1031 return CONTAINING_RECORD(iface
, struct d3d_geometry_shader
, ID3D11GeometryShader_iface
);
1034 static HRESULT STDMETHODCALLTYPE
d3d11_geometry_shader_QueryInterface(ID3D11GeometryShader
*iface
,
1035 REFIID riid
, void **object
)
1037 struct d3d_geometry_shader
*shader
= impl_from_ID3D11GeometryShader(iface
);
1039 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
1041 if (IsEqualGUID(riid
, &IID_ID3D11GeometryShader
)
1042 || IsEqualGUID(riid
, &IID_ID3D11DeviceChild
)
1043 || IsEqualGUID(riid
, &IID_IUnknown
))
1045 ID3D11GeometryShader_AddRef(iface
);
1050 if (IsEqualGUID(riid
, &IID_ID3D10GeometryShader
)
1051 || IsEqualGUID(riid
, &IID_ID3D10DeviceChild
))
1053 ID3D10GeometryShader_AddRef(&shader
->ID3D10GeometryShader_iface
);
1054 *object
= &shader
->ID3D10GeometryShader_iface
;
1058 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
1061 return E_NOINTERFACE
;
1064 static ULONG STDMETHODCALLTYPE
d3d11_geometry_shader_AddRef(ID3D11GeometryShader
*iface
)
1066 struct d3d_geometry_shader
*shader
= impl_from_ID3D11GeometryShader(iface
);
1067 ULONG refcount
= InterlockedIncrement(&shader
->refcount
);
1069 TRACE("%p increasing refcount to %u.\n", shader
, refcount
);
1073 ID3D11Device2_AddRef(shader
->device
);
1074 wined3d_mutex_lock();
1075 wined3d_shader_incref(shader
->wined3d_shader
);
1076 wined3d_mutex_unlock();
1082 static ULONG STDMETHODCALLTYPE
d3d11_geometry_shader_Release(ID3D11GeometryShader
*iface
)
1084 struct d3d_geometry_shader
*shader
= impl_from_ID3D11GeometryShader(iface
);
1085 ULONG refcount
= InterlockedDecrement(&shader
->refcount
);
1087 TRACE("%p decreasing refcount to %u.\n", shader
, refcount
);
1091 ID3D11Device2
*device
= shader
->device
;
1093 wined3d_mutex_lock();
1094 wined3d_shader_decref(shader
->wined3d_shader
);
1095 wined3d_mutex_unlock();
1097 /* Release the device last, it may cause the wined3d device to be
1099 ID3D11Device2_Release(device
);
1105 static void STDMETHODCALLTYPE
d3d11_geometry_shader_GetDevice(ID3D11GeometryShader
*iface
,
1106 ID3D11Device
**device
)
1108 struct d3d_geometry_shader
*shader
= impl_from_ID3D11GeometryShader(iface
);
1110 TRACE("iface %p, device %p.\n", iface
, device
);
1112 *device
= (ID3D11Device
*)shader
->device
;
1113 ID3D11Device_AddRef(*device
);
1116 static HRESULT STDMETHODCALLTYPE
d3d11_geometry_shader_GetPrivateData(ID3D11GeometryShader
*iface
,
1117 REFGUID guid
, UINT
*data_size
, void *data
)
1119 struct d3d_geometry_shader
*shader
= impl_from_ID3D11GeometryShader(iface
);
1121 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
1123 return d3d_get_private_data(&shader
->private_store
, guid
, data_size
, data
);
1126 static HRESULT STDMETHODCALLTYPE
d3d11_geometry_shader_SetPrivateData(ID3D11GeometryShader
*iface
,
1127 REFGUID guid
, UINT data_size
, const void *data
)
1129 struct d3d_geometry_shader
*shader
= impl_from_ID3D11GeometryShader(iface
);
1131 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
1133 return d3d_set_private_data(&shader
->private_store
, guid
, data_size
, data
);
1136 static HRESULT STDMETHODCALLTYPE
d3d11_geometry_shader_SetPrivateDataInterface(ID3D11GeometryShader
*iface
,
1137 REFGUID guid
, const IUnknown
*data
)
1139 struct d3d_geometry_shader
*shader
= impl_from_ID3D11GeometryShader(iface
);
1141 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
1143 return d3d_set_private_data_interface(&shader
->private_store
, guid
, data
);
1146 static const struct ID3D11GeometryShaderVtbl d3d11_geometry_shader_vtbl
=
1148 /* IUnknown methods */
1149 d3d11_geometry_shader_QueryInterface
,
1150 d3d11_geometry_shader_AddRef
,
1151 d3d11_geometry_shader_Release
,
1152 /* ID3D11DeviceChild methods */
1153 d3d11_geometry_shader_GetDevice
,
1154 d3d11_geometry_shader_GetPrivateData
,
1155 d3d11_geometry_shader_SetPrivateData
,
1156 d3d11_geometry_shader_SetPrivateDataInterface
,
1159 /* ID3D10GeometryShader methods */
1161 static inline struct d3d_geometry_shader
*impl_from_ID3D10GeometryShader(ID3D10GeometryShader
*iface
)
1163 return CONTAINING_RECORD(iface
, struct d3d_geometry_shader
, ID3D10GeometryShader_iface
);
1166 /* IUnknown methods */
1168 static HRESULT STDMETHODCALLTYPE
d3d10_geometry_shader_QueryInterface(ID3D10GeometryShader
*iface
,
1169 REFIID riid
, void **object
)
1171 struct d3d_geometry_shader
*shader
= impl_from_ID3D10GeometryShader(iface
);
1173 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
1175 return d3d11_geometry_shader_QueryInterface(&shader
->ID3D11GeometryShader_iface
, riid
, object
);
1178 static ULONG STDMETHODCALLTYPE
d3d10_geometry_shader_AddRef(ID3D10GeometryShader
*iface
)
1180 struct d3d_geometry_shader
*shader
= impl_from_ID3D10GeometryShader(iface
);
1182 TRACE("iface %p.\n", iface
);
1184 return d3d11_geometry_shader_AddRef(&shader
->ID3D11GeometryShader_iface
);
1187 static ULONG STDMETHODCALLTYPE
d3d10_geometry_shader_Release(ID3D10GeometryShader
*iface
)
1189 struct d3d_geometry_shader
*shader
= impl_from_ID3D10GeometryShader(iface
);
1191 TRACE("iface %p.\n", iface
);
1193 return d3d11_geometry_shader_Release(&shader
->ID3D11GeometryShader_iface
);
1196 /* ID3D10DeviceChild methods */
1198 static void STDMETHODCALLTYPE
d3d10_geometry_shader_GetDevice(ID3D10GeometryShader
*iface
, ID3D10Device
**device
)
1200 struct d3d_geometry_shader
*shader
= impl_from_ID3D10GeometryShader(iface
);
1202 TRACE("iface %p, device %p.\n", iface
, device
);
1204 ID3D11Device2_QueryInterface(shader
->device
, &IID_ID3D10Device
, (void **)device
);
1207 static HRESULT STDMETHODCALLTYPE
d3d10_geometry_shader_GetPrivateData(ID3D10GeometryShader
*iface
,
1208 REFGUID guid
, UINT
*data_size
, void *data
)
1210 struct d3d_geometry_shader
*shader
= impl_from_ID3D10GeometryShader(iface
);
1212 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
1213 iface
, debugstr_guid(guid
), data_size
, data
);
1215 return d3d_get_private_data(&shader
->private_store
, guid
, data_size
, data
);
1218 static HRESULT STDMETHODCALLTYPE
d3d10_geometry_shader_SetPrivateData(ID3D10GeometryShader
*iface
,
1219 REFGUID guid
, UINT data_size
, const void *data
)
1221 struct d3d_geometry_shader
*shader
= impl_from_ID3D10GeometryShader(iface
);
1223 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
1224 iface
, debugstr_guid(guid
), data_size
, data
);
1226 return d3d_set_private_data(&shader
->private_store
, guid
, data_size
, data
);
1229 static HRESULT STDMETHODCALLTYPE
d3d10_geometry_shader_SetPrivateDataInterface(ID3D10GeometryShader
*iface
,
1230 REFGUID guid
, const IUnknown
*data
)
1232 struct d3d_geometry_shader
*shader
= impl_from_ID3D10GeometryShader(iface
);
1234 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
1236 return d3d_set_private_data_interface(&shader
->private_store
, guid
, data
);
1239 static const struct ID3D10GeometryShaderVtbl d3d10_geometry_shader_vtbl
=
1241 /* IUnknown methods */
1242 d3d10_geometry_shader_QueryInterface
,
1243 d3d10_geometry_shader_AddRef
,
1244 d3d10_geometry_shader_Release
,
1245 /* ID3D10DeviceChild methods */
1246 d3d10_geometry_shader_GetDevice
,
1247 d3d10_geometry_shader_GetPrivateData
,
1248 d3d10_geometry_shader_SetPrivateData
,
1249 d3d10_geometry_shader_SetPrivateDataInterface
,
1252 static void STDMETHODCALLTYPE
d3d_geometry_shader_wined3d_object_destroyed(void *parent
)
1254 struct d3d_geometry_shader
*shader
= parent
;
1256 wined3d_private_store_cleanup(&shader
->private_store
);
1260 static const struct wined3d_parent_ops d3d_geometry_shader_wined3d_parent_ops
=
1262 d3d_geometry_shader_wined3d_object_destroyed
,
1265 static HRESULT
wined3d_so_elements_from_d3d11_so_entries(struct wined3d_stream_output_element
*elements
,
1266 const D3D11_SO_DECLARATION_ENTRY
*entries
, unsigned int entry_count
,
1267 const unsigned int *buffer_strides
, unsigned int buffer_stride_count
,
1268 const struct wined3d_shader_signature
*os
, D3D_FEATURE_LEVEL feature_level
)
1270 unsigned int i
, j
, mask
;
1272 for (i
= 0; i
< entry_count
; ++i
)
1274 struct wined3d_stream_output_element
*e
= &elements
[i
];
1275 const D3D11_SO_DECLARATION_ENTRY
*f
= &entries
[i
];
1276 struct wined3d_shader_signature_element
*output
;
1278 TRACE("Stream: %u, semantic: %s, semantic idx: %u, start component: %u, "
1279 "component count %u, output slot %u.\n",
1280 f
->Stream
, debugstr_a(f
->SemanticName
), f
->SemanticIndex
,
1281 f
->StartComponent
, f
->ComponentCount
, f
->OutputSlot
);
1283 if (f
->Stream
>= D3D11_SO_STREAM_COUNT
)
1285 WARN("Invalid stream %u.\n", f
->Stream
);
1286 return E_INVALIDARG
;
1288 if (f
->Stream
&& feature_level
< D3D_FEATURE_LEVEL_11_0
)
1290 WARN("Invalid stream %u for feature level %#x.\n", f
->Stream
, feature_level
);
1291 return E_INVALIDARG
;
1295 FIXME("Streams not implemented yet.\n");
1296 return E_INVALIDARG
;
1298 if (f
->OutputSlot
>= D3D11_SO_BUFFER_SLOT_COUNT
)
1300 WARN("Invalid output slot %u.\n", f
->OutputSlot
);
1301 return E_INVALIDARG
;
1304 e
->stream_idx
= f
->Stream
;
1305 e
->component_idx
= f
->StartComponent
;
1306 e
->component_count
= f
->ComponentCount
;
1307 e
->output_slot
= f
->OutputSlot
;
1309 if (!f
->SemanticName
)
1311 if (f
->SemanticIndex
)
1313 WARN("Invalid semantic idx %u for stream output gap.\n", f
->SemanticIndex
);
1314 return E_INVALIDARG
;
1316 if (e
->component_idx
|| !e
->component_count
)
1318 WARN("Invalid stream output gap %u-%u.\n", e
->component_idx
, e
->component_count
);
1319 return E_INVALIDARG
;
1322 e
->register_idx
= WINED3D_STREAM_OUTPUT_GAP
;
1324 else if ((output
= shader_find_signature_element(os
, f
->SemanticName
, f
->SemanticIndex
, f
->Stream
)))
1326 if (e
->component_idx
> 3 || e
->component_count
> 4 || !e
->component_count
1327 || e
->component_idx
+ e
->component_count
> 4)
1329 WARN("Invalid component range %u-%u.\n", e
->component_idx
, e
->component_count
);
1330 return E_INVALIDARG
;
1333 for (j
= 0; j
< 4; ++j
)
1335 if ((1u << j
) & output
->mask
)
1338 e
->component_idx
+= j
;
1339 mask
= ((1u << e
->component_count
) - 1) << e
->component_idx
;
1340 if ((output
->mask
& 0xff & mask
) != mask
)
1342 WARN("Invalid component range %u-%u (mask %#x), output mask %#x.\n",
1343 e
->component_idx
, e
->component_count
, mask
, output
->mask
& 0xff);
1344 return E_INVALIDARG
;
1347 e
->register_idx
= output
->register_idx
;
1348 TRACE("Register idx: %u, register component idx %u, register mask %#x.\n",
1349 e
->register_idx
, e
->component_idx
, mask
);
1353 WARN("Failed to find output signature element for stream output entry.\n");
1354 return E_INVALIDARG
;
1358 for (i
= 0; i
< entry_count
; ++i
)
1360 const struct wined3d_stream_output_element
*e1
= &elements
[i
];
1361 if (e1
->register_idx
== WINED3D_STREAM_OUTPUT_GAP
)
1364 for (j
= i
+ 1; j
< entry_count
; ++j
)
1366 const struct wined3d_stream_output_element
*e2
= &elements
[j
];
1368 if (e1
->register_idx
== e2
->register_idx
1369 && e1
->component_idx
< e2
->component_idx
+ e2
->component_count
1370 && e1
->component_idx
+ e1
->component_count
> e2
->component_idx
)
1372 WARN("Stream output elements %u and %u overlap.\n", i
, j
);
1373 return E_INVALIDARG
;
1378 for (i
= 0; i
< D3D11_SO_STREAM_COUNT
; ++i
)
1380 unsigned int current_stride
[D3D11_SO_BUFFER_SLOT_COUNT
] = {0};
1381 unsigned int element_count
[D3D11_SO_BUFFER_SLOT_COUNT
] = {0};
1382 unsigned int gap_count
[D3D11_SO_BUFFER_SLOT_COUNT
] = {0};
1384 for (j
= 0; j
< entry_count
; ++j
)
1386 const struct wined3d_stream_output_element
*e
= &elements
[j
];
1388 if (e
->stream_idx
!= i
)
1390 current_stride
[e
->output_slot
] += 4 * e
->component_count
;
1391 ++element_count
[e
->output_slot
];
1392 if (e
->register_idx
== WINED3D_STREAM_OUTPUT_GAP
)
1393 ++gap_count
[e
->output_slot
];
1396 for (j
= 0; j
< D3D11_SO_BUFFER_SLOT_COUNT
; ++j
)
1398 if (!element_count
[j
])
1400 if (element_count
[j
] == gap_count
[j
])
1402 WARN("Stream %u, output slot %u contains only gaps.\n", i
, j
);
1403 return E_INVALIDARG
;
1405 if (buffer_stride_count
)
1407 if (buffer_stride_count
<= j
)
1409 WARN("Buffer strides are required for all buffer slots.\n");
1410 return E_INVALIDARG
;
1412 if (buffer_strides
[j
] < current_stride
[j
] || buffer_strides
[j
] % 4)
1414 WARN("Invalid stride %u for buffer slot %u.\n", buffer_strides
[j
], j
);
1415 return E_INVALIDARG
;
1420 if (!i
&& feature_level
< D3D_FEATURE_LEVEL_11_0
&& element_count
[0] != entry_count
)
1422 for (j
= 0; j
< ARRAY_SIZE(element_count
); ++j
)
1424 if (element_count
[j
] > 1)
1426 WARN("Only one element per output slot is allowed.\n");
1427 return E_INVALIDARG
;
1436 static HRESULT
d3d_geometry_shader_init(struct d3d_geometry_shader
*shader
,
1437 struct d3d_device
*device
, const void *byte_code
, SIZE_T byte_code_length
,
1438 const D3D11_SO_DECLARATION_ENTRY
*so_entries
, unsigned int so_entry_count
,
1439 const unsigned int *buffer_strides
, unsigned int buffer_stride_count
,
1440 unsigned int rasterizer_stream
)
1442 struct wined3d_stream_output_desc so_desc
;
1443 struct wined3d_shader_desc desc
;
1447 if (so_entry_count
> D3D11_SO_STREAM_COUNT
* D3D11_SO_OUTPUT_COMPONENT_COUNT
)
1449 WARN("Entry count %u is greater than %u.\n",
1450 so_entry_count
, D3D11_SO_STREAM_COUNT
* D3D11_SO_OUTPUT_COMPONENT_COUNT
);
1451 return E_INVALIDARG
;
1453 if (so_entries
&& !so_entry_count
)
1455 WARN("Invalid SO entry count %u.\n", so_entry_count
);
1456 return E_INVALIDARG
;
1458 if (rasterizer_stream
!= D3D11_SO_NO_RASTERIZED_STREAM
&& rasterizer_stream
>= D3D11_SO_STREAM_COUNT
)
1460 WARN("Invalid rasterizer stream %u.\n", rasterizer_stream
);
1461 return E_INVALIDARG
;
1463 if (device
->feature_level
< D3D_FEATURE_LEVEL_11_0
)
1465 if (rasterizer_stream
)
1467 WARN("Invalid rasterizer stream %u for feature level %#x.\n",
1468 rasterizer_stream
, device
->feature_level
);
1469 return E_INVALIDARG
;
1471 if (buffer_stride_count
&& buffer_stride_count
!= 1)
1473 WARN("Invalid buffer stride count %u for feature level %#x.\n",
1474 buffer_stride_count
, device
->feature_level
);
1475 return E_INVALIDARG
;
1479 if (FAILED(hr
= shader_extract_from_dxbc(byte_code
, byte_code_length
, &desc
, device
->feature_level
)))
1481 WARN("Failed to extract shader, hr %#x.\n", hr
);
1484 desc
.max_version
= d3d_sm_from_feature_level(device
->feature_level
);
1486 memset(&so_desc
, 0, sizeof(so_desc
));
1489 so_desc
.element_count
= so_entry_count
;
1490 for (i
= 0; i
< min(buffer_stride_count
, ARRAY_SIZE(so_desc
.buffer_strides
)); ++i
)
1491 so_desc
.buffer_strides
[i
] = buffer_strides
[i
];
1492 so_desc
.buffer_stride_count
= buffer_stride_count
;
1493 so_desc
.rasterizer_stream_idx
= rasterizer_stream
;
1495 if (!(so_desc
.elements
= heap_calloc(so_entry_count
, sizeof(*so_desc
.elements
))))
1497 ERR("Failed to allocate wined3d stream output element array memory.\n");
1498 free_shader_desc(&desc
);
1499 return E_OUTOFMEMORY
;
1501 if (FAILED(hr
= wined3d_so_elements_from_d3d11_so_entries(so_desc
.elements
,
1502 so_entries
, so_entry_count
, buffer_strides
, buffer_stride_count
,
1503 &desc
.output_signature
, device
->feature_level
)))
1505 heap_free(so_desc
.elements
);
1506 free_shader_desc(&desc
);
1511 shader
->ID3D11GeometryShader_iface
.lpVtbl
= &d3d11_geometry_shader_vtbl
;
1512 shader
->ID3D10GeometryShader_iface
.lpVtbl
= &d3d10_geometry_shader_vtbl
;
1513 shader
->refcount
= 1;
1514 wined3d_mutex_lock();
1515 wined3d_private_store_init(&shader
->private_store
);
1517 hr
= wined3d_shader_create_gs(device
->wined3d_device
, &desc
, so_entries
? &so_desc
: NULL
,
1518 shader
, &d3d_geometry_shader_wined3d_parent_ops
, &shader
->wined3d_shader
);
1519 heap_free(so_desc
.elements
);
1520 free_shader_desc(&desc
);
1523 WARN("Failed to create wined3d geometry shader, hr %#x.\n", hr
);
1524 wined3d_private_store_cleanup(&shader
->private_store
);
1525 wined3d_mutex_unlock();
1526 return E_INVALIDARG
;
1528 wined3d_mutex_unlock();
1530 ID3D11Device2_AddRef(shader
->device
= &device
->ID3D11Device2_iface
);
1535 HRESULT
d3d_geometry_shader_create(struct d3d_device
*device
, const void *byte_code
, SIZE_T byte_code_length
,
1536 const D3D11_SO_DECLARATION_ENTRY
*so_entries
, unsigned int so_entry_count
,
1537 const unsigned int *buffer_strides
, unsigned int buffer_stride_count
, unsigned int rasterizer_stream
,
1538 struct d3d_geometry_shader
**shader
)
1540 struct d3d_geometry_shader
*object
;
1543 if (!(object
= heap_alloc_zero(sizeof(*object
))))
1544 return E_OUTOFMEMORY
;
1546 if (FAILED(hr
= d3d_geometry_shader_init(object
, device
, byte_code
, byte_code_length
,
1547 so_entries
, so_entry_count
, buffer_strides
, buffer_stride_count
, rasterizer_stream
)))
1549 WARN("Failed to initialize geometry shader, hr %#x.\n", hr
);
1554 TRACE("Created geometry shader %p.\n", object
);
1560 struct d3d_geometry_shader
*unsafe_impl_from_ID3D11GeometryShader(ID3D11GeometryShader
*iface
)
1564 assert(iface
->lpVtbl
== &d3d11_geometry_shader_vtbl
);
1566 return impl_from_ID3D11GeometryShader(iface
);
1569 struct d3d_geometry_shader
*unsafe_impl_from_ID3D10GeometryShader(ID3D10GeometryShader
*iface
)
1573 assert(iface
->lpVtbl
== &d3d10_geometry_shader_vtbl
);
1575 return impl_from_ID3D10GeometryShader(iface
);
1578 /* ID3D11PixelShader methods */
1580 static inline struct d3d_pixel_shader
*impl_from_ID3D11PixelShader(ID3D11PixelShader
*iface
)
1582 return CONTAINING_RECORD(iface
, struct d3d_pixel_shader
, ID3D11PixelShader_iface
);
1585 static HRESULT STDMETHODCALLTYPE
d3d11_pixel_shader_QueryInterface(ID3D11PixelShader
*iface
,
1586 REFIID riid
, void **object
)
1588 struct d3d_pixel_shader
*shader
= impl_from_ID3D11PixelShader(iface
);
1590 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
1592 if (IsEqualGUID(riid
, &IID_ID3D11PixelShader
)
1593 || IsEqualGUID(riid
, &IID_ID3D11DeviceChild
)
1594 || IsEqualGUID(riid
, &IID_IUnknown
))
1596 ID3D11PixelShader_AddRef(iface
);
1601 if (IsEqualGUID(riid
, &IID_ID3D10PixelShader
)
1602 || IsEqualGUID(riid
, &IID_ID3D10DeviceChild
))
1604 IUnknown_AddRef(&shader
->ID3D10PixelShader_iface
);
1605 *object
= &shader
->ID3D10PixelShader_iface
;
1609 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
1612 return E_NOINTERFACE
;
1615 static ULONG STDMETHODCALLTYPE
d3d11_pixel_shader_AddRef(ID3D11PixelShader
*iface
)
1617 struct d3d_pixel_shader
*shader
= impl_from_ID3D11PixelShader(iface
);
1618 ULONG refcount
= InterlockedIncrement(&shader
->refcount
);
1620 TRACE("%p increasing refcount to %u.\n", shader
, refcount
);
1624 ID3D11Device2_AddRef(shader
->device
);
1625 wined3d_mutex_lock();
1626 wined3d_shader_incref(shader
->wined3d_shader
);
1627 wined3d_mutex_unlock();
1633 static ULONG STDMETHODCALLTYPE
d3d11_pixel_shader_Release(ID3D11PixelShader
*iface
)
1635 struct d3d_pixel_shader
*shader
= impl_from_ID3D11PixelShader(iface
);
1636 ULONG refcount
= InterlockedDecrement(&shader
->refcount
);
1638 TRACE("%p decreasing refcount to %u.\n", shader
, refcount
);
1642 ID3D11Device2
*device
= shader
->device
;
1644 wined3d_mutex_lock();
1645 wined3d_shader_decref(shader
->wined3d_shader
);
1646 wined3d_mutex_unlock();
1647 /* Release the device last, it may cause the wined3d device to be
1649 ID3D11Device2_Release(device
);
1655 static void STDMETHODCALLTYPE
d3d11_pixel_shader_GetDevice(ID3D11PixelShader
*iface
,
1656 ID3D11Device
**device
)
1658 struct d3d_pixel_shader
*shader
= impl_from_ID3D11PixelShader(iface
);
1660 TRACE("iface %p, device %p.\n", iface
, device
);
1662 *device
= (ID3D11Device
*)shader
->device
;
1663 ID3D11Device_AddRef(*device
);
1666 static HRESULT STDMETHODCALLTYPE
d3d11_pixel_shader_GetPrivateData(ID3D11PixelShader
*iface
,
1667 REFGUID guid
, UINT
*data_size
, void *data
)
1669 struct d3d_pixel_shader
*shader
= impl_from_ID3D11PixelShader(iface
);
1671 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
1673 return d3d_get_private_data(&shader
->private_store
, guid
, data_size
, data
);
1676 static HRESULT STDMETHODCALLTYPE
d3d11_pixel_shader_SetPrivateData(ID3D11PixelShader
*iface
,
1677 REFGUID guid
, UINT data_size
, const void *data
)
1679 struct d3d_pixel_shader
*shader
= impl_from_ID3D11PixelShader(iface
);
1681 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
1683 return d3d_set_private_data(&shader
->private_store
, guid
, data_size
, data
);
1686 static HRESULT STDMETHODCALLTYPE
d3d11_pixel_shader_SetPrivateDataInterface(ID3D11PixelShader
*iface
,
1687 REFGUID guid
, const IUnknown
*data
)
1689 struct d3d_pixel_shader
*shader
= impl_from_ID3D11PixelShader(iface
);
1691 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
1693 return d3d_set_private_data_interface(&shader
->private_store
, guid
, data
);
1696 static const struct ID3D11PixelShaderVtbl d3d11_pixel_shader_vtbl
=
1698 /* IUnknown methods */
1699 d3d11_pixel_shader_QueryInterface
,
1700 d3d11_pixel_shader_AddRef
,
1701 d3d11_pixel_shader_Release
,
1702 /* ID3D11DeviceChild methods */
1703 d3d11_pixel_shader_GetDevice
,
1704 d3d11_pixel_shader_GetPrivateData
,
1705 d3d11_pixel_shader_SetPrivateData
,
1706 d3d11_pixel_shader_SetPrivateDataInterface
,
1709 /* ID3D10PixelShader methods */
1711 static inline struct d3d_pixel_shader
*impl_from_ID3D10PixelShader(ID3D10PixelShader
*iface
)
1713 return CONTAINING_RECORD(iface
, struct d3d_pixel_shader
, ID3D10PixelShader_iface
);
1716 /* IUnknown methods */
1718 static HRESULT STDMETHODCALLTYPE
d3d10_pixel_shader_QueryInterface(ID3D10PixelShader
*iface
,
1719 REFIID riid
, void **object
)
1721 struct d3d_pixel_shader
*shader
= impl_from_ID3D10PixelShader(iface
);
1723 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
1725 return d3d11_pixel_shader_QueryInterface(&shader
->ID3D11PixelShader_iface
, riid
, object
);
1728 static ULONG STDMETHODCALLTYPE
d3d10_pixel_shader_AddRef(ID3D10PixelShader
*iface
)
1730 struct d3d_pixel_shader
*shader
= impl_from_ID3D10PixelShader(iface
);
1732 TRACE("iface %p.\n", iface
);
1734 return d3d11_pixel_shader_AddRef(&shader
->ID3D11PixelShader_iface
);
1737 static ULONG STDMETHODCALLTYPE
d3d10_pixel_shader_Release(ID3D10PixelShader
*iface
)
1739 struct d3d_pixel_shader
*shader
= impl_from_ID3D10PixelShader(iface
);
1741 TRACE("iface %p.\n", iface
);
1743 return d3d11_pixel_shader_Release(&shader
->ID3D11PixelShader_iface
);
1746 /* ID3D10DeviceChild methods */
1748 static void STDMETHODCALLTYPE
d3d10_pixel_shader_GetDevice(ID3D10PixelShader
*iface
, ID3D10Device
**device
)
1750 struct d3d_pixel_shader
*shader
= impl_from_ID3D10PixelShader(iface
);
1752 TRACE("iface %p, device %p.\n", iface
, device
);
1754 ID3D11Device2_QueryInterface(shader
->device
, &IID_ID3D10Device
, (void **)device
);
1757 static HRESULT STDMETHODCALLTYPE
d3d10_pixel_shader_GetPrivateData(ID3D10PixelShader
*iface
,
1758 REFGUID guid
, UINT
*data_size
, void *data
)
1760 struct d3d_pixel_shader
*shader
= impl_from_ID3D10PixelShader(iface
);
1762 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
1763 iface
, debugstr_guid(guid
), data_size
, data
);
1765 return d3d_get_private_data(&shader
->private_store
, guid
, data_size
, data
);
1768 static HRESULT STDMETHODCALLTYPE
d3d10_pixel_shader_SetPrivateData(ID3D10PixelShader
*iface
,
1769 REFGUID guid
, UINT data_size
, const void *data
)
1771 struct d3d_pixel_shader
*shader
= impl_from_ID3D10PixelShader(iface
);
1773 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
1774 iface
, debugstr_guid(guid
), data_size
, data
);
1776 return d3d_set_private_data(&shader
->private_store
, guid
, data_size
, data
);
1779 static HRESULT STDMETHODCALLTYPE
d3d10_pixel_shader_SetPrivateDataInterface(ID3D10PixelShader
*iface
,
1780 REFGUID guid
, const IUnknown
*data
)
1782 struct d3d_pixel_shader
*shader
= impl_from_ID3D10PixelShader(iface
);
1784 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
1786 return d3d_set_private_data_interface(&shader
->private_store
, guid
, data
);
1789 static const struct ID3D10PixelShaderVtbl d3d10_pixel_shader_vtbl
=
1791 /* IUnknown methods */
1792 d3d10_pixel_shader_QueryInterface
,
1793 d3d10_pixel_shader_AddRef
,
1794 d3d10_pixel_shader_Release
,
1795 /* ID3D10DeviceChild methods */
1796 d3d10_pixel_shader_GetDevice
,
1797 d3d10_pixel_shader_GetPrivateData
,
1798 d3d10_pixel_shader_SetPrivateData
,
1799 d3d10_pixel_shader_SetPrivateDataInterface
,
1802 static void STDMETHODCALLTYPE
d3d_pixel_shader_wined3d_object_destroyed(void *parent
)
1804 struct d3d_pixel_shader
*shader
= parent
;
1806 wined3d_private_store_cleanup(&shader
->private_store
);
1810 static const struct wined3d_parent_ops d3d_pixel_shader_wined3d_parent_ops
=
1812 d3d_pixel_shader_wined3d_object_destroyed
,
1815 static HRESULT
d3d_pixel_shader_init(struct d3d_pixel_shader
*shader
, struct d3d_device
*device
,
1816 const void *byte_code
, SIZE_T byte_code_length
)
1818 struct wined3d_shader_desc desc
;
1821 shader
->ID3D11PixelShader_iface
.lpVtbl
= &d3d11_pixel_shader_vtbl
;
1822 shader
->ID3D10PixelShader_iface
.lpVtbl
= &d3d10_pixel_shader_vtbl
;
1823 shader
->refcount
= 1;
1824 wined3d_mutex_lock();
1825 wined3d_private_store_init(&shader
->private_store
);
1827 if (FAILED(hr
= shader_extract_from_dxbc(byte_code
, byte_code_length
, &desc
, device
->feature_level
)))
1829 WARN("Failed to extract shader, hr %#x.\n", hr
);
1830 wined3d_private_store_cleanup(&shader
->private_store
);
1831 wined3d_mutex_unlock();
1834 desc
.max_version
= d3d_sm_from_feature_level(device
->feature_level
);
1836 hr
= wined3d_shader_create_ps(device
->wined3d_device
, &desc
, shader
,
1837 &d3d_pixel_shader_wined3d_parent_ops
, &shader
->wined3d_shader
);
1838 free_shader_desc(&desc
);
1841 WARN("Failed to create wined3d pixel shader, hr %#x.\n", hr
);
1842 wined3d_private_store_cleanup(&shader
->private_store
);
1843 wined3d_mutex_unlock();
1844 return E_INVALIDARG
;
1846 wined3d_mutex_unlock();
1848 ID3D11Device2_AddRef(shader
->device
= &device
->ID3D11Device2_iface
);
1853 HRESULT
d3d_pixel_shader_create(struct d3d_device
*device
, const void *byte_code
, SIZE_T byte_code_length
,
1854 struct d3d_pixel_shader
**shader
)
1856 struct d3d_pixel_shader
*object
;
1859 if (!(object
= heap_alloc_zero(sizeof(*object
))))
1860 return E_OUTOFMEMORY
;
1862 if (FAILED(hr
= d3d_pixel_shader_init(object
, device
, byte_code
, byte_code_length
)))
1864 WARN("Failed to initialize pixel shader, hr %#x.\n", hr
);
1869 TRACE("Created pixel shader %p.\n", object
);
1875 struct d3d_pixel_shader
*unsafe_impl_from_ID3D11PixelShader(ID3D11PixelShader
*iface
)
1879 assert(iface
->lpVtbl
== &d3d11_pixel_shader_vtbl
);
1881 return impl_from_ID3D11PixelShader(iface
);
1884 struct d3d_pixel_shader
*unsafe_impl_from_ID3D10PixelShader(ID3D10PixelShader
*iface
)
1888 assert(iface
->lpVtbl
== &d3d10_pixel_shader_vtbl
);
1890 return impl_from_ID3D10PixelShader(iface
);
1893 /* ID3D11ComputeShader methods */
1895 static inline struct d3d11_compute_shader
*impl_from_ID3D11ComputeShader(ID3D11ComputeShader
*iface
)
1897 return CONTAINING_RECORD(iface
, struct d3d11_compute_shader
, ID3D11ComputeShader_iface
);
1900 static HRESULT STDMETHODCALLTYPE
d3d11_compute_shader_QueryInterface(ID3D11ComputeShader
*iface
,
1901 REFIID riid
, void **object
)
1903 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
1905 if (IsEqualGUID(riid
, &IID_ID3D11ComputeShader
)
1906 || IsEqualGUID(riid
, &IID_ID3D11DeviceChild
)
1907 || IsEqualGUID(riid
, &IID_IUnknown
))
1909 ID3D11ComputeShader_AddRef(*object
= iface
);
1913 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
1916 return E_NOINTERFACE
;
1919 static ULONG STDMETHODCALLTYPE
d3d11_compute_shader_AddRef(ID3D11ComputeShader
*iface
)
1921 struct d3d11_compute_shader
*shader
= impl_from_ID3D11ComputeShader(iface
);
1922 ULONG refcount
= InterlockedIncrement(&shader
->refcount
);
1924 TRACE("%p increasing refcount to %u.\n", shader
, refcount
);
1928 ID3D11Device2_AddRef(shader
->device
);
1929 wined3d_mutex_lock();
1930 wined3d_shader_incref(shader
->wined3d_shader
);
1931 wined3d_mutex_unlock();
1937 static ULONG STDMETHODCALLTYPE
d3d11_compute_shader_Release(ID3D11ComputeShader
*iface
)
1939 struct d3d11_compute_shader
*shader
= impl_from_ID3D11ComputeShader(iface
);
1940 ULONG refcount
= InterlockedDecrement(&shader
->refcount
);
1942 TRACE("%p decreasing refcount to %u.\n", shader
, refcount
);
1946 ID3D11Device2
*device
= shader
->device
;
1948 wined3d_mutex_lock();
1949 wined3d_shader_decref(shader
->wined3d_shader
);
1950 wined3d_mutex_unlock();
1952 /* Release the device last, it may cause the wined3d device to be
1954 ID3D11Device2_Release(device
);
1960 static void STDMETHODCALLTYPE
d3d11_compute_shader_GetDevice(ID3D11ComputeShader
*iface
,
1961 ID3D11Device
**device
)
1963 struct d3d11_compute_shader
*shader
= impl_from_ID3D11ComputeShader(iface
);
1965 TRACE("iface %p, device %p.\n", iface
, device
);
1967 ID3D11Device_AddRef(*device
= (ID3D11Device
*)shader
->device
);
1970 static HRESULT STDMETHODCALLTYPE
d3d11_compute_shader_GetPrivateData(ID3D11ComputeShader
*iface
,
1971 REFGUID guid
, UINT
*data_size
, void *data
)
1973 struct d3d11_compute_shader
*shader
= impl_from_ID3D11ComputeShader(iface
);
1975 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
1977 return d3d_get_private_data(&shader
->private_store
, guid
, data_size
, data
);
1980 static HRESULT STDMETHODCALLTYPE
d3d11_compute_shader_SetPrivateData(ID3D11ComputeShader
*iface
,
1981 REFGUID guid
, UINT data_size
, const void *data
)
1983 struct d3d11_compute_shader
*shader
= impl_from_ID3D11ComputeShader(iface
);
1985 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
1987 return d3d_set_private_data(&shader
->private_store
, guid
, data_size
, data
);
1990 static HRESULT STDMETHODCALLTYPE
d3d11_compute_shader_SetPrivateDataInterface(ID3D11ComputeShader
*iface
,
1991 REFGUID guid
, const IUnknown
*data
)
1993 struct d3d11_compute_shader
*shader
= impl_from_ID3D11ComputeShader(iface
);
1995 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
1997 return d3d_set_private_data_interface(&shader
->private_store
, guid
, data
);
2000 static const struct ID3D11ComputeShaderVtbl d3d11_compute_shader_vtbl
=
2002 /* IUnknown methods */
2003 d3d11_compute_shader_QueryInterface
,
2004 d3d11_compute_shader_AddRef
,
2005 d3d11_compute_shader_Release
,
2006 /* ID3D11DeviceChild methods */
2007 d3d11_compute_shader_GetDevice
,
2008 d3d11_compute_shader_GetPrivateData
,
2009 d3d11_compute_shader_SetPrivateData
,
2010 d3d11_compute_shader_SetPrivateDataInterface
,
2013 static void STDMETHODCALLTYPE
d3d11_compute_shader_wined3d_object_destroyed(void *parent
)
2015 struct d3d11_compute_shader
*shader
= parent
;
2017 wined3d_private_store_cleanup(&shader
->private_store
);
2021 static const struct wined3d_parent_ops d3d11_compute_shader_wined3d_parent_ops
=
2023 d3d11_compute_shader_wined3d_object_destroyed
,
2026 static HRESULT
d3d11_compute_shader_init(struct d3d11_compute_shader
*shader
, struct d3d_device
*device
,
2027 const void *byte_code
, SIZE_T byte_code_length
)
2029 struct wined3d_shader_desc desc
;
2032 shader
->ID3D11ComputeShader_iface
.lpVtbl
= &d3d11_compute_shader_vtbl
;
2033 shader
->refcount
= 1;
2034 wined3d_mutex_lock();
2035 wined3d_private_store_init(&shader
->private_store
);
2037 if (FAILED(hr
= shader_extract_from_dxbc(byte_code
, byte_code_length
, &desc
, device
->feature_level
)))
2039 WARN("Failed to extract shader, hr %#x.\n", hr
);
2040 wined3d_private_store_cleanup(&shader
->private_store
);
2041 wined3d_mutex_unlock();
2044 desc
.max_version
= d3d_sm_from_feature_level(device
->feature_level
);
2046 hr
= wined3d_shader_create_cs(device
->wined3d_device
, &desc
, shader
,
2047 &d3d11_compute_shader_wined3d_parent_ops
, &shader
->wined3d_shader
);
2048 free_shader_desc(&desc
);
2051 WARN("Failed to create wined3d compute shader, hr %#x.\n", hr
);
2052 wined3d_private_store_cleanup(&shader
->private_store
);
2053 wined3d_mutex_unlock();
2054 return E_INVALIDARG
;
2056 wined3d_mutex_unlock();
2058 ID3D11Device2_AddRef(shader
->device
= &device
->ID3D11Device2_iface
);
2063 HRESULT
d3d11_compute_shader_create(struct d3d_device
*device
, const void *byte_code
, SIZE_T byte_code_length
,
2064 struct d3d11_compute_shader
**shader
)
2066 struct d3d11_compute_shader
*object
;
2069 if (!(object
= heap_alloc_zero(sizeof(*object
))))
2070 return E_OUTOFMEMORY
;
2072 if (FAILED(hr
= d3d11_compute_shader_init(object
, device
, byte_code
, byte_code_length
)))
2078 TRACE("Created compute shader %p.\n", object
);
2084 struct d3d11_compute_shader
*unsafe_impl_from_ID3D11ComputeShader(ID3D11ComputeShader
*iface
)
2088 assert(iface
->lpVtbl
== &d3d11_compute_shader_vtbl
);
2090 return impl_from_ID3D11ComputeShader(iface
);
2093 /* ID3D11ClassLinkage methods */
2095 static inline struct d3d11_class_linkage
*impl_from_ID3D11ClassLinkage(ID3D11ClassLinkage
*iface
)
2097 return CONTAINING_RECORD(iface
, struct d3d11_class_linkage
, ID3D11ClassLinkage_iface
);
2100 static HRESULT STDMETHODCALLTYPE
d3d11_class_linkage_QueryInterface(ID3D11ClassLinkage
*iface
,
2101 REFIID riid
, void **object
)
2103 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
2105 if (IsEqualGUID(riid
, &IID_ID3D11ClassLinkage
)
2106 || IsEqualGUID(riid
, &IID_ID3D11DeviceChild
)
2107 || IsEqualGUID(riid
, &IID_IUnknown
))
2109 ID3D11ClassLinkage_AddRef(*object
= iface
);
2113 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
2116 return E_NOINTERFACE
;
2119 static ULONG STDMETHODCALLTYPE
d3d11_class_linkage_AddRef(ID3D11ClassLinkage
*iface
)
2121 struct d3d11_class_linkage
*class_linkage
= impl_from_ID3D11ClassLinkage(iface
);
2122 ULONG refcount
= InterlockedIncrement(&class_linkage
->refcount
);
2124 TRACE("%p increasing refcount to %u.\n", class_linkage
, refcount
);
2129 static ULONG STDMETHODCALLTYPE
d3d11_class_linkage_Release(ID3D11ClassLinkage
*iface
)
2131 struct d3d11_class_linkage
*class_linkage
= impl_from_ID3D11ClassLinkage(iface
);
2132 ULONG refcount
= InterlockedDecrement(&class_linkage
->refcount
);
2134 TRACE("%p decreasing refcount to %u.\n", class_linkage
, refcount
);
2138 ID3D11Device2
*device
= class_linkage
->device
;
2140 wined3d_private_store_cleanup(&class_linkage
->private_store
);
2141 heap_free(class_linkage
);
2143 ID3D11Device2_Release(device
);
2149 static void STDMETHODCALLTYPE
d3d11_class_linkage_GetDevice(ID3D11ClassLinkage
*iface
,
2150 ID3D11Device
**device
)
2152 struct d3d11_class_linkage
*class_linkage
= impl_from_ID3D11ClassLinkage(iface
);
2154 TRACE("iface %p, device %p.\n", iface
, device
);
2156 ID3D11Device_AddRef(*device
= (ID3D11Device
*)class_linkage
->device
);
2159 static HRESULT STDMETHODCALLTYPE
d3d11_class_linkage_GetPrivateData(ID3D11ClassLinkage
*iface
,
2160 REFGUID guid
, UINT
*data_size
, void *data
)
2162 struct d3d11_class_linkage
*class_linkage
= impl_from_ID3D11ClassLinkage(iface
);
2164 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
2166 return d3d_get_private_data(&class_linkage
->private_store
, guid
, data_size
, data
);
2169 static HRESULT STDMETHODCALLTYPE
d3d11_class_linkage_SetPrivateData(ID3D11ClassLinkage
*iface
,
2170 REFGUID guid
, UINT data_size
, const void *data
)
2172 struct d3d11_class_linkage
*class_linkage
= impl_from_ID3D11ClassLinkage(iface
);
2174 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
2176 return d3d_set_private_data(&class_linkage
->private_store
, guid
, data_size
, data
);
2179 static HRESULT STDMETHODCALLTYPE
d3d11_class_linkage_SetPrivateDataInterface(ID3D11ClassLinkage
*iface
,
2180 REFGUID guid
, const IUnknown
*data
)
2182 struct d3d11_class_linkage
*class_linkage
= impl_from_ID3D11ClassLinkage(iface
);
2184 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
2186 return d3d_set_private_data_interface(&class_linkage
->private_store
, guid
, data
);
2189 static HRESULT STDMETHODCALLTYPE
d3d11_class_linkage_GetClassInstance(ID3D11ClassLinkage
*iface
,
2190 const char *instance_name
, UINT instance_index
, ID3D11ClassInstance
**class_instance
)
2192 FIXME("iface %p, instance_name %s, instance_index %u, class_instance %p stub!\n",
2193 iface
, debugstr_a(instance_name
), instance_index
, class_instance
);
2198 static HRESULT STDMETHODCALLTYPE
d3d11_class_linkage_CreateClassInstance(ID3D11ClassLinkage
*iface
,
2199 const char *type_name
, UINT cb_offset
, UINT cb_vector_offset
, UINT texture_offset
,
2200 UINT sampler_offset
, ID3D11ClassInstance
**class_instance
)
2202 FIXME("iface %p, type_name %s, cb_offset %u, cb_vector_offset %u, texture_offset %u, "
2203 "sampler_offset %u, class_instance %p stub!\n",
2204 iface
, debugstr_a(type_name
), cb_offset
, cb_vector_offset
, texture_offset
,
2205 sampler_offset
, class_instance
);
2210 static const struct ID3D11ClassLinkageVtbl d3d11_class_linkage_vtbl
=
2212 /* IUnknown methods */
2213 d3d11_class_linkage_QueryInterface
,
2214 d3d11_class_linkage_AddRef
,
2215 d3d11_class_linkage_Release
,
2216 /* ID3D11DeviceChild methods */
2217 d3d11_class_linkage_GetDevice
,
2218 d3d11_class_linkage_GetPrivateData
,
2219 d3d11_class_linkage_SetPrivateData
,
2220 d3d11_class_linkage_SetPrivateDataInterface
,
2221 /* ID3D11ClassLinkage methods */
2222 d3d11_class_linkage_GetClassInstance
,
2223 d3d11_class_linkage_CreateClassInstance
,
2226 HRESULT
d3d11_class_linkage_create(struct d3d_device
*device
, struct d3d11_class_linkage
**class_linkage
)
2228 struct d3d11_class_linkage
*object
;
2230 if (!(object
= heap_alloc_zero(sizeof(*object
))))
2231 return E_OUTOFMEMORY
;
2233 object
->ID3D11ClassLinkage_iface
.lpVtbl
= &d3d11_class_linkage_vtbl
;
2234 object
->refcount
= 1;
2235 wined3d_private_store_init(&object
->private_store
);
2237 ID3D11Device2_AddRef(object
->device
= &device
->ID3D11Device2_iface
);
2239 TRACE("Created class linkage %p.\n", object
);
2240 *class_linkage
= object
;