d3dx9_36: Rename variables in D3DXGetShaderConstantTable(Ex) to match naming conventi...
[wine] / dlls / d3dx9_36 / shader.c
1 /*
2  * Copyright 2008 Luis Busquets
3  *
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.
8  *
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.
13  *
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
17  */
18
19 #include "config.h"
20 #include "wine/port.h"
21 #include "wine/debug.h"
22 #include "wine/unicode.h"
23 #include "windef.h"
24 #include "wingdi.h"
25 #include "d3dx9.h"
26 #include "d3dx9shader.h"
27 #include "d3dx9_36_private.h"
28
29 WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
30
31 LPCSTR WINAPI D3DXGetPixelShaderProfile(LPDIRECT3DDEVICE9 device)
32 {
33     D3DCAPS9 caps;
34
35     TRACE("device %p\n", device);
36
37     if (!device) return NULL;
38
39     IDirect3DDevice9_GetDeviceCaps(device,&caps);
40
41     switch (caps.PixelShaderVersion)
42     {
43     case D3DPS_VERSION(1, 1):
44         return "ps_1_1";
45
46     case D3DPS_VERSION(1, 2):
47         return "ps_1_2";
48
49     case D3DPS_VERSION(1, 3):
50         return "ps_1_3";
51
52     case D3DPS_VERSION(1, 4):
53         return "ps_1_4";
54
55     case D3DPS_VERSION(2, 0):
56         if ((caps.PS20Caps.NumTemps>=22)                          &&
57             (caps.PS20Caps.Caps&D3DPS20CAPS_ARBITRARYSWIZZLE)     &&
58             (caps.PS20Caps.Caps&D3DPS20CAPS_GRADIENTINSTRUCTIONS) &&
59             (caps.PS20Caps.Caps&D3DPS20CAPS_PREDICATION)          &&
60             (caps.PS20Caps.Caps&D3DPS20CAPS_NODEPENDENTREADLIMIT) &&
61             (caps.PS20Caps.Caps&D3DPS20CAPS_NOTEXINSTRUCTIONLIMIT))
62         {
63             return "ps_2_a";
64         }
65         if ((caps.PS20Caps.NumTemps>=32)                          &&
66             (caps.PS20Caps.Caps&D3DPS20CAPS_NOTEXINSTRUCTIONLIMIT))
67         {
68             return "ps_2_b";
69         }
70         return "ps_2_0";
71
72     case D3DPS_VERSION(3, 0):
73         return "ps_3_0";
74     }
75
76     return NULL;
77 }
78
79 UINT WINAPI D3DXGetShaderSize(const DWORD *byte_code)
80 {
81     const DWORD *ptr = byte_code;
82
83     TRACE("byte_code %p\n", byte_code);
84
85     if (!ptr) return 0;
86
87     /* Look for the END token, skipping the VERSION token */
88     while (*++ptr != D3DSIO_END)
89     {
90         /* Skip comments */
91         if ((*ptr & D3DSI_OPCODE_MASK) == D3DSIO_COMMENT)
92         {
93             ptr += ((*ptr & D3DSI_COMMENTSIZE_MASK) >> D3DSI_COMMENTSIZE_SHIFT);
94         }
95     }
96     ++ptr;
97
98     /* Return the shader size in bytes */
99     return (ptr - byte_code) * sizeof(*ptr);
100 }
101
102 DWORD WINAPI D3DXGetShaderVersion(const DWORD *byte_code)
103 {
104     TRACE("byte_code %p\n", byte_code);
105
106     return byte_code ? *byte_code : 0;
107 }
108
109 LPCSTR WINAPI D3DXGetVertexShaderProfile(LPDIRECT3DDEVICE9 device)
110 {
111     D3DCAPS9 caps;
112
113     TRACE("device %p\n", device);
114
115     if (!device) return NULL;
116
117     IDirect3DDevice9_GetDeviceCaps(device,&caps);
118
119     switch (caps.VertexShaderVersion)
120     {
121     case D3DVS_VERSION(1, 1):
122         return "vs_1_1";
123     case D3DVS_VERSION(2, 0):
124         if ((caps.VS20Caps.NumTemps>=13) &&
125             (caps.VS20Caps.DynamicFlowControlDepth==24) &&
126             (caps.VS20Caps.Caps&D3DPS20CAPS_PREDICATION))
127         {
128             return "vs_2_a";
129         }
130         return "vs_2_0";
131     case D3DVS_VERSION(3, 0):
132         return "vs_3_0";
133     }
134
135     return NULL;
136 }
137
138 HRESULT WINAPI D3DXFindShaderComment(CONST DWORD* byte_code, DWORD fourcc, LPCVOID* data, UINT* size)
139 {
140     CONST DWORD *ptr = byte_code;
141
142     TRACE("(%p, %x, %p, %p)", byte_code, fourcc, data, size);
143
144     if (!byte_code)
145         return D3DERR_INVALIDCALL;
146
147     while (*++ptr != D3DSIO_END)
148     {
149         /* Check if it is a comment */
150         if ((*ptr & D3DSI_OPCODE_MASK) == D3DSIO_COMMENT)
151         {
152             DWORD comment_size = (*ptr & D3DSI_COMMENTSIZE_MASK) >> D3DSI_COMMENTSIZE_SHIFT;
153
154             /* Check if this is the comment we are looking for */
155             if (*(ptr + 1) == fourcc)
156             {
157                 UINT ctab_size = (comment_size - 1) * sizeof(DWORD);
158                 LPCVOID ctab_data = ptr + 2;
159                 if (size)
160                     *size = ctab_size;
161                 if (data)
162                     *data = ctab_data;
163                 TRACE("Returning comment data at %p with size %d\n", ctab_data, ctab_size);
164                 return D3D_OK;
165             }
166             ptr += comment_size;
167         }
168     }
169
170     return S_FALSE;
171 }
172
173 HRESULT WINAPI D3DXAssembleShader(LPCSTR data,
174                                   UINT data_len,
175                                   CONST D3DXMACRO* defines,
176                                   LPD3DXINCLUDE include,
177                                   DWORD flags,
178                                   LPD3DXBUFFER* shader,
179                                   LPD3DXBUFFER* error_messages)
180 {
181     FIXME("(%p, %d, %p, %p, %x, %p, %p): stub\n", data, data_len, defines, include, flags, shader, error_messages);
182     return D3DERR_INVALIDCALL;
183 }
184
185 HRESULT WINAPI D3DXAssembleShaderFromFileA(LPCSTR filename,
186                                            CONST D3DXMACRO* defines,
187                                            LPD3DXINCLUDE include,
188                                            DWORD flags,
189                                            LPD3DXBUFFER* shader,
190                                            LPD3DXBUFFER* error_messages)
191 {
192     LPWSTR filename_w = NULL;
193     DWORD len;
194     HRESULT ret;
195
196     if (!filename) return D3DXERR_INVALIDDATA;
197
198     len = MultiByteToWideChar(CP_ACP, 0, filename, -1, NULL, 0);
199     filename_w = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
200     if (!filename_w) return E_OUTOFMEMORY;
201     MultiByteToWideChar(CP_ACP, 0, filename, -1, filename_w, len);
202
203     ret = D3DXAssembleShaderFromFileW(filename_w, defines, include, flags, shader, error_messages);
204
205     HeapFree(GetProcessHeap(), 0, filename_w);
206     return ret;
207 }
208
209 HRESULT WINAPI D3DXAssembleShaderFromFileW(LPCWSTR filename,
210                                            CONST D3DXMACRO* defines,
211                                            LPD3DXINCLUDE include,
212                                            DWORD flags,
213                                            LPD3DXBUFFER* shader,
214                                            LPD3DXBUFFER* error_messages)
215 {
216     FIXME("(%s, %p, %p, %x, %p, %p): stub\n", debugstr_w(filename), defines, include, flags, shader, error_messages);
217     return D3DERR_INVALIDCALL;
218 }
219
220 HRESULT WINAPI D3DXAssembleShaderFromResourceA(HMODULE module,
221                                                LPCSTR resource,
222                                                CONST D3DXMACRO* defines,
223                                                LPD3DXINCLUDE include,
224                                                DWORD flags,
225                                                LPD3DXBUFFER* shader,
226                                                LPD3DXBUFFER* error_messages)
227 {
228     HRSRC res;
229     LPCSTR buffer;
230     DWORD len;
231
232     if (!(res = FindResourceA(module, resource, (LPCSTR)RT_RCDATA)))
233         return D3DXERR_INVALIDDATA;
234     if (FAILED(load_resource_into_memory(module, res, (LPVOID *)&buffer, &len)))
235         return D3DXERR_INVALIDDATA;
236     return D3DXAssembleShader(buffer, len, defines, include, flags,
237                               shader, error_messages);
238 }
239
240 HRESULT WINAPI D3DXAssembleShaderFromResourceW(HMODULE module,
241                                                LPCWSTR resource,
242                                                CONST D3DXMACRO* defines,
243                                                LPD3DXINCLUDE include,
244                                                DWORD flags,
245                                                LPD3DXBUFFER* shader,
246                                                LPD3DXBUFFER* error_messages)
247 {
248     HRSRC res;
249     LPCSTR buffer;
250     DWORD len;
251
252     if (!(res = FindResourceW(module, resource, (LPCWSTR)RT_RCDATA)))
253         return D3DXERR_INVALIDDATA;
254     if (FAILED(load_resource_into_memory(module, res, (LPVOID *)&buffer, &len)))
255         return D3DXERR_INVALIDDATA;
256     return D3DXAssembleShader(buffer, len, defines, include, flags,
257                               shader, error_messages);
258 }
259
260 HRESULT WINAPI D3DXCompileShader(LPCSTR pSrcData,
261                                  UINT srcDataLen,
262                                  CONST D3DXMACRO* pDefines,
263                                  LPD3DXINCLUDE pInclude,
264                                  LPCSTR pFunctionName,
265                                  LPCSTR pProfile,
266                                  DWORD Flags,
267                                  LPD3DXBUFFER* ppShader,
268                                  LPD3DXBUFFER* ppErrorMsgs,
269                                  LPD3DXCONSTANTTABLE * ppConstantTable)
270 {
271     FIXME("(%p, %d, %p, %p, %p, %p, %d, %p, %p, %p): stub\n",
272           pSrcData, srcDataLen, pDefines, pInclude, pFunctionName,
273           pProfile, Flags, ppShader, ppErrorMsgs, ppConstantTable);
274     return D3DERR_INVALIDCALL;
275 }
276
277 static const struct ID3DXConstantTableVtbl ID3DXConstantTable_Vtbl;
278
279 typedef struct ID3DXConstantTableImpl {
280     const ID3DXConstantTableVtbl *lpVtbl;
281     LONG ref;
282     LPVOID ctab;
283     DWORD size;
284 } ID3DXConstantTableImpl;
285
286 /*** IUnknown methods ***/
287 static HRESULT WINAPI ID3DXConstantTableImpl_QueryInterface(ID3DXConstantTable* iface, REFIID riid, void** ppvObject)
288 {
289     ID3DXConstantTableImpl *This = (ID3DXConstantTableImpl *)iface;
290
291     TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppvObject);
292
293     if (IsEqualGUID(riid, &IID_IUnknown) ||
294         IsEqualGUID(riid, &IID_ID3DXConstantTable))
295     {
296         ID3DXConstantTable_AddRef(iface);
297         *ppvObject = This;
298         return S_OK;
299     }
300
301     ERR("Interface %s not found\n", debugstr_guid(riid));
302
303     return E_NOINTERFACE;
304 }
305
306 static ULONG WINAPI ID3DXConstantTableImpl_AddRef(ID3DXConstantTable* iface)
307 {
308     ID3DXConstantTableImpl *This = (ID3DXConstantTableImpl *)iface;
309
310     TRACE("(%p)->(): AddRef from %d\n", This, This->ref);
311
312     return InterlockedIncrement(&This->ref);
313 }
314
315 static ULONG WINAPI ID3DXConstantTableImpl_Release(ID3DXConstantTable* iface)
316 {
317     ID3DXConstantTableImpl *This = (ID3DXConstantTableImpl *)iface;
318     ULONG ref = InterlockedDecrement(&This->ref);
319
320     TRACE("(%p)->(): Release from %d\n", This, ref + 1);
321
322     if (!ref)
323     {
324         HeapFree(GetProcessHeap(), 0, This->ctab);
325         HeapFree(GetProcessHeap(), 0, This);
326     }
327
328     return ref;
329 }
330
331 /*** ID3DXBuffer methods ***/
332 static LPVOID WINAPI ID3DXConstantTableImpl_GetBufferPointer(ID3DXConstantTable* iface)
333 {
334     ID3DXConstantTableImpl *This = (ID3DXConstantTableImpl *)iface;
335
336     TRACE("(%p)->()\n", This);
337
338     return This->ctab;
339 }
340
341 static DWORD WINAPI ID3DXConstantTableImpl_GetBufferSize(ID3DXConstantTable* iface)
342 {
343     ID3DXConstantTableImpl *This = (ID3DXConstantTableImpl *)iface;
344
345     TRACE("(%p)->()\n", This);
346
347     return This->size;
348 }
349
350 /*** ID3DXConstantTable methods ***/
351 static HRESULT WINAPI ID3DXConstantTableImpl_GetDesc(ID3DXConstantTable* iface, D3DXCONSTANTTABLE_DESC *desc)
352 {
353     ID3DXConstantTableImpl *This = (ID3DXConstantTableImpl *)iface;
354
355     FIXME("(%p)->(%p): stub\n", This, desc);
356
357     return E_NOTIMPL;
358 }
359
360 static HRESULT WINAPI ID3DXConstantTableImpl_GetConstantDesc(ID3DXConstantTable* iface, D3DXHANDLE constant,
361                                                              D3DXCONSTANT_DESC *desc, UINT *count)
362 {
363     ID3DXConstantTableImpl *This = (ID3DXConstantTableImpl *)iface;
364
365     FIXME("(%p)->(%p, %p, %p): stub\n", This, constant, desc, count);
366
367     return E_NOTIMPL;
368 }
369
370 static D3DXHANDLE WINAPI ID3DXConstantTableImpl_GetConstant(ID3DXConstantTable* iface, D3DXHANDLE constant, UINT index)
371 {
372     ID3DXConstantTableImpl *This = (ID3DXConstantTableImpl *)iface;
373
374     FIXME("(%p)->(%p, %d): stub\n", This, constant, index);
375
376     return NULL;
377 }
378
379 static D3DXHANDLE WINAPI ID3DXConstantTableImpl_GetConstantByName(ID3DXConstantTable* iface, D3DXHANDLE constant, LPCSTR name)
380 {
381     ID3DXConstantTableImpl *This = (ID3DXConstantTableImpl *)iface;
382
383     FIXME("(%p)->(%p, %s): stub\n", This, constant, name);
384
385     return NULL;
386 }
387
388 static D3DXHANDLE WINAPI ID3DXConstantTableImpl_GetConstantByElement(ID3DXConstantTable* iface, D3DXHANDLE constant, UINT index)
389 {
390     ID3DXConstantTableImpl *This = (ID3DXConstantTableImpl *)iface;
391
392     FIXME("(%p)->(%p, %d): stub\n", This, constant, index);
393
394     return NULL;
395 }
396
397 static HRESULT WINAPI ID3DXConstantTableImpl_SetDefaults(ID3DXConstantTable* iface, LPDIRECT3DDEVICE9 device)
398 {
399     ID3DXConstantTableImpl *This = (ID3DXConstantTableImpl *)iface;
400
401     FIXME("(%p)->(%p): stub\n", This, device);
402
403     return E_NOTIMPL;
404 }
405
406 static HRESULT WINAPI ID3DXConstantTableImpl_SetValue(ID3DXConstantTable* iface, LPDIRECT3DDEVICE9 device,
407                                                       D3DXHANDLE constant, LPCVOID data, UINT bytes)
408 {
409     ID3DXConstantTableImpl *This = (ID3DXConstantTableImpl *)iface;
410
411     FIXME("(%p)->(%p, %p, %p, %d): stub\n", This, device, constant, data, bytes);
412
413     return E_NOTIMPL;
414 }
415
416 static HRESULT WINAPI ID3DXConstantTableImpl_SetBool(ID3DXConstantTable* iface, LPDIRECT3DDEVICE9 device,
417                                                      D3DXHANDLE constant, BOOL b)
418 {
419     ID3DXConstantTableImpl *This = (ID3DXConstantTableImpl *)iface;
420
421     FIXME("(%p)->(%p, %p, %d): stub\n", This, device, constant, b);
422
423     return E_NOTIMPL;
424 }
425
426 static HRESULT WINAPI ID3DXConstantTableImpl_SetBoolArray(ID3DXConstantTable* iface, LPDIRECT3DDEVICE9 device,
427                                                           D3DXHANDLE constant, CONST BOOL* b, UINT count)
428 {
429     ID3DXConstantTableImpl *This = (ID3DXConstantTableImpl *)iface;
430
431     FIXME("(%p)->(%p, %p, %p, %d): stub\n", This, device, constant, b, count);
432
433     return E_NOTIMPL;
434 }
435
436 static HRESULT WINAPI ID3DXConstantTableImpl_SetInt(ID3DXConstantTable* iface, LPDIRECT3DDEVICE9 device, D3DXHANDLE constant, INT n)
437 {
438     ID3DXConstantTableImpl *This = (ID3DXConstantTableImpl *)iface;
439
440     FIXME("(%p)->(%p, %p, %d): stub\n", This, device, constant, n);
441
442     return E_NOTIMPL;
443 }
444
445 static HRESULT WINAPI ID3DXConstantTableImpl_SetIntArray(ID3DXConstantTable* iface, LPDIRECT3DDEVICE9 device,
446                                                          D3DXHANDLE constant, CONST INT* n, UINT count)
447 {
448     ID3DXConstantTableImpl *This = (ID3DXConstantTableImpl *)iface;
449
450     FIXME("(%p)->(%p, %p, %p, %d): stub\n", This, device, constant, n, count);
451
452     return E_NOTIMPL;
453 }
454
455 static HRESULT WINAPI ID3DXConstantTableImpl_SetFloat(ID3DXConstantTable* iface, LPDIRECT3DDEVICE9 device,
456                                                       D3DXHANDLE constant, FLOAT f)
457 {
458     ID3DXConstantTableImpl *This = (ID3DXConstantTableImpl *)iface;
459
460     FIXME("(%p)->(%p, %p, %f): stub\n", This, device, constant, f);
461
462     return E_NOTIMPL;
463 }
464
465 static HRESULT WINAPI ID3DXConstantTableImpl_SetFloatArray(ID3DXConstantTable* iface, LPDIRECT3DDEVICE9 device,
466                                                            D3DXHANDLE constant, CONST FLOAT* f, UINT count)
467 {
468     ID3DXConstantTableImpl *This = (ID3DXConstantTableImpl *)iface;
469
470     FIXME("(%p)->(%p, %p, %p, %d): stub\n", This, device, constant, f, count);
471
472     return E_NOTIMPL;
473 }
474
475 static HRESULT WINAPI ID3DXConstantTableImpl_SetVector(ID3DXConstantTable* iface, LPDIRECT3DDEVICE9 device,
476                                                        D3DXHANDLE constant, CONST D3DXVECTOR4* vector)
477 {
478     ID3DXConstantTableImpl *This = (ID3DXConstantTableImpl *)iface;
479
480     FIXME("(%p)->(%p, %p, %p): stub\n", This, device, constant, vector);
481
482     return E_NOTIMPL;
483 }
484
485 static HRESULT WINAPI ID3DXConstantTableImpl_SetVectorArray(ID3DXConstantTable* iface, LPDIRECT3DDEVICE9 device,
486                                                             D3DXHANDLE constant, CONST D3DXVECTOR4* vector, UINT count)
487 {
488     ID3DXConstantTableImpl *This = (ID3DXConstantTableImpl *)iface;
489
490     FIXME("(%p)->(%p, %p, %p, %d): stub\n", This, device, constant, vector, count);
491
492     return E_NOTIMPL;
493 }
494
495 static HRESULT WINAPI ID3DXConstantTableImpl_SetMatrix(ID3DXConstantTable* iface, LPDIRECT3DDEVICE9 device,
496                                                        D3DXHANDLE constant, CONST D3DXMATRIX* matrix)
497 {
498     ID3DXConstantTableImpl *This = (ID3DXConstantTableImpl *)iface;
499
500     FIXME("(%p)->(%p, %p, %p): stub\n", This, device, constant, matrix);
501
502     return E_NOTIMPL;
503 }
504
505 static HRESULT WINAPI ID3DXConstantTableImpl_SetMatrixArray(ID3DXConstantTable* iface, LPDIRECT3DDEVICE9 device,
506                                                             D3DXHANDLE constant, CONST D3DXMATRIX* matrix, UINT count)
507 {
508     ID3DXConstantTableImpl *This = (ID3DXConstantTableImpl *)iface;
509
510     FIXME("(%p)->(%p, %p, %p, %d): stub\n", This, device, constant, matrix, count);
511
512     return E_NOTIMPL;
513 }
514
515 static HRESULT WINAPI ID3DXConstantTableImpl_SetMatrixPointerArray(ID3DXConstantTable* iface, LPDIRECT3DDEVICE9 device,
516                                                                    D3DXHANDLE constant, CONST D3DXMATRIX** matrix, UINT count)
517 {
518     ID3DXConstantTableImpl *This = (ID3DXConstantTableImpl *)iface;
519
520     FIXME("(%p)->(%p, %p, %p, %d): stub\n", This, device, constant, matrix, count);
521
522     return E_NOTIMPL;
523 }
524
525 static HRESULT WINAPI ID3DXConstantTableImpl_SetMatrixTranspose(ID3DXConstantTable* iface, LPDIRECT3DDEVICE9 device,
526                                                                 D3DXHANDLE constant, CONST D3DXMATRIX* matrix)
527 {
528     ID3DXConstantTableImpl *This = (ID3DXConstantTableImpl *)iface;
529
530     FIXME("(%p)->(%p, %p, %p): stub\n", This, device, constant, matrix);
531
532     return E_NOTIMPL;
533 }
534
535 static HRESULT WINAPI ID3DXConstantTableImpl_SetMatrixTransposeArray(ID3DXConstantTable* iface, LPDIRECT3DDEVICE9 device,
536                                                                      D3DXHANDLE constant, CONST D3DXMATRIX* matrix, UINT count)
537 {
538     ID3DXConstantTableImpl *This = (ID3DXConstantTableImpl *)iface;
539
540     FIXME("(%p)->(%p, %p, %p, %d): stub\n", This, device, constant, matrix, count);
541
542     return E_NOTIMPL;
543 }
544
545 static HRESULT WINAPI ID3DXConstantTableImpl_SetMatrixTransposePointerArray(ID3DXConstantTable* iface, LPDIRECT3DDEVICE9 device,
546                                                                             D3DXHANDLE constant, CONST D3DXMATRIX** matrix, UINT count)
547 {
548     ID3DXConstantTableImpl *This = (ID3DXConstantTableImpl *)iface;
549
550     FIXME("(%p)->(%p, %p, %p, %d): stub\n", This, device, constant, matrix, count);
551
552     return E_NOTIMPL;
553 }
554
555 static const struct ID3DXConstantTableVtbl ID3DXConstantTable_Vtbl =
556 {
557     /*** IUnknown methods ***/
558     ID3DXConstantTableImpl_QueryInterface,
559     ID3DXConstantTableImpl_AddRef,
560     ID3DXConstantTableImpl_Release,
561     /*** ID3DXBuffer methods ***/
562     ID3DXConstantTableImpl_GetBufferPointer,
563     ID3DXConstantTableImpl_GetBufferSize,
564     /*** ID3DXConstantTable methods ***/
565     ID3DXConstantTableImpl_GetDesc,
566     ID3DXConstantTableImpl_GetConstantDesc,
567     ID3DXConstantTableImpl_GetConstant,
568     ID3DXConstantTableImpl_GetConstantByName,
569     ID3DXConstantTableImpl_GetConstantByElement,
570     ID3DXConstantTableImpl_SetDefaults,
571     ID3DXConstantTableImpl_SetValue,
572     ID3DXConstantTableImpl_SetBool,
573     ID3DXConstantTableImpl_SetBoolArray,
574     ID3DXConstantTableImpl_SetInt,
575     ID3DXConstantTableImpl_SetIntArray,
576     ID3DXConstantTableImpl_SetFloat,
577     ID3DXConstantTableImpl_SetFloatArray,
578     ID3DXConstantTableImpl_SetVector,
579     ID3DXConstantTableImpl_SetVectorArray,
580     ID3DXConstantTableImpl_SetMatrix,
581     ID3DXConstantTableImpl_SetMatrixArray,
582     ID3DXConstantTableImpl_SetMatrixPointerArray,
583     ID3DXConstantTableImpl_SetMatrixTranspose,
584     ID3DXConstantTableImpl_SetMatrixTransposeArray,
585     ID3DXConstantTableImpl_SetMatrixTransposePointerArray
586 };
587
588 HRESULT WINAPI D3DXGetShaderConstantTableEx(CONST DWORD* byte_code,
589                                             DWORD flags,
590                                             LPD3DXCONSTANTTABLE* constant_table)
591 {
592     ID3DXConstantTableImpl* object;
593     HRESULT hr;
594     LPCVOID data;
595     UINT size;
596
597     FIXME("(%p, %x, %p): semi-stub\n", byte_code, flags, constant_table);
598
599     if (!byte_code || !constant_table)
600         return D3DERR_INVALIDCALL;
601
602     hr = D3DXFindShaderComment(byte_code, MAKEFOURCC('C','T','A','B'), &data, &size);
603     if (hr != D3D_OK)
604         return D3DXERR_INVALIDDATA;
605
606     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ID3DXConstantTableImpl));
607     if (!object)
608     {
609         ERR("Out of memory\n");
610         return E_OUTOFMEMORY;
611     }
612
613     object->lpVtbl = &ID3DXConstantTable_Vtbl;
614     object->ref = 1;
615
616     object->ctab = HeapAlloc(GetProcessHeap(), 0, size);
617     if (!object->ctab)
618     {
619         HeapFree(GetProcessHeap(), 0, object);
620         ERR("Out of memory\n");
621         return E_OUTOFMEMORY;
622     }
623     object->size = size;
624     memcpy(object->ctab, data, object->size);
625
626     *constant_table = (LPD3DXCONSTANTTABLE)object;
627
628     return D3D_OK;
629 }
630
631 HRESULT WINAPI D3DXGetShaderConstantTable(CONST DWORD* byte_code,
632                                           LPD3DXCONSTANTTABLE* constant_table)
633 {
634     TRACE("(%p, %p): Forwarded to D3DXGetShaderConstantTableEx\n", byte_code, constant_table);
635
636     return D3DXGetShaderConstantTableEx(byte_code, 0, constant_table);
637 }