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 ID3D11Device1_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 ID3D11Device1
*device
= shader
->device
;
353 wined3d_mutex_lock();
354 wined3d_shader_decref(shader
->wined3d_shader
);
355 wined3d_mutex_unlock();
356 /* Release the device last, it may cause the wined3d device to be
358 ID3D11Device1_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 ID3D11Device1_QueryInterface(shader
->device
, &IID_ID3D10Device
, (void **)device
);
466 static HRESULT STDMETHODCALLTYPE
d3d10_vertex_shader_GetPrivateData(ID3D10VertexShader
*iface
,
467 REFGUID guid
, UINT
*data_size
, void *data
)
469 struct d3d_vertex_shader
*shader
= impl_from_ID3D10VertexShader(iface
);
471 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
472 iface
, debugstr_guid(guid
), data_size
, data
);
474 return d3d_get_private_data(&shader
->private_store
, guid
, data_size
, data
);
477 static HRESULT STDMETHODCALLTYPE
d3d10_vertex_shader_SetPrivateData(ID3D10VertexShader
*iface
,
478 REFGUID guid
, UINT data_size
, const void *data
)
480 struct d3d_vertex_shader
*shader
= impl_from_ID3D10VertexShader(iface
);
482 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
483 iface
, debugstr_guid(guid
), data_size
, data
);
485 return d3d_set_private_data(&shader
->private_store
, guid
, data_size
, data
);
488 static HRESULT STDMETHODCALLTYPE
d3d10_vertex_shader_SetPrivateDataInterface(ID3D10VertexShader
*iface
,
489 REFGUID guid
, const IUnknown
*data
)
491 struct d3d_vertex_shader
*shader
= impl_from_ID3D10VertexShader(iface
);
493 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
495 return d3d_set_private_data_interface(&shader
->private_store
, guid
, data
);
498 static const struct ID3D10VertexShaderVtbl d3d10_vertex_shader_vtbl
=
500 /* IUnknown methods */
501 d3d10_vertex_shader_QueryInterface
,
502 d3d10_vertex_shader_AddRef
,
503 d3d10_vertex_shader_Release
,
504 /* ID3D10DeviceChild methods */
505 d3d10_vertex_shader_GetDevice
,
506 d3d10_vertex_shader_GetPrivateData
,
507 d3d10_vertex_shader_SetPrivateData
,
508 d3d10_vertex_shader_SetPrivateDataInterface
,
511 static void STDMETHODCALLTYPE
d3d_vertex_shader_wined3d_object_destroyed(void *parent
)
513 struct d3d_vertex_shader
*shader
= parent
;
515 wined3d_private_store_cleanup(&shader
->private_store
);
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 shader
->device
= &device
->ID3D11Device1_iface
;
579 ID3D11Device1_AddRef(shader
->device
);
584 HRESULT
d3d_vertex_shader_create(struct d3d_device
*device
, const void *byte_code
, SIZE_T byte_code_length
,
585 struct d3d_vertex_shader
**shader
)
587 struct d3d_vertex_shader
*object
;
590 if (!(object
= heap_alloc_zero(sizeof(*object
))))
591 return E_OUTOFMEMORY
;
593 if (FAILED(hr
= d3d_vertex_shader_init(object
, device
, byte_code
, byte_code_length
)))
595 WARN("Failed to initialize vertex shader, hr %#x.\n", hr
);
600 TRACE("Created vertex shader %p.\n", object
);
606 struct d3d_vertex_shader
*unsafe_impl_from_ID3D11VertexShader(ID3D11VertexShader
*iface
)
610 assert(iface
->lpVtbl
== &d3d11_vertex_shader_vtbl
);
612 return impl_from_ID3D11VertexShader(iface
);
615 struct d3d_vertex_shader
*unsafe_impl_from_ID3D10VertexShader(ID3D10VertexShader
*iface
)
619 assert(iface
->lpVtbl
== &d3d10_vertex_shader_vtbl
);
621 return impl_from_ID3D10VertexShader(iface
);
624 /* ID3D11HullShader methods */
626 static inline struct d3d11_hull_shader
*impl_from_ID3D11HullShader(ID3D11HullShader
*iface
)
628 return CONTAINING_RECORD(iface
, struct d3d11_hull_shader
, ID3D11HullShader_iface
);
631 static HRESULT STDMETHODCALLTYPE
d3d11_hull_shader_QueryInterface(ID3D11HullShader
*iface
,
632 REFIID riid
, void **object
)
634 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
636 if (IsEqualGUID(riid
, &IID_ID3D11HullShader
)
637 || IsEqualGUID(riid
, &IID_ID3D11DeviceChild
)
638 || IsEqualGUID(riid
, &IID_IUnknown
))
640 ID3D11HullShader_AddRef(iface
);
645 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
648 return E_NOINTERFACE
;
651 static ULONG STDMETHODCALLTYPE
d3d11_hull_shader_AddRef(ID3D11HullShader
*iface
)
653 struct d3d11_hull_shader
*shader
= impl_from_ID3D11HullShader(iface
);
654 ULONG refcount
= InterlockedIncrement(&shader
->refcount
);
656 TRACE("%p increasing refcount to %u.\n", shader
, refcount
);
660 ID3D11Device1_AddRef(shader
->device
);
661 wined3d_mutex_lock();
662 wined3d_shader_incref(shader
->wined3d_shader
);
663 wined3d_mutex_unlock();
669 static ULONG STDMETHODCALLTYPE
d3d11_hull_shader_Release(ID3D11HullShader
*iface
)
671 struct d3d11_hull_shader
*shader
= impl_from_ID3D11HullShader(iface
);
672 ULONG refcount
= InterlockedDecrement(&shader
->refcount
);
674 TRACE("%p decreasing refcount to %u.\n", shader
, refcount
);
678 ID3D11Device1
*device
= shader
->device
;
680 wined3d_mutex_lock();
681 wined3d_shader_decref(shader
->wined3d_shader
);
682 wined3d_mutex_unlock();
684 /* Release the device last, it may cause the wined3d device to be
686 ID3D11Device1_Release(device
);
692 static void STDMETHODCALLTYPE
d3d11_hull_shader_GetDevice(ID3D11HullShader
*iface
,
693 ID3D11Device
**device
)
695 struct d3d11_hull_shader
*shader
= impl_from_ID3D11HullShader(iface
);
697 TRACE("iface %p, device %p.\n", iface
, device
);
699 *device
= (ID3D11Device
*)shader
->device
;
700 ID3D11Device_AddRef(*device
);
703 static HRESULT STDMETHODCALLTYPE
d3d11_hull_shader_GetPrivateData(ID3D11HullShader
*iface
,
704 REFGUID guid
, UINT
*data_size
, void *data
)
706 struct d3d11_hull_shader
*shader
= impl_from_ID3D11HullShader(iface
);
708 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
710 return d3d_get_private_data(&shader
->private_store
, guid
, data_size
, data
);
713 static HRESULT STDMETHODCALLTYPE
d3d11_hull_shader_SetPrivateData(ID3D11HullShader
*iface
,
714 REFGUID guid
, UINT data_size
, const void *data
)
716 struct d3d11_hull_shader
*shader
= impl_from_ID3D11HullShader(iface
);
718 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
720 return d3d_set_private_data(&shader
->private_store
, guid
, data_size
, data
);
723 static HRESULT STDMETHODCALLTYPE
d3d11_hull_shader_SetPrivateDataInterface(ID3D11HullShader
*iface
,
724 REFGUID guid
, const IUnknown
*data
)
726 struct d3d11_hull_shader
*shader
= impl_from_ID3D11HullShader(iface
);
728 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
730 return d3d_set_private_data_interface(&shader
->private_store
, guid
, data
);
733 static const struct ID3D11HullShaderVtbl d3d11_hull_shader_vtbl
=
735 /* IUnknown methods */
736 d3d11_hull_shader_QueryInterface
,
737 d3d11_hull_shader_AddRef
,
738 d3d11_hull_shader_Release
,
739 /* ID3D11DeviceChild methods */
740 d3d11_hull_shader_GetDevice
,
741 d3d11_hull_shader_GetPrivateData
,
742 d3d11_hull_shader_SetPrivateData
,
743 d3d11_hull_shader_SetPrivateDataInterface
,
746 static void STDMETHODCALLTYPE
d3d11_hull_shader_wined3d_object_destroyed(void *parent
)
748 struct d3d11_hull_shader
*shader
= parent
;
750 wined3d_private_store_cleanup(&shader
->private_store
);
754 static const struct wined3d_parent_ops d3d11_hull_shader_wined3d_parent_ops
=
756 d3d11_hull_shader_wined3d_object_destroyed
,
759 static HRESULT
d3d11_hull_shader_init(struct d3d11_hull_shader
*shader
, struct d3d_device
*device
,
760 const void *byte_code
, SIZE_T byte_code_length
)
762 struct wined3d_shader_desc desc
;
765 shader
->ID3D11HullShader_iface
.lpVtbl
= &d3d11_hull_shader_vtbl
;
766 shader
->refcount
= 1;
767 wined3d_mutex_lock();
768 wined3d_private_store_init(&shader
->private_store
);
770 if (FAILED(hr
= shader_extract_from_dxbc(byte_code
, byte_code_length
, &desc
, device
->feature_level
)))
772 WARN("Failed to extract shader, hr %#x.\n", hr
);
773 wined3d_private_store_cleanup(&shader
->private_store
);
774 wined3d_mutex_unlock();
777 desc
.max_version
= d3d_sm_from_feature_level(device
->feature_level
);
779 hr
= wined3d_shader_create_hs(device
->wined3d_device
, &desc
, shader
,
780 &d3d11_hull_shader_wined3d_parent_ops
, &shader
->wined3d_shader
);
781 free_shader_desc(&desc
);
784 WARN("Failed to create wined3d hull shader, hr %#x.\n", hr
);
785 wined3d_private_store_cleanup(&shader
->private_store
);
786 wined3d_mutex_unlock();
789 wined3d_mutex_unlock();
791 shader
->device
= &device
->ID3D11Device1_iface
;
792 ID3D11Device1_AddRef(shader
->device
);
797 HRESULT
d3d11_hull_shader_create(struct d3d_device
*device
, const void *byte_code
, SIZE_T byte_code_length
,
798 struct d3d11_hull_shader
**shader
)
800 struct d3d11_hull_shader
*object
;
803 if (!(object
= heap_alloc_zero(sizeof(*object
))))
804 return E_OUTOFMEMORY
;
806 if (FAILED(hr
= d3d11_hull_shader_init(object
, device
, byte_code
, byte_code_length
)))
812 TRACE("Created hull shader %p.\n", object
);
818 struct d3d11_hull_shader
*unsafe_impl_from_ID3D11HullShader(ID3D11HullShader
*iface
)
822 assert(iface
->lpVtbl
== &d3d11_hull_shader_vtbl
);
824 return impl_from_ID3D11HullShader(iface
);
827 /* ID3D11DomainShader methods */
829 static inline struct d3d11_domain_shader
*impl_from_ID3D11DomainShader(ID3D11DomainShader
*iface
)
831 return CONTAINING_RECORD(iface
, struct d3d11_domain_shader
, ID3D11DomainShader_iface
);
834 static HRESULT STDMETHODCALLTYPE
d3d11_domain_shader_QueryInterface(ID3D11DomainShader
*iface
,
835 REFIID riid
, void **object
)
837 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
839 if (IsEqualGUID(riid
, &IID_ID3D11DomainShader
)
840 || IsEqualGUID(riid
, &IID_ID3D11DeviceChild
)
841 || IsEqualGUID(riid
, &IID_IUnknown
))
843 ID3D11DomainShader_AddRef(iface
);
848 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
851 return E_NOINTERFACE
;
854 static ULONG STDMETHODCALLTYPE
d3d11_domain_shader_AddRef(ID3D11DomainShader
*iface
)
856 struct d3d11_domain_shader
*shader
= impl_from_ID3D11DomainShader(iface
);
857 ULONG refcount
= InterlockedIncrement(&shader
->refcount
);
859 TRACE("%p increasing refcount to %u.\n", shader
, refcount
);
863 ID3D11Device1_AddRef(shader
->device
);
864 wined3d_mutex_lock();
865 wined3d_shader_incref(shader
->wined3d_shader
);
866 wined3d_mutex_unlock();
872 static ULONG STDMETHODCALLTYPE
d3d11_domain_shader_Release(ID3D11DomainShader
*iface
)
874 struct d3d11_domain_shader
*shader
= impl_from_ID3D11DomainShader(iface
);
875 ULONG refcount
= InterlockedDecrement(&shader
->refcount
);
877 TRACE("%p decreasing refcount to %u.\n", shader
, refcount
);
881 ID3D11Device1
*device
= shader
->device
;
883 wined3d_mutex_lock();
884 wined3d_shader_decref(shader
->wined3d_shader
);
885 wined3d_mutex_unlock();
887 /* Release the device last, it may cause the wined3d device to be
889 ID3D11Device1_Release(device
);
895 static void STDMETHODCALLTYPE
d3d11_domain_shader_GetDevice(ID3D11DomainShader
*iface
,
896 ID3D11Device
**device
)
898 struct d3d11_domain_shader
*shader
= impl_from_ID3D11DomainShader(iface
);
900 TRACE("iface %p, device %p.\n", iface
, device
);
902 *device
= (ID3D11Device
*)shader
->device
;
903 ID3D11Device_AddRef(*device
);
906 static HRESULT STDMETHODCALLTYPE
d3d11_domain_shader_GetPrivateData(ID3D11DomainShader
*iface
,
907 REFGUID guid
, UINT
*data_size
, void *data
)
909 struct d3d11_domain_shader
*shader
= impl_from_ID3D11DomainShader(iface
);
911 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
913 return d3d_get_private_data(&shader
->private_store
, guid
, data_size
, data
);
916 static HRESULT STDMETHODCALLTYPE
d3d11_domain_shader_SetPrivateData(ID3D11DomainShader
*iface
,
917 REFGUID guid
, UINT data_size
, const void *data
)
919 struct d3d11_domain_shader
*shader
= impl_from_ID3D11DomainShader(iface
);
921 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
923 return d3d_set_private_data(&shader
->private_store
, guid
, data_size
, data
);
926 static HRESULT STDMETHODCALLTYPE
d3d11_domain_shader_SetPrivateDataInterface(ID3D11DomainShader
*iface
,
927 REFGUID guid
, const IUnknown
*data
)
929 struct d3d11_domain_shader
*shader
= impl_from_ID3D11DomainShader(iface
);
931 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
933 return d3d_set_private_data_interface(&shader
->private_store
, guid
, data
);
936 static const struct ID3D11DomainShaderVtbl d3d11_domain_shader_vtbl
=
938 /* IUnknown methods */
939 d3d11_domain_shader_QueryInterface
,
940 d3d11_domain_shader_AddRef
,
941 d3d11_domain_shader_Release
,
942 /* ID3D11DeviceChild methods */
943 d3d11_domain_shader_GetDevice
,
944 d3d11_domain_shader_GetPrivateData
,
945 d3d11_domain_shader_SetPrivateData
,
946 d3d11_domain_shader_SetPrivateDataInterface
,
949 static void STDMETHODCALLTYPE
d3d11_domain_shader_wined3d_object_destroyed(void *parent
)
951 struct d3d11_domain_shader
*shader
= parent
;
953 wined3d_private_store_cleanup(&shader
->private_store
);
957 static const struct wined3d_parent_ops d3d11_domain_shader_wined3d_parent_ops
=
959 d3d11_domain_shader_wined3d_object_destroyed
,
962 static HRESULT
d3d11_domain_shader_init(struct d3d11_domain_shader
*shader
, struct d3d_device
*device
,
963 const void *byte_code
, SIZE_T byte_code_length
)
965 struct wined3d_shader_desc desc
;
968 shader
->ID3D11DomainShader_iface
.lpVtbl
= &d3d11_domain_shader_vtbl
;
969 shader
->refcount
= 1;
970 wined3d_mutex_lock();
971 wined3d_private_store_init(&shader
->private_store
);
973 if (FAILED(hr
= shader_extract_from_dxbc(byte_code
, byte_code_length
, &desc
, device
->feature_level
)))
975 WARN("Failed to extract shader, hr %#x.\n", hr
);
976 wined3d_private_store_cleanup(&shader
->private_store
);
977 wined3d_mutex_unlock();
980 desc
.max_version
= d3d_sm_from_feature_level(device
->feature_level
);
982 hr
= wined3d_shader_create_ds(device
->wined3d_device
, &desc
, shader
,
983 &d3d11_domain_shader_wined3d_parent_ops
, &shader
->wined3d_shader
);
984 free_shader_desc(&desc
);
987 WARN("Failed to create wined3d domain shader, hr %#x.\n", hr
);
988 wined3d_private_store_cleanup(&shader
->private_store
);
989 wined3d_mutex_unlock();
992 wined3d_mutex_unlock();
994 shader
->device
= &device
->ID3D11Device1_iface
;
995 ID3D11Device1_AddRef(shader
->device
);
1000 HRESULT
d3d11_domain_shader_create(struct d3d_device
*device
, const void *byte_code
, SIZE_T byte_code_length
,
1001 struct d3d11_domain_shader
**shader
)
1003 struct d3d11_domain_shader
*object
;
1006 if (!(object
= heap_alloc_zero(sizeof(*object
))))
1007 return E_OUTOFMEMORY
;
1009 if (FAILED(hr
= d3d11_domain_shader_init(object
, device
, byte_code
, byte_code_length
)))
1015 TRACE("Created domain shader %p.\n", object
);
1021 struct d3d11_domain_shader
*unsafe_impl_from_ID3D11DomainShader(ID3D11DomainShader
*iface
)
1025 assert(iface
->lpVtbl
== &d3d11_domain_shader_vtbl
);
1027 return impl_from_ID3D11DomainShader(iface
);
1030 /* ID3D11GeometryShader methods */
1032 static inline struct d3d_geometry_shader
*impl_from_ID3D11GeometryShader(ID3D11GeometryShader
*iface
)
1034 return CONTAINING_RECORD(iface
, struct d3d_geometry_shader
, ID3D11GeometryShader_iface
);
1037 static HRESULT STDMETHODCALLTYPE
d3d11_geometry_shader_QueryInterface(ID3D11GeometryShader
*iface
,
1038 REFIID riid
, void **object
)
1040 struct d3d_geometry_shader
*shader
= impl_from_ID3D11GeometryShader(iface
);
1042 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
1044 if (IsEqualGUID(riid
, &IID_ID3D11GeometryShader
)
1045 || IsEqualGUID(riid
, &IID_ID3D11DeviceChild
)
1046 || IsEqualGUID(riid
, &IID_IUnknown
))
1048 ID3D11GeometryShader_AddRef(iface
);
1053 if (IsEqualGUID(riid
, &IID_ID3D10GeometryShader
)
1054 || IsEqualGUID(riid
, &IID_ID3D10DeviceChild
))
1056 ID3D10GeometryShader_AddRef(&shader
->ID3D10GeometryShader_iface
);
1057 *object
= &shader
->ID3D10GeometryShader_iface
;
1061 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
1064 return E_NOINTERFACE
;
1067 static ULONG STDMETHODCALLTYPE
d3d11_geometry_shader_AddRef(ID3D11GeometryShader
*iface
)
1069 struct d3d_geometry_shader
*shader
= impl_from_ID3D11GeometryShader(iface
);
1070 ULONG refcount
= InterlockedIncrement(&shader
->refcount
);
1072 TRACE("%p increasing refcount to %u.\n", shader
, refcount
);
1076 ID3D11Device1_AddRef(shader
->device
);
1077 wined3d_mutex_lock();
1078 wined3d_shader_incref(shader
->wined3d_shader
);
1079 wined3d_mutex_unlock();
1085 static ULONG STDMETHODCALLTYPE
d3d11_geometry_shader_Release(ID3D11GeometryShader
*iface
)
1087 struct d3d_geometry_shader
*shader
= impl_from_ID3D11GeometryShader(iface
);
1088 ULONG refcount
= InterlockedDecrement(&shader
->refcount
);
1090 TRACE("%p decreasing refcount to %u.\n", shader
, refcount
);
1094 ID3D11Device1
*device
= shader
->device
;
1096 wined3d_mutex_lock();
1097 wined3d_shader_decref(shader
->wined3d_shader
);
1098 wined3d_mutex_unlock();
1100 /* Release the device last, it may cause the wined3d device to be
1102 ID3D11Device1_Release(device
);
1108 static void STDMETHODCALLTYPE
d3d11_geometry_shader_GetDevice(ID3D11GeometryShader
*iface
,
1109 ID3D11Device
**device
)
1111 struct d3d_geometry_shader
*shader
= impl_from_ID3D11GeometryShader(iface
);
1113 TRACE("iface %p, device %p.\n", iface
, device
);
1115 *device
= (ID3D11Device
*)shader
->device
;
1116 ID3D11Device_AddRef(*device
);
1119 static HRESULT STDMETHODCALLTYPE
d3d11_geometry_shader_GetPrivateData(ID3D11GeometryShader
*iface
,
1120 REFGUID guid
, UINT
*data_size
, void *data
)
1122 struct d3d_geometry_shader
*shader
= impl_from_ID3D11GeometryShader(iface
);
1124 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
1126 return d3d_get_private_data(&shader
->private_store
, guid
, data_size
, data
);
1129 static HRESULT STDMETHODCALLTYPE
d3d11_geometry_shader_SetPrivateData(ID3D11GeometryShader
*iface
,
1130 REFGUID guid
, UINT data_size
, const void *data
)
1132 struct d3d_geometry_shader
*shader
= impl_from_ID3D11GeometryShader(iface
);
1134 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
1136 return d3d_set_private_data(&shader
->private_store
, guid
, data_size
, data
);
1139 static HRESULT STDMETHODCALLTYPE
d3d11_geometry_shader_SetPrivateDataInterface(ID3D11GeometryShader
*iface
,
1140 REFGUID guid
, const IUnknown
*data
)
1142 struct d3d_geometry_shader
*shader
= impl_from_ID3D11GeometryShader(iface
);
1144 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
1146 return d3d_set_private_data_interface(&shader
->private_store
, guid
, data
);
1149 static const struct ID3D11GeometryShaderVtbl d3d11_geometry_shader_vtbl
=
1151 /* IUnknown methods */
1152 d3d11_geometry_shader_QueryInterface
,
1153 d3d11_geometry_shader_AddRef
,
1154 d3d11_geometry_shader_Release
,
1155 /* ID3D11DeviceChild methods */
1156 d3d11_geometry_shader_GetDevice
,
1157 d3d11_geometry_shader_GetPrivateData
,
1158 d3d11_geometry_shader_SetPrivateData
,
1159 d3d11_geometry_shader_SetPrivateDataInterface
,
1162 /* ID3D10GeometryShader methods */
1164 static inline struct d3d_geometry_shader
*impl_from_ID3D10GeometryShader(ID3D10GeometryShader
*iface
)
1166 return CONTAINING_RECORD(iface
, struct d3d_geometry_shader
, ID3D10GeometryShader_iface
);
1169 /* IUnknown methods */
1171 static HRESULT STDMETHODCALLTYPE
d3d10_geometry_shader_QueryInterface(ID3D10GeometryShader
*iface
,
1172 REFIID riid
, void **object
)
1174 struct d3d_geometry_shader
*shader
= impl_from_ID3D10GeometryShader(iface
);
1176 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
1178 return d3d11_geometry_shader_QueryInterface(&shader
->ID3D11GeometryShader_iface
, riid
, object
);
1181 static ULONG STDMETHODCALLTYPE
d3d10_geometry_shader_AddRef(ID3D10GeometryShader
*iface
)
1183 struct d3d_geometry_shader
*shader
= impl_from_ID3D10GeometryShader(iface
);
1185 TRACE("iface %p.\n", iface
);
1187 return d3d11_geometry_shader_AddRef(&shader
->ID3D11GeometryShader_iface
);
1190 static ULONG STDMETHODCALLTYPE
d3d10_geometry_shader_Release(ID3D10GeometryShader
*iface
)
1192 struct d3d_geometry_shader
*shader
= impl_from_ID3D10GeometryShader(iface
);
1194 TRACE("iface %p.\n", iface
);
1196 return d3d11_geometry_shader_Release(&shader
->ID3D11GeometryShader_iface
);
1199 /* ID3D10DeviceChild methods */
1201 static void STDMETHODCALLTYPE
d3d10_geometry_shader_GetDevice(ID3D10GeometryShader
*iface
, ID3D10Device
**device
)
1203 struct d3d_geometry_shader
*shader
= impl_from_ID3D10GeometryShader(iface
);
1205 TRACE("iface %p, device %p.\n", iface
, device
);
1207 ID3D11Device1_QueryInterface(shader
->device
, &IID_ID3D10Device
, (void **)device
);
1210 static HRESULT STDMETHODCALLTYPE
d3d10_geometry_shader_GetPrivateData(ID3D10GeometryShader
*iface
,
1211 REFGUID guid
, UINT
*data_size
, void *data
)
1213 struct d3d_geometry_shader
*shader
= impl_from_ID3D10GeometryShader(iface
);
1215 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
1216 iface
, debugstr_guid(guid
), data_size
, data
);
1218 return d3d_get_private_data(&shader
->private_store
, guid
, data_size
, data
);
1221 static HRESULT STDMETHODCALLTYPE
d3d10_geometry_shader_SetPrivateData(ID3D10GeometryShader
*iface
,
1222 REFGUID guid
, UINT data_size
, const void *data
)
1224 struct d3d_geometry_shader
*shader
= impl_from_ID3D10GeometryShader(iface
);
1226 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
1227 iface
, debugstr_guid(guid
), data_size
, data
);
1229 return d3d_set_private_data(&shader
->private_store
, guid
, data_size
, data
);
1232 static HRESULT STDMETHODCALLTYPE
d3d10_geometry_shader_SetPrivateDataInterface(ID3D10GeometryShader
*iface
,
1233 REFGUID guid
, const IUnknown
*data
)
1235 struct d3d_geometry_shader
*shader
= impl_from_ID3D10GeometryShader(iface
);
1237 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
1239 return d3d_set_private_data_interface(&shader
->private_store
, guid
, data
);
1242 static const struct ID3D10GeometryShaderVtbl d3d10_geometry_shader_vtbl
=
1244 /* IUnknown methods */
1245 d3d10_geometry_shader_QueryInterface
,
1246 d3d10_geometry_shader_AddRef
,
1247 d3d10_geometry_shader_Release
,
1248 /* ID3D10DeviceChild methods */
1249 d3d10_geometry_shader_GetDevice
,
1250 d3d10_geometry_shader_GetPrivateData
,
1251 d3d10_geometry_shader_SetPrivateData
,
1252 d3d10_geometry_shader_SetPrivateDataInterface
,
1255 static void STDMETHODCALLTYPE
d3d_geometry_shader_wined3d_object_destroyed(void *parent
)
1257 struct d3d_geometry_shader
*shader
= parent
;
1259 wined3d_private_store_cleanup(&shader
->private_store
);
1263 static const struct wined3d_parent_ops d3d_geometry_shader_wined3d_parent_ops
=
1265 d3d_geometry_shader_wined3d_object_destroyed
,
1268 static HRESULT
wined3d_so_elements_from_d3d11_so_entries(struct wined3d_stream_output_element
*elements
,
1269 const D3D11_SO_DECLARATION_ENTRY
*entries
, unsigned int entry_count
,
1270 const unsigned int *buffer_strides
, unsigned int buffer_stride_count
,
1271 const struct wined3d_shader_signature
*os
, D3D_FEATURE_LEVEL feature_level
)
1273 unsigned int i
, j
, mask
;
1275 for (i
= 0; i
< entry_count
; ++i
)
1277 struct wined3d_stream_output_element
*e
= &elements
[i
];
1278 const D3D11_SO_DECLARATION_ENTRY
*f
= &entries
[i
];
1279 struct wined3d_shader_signature_element
*output
;
1281 TRACE("Stream: %u, semantic: %s, semantic idx: %u, start component: %u, "
1282 "component count %u, output slot %u.\n",
1283 f
->Stream
, debugstr_a(f
->SemanticName
), f
->SemanticIndex
,
1284 f
->StartComponent
, f
->ComponentCount
, f
->OutputSlot
);
1286 if (f
->Stream
>= D3D11_SO_STREAM_COUNT
)
1288 WARN("Invalid stream %u.\n", f
->Stream
);
1289 return E_INVALIDARG
;
1291 if (f
->Stream
&& feature_level
< D3D_FEATURE_LEVEL_11_0
)
1293 WARN("Invalid stream %u for feature level %#x.\n", f
->Stream
, feature_level
);
1294 return E_INVALIDARG
;
1298 FIXME("Streams not implemented yet.\n");
1299 return E_INVALIDARG
;
1301 if (f
->OutputSlot
>= D3D11_SO_BUFFER_SLOT_COUNT
)
1303 WARN("Invalid output slot %u.\n", f
->OutputSlot
);
1304 return E_INVALIDARG
;
1307 e
->stream_idx
= f
->Stream
;
1308 e
->component_idx
= f
->StartComponent
;
1309 e
->component_count
= f
->ComponentCount
;
1310 e
->output_slot
= f
->OutputSlot
;
1312 if (!f
->SemanticName
)
1314 if (f
->SemanticIndex
)
1316 WARN("Invalid semantic idx %u for stream output gap.\n", f
->SemanticIndex
);
1317 return E_INVALIDARG
;
1319 if (e
->component_idx
|| !e
->component_count
)
1321 WARN("Invalid stream output gap %u-%u.\n", e
->component_idx
, e
->component_count
);
1322 return E_INVALIDARG
;
1325 e
->register_idx
= WINED3D_STREAM_OUTPUT_GAP
;
1327 else if ((output
= shader_find_signature_element(os
, f
->SemanticName
, f
->SemanticIndex
, f
->Stream
)))
1329 if (e
->component_idx
> 3 || e
->component_count
> 4 || !e
->component_count
1330 || e
->component_idx
+ e
->component_count
> 4)
1332 WARN("Invalid component range %u-%u.\n", e
->component_idx
, e
->component_count
);
1333 return E_INVALIDARG
;
1336 for (j
= 0; j
< 4; ++j
)
1338 if ((1u << j
) & output
->mask
)
1341 e
->component_idx
+= j
;
1342 mask
= ((1u << e
->component_count
) - 1) << e
->component_idx
;
1343 if ((output
->mask
& 0xff & mask
) != mask
)
1345 WARN("Invalid component range %u-%u (mask %#x), output mask %#x.\n",
1346 e
->component_idx
, e
->component_count
, mask
, output
->mask
& 0xff);
1347 return E_INVALIDARG
;
1350 e
->register_idx
= output
->register_idx
;
1351 TRACE("Register idx: %u, register component idx %u, register mask %#x.\n",
1352 e
->register_idx
, e
->component_idx
, mask
);
1356 WARN("Failed to find output signature element for stream output entry.\n");
1357 return E_INVALIDARG
;
1361 for (i
= 0; i
< entry_count
; ++i
)
1363 const struct wined3d_stream_output_element
*e1
= &elements
[i
];
1364 if (e1
->register_idx
== WINED3D_STREAM_OUTPUT_GAP
)
1367 for (j
= i
+ 1; j
< entry_count
; ++j
)
1369 const struct wined3d_stream_output_element
*e2
= &elements
[j
];
1371 if (e1
->register_idx
== e2
->register_idx
1372 && e1
->component_idx
< e2
->component_idx
+ e2
->component_count
1373 && e1
->component_idx
+ e1
->component_count
> e2
->component_idx
)
1375 WARN("Stream output elements %u and %u overlap.\n", i
, j
);
1376 return E_INVALIDARG
;
1381 for (i
= 0; i
< D3D11_SO_STREAM_COUNT
; ++i
)
1383 unsigned int current_stride
[D3D11_SO_BUFFER_SLOT_COUNT
] = {0};
1384 unsigned int element_count
[D3D11_SO_BUFFER_SLOT_COUNT
] = {0};
1385 unsigned int gap_count
[D3D11_SO_BUFFER_SLOT_COUNT
] = {0};
1387 for (j
= 0; j
< entry_count
; ++j
)
1389 const struct wined3d_stream_output_element
*e
= &elements
[j
];
1391 if (e
->stream_idx
!= i
)
1393 current_stride
[e
->output_slot
] += 4 * e
->component_count
;
1394 ++element_count
[e
->output_slot
];
1395 if (e
->register_idx
== WINED3D_STREAM_OUTPUT_GAP
)
1396 ++gap_count
[e
->output_slot
];
1399 for (j
= 0; j
< D3D11_SO_BUFFER_SLOT_COUNT
; ++j
)
1401 if (!element_count
[j
])
1403 if (element_count
[j
] == gap_count
[j
])
1405 WARN("Stream %u, output slot %u contains only gaps.\n", i
, j
);
1406 return E_INVALIDARG
;
1408 if (buffer_stride_count
)
1410 if (buffer_stride_count
<= j
)
1412 WARN("Buffer strides are required for all buffer slots.\n");
1413 return E_INVALIDARG
;
1415 if (buffer_strides
[j
] < current_stride
[j
] || buffer_strides
[j
] % 4)
1417 WARN("Invalid stride %u for buffer slot %u.\n", buffer_strides
[j
], j
);
1418 return E_INVALIDARG
;
1423 if (!i
&& feature_level
< D3D_FEATURE_LEVEL_11_0
&& element_count
[0] != entry_count
)
1425 for (j
= 0; j
< ARRAY_SIZE(element_count
); ++j
)
1427 if (element_count
[j
] > 1)
1429 WARN("Only one element per output slot is allowed.\n");
1430 return E_INVALIDARG
;
1439 static HRESULT
d3d_geometry_shader_init(struct d3d_geometry_shader
*shader
,
1440 struct d3d_device
*device
, const void *byte_code
, SIZE_T byte_code_length
,
1441 const D3D11_SO_DECLARATION_ENTRY
*so_entries
, unsigned int so_entry_count
,
1442 const unsigned int *buffer_strides
, unsigned int buffer_stride_count
,
1443 unsigned int rasterizer_stream
)
1445 struct wined3d_stream_output_desc so_desc
;
1446 struct wined3d_shader_desc desc
;
1450 if (so_entry_count
> D3D11_SO_STREAM_COUNT
* D3D11_SO_OUTPUT_COMPONENT_COUNT
)
1452 WARN("Entry count %u is greater than %u.\n",
1453 so_entry_count
, D3D11_SO_STREAM_COUNT
* D3D11_SO_OUTPUT_COMPONENT_COUNT
);
1454 return E_INVALIDARG
;
1456 if (so_entries
&& !so_entry_count
)
1458 WARN("Invalid SO entry count %u.\n", so_entry_count
);
1459 return E_INVALIDARG
;
1461 if (rasterizer_stream
!= D3D11_SO_NO_RASTERIZED_STREAM
&& rasterizer_stream
>= D3D11_SO_STREAM_COUNT
)
1463 WARN("Invalid rasterizer stream %u.\n", rasterizer_stream
);
1464 return E_INVALIDARG
;
1466 if (device
->feature_level
< D3D_FEATURE_LEVEL_11_0
)
1468 if (rasterizer_stream
)
1470 WARN("Invalid rasterizer stream %u for feature level %#x.\n",
1471 rasterizer_stream
, device
->feature_level
);
1472 return E_INVALIDARG
;
1474 if (buffer_stride_count
&& buffer_stride_count
!= 1)
1476 WARN("Invalid buffer stride count %u for feature level %#x.\n",
1477 buffer_stride_count
, device
->feature_level
);
1478 return E_INVALIDARG
;
1482 if (FAILED(hr
= shader_extract_from_dxbc(byte_code
, byte_code_length
, &desc
, device
->feature_level
)))
1484 WARN("Failed to extract shader, hr %#x.\n", hr
);
1487 desc
.max_version
= d3d_sm_from_feature_level(device
->feature_level
);
1489 memset(&so_desc
, 0, sizeof(so_desc
));
1492 so_desc
.element_count
= so_entry_count
;
1493 for (i
= 0; i
< min(buffer_stride_count
, ARRAY_SIZE(so_desc
.buffer_strides
)); ++i
)
1494 so_desc
.buffer_strides
[i
] = buffer_strides
[i
];
1495 so_desc
.buffer_stride_count
= buffer_stride_count
;
1496 so_desc
.rasterizer_stream_idx
= rasterizer_stream
;
1498 if (!(so_desc
.elements
= heap_calloc(so_entry_count
, sizeof(*so_desc
.elements
))))
1500 ERR("Failed to allocate wined3d stream output element array memory.\n");
1501 free_shader_desc(&desc
);
1502 return E_OUTOFMEMORY
;
1504 if (FAILED(hr
= wined3d_so_elements_from_d3d11_so_entries(so_desc
.elements
,
1505 so_entries
, so_entry_count
, buffer_strides
, buffer_stride_count
,
1506 &desc
.output_signature
, device
->feature_level
)))
1508 heap_free(so_desc
.elements
);
1509 free_shader_desc(&desc
);
1514 shader
->ID3D11GeometryShader_iface
.lpVtbl
= &d3d11_geometry_shader_vtbl
;
1515 shader
->ID3D10GeometryShader_iface
.lpVtbl
= &d3d10_geometry_shader_vtbl
;
1516 shader
->refcount
= 1;
1517 wined3d_mutex_lock();
1518 wined3d_private_store_init(&shader
->private_store
);
1520 hr
= wined3d_shader_create_gs(device
->wined3d_device
, &desc
, so_entries
? &so_desc
: NULL
,
1521 shader
, &d3d_geometry_shader_wined3d_parent_ops
, &shader
->wined3d_shader
);
1522 heap_free(so_desc
.elements
);
1523 free_shader_desc(&desc
);
1526 WARN("Failed to create wined3d geometry shader, hr %#x.\n", hr
);
1527 wined3d_private_store_cleanup(&shader
->private_store
);
1528 wined3d_mutex_unlock();
1529 return E_INVALIDARG
;
1531 wined3d_mutex_unlock();
1533 shader
->device
= &device
->ID3D11Device1_iface
;
1534 ID3D11Device1_AddRef(shader
->device
);
1539 HRESULT
d3d_geometry_shader_create(struct d3d_device
*device
, const void *byte_code
, SIZE_T byte_code_length
,
1540 const D3D11_SO_DECLARATION_ENTRY
*so_entries
, unsigned int so_entry_count
,
1541 const unsigned int *buffer_strides
, unsigned int buffer_stride_count
, unsigned int rasterizer_stream
,
1542 struct d3d_geometry_shader
**shader
)
1544 struct d3d_geometry_shader
*object
;
1547 if (!(object
= heap_alloc_zero(sizeof(*object
))))
1548 return E_OUTOFMEMORY
;
1550 if (FAILED(hr
= d3d_geometry_shader_init(object
, device
, byte_code
, byte_code_length
,
1551 so_entries
, so_entry_count
, buffer_strides
, buffer_stride_count
, rasterizer_stream
)))
1553 WARN("Failed to initialize geometry shader, hr %#x.\n", hr
);
1558 TRACE("Created geometry shader %p.\n", object
);
1564 struct d3d_geometry_shader
*unsafe_impl_from_ID3D11GeometryShader(ID3D11GeometryShader
*iface
)
1568 assert(iface
->lpVtbl
== &d3d11_geometry_shader_vtbl
);
1570 return impl_from_ID3D11GeometryShader(iface
);
1573 struct d3d_geometry_shader
*unsafe_impl_from_ID3D10GeometryShader(ID3D10GeometryShader
*iface
)
1577 assert(iface
->lpVtbl
== &d3d10_geometry_shader_vtbl
);
1579 return impl_from_ID3D10GeometryShader(iface
);
1582 /* ID3D11PixelShader methods */
1584 static inline struct d3d_pixel_shader
*impl_from_ID3D11PixelShader(ID3D11PixelShader
*iface
)
1586 return CONTAINING_RECORD(iface
, struct d3d_pixel_shader
, ID3D11PixelShader_iface
);
1589 static HRESULT STDMETHODCALLTYPE
d3d11_pixel_shader_QueryInterface(ID3D11PixelShader
*iface
,
1590 REFIID riid
, void **object
)
1592 struct d3d_pixel_shader
*shader
= impl_from_ID3D11PixelShader(iface
);
1594 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
1596 if (IsEqualGUID(riid
, &IID_ID3D11PixelShader
)
1597 || IsEqualGUID(riid
, &IID_ID3D11DeviceChild
)
1598 || IsEqualGUID(riid
, &IID_IUnknown
))
1600 ID3D11PixelShader_AddRef(iface
);
1605 if (IsEqualGUID(riid
, &IID_ID3D10PixelShader
)
1606 || IsEqualGUID(riid
, &IID_ID3D10DeviceChild
))
1608 IUnknown_AddRef(&shader
->ID3D10PixelShader_iface
);
1609 *object
= &shader
->ID3D10PixelShader_iface
;
1613 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
1616 return E_NOINTERFACE
;
1619 static ULONG STDMETHODCALLTYPE
d3d11_pixel_shader_AddRef(ID3D11PixelShader
*iface
)
1621 struct d3d_pixel_shader
*shader
= impl_from_ID3D11PixelShader(iface
);
1622 ULONG refcount
= InterlockedIncrement(&shader
->refcount
);
1624 TRACE("%p increasing refcount to %u.\n", shader
, refcount
);
1628 ID3D11Device1_AddRef(shader
->device
);
1629 wined3d_mutex_lock();
1630 wined3d_shader_incref(shader
->wined3d_shader
);
1631 wined3d_mutex_unlock();
1637 static ULONG STDMETHODCALLTYPE
d3d11_pixel_shader_Release(ID3D11PixelShader
*iface
)
1639 struct d3d_pixel_shader
*shader
= impl_from_ID3D11PixelShader(iface
);
1640 ULONG refcount
= InterlockedDecrement(&shader
->refcount
);
1642 TRACE("%p decreasing refcount to %u.\n", shader
, refcount
);
1646 ID3D11Device1
*device
= shader
->device
;
1648 wined3d_mutex_lock();
1649 wined3d_shader_decref(shader
->wined3d_shader
);
1650 wined3d_mutex_unlock();
1651 /* Release the device last, it may cause the wined3d device to be
1653 ID3D11Device1_Release(device
);
1659 static void STDMETHODCALLTYPE
d3d11_pixel_shader_GetDevice(ID3D11PixelShader
*iface
,
1660 ID3D11Device
**device
)
1662 struct d3d_pixel_shader
*shader
= impl_from_ID3D11PixelShader(iface
);
1664 TRACE("iface %p, device %p.\n", iface
, device
);
1666 *device
= (ID3D11Device
*)shader
->device
;
1667 ID3D11Device_AddRef(*device
);
1670 static HRESULT STDMETHODCALLTYPE
d3d11_pixel_shader_GetPrivateData(ID3D11PixelShader
*iface
,
1671 REFGUID guid
, UINT
*data_size
, void *data
)
1673 struct d3d_pixel_shader
*shader
= impl_from_ID3D11PixelShader(iface
);
1675 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
1677 return d3d_get_private_data(&shader
->private_store
, guid
, data_size
, data
);
1680 static HRESULT STDMETHODCALLTYPE
d3d11_pixel_shader_SetPrivateData(ID3D11PixelShader
*iface
,
1681 REFGUID guid
, UINT data_size
, const void *data
)
1683 struct d3d_pixel_shader
*shader
= impl_from_ID3D11PixelShader(iface
);
1685 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
1687 return d3d_set_private_data(&shader
->private_store
, guid
, data_size
, data
);
1690 static HRESULT STDMETHODCALLTYPE
d3d11_pixel_shader_SetPrivateDataInterface(ID3D11PixelShader
*iface
,
1691 REFGUID guid
, const IUnknown
*data
)
1693 struct d3d_pixel_shader
*shader
= impl_from_ID3D11PixelShader(iface
);
1695 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
1697 return d3d_set_private_data_interface(&shader
->private_store
, guid
, data
);
1700 static const struct ID3D11PixelShaderVtbl d3d11_pixel_shader_vtbl
=
1702 /* IUnknown methods */
1703 d3d11_pixel_shader_QueryInterface
,
1704 d3d11_pixel_shader_AddRef
,
1705 d3d11_pixel_shader_Release
,
1706 /* ID3D11DeviceChild methods */
1707 d3d11_pixel_shader_GetDevice
,
1708 d3d11_pixel_shader_GetPrivateData
,
1709 d3d11_pixel_shader_SetPrivateData
,
1710 d3d11_pixel_shader_SetPrivateDataInterface
,
1713 /* ID3D10PixelShader methods */
1715 static inline struct d3d_pixel_shader
*impl_from_ID3D10PixelShader(ID3D10PixelShader
*iface
)
1717 return CONTAINING_RECORD(iface
, struct d3d_pixel_shader
, ID3D10PixelShader_iface
);
1720 /* IUnknown methods */
1722 static HRESULT STDMETHODCALLTYPE
d3d10_pixel_shader_QueryInterface(ID3D10PixelShader
*iface
,
1723 REFIID riid
, void **object
)
1725 struct d3d_pixel_shader
*shader
= impl_from_ID3D10PixelShader(iface
);
1727 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
1729 return d3d11_pixel_shader_QueryInterface(&shader
->ID3D11PixelShader_iface
, riid
, object
);
1732 static ULONG STDMETHODCALLTYPE
d3d10_pixel_shader_AddRef(ID3D10PixelShader
*iface
)
1734 struct d3d_pixel_shader
*shader
= impl_from_ID3D10PixelShader(iface
);
1736 TRACE("iface %p.\n", iface
);
1738 return d3d11_pixel_shader_AddRef(&shader
->ID3D11PixelShader_iface
);
1741 static ULONG STDMETHODCALLTYPE
d3d10_pixel_shader_Release(ID3D10PixelShader
*iface
)
1743 struct d3d_pixel_shader
*shader
= impl_from_ID3D10PixelShader(iface
);
1745 TRACE("iface %p.\n", iface
);
1747 return d3d11_pixel_shader_Release(&shader
->ID3D11PixelShader_iface
);
1750 /* ID3D10DeviceChild methods */
1752 static void STDMETHODCALLTYPE
d3d10_pixel_shader_GetDevice(ID3D10PixelShader
*iface
, ID3D10Device
**device
)
1754 struct d3d_pixel_shader
*shader
= impl_from_ID3D10PixelShader(iface
);
1756 TRACE("iface %p, device %p.\n", iface
, device
);
1758 ID3D11Device1_QueryInterface(shader
->device
, &IID_ID3D10Device
, (void **)device
);
1761 static HRESULT STDMETHODCALLTYPE
d3d10_pixel_shader_GetPrivateData(ID3D10PixelShader
*iface
,
1762 REFGUID guid
, UINT
*data_size
, void *data
)
1764 struct d3d_pixel_shader
*shader
= impl_from_ID3D10PixelShader(iface
);
1766 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
1767 iface
, debugstr_guid(guid
), data_size
, data
);
1769 return d3d_get_private_data(&shader
->private_store
, guid
, data_size
, data
);
1772 static HRESULT STDMETHODCALLTYPE
d3d10_pixel_shader_SetPrivateData(ID3D10PixelShader
*iface
,
1773 REFGUID guid
, UINT data_size
, const void *data
)
1775 struct d3d_pixel_shader
*shader
= impl_from_ID3D10PixelShader(iface
);
1777 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
1778 iface
, debugstr_guid(guid
), data_size
, data
);
1780 return d3d_set_private_data(&shader
->private_store
, guid
, data_size
, data
);
1783 static HRESULT STDMETHODCALLTYPE
d3d10_pixel_shader_SetPrivateDataInterface(ID3D10PixelShader
*iface
,
1784 REFGUID guid
, const IUnknown
*data
)
1786 struct d3d_pixel_shader
*shader
= impl_from_ID3D10PixelShader(iface
);
1788 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
1790 return d3d_set_private_data_interface(&shader
->private_store
, guid
, data
);
1793 static const struct ID3D10PixelShaderVtbl d3d10_pixel_shader_vtbl
=
1795 /* IUnknown methods */
1796 d3d10_pixel_shader_QueryInterface
,
1797 d3d10_pixel_shader_AddRef
,
1798 d3d10_pixel_shader_Release
,
1799 /* ID3D10DeviceChild methods */
1800 d3d10_pixel_shader_GetDevice
,
1801 d3d10_pixel_shader_GetPrivateData
,
1802 d3d10_pixel_shader_SetPrivateData
,
1803 d3d10_pixel_shader_SetPrivateDataInterface
,
1806 static void STDMETHODCALLTYPE
d3d_pixel_shader_wined3d_object_destroyed(void *parent
)
1808 struct d3d_pixel_shader
*shader
= parent
;
1810 wined3d_private_store_cleanup(&shader
->private_store
);
1814 static const struct wined3d_parent_ops d3d_pixel_shader_wined3d_parent_ops
=
1816 d3d_pixel_shader_wined3d_object_destroyed
,
1819 static HRESULT
d3d_pixel_shader_init(struct d3d_pixel_shader
*shader
, struct d3d_device
*device
,
1820 const void *byte_code
, SIZE_T byte_code_length
)
1822 struct wined3d_shader_desc desc
;
1825 shader
->ID3D11PixelShader_iface
.lpVtbl
= &d3d11_pixel_shader_vtbl
;
1826 shader
->ID3D10PixelShader_iface
.lpVtbl
= &d3d10_pixel_shader_vtbl
;
1827 shader
->refcount
= 1;
1828 wined3d_mutex_lock();
1829 wined3d_private_store_init(&shader
->private_store
);
1831 if (FAILED(hr
= shader_extract_from_dxbc(byte_code
, byte_code_length
, &desc
, device
->feature_level
)))
1833 WARN("Failed to extract shader, hr %#x.\n", hr
);
1834 wined3d_private_store_cleanup(&shader
->private_store
);
1835 wined3d_mutex_unlock();
1838 desc
.max_version
= d3d_sm_from_feature_level(device
->feature_level
);
1840 hr
= wined3d_shader_create_ps(device
->wined3d_device
, &desc
, shader
,
1841 &d3d_pixel_shader_wined3d_parent_ops
, &shader
->wined3d_shader
);
1842 free_shader_desc(&desc
);
1845 WARN("Failed to create wined3d pixel shader, hr %#x.\n", hr
);
1846 wined3d_private_store_cleanup(&shader
->private_store
);
1847 wined3d_mutex_unlock();
1848 return E_INVALIDARG
;
1850 wined3d_mutex_unlock();
1852 shader
->device
= &device
->ID3D11Device1_iface
;
1853 ID3D11Device1_AddRef(shader
->device
);
1858 HRESULT
d3d_pixel_shader_create(struct d3d_device
*device
, const void *byte_code
, SIZE_T byte_code_length
,
1859 struct d3d_pixel_shader
**shader
)
1861 struct d3d_pixel_shader
*object
;
1864 if (!(object
= heap_alloc_zero(sizeof(*object
))))
1865 return E_OUTOFMEMORY
;
1867 if (FAILED(hr
= d3d_pixel_shader_init(object
, device
, byte_code
, byte_code_length
)))
1869 WARN("Failed to initialize pixel shader, hr %#x.\n", hr
);
1874 TRACE("Created pixel shader %p.\n", object
);
1880 struct d3d_pixel_shader
*unsafe_impl_from_ID3D11PixelShader(ID3D11PixelShader
*iface
)
1884 assert(iface
->lpVtbl
== &d3d11_pixel_shader_vtbl
);
1886 return impl_from_ID3D11PixelShader(iface
);
1889 struct d3d_pixel_shader
*unsafe_impl_from_ID3D10PixelShader(ID3D10PixelShader
*iface
)
1893 assert(iface
->lpVtbl
== &d3d10_pixel_shader_vtbl
);
1895 return impl_from_ID3D10PixelShader(iface
);
1898 /* ID3D11ComputeShader methods */
1900 static inline struct d3d11_compute_shader
*impl_from_ID3D11ComputeShader(ID3D11ComputeShader
*iface
)
1902 return CONTAINING_RECORD(iface
, struct d3d11_compute_shader
, ID3D11ComputeShader_iface
);
1905 static HRESULT STDMETHODCALLTYPE
d3d11_compute_shader_QueryInterface(ID3D11ComputeShader
*iface
,
1906 REFIID riid
, void **object
)
1908 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
1910 if (IsEqualGUID(riid
, &IID_ID3D11ComputeShader
)
1911 || IsEqualGUID(riid
, &IID_ID3D11DeviceChild
)
1912 || IsEqualGUID(riid
, &IID_IUnknown
))
1914 ID3D11ComputeShader_AddRef(*object
= iface
);
1918 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
1921 return E_NOINTERFACE
;
1924 static ULONG STDMETHODCALLTYPE
d3d11_compute_shader_AddRef(ID3D11ComputeShader
*iface
)
1926 struct d3d11_compute_shader
*shader
= impl_from_ID3D11ComputeShader(iface
);
1927 ULONG refcount
= InterlockedIncrement(&shader
->refcount
);
1929 TRACE("%p increasing refcount to %u.\n", shader
, refcount
);
1933 ID3D11Device1_AddRef(shader
->device
);
1934 wined3d_mutex_lock();
1935 wined3d_shader_incref(shader
->wined3d_shader
);
1936 wined3d_mutex_unlock();
1942 static ULONG STDMETHODCALLTYPE
d3d11_compute_shader_Release(ID3D11ComputeShader
*iface
)
1944 struct d3d11_compute_shader
*shader
= impl_from_ID3D11ComputeShader(iface
);
1945 ULONG refcount
= InterlockedDecrement(&shader
->refcount
);
1947 TRACE("%p decreasing refcount to %u.\n", shader
, refcount
);
1951 ID3D11Device1
*device
= shader
->device
;
1953 wined3d_mutex_lock();
1954 wined3d_shader_decref(shader
->wined3d_shader
);
1955 wined3d_mutex_unlock();
1957 /* Release the device last, it may cause the wined3d device to be
1959 ID3D11Device1_Release(device
);
1965 static void STDMETHODCALLTYPE
d3d11_compute_shader_GetDevice(ID3D11ComputeShader
*iface
,
1966 ID3D11Device
**device
)
1968 struct d3d11_compute_shader
*shader
= impl_from_ID3D11ComputeShader(iface
);
1970 TRACE("iface %p, device %p.\n", iface
, device
);
1972 ID3D11Device_AddRef(*device
= (ID3D11Device
*)shader
->device
);
1975 static HRESULT STDMETHODCALLTYPE
d3d11_compute_shader_GetPrivateData(ID3D11ComputeShader
*iface
,
1976 REFGUID guid
, UINT
*data_size
, void *data
)
1978 struct d3d11_compute_shader
*shader
= impl_from_ID3D11ComputeShader(iface
);
1980 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
1982 return d3d_get_private_data(&shader
->private_store
, guid
, data_size
, data
);
1985 static HRESULT STDMETHODCALLTYPE
d3d11_compute_shader_SetPrivateData(ID3D11ComputeShader
*iface
,
1986 REFGUID guid
, UINT data_size
, const void *data
)
1988 struct d3d11_compute_shader
*shader
= impl_from_ID3D11ComputeShader(iface
);
1990 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
1992 return d3d_set_private_data(&shader
->private_store
, guid
, data_size
, data
);
1995 static HRESULT STDMETHODCALLTYPE
d3d11_compute_shader_SetPrivateDataInterface(ID3D11ComputeShader
*iface
,
1996 REFGUID guid
, const IUnknown
*data
)
1998 struct d3d11_compute_shader
*shader
= impl_from_ID3D11ComputeShader(iface
);
2000 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
2002 return d3d_set_private_data_interface(&shader
->private_store
, guid
, data
);
2005 static const struct ID3D11ComputeShaderVtbl d3d11_compute_shader_vtbl
=
2007 /* IUnknown methods */
2008 d3d11_compute_shader_QueryInterface
,
2009 d3d11_compute_shader_AddRef
,
2010 d3d11_compute_shader_Release
,
2011 /* ID3D11DeviceChild methods */
2012 d3d11_compute_shader_GetDevice
,
2013 d3d11_compute_shader_GetPrivateData
,
2014 d3d11_compute_shader_SetPrivateData
,
2015 d3d11_compute_shader_SetPrivateDataInterface
,
2018 static void STDMETHODCALLTYPE
d3d11_compute_shader_wined3d_object_destroyed(void *parent
)
2020 struct d3d11_compute_shader
*shader
= parent
;
2022 wined3d_private_store_cleanup(&shader
->private_store
);
2026 static const struct wined3d_parent_ops d3d11_compute_shader_wined3d_parent_ops
=
2028 d3d11_compute_shader_wined3d_object_destroyed
,
2031 static HRESULT
d3d11_compute_shader_init(struct d3d11_compute_shader
*shader
, struct d3d_device
*device
,
2032 const void *byte_code
, SIZE_T byte_code_length
)
2034 struct wined3d_shader_desc desc
;
2037 shader
->ID3D11ComputeShader_iface
.lpVtbl
= &d3d11_compute_shader_vtbl
;
2038 shader
->refcount
= 1;
2039 wined3d_mutex_lock();
2040 wined3d_private_store_init(&shader
->private_store
);
2042 if (FAILED(hr
= shader_extract_from_dxbc(byte_code
, byte_code_length
, &desc
, device
->feature_level
)))
2044 WARN("Failed to extract shader, hr %#x.\n", hr
);
2045 wined3d_private_store_cleanup(&shader
->private_store
);
2046 wined3d_mutex_unlock();
2049 desc
.max_version
= d3d_sm_from_feature_level(device
->feature_level
);
2051 hr
= wined3d_shader_create_cs(device
->wined3d_device
, &desc
, shader
,
2052 &d3d11_compute_shader_wined3d_parent_ops
, &shader
->wined3d_shader
);
2053 free_shader_desc(&desc
);
2056 WARN("Failed to create wined3d compute shader, hr %#x.\n", hr
);
2057 wined3d_private_store_cleanup(&shader
->private_store
);
2058 wined3d_mutex_unlock();
2059 return E_INVALIDARG
;
2061 wined3d_mutex_unlock();
2063 ID3D11Device1_AddRef(shader
->device
= &device
->ID3D11Device1_iface
);
2068 HRESULT
d3d11_compute_shader_create(struct d3d_device
*device
, const void *byte_code
, SIZE_T byte_code_length
,
2069 struct d3d11_compute_shader
**shader
)
2071 struct d3d11_compute_shader
*object
;
2074 if (!(object
= heap_alloc_zero(sizeof(*object
))))
2075 return E_OUTOFMEMORY
;
2077 if (FAILED(hr
= d3d11_compute_shader_init(object
, device
, byte_code
, byte_code_length
)))
2083 TRACE("Created compute shader %p.\n", object
);
2089 struct d3d11_compute_shader
*unsafe_impl_from_ID3D11ComputeShader(ID3D11ComputeShader
*iface
)
2093 assert(iface
->lpVtbl
== &d3d11_compute_shader_vtbl
);
2095 return impl_from_ID3D11ComputeShader(iface
);
2098 /* ID3D11ClassLinkage methods */
2100 static inline struct d3d11_class_linkage
*impl_from_ID3D11ClassLinkage(ID3D11ClassLinkage
*iface
)
2102 return CONTAINING_RECORD(iface
, struct d3d11_class_linkage
, ID3D11ClassLinkage_iface
);
2105 static HRESULT STDMETHODCALLTYPE
d3d11_class_linkage_QueryInterface(ID3D11ClassLinkage
*iface
,
2106 REFIID riid
, void **object
)
2108 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
2110 if (IsEqualGUID(riid
, &IID_ID3D11ClassLinkage
)
2111 || IsEqualGUID(riid
, &IID_ID3D11DeviceChild
)
2112 || IsEqualGUID(riid
, &IID_IUnknown
))
2114 ID3D11ClassLinkage_AddRef(*object
= iface
);
2118 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
2121 return E_NOINTERFACE
;
2124 static ULONG STDMETHODCALLTYPE
d3d11_class_linkage_AddRef(ID3D11ClassLinkage
*iface
)
2126 struct d3d11_class_linkage
*class_linkage
= impl_from_ID3D11ClassLinkage(iface
);
2127 ULONG refcount
= InterlockedIncrement(&class_linkage
->refcount
);
2129 TRACE("%p increasing refcount to %u.\n", class_linkage
, refcount
);
2134 static ULONG STDMETHODCALLTYPE
d3d11_class_linkage_Release(ID3D11ClassLinkage
*iface
)
2136 struct d3d11_class_linkage
*class_linkage
= impl_from_ID3D11ClassLinkage(iface
);
2137 ULONG refcount
= InterlockedDecrement(&class_linkage
->refcount
);
2139 TRACE("%p decreasing refcount to %u.\n", class_linkage
, refcount
);
2143 ID3D11Device1
*device
= class_linkage
->device
;
2145 wined3d_private_store_cleanup(&class_linkage
->private_store
);
2146 heap_free(class_linkage
);
2148 ID3D11Device1_Release(device
);
2154 static void STDMETHODCALLTYPE
d3d11_class_linkage_GetDevice(ID3D11ClassLinkage
*iface
,
2155 ID3D11Device
**device
)
2157 struct d3d11_class_linkage
*class_linkage
= impl_from_ID3D11ClassLinkage(iface
);
2159 TRACE("iface %p, device %p.\n", iface
, device
);
2161 ID3D11Device_AddRef(*device
= (ID3D11Device
*)class_linkage
->device
);
2164 static HRESULT STDMETHODCALLTYPE
d3d11_class_linkage_GetPrivateData(ID3D11ClassLinkage
*iface
,
2165 REFGUID guid
, UINT
*data_size
, void *data
)
2167 struct d3d11_class_linkage
*class_linkage
= impl_from_ID3D11ClassLinkage(iface
);
2169 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
2171 return d3d_get_private_data(&class_linkage
->private_store
, guid
, data_size
, data
);
2174 static HRESULT STDMETHODCALLTYPE
d3d11_class_linkage_SetPrivateData(ID3D11ClassLinkage
*iface
,
2175 REFGUID guid
, UINT data_size
, const void *data
)
2177 struct d3d11_class_linkage
*class_linkage
= impl_from_ID3D11ClassLinkage(iface
);
2179 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
2181 return d3d_set_private_data(&class_linkage
->private_store
, guid
, data_size
, data
);
2184 static HRESULT STDMETHODCALLTYPE
d3d11_class_linkage_SetPrivateDataInterface(ID3D11ClassLinkage
*iface
,
2185 REFGUID guid
, const IUnknown
*data
)
2187 struct d3d11_class_linkage
*class_linkage
= impl_from_ID3D11ClassLinkage(iface
);
2189 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
2191 return d3d_set_private_data_interface(&class_linkage
->private_store
, guid
, data
);
2194 static HRESULT STDMETHODCALLTYPE
d3d11_class_linkage_GetClassInstance(ID3D11ClassLinkage
*iface
,
2195 const char *instance_name
, UINT instance_index
, ID3D11ClassInstance
**class_instance
)
2197 FIXME("iface %p, instance_name %s, instance_index %u, class_instance %p stub!\n",
2198 iface
, debugstr_a(instance_name
), instance_index
, class_instance
);
2203 static HRESULT STDMETHODCALLTYPE
d3d11_class_linkage_CreateClassInstance(ID3D11ClassLinkage
*iface
,
2204 const char *type_name
, UINT cb_offset
, UINT cb_vector_offset
, UINT texture_offset
,
2205 UINT sampler_offset
, ID3D11ClassInstance
**class_instance
)
2207 FIXME("iface %p, type_name %s, cb_offset %u, cb_vector_offset %u, texture_offset %u, "
2208 "sampler_offset %u, class_instance %p stub!\n",
2209 iface
, debugstr_a(type_name
), cb_offset
, cb_vector_offset
, texture_offset
,
2210 sampler_offset
, class_instance
);
2215 static const struct ID3D11ClassLinkageVtbl d3d11_class_linkage_vtbl
=
2217 /* IUnknown methods */
2218 d3d11_class_linkage_QueryInterface
,
2219 d3d11_class_linkage_AddRef
,
2220 d3d11_class_linkage_Release
,
2221 /* ID3D11DeviceChild methods */
2222 d3d11_class_linkage_GetDevice
,
2223 d3d11_class_linkage_GetPrivateData
,
2224 d3d11_class_linkage_SetPrivateData
,
2225 d3d11_class_linkage_SetPrivateDataInterface
,
2226 /* ID3D11ClassLinkage methods */
2227 d3d11_class_linkage_GetClassInstance
,
2228 d3d11_class_linkage_CreateClassInstance
,
2231 HRESULT
d3d11_class_linkage_create(struct d3d_device
*device
, struct d3d11_class_linkage
**class_linkage
)
2233 struct d3d11_class_linkage
*object
;
2235 if (!(object
= heap_alloc_zero(sizeof(*object
))))
2236 return E_OUTOFMEMORY
;
2238 object
->ID3D11ClassLinkage_iface
.lpVtbl
= &d3d11_class_linkage_vtbl
;
2239 object
->refcount
= 1;
2240 wined3d_private_store_init(&object
->private_store
);
2242 ID3D11Device1_AddRef(object
->device
= &device
->ID3D11Device1_iface
);
2244 TRACE("Created class linkage %p.\n", object
);
2245 *class_linkage
= object
;