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
);
140 FIXME("Unhandled chunk %s.\n", debugstr_an((const char *)&tag
, 4));
147 static void free_shader_desc(struct wined3d_shader_desc
*desc
)
149 shader_free_signature(&desc
->input_signature
);
150 shader_free_signature(&desc
->output_signature
);
151 shader_free_signature(&desc
->patch_constant_signature
);
154 static HRESULT
shader_extract_from_dxbc(const void *dxbc
, SIZE_T dxbc_length
,
155 struct wined3d_shader_desc
*desc
, D3D_FEATURE_LEVEL feature_level
)
157 struct shader_handler_context ctx
= {feature_level
, desc
};
160 desc
->byte_code
= NULL
;
161 desc
->byte_code_size
= 0;
162 memset(&desc
->input_signature
, 0, sizeof(desc
->input_signature
));
163 memset(&desc
->output_signature
, 0, sizeof(desc
->output_signature
));
164 memset(&desc
->patch_constant_signature
, 0, sizeof(desc
->patch_constant_signature
));
166 hr
= parse_dxbc(dxbc
, dxbc_length
, shdr_handler
, &ctx
);
167 if (!desc
->byte_code
)
172 FIXME("Failed to parse shader, hr %#x.\n", hr
);
173 free_shader_desc(desc
);
179 static const char *shader_get_string(const char *data
, size_t data_size
, DWORD offset
)
183 if (offset
>= data_size
)
185 WARN("Invalid offset %#x (data size %#lx).\n", offset
, (long)data_size
);
189 max_len
= data_size
- offset
;
190 len
= strnlen(data
+ offset
, max_len
);
195 return data
+ offset
;
198 HRESULT
shader_parse_signature(DWORD tag
, const char *data
, DWORD data_size
,
199 struct wined3d_shader_signature
*s
)
201 struct wined3d_shader_signature_element
*e
;
202 const char *ptr
= data
;
206 if (!require_space(0, 2, sizeof(DWORD
), data_size
))
208 WARN("Invalid data size %#x.\n", data_size
);
212 read_dword(&ptr
, &count
);
213 TRACE("%u elements.\n", count
);
215 skip_dword_unknown(&ptr
, 1); /* It seems to always be 0x00000008. */
217 if (!require_space(ptr
- data
, count
, 6 * sizeof(DWORD
), data_size
))
219 WARN("Invalid count %#x (data size %#x).\n", count
, data_size
);
223 if (!(e
= heap_calloc(count
, sizeof(*e
))))
225 ERR("Failed to allocate input signature memory.\n");
226 return E_OUTOFMEMORY
;
229 for (i
= 0; i
< count
; ++i
)
234 read_dword(&ptr
, &e
[i
].stream_idx
);
237 read_dword(&ptr
, &name_offset
);
238 if (!(e
[i
].semantic_name
= shader_get_string(data
, data_size
, name_offset
)))
240 WARN("Invalid name offset %#x (data size %#x).\n", name_offset
, data_size
);
244 read_dword(&ptr
, &e
[i
].semantic_idx
);
245 read_dword(&ptr
, &e
[i
].sysval_semantic
);
246 read_dword(&ptr
, &e
[i
].component_type
);
247 read_dword(&ptr
, &e
[i
].register_idx
);
248 read_dword(&ptr
, &e
[i
].mask
);
250 TRACE("Stream: %u, semantic: %s, semantic idx: %u, sysval_semantic %#x, "
251 "type %u, register idx: %u, use_mask %#x, input_mask %#x.\n",
252 e
[i
].stream_idx
, debugstr_a(e
[i
].semantic_name
), e
[i
].semantic_idx
, e
[i
].sysval_semantic
,
253 e
[i
].component_type
, e
[i
].register_idx
, (e
[i
].mask
>> 8) & 0xff, e
[i
].mask
& 0xff);
257 s
->element_count
= count
;
262 struct wined3d_shader_signature_element
*shader_find_signature_element(const struct wined3d_shader_signature
*s
,
263 const char *semantic_name
, unsigned int semantic_idx
, unsigned int stream_idx
)
265 struct wined3d_shader_signature_element
*e
= s
->elements
;
268 for (i
= 0; i
< s
->element_count
; ++i
)
270 if (!strcasecmp(e
[i
].semantic_name
, semantic_name
) && e
[i
].semantic_idx
== semantic_idx
271 && e
[i
].stream_idx
== stream_idx
)
278 void shader_free_signature(struct wined3d_shader_signature
*s
)
280 heap_free(s
->elements
);
283 /* ID3D11VertexShader methods */
285 static inline struct d3d_vertex_shader
*impl_from_ID3D11VertexShader(ID3D11VertexShader
*iface
)
287 return CONTAINING_RECORD(iface
, struct d3d_vertex_shader
, ID3D11VertexShader_iface
);
290 static HRESULT STDMETHODCALLTYPE
d3d11_vertex_shader_QueryInterface(ID3D11VertexShader
*iface
,
291 REFIID riid
, void **object
)
293 struct d3d_vertex_shader
*shader
= impl_from_ID3D11VertexShader(iface
);
295 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
297 if (IsEqualGUID(riid
, &IID_ID3D11VertexShader
)
298 || IsEqualGUID(riid
, &IID_ID3D11DeviceChild
)
299 || IsEqualGUID(riid
, &IID_IUnknown
))
301 ID3D11VertexShader_AddRef(iface
);
306 if (IsEqualGUID(riid
, &IID_ID3D10VertexShader
)
307 || IsEqualGUID(riid
, &IID_ID3D10DeviceChild
))
309 IUnknown_AddRef(&shader
->ID3D10VertexShader_iface
);
310 *object
= &shader
->ID3D10VertexShader_iface
;
314 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
317 return E_NOINTERFACE
;
320 static ULONG STDMETHODCALLTYPE
d3d11_vertex_shader_AddRef(ID3D11VertexShader
*iface
)
322 struct d3d_vertex_shader
*shader
= impl_from_ID3D11VertexShader(iface
);
323 ULONG refcount
= InterlockedIncrement(&shader
->refcount
);
325 TRACE("%p increasing refcount to %u.\n", shader
, refcount
);
329 ID3D11Device_AddRef(shader
->device
);
330 wined3d_mutex_lock();
331 wined3d_shader_incref(shader
->wined3d_shader
);
332 wined3d_mutex_unlock();
338 static ULONG STDMETHODCALLTYPE
d3d11_vertex_shader_Release(ID3D11VertexShader
*iface
)
340 struct d3d_vertex_shader
*shader
= impl_from_ID3D11VertexShader(iface
);
341 ULONG refcount
= InterlockedDecrement(&shader
->refcount
);
343 TRACE("%p decreasing refcount to %u.\n", shader
, refcount
);
347 ID3D11Device
*device
= shader
->device
;
349 wined3d_mutex_lock();
350 wined3d_shader_decref(shader
->wined3d_shader
);
351 wined3d_mutex_unlock();
352 /* Release the device last, it may cause the wined3d device to be
354 ID3D11Device_Release(device
);
360 static void STDMETHODCALLTYPE
d3d11_vertex_shader_GetDevice(ID3D11VertexShader
*iface
,
361 ID3D11Device
**device
)
363 struct d3d_vertex_shader
*shader
= impl_from_ID3D11VertexShader(iface
);
365 TRACE("iface %p, device %p.\n", iface
, device
);
367 *device
= shader
->device
;
368 ID3D11Device_AddRef(*device
);
371 static HRESULT STDMETHODCALLTYPE
d3d11_vertex_shader_GetPrivateData(ID3D11VertexShader
*iface
,
372 REFGUID guid
, UINT
*data_size
, void *data
)
374 struct d3d_vertex_shader
*shader
= impl_from_ID3D11VertexShader(iface
);
376 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
378 return d3d_get_private_data(&shader
->private_store
, guid
, data_size
, data
);
381 static HRESULT STDMETHODCALLTYPE
d3d11_vertex_shader_SetPrivateData(ID3D11VertexShader
*iface
,
382 REFGUID guid
, UINT data_size
, const void *data
)
384 struct d3d_vertex_shader
*shader
= impl_from_ID3D11VertexShader(iface
);
386 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
388 return d3d_set_private_data(&shader
->private_store
, guid
, data_size
, data
);
391 static HRESULT STDMETHODCALLTYPE
d3d11_vertex_shader_SetPrivateDataInterface(ID3D11VertexShader
*iface
,
392 REFGUID guid
, const IUnknown
*data
)
394 struct d3d_vertex_shader
*shader
= impl_from_ID3D11VertexShader(iface
);
396 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
398 return d3d_set_private_data_interface(&shader
->private_store
, guid
, data
);
401 static const struct ID3D11VertexShaderVtbl d3d11_vertex_shader_vtbl
=
403 /* IUnknown methods */
404 d3d11_vertex_shader_QueryInterface
,
405 d3d11_vertex_shader_AddRef
,
406 d3d11_vertex_shader_Release
,
407 /* ID3D11DeviceChild methods */
408 d3d11_vertex_shader_GetDevice
,
409 d3d11_vertex_shader_GetPrivateData
,
410 d3d11_vertex_shader_SetPrivateData
,
411 d3d11_vertex_shader_SetPrivateDataInterface
,
414 /* ID3D10VertexShader methods */
416 static inline struct d3d_vertex_shader
*impl_from_ID3D10VertexShader(ID3D10VertexShader
*iface
)
418 return CONTAINING_RECORD(iface
, struct d3d_vertex_shader
, ID3D10VertexShader_iface
);
421 /* IUnknown methods */
423 static HRESULT STDMETHODCALLTYPE
d3d10_vertex_shader_QueryInterface(ID3D10VertexShader
*iface
,
424 REFIID riid
, void **object
)
426 struct d3d_vertex_shader
*shader
= impl_from_ID3D10VertexShader(iface
);
428 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
430 return d3d11_vertex_shader_QueryInterface(&shader
->ID3D11VertexShader_iface
, riid
, object
);
433 static ULONG STDMETHODCALLTYPE
d3d10_vertex_shader_AddRef(ID3D10VertexShader
*iface
)
435 struct d3d_vertex_shader
*shader
= impl_from_ID3D10VertexShader(iface
);
437 TRACE("iface %p.\n", iface
);
439 return d3d11_vertex_shader_AddRef(&shader
->ID3D11VertexShader_iface
);
442 static ULONG STDMETHODCALLTYPE
d3d10_vertex_shader_Release(ID3D10VertexShader
*iface
)
444 struct d3d_vertex_shader
*shader
= impl_from_ID3D10VertexShader(iface
);
446 TRACE("iface %p.\n", iface
);
448 return d3d11_vertex_shader_Release(&shader
->ID3D11VertexShader_iface
);
451 /* ID3D10DeviceChild methods */
453 static void STDMETHODCALLTYPE
d3d10_vertex_shader_GetDevice(ID3D10VertexShader
*iface
, ID3D10Device
**device
)
455 struct d3d_vertex_shader
*shader
= impl_from_ID3D10VertexShader(iface
);
457 TRACE("iface %p, device %p.\n", iface
, device
);
459 ID3D11Device_QueryInterface(shader
->device
, &IID_ID3D10Device
, (void **)device
);
462 static HRESULT STDMETHODCALLTYPE
d3d10_vertex_shader_GetPrivateData(ID3D10VertexShader
*iface
,
463 REFGUID guid
, UINT
*data_size
, void *data
)
465 struct d3d_vertex_shader
*shader
= impl_from_ID3D10VertexShader(iface
);
467 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
468 iface
, debugstr_guid(guid
), data_size
, data
);
470 return d3d_get_private_data(&shader
->private_store
, guid
, data_size
, data
);
473 static HRESULT STDMETHODCALLTYPE
d3d10_vertex_shader_SetPrivateData(ID3D10VertexShader
*iface
,
474 REFGUID guid
, UINT data_size
, const void *data
)
476 struct d3d_vertex_shader
*shader
= impl_from_ID3D10VertexShader(iface
);
478 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
479 iface
, debugstr_guid(guid
), data_size
, data
);
481 return d3d_set_private_data(&shader
->private_store
, guid
, data_size
, data
);
484 static HRESULT STDMETHODCALLTYPE
d3d10_vertex_shader_SetPrivateDataInterface(ID3D10VertexShader
*iface
,
485 REFGUID guid
, const IUnknown
*data
)
487 struct d3d_vertex_shader
*shader
= impl_from_ID3D10VertexShader(iface
);
489 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
491 return d3d_set_private_data_interface(&shader
->private_store
, guid
, data
);
494 static const struct ID3D10VertexShaderVtbl d3d10_vertex_shader_vtbl
=
496 /* IUnknown methods */
497 d3d10_vertex_shader_QueryInterface
,
498 d3d10_vertex_shader_AddRef
,
499 d3d10_vertex_shader_Release
,
500 /* ID3D10DeviceChild methods */
501 d3d10_vertex_shader_GetDevice
,
502 d3d10_vertex_shader_GetPrivateData
,
503 d3d10_vertex_shader_SetPrivateData
,
504 d3d10_vertex_shader_SetPrivateDataInterface
,
507 static void STDMETHODCALLTYPE
d3d_vertex_shader_wined3d_object_destroyed(void *parent
)
509 struct d3d_vertex_shader
*shader
= parent
;
511 wined3d_private_store_cleanup(&shader
->private_store
);
515 static const struct wined3d_parent_ops d3d_vertex_shader_wined3d_parent_ops
=
517 d3d_vertex_shader_wined3d_object_destroyed
,
520 static unsigned int d3d_sm_from_feature_level(D3D_FEATURE_LEVEL feature_level
)
522 switch (feature_level
)
524 case D3D_FEATURE_LEVEL_11_1
:
525 case D3D_FEATURE_LEVEL_11_0
:
527 case D3D_FEATURE_LEVEL_10_1
:
528 case D3D_FEATURE_LEVEL_10_0
:
530 case D3D_FEATURE_LEVEL_9_3
:
532 case D3D_FEATURE_LEVEL_9_2
:
533 case D3D_FEATURE_LEVEL_9_1
:
536 ERR("Unexpected feature_level %#x.\n", feature_level
);
541 static HRESULT
d3d_vertex_shader_init(struct d3d_vertex_shader
*shader
, struct d3d_device
*device
,
542 const void *byte_code
, SIZE_T byte_code_length
)
544 struct wined3d_shader_desc desc
;
547 shader
->ID3D11VertexShader_iface
.lpVtbl
= &d3d11_vertex_shader_vtbl
;
548 shader
->ID3D10VertexShader_iface
.lpVtbl
= &d3d10_vertex_shader_vtbl
;
549 shader
->refcount
= 1;
550 wined3d_mutex_lock();
551 wined3d_private_store_init(&shader
->private_store
);
553 if (FAILED(hr
= shader_extract_from_dxbc(byte_code
, byte_code_length
, &desc
, device
->feature_level
)))
555 WARN("Failed to extract shader, hr %#x.\n", hr
);
556 wined3d_private_store_cleanup(&shader
->private_store
);
557 wined3d_mutex_unlock();
560 desc
.max_version
= d3d_sm_from_feature_level(device
->feature_level
);
562 hr
= wined3d_shader_create_vs(device
->wined3d_device
, &desc
, shader
,
563 &d3d_vertex_shader_wined3d_parent_ops
, &shader
->wined3d_shader
);
564 free_shader_desc(&desc
);
567 WARN("Failed to create wined3d vertex shader, hr %#x.\n", hr
);
568 wined3d_private_store_cleanup(&shader
->private_store
);
569 wined3d_mutex_unlock();
572 wined3d_mutex_unlock();
574 shader
->device
= &device
->ID3D11Device_iface
;
575 ID3D11Device_AddRef(shader
->device
);
580 HRESULT
d3d_vertex_shader_create(struct d3d_device
*device
, const void *byte_code
, SIZE_T byte_code_length
,
581 struct d3d_vertex_shader
**shader
)
583 struct d3d_vertex_shader
*object
;
586 if (!(object
= heap_alloc_zero(sizeof(*object
))))
587 return E_OUTOFMEMORY
;
589 if (FAILED(hr
= d3d_vertex_shader_init(object
, device
, byte_code
, byte_code_length
)))
591 WARN("Failed to initialize vertex shader, hr %#x.\n", hr
);
596 TRACE("Created vertex shader %p.\n", object
);
602 struct d3d_vertex_shader
*unsafe_impl_from_ID3D11VertexShader(ID3D11VertexShader
*iface
)
606 assert(iface
->lpVtbl
== &d3d11_vertex_shader_vtbl
);
608 return impl_from_ID3D11VertexShader(iface
);
611 struct d3d_vertex_shader
*unsafe_impl_from_ID3D10VertexShader(ID3D10VertexShader
*iface
)
615 assert(iface
->lpVtbl
== &d3d10_vertex_shader_vtbl
);
617 return impl_from_ID3D10VertexShader(iface
);
620 /* ID3D11HullShader methods */
622 static inline struct d3d11_hull_shader
*impl_from_ID3D11HullShader(ID3D11HullShader
*iface
)
624 return CONTAINING_RECORD(iface
, struct d3d11_hull_shader
, ID3D11HullShader_iface
);
627 static HRESULT STDMETHODCALLTYPE
d3d11_hull_shader_QueryInterface(ID3D11HullShader
*iface
,
628 REFIID riid
, void **object
)
630 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
632 if (IsEqualGUID(riid
, &IID_ID3D11HullShader
)
633 || IsEqualGUID(riid
, &IID_ID3D11DeviceChild
)
634 || IsEqualGUID(riid
, &IID_IUnknown
))
636 ID3D11HullShader_AddRef(iface
);
641 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
644 return E_NOINTERFACE
;
647 static ULONG STDMETHODCALLTYPE
d3d11_hull_shader_AddRef(ID3D11HullShader
*iface
)
649 struct d3d11_hull_shader
*shader
= impl_from_ID3D11HullShader(iface
);
650 ULONG refcount
= InterlockedIncrement(&shader
->refcount
);
652 TRACE("%p increasing refcount to %u.\n", shader
, refcount
);
656 ID3D11Device_AddRef(shader
->device
);
657 wined3d_mutex_lock();
658 wined3d_shader_incref(shader
->wined3d_shader
);
659 wined3d_mutex_unlock();
665 static ULONG STDMETHODCALLTYPE
d3d11_hull_shader_Release(ID3D11HullShader
*iface
)
667 struct d3d11_hull_shader
*shader
= impl_from_ID3D11HullShader(iface
);
668 ULONG refcount
= InterlockedDecrement(&shader
->refcount
);
670 TRACE("%p decreasing refcount to %u.\n", shader
, refcount
);
674 ID3D11Device
*device
= shader
->device
;
676 wined3d_mutex_lock();
677 wined3d_shader_decref(shader
->wined3d_shader
);
678 wined3d_mutex_unlock();
680 /* Release the device last, it may cause the wined3d device to be
682 ID3D11Device_Release(device
);
688 static void STDMETHODCALLTYPE
d3d11_hull_shader_GetDevice(ID3D11HullShader
*iface
,
689 ID3D11Device
**device
)
691 struct d3d11_hull_shader
*shader
= impl_from_ID3D11HullShader(iface
);
693 TRACE("iface %p, device %p.\n", iface
, device
);
695 *device
= shader
->device
;
696 ID3D11Device_AddRef(*device
);
699 static HRESULT STDMETHODCALLTYPE
d3d11_hull_shader_GetPrivateData(ID3D11HullShader
*iface
,
700 REFGUID guid
, UINT
*data_size
, void *data
)
702 struct d3d11_hull_shader
*shader
= impl_from_ID3D11HullShader(iface
);
704 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
706 return d3d_get_private_data(&shader
->private_store
, guid
, data_size
, data
);
709 static HRESULT STDMETHODCALLTYPE
d3d11_hull_shader_SetPrivateData(ID3D11HullShader
*iface
,
710 REFGUID guid
, UINT data_size
, const void *data
)
712 struct d3d11_hull_shader
*shader
= impl_from_ID3D11HullShader(iface
);
714 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
716 return d3d_set_private_data(&shader
->private_store
, guid
, data_size
, data
);
719 static HRESULT STDMETHODCALLTYPE
d3d11_hull_shader_SetPrivateDataInterface(ID3D11HullShader
*iface
,
720 REFGUID guid
, const IUnknown
*data
)
722 struct d3d11_hull_shader
*shader
= impl_from_ID3D11HullShader(iface
);
724 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
726 return d3d_set_private_data_interface(&shader
->private_store
, guid
, data
);
729 static const struct ID3D11HullShaderVtbl d3d11_hull_shader_vtbl
=
731 /* IUnknown methods */
732 d3d11_hull_shader_QueryInterface
,
733 d3d11_hull_shader_AddRef
,
734 d3d11_hull_shader_Release
,
735 /* ID3D11DeviceChild methods */
736 d3d11_hull_shader_GetDevice
,
737 d3d11_hull_shader_GetPrivateData
,
738 d3d11_hull_shader_SetPrivateData
,
739 d3d11_hull_shader_SetPrivateDataInterface
,
742 static void STDMETHODCALLTYPE
d3d11_hull_shader_wined3d_object_destroyed(void *parent
)
744 struct d3d11_hull_shader
*shader
= parent
;
746 wined3d_private_store_cleanup(&shader
->private_store
);
750 static const struct wined3d_parent_ops d3d11_hull_shader_wined3d_parent_ops
=
752 d3d11_hull_shader_wined3d_object_destroyed
,
755 static HRESULT
d3d11_hull_shader_init(struct d3d11_hull_shader
*shader
, struct d3d_device
*device
,
756 const void *byte_code
, SIZE_T byte_code_length
)
758 struct wined3d_shader_desc desc
;
761 shader
->ID3D11HullShader_iface
.lpVtbl
= &d3d11_hull_shader_vtbl
;
762 shader
->refcount
= 1;
763 wined3d_mutex_lock();
764 wined3d_private_store_init(&shader
->private_store
);
766 if (FAILED(hr
= shader_extract_from_dxbc(byte_code
, byte_code_length
, &desc
, device
->feature_level
)))
768 WARN("Failed to extract shader, hr %#x.\n", hr
);
769 wined3d_private_store_cleanup(&shader
->private_store
);
770 wined3d_mutex_unlock();
773 desc
.max_version
= d3d_sm_from_feature_level(device
->feature_level
);
775 hr
= wined3d_shader_create_hs(device
->wined3d_device
, &desc
, shader
,
776 &d3d11_hull_shader_wined3d_parent_ops
, &shader
->wined3d_shader
);
777 free_shader_desc(&desc
);
780 WARN("Failed to create wined3d hull shader, hr %#x.\n", hr
);
781 wined3d_private_store_cleanup(&shader
->private_store
);
782 wined3d_mutex_unlock();
785 wined3d_mutex_unlock();
787 shader
->device
= &device
->ID3D11Device_iface
;
788 ID3D11Device_AddRef(shader
->device
);
793 HRESULT
d3d11_hull_shader_create(struct d3d_device
*device
, const void *byte_code
, SIZE_T byte_code_length
,
794 struct d3d11_hull_shader
**shader
)
796 struct d3d11_hull_shader
*object
;
799 if (!(object
= heap_alloc_zero(sizeof(*object
))))
800 return E_OUTOFMEMORY
;
802 if (FAILED(hr
= d3d11_hull_shader_init(object
, device
, byte_code
, byte_code_length
)))
808 TRACE("Created hull shader %p.\n", object
);
814 struct d3d11_hull_shader
*unsafe_impl_from_ID3D11HullShader(ID3D11HullShader
*iface
)
818 assert(iface
->lpVtbl
== &d3d11_hull_shader_vtbl
);
820 return impl_from_ID3D11HullShader(iface
);
823 /* ID3D11DomainShader methods */
825 static inline struct d3d11_domain_shader
*impl_from_ID3D11DomainShader(ID3D11DomainShader
*iface
)
827 return CONTAINING_RECORD(iface
, struct d3d11_domain_shader
, ID3D11DomainShader_iface
);
830 static HRESULT STDMETHODCALLTYPE
d3d11_domain_shader_QueryInterface(ID3D11DomainShader
*iface
,
831 REFIID riid
, void **object
)
833 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
835 if (IsEqualGUID(riid
, &IID_ID3D11DomainShader
)
836 || IsEqualGUID(riid
, &IID_ID3D11DeviceChild
)
837 || IsEqualGUID(riid
, &IID_IUnknown
))
839 ID3D11DomainShader_AddRef(iface
);
844 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
847 return E_NOINTERFACE
;
850 static ULONG STDMETHODCALLTYPE
d3d11_domain_shader_AddRef(ID3D11DomainShader
*iface
)
852 struct d3d11_domain_shader
*shader
= impl_from_ID3D11DomainShader(iface
);
853 ULONG refcount
= InterlockedIncrement(&shader
->refcount
);
855 TRACE("%p increasing refcount to %u.\n", shader
, refcount
);
859 ID3D11Device_AddRef(shader
->device
);
860 wined3d_mutex_lock();
861 wined3d_shader_incref(shader
->wined3d_shader
);
862 wined3d_mutex_unlock();
868 static ULONG STDMETHODCALLTYPE
d3d11_domain_shader_Release(ID3D11DomainShader
*iface
)
870 struct d3d11_domain_shader
*shader
= impl_from_ID3D11DomainShader(iface
);
871 ULONG refcount
= InterlockedDecrement(&shader
->refcount
);
873 TRACE("%p decreasing refcount to %u.\n", shader
, refcount
);
877 ID3D11Device
*device
= shader
->device
;
879 wined3d_mutex_lock();
880 wined3d_shader_decref(shader
->wined3d_shader
);
881 wined3d_mutex_unlock();
883 /* Release the device last, it may cause the wined3d device to be
885 ID3D11Device_Release(device
);
891 static void STDMETHODCALLTYPE
d3d11_domain_shader_GetDevice(ID3D11DomainShader
*iface
,
892 ID3D11Device
**device
)
894 struct d3d11_domain_shader
*shader
= impl_from_ID3D11DomainShader(iface
);
896 TRACE("iface %p, device %p.\n", iface
, device
);
898 *device
= shader
->device
;
899 ID3D11Device_AddRef(*device
);
902 static HRESULT STDMETHODCALLTYPE
d3d11_domain_shader_GetPrivateData(ID3D11DomainShader
*iface
,
903 REFGUID guid
, UINT
*data_size
, void *data
)
905 struct d3d11_domain_shader
*shader
= impl_from_ID3D11DomainShader(iface
);
907 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
909 return d3d_get_private_data(&shader
->private_store
, guid
, data_size
, data
);
912 static HRESULT STDMETHODCALLTYPE
d3d11_domain_shader_SetPrivateData(ID3D11DomainShader
*iface
,
913 REFGUID guid
, UINT data_size
, const void *data
)
915 struct d3d11_domain_shader
*shader
= impl_from_ID3D11DomainShader(iface
);
917 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
919 return d3d_set_private_data(&shader
->private_store
, guid
, data_size
, data
);
922 static HRESULT STDMETHODCALLTYPE
d3d11_domain_shader_SetPrivateDataInterface(ID3D11DomainShader
*iface
,
923 REFGUID guid
, const IUnknown
*data
)
925 struct d3d11_domain_shader
*shader
= impl_from_ID3D11DomainShader(iface
);
927 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
929 return d3d_set_private_data_interface(&shader
->private_store
, guid
, data
);
932 static const struct ID3D11DomainShaderVtbl d3d11_domain_shader_vtbl
=
934 /* IUnknown methods */
935 d3d11_domain_shader_QueryInterface
,
936 d3d11_domain_shader_AddRef
,
937 d3d11_domain_shader_Release
,
938 /* ID3D11DeviceChild methods */
939 d3d11_domain_shader_GetDevice
,
940 d3d11_domain_shader_GetPrivateData
,
941 d3d11_domain_shader_SetPrivateData
,
942 d3d11_domain_shader_SetPrivateDataInterface
,
945 static void STDMETHODCALLTYPE
d3d11_domain_shader_wined3d_object_destroyed(void *parent
)
947 struct d3d11_domain_shader
*shader
= parent
;
949 wined3d_private_store_cleanup(&shader
->private_store
);
953 static const struct wined3d_parent_ops d3d11_domain_shader_wined3d_parent_ops
=
955 d3d11_domain_shader_wined3d_object_destroyed
,
958 static HRESULT
d3d11_domain_shader_init(struct d3d11_domain_shader
*shader
, struct d3d_device
*device
,
959 const void *byte_code
, SIZE_T byte_code_length
)
961 struct wined3d_shader_desc desc
;
964 shader
->ID3D11DomainShader_iface
.lpVtbl
= &d3d11_domain_shader_vtbl
;
965 shader
->refcount
= 1;
966 wined3d_mutex_lock();
967 wined3d_private_store_init(&shader
->private_store
);
969 if (FAILED(hr
= shader_extract_from_dxbc(byte_code
, byte_code_length
, &desc
, device
->feature_level
)))
971 WARN("Failed to extract shader, hr %#x.\n", hr
);
972 wined3d_private_store_cleanup(&shader
->private_store
);
973 wined3d_mutex_unlock();
976 desc
.max_version
= d3d_sm_from_feature_level(device
->feature_level
);
978 hr
= wined3d_shader_create_ds(device
->wined3d_device
, &desc
, shader
,
979 &d3d11_domain_shader_wined3d_parent_ops
, &shader
->wined3d_shader
);
980 free_shader_desc(&desc
);
983 WARN("Failed to create wined3d domain shader, hr %#x.\n", hr
);
984 wined3d_private_store_cleanup(&shader
->private_store
);
985 wined3d_mutex_unlock();
988 wined3d_mutex_unlock();
990 shader
->device
= &device
->ID3D11Device_iface
;
991 ID3D11Device_AddRef(shader
->device
);
996 HRESULT
d3d11_domain_shader_create(struct d3d_device
*device
, const void *byte_code
, SIZE_T byte_code_length
,
997 struct d3d11_domain_shader
**shader
)
999 struct d3d11_domain_shader
*object
;
1002 if (!(object
= heap_alloc_zero(sizeof(*object
))))
1003 return E_OUTOFMEMORY
;
1005 if (FAILED(hr
= d3d11_domain_shader_init(object
, device
, byte_code
, byte_code_length
)))
1011 TRACE("Created domain shader %p.\n", object
);
1017 struct d3d11_domain_shader
*unsafe_impl_from_ID3D11DomainShader(ID3D11DomainShader
*iface
)
1021 assert(iface
->lpVtbl
== &d3d11_domain_shader_vtbl
);
1023 return impl_from_ID3D11DomainShader(iface
);
1026 /* ID3D11GeometryShader methods */
1028 static inline struct d3d_geometry_shader
*impl_from_ID3D11GeometryShader(ID3D11GeometryShader
*iface
)
1030 return CONTAINING_RECORD(iface
, struct d3d_geometry_shader
, ID3D11GeometryShader_iface
);
1033 static HRESULT STDMETHODCALLTYPE
d3d11_geometry_shader_QueryInterface(ID3D11GeometryShader
*iface
,
1034 REFIID riid
, void **object
)
1036 struct d3d_geometry_shader
*shader
= impl_from_ID3D11GeometryShader(iface
);
1038 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
1040 if (IsEqualGUID(riid
, &IID_ID3D11GeometryShader
)
1041 || IsEqualGUID(riid
, &IID_ID3D11DeviceChild
)
1042 || IsEqualGUID(riid
, &IID_IUnknown
))
1044 ID3D11GeometryShader_AddRef(iface
);
1049 if (IsEqualGUID(riid
, &IID_ID3D10GeometryShader
)
1050 || IsEqualGUID(riid
, &IID_ID3D10DeviceChild
))
1052 ID3D10GeometryShader_AddRef(&shader
->ID3D10GeometryShader_iface
);
1053 *object
= &shader
->ID3D10GeometryShader_iface
;
1057 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
1060 return E_NOINTERFACE
;
1063 static ULONG STDMETHODCALLTYPE
d3d11_geometry_shader_AddRef(ID3D11GeometryShader
*iface
)
1065 struct d3d_geometry_shader
*shader
= impl_from_ID3D11GeometryShader(iface
);
1066 ULONG refcount
= InterlockedIncrement(&shader
->refcount
);
1068 TRACE("%p increasing refcount to %u.\n", shader
, refcount
);
1072 ID3D11Device_AddRef(shader
->device
);
1073 wined3d_mutex_lock();
1074 wined3d_shader_incref(shader
->wined3d_shader
);
1075 wined3d_mutex_unlock();
1081 static ULONG STDMETHODCALLTYPE
d3d11_geometry_shader_Release(ID3D11GeometryShader
*iface
)
1083 struct d3d_geometry_shader
*shader
= impl_from_ID3D11GeometryShader(iface
);
1084 ULONG refcount
= InterlockedDecrement(&shader
->refcount
);
1086 TRACE("%p decreasing refcount to %u.\n", shader
, refcount
);
1090 ID3D11Device
*device
= shader
->device
;
1092 wined3d_mutex_lock();
1093 wined3d_shader_decref(shader
->wined3d_shader
);
1094 wined3d_mutex_unlock();
1096 /* Release the device last, it may cause the wined3d device to be
1098 ID3D11Device_Release(device
);
1104 static void STDMETHODCALLTYPE
d3d11_geometry_shader_GetDevice(ID3D11GeometryShader
*iface
,
1105 ID3D11Device
**device
)
1107 struct d3d_geometry_shader
*shader
= impl_from_ID3D11GeometryShader(iface
);
1109 TRACE("iface %p, device %p.\n", iface
, device
);
1111 *device
= shader
->device
;
1112 ID3D11Device_AddRef(*device
);
1115 static HRESULT STDMETHODCALLTYPE
d3d11_geometry_shader_GetPrivateData(ID3D11GeometryShader
*iface
,
1116 REFGUID guid
, UINT
*data_size
, void *data
)
1118 struct d3d_geometry_shader
*shader
= impl_from_ID3D11GeometryShader(iface
);
1120 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
1122 return d3d_get_private_data(&shader
->private_store
, guid
, data_size
, data
);
1125 static HRESULT STDMETHODCALLTYPE
d3d11_geometry_shader_SetPrivateData(ID3D11GeometryShader
*iface
,
1126 REFGUID guid
, UINT data_size
, const void *data
)
1128 struct d3d_geometry_shader
*shader
= impl_from_ID3D11GeometryShader(iface
);
1130 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
1132 return d3d_set_private_data(&shader
->private_store
, guid
, data_size
, data
);
1135 static HRESULT STDMETHODCALLTYPE
d3d11_geometry_shader_SetPrivateDataInterface(ID3D11GeometryShader
*iface
,
1136 REFGUID guid
, const IUnknown
*data
)
1138 struct d3d_geometry_shader
*shader
= impl_from_ID3D11GeometryShader(iface
);
1140 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
1142 return d3d_set_private_data_interface(&shader
->private_store
, guid
, data
);
1145 static const struct ID3D11GeometryShaderVtbl d3d11_geometry_shader_vtbl
=
1147 /* IUnknown methods */
1148 d3d11_geometry_shader_QueryInterface
,
1149 d3d11_geometry_shader_AddRef
,
1150 d3d11_geometry_shader_Release
,
1151 /* ID3D11DeviceChild methods */
1152 d3d11_geometry_shader_GetDevice
,
1153 d3d11_geometry_shader_GetPrivateData
,
1154 d3d11_geometry_shader_SetPrivateData
,
1155 d3d11_geometry_shader_SetPrivateDataInterface
,
1158 /* ID3D10GeometryShader methods */
1160 static inline struct d3d_geometry_shader
*impl_from_ID3D10GeometryShader(ID3D10GeometryShader
*iface
)
1162 return CONTAINING_RECORD(iface
, struct d3d_geometry_shader
, ID3D10GeometryShader_iface
);
1165 /* IUnknown methods */
1167 static HRESULT STDMETHODCALLTYPE
d3d10_geometry_shader_QueryInterface(ID3D10GeometryShader
*iface
,
1168 REFIID riid
, void **object
)
1170 struct d3d_geometry_shader
*shader
= impl_from_ID3D10GeometryShader(iface
);
1172 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
1174 return d3d11_geometry_shader_QueryInterface(&shader
->ID3D11GeometryShader_iface
, riid
, object
);
1177 static ULONG STDMETHODCALLTYPE
d3d10_geometry_shader_AddRef(ID3D10GeometryShader
*iface
)
1179 struct d3d_geometry_shader
*shader
= impl_from_ID3D10GeometryShader(iface
);
1181 TRACE("iface %p.\n", iface
);
1183 return d3d11_geometry_shader_AddRef(&shader
->ID3D11GeometryShader_iface
);
1186 static ULONG STDMETHODCALLTYPE
d3d10_geometry_shader_Release(ID3D10GeometryShader
*iface
)
1188 struct d3d_geometry_shader
*shader
= impl_from_ID3D10GeometryShader(iface
);
1190 TRACE("iface %p.\n", iface
);
1192 return d3d11_geometry_shader_Release(&shader
->ID3D11GeometryShader_iface
);
1195 /* ID3D10DeviceChild methods */
1197 static void STDMETHODCALLTYPE
d3d10_geometry_shader_GetDevice(ID3D10GeometryShader
*iface
, ID3D10Device
**device
)
1199 struct d3d_geometry_shader
*shader
= impl_from_ID3D10GeometryShader(iface
);
1201 TRACE("iface %p, device %p.\n", iface
, device
);
1203 ID3D11Device_QueryInterface(shader
->device
, &IID_ID3D10Device
, (void **)device
);
1206 static HRESULT STDMETHODCALLTYPE
d3d10_geometry_shader_GetPrivateData(ID3D10GeometryShader
*iface
,
1207 REFGUID guid
, UINT
*data_size
, void *data
)
1209 struct d3d_geometry_shader
*shader
= impl_from_ID3D10GeometryShader(iface
);
1211 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
1212 iface
, debugstr_guid(guid
), data_size
, data
);
1214 return d3d_get_private_data(&shader
->private_store
, guid
, data_size
, data
);
1217 static HRESULT STDMETHODCALLTYPE
d3d10_geometry_shader_SetPrivateData(ID3D10GeometryShader
*iface
,
1218 REFGUID guid
, UINT data_size
, const void *data
)
1220 struct d3d_geometry_shader
*shader
= impl_from_ID3D10GeometryShader(iface
);
1222 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
1223 iface
, debugstr_guid(guid
), data_size
, data
);
1225 return d3d_set_private_data(&shader
->private_store
, guid
, data_size
, data
);
1228 static HRESULT STDMETHODCALLTYPE
d3d10_geometry_shader_SetPrivateDataInterface(ID3D10GeometryShader
*iface
,
1229 REFGUID guid
, const IUnknown
*data
)
1231 struct d3d_geometry_shader
*shader
= impl_from_ID3D10GeometryShader(iface
);
1233 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
1235 return d3d_set_private_data_interface(&shader
->private_store
, guid
, data
);
1238 static const struct ID3D10GeometryShaderVtbl d3d10_geometry_shader_vtbl
=
1240 /* IUnknown methods */
1241 d3d10_geometry_shader_QueryInterface
,
1242 d3d10_geometry_shader_AddRef
,
1243 d3d10_geometry_shader_Release
,
1244 /* ID3D10DeviceChild methods */
1245 d3d10_geometry_shader_GetDevice
,
1246 d3d10_geometry_shader_GetPrivateData
,
1247 d3d10_geometry_shader_SetPrivateData
,
1248 d3d10_geometry_shader_SetPrivateDataInterface
,
1251 static void STDMETHODCALLTYPE
d3d_geometry_shader_wined3d_object_destroyed(void *parent
)
1253 struct d3d_geometry_shader
*shader
= parent
;
1255 wined3d_private_store_cleanup(&shader
->private_store
);
1259 static const struct wined3d_parent_ops d3d_geometry_shader_wined3d_parent_ops
=
1261 d3d_geometry_shader_wined3d_object_destroyed
,
1264 static HRESULT
wined3d_so_elements_from_d3d11_so_entries(struct wined3d_stream_output_element
*elements
,
1265 const D3D11_SO_DECLARATION_ENTRY
*entries
, unsigned int entry_count
,
1266 const unsigned int *buffer_strides
, unsigned int buffer_stride_count
,
1267 const struct wined3d_shader_signature
*os
, D3D_FEATURE_LEVEL feature_level
)
1269 unsigned int i
, j
, mask
;
1271 for (i
= 0; i
< entry_count
; ++i
)
1273 struct wined3d_stream_output_element
*e
= &elements
[i
];
1274 const D3D11_SO_DECLARATION_ENTRY
*f
= &entries
[i
];
1275 struct wined3d_shader_signature_element
*output
;
1277 TRACE("Stream: %u, semantic: %s, semantic idx: %u, start component: %u, "
1278 "component count %u, output slot %u.\n",
1279 f
->Stream
, debugstr_a(f
->SemanticName
), f
->SemanticIndex
,
1280 f
->StartComponent
, f
->ComponentCount
, f
->OutputSlot
);
1282 if (f
->Stream
>= D3D11_SO_STREAM_COUNT
)
1284 WARN("Invalid stream %u.\n", f
->Stream
);
1285 return E_INVALIDARG
;
1287 if (f
->Stream
&& feature_level
< D3D_FEATURE_LEVEL_11_0
)
1289 WARN("Invalid stream %u for feature level %#x.\n", f
->Stream
, feature_level
);
1290 return E_INVALIDARG
;
1294 FIXME("Streams not implemented yet.\n");
1295 return E_INVALIDARG
;
1297 if (f
->OutputSlot
>= D3D11_SO_BUFFER_SLOT_COUNT
)
1299 WARN("Invalid output slot %u.\n", f
->OutputSlot
);
1300 return E_INVALIDARG
;
1303 e
->stream_idx
= f
->Stream
;
1304 e
->component_idx
= f
->StartComponent
;
1305 e
->component_count
= f
->ComponentCount
;
1306 e
->output_slot
= f
->OutputSlot
;
1308 if (!f
->SemanticName
)
1310 if (f
->SemanticIndex
)
1312 WARN("Invalid semantic idx %u for stream output gap.\n", f
->SemanticIndex
);
1313 return E_INVALIDARG
;
1315 if (e
->component_idx
|| !e
->component_count
)
1317 WARN("Invalid stream output gap %u-%u.\n", e
->component_idx
, e
->component_count
);
1318 return E_INVALIDARG
;
1321 e
->register_idx
= WINED3D_STREAM_OUTPUT_GAP
;
1323 else if ((output
= shader_find_signature_element(os
, f
->SemanticName
, f
->SemanticIndex
, f
->Stream
)))
1325 if (e
->component_idx
> 3 || e
->component_count
> 4 || !e
->component_count
1326 || e
->component_idx
+ e
->component_count
> 4)
1328 WARN("Invalid component range %u-%u.\n", e
->component_idx
, e
->component_count
);
1329 return E_INVALIDARG
;
1332 for (j
= 0; j
< 4; ++j
)
1334 if ((1u << j
) & output
->mask
)
1337 e
->component_idx
+= j
;
1338 mask
= ((1u << e
->component_count
) - 1) << e
->component_idx
;
1339 if ((output
->mask
& 0xff & mask
) != mask
)
1341 WARN("Invalid component range %u-%u (mask %#x), output mask %#x.\n",
1342 e
->component_idx
, e
->component_count
, mask
, output
->mask
& 0xff);
1343 return E_INVALIDARG
;
1346 e
->register_idx
= output
->register_idx
;
1347 TRACE("Register idx: %u, register component idx %u, register mask %#x.\n",
1348 e
->register_idx
, e
->component_idx
, mask
);
1352 WARN("Failed to find output signature element for stream output entry.\n");
1353 return E_INVALIDARG
;
1357 for (i
= 0; i
< entry_count
; ++i
)
1359 const struct wined3d_stream_output_element
*e1
= &elements
[i
];
1360 if (e1
->register_idx
== WINED3D_STREAM_OUTPUT_GAP
)
1363 for (j
= i
+ 1; j
< entry_count
; ++j
)
1365 const struct wined3d_stream_output_element
*e2
= &elements
[j
];
1367 if (e1
->register_idx
== e2
->register_idx
1368 && e1
->component_idx
< e2
->component_idx
+ e2
->component_count
1369 && e1
->component_idx
+ e1
->component_count
> e2
->component_idx
)
1371 WARN("Stream output elements %u and %u overlap.\n", i
, j
);
1372 return E_INVALIDARG
;
1377 for (i
= 0; i
< D3D11_SO_STREAM_COUNT
; ++i
)
1379 unsigned int current_stride
[D3D11_SO_BUFFER_SLOT_COUNT
] = {0};
1380 unsigned int element_count
[D3D11_SO_BUFFER_SLOT_COUNT
] = {0};
1381 unsigned int gap_count
[D3D11_SO_BUFFER_SLOT_COUNT
] = {0};
1383 for (j
= 0; j
< entry_count
; ++j
)
1385 const struct wined3d_stream_output_element
*e
= &elements
[j
];
1387 if (e
->stream_idx
!= i
)
1389 current_stride
[e
->output_slot
] += 4 * e
->component_count
;
1390 ++element_count
[e
->output_slot
];
1391 if (e
->register_idx
== WINED3D_STREAM_OUTPUT_GAP
)
1392 ++gap_count
[e
->output_slot
];
1395 for (j
= 0; j
< D3D11_SO_BUFFER_SLOT_COUNT
; ++j
)
1397 if (!element_count
[j
])
1399 if (element_count
[j
] == gap_count
[j
])
1401 WARN("Stream %u, output slot %u contains only gaps.\n", i
, j
);
1402 return E_INVALIDARG
;
1404 if (buffer_stride_count
)
1406 if (buffer_stride_count
<= j
)
1408 WARN("Buffer strides are required for all buffer slots.\n");
1409 return E_INVALIDARG
;
1411 if (buffer_strides
[j
] < current_stride
[j
] || buffer_strides
[j
] % 4)
1413 WARN("Invalid stride %u for buffer slot %u.\n", buffer_strides
[j
], j
);
1414 return E_INVALIDARG
;
1419 if (!i
&& feature_level
< D3D_FEATURE_LEVEL_11_0
&& element_count
[0] != entry_count
)
1421 for (j
= 0; j
< ARRAY_SIZE(element_count
); ++j
)
1423 if (element_count
[j
] > 1)
1425 WARN("Only one element per output slot is allowed.\n");
1426 return E_INVALIDARG
;
1435 static HRESULT
d3d_geometry_shader_init(struct d3d_geometry_shader
*shader
,
1436 struct d3d_device
*device
, const void *byte_code
, SIZE_T byte_code_length
,
1437 const D3D11_SO_DECLARATION_ENTRY
*so_entries
, unsigned int so_entry_count
,
1438 const unsigned int *buffer_strides
, unsigned int buffer_stride_count
,
1439 unsigned int rasterizer_stream
)
1441 struct wined3d_stream_output_desc so_desc
;
1442 struct wined3d_shader_desc desc
;
1446 if (so_entry_count
> D3D11_SO_STREAM_COUNT
* D3D11_SO_OUTPUT_COMPONENT_COUNT
)
1448 WARN("Entry count %u is greater than %u.\n",
1449 so_entry_count
, D3D11_SO_STREAM_COUNT
* D3D11_SO_OUTPUT_COMPONENT_COUNT
);
1450 return E_INVALIDARG
;
1452 if (so_entries
&& !so_entry_count
)
1454 WARN("Invalid SO entry count %u.\n", so_entry_count
);
1455 return E_INVALIDARG
;
1457 if (rasterizer_stream
!= D3D11_SO_NO_RASTERIZED_STREAM
&& rasterizer_stream
>= D3D11_SO_STREAM_COUNT
)
1459 WARN("Invalid rasterizer stream %u.\n", rasterizer_stream
);
1460 return E_INVALIDARG
;
1462 if (device
->feature_level
< D3D_FEATURE_LEVEL_11_0
)
1464 if (rasterizer_stream
)
1466 WARN("Invalid rasterizer stream %u for feature level %#x.\n",
1467 rasterizer_stream
, device
->feature_level
);
1468 return E_INVALIDARG
;
1470 if (buffer_stride_count
&& buffer_stride_count
!= 1)
1472 WARN("Invalid buffer stride count %u for feature level %#x.\n",
1473 buffer_stride_count
, device
->feature_level
);
1474 return E_INVALIDARG
;
1478 if (FAILED(hr
= shader_extract_from_dxbc(byte_code
, byte_code_length
, &desc
, device
->feature_level
)))
1480 WARN("Failed to extract shader, hr %#x.\n", hr
);
1483 desc
.max_version
= d3d_sm_from_feature_level(device
->feature_level
);
1485 memset(&so_desc
, 0, sizeof(so_desc
));
1488 so_desc
.element_count
= so_entry_count
;
1489 for (i
= 0; i
< min(buffer_stride_count
, ARRAY_SIZE(so_desc
.buffer_strides
)); ++i
)
1490 so_desc
.buffer_strides
[i
] = buffer_strides
[i
];
1491 so_desc
.buffer_stride_count
= buffer_stride_count
;
1492 so_desc
.rasterizer_stream_idx
= rasterizer_stream
;
1494 if (!(so_desc
.elements
= heap_calloc(so_entry_count
, sizeof(*so_desc
.elements
))))
1496 ERR("Failed to allocate wined3d stream output element array memory.\n");
1497 free_shader_desc(&desc
);
1498 return E_OUTOFMEMORY
;
1500 if (FAILED(hr
= wined3d_so_elements_from_d3d11_so_entries(so_desc
.elements
,
1501 so_entries
, so_entry_count
, buffer_strides
, buffer_stride_count
,
1502 &desc
.output_signature
, device
->feature_level
)))
1504 heap_free(so_desc
.elements
);
1505 free_shader_desc(&desc
);
1510 shader
->ID3D11GeometryShader_iface
.lpVtbl
= &d3d11_geometry_shader_vtbl
;
1511 shader
->ID3D10GeometryShader_iface
.lpVtbl
= &d3d10_geometry_shader_vtbl
;
1512 shader
->refcount
= 1;
1513 wined3d_mutex_lock();
1514 wined3d_private_store_init(&shader
->private_store
);
1516 hr
= wined3d_shader_create_gs(device
->wined3d_device
, &desc
, so_entries
? &so_desc
: NULL
,
1517 shader
, &d3d_geometry_shader_wined3d_parent_ops
, &shader
->wined3d_shader
);
1518 heap_free(so_desc
.elements
);
1519 free_shader_desc(&desc
);
1522 WARN("Failed to create wined3d geometry shader, hr %#x.\n", hr
);
1523 wined3d_private_store_cleanup(&shader
->private_store
);
1524 wined3d_mutex_unlock();
1525 return E_INVALIDARG
;
1527 wined3d_mutex_unlock();
1529 shader
->device
= &device
->ID3D11Device_iface
;
1530 ID3D11Device_AddRef(shader
->device
);
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 ID3D11Device_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 ID3D11Device
*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 ID3D11Device_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
= 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 ID3D11Device_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 shader
->device
= &device
->ID3D11Device_iface
;
1849 ID3D11Device_AddRef(shader
->device
);
1854 HRESULT
d3d_pixel_shader_create(struct d3d_device
*device
, const void *byte_code
, SIZE_T byte_code_length
,
1855 struct d3d_pixel_shader
**shader
)
1857 struct d3d_pixel_shader
*object
;
1860 if (!(object
= heap_alloc_zero(sizeof(*object
))))
1861 return E_OUTOFMEMORY
;
1863 if (FAILED(hr
= d3d_pixel_shader_init(object
, device
, byte_code
, byte_code_length
)))
1865 WARN("Failed to initialize pixel shader, hr %#x.\n", hr
);
1870 TRACE("Created pixel shader %p.\n", object
);
1876 struct d3d_pixel_shader
*unsafe_impl_from_ID3D11PixelShader(ID3D11PixelShader
*iface
)
1880 assert(iface
->lpVtbl
== &d3d11_pixel_shader_vtbl
);
1882 return impl_from_ID3D11PixelShader(iface
);
1885 struct d3d_pixel_shader
*unsafe_impl_from_ID3D10PixelShader(ID3D10PixelShader
*iface
)
1889 assert(iface
->lpVtbl
== &d3d10_pixel_shader_vtbl
);
1891 return impl_from_ID3D10PixelShader(iface
);
1894 /* ID3D11ComputeShader methods */
1896 static inline struct d3d11_compute_shader
*impl_from_ID3D11ComputeShader(ID3D11ComputeShader
*iface
)
1898 return CONTAINING_RECORD(iface
, struct d3d11_compute_shader
, ID3D11ComputeShader_iface
);
1901 static HRESULT STDMETHODCALLTYPE
d3d11_compute_shader_QueryInterface(ID3D11ComputeShader
*iface
,
1902 REFIID riid
, void **object
)
1904 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
1906 if (IsEqualGUID(riid
, &IID_ID3D11ComputeShader
)
1907 || IsEqualGUID(riid
, &IID_ID3D11DeviceChild
)
1908 || IsEqualGUID(riid
, &IID_IUnknown
))
1910 ID3D11ComputeShader_AddRef(*object
= iface
);
1914 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
1917 return E_NOINTERFACE
;
1920 static ULONG STDMETHODCALLTYPE
d3d11_compute_shader_AddRef(ID3D11ComputeShader
*iface
)
1922 struct d3d11_compute_shader
*shader
= impl_from_ID3D11ComputeShader(iface
);
1923 ULONG refcount
= InterlockedIncrement(&shader
->refcount
);
1925 TRACE("%p increasing refcount to %u.\n", shader
, refcount
);
1929 ID3D11Device_AddRef(shader
->device
);
1930 wined3d_mutex_lock();
1931 wined3d_shader_incref(shader
->wined3d_shader
);
1932 wined3d_mutex_unlock();
1938 static ULONG STDMETHODCALLTYPE
d3d11_compute_shader_Release(ID3D11ComputeShader
*iface
)
1940 struct d3d11_compute_shader
*shader
= impl_from_ID3D11ComputeShader(iface
);
1941 ULONG refcount
= InterlockedDecrement(&shader
->refcount
);
1943 TRACE("%p decreasing refcount to %u.\n", shader
, refcount
);
1947 ID3D11Device
*device
= shader
->device
;
1949 wined3d_mutex_lock();
1950 wined3d_shader_decref(shader
->wined3d_shader
);
1951 wined3d_mutex_unlock();
1953 /* Release the device last, it may cause the wined3d device to be
1955 ID3D11Device_Release(device
);
1961 static void STDMETHODCALLTYPE
d3d11_compute_shader_GetDevice(ID3D11ComputeShader
*iface
,
1962 ID3D11Device
**device
)
1964 struct d3d11_compute_shader
*shader
= impl_from_ID3D11ComputeShader(iface
);
1966 TRACE("iface %p, device %p.\n", iface
, device
);
1968 ID3D11Device_AddRef(*device
= shader
->device
);
1971 static HRESULT STDMETHODCALLTYPE
d3d11_compute_shader_GetPrivateData(ID3D11ComputeShader
*iface
,
1972 REFGUID guid
, UINT
*data_size
, void *data
)
1974 struct d3d11_compute_shader
*shader
= impl_from_ID3D11ComputeShader(iface
);
1976 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
1978 return d3d_get_private_data(&shader
->private_store
, guid
, data_size
, data
);
1981 static HRESULT STDMETHODCALLTYPE
d3d11_compute_shader_SetPrivateData(ID3D11ComputeShader
*iface
,
1982 REFGUID guid
, UINT data_size
, const void *data
)
1984 struct d3d11_compute_shader
*shader
= impl_from_ID3D11ComputeShader(iface
);
1986 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
1988 return d3d_set_private_data(&shader
->private_store
, guid
, data_size
, data
);
1991 static HRESULT STDMETHODCALLTYPE
d3d11_compute_shader_SetPrivateDataInterface(ID3D11ComputeShader
*iface
,
1992 REFGUID guid
, const IUnknown
*data
)
1994 struct d3d11_compute_shader
*shader
= impl_from_ID3D11ComputeShader(iface
);
1996 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
1998 return d3d_set_private_data_interface(&shader
->private_store
, guid
, data
);
2001 static const struct ID3D11ComputeShaderVtbl d3d11_compute_shader_vtbl
=
2003 /* IUnknown methods */
2004 d3d11_compute_shader_QueryInterface
,
2005 d3d11_compute_shader_AddRef
,
2006 d3d11_compute_shader_Release
,
2007 /* ID3D11DeviceChild methods */
2008 d3d11_compute_shader_GetDevice
,
2009 d3d11_compute_shader_GetPrivateData
,
2010 d3d11_compute_shader_SetPrivateData
,
2011 d3d11_compute_shader_SetPrivateDataInterface
,
2014 static void STDMETHODCALLTYPE
d3d11_compute_shader_wined3d_object_destroyed(void *parent
)
2016 struct d3d11_compute_shader
*shader
= parent
;
2018 wined3d_private_store_cleanup(&shader
->private_store
);
2022 static const struct wined3d_parent_ops d3d11_compute_shader_wined3d_parent_ops
=
2024 d3d11_compute_shader_wined3d_object_destroyed
,
2027 static HRESULT
d3d11_compute_shader_init(struct d3d11_compute_shader
*shader
, struct d3d_device
*device
,
2028 const void *byte_code
, SIZE_T byte_code_length
)
2030 struct wined3d_shader_desc desc
;
2033 shader
->ID3D11ComputeShader_iface
.lpVtbl
= &d3d11_compute_shader_vtbl
;
2034 shader
->refcount
= 1;
2035 wined3d_mutex_lock();
2036 wined3d_private_store_init(&shader
->private_store
);
2038 if (FAILED(hr
= shader_extract_from_dxbc(byte_code
, byte_code_length
, &desc
, device
->feature_level
)))
2040 WARN("Failed to extract shader, hr %#x.\n", hr
);
2041 wined3d_private_store_cleanup(&shader
->private_store
);
2042 wined3d_mutex_unlock();
2045 desc
.max_version
= d3d_sm_from_feature_level(device
->feature_level
);
2047 hr
= wined3d_shader_create_cs(device
->wined3d_device
, &desc
, shader
,
2048 &d3d11_compute_shader_wined3d_parent_ops
, &shader
->wined3d_shader
);
2049 free_shader_desc(&desc
);
2052 WARN("Failed to create wined3d compute shader, hr %#x.\n", hr
);
2053 wined3d_private_store_cleanup(&shader
->private_store
);
2054 wined3d_mutex_unlock();
2055 return E_INVALIDARG
;
2057 wined3d_mutex_unlock();
2059 ID3D11Device_AddRef(shader
->device
= &device
->ID3D11Device_iface
);
2064 HRESULT
d3d11_compute_shader_create(struct d3d_device
*device
, const void *byte_code
, SIZE_T byte_code_length
,
2065 struct d3d11_compute_shader
**shader
)
2067 struct d3d11_compute_shader
*object
;
2070 if (!(object
= heap_alloc_zero(sizeof(*object
))))
2071 return E_OUTOFMEMORY
;
2073 if (FAILED(hr
= d3d11_compute_shader_init(object
, device
, byte_code
, byte_code_length
)))
2079 TRACE("Created compute shader %p.\n", object
);
2085 struct d3d11_compute_shader
*unsafe_impl_from_ID3D11ComputeShader(ID3D11ComputeShader
*iface
)
2089 assert(iface
->lpVtbl
== &d3d11_compute_shader_vtbl
);
2091 return impl_from_ID3D11ComputeShader(iface
);
2094 /* ID3D11ClassLinkage methods */
2096 static inline struct d3d11_class_linkage
*impl_from_ID3D11ClassLinkage(ID3D11ClassLinkage
*iface
)
2098 return CONTAINING_RECORD(iface
, struct d3d11_class_linkage
, ID3D11ClassLinkage_iface
);
2101 static HRESULT STDMETHODCALLTYPE
d3d11_class_linkage_QueryInterface(ID3D11ClassLinkage
*iface
,
2102 REFIID riid
, void **object
)
2104 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
2106 if (IsEqualGUID(riid
, &IID_ID3D11ClassLinkage
)
2107 || IsEqualGUID(riid
, &IID_ID3D11DeviceChild
)
2108 || IsEqualGUID(riid
, &IID_IUnknown
))
2110 ID3D11ClassLinkage_AddRef(*object
= iface
);
2114 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
2117 return E_NOINTERFACE
;
2120 static ULONG STDMETHODCALLTYPE
d3d11_class_linkage_AddRef(ID3D11ClassLinkage
*iface
)
2122 struct d3d11_class_linkage
*class_linkage
= impl_from_ID3D11ClassLinkage(iface
);
2123 ULONG refcount
= InterlockedIncrement(&class_linkage
->refcount
);
2125 TRACE("%p increasing refcount to %u.\n", class_linkage
, refcount
);
2130 static ULONG STDMETHODCALLTYPE
d3d11_class_linkage_Release(ID3D11ClassLinkage
*iface
)
2132 struct d3d11_class_linkage
*class_linkage
= impl_from_ID3D11ClassLinkage(iface
);
2133 ULONG refcount
= InterlockedDecrement(&class_linkage
->refcount
);
2135 TRACE("%p decreasing refcount to %u.\n", class_linkage
, refcount
);
2139 ID3D11Device
*device
= class_linkage
->device
;
2141 wined3d_private_store_cleanup(&class_linkage
->private_store
);
2142 heap_free(class_linkage
);
2144 ID3D11Device_Release(device
);
2150 static void STDMETHODCALLTYPE
d3d11_class_linkage_GetDevice(ID3D11ClassLinkage
*iface
,
2151 ID3D11Device
**device
)
2153 struct d3d11_class_linkage
*class_linkage
= impl_from_ID3D11ClassLinkage(iface
);
2155 TRACE("iface %p, device %p.\n", iface
, device
);
2157 ID3D11Device_AddRef(*device
= class_linkage
->device
);
2160 static HRESULT STDMETHODCALLTYPE
d3d11_class_linkage_GetPrivateData(ID3D11ClassLinkage
*iface
,
2161 REFGUID guid
, UINT
*data_size
, void *data
)
2163 struct d3d11_class_linkage
*class_linkage
= impl_from_ID3D11ClassLinkage(iface
);
2165 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
2167 return d3d_get_private_data(&class_linkage
->private_store
, guid
, data_size
, data
);
2170 static HRESULT STDMETHODCALLTYPE
d3d11_class_linkage_SetPrivateData(ID3D11ClassLinkage
*iface
,
2171 REFGUID guid
, UINT data_size
, const void *data
)
2173 struct d3d11_class_linkage
*class_linkage
= impl_from_ID3D11ClassLinkage(iface
);
2175 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
2177 return d3d_set_private_data(&class_linkage
->private_store
, guid
, data_size
, data
);
2180 static HRESULT STDMETHODCALLTYPE
d3d11_class_linkage_SetPrivateDataInterface(ID3D11ClassLinkage
*iface
,
2181 REFGUID guid
, const IUnknown
*data
)
2183 struct d3d11_class_linkage
*class_linkage
= impl_from_ID3D11ClassLinkage(iface
);
2185 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
2187 return d3d_set_private_data_interface(&class_linkage
->private_store
, guid
, data
);
2190 static HRESULT STDMETHODCALLTYPE
d3d11_class_linkage_GetClassInstance(ID3D11ClassLinkage
*iface
,
2191 const char *instance_name
, UINT instance_index
, ID3D11ClassInstance
**class_instance
)
2193 FIXME("iface %p, instance_name %s, instance_index %u, class_instance %p stub!\n",
2194 iface
, debugstr_a(instance_name
), instance_index
, class_instance
);
2199 static HRESULT STDMETHODCALLTYPE
d3d11_class_linkage_CreateClassInstance(ID3D11ClassLinkage
*iface
,
2200 const char *type_name
, UINT cb_offset
, UINT cb_vector_offset
, UINT texture_offset
,
2201 UINT sampler_offset
, ID3D11ClassInstance
**class_instance
)
2203 FIXME("iface %p, type_name %s, cb_offset %u, cb_vector_offset %u, texture_offset %u, "
2204 "sampler_offset %u, class_instance %p stub!\n",
2205 iface
, debugstr_a(type_name
), cb_offset
, cb_vector_offset
, texture_offset
,
2206 sampler_offset
, class_instance
);
2211 static const struct ID3D11ClassLinkageVtbl d3d11_class_linkage_vtbl
=
2213 /* IUnknown methods */
2214 d3d11_class_linkage_QueryInterface
,
2215 d3d11_class_linkage_AddRef
,
2216 d3d11_class_linkage_Release
,
2217 /* ID3D11DeviceChild methods */
2218 d3d11_class_linkage_GetDevice
,
2219 d3d11_class_linkage_GetPrivateData
,
2220 d3d11_class_linkage_SetPrivateData
,
2221 d3d11_class_linkage_SetPrivateDataInterface
,
2222 /* ID3D11ClassLinkage methods */
2223 d3d11_class_linkage_GetClassInstance
,
2224 d3d11_class_linkage_CreateClassInstance
,
2227 HRESULT
d3d11_class_linkage_create(struct d3d_device
*device
, struct d3d11_class_linkage
**class_linkage
)
2229 struct d3d11_class_linkage
*object
;
2231 if (!(object
= heap_alloc_zero(sizeof(*object
))))
2232 return E_OUTOFMEMORY
;
2234 object
->ID3D11ClassLinkage_iface
.lpVtbl
= &d3d11_class_linkage_vtbl
;
2235 object
->refcount
= 1;
2236 wined3d_private_store_init(&object
->private_store
);
2238 ID3D11Device_AddRef(object
->device
= &device
->ID3D11Device_iface
);
2240 TRACE("Created class linkage %p.\n", object
);
2241 *class_linkage
= object
;