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 "d3d10core_private.h"
25 WINE_DEFAULT_DEBUG_CHANNEL(d3d10core
);
27 struct input_signature_element
29 const char *semantic_name
;
31 DWORD unknown
; /* system value semantic? */
37 struct input_signature
39 struct input_signature_element
*elements
;
43 static HRESULT
parse_isgn(const char *data
, struct input_signature
*is
)
45 struct input_signature_element
*e
;
46 const char *ptr
= data
;
50 read_dword(&ptr
, &count
);
51 TRACE("%u elements\n", count
);
53 skip_dword_unknown(&ptr
, 1);
55 e
= HeapAlloc(GetProcessHeap(), 0, count
* sizeof(*e
));
58 ERR("Failed to allocate input signature memory.\n");
62 for (i
= 0; i
< count
; ++i
)
66 read_dword(&ptr
, &name_offset
);
67 e
[i
].semantic_name
= data
+ name_offset
;
68 read_dword(&ptr
, &e
[i
].semantic_idx
);
69 read_dword(&ptr
, &e
[i
].unknown
);
70 read_dword(&ptr
, &e
[i
].component_type
);
71 read_dword(&ptr
, &e
[i
].register_idx
);
72 read_dword(&ptr
, &e
[i
].mask
);
74 TRACE("semantic: %s, semantic idx: %u, unknown %#x, type %u, register idx: %u, use_mask %#x, input_mask %#x\n",
75 e
[i
].semantic_name
, e
[i
].semantic_idx
, e
[i
].unknown
, e
[i
].component_type
,
76 e
[i
].register_idx
, (e
[i
].mask
>> 8) & 0xff, e
[i
].mask
& 0xff);
80 is
->element_count
= count
;
85 static HRESULT
isgn_handler(const char *data
, DWORD data_size
, DWORD tag
, void *ctx
)
87 struct input_signature
*is
= ctx
;
88 const char *ptr
= data
;
94 return parse_isgn(ptr
, is
);
97 memcpy(tag_str
, &tag
, 4);
99 FIXME("Unhandled chunk %s\n", tag_str
);
104 HRESULT
d3d10_input_layout_to_wined3d_declaration(const D3D10_INPUT_ELEMENT_DESC
*element_descs
,
105 UINT element_count
, const void *shader_byte_code
, SIZE_T shader_byte_code_length
,
106 WINED3DVERTEXELEMENT
**wined3d_elements
, UINT
*wined3d_element_count
)
108 struct input_signature is
;
112 hr
= parse_dxbc(shader_byte_code
, shader_byte_code_length
, isgn_handler
, &is
);
115 ERR("Failed to parse input signature.\n");
119 *wined3d_elements
= HeapAlloc(GetProcessHeap(), 0, element_count
* sizeof(**wined3d_elements
));
120 if (!*wined3d_elements
)
122 ERR("Failed to allocate wined3d vertex element array memory.\n");
123 HeapFree(GetProcessHeap(), 0, is
.elements
);
124 return E_OUTOFMEMORY
;
126 *wined3d_element_count
= 0;
128 for (i
= 0; i
< element_count
; ++i
)
132 for (j
= 0; j
< is
.element_count
; ++j
)
134 if (!strcmp(element_descs
[i
].SemanticName
, is
.elements
[j
].semantic_name
)
135 && element_descs
[i
].SemanticIndex
== is
.elements
[j
].semantic_idx
)
137 WINED3DVERTEXELEMENT
*e
= &(*wined3d_elements
)[(*wined3d_element_count
)++];
138 const D3D10_INPUT_ELEMENT_DESC
*f
= &element_descs
[i
];
140 e
->format
= wined3dformat_from_dxgi_format(f
->Format
);
141 e
->input_slot
= f
->InputSlot
;
142 e
->offset
= f
->AlignedByteOffset
;
143 e
->output_slot
= is
.elements
[j
].register_idx
;
144 e
->method
= WINED3DDECLMETHOD_DEFAULT
;
148 if (f
->AlignedByteOffset
== D3D10_APPEND_ALIGNED_ELEMENT
)
149 FIXME("D3D10_APPEND_ALIGNED_ELEMENT not supported\n");
150 if (f
->InputSlotClass
!= D3D10_INPUT_PER_VERTEX_DATA
)
151 FIXME("Ignoring input slot class (%#x)\n", f
->InputSlotClass
);
152 if (f
->InstanceDataStepRate
)
153 FIXME("Ignoring instace data step rate (%#x)\n", f
->InstanceDataStepRate
);
160 HeapFree(GetProcessHeap(), 0, is
.elements
);
165 /* IUnknown methods */
167 static HRESULT STDMETHODCALLTYPE
d3d10_input_layout_QueryInterface(ID3D10InputLayout
*iface
,
168 REFIID riid
, void **object
)
170 TRACE("iface %p, riid %s, object %p\n", iface
, debugstr_guid(riid
), object
);
172 if (IsEqualGUID(riid
, &IID_ID3D10InputLayout
)
173 || IsEqualGUID(riid
, &IID_ID3D10DeviceChild
)
174 || IsEqualGUID(riid
, &IID_IUnknown
))
176 IUnknown_AddRef(iface
);
181 WARN("%s not implemented, returning E_NOINTERFACE\n", debugstr_guid(riid
));
184 return E_NOINTERFACE
;
187 static ULONG STDMETHODCALLTYPE
d3d10_input_layout_AddRef(ID3D10InputLayout
*iface
)
189 struct d3d10_input_layout
*This
= (struct d3d10_input_layout
*)iface
;
190 ULONG refcount
= InterlockedIncrement(&This
->refcount
);
192 TRACE("%p increasing refcount to %u\n", This
, refcount
);
197 static ULONG STDMETHODCALLTYPE
d3d10_input_layout_Release(ID3D10InputLayout
*iface
)
199 struct d3d10_input_layout
*This
= (struct d3d10_input_layout
*)iface
;
200 ULONG refcount
= InterlockedDecrement(&This
->refcount
);
202 TRACE("%p decreasing refcount to %u\n", This
, refcount
);
206 IWineD3DVertexDeclaration_Release(This
->wined3d_decl
);
207 HeapFree(GetProcessHeap(), 0, This
);
213 /* ID3D10DeviceChild methods */
215 static void STDMETHODCALLTYPE
d3d10_input_layout_GetDevice(ID3D10InputLayout
*iface
, ID3D10Device
**device
)
217 FIXME("iface %p, device %p stub!\n", iface
, device
);
220 static HRESULT STDMETHODCALLTYPE
d3d10_input_layout_GetPrivateData(ID3D10InputLayout
*iface
,
221 REFGUID guid
, UINT
*data_size
, void *data
)
223 FIXME("iface %p, guid %s, data_size %p, data %p stub!\n",
224 iface
, debugstr_guid(guid
), data_size
, data
);
229 static HRESULT STDMETHODCALLTYPE
d3d10_input_layout_SetPrivateData(ID3D10InputLayout
*iface
,
230 REFGUID guid
, UINT data_size
, const void *data
)
232 FIXME("iface %p, guid %s, data_size %u, data %p stub!\n",
233 iface
, debugstr_guid(guid
), data_size
, data
);
238 static HRESULT STDMETHODCALLTYPE
d3d10_input_layout_SetPrivateDataInterface(ID3D10InputLayout
*iface
,
239 REFGUID guid
, const IUnknown
*data
)
241 FIXME("iface %p, guid %s, data %p stub!\n", iface
, debugstr_guid(guid
), data
);
246 const struct ID3D10InputLayoutVtbl d3d10_input_layout_vtbl
=
248 /* IUnknown methods */
249 d3d10_input_layout_QueryInterface
,
250 d3d10_input_layout_AddRef
,
251 d3d10_input_layout_Release
,
252 /* ID3D10DeviceChild methods */
253 d3d10_input_layout_GetDevice
,
254 d3d10_input_layout_GetPrivateData
,
255 d3d10_input_layout_SetPrivateData
,
256 d3d10_input_layout_SetPrivateDataInterface
,