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 (FAILED(hr
= shader_parse_signature(data
, data_size
, &desc
->input_signature
)))
60 if (ctx
->feature_level
<= D3D_FEATURE_LEVEL_9_3
)
62 TRACE("Skipping shader output signature on feature level %#x.\n", ctx
->feature_level
);
65 if (FAILED(hr
= shader_parse_signature(data
, data_size
, &desc
->output_signature
)))
71 if (ctx
->feature_level
<= D3D_FEATURE_LEVEL_9_3
)
73 TRACE("Skipping SM4+ shader code on feature level %#x.\n", ctx
->feature_level
);
77 FIXME("Multiple shader code chunks.\n");
78 desc
->byte_code
= (const DWORD
*)data
;
79 desc
->byte_code_size
= data_size
;
80 desc
->format
= WINED3D_SHADER_BYTE_CODE_FORMAT_SM4
;
84 if (ctx
->feature_level
<= D3D_FEATURE_LEVEL_9_3
)
86 const struct aon9_header
*header
= (const struct aon9_header
*)data
;
87 unsigned int unknown_dword_count
;
88 const char *byte_code
;
90 if (data_size
< sizeof(*header
))
92 WARN("Invalid Aon9 data size %#x.\n", data_size
);
95 byte_code
= data
+ header
->byte_code_offset
;
96 unknown_dword_count
= (header
->byte_code_offset
- sizeof(*header
)) / sizeof(DWORD
);
98 if (data_size
- 2 * sizeof(DWORD
) < header
->byte_code_offset
)
100 WARN("Invalid byte code offset %#x (size %#x).\n", header
->byte_code_offset
, data_size
);
103 FIXME("Skipping %u unknown DWORDs.\n", unknown_dword_count
);
106 FIXME("Multiple shader code chunks.\n");
107 desc
->byte_code
= (const DWORD
*)byte_code
;
108 desc
->byte_code_size
= data_size
- header
->byte_code_offset
;
109 desc
->format
= WINED3D_SHADER_BYTE_CODE_FORMAT_SM1
;
110 TRACE("Feature level 9 shader version 0%08x, 0%08x.\n", header
->shader_version
, *desc
->byte_code
);
114 TRACE("Skipping feature level 9 shader code on feature level %#x.\n", ctx
->feature_level
);
119 FIXME("Unhandled chunk %s.\n", debugstr_an((const char *)&tag
, 4));
126 static HRESULT
shader_extract_from_dxbc(const void *dxbc
, SIZE_T dxbc_length
, struct wined3d_shader_desc
*desc
,
127 D3D_FEATURE_LEVEL feature_level
)
129 struct shader_handler_context ctx
= {feature_level
, desc
};
132 desc
->byte_code
= NULL
;
133 desc
->byte_code_size
= 0;
134 memset(&desc
->input_signature
, 0, sizeof(desc
->input_signature
));
135 memset(&desc
->output_signature
, 0, sizeof(desc
->output_signature
));
137 hr
= parse_dxbc(dxbc
, dxbc_length
, shdr_handler
, &ctx
);
138 if (!desc
->byte_code
)
143 FIXME("Failed to parse shader, hr %#x.\n", hr
);
144 shader_free_signature(&desc
->input_signature
);
145 shader_free_signature(&desc
->output_signature
);
151 static const char *shader_get_string(const char *data
, size_t data_size
, DWORD offset
)
155 if (offset
>= data_size
)
157 WARN("Invalid offset %#x (data size %#lx).\n", offset
, (long)data_size
);
161 max_len
= data_size
- offset
;
162 len
= strnlen(data
+ offset
, max_len
);
167 return data
+ offset
;
170 HRESULT
shader_parse_signature(const char *data
, DWORD data_size
, struct wined3d_shader_signature
*s
)
172 struct wined3d_shader_signature_element
*e
;
173 const char *ptr
= data
;
177 if (!require_space(0, 2, sizeof(DWORD
), data_size
))
179 WARN("Invalid data size %#x.\n", data_size
);
183 read_dword(&ptr
, &count
);
184 TRACE("%u elements\n", count
);
186 skip_dword_unknown(&ptr
, 1); /* It seems to always be 0x00000008. */
188 if (!require_space(ptr
- data
, count
, 6 * sizeof(DWORD
), data_size
))
190 WARN("Invalid count %#x (data size %#x).\n", count
, data_size
);
194 if (!(e
= d3d11_calloc(count
, sizeof(*e
))))
196 ERR("Failed to allocate input signature memory.\n");
197 return E_OUTOFMEMORY
;
200 for (i
= 0; i
< count
; ++i
)
204 read_dword(&ptr
, &name_offset
);
205 if (!(e
[i
].semantic_name
= shader_get_string(data
, data_size
, name_offset
)))
207 WARN("Invalid name offset %#x (data size %#x).\n", name_offset
, data_size
);
208 HeapFree(GetProcessHeap(), 0, e
);
211 read_dword(&ptr
, &e
[i
].semantic_idx
);
212 read_dword(&ptr
, &e
[i
].sysval_semantic
);
213 read_dword(&ptr
, &e
[i
].component_type
);
214 read_dword(&ptr
, &e
[i
].register_idx
);
215 read_dword(&ptr
, &e
[i
].mask
);
217 TRACE("semantic: %s, semantic idx: %u, sysval_semantic %#x, "
218 "type %u, register idx: %u, use_mask %#x, input_mask %#x\n",
219 debugstr_a(e
[i
].semantic_name
), e
[i
].semantic_idx
, e
[i
].sysval_semantic
,
220 e
[i
].component_type
, e
[i
].register_idx
, (e
[i
].mask
>> 8) & 0xff, e
[i
].mask
& 0xff);
224 s
->element_count
= count
;
229 struct wined3d_shader_signature_element
*shader_find_signature_element(const struct wined3d_shader_signature
*s
,
230 const char *semantic_name
, unsigned int semantic_idx
)
232 struct wined3d_shader_signature_element
*e
= s
->elements
;
235 for (i
= 0; i
< s
->element_count
; ++i
)
237 if (!strcasecmp(e
[i
].semantic_name
, semantic_name
) && e
[i
].semantic_idx
== semantic_idx
)
244 void shader_free_signature(struct wined3d_shader_signature
*s
)
246 HeapFree(GetProcessHeap(), 0, s
->elements
);
249 /* ID3D11VertexShader methods */
251 static inline struct d3d_vertex_shader
*impl_from_ID3D11VertexShader(ID3D11VertexShader
*iface
)
253 return CONTAINING_RECORD(iface
, struct d3d_vertex_shader
, ID3D11VertexShader_iface
);
256 static HRESULT STDMETHODCALLTYPE
d3d11_vertex_shader_QueryInterface(ID3D11VertexShader
*iface
,
257 REFIID riid
, void **object
)
259 struct d3d_vertex_shader
*shader
= impl_from_ID3D11VertexShader(iface
);
261 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
263 if (IsEqualGUID(riid
, &IID_ID3D11VertexShader
)
264 || IsEqualGUID(riid
, &IID_ID3D11DeviceChild
)
265 || IsEqualGUID(riid
, &IID_IUnknown
))
267 ID3D11VertexShader_AddRef(iface
);
272 if (IsEqualGUID(riid
, &IID_ID3D10VertexShader
)
273 || IsEqualGUID(riid
, &IID_ID3D10DeviceChild
))
275 IUnknown_AddRef(&shader
->ID3D10VertexShader_iface
);
276 *object
= &shader
->ID3D10VertexShader_iface
;
280 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
283 return E_NOINTERFACE
;
286 static ULONG STDMETHODCALLTYPE
d3d11_vertex_shader_AddRef(ID3D11VertexShader
*iface
)
288 struct d3d_vertex_shader
*shader
= impl_from_ID3D11VertexShader(iface
);
289 ULONG refcount
= InterlockedIncrement(&shader
->refcount
);
291 TRACE("%p increasing refcount to %u.\n", shader
, refcount
);
295 ID3D11Device_AddRef(shader
->device
);
296 wined3d_mutex_lock();
297 wined3d_shader_incref(shader
->wined3d_shader
);
298 wined3d_mutex_unlock();
304 static ULONG STDMETHODCALLTYPE
d3d11_vertex_shader_Release(ID3D11VertexShader
*iface
)
306 struct d3d_vertex_shader
*shader
= impl_from_ID3D11VertexShader(iface
);
307 ULONG refcount
= InterlockedDecrement(&shader
->refcount
);
309 TRACE("%p decreasing refcount to %u.\n", shader
, refcount
);
313 ID3D11Device
*device
= shader
->device
;
315 wined3d_mutex_lock();
316 wined3d_shader_decref(shader
->wined3d_shader
);
317 wined3d_mutex_unlock();
318 /* Release the device last, it may cause the wined3d device to be
320 ID3D11Device_Release(device
);
326 static void STDMETHODCALLTYPE
d3d11_vertex_shader_GetDevice(ID3D11VertexShader
*iface
,
327 ID3D11Device
**device
)
329 struct d3d_vertex_shader
*shader
= impl_from_ID3D11VertexShader(iface
);
331 TRACE("iface %p, device %p.\n", iface
, device
);
333 *device
= shader
->device
;
334 ID3D11Device_AddRef(*device
);
337 static HRESULT STDMETHODCALLTYPE
d3d11_vertex_shader_GetPrivateData(ID3D11VertexShader
*iface
,
338 REFGUID guid
, UINT
*data_size
, void *data
)
340 struct d3d_vertex_shader
*shader
= impl_from_ID3D11VertexShader(iface
);
342 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
344 return d3d_get_private_data(&shader
->private_store
, guid
, data_size
, data
);
347 static HRESULT STDMETHODCALLTYPE
d3d11_vertex_shader_SetPrivateData(ID3D11VertexShader
*iface
,
348 REFGUID guid
, UINT data_size
, const void *data
)
350 struct d3d_vertex_shader
*shader
= impl_from_ID3D11VertexShader(iface
);
352 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
354 return d3d_set_private_data(&shader
->private_store
, guid
, data_size
, data
);
357 static HRESULT STDMETHODCALLTYPE
d3d11_vertex_shader_SetPrivateDataInterface(ID3D11VertexShader
*iface
,
358 REFGUID guid
, const IUnknown
*data
)
360 struct d3d_vertex_shader
*shader
= impl_from_ID3D11VertexShader(iface
);
362 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
364 return d3d_set_private_data_interface(&shader
->private_store
, guid
, data
);
367 static const struct ID3D11VertexShaderVtbl d3d11_vertex_shader_vtbl
=
369 /* IUnknown methods */
370 d3d11_vertex_shader_QueryInterface
,
371 d3d11_vertex_shader_AddRef
,
372 d3d11_vertex_shader_Release
,
373 /* ID3D11DeviceChild methods */
374 d3d11_vertex_shader_GetDevice
,
375 d3d11_vertex_shader_GetPrivateData
,
376 d3d11_vertex_shader_SetPrivateData
,
377 d3d11_vertex_shader_SetPrivateDataInterface
,
380 /* ID3D10VertexShader methods */
382 static inline struct d3d_vertex_shader
*impl_from_ID3D10VertexShader(ID3D10VertexShader
*iface
)
384 return CONTAINING_RECORD(iface
, struct d3d_vertex_shader
, ID3D10VertexShader_iface
);
387 /* IUnknown methods */
389 static HRESULT STDMETHODCALLTYPE
d3d10_vertex_shader_QueryInterface(ID3D10VertexShader
*iface
,
390 REFIID riid
, void **object
)
392 struct d3d_vertex_shader
*shader
= impl_from_ID3D10VertexShader(iface
);
394 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
396 return d3d11_vertex_shader_QueryInterface(&shader
->ID3D11VertexShader_iface
, riid
, object
);
399 static ULONG STDMETHODCALLTYPE
d3d10_vertex_shader_AddRef(ID3D10VertexShader
*iface
)
401 struct d3d_vertex_shader
*shader
= impl_from_ID3D10VertexShader(iface
);
403 TRACE("iface %p.\n", iface
);
405 return d3d11_vertex_shader_AddRef(&shader
->ID3D11VertexShader_iface
);
408 static ULONG STDMETHODCALLTYPE
d3d10_vertex_shader_Release(ID3D10VertexShader
*iface
)
410 struct d3d_vertex_shader
*shader
= impl_from_ID3D10VertexShader(iface
);
412 TRACE("iface %p.\n", iface
);
414 return d3d11_vertex_shader_Release(&shader
->ID3D11VertexShader_iface
);
417 /* ID3D10DeviceChild methods */
419 static void STDMETHODCALLTYPE
d3d10_vertex_shader_GetDevice(ID3D10VertexShader
*iface
, ID3D10Device
**device
)
421 struct d3d_vertex_shader
*shader
= impl_from_ID3D10VertexShader(iface
);
423 TRACE("iface %p, device %p.\n", iface
, device
);
425 ID3D11Device_QueryInterface(shader
->device
, &IID_ID3D10Device
, (void **)device
);
428 static HRESULT STDMETHODCALLTYPE
d3d10_vertex_shader_GetPrivateData(ID3D10VertexShader
*iface
,
429 REFGUID guid
, UINT
*data_size
, void *data
)
431 struct d3d_vertex_shader
*shader
= impl_from_ID3D10VertexShader(iface
);
433 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
434 iface
, debugstr_guid(guid
), data_size
, data
);
436 return d3d_get_private_data(&shader
->private_store
, guid
, data_size
, data
);
439 static HRESULT STDMETHODCALLTYPE
d3d10_vertex_shader_SetPrivateData(ID3D10VertexShader
*iface
,
440 REFGUID guid
, UINT data_size
, const void *data
)
442 struct d3d_vertex_shader
*shader
= impl_from_ID3D10VertexShader(iface
);
444 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
445 iface
, debugstr_guid(guid
), data_size
, data
);
447 return d3d_set_private_data(&shader
->private_store
, guid
, data_size
, data
);
450 static HRESULT STDMETHODCALLTYPE
d3d10_vertex_shader_SetPrivateDataInterface(ID3D10VertexShader
*iface
,
451 REFGUID guid
, const IUnknown
*data
)
453 struct d3d_vertex_shader
*shader
= impl_from_ID3D10VertexShader(iface
);
455 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
457 return d3d_set_private_data_interface(&shader
->private_store
, guid
, data
);
460 static const struct ID3D10VertexShaderVtbl d3d10_vertex_shader_vtbl
=
462 /* IUnknown methods */
463 d3d10_vertex_shader_QueryInterface
,
464 d3d10_vertex_shader_AddRef
,
465 d3d10_vertex_shader_Release
,
466 /* ID3D10DeviceChild methods */
467 d3d10_vertex_shader_GetDevice
,
468 d3d10_vertex_shader_GetPrivateData
,
469 d3d10_vertex_shader_SetPrivateData
,
470 d3d10_vertex_shader_SetPrivateDataInterface
,
473 static void STDMETHODCALLTYPE
d3d_vertex_shader_wined3d_object_destroyed(void *parent
)
475 struct d3d_vertex_shader
*shader
= parent
;
477 wined3d_private_store_cleanup(&shader
->private_store
);
478 HeapFree(GetProcessHeap(), 0, parent
);
481 static const struct wined3d_parent_ops d3d_vertex_shader_wined3d_parent_ops
=
483 d3d_vertex_shader_wined3d_object_destroyed
,
486 static unsigned int d3d_sm_from_feature_level(D3D_FEATURE_LEVEL feature_level
)
488 switch (feature_level
)
490 case D3D_FEATURE_LEVEL_11_1
:
491 case D3D_FEATURE_LEVEL_11_0
:
493 case D3D_FEATURE_LEVEL_10_1
:
494 case D3D_FEATURE_LEVEL_10_0
:
496 case D3D_FEATURE_LEVEL_9_3
:
498 case D3D_FEATURE_LEVEL_9_2
:
499 case D3D_FEATURE_LEVEL_9_1
:
502 ERR("Unexpected feature_level %#x.\n", feature_level
);
507 static HRESULT
d3d_vertex_shader_init(struct d3d_vertex_shader
*shader
, struct d3d_device
*device
,
508 const void *byte_code
, SIZE_T byte_code_length
)
510 struct wined3d_shader_desc desc
;
513 shader
->ID3D11VertexShader_iface
.lpVtbl
= &d3d11_vertex_shader_vtbl
;
514 shader
->ID3D10VertexShader_iface
.lpVtbl
= &d3d10_vertex_shader_vtbl
;
515 shader
->refcount
= 1;
516 wined3d_mutex_lock();
517 wined3d_private_store_init(&shader
->private_store
);
519 if (FAILED(hr
= shader_extract_from_dxbc(byte_code
, byte_code_length
, &desc
, device
->feature_level
)))
521 WARN("Failed to extract shader, hr %#x.\n", hr
);
522 wined3d_private_store_cleanup(&shader
->private_store
);
523 wined3d_mutex_unlock();
526 desc
.max_version
= d3d_sm_from_feature_level(device
->feature_level
);
528 hr
= wined3d_shader_create_vs(device
->wined3d_device
, &desc
, shader
,
529 &d3d_vertex_shader_wined3d_parent_ops
, &shader
->wined3d_shader
);
530 shader_free_signature(&desc
.input_signature
);
531 shader_free_signature(&desc
.output_signature
);
534 WARN("Failed to create wined3d vertex shader, hr %#x.\n", hr
);
535 wined3d_private_store_cleanup(&shader
->private_store
);
536 wined3d_mutex_unlock();
539 wined3d_mutex_unlock();
541 shader
->device
= &device
->ID3D11Device_iface
;
542 ID3D11Device_AddRef(shader
->device
);
547 HRESULT
d3d_vertex_shader_create(struct d3d_device
*device
, const void *byte_code
, SIZE_T byte_code_length
,
548 struct d3d_vertex_shader
**shader
)
550 struct d3d_vertex_shader
*object
;
553 if (!(object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*object
))))
554 return E_OUTOFMEMORY
;
556 if (FAILED(hr
= d3d_vertex_shader_init(object
, device
, byte_code
, byte_code_length
)))
558 WARN("Failed to initialize vertex shader, hr %#x.\n", hr
);
559 HeapFree(GetProcessHeap(), 0, object
);
563 TRACE("Created vertex shader %p.\n", object
);
569 struct d3d_vertex_shader
*unsafe_impl_from_ID3D11VertexShader(ID3D11VertexShader
*iface
)
573 assert(iface
->lpVtbl
== &d3d11_vertex_shader_vtbl
);
575 return impl_from_ID3D11VertexShader(iface
);
578 struct d3d_vertex_shader
*unsafe_impl_from_ID3D10VertexShader(ID3D10VertexShader
*iface
)
582 assert(iface
->lpVtbl
== &d3d10_vertex_shader_vtbl
);
584 return impl_from_ID3D10VertexShader(iface
);
587 /* ID3D11HullShader methods */
589 static inline struct d3d11_hull_shader
*impl_from_ID3D11HullShader(ID3D11HullShader
*iface
)
591 return CONTAINING_RECORD(iface
, struct d3d11_hull_shader
, ID3D11HullShader_iface
);
594 static HRESULT STDMETHODCALLTYPE
d3d11_hull_shader_QueryInterface(ID3D11HullShader
*iface
,
595 REFIID riid
, void **object
)
597 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
599 if (IsEqualGUID(riid
, &IID_ID3D11HullShader
)
600 || IsEqualGUID(riid
, &IID_ID3D11DeviceChild
)
601 || IsEqualGUID(riid
, &IID_IUnknown
))
603 ID3D11HullShader_AddRef(iface
);
608 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
611 return E_NOINTERFACE
;
614 static ULONG STDMETHODCALLTYPE
d3d11_hull_shader_AddRef(ID3D11HullShader
*iface
)
616 struct d3d11_hull_shader
*shader
= impl_from_ID3D11HullShader(iface
);
617 ULONG refcount
= InterlockedIncrement(&shader
->refcount
);
619 TRACE("%p increasing refcount to %u.\n", shader
, refcount
);
624 static ULONG STDMETHODCALLTYPE
d3d11_hull_shader_Release(ID3D11HullShader
*iface
)
626 struct d3d11_hull_shader
*shader
= impl_from_ID3D11HullShader(iface
);
627 ULONG refcount
= InterlockedDecrement(&shader
->refcount
);
629 TRACE("%p decreasing refcount to %u.\n", shader
, refcount
);
633 ID3D11Device
*device
= shader
->device
;
635 wined3d_mutex_lock();
636 wined3d_shader_decref(shader
->wined3d_shader
);
637 wined3d_mutex_unlock();
639 /* Release the device last, it may cause the wined3d device to be
641 ID3D11Device_Release(device
);
647 static void STDMETHODCALLTYPE
d3d11_hull_shader_GetDevice(ID3D11HullShader
*iface
,
648 ID3D11Device
**device
)
650 struct d3d11_hull_shader
*shader
= impl_from_ID3D11HullShader(iface
);
652 TRACE("iface %p, device %p.\n", iface
, device
);
654 *device
= shader
->device
;
655 ID3D11Device_AddRef(*device
);
658 static HRESULT STDMETHODCALLTYPE
d3d11_hull_shader_GetPrivateData(ID3D11HullShader
*iface
,
659 REFGUID guid
, UINT
*data_size
, void *data
)
661 struct d3d11_hull_shader
*shader
= impl_from_ID3D11HullShader(iface
);
663 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
665 return d3d_get_private_data(&shader
->private_store
, guid
, data_size
, data
);
668 static HRESULT STDMETHODCALLTYPE
d3d11_hull_shader_SetPrivateData(ID3D11HullShader
*iface
,
669 REFGUID guid
, UINT data_size
, const void *data
)
671 struct d3d11_hull_shader
*shader
= impl_from_ID3D11HullShader(iface
);
673 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
675 return d3d_set_private_data(&shader
->private_store
, guid
, data_size
, data
);
678 static HRESULT STDMETHODCALLTYPE
d3d11_hull_shader_SetPrivateDataInterface(ID3D11HullShader
*iface
,
679 REFGUID guid
, const IUnknown
*data
)
681 struct d3d11_hull_shader
*shader
= impl_from_ID3D11HullShader(iface
);
683 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
685 return d3d_set_private_data_interface(&shader
->private_store
, guid
, data
);
688 static const struct ID3D11HullShaderVtbl d3d11_hull_shader_vtbl
=
690 /* IUnknown methods */
691 d3d11_hull_shader_QueryInterface
,
692 d3d11_hull_shader_AddRef
,
693 d3d11_hull_shader_Release
,
694 /* ID3D11DeviceChild methods */
695 d3d11_hull_shader_GetDevice
,
696 d3d11_hull_shader_GetPrivateData
,
697 d3d11_hull_shader_SetPrivateData
,
698 d3d11_hull_shader_SetPrivateDataInterface
,
701 static void STDMETHODCALLTYPE
d3d11_hull_shader_wined3d_object_destroyed(void *parent
)
703 struct d3d11_hull_shader
*shader
= parent
;
705 wined3d_private_store_cleanup(&shader
->private_store
);
706 HeapFree(GetProcessHeap(), 0, parent
);
709 static const struct wined3d_parent_ops d3d11_hull_shader_wined3d_parent_ops
=
711 d3d11_hull_shader_wined3d_object_destroyed
,
714 static HRESULT
d3d11_hull_shader_init(struct d3d11_hull_shader
*shader
, struct d3d_device
*device
,
715 const void *byte_code
, SIZE_T byte_code_length
)
717 struct wined3d_shader_desc desc
;
720 shader
->ID3D11HullShader_iface
.lpVtbl
= &d3d11_hull_shader_vtbl
;
721 shader
->refcount
= 1;
722 wined3d_mutex_lock();
723 wined3d_private_store_init(&shader
->private_store
);
725 if (FAILED(hr
= shader_extract_from_dxbc(byte_code
, byte_code_length
, &desc
, device
->feature_level
)))
727 WARN("Failed to extract shader, hr %#x.\n", hr
);
728 wined3d_private_store_cleanup(&shader
->private_store
);
729 wined3d_mutex_unlock();
732 desc
.max_version
= d3d_sm_from_feature_level(device
->feature_level
);
734 hr
= wined3d_shader_create_hs(device
->wined3d_device
, &desc
, shader
,
735 &d3d11_hull_shader_wined3d_parent_ops
, &shader
->wined3d_shader
);
736 shader_free_signature(&desc
.input_signature
);
737 shader_free_signature(&desc
.output_signature
);
740 WARN("Failed to create wined3d hull shader, hr %#x.\n", hr
);
741 wined3d_private_store_cleanup(&shader
->private_store
);
742 wined3d_mutex_unlock();
745 wined3d_mutex_unlock();
747 shader
->device
= &device
->ID3D11Device_iface
;
748 ID3D11Device_AddRef(shader
->device
);
753 HRESULT
d3d11_hull_shader_create(struct d3d_device
*device
, const void *byte_code
, SIZE_T byte_code_length
,
754 struct d3d11_hull_shader
**shader
)
756 struct d3d11_hull_shader
*object
;
759 if (!(object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*object
))))
760 return E_OUTOFMEMORY
;
762 if (FAILED(hr
= d3d11_hull_shader_init(object
, device
, byte_code
, byte_code_length
)))
764 HeapFree(GetProcessHeap(), 0, object
);
768 TRACE("Created hull shader %p.\n", object
);
774 /* ID3D11DomainShader methods */
776 static inline struct d3d11_domain_shader
*impl_from_ID3D11DomainShader(ID3D11DomainShader
*iface
)
778 return CONTAINING_RECORD(iface
, struct d3d11_domain_shader
, ID3D11DomainShader_iface
);
781 static HRESULT STDMETHODCALLTYPE
d3d11_domain_shader_QueryInterface(ID3D11DomainShader
*iface
,
782 REFIID riid
, void **object
)
784 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
786 if (IsEqualGUID(riid
, &IID_ID3D11DomainShader
)
787 || IsEqualGUID(riid
, &IID_ID3D11DeviceChild
)
788 || IsEqualGUID(riid
, &IID_IUnknown
))
790 ID3D11DomainShader_AddRef(iface
);
795 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
798 return E_NOINTERFACE
;
801 static ULONG STDMETHODCALLTYPE
d3d11_domain_shader_AddRef(ID3D11DomainShader
*iface
)
803 struct d3d11_domain_shader
*shader
= impl_from_ID3D11DomainShader(iface
);
804 ULONG refcount
= InterlockedIncrement(&shader
->refcount
);
806 TRACE("%p increasing refcount to %u.\n", shader
, refcount
);
811 static ULONG STDMETHODCALLTYPE
d3d11_domain_shader_Release(ID3D11DomainShader
*iface
)
813 struct d3d11_domain_shader
*shader
= impl_from_ID3D11DomainShader(iface
);
814 ULONG refcount
= InterlockedDecrement(&shader
->refcount
);
816 TRACE("%p decreasing refcount to %u.\n", shader
, refcount
);
820 ID3D11Device
*device
= shader
->device
;
822 wined3d_mutex_lock();
823 wined3d_shader_decref(shader
->wined3d_shader
);
824 wined3d_mutex_unlock();
826 /* Release the device last, it may cause the wined3d device to be
828 ID3D11Device_Release(device
);
834 static void STDMETHODCALLTYPE
d3d11_domain_shader_GetDevice(ID3D11DomainShader
*iface
,
835 ID3D11Device
**device
)
837 struct d3d11_domain_shader
*shader
= impl_from_ID3D11DomainShader(iface
);
839 TRACE("iface %p, device %p.\n", iface
, device
);
841 *device
= shader
->device
;
842 ID3D11Device_AddRef(*device
);
845 static HRESULT STDMETHODCALLTYPE
d3d11_domain_shader_GetPrivateData(ID3D11DomainShader
*iface
,
846 REFGUID guid
, UINT
*data_size
, void *data
)
848 struct d3d11_domain_shader
*shader
= impl_from_ID3D11DomainShader(iface
);
850 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
852 return d3d_get_private_data(&shader
->private_store
, guid
, data_size
, data
);
855 static HRESULT STDMETHODCALLTYPE
d3d11_domain_shader_SetPrivateData(ID3D11DomainShader
*iface
,
856 REFGUID guid
, UINT data_size
, const void *data
)
858 struct d3d11_domain_shader
*shader
= impl_from_ID3D11DomainShader(iface
);
860 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
862 return d3d_set_private_data(&shader
->private_store
, guid
, data_size
, data
);
865 static HRESULT STDMETHODCALLTYPE
d3d11_domain_shader_SetPrivateDataInterface(ID3D11DomainShader
*iface
,
866 REFGUID guid
, const IUnknown
*data
)
868 struct d3d11_domain_shader
*shader
= impl_from_ID3D11DomainShader(iface
);
870 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
872 return d3d_set_private_data_interface(&shader
->private_store
, guid
, data
);
875 static const struct ID3D11DomainShaderVtbl d3d11_domain_shader_vtbl
=
877 /* IUnknown methods */
878 d3d11_domain_shader_QueryInterface
,
879 d3d11_domain_shader_AddRef
,
880 d3d11_domain_shader_Release
,
881 /* ID3D11DeviceChild methods */
882 d3d11_domain_shader_GetDevice
,
883 d3d11_domain_shader_GetPrivateData
,
884 d3d11_domain_shader_SetPrivateData
,
885 d3d11_domain_shader_SetPrivateDataInterface
,
888 static void STDMETHODCALLTYPE
d3d11_domain_shader_wined3d_object_destroyed(void *parent
)
890 struct d3d11_domain_shader
*shader
= parent
;
892 wined3d_private_store_cleanup(&shader
->private_store
);
893 HeapFree(GetProcessHeap(), 0, parent
);
896 static const struct wined3d_parent_ops d3d11_domain_shader_wined3d_parent_ops
=
898 d3d11_domain_shader_wined3d_object_destroyed
,
901 static HRESULT
d3d11_domain_shader_init(struct d3d11_domain_shader
*shader
, struct d3d_device
*device
,
902 const void *byte_code
, SIZE_T byte_code_length
)
904 struct wined3d_shader_desc desc
;
907 shader
->ID3D11DomainShader_iface
.lpVtbl
= &d3d11_domain_shader_vtbl
;
908 shader
->refcount
= 1;
909 wined3d_mutex_lock();
910 wined3d_private_store_init(&shader
->private_store
);
912 if (FAILED(hr
= shader_extract_from_dxbc(byte_code
, byte_code_length
, &desc
, device
->feature_level
)))
914 WARN("Failed to extract shader, hr %#x.\n", hr
);
915 wined3d_private_store_cleanup(&shader
->private_store
);
916 wined3d_mutex_unlock();
919 desc
.max_version
= d3d_sm_from_feature_level(device
->feature_level
);
921 hr
= wined3d_shader_create_ds(device
->wined3d_device
, &desc
, shader
,
922 &d3d11_domain_shader_wined3d_parent_ops
, &shader
->wined3d_shader
);
923 shader_free_signature(&desc
.input_signature
);
924 shader_free_signature(&desc
.output_signature
);
927 WARN("Failed to create wined3d domain shader, hr %#x.\n", hr
);
928 wined3d_private_store_cleanup(&shader
->private_store
);
929 wined3d_mutex_unlock();
932 wined3d_mutex_unlock();
934 shader
->device
= &device
->ID3D11Device_iface
;
935 ID3D11Device_AddRef(shader
->device
);
940 HRESULT
d3d11_domain_shader_create(struct d3d_device
*device
, const void *byte_code
, SIZE_T byte_code_length
,
941 struct d3d11_domain_shader
**shader
)
943 struct d3d11_domain_shader
*object
;
946 if (!(object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*object
))))
947 return E_OUTOFMEMORY
;
949 if (FAILED(hr
= d3d11_domain_shader_init(object
, device
, byte_code
, byte_code_length
)))
951 HeapFree(GetProcessHeap(), 0, object
);
955 TRACE("Created domain shader %p.\n", object
);
961 /* ID3D11GeometryShader methods */
963 static inline struct d3d_geometry_shader
*impl_from_ID3D11GeometryShader(ID3D11GeometryShader
*iface
)
965 return CONTAINING_RECORD(iface
, struct d3d_geometry_shader
, ID3D11GeometryShader_iface
);
968 static HRESULT STDMETHODCALLTYPE
d3d11_geometry_shader_QueryInterface(ID3D11GeometryShader
*iface
,
969 REFIID riid
, void **object
)
971 struct d3d_geometry_shader
*shader
= impl_from_ID3D11GeometryShader(iface
);
973 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
975 if (IsEqualGUID(riid
, &IID_ID3D11GeometryShader
)
976 || IsEqualGUID(riid
, &IID_ID3D11DeviceChild
)
977 || IsEqualGUID(riid
, &IID_IUnknown
))
979 ID3D11GeometryShader_AddRef(iface
);
984 if (IsEqualGUID(riid
, &IID_ID3D10GeometryShader
)
985 || IsEqualGUID(riid
, &IID_ID3D10DeviceChild
))
987 ID3D10GeometryShader_AddRef(&shader
->ID3D10GeometryShader_iface
);
988 *object
= &shader
->ID3D10GeometryShader_iface
;
992 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
995 return E_NOINTERFACE
;
998 static ULONG STDMETHODCALLTYPE
d3d11_geometry_shader_AddRef(ID3D11GeometryShader
*iface
)
1000 struct d3d_geometry_shader
*shader
= impl_from_ID3D11GeometryShader(iface
);
1001 ULONG refcount
= InterlockedIncrement(&shader
->refcount
);
1003 TRACE("%p increasing refcount to %u.\n", shader
, refcount
);
1008 static ULONG STDMETHODCALLTYPE
d3d11_geometry_shader_Release(ID3D11GeometryShader
*iface
)
1010 struct d3d_geometry_shader
*shader
= impl_from_ID3D11GeometryShader(iface
);
1011 ULONG refcount
= InterlockedDecrement(&shader
->refcount
);
1013 TRACE("%p decreasing refcount to %u.\n", shader
, refcount
);
1017 ID3D11Device
*device
= shader
->device
;
1019 wined3d_mutex_lock();
1020 wined3d_shader_decref(shader
->wined3d_shader
);
1021 wined3d_mutex_unlock();
1023 /* Release the device last, it may cause the wined3d device to be
1025 ID3D11Device_Release(device
);
1031 static void STDMETHODCALLTYPE
d3d11_geometry_shader_GetDevice(ID3D11GeometryShader
*iface
,
1032 ID3D11Device
**device
)
1034 struct d3d_geometry_shader
*shader
= impl_from_ID3D11GeometryShader(iface
);
1036 TRACE("iface %p, device %p.\n", iface
, device
);
1038 *device
= shader
->device
;
1039 ID3D11Device_AddRef(*device
);
1042 static HRESULT STDMETHODCALLTYPE
d3d11_geometry_shader_GetPrivateData(ID3D11GeometryShader
*iface
,
1043 REFGUID guid
, UINT
*data_size
, void *data
)
1045 struct d3d_geometry_shader
*shader
= impl_from_ID3D11GeometryShader(iface
);
1047 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
1049 return d3d_get_private_data(&shader
->private_store
, guid
, data_size
, data
);
1052 static HRESULT STDMETHODCALLTYPE
d3d11_geometry_shader_SetPrivateData(ID3D11GeometryShader
*iface
,
1053 REFGUID guid
, UINT data_size
, const void *data
)
1055 struct d3d_geometry_shader
*shader
= impl_from_ID3D11GeometryShader(iface
);
1057 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
1059 return d3d_set_private_data(&shader
->private_store
, guid
, data_size
, data
);
1062 static HRESULT STDMETHODCALLTYPE
d3d11_geometry_shader_SetPrivateDataInterface(ID3D11GeometryShader
*iface
,
1063 REFGUID guid
, const IUnknown
*data
)
1065 struct d3d_geometry_shader
*shader
= impl_from_ID3D11GeometryShader(iface
);
1067 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
1069 return d3d_set_private_data_interface(&shader
->private_store
, guid
, data
);
1072 static const struct ID3D11GeometryShaderVtbl d3d11_geometry_shader_vtbl
=
1074 /* IUnknown methods */
1075 d3d11_geometry_shader_QueryInterface
,
1076 d3d11_geometry_shader_AddRef
,
1077 d3d11_geometry_shader_Release
,
1078 /* ID3D11DeviceChild methods */
1079 d3d11_geometry_shader_GetDevice
,
1080 d3d11_geometry_shader_GetPrivateData
,
1081 d3d11_geometry_shader_SetPrivateData
,
1082 d3d11_geometry_shader_SetPrivateDataInterface
,
1085 /* ID3D10GeometryShader methods */
1087 static inline struct d3d_geometry_shader
*impl_from_ID3D10GeometryShader(ID3D10GeometryShader
*iface
)
1089 return CONTAINING_RECORD(iface
, struct d3d_geometry_shader
, ID3D10GeometryShader_iface
);
1092 /* IUnknown methods */
1094 static HRESULT STDMETHODCALLTYPE
d3d10_geometry_shader_QueryInterface(ID3D10GeometryShader
*iface
,
1095 REFIID riid
, void **object
)
1097 struct d3d_geometry_shader
*shader
= impl_from_ID3D10GeometryShader(iface
);
1099 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
1101 return d3d11_geometry_shader_QueryInterface(&shader
->ID3D11GeometryShader_iface
, riid
, object
);
1104 static ULONG STDMETHODCALLTYPE
d3d10_geometry_shader_AddRef(ID3D10GeometryShader
*iface
)
1106 struct d3d_geometry_shader
*shader
= impl_from_ID3D10GeometryShader(iface
);
1108 TRACE("iface %p.\n", iface
);
1110 return d3d11_geometry_shader_AddRef(&shader
->ID3D11GeometryShader_iface
);
1113 static ULONG STDMETHODCALLTYPE
d3d10_geometry_shader_Release(ID3D10GeometryShader
*iface
)
1115 struct d3d_geometry_shader
*shader
= impl_from_ID3D10GeometryShader(iface
);
1117 TRACE("iface %p.\n", iface
);
1119 return d3d11_geometry_shader_Release(&shader
->ID3D11GeometryShader_iface
);
1122 /* ID3D10DeviceChild methods */
1124 static void STDMETHODCALLTYPE
d3d10_geometry_shader_GetDevice(ID3D10GeometryShader
*iface
, ID3D10Device
**device
)
1126 struct d3d_geometry_shader
*shader
= impl_from_ID3D10GeometryShader(iface
);
1128 TRACE("iface %p, device %p.\n", iface
, device
);
1130 ID3D11Device_QueryInterface(shader
->device
, &IID_ID3D10Device
, (void **)device
);
1133 static HRESULT STDMETHODCALLTYPE
d3d10_geometry_shader_GetPrivateData(ID3D10GeometryShader
*iface
,
1134 REFGUID guid
, UINT
*data_size
, void *data
)
1136 struct d3d_geometry_shader
*shader
= impl_from_ID3D10GeometryShader(iface
);
1138 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
1139 iface
, debugstr_guid(guid
), data_size
, data
);
1141 return d3d_get_private_data(&shader
->private_store
, guid
, data_size
, data
);
1144 static HRESULT STDMETHODCALLTYPE
d3d10_geometry_shader_SetPrivateData(ID3D10GeometryShader
*iface
,
1145 REFGUID guid
, UINT data_size
, const void *data
)
1147 struct d3d_geometry_shader
*shader
= impl_from_ID3D10GeometryShader(iface
);
1149 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
1150 iface
, debugstr_guid(guid
), data_size
, data
);
1152 return d3d_set_private_data(&shader
->private_store
, guid
, data_size
, data
);
1155 static HRESULT STDMETHODCALLTYPE
d3d10_geometry_shader_SetPrivateDataInterface(ID3D10GeometryShader
*iface
,
1156 REFGUID guid
, const IUnknown
*data
)
1158 struct d3d_geometry_shader
*shader
= impl_from_ID3D10GeometryShader(iface
);
1160 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
1162 return d3d_set_private_data_interface(&shader
->private_store
, guid
, data
);
1165 static const struct ID3D10GeometryShaderVtbl d3d10_geometry_shader_vtbl
=
1167 /* IUnknown methods */
1168 d3d10_geometry_shader_QueryInterface
,
1169 d3d10_geometry_shader_AddRef
,
1170 d3d10_geometry_shader_Release
,
1171 /* ID3D10DeviceChild methods */
1172 d3d10_geometry_shader_GetDevice
,
1173 d3d10_geometry_shader_GetPrivateData
,
1174 d3d10_geometry_shader_SetPrivateData
,
1175 d3d10_geometry_shader_SetPrivateDataInterface
,
1178 static void STDMETHODCALLTYPE
d3d_geometry_shader_wined3d_object_destroyed(void *parent
)
1180 struct d3d_geometry_shader
*shader
= parent
;
1182 wined3d_private_store_cleanup(&shader
->private_store
);
1183 HeapFree(GetProcessHeap(), 0, parent
);
1186 static const struct wined3d_parent_ops d3d_geometry_shader_wined3d_parent_ops
=
1188 d3d_geometry_shader_wined3d_object_destroyed
,
1191 static HRESULT
wined3d_so_elements_from_d3d11_so_entries(struct wined3d_stream_output_element
*elements
,
1192 const D3D11_SO_DECLARATION_ENTRY
*entries
, unsigned int entry_count
,
1193 const unsigned int *buffer_strides
, unsigned int buffer_stride_count
,
1194 const struct wined3d_shader_signature
*os
, D3D_FEATURE_LEVEL feature_level
)
1196 unsigned int i
, j
, mask
;
1198 for (i
= 0; i
< entry_count
; ++i
)
1200 struct wined3d_stream_output_element
*e
= &elements
[i
];
1201 const D3D11_SO_DECLARATION_ENTRY
*f
= &entries
[i
];
1202 struct wined3d_shader_signature_element
*output
;
1204 TRACE("Stream: %u, semantic: %s, semantic idx: %u, start component: %u, "
1205 "component count %u, output slot %u.\n",
1206 f
->Stream
, debugstr_a(f
->SemanticName
), f
->SemanticIndex
,
1207 f
->StartComponent
, f
->ComponentCount
, f
->OutputSlot
);
1209 if (f
->Stream
>= D3D11_SO_STREAM_COUNT
)
1211 WARN("Invalid stream %u.\n", f
->Stream
);
1212 return E_INVALIDARG
;
1214 if (f
->Stream
&& feature_level
< D3D_FEATURE_LEVEL_11_0
)
1216 WARN("Invalid stream %u for feature level %#x.\n", f
->Stream
, feature_level
);
1217 return E_INVALIDARG
;
1221 FIXME("Streams not implemented yet.\n");
1222 return E_INVALIDARG
;
1224 if (f
->OutputSlot
>= D3D11_SO_BUFFER_SLOT_COUNT
)
1226 WARN("Invalid output slot %u.\n", f
->OutputSlot
);
1227 return E_INVALIDARG
;
1230 e
->stream_idx
= f
->Stream
;
1231 e
->component_idx
= f
->StartComponent
;
1232 e
->component_count
= f
->ComponentCount
;
1233 e
->output_slot
= f
->OutputSlot
;
1235 if (!f
->SemanticName
)
1237 if (f
->SemanticIndex
)
1239 WARN("Invalid semantic idx %u for stream output gap.\n", f
->SemanticIndex
);
1240 return E_INVALIDARG
;
1242 if (e
->component_idx
|| !e
->component_count
)
1244 WARN("Invalid stream output gap %u-%u.\n", e
->component_idx
, e
->component_count
);
1245 return E_INVALIDARG
;
1248 e
->register_idx
= WINED3D_STREAM_OUTPUT_GAP
;
1250 else if ((output
= shader_find_signature_element(os
, f
->SemanticName
, f
->SemanticIndex
)))
1252 if (e
->component_idx
> 3 || e
->component_count
> 4 || !e
->component_count
1253 || e
->component_idx
+ e
->component_count
> 4)
1255 WARN("Invalid component range %u-%u.\n", e
->component_idx
, e
->component_count
);
1256 return E_INVALIDARG
;
1259 for (j
= 0; j
< 4; ++j
)
1261 if ((1u << j
) & output
->mask
)
1264 e
->component_idx
+= j
;
1265 mask
= ((1u << e
->component_count
) - 1) << e
->component_idx
;
1266 if ((output
->mask
& 0xff & mask
) != mask
)
1268 WARN("Invalid component range %u-%u (mask %#x), output mask %#x.\n",
1269 e
->component_idx
, e
->component_count
, mask
, output
->mask
& 0xff);
1270 return E_INVALIDARG
;
1273 e
->register_idx
= output
->register_idx
;
1274 TRACE("Register idx: %u, register component idx %u, register mask %#x.\n",
1275 e
->register_idx
, e
->component_idx
, mask
);
1279 WARN("Failed to find output signature element for stream output entry.\n");
1280 return E_INVALIDARG
;
1284 for (i
= 0; i
< entry_count
; ++i
)
1286 const struct wined3d_stream_output_element
*e1
= &elements
[i
];
1287 if (e1
->register_idx
== WINED3D_STREAM_OUTPUT_GAP
)
1290 for (j
= i
+ 1; j
< entry_count
; ++j
)
1292 const struct wined3d_stream_output_element
*e2
= &elements
[j
];
1294 if (e1
->register_idx
== e2
->register_idx
1295 && e1
->component_idx
< e2
->component_idx
+ e2
->component_count
1296 && e1
->component_idx
+ e1
->component_count
> e2
->component_idx
)
1298 WARN("Stream output elements %u and %u overlap.\n", i
, j
);
1299 return E_INVALIDARG
;
1304 for (i
= 0; i
< D3D11_SO_STREAM_COUNT
; ++i
)
1306 unsigned int current_stride
[D3D11_SO_BUFFER_SLOT_COUNT
] = {0};
1307 unsigned int element_count
[D3D11_SO_BUFFER_SLOT_COUNT
] = {0};
1308 unsigned int gap_count
[D3D11_SO_BUFFER_SLOT_COUNT
] = {0};
1310 for (j
= 0; j
< entry_count
; ++j
)
1312 const struct wined3d_stream_output_element
*e
= &elements
[j
];
1314 if (e
->stream_idx
!= i
)
1316 current_stride
[e
->output_slot
] += 4 * e
->component_count
;
1317 ++element_count
[e
->output_slot
];
1318 if (e
->register_idx
== WINED3D_STREAM_OUTPUT_GAP
)
1319 ++gap_count
[e
->output_slot
];
1322 for (j
= 0; j
< D3D11_SO_BUFFER_SLOT_COUNT
; ++j
)
1324 if (!element_count
[j
])
1326 if (element_count
[j
] == gap_count
[j
])
1328 WARN("Stream %u, output slot %u contains only gaps.\n", i
, j
);
1329 return E_INVALIDARG
;
1331 if (buffer_stride_count
)
1333 if (buffer_stride_count
<= j
)
1335 WARN("Buffer strides are required for all buffer slots.\n");
1336 return E_INVALIDARG
;
1338 if (buffer_strides
[j
] < current_stride
[j
] || buffer_strides
[j
] % 4)
1340 WARN("Invalid stride %u for buffer slot %u.\n", buffer_strides
[j
], j
);
1341 return E_INVALIDARG
;
1346 if (!i
&& feature_level
< D3D_FEATURE_LEVEL_11_0
&& element_count
[0] != entry_count
)
1348 for (j
= 0; j
< ARRAY_SIZE(element_count
); ++j
)
1350 if (element_count
[j
] > 1)
1352 WARN("Only one element per output slot is allowed.\n");
1353 return E_INVALIDARG
;
1362 static HRESULT
d3d_geometry_shader_init(struct d3d_geometry_shader
*shader
,
1363 struct d3d_device
*device
, const void *byte_code
, SIZE_T byte_code_length
,
1364 const D3D11_SO_DECLARATION_ENTRY
*so_entries
, unsigned int so_entry_count
,
1365 const unsigned int *buffer_strides
, unsigned int buffer_stride_count
,
1366 unsigned int rasterizer_stream
)
1368 struct wined3d_stream_output_desc so_desc
;
1369 struct wined3d_shader_desc desc
;
1373 if (so_entry_count
> D3D11_SO_STREAM_COUNT
* D3D11_SO_OUTPUT_COMPONENT_COUNT
)
1375 WARN("Entry count %u is greater than %u.\n",
1376 so_entry_count
, D3D11_SO_STREAM_COUNT
* D3D11_SO_OUTPUT_COMPONENT_COUNT
);
1377 return E_INVALIDARG
;
1379 if (so_entries
&& !so_entry_count
)
1381 WARN("Invalid SO entry count %u.\n", so_entry_count
);
1382 return E_INVALIDARG
;
1384 if (rasterizer_stream
!= D3D11_SO_NO_RASTERIZED_STREAM
&& rasterizer_stream
>= D3D11_SO_STREAM_COUNT
)
1386 WARN("Invalid rasterizer stream %u.\n", rasterizer_stream
);
1387 return E_INVALIDARG
;
1389 if (device
->feature_level
< D3D_FEATURE_LEVEL_11_0
)
1391 if (rasterizer_stream
)
1393 WARN("Invalid rasterizer stream %u for feature level %#x.\n",
1394 rasterizer_stream
, device
->feature_level
);
1395 return E_INVALIDARG
;
1397 if (buffer_stride_count
&& buffer_stride_count
!= 1)
1399 WARN("Invalid buffer stride count %u for feature level %#x.\n",
1400 buffer_stride_count
, device
->feature_level
);
1401 return E_INVALIDARG
;
1405 if (FAILED(hr
= shader_extract_from_dxbc(byte_code
, byte_code_length
, &desc
, device
->feature_level
)))
1407 WARN("Failed to extract shader, hr %#x.\n", hr
);
1410 desc
.max_version
= d3d_sm_from_feature_level(device
->feature_level
);
1412 memset(&so_desc
, 0, sizeof(so_desc
));
1415 so_desc
.element_count
= so_entry_count
;
1416 for (i
= 0; i
< min(buffer_stride_count
, ARRAY_SIZE(so_desc
.buffer_strides
)); ++i
)
1417 so_desc
.buffer_strides
[i
] = buffer_strides
[i
];
1418 so_desc
.buffer_stride_count
= buffer_stride_count
;
1419 so_desc
.rasterizer_stream_idx
= rasterizer_stream
;
1421 if (!(so_desc
.elements
= d3d11_calloc(so_entry_count
, sizeof(*so_desc
.elements
))))
1423 ERR("Failed to allocate wined3d stream output element array memory.\n");
1424 shader_free_signature(&desc
.input_signature
);
1425 shader_free_signature(&desc
.output_signature
);
1426 return E_OUTOFMEMORY
;
1428 if (FAILED(hr
= wined3d_so_elements_from_d3d11_so_entries(so_desc
.elements
,
1429 so_entries
, so_entry_count
, buffer_strides
, buffer_stride_count
,
1430 &desc
.output_signature
, device
->feature_level
)))
1432 HeapFree(GetProcessHeap(), 0, so_desc
.elements
);
1433 shader_free_signature(&desc
.input_signature
);
1434 shader_free_signature(&desc
.output_signature
);
1439 shader
->ID3D11GeometryShader_iface
.lpVtbl
= &d3d11_geometry_shader_vtbl
;
1440 shader
->ID3D10GeometryShader_iface
.lpVtbl
= &d3d10_geometry_shader_vtbl
;
1441 shader
->refcount
= 1;
1442 wined3d_mutex_lock();
1443 wined3d_private_store_init(&shader
->private_store
);
1445 hr
= wined3d_shader_create_gs(device
->wined3d_device
, &desc
, so_entries
? &so_desc
: NULL
,
1446 shader
, &d3d_geometry_shader_wined3d_parent_ops
, &shader
->wined3d_shader
);
1447 HeapFree(GetProcessHeap(), 0, so_desc
.elements
);
1448 shader_free_signature(&desc
.input_signature
);
1449 shader_free_signature(&desc
.output_signature
);
1452 WARN("Failed to create wined3d geometry shader, hr %#x.\n", hr
);
1453 wined3d_private_store_cleanup(&shader
->private_store
);
1454 wined3d_mutex_unlock();
1455 return E_INVALIDARG
;
1457 wined3d_mutex_unlock();
1459 shader
->device
= &device
->ID3D11Device_iface
;
1460 ID3D11Device_AddRef(shader
->device
);
1465 HRESULT
d3d_geometry_shader_create(struct d3d_device
*device
, const void *byte_code
, SIZE_T byte_code_length
,
1466 const D3D11_SO_DECLARATION_ENTRY
*so_entries
, unsigned int so_entry_count
,
1467 const unsigned int *buffer_strides
, unsigned int buffer_stride_count
, unsigned int rasterizer_stream
,
1468 struct d3d_geometry_shader
**shader
)
1470 struct d3d_geometry_shader
*object
;
1473 if (!(object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*object
))))
1474 return E_OUTOFMEMORY
;
1476 if (FAILED(hr
= d3d_geometry_shader_init(object
, device
, byte_code
, byte_code_length
,
1477 so_entries
, so_entry_count
, buffer_strides
, buffer_stride_count
, rasterizer_stream
)))
1479 WARN("Failed to initialize geometry shader, hr %#x.\n", hr
);
1480 HeapFree(GetProcessHeap(), 0, object
);
1484 TRACE("Created geometry shader %p.\n", object
);
1490 struct d3d_geometry_shader
*unsafe_impl_from_ID3D11GeometryShader(ID3D11GeometryShader
*iface
)
1494 assert(iface
->lpVtbl
== &d3d11_geometry_shader_vtbl
);
1496 return impl_from_ID3D11GeometryShader(iface
);
1499 struct d3d_geometry_shader
*unsafe_impl_from_ID3D10GeometryShader(ID3D10GeometryShader
*iface
)
1503 assert(iface
->lpVtbl
== &d3d10_geometry_shader_vtbl
);
1505 return impl_from_ID3D10GeometryShader(iface
);
1508 /* ID3D11PixelShader methods */
1510 static inline struct d3d_pixel_shader
*impl_from_ID3D11PixelShader(ID3D11PixelShader
*iface
)
1512 return CONTAINING_RECORD(iface
, struct d3d_pixel_shader
, ID3D11PixelShader_iface
);
1515 static HRESULT STDMETHODCALLTYPE
d3d11_pixel_shader_QueryInterface(ID3D11PixelShader
*iface
,
1516 REFIID riid
, void **object
)
1518 struct d3d_pixel_shader
*shader
= impl_from_ID3D11PixelShader(iface
);
1520 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
1522 if (IsEqualGUID(riid
, &IID_ID3D11PixelShader
)
1523 || IsEqualGUID(riid
, &IID_ID3D11DeviceChild
)
1524 || IsEqualGUID(riid
, &IID_IUnknown
))
1526 ID3D11PixelShader_AddRef(iface
);
1531 if (IsEqualGUID(riid
, &IID_ID3D10PixelShader
)
1532 || IsEqualGUID(riid
, &IID_ID3D10DeviceChild
))
1534 IUnknown_AddRef(&shader
->ID3D10PixelShader_iface
);
1535 *object
= &shader
->ID3D10PixelShader_iface
;
1539 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
1542 return E_NOINTERFACE
;
1545 static ULONG STDMETHODCALLTYPE
d3d11_pixel_shader_AddRef(ID3D11PixelShader
*iface
)
1547 struct d3d_pixel_shader
*shader
= impl_from_ID3D11PixelShader(iface
);
1548 ULONG refcount
= InterlockedIncrement(&shader
->refcount
);
1550 TRACE("%p increasing refcount to %u.\n", shader
, refcount
);
1554 ID3D11Device_AddRef(shader
->device
);
1555 wined3d_mutex_lock();
1556 wined3d_shader_incref(shader
->wined3d_shader
);
1557 wined3d_mutex_unlock();
1563 static ULONG STDMETHODCALLTYPE
d3d11_pixel_shader_Release(ID3D11PixelShader
*iface
)
1565 struct d3d_pixel_shader
*shader
= impl_from_ID3D11PixelShader(iface
);
1566 ULONG refcount
= InterlockedDecrement(&shader
->refcount
);
1568 TRACE("%p decreasing refcount to %u.\n", shader
, refcount
);
1572 ID3D11Device
*device
= shader
->device
;
1574 wined3d_mutex_lock();
1575 wined3d_shader_decref(shader
->wined3d_shader
);
1576 wined3d_mutex_unlock();
1577 /* Release the device last, it may cause the wined3d device to be
1579 ID3D11Device_Release(device
);
1585 static void STDMETHODCALLTYPE
d3d11_pixel_shader_GetDevice(ID3D11PixelShader
*iface
,
1586 ID3D11Device
**device
)
1588 struct d3d_pixel_shader
*shader
= impl_from_ID3D11PixelShader(iface
);
1590 TRACE("iface %p, device %p.\n", iface
, device
);
1592 *device
= shader
->device
;
1593 ID3D11Device_AddRef(*device
);
1596 static HRESULT STDMETHODCALLTYPE
d3d11_pixel_shader_GetPrivateData(ID3D11PixelShader
*iface
,
1597 REFGUID guid
, UINT
*data_size
, void *data
)
1599 struct d3d_pixel_shader
*shader
= impl_from_ID3D11PixelShader(iface
);
1601 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
1603 return d3d_get_private_data(&shader
->private_store
, guid
, data_size
, data
);
1606 static HRESULT STDMETHODCALLTYPE
d3d11_pixel_shader_SetPrivateData(ID3D11PixelShader
*iface
,
1607 REFGUID guid
, UINT data_size
, const void *data
)
1609 struct d3d_pixel_shader
*shader
= impl_from_ID3D11PixelShader(iface
);
1611 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
1613 return d3d_set_private_data(&shader
->private_store
, guid
, data_size
, data
);
1616 static HRESULT STDMETHODCALLTYPE
d3d11_pixel_shader_SetPrivateDataInterface(ID3D11PixelShader
*iface
,
1617 REFGUID guid
, const IUnknown
*data
)
1619 struct d3d_pixel_shader
*shader
= impl_from_ID3D11PixelShader(iface
);
1621 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
1623 return d3d_set_private_data_interface(&shader
->private_store
, guid
, data
);
1626 static const struct ID3D11PixelShaderVtbl d3d11_pixel_shader_vtbl
=
1628 /* IUnknown methods */
1629 d3d11_pixel_shader_QueryInterface
,
1630 d3d11_pixel_shader_AddRef
,
1631 d3d11_pixel_shader_Release
,
1632 /* ID3D11DeviceChild methods */
1633 d3d11_pixel_shader_GetDevice
,
1634 d3d11_pixel_shader_GetPrivateData
,
1635 d3d11_pixel_shader_SetPrivateData
,
1636 d3d11_pixel_shader_SetPrivateDataInterface
,
1639 /* ID3D10PixelShader methods */
1641 static inline struct d3d_pixel_shader
*impl_from_ID3D10PixelShader(ID3D10PixelShader
*iface
)
1643 return CONTAINING_RECORD(iface
, struct d3d_pixel_shader
, ID3D10PixelShader_iface
);
1646 /* IUnknown methods */
1648 static HRESULT STDMETHODCALLTYPE
d3d10_pixel_shader_QueryInterface(ID3D10PixelShader
*iface
,
1649 REFIID riid
, void **object
)
1651 struct d3d_pixel_shader
*shader
= impl_from_ID3D10PixelShader(iface
);
1653 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
1655 return d3d11_pixel_shader_QueryInterface(&shader
->ID3D11PixelShader_iface
, riid
, object
);
1658 static ULONG STDMETHODCALLTYPE
d3d10_pixel_shader_AddRef(ID3D10PixelShader
*iface
)
1660 struct d3d_pixel_shader
*shader
= impl_from_ID3D10PixelShader(iface
);
1662 TRACE("iface %p.\n", iface
);
1664 return d3d11_pixel_shader_AddRef(&shader
->ID3D11PixelShader_iface
);
1667 static ULONG STDMETHODCALLTYPE
d3d10_pixel_shader_Release(ID3D10PixelShader
*iface
)
1669 struct d3d_pixel_shader
*shader
= impl_from_ID3D10PixelShader(iface
);
1671 TRACE("iface %p.\n", iface
);
1673 return d3d11_pixel_shader_Release(&shader
->ID3D11PixelShader_iface
);
1676 /* ID3D10DeviceChild methods */
1678 static void STDMETHODCALLTYPE
d3d10_pixel_shader_GetDevice(ID3D10PixelShader
*iface
, ID3D10Device
**device
)
1680 struct d3d_pixel_shader
*shader
= impl_from_ID3D10PixelShader(iface
);
1682 TRACE("iface %p, device %p.\n", iface
, device
);
1684 ID3D11Device_QueryInterface(shader
->device
, &IID_ID3D10Device
, (void **)device
);
1687 static HRESULT STDMETHODCALLTYPE
d3d10_pixel_shader_GetPrivateData(ID3D10PixelShader
*iface
,
1688 REFGUID guid
, UINT
*data_size
, void *data
)
1690 struct d3d_pixel_shader
*shader
= impl_from_ID3D10PixelShader(iface
);
1692 TRACE("iface %p, guid %s, data_size %p, data %p.\n",
1693 iface
, debugstr_guid(guid
), data_size
, data
);
1695 return d3d_get_private_data(&shader
->private_store
, guid
, data_size
, data
);
1698 static HRESULT STDMETHODCALLTYPE
d3d10_pixel_shader_SetPrivateData(ID3D10PixelShader
*iface
,
1699 REFGUID guid
, UINT data_size
, const void *data
)
1701 struct d3d_pixel_shader
*shader
= impl_from_ID3D10PixelShader(iface
);
1703 TRACE("iface %p, guid %s, data_size %u, data %p.\n",
1704 iface
, debugstr_guid(guid
), data_size
, data
);
1706 return d3d_set_private_data(&shader
->private_store
, guid
, data_size
, data
);
1709 static HRESULT STDMETHODCALLTYPE
d3d10_pixel_shader_SetPrivateDataInterface(ID3D10PixelShader
*iface
,
1710 REFGUID guid
, const IUnknown
*data
)
1712 struct d3d_pixel_shader
*shader
= impl_from_ID3D10PixelShader(iface
);
1714 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
1716 return d3d_set_private_data_interface(&shader
->private_store
, guid
, data
);
1719 static const struct ID3D10PixelShaderVtbl d3d10_pixel_shader_vtbl
=
1721 /* IUnknown methods */
1722 d3d10_pixel_shader_QueryInterface
,
1723 d3d10_pixel_shader_AddRef
,
1724 d3d10_pixel_shader_Release
,
1725 /* ID3D10DeviceChild methods */
1726 d3d10_pixel_shader_GetDevice
,
1727 d3d10_pixel_shader_GetPrivateData
,
1728 d3d10_pixel_shader_SetPrivateData
,
1729 d3d10_pixel_shader_SetPrivateDataInterface
,
1732 static void STDMETHODCALLTYPE
d3d_pixel_shader_wined3d_object_destroyed(void *parent
)
1734 struct d3d_pixel_shader
*shader
= parent
;
1736 wined3d_private_store_cleanup(&shader
->private_store
);
1737 HeapFree(GetProcessHeap(), 0, parent
);
1740 static const struct wined3d_parent_ops d3d_pixel_shader_wined3d_parent_ops
=
1742 d3d_pixel_shader_wined3d_object_destroyed
,
1745 static HRESULT
d3d_pixel_shader_init(struct d3d_pixel_shader
*shader
, struct d3d_device
*device
,
1746 const void *byte_code
, SIZE_T byte_code_length
)
1748 struct wined3d_shader_desc desc
;
1751 shader
->ID3D11PixelShader_iface
.lpVtbl
= &d3d11_pixel_shader_vtbl
;
1752 shader
->ID3D10PixelShader_iface
.lpVtbl
= &d3d10_pixel_shader_vtbl
;
1753 shader
->refcount
= 1;
1754 wined3d_mutex_lock();
1755 wined3d_private_store_init(&shader
->private_store
);
1757 if (FAILED(hr
= shader_extract_from_dxbc(byte_code
, byte_code_length
, &desc
, device
->feature_level
)))
1759 WARN("Failed to extract shader, hr %#x.\n", hr
);
1760 wined3d_private_store_cleanup(&shader
->private_store
);
1761 wined3d_mutex_unlock();
1764 desc
.max_version
= d3d_sm_from_feature_level(device
->feature_level
);
1766 hr
= wined3d_shader_create_ps(device
->wined3d_device
, &desc
, shader
,
1767 &d3d_pixel_shader_wined3d_parent_ops
, &shader
->wined3d_shader
);
1768 shader_free_signature(&desc
.input_signature
);
1769 shader_free_signature(&desc
.output_signature
);
1772 WARN("Failed to create wined3d pixel shader, hr %#x.\n", hr
);
1773 wined3d_private_store_cleanup(&shader
->private_store
);
1774 wined3d_mutex_unlock();
1775 return E_INVALIDARG
;
1777 wined3d_mutex_unlock();
1779 shader
->device
= &device
->ID3D11Device_iface
;
1780 ID3D11Device_AddRef(shader
->device
);
1785 HRESULT
d3d_pixel_shader_create(struct d3d_device
*device
, const void *byte_code
, SIZE_T byte_code_length
,
1786 struct d3d_pixel_shader
**shader
)
1788 struct d3d_pixel_shader
*object
;
1791 if (!(object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*object
))))
1792 return E_OUTOFMEMORY
;
1794 if (FAILED(hr
= d3d_pixel_shader_init(object
, device
, byte_code
, byte_code_length
)))
1796 WARN("Failed to initialize pixel shader, hr %#x.\n", hr
);
1797 HeapFree(GetProcessHeap(), 0, object
);
1801 TRACE("Created pixel shader %p.\n", object
);
1807 struct d3d_pixel_shader
*unsafe_impl_from_ID3D11PixelShader(ID3D11PixelShader
*iface
)
1811 assert(iface
->lpVtbl
== &d3d11_pixel_shader_vtbl
);
1813 return impl_from_ID3D11PixelShader(iface
);
1816 struct d3d_pixel_shader
*unsafe_impl_from_ID3D10PixelShader(ID3D10PixelShader
*iface
)
1820 assert(iface
->lpVtbl
== &d3d10_pixel_shader_vtbl
);
1822 return impl_from_ID3D10PixelShader(iface
);
1825 /* ID3D11ComputeShader methods */
1827 static inline struct d3d11_compute_shader
*impl_from_ID3D11ComputeShader(ID3D11ComputeShader
*iface
)
1829 return CONTAINING_RECORD(iface
, struct d3d11_compute_shader
, ID3D11ComputeShader_iface
);
1832 static HRESULT STDMETHODCALLTYPE
d3d11_compute_shader_QueryInterface(ID3D11ComputeShader
*iface
,
1833 REFIID riid
, void **object
)
1835 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
1837 if (IsEqualGUID(riid
, &IID_ID3D11ComputeShader
)
1838 || IsEqualGUID(riid
, &IID_ID3D11DeviceChild
)
1839 || IsEqualGUID(riid
, &IID_IUnknown
))
1841 ID3D11ComputeShader_AddRef(*object
= iface
);
1845 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
1848 return E_NOINTERFACE
;
1851 static ULONG STDMETHODCALLTYPE
d3d11_compute_shader_AddRef(ID3D11ComputeShader
*iface
)
1853 struct d3d11_compute_shader
*shader
= impl_from_ID3D11ComputeShader(iface
);
1854 ULONG refcount
= InterlockedIncrement(&shader
->refcount
);
1856 TRACE("%p increasing refcount to %u.\n", shader
, refcount
);
1861 static ULONG STDMETHODCALLTYPE
d3d11_compute_shader_Release(ID3D11ComputeShader
*iface
)
1863 struct d3d11_compute_shader
*shader
= impl_from_ID3D11ComputeShader(iface
);
1864 ULONG refcount
= InterlockedDecrement(&shader
->refcount
);
1866 TRACE("%p decreasing refcount to %u.\n", shader
, refcount
);
1870 ID3D11Device
*device
= shader
->device
;
1872 wined3d_mutex_lock();
1873 wined3d_shader_decref(shader
->wined3d_shader
);
1874 wined3d_mutex_unlock();
1876 /* Release the device last, it may cause the wined3d device to be
1878 ID3D11Device_Release(device
);
1884 static void STDMETHODCALLTYPE
d3d11_compute_shader_GetDevice(ID3D11ComputeShader
*iface
,
1885 ID3D11Device
**device
)
1887 struct d3d11_compute_shader
*shader
= impl_from_ID3D11ComputeShader(iface
);
1889 TRACE("iface %p, device %p.\n", iface
, device
);
1891 ID3D11Device_AddRef(*device
= shader
->device
);
1894 static HRESULT STDMETHODCALLTYPE
d3d11_compute_shader_GetPrivateData(ID3D11ComputeShader
*iface
,
1895 REFGUID guid
, UINT
*data_size
, void *data
)
1897 struct d3d11_compute_shader
*shader
= impl_from_ID3D11ComputeShader(iface
);
1899 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
1901 return d3d_get_private_data(&shader
->private_store
, guid
, data_size
, data
);
1904 static HRESULT STDMETHODCALLTYPE
d3d11_compute_shader_SetPrivateData(ID3D11ComputeShader
*iface
,
1905 REFGUID guid
, UINT data_size
, const void *data
)
1907 struct d3d11_compute_shader
*shader
= impl_from_ID3D11ComputeShader(iface
);
1909 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
1911 return d3d_set_private_data(&shader
->private_store
, guid
, data_size
, data
);
1914 static HRESULT STDMETHODCALLTYPE
d3d11_compute_shader_SetPrivateDataInterface(ID3D11ComputeShader
*iface
,
1915 REFGUID guid
, const IUnknown
*data
)
1917 struct d3d11_compute_shader
*shader
= impl_from_ID3D11ComputeShader(iface
);
1919 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
1921 return d3d_set_private_data_interface(&shader
->private_store
, guid
, data
);
1924 static const struct ID3D11ComputeShaderVtbl d3d11_compute_shader_vtbl
=
1926 /* IUnknown methods */
1927 d3d11_compute_shader_QueryInterface
,
1928 d3d11_compute_shader_AddRef
,
1929 d3d11_compute_shader_Release
,
1930 /* ID3D11DeviceChild methods */
1931 d3d11_compute_shader_GetDevice
,
1932 d3d11_compute_shader_GetPrivateData
,
1933 d3d11_compute_shader_SetPrivateData
,
1934 d3d11_compute_shader_SetPrivateDataInterface
,
1937 static void STDMETHODCALLTYPE
d3d11_compute_shader_wined3d_object_destroyed(void *parent
)
1939 struct d3d11_compute_shader
*shader
= parent
;
1941 wined3d_private_store_cleanup(&shader
->private_store
);
1942 HeapFree(GetProcessHeap(), 0, parent
);
1945 static const struct wined3d_parent_ops d3d11_compute_shader_wined3d_parent_ops
=
1947 d3d11_compute_shader_wined3d_object_destroyed
,
1950 static HRESULT
d3d11_compute_shader_init(struct d3d11_compute_shader
*shader
, struct d3d_device
*device
,
1951 const void *byte_code
, SIZE_T byte_code_length
)
1953 struct wined3d_shader_desc desc
;
1956 shader
->ID3D11ComputeShader_iface
.lpVtbl
= &d3d11_compute_shader_vtbl
;
1957 shader
->refcount
= 1;
1958 wined3d_mutex_lock();
1959 wined3d_private_store_init(&shader
->private_store
);
1961 if (FAILED(hr
= shader_extract_from_dxbc(byte_code
, byte_code_length
, &desc
, device
->feature_level
)))
1963 WARN("Failed to extract shader, hr %#x.\n", hr
);
1964 wined3d_private_store_cleanup(&shader
->private_store
);
1965 wined3d_mutex_unlock();
1968 desc
.max_version
= d3d_sm_from_feature_level(device
->feature_level
);
1970 hr
= wined3d_shader_create_cs(device
->wined3d_device
, &desc
, shader
,
1971 &d3d11_compute_shader_wined3d_parent_ops
, &shader
->wined3d_shader
);
1972 shader_free_signature(&desc
.input_signature
);
1973 shader_free_signature(&desc
.output_signature
);
1976 WARN("Failed to create wined3d compute shader, hr %#x.\n", hr
);
1977 wined3d_private_store_cleanup(&shader
->private_store
);
1978 wined3d_mutex_unlock();
1979 return E_INVALIDARG
;
1981 wined3d_mutex_unlock();
1983 ID3D11Device_AddRef(shader
->device
= &device
->ID3D11Device_iface
);
1988 HRESULT
d3d11_compute_shader_create(struct d3d_device
*device
, const void *byte_code
, SIZE_T byte_code_length
,
1989 struct d3d11_compute_shader
**shader
)
1991 struct d3d11_compute_shader
*object
;
1994 if (!(object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*object
))))
1995 return E_OUTOFMEMORY
;
1997 if (FAILED(hr
= d3d11_compute_shader_init(object
, device
, byte_code
, byte_code_length
)))
1999 HeapFree(GetProcessHeap(), 0, object
);
2003 TRACE("Created compute shader %p.\n", object
);
2009 struct d3d11_compute_shader
*unsafe_impl_from_ID3D11ComputeShader(ID3D11ComputeShader
*iface
)
2013 assert(iface
->lpVtbl
== &d3d11_compute_shader_vtbl
);
2015 return impl_from_ID3D11ComputeShader(iface
);
2018 /* ID3D11ClassLinkage methods */
2020 static inline struct d3d11_class_linkage
*impl_from_ID3D11ClassLinkage(ID3D11ClassLinkage
*iface
)
2022 return CONTAINING_RECORD(iface
, struct d3d11_class_linkage
, ID3D11ClassLinkage_iface
);
2025 static HRESULT STDMETHODCALLTYPE
d3d11_class_linkage_QueryInterface(ID3D11ClassLinkage
*iface
,
2026 REFIID riid
, void **object
)
2028 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), object
);
2030 if (IsEqualGUID(riid
, &IID_ID3D11ClassLinkage
)
2031 || IsEqualGUID(riid
, &IID_ID3D11DeviceChild
)
2032 || IsEqualGUID(riid
, &IID_IUnknown
))
2034 ID3D11ClassLinkage_AddRef(*object
= iface
);
2038 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
2041 return E_NOINTERFACE
;
2044 static ULONG STDMETHODCALLTYPE
d3d11_class_linkage_AddRef(ID3D11ClassLinkage
*iface
)
2046 struct d3d11_class_linkage
*class_linkage
= impl_from_ID3D11ClassLinkage(iface
);
2047 ULONG refcount
= InterlockedIncrement(&class_linkage
->refcount
);
2049 TRACE("%p increasing refcount to %u.\n", class_linkage
, refcount
);
2054 static ULONG STDMETHODCALLTYPE
d3d11_class_linkage_Release(ID3D11ClassLinkage
*iface
)
2056 struct d3d11_class_linkage
*class_linkage
= impl_from_ID3D11ClassLinkage(iface
);
2057 ULONG refcount
= InterlockedDecrement(&class_linkage
->refcount
);
2059 TRACE("%p decreasing refcount to %u.\n", class_linkage
, refcount
);
2063 wined3d_private_store_cleanup(&class_linkage
->private_store
);
2064 HeapFree(GetProcessHeap(), 0, class_linkage
);
2070 static void STDMETHODCALLTYPE
d3d11_class_linkage_GetDevice(ID3D11ClassLinkage
*iface
,
2071 ID3D11Device
**device
)
2073 FIXME("iface %p, device %p stub!\n", iface
, device
);
2076 static HRESULT STDMETHODCALLTYPE
d3d11_class_linkage_GetPrivateData(ID3D11ClassLinkage
*iface
,
2077 REFGUID guid
, UINT
*data_size
, void *data
)
2079 struct d3d11_class_linkage
*class_linkage
= impl_from_ID3D11ClassLinkage(iface
);
2081 TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
2083 return d3d_get_private_data(&class_linkage
->private_store
, guid
, data_size
, data
);
2086 static HRESULT STDMETHODCALLTYPE
d3d11_class_linkage_SetPrivateData(ID3D11ClassLinkage
*iface
,
2087 REFGUID guid
, UINT data_size
, const void *data
)
2089 struct d3d11_class_linkage
*class_linkage
= impl_from_ID3D11ClassLinkage(iface
);
2091 TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface
, debugstr_guid(guid
), data_size
, data
);
2093 return d3d_set_private_data(&class_linkage
->private_store
, guid
, data_size
, data
);
2096 static HRESULT STDMETHODCALLTYPE
d3d11_class_linkage_SetPrivateDataInterface(ID3D11ClassLinkage
*iface
,
2097 REFGUID guid
, const IUnknown
*data
)
2099 struct d3d11_class_linkage
*class_linkage
= impl_from_ID3D11ClassLinkage(iface
);
2101 TRACE("iface %p, guid %s, data %p.\n", iface
, debugstr_guid(guid
), data
);
2103 return d3d_set_private_data_interface(&class_linkage
->private_store
, guid
, data
);
2106 static HRESULT STDMETHODCALLTYPE
d3d11_class_linkage_GetClassInstance(ID3D11ClassLinkage
*iface
,
2107 const char *instance_name
, UINT instance_index
, ID3D11ClassInstance
**class_instance
)
2109 FIXME("iface %p, instance_name %s, instance_index %u, class_instance %p stub!\n",
2110 iface
, debugstr_a(instance_name
), instance_index
, class_instance
);
2115 static HRESULT STDMETHODCALLTYPE
d3d11_class_linkage_CreateClassInstance(ID3D11ClassLinkage
*iface
,
2116 const char *type_name
, UINT cb_offset
, UINT cb_vector_offset
, UINT texture_offset
,
2117 UINT sampler_offset
, ID3D11ClassInstance
**class_instance
)
2119 FIXME("iface %p, type_name %s, cb_offset %u, cb_vector_offset %u, texture_offset %u, "
2120 "sampler_offset %u, class_instance %p stub!\n",
2121 iface
, debugstr_a(type_name
), cb_offset
, cb_vector_offset
, texture_offset
,
2122 sampler_offset
, class_instance
);
2127 static const struct ID3D11ClassLinkageVtbl d3d11_class_linkage_vtbl
=
2129 /* IUnknown methods */
2130 d3d11_class_linkage_QueryInterface
,
2131 d3d11_class_linkage_AddRef
,
2132 d3d11_class_linkage_Release
,
2133 /* ID3D11DeviceChild methods */
2134 d3d11_class_linkage_GetDevice
,
2135 d3d11_class_linkage_GetPrivateData
,
2136 d3d11_class_linkage_SetPrivateData
,
2137 d3d11_class_linkage_SetPrivateDataInterface
,
2138 /* ID3D11ClassLinkage methods */
2139 d3d11_class_linkage_GetClassInstance
,
2140 d3d11_class_linkage_CreateClassInstance
,
2143 HRESULT
d3d11_class_linkage_create(struct d3d_device
*device
, struct d3d11_class_linkage
**class_linkage
)
2145 struct d3d11_class_linkage
*object
;
2147 if (!(object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*object
))))
2148 return E_OUTOFMEMORY
;
2150 object
->ID3D11ClassLinkage_iface
.lpVtbl
= &d3d11_class_linkage_vtbl
;
2151 object
->refcount
= 1;
2152 wined3d_private_store_init(&object
->private_store
);
2154 TRACE("Created class linkage %p.\n", object
);
2155 *class_linkage
= object
;