2 * Copyright 2008 Luis Busquets
3 * Copyright 2009 Matteo Bruni
4 * Copyright 2011 Travis Athougies
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include "wine/port.h"
24 #define NONAMELESSUNION
25 #define NONAMELESSSTRUCT
26 #include "wine/debug.h"
27 #include "wine/unicode.h"
31 #include "d3dcommon.h"
32 #include "d3dcompiler.h"
33 #include "d3dx9_36_private.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
37 /* This function is not declared in the SDK headers yet */
38 HRESULT WINAPI D3DAssemble(LPCVOID data, SIZE_T datasize, LPCSTR filename,
39 const D3D_SHADER_MACRO *defines, ID3DInclude *include,
41 ID3DBlob **shader, ID3DBlob **error_messages);
43 LPCSTR WINAPI D3DXGetPixelShaderProfile(LPDIRECT3DDEVICE9 device)
47 TRACE("device %p\n", device);
49 if (!device) return NULL;
51 IDirect3DDevice9_GetDeviceCaps(device,&caps);
53 switch (caps.PixelShaderVersion)
55 case D3DPS_VERSION(1, 1):
58 case D3DPS_VERSION(1, 2):
61 case D3DPS_VERSION(1, 3):
64 case D3DPS_VERSION(1, 4):
67 case D3DPS_VERSION(2, 0):
68 if ((caps.PS20Caps.NumTemps>=22) &&
69 (caps.PS20Caps.Caps&D3DPS20CAPS_ARBITRARYSWIZZLE) &&
70 (caps.PS20Caps.Caps&D3DPS20CAPS_GRADIENTINSTRUCTIONS) &&
71 (caps.PS20Caps.Caps&D3DPS20CAPS_PREDICATION) &&
72 (caps.PS20Caps.Caps&D3DPS20CAPS_NODEPENDENTREADLIMIT) &&
73 (caps.PS20Caps.Caps&D3DPS20CAPS_NOTEXINSTRUCTIONLIMIT))
77 if ((caps.PS20Caps.NumTemps>=32) &&
78 (caps.PS20Caps.Caps&D3DPS20CAPS_NOTEXINSTRUCTIONLIMIT))
84 case D3DPS_VERSION(3, 0):
91 UINT WINAPI D3DXGetShaderSize(const DWORD *byte_code)
93 const DWORD *ptr = byte_code;
95 TRACE("byte_code %p\n", byte_code);
99 /* Look for the END token, skipping the VERSION token */
100 while (*++ptr != D3DSIO_END)
103 if ((*ptr & D3DSI_OPCODE_MASK) == D3DSIO_COMMENT)
105 ptr += ((*ptr & D3DSI_COMMENTSIZE_MASK) >> D3DSI_COMMENTSIZE_SHIFT);
110 /* Return the shader size in bytes */
111 return (ptr - byte_code) * sizeof(*ptr);
114 DWORD WINAPI D3DXGetShaderVersion(const DWORD *byte_code)
116 TRACE("byte_code %p\n", byte_code);
118 return byte_code ? *byte_code : 0;
121 LPCSTR WINAPI D3DXGetVertexShaderProfile(LPDIRECT3DDEVICE9 device)
125 TRACE("device %p\n", device);
127 if (!device) return NULL;
129 IDirect3DDevice9_GetDeviceCaps(device,&caps);
131 switch (caps.VertexShaderVersion)
133 case D3DVS_VERSION(1, 1):
135 case D3DVS_VERSION(2, 0):
136 if ((caps.VS20Caps.NumTemps>=13) &&
137 (caps.VS20Caps.DynamicFlowControlDepth==24) &&
138 (caps.VS20Caps.Caps&D3DPS20CAPS_PREDICATION))
143 case D3DVS_VERSION(3, 0):
150 HRESULT WINAPI D3DXFindShaderComment(CONST DWORD* byte_code, DWORD fourcc, LPCVOID* data, UINT* size)
152 CONST DWORD *ptr = byte_code;
154 TRACE("(%p, %x, %p, %p)\n", byte_code, fourcc, data, size);
156 if (data) *data = NULL;
160 return D3DERR_INVALIDCALL;
162 while (*++ptr != D3DSIO_END)
164 /* Check if it is a comment */
165 if ((*ptr & D3DSI_OPCODE_MASK) == D3DSIO_COMMENT)
167 DWORD comment_size = (*ptr & D3DSI_COMMENTSIZE_MASK) >> D3DSI_COMMENTSIZE_SHIFT;
169 /* Check if this is the comment we are looking for */
170 if (*(ptr + 1) == fourcc)
172 UINT ctab_size = (comment_size - 1) * sizeof(DWORD);
173 LPCVOID ctab_data = ptr + 2;
178 TRACE("Returning comment data at %p with size %d\n", ctab_data, ctab_size);
188 HRESULT WINAPI D3DXAssembleShader(LPCSTR data,
190 CONST D3DXMACRO* defines,
191 LPD3DXINCLUDE include,
193 LPD3DXBUFFER* shader,
194 LPD3DXBUFFER* error_messages)
196 /* Forward to d3dcompiler: the parameter types aren't really different,
197 the actual data types are equivalent */
198 HRESULT hr = D3DAssemble(data, data_len, NULL, (D3D_SHADER_MACRO *)defines,
199 (ID3DInclude *)include, flags, (ID3DBlob **)shader,
200 (ID3DBlob **)error_messages);
202 if(hr == E_FAIL) hr = D3DXERR_INVALIDDATA;
206 /* D3DXInclude private implementation, used to implement
207 D3DXAssembleShaderFromFile from D3DXAssembleShader */
208 /* To be able to correctly resolve include search paths we have to store
209 the pathname of each include file. We store the pathname pointer right
210 before the file data. */
211 static HRESULT WINAPI d3dincludefromfile_open(ID3DXInclude *iface,
212 D3DXINCLUDE_TYPE include_type,
213 LPCSTR filename, LPCVOID parent_data,
214 LPCVOID *data, UINT *bytes) {
215 const char *p, *parent_name = "";
216 char *pathname = NULL;
217 char **buffer = NULL;
221 if(parent_data != NULL)
222 parent_name = *((const char **)parent_data - 1);
224 TRACE("Looking up for include file %s, parent %s\n", debugstr_a(filename), debugstr_a(parent_name));
226 if ((p = strrchr(parent_name, '\\')) || (p = strrchr(parent_name, '/'))) p++;
227 else p = parent_name;
228 pathname = HeapAlloc(GetProcessHeap(), 0, (p - parent_name) + strlen(filename) + 1);
230 return HRESULT_FROM_WIN32(GetLastError());
232 memcpy(pathname, parent_name, p - parent_name);
233 strcpy(pathname + (p - parent_name), filename);
235 file = CreateFileA(pathname, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
236 if(file == INVALID_HANDLE_VALUE)
239 TRACE("Include file found at pathname = %s\n", debugstr_a(pathname));
241 size = GetFileSize(file, NULL);
242 if(size == INVALID_FILE_SIZE)
245 buffer = HeapAlloc(GetProcessHeap(), 0, size + sizeof(char *));
249 if(!ReadFile(file, buffer + 1, size, bytes, NULL))
259 HeapFree(GetProcessHeap(), 0, pathname);
260 HeapFree(GetProcessHeap(), 0, buffer);
261 return HRESULT_FROM_WIN32(GetLastError());
264 static HRESULT WINAPI d3dincludefromfile_close(ID3DXInclude *iface, LPCVOID data) {
265 HeapFree(GetProcessHeap(), 0, *((char **)data - 1));
266 HeapFree(GetProcessHeap(), 0, (char **)data - 1);
270 static const struct ID3DXIncludeVtbl D3DXInclude_Vtbl = {
271 d3dincludefromfile_open,
272 d3dincludefromfile_close
275 struct D3DXIncludeImpl {
276 ID3DXInclude ID3DXInclude_iface;
279 HRESULT WINAPI D3DXAssembleShaderFromFileA(LPCSTR filename,
280 CONST D3DXMACRO* defines,
281 LPD3DXINCLUDE include,
283 LPD3DXBUFFER* shader,
284 LPD3DXBUFFER* error_messages)
286 LPWSTR filename_w = NULL;
290 if (!filename) return D3DXERR_INVALIDDATA;
292 len = MultiByteToWideChar(CP_ACP, 0, filename, -1, NULL, 0);
293 filename_w = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
294 if (!filename_w) return E_OUTOFMEMORY;
295 MultiByteToWideChar(CP_ACP, 0, filename, -1, filename_w, len);
297 ret = D3DXAssembleShaderFromFileW(filename_w, defines, include, flags, shader, error_messages);
299 HeapFree(GetProcessHeap(), 0, filename_w);
303 HRESULT WINAPI D3DXAssembleShaderFromFileW(LPCWSTR filename,
304 CONST D3DXMACRO* defines,
305 LPD3DXINCLUDE include,
307 LPD3DXBUFFER* shader,
308 LPD3DXBUFFER* error_messages)
313 struct D3DXIncludeImpl includefromfile;
315 if(FAILED(map_view_of_file(filename, &buffer, &len)))
316 return D3DXERR_INVALIDDATA;
320 includefromfile.ID3DXInclude_iface.lpVtbl = &D3DXInclude_Vtbl;
321 include = &includefromfile.ID3DXInclude_iface;
324 hr = D3DXAssembleShader(buffer, len, defines, include, flags,
325 shader, error_messages);
327 UnmapViewOfFile(buffer);
331 HRESULT WINAPI D3DXAssembleShaderFromResourceA(HMODULE module,
333 CONST D3DXMACRO* defines,
334 LPD3DXINCLUDE include,
336 LPD3DXBUFFER* shader,
337 LPD3DXBUFFER* error_messages)
343 if (!(res = FindResourceA(module, resource, (LPCSTR)RT_RCDATA)))
344 return D3DXERR_INVALIDDATA;
345 if (FAILED(load_resource_into_memory(module, res, (LPVOID *)&buffer, &len)))
346 return D3DXERR_INVALIDDATA;
347 return D3DXAssembleShader(buffer, len, defines, include, flags,
348 shader, error_messages);
351 HRESULT WINAPI D3DXAssembleShaderFromResourceW(HMODULE module,
353 CONST D3DXMACRO* defines,
354 LPD3DXINCLUDE include,
356 LPD3DXBUFFER* shader,
357 LPD3DXBUFFER* error_messages)
363 if (!(res = FindResourceW(module, resource, (LPCWSTR)RT_RCDATA)))
364 return D3DXERR_INVALIDDATA;
365 if (FAILED(load_resource_into_memory(module, res, (LPVOID *)&buffer, &len)))
366 return D3DXERR_INVALIDDATA;
367 return D3DXAssembleShader(buffer, len, defines, include, flags,
368 shader, error_messages);
371 HRESULT WINAPI D3DXCompileShader(LPCSTR pSrcData,
373 CONST D3DXMACRO* pDefines,
374 LPD3DXINCLUDE pInclude,
375 LPCSTR pFunctionName,
378 LPD3DXBUFFER* ppShader,
379 LPD3DXBUFFER* ppErrorMsgs,
380 LPD3DXCONSTANTTABLE * ppConstantTable)
382 HRESULT hr = D3DCompile(pSrcData, srcDataLen, NULL,
383 (D3D_SHADER_MACRO *)pDefines, (ID3DInclude *)pInclude,
384 pFunctionName, pProfile, Flags, 0,
385 (ID3DBlob **)ppShader, (ID3DBlob **)ppErrorMsgs);
387 if(SUCCEEDED(hr) && ppConstantTable)
388 return D3DXGetShaderConstantTable(ID3DXBuffer_GetBufferPointer(*ppShader),
393 HRESULT WINAPI D3DXCompileShaderFromFileA(LPCSTR filename,
394 CONST D3DXMACRO* defines,
395 LPD3DXINCLUDE include,
399 LPD3DXBUFFER* shader,
400 LPD3DXBUFFER* error_messages,
401 LPD3DXCONSTANTTABLE* constant_table)
403 LPWSTR filename_w = NULL;
407 if (!filename) return D3DXERR_INVALIDDATA;
409 len = MultiByteToWideChar(CP_ACP, 0, filename, -1, NULL, 0);
410 filename_w = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
411 if (!filename_w) return E_OUTOFMEMORY;
412 MultiByteToWideChar(CP_ACP, 0, filename, -1, filename_w, len);
414 ret = D3DXCompileShaderFromFileW(filename_w, defines, include,
415 entrypoint, profile, flags,
416 shader, error_messages, constant_table);
418 HeapFree(GetProcessHeap(), 0, filename_w);
422 HRESULT WINAPI D3DXCompileShaderFromFileW(LPCWSTR filename,
423 CONST D3DXMACRO* defines,
424 LPD3DXINCLUDE include,
428 LPD3DXBUFFER* shader,
429 LPD3DXBUFFER* error_messages,
430 LPD3DXCONSTANTTABLE* constant_table)
433 DWORD len, filename_len;
435 struct D3DXIncludeImpl includefromfile;
438 if (FAILED(map_view_of_file(filename, &buffer, &len)))
439 return D3DXERR_INVALIDDATA;
443 includefromfile.ID3DXInclude_iface.lpVtbl = &D3DXInclude_Vtbl;
444 include = &includefromfile.ID3DXInclude_iface;
447 filename_len = WideCharToMultiByte(CP_ACP, 0, filename, -1, NULL, 0, NULL, NULL);
448 filename_a = HeapAlloc(GetProcessHeap(), 0, filename_len * sizeof(char));
451 UnmapViewOfFile(buffer);
452 return E_OUTOFMEMORY;
454 WideCharToMultiByte(CP_ACP, 0, filename, -1, filename_a, filename_len, NULL, NULL);
456 hr = D3DCompile(buffer, len, filename_a, (const D3D_SHADER_MACRO *)defines,
457 (ID3DInclude *)include, entrypoint, profile, flags, 0,
458 (ID3DBlob **)shader, (ID3DBlob **)error_messages);
460 if (SUCCEEDED(hr) && constant_table)
461 hr = D3DXGetShaderConstantTable(ID3DXBuffer_GetBufferPointer(*shader),
464 HeapFree(GetProcessHeap(), 0, filename_a);
465 UnmapViewOfFile(buffer);
469 HRESULT WINAPI D3DXCompileShaderFromResourceA(HMODULE module,
471 CONST D3DXMACRO* defines,
472 LPD3DXINCLUDE include,
476 LPD3DXBUFFER* shader,
477 LPD3DXBUFFER* error_messages,
478 LPD3DXCONSTANTTABLE* constant_table)
484 if (!(res = FindResourceA(module, resource, (LPCSTR)RT_RCDATA)))
485 return D3DXERR_INVALIDDATA;
486 if (FAILED(load_resource_into_memory(module, res, (LPVOID *)&buffer, &len)))
487 return D3DXERR_INVALIDDATA;
488 return D3DXCompileShader(buffer, len, defines, include, entrypoint, profile,
489 flags, shader, error_messages, constant_table);
492 HRESULT WINAPI D3DXCompileShaderFromResourceW(HMODULE module,
494 CONST D3DXMACRO* defines,
495 LPD3DXINCLUDE include,
499 LPD3DXBUFFER* shader,
500 LPD3DXBUFFER* error_messages,
501 LPD3DXCONSTANTTABLE* constant_table)
507 if (!(res = FindResourceW(module, resource, (LPCWSTR)RT_RCDATA)))
508 return D3DXERR_INVALIDDATA;
509 if (FAILED(load_resource_into_memory(module, res, (LPVOID *)&buffer, &len)))
510 return D3DXERR_INVALIDDATA;
511 return D3DXCompileShader(buffer, len, defines, include, entrypoint, profile,
512 flags, shader, error_messages, constant_table);
515 HRESULT WINAPI D3DXPreprocessShader(LPCSTR data,
517 CONST D3DXMACRO* defines,
518 LPD3DXINCLUDE include,
519 LPD3DXBUFFER* shader,
520 LPD3DXBUFFER* error_messages)
522 TRACE("Forward to D3DPreprocess\n");
523 return D3DPreprocess(data, data_len, NULL,
524 (const D3D_SHADER_MACRO *)defines, (ID3DInclude *)include,
525 (ID3DBlob **)shader, (ID3DBlob **)error_messages);
528 HRESULT WINAPI D3DXPreprocessShaderFromFileA(LPCSTR filename,
529 CONST D3DXMACRO* defines,
530 LPD3DXINCLUDE include,
531 LPD3DXBUFFER* shader,
532 LPD3DXBUFFER* error_messages)
534 WCHAR *filename_w = NULL;
538 if (!filename) return D3DXERR_INVALIDDATA;
540 len = MultiByteToWideChar(CP_ACP, 0, filename, -1, NULL, 0);
541 filename_w = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
542 if (!filename_w) return E_OUTOFMEMORY;
543 MultiByteToWideChar(CP_ACP, 0, filename, -1, filename_w, len);
545 ret = D3DXPreprocessShaderFromFileW(filename_w, defines, include, shader, error_messages);
547 HeapFree(GetProcessHeap(), 0, filename_w);
551 HRESULT WINAPI D3DXPreprocessShaderFromFileW(LPCWSTR filename,
552 CONST D3DXMACRO* defines,
553 LPD3DXINCLUDE include,
554 LPD3DXBUFFER* shader,
555 LPD3DXBUFFER* error_messages)
560 struct D3DXIncludeImpl includefromfile;
562 if (FAILED(map_view_of_file(filename, &buffer, &len)))
563 return D3DXERR_INVALIDDATA;
567 includefromfile.ID3DXInclude_iface.lpVtbl = &D3DXInclude_Vtbl;
568 include = &includefromfile.ID3DXInclude_iface;
571 hr = D3DPreprocess(buffer, len, NULL,
572 (const D3D_SHADER_MACRO *)defines,
573 (ID3DInclude *) include,
574 (ID3DBlob **)shader, (ID3DBlob **)error_messages);
576 UnmapViewOfFile(buffer);
580 HRESULT WINAPI D3DXPreprocessShaderFromResourceA(HMODULE module,
582 CONST D3DXMACRO* defines,
583 LPD3DXINCLUDE include,
584 LPD3DXBUFFER* shader,
585 LPD3DXBUFFER* error_messages)
591 if (!(res = FindResourceA(module, resource, (LPCSTR)RT_RCDATA)))
592 return D3DXERR_INVALIDDATA;
593 if (FAILED(load_resource_into_memory(module, res, (LPVOID *)&buffer, &len)))
594 return D3DXERR_INVALIDDATA;
595 return D3DXPreprocessShader(buffer, len, defines, include,
596 shader, error_messages);
599 HRESULT WINAPI D3DXPreprocessShaderFromResourceW(HMODULE module,
601 CONST D3DXMACRO* defines,
602 LPD3DXINCLUDE include,
603 LPD3DXBUFFER* shader,
604 LPD3DXBUFFER* error_messages)
610 if (!(res = FindResourceW(module, resource, (const WCHAR *)RT_RCDATA)))
611 return D3DXERR_INVALIDDATA;
612 if (FAILED(load_resource_into_memory(module, res, (void **)&buffer, &len)))
613 return D3DXERR_INVALIDDATA;
614 return D3DXPreprocessShader(buffer, len, defines, include,
615 shader, error_messages);
619 typedef struct ctab_constant {
620 D3DXCONSTANT_DESC desc;
621 struct ctab_constant *members;
624 static const struct ID3DXConstantTableVtbl ID3DXConstantTable_Vtbl;
626 struct ID3DXConstantTableImpl {
627 ID3DXConstantTable ID3DXConstantTable_iface;
631 D3DXCONSTANTTABLE_DESC desc;
632 ctab_constant *constants;
635 static void free_constant_table(struct ID3DXConstantTableImpl *table)
637 HeapFree(GetProcessHeap(), 0, table->constants);
638 HeapFree(GetProcessHeap(), 0, table->ctab);
641 static inline struct ID3DXConstantTableImpl *impl_from_ID3DXConstantTable(ID3DXConstantTable *iface)
643 return CONTAINING_RECORD(iface, struct ID3DXConstantTableImpl, ID3DXConstantTable_iface);
646 static inline int is_vertex_shader(DWORD version)
648 return (version & 0xFFFF0000) == 0xFFFE0000;
651 static DWORD calc_bytes(D3DXCONSTANT_DESC *desc)
653 if (desc->RegisterSet != D3DXRS_FLOAT4 && desc->RegisterSet != D3DXRS_SAMPLER)
654 FIXME("Don't know how to calculate Bytes for constants of type %d\n",
657 return 4 * desc->Elements * desc->Rows * desc->Columns;
660 static inline int is_constant_handle(D3DXHANDLE handle)
662 return !((UINT_PTR)handle >> 16);
665 static inline ctab_constant *constant_from_handle(struct ID3DXConstantTableImpl *table, D3DXHANDLE handle)
667 return &table->constants[(UINT_PTR)handle - 1];
670 static inline D3DXHANDLE handle_from_constant_index(UINT index)
672 return (D3DXHANDLE)(DWORD_PTR)(index + 1);
675 static inline void set_float_shader_constant(struct ID3DXConstantTableImpl *table, IDirect3DDevice9 *device,
676 UINT register_index, const FLOAT *data, UINT count)
678 if (is_vertex_shader(table->desc.Version))
679 IDirect3DDevice9_SetVertexShaderConstantF(device, register_index, data, count);
681 IDirect3DDevice9_SetPixelShaderConstantF(device, register_index, data, count);
684 /*** IUnknown methods ***/
685 static HRESULT WINAPI ID3DXConstantTableImpl_QueryInterface(ID3DXConstantTable *iface, REFIID riid, void **out)
687 TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
689 if (IsEqualGUID(riid, &IID_IUnknown) ||
690 IsEqualGUID(riid, &IID_ID3DXBuffer) ||
691 IsEqualGUID(riid, &IID_ID3DXConstantTable))
693 ID3DXConstantTable_AddRef(iface);
698 WARN("Interface %s not found.\n", debugstr_guid(riid));
700 return E_NOINTERFACE;
703 static ULONG WINAPI ID3DXConstantTableImpl_AddRef(ID3DXConstantTable *iface)
705 struct ID3DXConstantTableImpl *This = impl_from_ID3DXConstantTable(iface);
707 TRACE("(%p)->(): AddRef from %d\n", This, This->ref);
709 return InterlockedIncrement(&This->ref);
712 static ULONG WINAPI ID3DXConstantTableImpl_Release(ID3DXConstantTable *iface)
714 struct ID3DXConstantTableImpl *This = impl_from_ID3DXConstantTable(iface);
715 ULONG ref = InterlockedDecrement(&This->ref);
717 TRACE("(%p)->(): Release from %d\n", This, ref + 1);
721 free_constant_table(This);
722 HeapFree(GetProcessHeap(), 0, This);
728 /*** ID3DXBuffer methods ***/
729 static LPVOID WINAPI ID3DXConstantTableImpl_GetBufferPointer(ID3DXConstantTable *iface)
731 struct ID3DXConstantTableImpl *This = impl_from_ID3DXConstantTable(iface);
733 TRACE("(%p)->()\n", This);
738 static DWORD WINAPI ID3DXConstantTableImpl_GetBufferSize(ID3DXConstantTable *iface)
740 struct ID3DXConstantTableImpl *This = impl_from_ID3DXConstantTable(iface);
742 TRACE("(%p)->()\n", This);
747 /*** ID3DXConstantTable methods ***/
748 static HRESULT WINAPI ID3DXConstantTableImpl_GetDesc(ID3DXConstantTable *iface, D3DXCONSTANTTABLE_DESC *desc)
750 struct ID3DXConstantTableImpl *This = impl_from_ID3DXConstantTable(iface);
752 TRACE("(%p)->(%p)\n", This, desc);
755 return D3DERR_INVALIDCALL;
757 memcpy(desc, &This->desc, sizeof(This->desc));
762 static HRESULT WINAPI ID3DXConstantTableImpl_GetConstantDesc(ID3DXConstantTable *iface, D3DXHANDLE constant,
763 D3DXCONSTANT_DESC *desc, UINT *count)
765 struct ID3DXConstantTableImpl *This = impl_from_ID3DXConstantTable(iface);
766 ctab_constant *constant_info;
768 TRACE("(%p)->(%p, %p, %p)\n", This, constant, desc, count);
771 return D3DERR_INVALIDCALL;
773 /* Applications can pass the name of the constant in place of the handle */
774 if (!is_constant_handle(constant))
776 constant = ID3DXConstantTable_GetConstantByName(iface, NULL, constant);
778 return D3DERR_INVALIDCALL;
781 constant_info = constant_from_handle(This, constant);
784 *desc = constant_info->desc;
791 static UINT WINAPI ID3DXConstantTableImpl_GetSamplerIndex(ID3DXConstantTable *iface, D3DXHANDLE constant)
793 struct ID3DXConstantTableImpl *This = impl_from_ID3DXConstantTable(iface);
794 D3DXCONSTANT_DESC desc;
798 TRACE("(%p)->(%p)\n", This, constant);
800 res = ID3DXConstantTable_GetConstantDesc(iface, constant, &desc, &count);
804 if (desc.RegisterSet != D3DXRS_SAMPLER)
807 return desc.RegisterIndex;
810 static D3DXHANDLE WINAPI ID3DXConstantTableImpl_GetConstant(ID3DXConstantTable *iface, D3DXHANDLE constant, UINT index)
812 struct ID3DXConstantTableImpl *This = impl_from_ID3DXConstantTable(iface);
814 TRACE("(%p)->(%p, %d)\n", This, constant, index);
818 FIXME("Only top level constants supported\n");
822 if (index >= This->desc.Constants)
825 return handle_from_constant_index(index);
828 static D3DXHANDLE WINAPI ID3DXConstantTableImpl_GetConstantByName(ID3DXConstantTable *iface, D3DXHANDLE constant, LPCSTR name)
830 struct ID3DXConstantTableImpl *This = impl_from_ID3DXConstantTable(iface);
833 TRACE("(%p)->(%p, %s)\n", This, constant, name);
840 FIXME("Only top level constants supported\n");
844 for (i = 0; i < This->desc.Constants; i++)
845 if (!strcmp(This->constants[i].desc.Name, name))
846 return handle_from_constant_index(i);
851 static D3DXHANDLE WINAPI ID3DXConstantTableImpl_GetConstantElement(ID3DXConstantTable *iface, D3DXHANDLE constant, UINT index)
853 struct ID3DXConstantTableImpl *This = impl_from_ID3DXConstantTable(iface);
855 FIXME("(%p)->(%p, %d): stub\n", This, constant, index);
860 static HRESULT set_scalar_array(ID3DXConstantTable *iface, IDirect3DDevice9 *device, D3DXHANDLE constant, const void *data,
861 UINT count, D3DXPARAMETER_TYPE type)
863 struct ID3DXConstantTableImpl *This = impl_from_ID3DXConstantTable(iface);
864 D3DXCONSTANT_DESC desc;
866 UINT i, desc_count = 1;
867 float row[4] = {0.0f, 0.0f, 0.0f, 0.0f};
869 hr = ID3DXConstantTable_GetConstantDesc(iface, constant, &desc, &desc_count);
872 TRACE("ID3DXConstantTable_GetConstantDesc failed: %08x\n", hr);
873 return D3DERR_INVALIDCALL;
876 if (desc.Class != D3DXPC_SCALAR)
879 switch (desc.RegisterSet)
882 for (i = 0; i < min(count, desc.RegisterCount); i++)
884 /* We need the for loop since each IDirect3DDevice9_Set*ShaderConstantF expects a float4 */
888 row[0] = ((float *)data)[i];
891 row[0] = (float)((int *)data)[i];
894 row[0] = ((BOOL *)data)[i] ? 1.0f : 0.0f;
897 FIXME("Unhandled type %#x\n", type);
898 return D3DERR_INVALIDCALL;
900 set_float_shader_constant(This, device, desc.RegisterIndex + i, row, 1);
904 FIXME("Handle other register sets\n");
911 static HRESULT set_vector_array(ID3DXConstantTable *iface, IDirect3DDevice9 *device, D3DXHANDLE constant, const void *data,
912 UINT count, D3DXPARAMETER_TYPE type)
914 struct ID3DXConstantTableImpl *This = impl_from_ID3DXConstantTable(iface);
915 D3DXCONSTANT_DESC desc;
917 UINT i, j, desc_count = 1;
918 float vec[4] = {0.0f, 0.0f, 0.0f, 0.0f};
920 hr = ID3DXConstantTable_GetConstantDesc(iface, constant, &desc, &desc_count);
923 TRACE("ID3DXConstantTable_GetConstantDesc failed: %08x\n", hr);
924 return D3DERR_INVALIDCALL;
927 if (desc.Class == D3DXPC_MATRIX_ROWS || desc.Class == D3DXPC_MATRIX_COLUMNS)
930 switch (desc.RegisterSet)
933 for (i = 0; i < min(count, desc.RegisterCount); i++)
938 memcpy(vec, ((float *)data) + i * desc.Columns, desc.Columns * sizeof(float));
941 for (j = 0; j < desc.Columns; j++)
942 vec[j] = (float)((int *)data)[i * desc.Columns + j];
945 for (j = 0; j < desc.Columns; j++)
946 vec[j] = ((BOOL *)data)[i * desc.Columns + j] ? 1.0f : 0.0f;
949 FIXME("Unhandled type %#x\n", type);
950 return D3DERR_INVALIDCALL;
953 set_float_shader_constant(This, device, desc.RegisterIndex + i, vec, 1);
957 FIXME("Unhandled register set %#x\n", desc.RegisterSet);
964 static HRESULT set_float_matrix(FLOAT *matrix, const D3DXCONSTANT_DESC *desc,
965 UINT row_offset, UINT column_offset, UINT rows, UINT columns,
966 const void *data, D3DXPARAMETER_TYPE type, UINT src_columns)
973 for (i = 0; i < rows; i++)
975 for (j = 0; j < columns; j++)
976 matrix[i * row_offset + j * column_offset] = ((FLOAT *)data)[i * src_columns + j];
980 for (i = 0; i < rows; i++)
982 for (j = 0; j < columns; j++)
983 matrix[i * row_offset + j * column_offset] = ((INT *)data)[i * src_columns + j];
987 FIXME("Unhandled type %#x\n", type);
988 return D3DERR_INVALIDCALL;
994 static HRESULT set_matrix_array(ID3DXConstantTable *iface, IDirect3DDevice9 *device, D3DXHANDLE constant, const void *data,
995 UINT count, D3DXPARAMETER_CLASS class, D3DXPARAMETER_TYPE type, UINT rows, UINT columns)
997 struct ID3DXConstantTableImpl *This = impl_from_ID3DXConstantTable(iface);
998 D3DXCONSTANT_DESC desc;
1000 UINT registers_per_matrix;
1001 UINT i, desc_count = 1;
1002 UINT num_rows, num_columns;
1003 UINT row_offset, column_offset;
1004 const DWORD *data_ptr;
1005 FLOAT matrix[16] = {0.0f, 0.0f, 0.0f, 0.0f,
1006 0.0f, 0.0f, 0.0f, 0.0f,
1007 0.0f, 0.0f, 0.0f, 0.0f,
1008 0.0f, 0.0f, 0.0f, 0.0f};
1010 hr = ID3DXConstantTable_GetConstantDesc(iface, constant, &desc, &desc_count);
1013 TRACE("ID3DXConstantTable_GetConstantDesc failed: %08x\n", hr);
1014 return D3DERR_INVALIDCALL;
1017 if (desc.Class == D3DXPC_MATRIX_ROWS || desc.Class == D3DXPC_MATRIX_COLUMNS)
1019 if (desc.Class == class)
1030 if (class == D3DXPC_MATRIX_ROWS)
1032 num_rows = min(desc.Rows, rows);
1033 num_columns = min(desc.Columns, columns);
1037 num_rows = min(desc.Columns, columns);
1038 num_columns = min(desc.Rows, rows);
1041 registers_per_matrix = (desc.Class == D3DXPC_MATRIX_ROWS) ? desc.Rows : desc.Columns;
1043 else if (desc.Class == D3DXPC_SCALAR)
1047 num_rows = min(desc.Rows, rows);
1048 num_columns = min(desc.Columns, columns);
1049 registers_per_matrix = 1;
1053 FIXME("Unhandled variable class %#x\n", desc.Class);
1057 switch (desc.RegisterSet)
1061 for (i = 0; i < count; i++)
1063 if (registers_per_matrix * (i + 1) > desc.RegisterCount)
1066 hr = set_float_matrix(matrix, &desc, row_offset, column_offset, num_rows, num_columns, data_ptr, type, columns);
1067 if (FAILED(hr)) return hr;
1069 set_float_shader_constant(This, device, desc.RegisterIndex + i * registers_per_matrix, matrix, registers_per_matrix);
1071 data_ptr += rows * columns;
1075 FIXME("Unhandled register set %#x\n", desc.RegisterSet);
1082 static HRESULT set_matrix_pointer_array(ID3DXConstantTable *iface, IDirect3DDevice9 *device, D3DXHANDLE constant,
1083 const D3DXMATRIX **data, UINT count, D3DXPARAMETER_CLASS class)
1085 struct ID3DXConstantTableImpl *This = impl_from_ID3DXConstantTable(iface);
1086 D3DXCONSTANT_DESC desc;
1088 UINT registers_per_matrix;
1089 UINT i, desc_count = 1;
1090 UINT num_rows, num_columns;
1091 UINT row_offset, column_offset;
1092 FLOAT matrix[16] = {0.0f, 0.0f, 0.0f, 0.0f,
1093 0.0f, 0.0f, 0.0f, 0.0f,
1094 0.0f, 0.0f, 0.0f, 0.0f,
1095 0.0f, 0.0f, 0.0f, 0.0f};
1097 hr = ID3DXConstantTable_GetConstantDesc(iface, constant, &desc, &desc_count);
1100 TRACE("ID3DXConstantTable_GetConstantDesc failed: %08x\n", hr);
1101 return D3DERR_INVALIDCALL;
1104 if (desc.Class == D3DXPC_MATRIX_ROWS || desc.Class == D3DXPC_MATRIX_COLUMNS)
1106 if (desc.Class == class)
1117 if (class == D3DXPC_MATRIX_ROWS)
1119 num_rows = desc.Rows;
1120 num_columns = desc.Columns;
1124 num_rows = desc.Columns;
1125 num_columns = desc.Rows;
1128 registers_per_matrix = (desc.Class == D3DXPC_MATRIX_ROWS) ? desc.Rows : desc.Columns;
1130 else if (desc.Class == D3DXPC_SCALAR)
1132 registers_per_matrix = 1;
1135 num_rows = desc.Rows;
1136 num_columns = desc.Columns;
1138 else if (desc.Class == D3DXPC_VECTOR)
1140 registers_per_matrix = 1;
1142 if (class == D3DXPC_MATRIX_ROWS)
1146 num_rows = desc.Rows;
1147 num_columns = desc.Columns;
1153 num_rows = desc.Columns;
1154 num_columns = desc.Rows;
1159 FIXME("Unhandled variable class %#x\n", desc.Class);
1163 switch (desc.RegisterSet)
1166 for (i = 0; i < count; i++)
1168 if (registers_per_matrix * (i + 1) > desc.RegisterCount)
1171 hr = set_float_matrix(matrix, &desc, row_offset, column_offset, num_rows, num_columns, *data, D3DXPT_FLOAT, 4);
1172 if (FAILED(hr)) return hr;
1174 set_float_shader_constant(This, device, desc.RegisterIndex + i * registers_per_matrix, matrix, registers_per_matrix);
1180 FIXME("Unhandled register set %#x\n", desc.RegisterSet);
1187 static HRESULT WINAPI ID3DXConstantTableImpl_SetDefaults(ID3DXConstantTable *iface, LPDIRECT3DDEVICE9 device)
1189 struct ID3DXConstantTableImpl *This = impl_from_ID3DXConstantTable(iface);
1192 TRACE("(%p)->(%p)\n", This, device);
1195 return D3DERR_INVALIDCALL;
1197 for (i = 0; i < This->desc.Constants; i++)
1199 D3DXCONSTANT_DESC *desc = &This->constants[i].desc;
1201 if (!desc->DefaultValue)
1204 set_float_shader_constant(This, device, desc->RegisterIndex, desc->DefaultValue, desc->RegisterCount);
1210 static HRESULT WINAPI ID3DXConstantTableImpl_SetValue(ID3DXConstantTable *iface, LPDIRECT3DDEVICE9 device,
1211 D3DXHANDLE constant, LPCVOID data, UINT bytes)
1213 struct ID3DXConstantTableImpl *This = impl_from_ID3DXConstantTable(iface);
1217 D3DXCONSTANT_DESC desc;
1219 TRACE("(%p)->(%p, %p, %p, %d)\n", This, device, constant, data, bytes);
1221 if (!device || !constant || !data)
1222 return D3DERR_INVALIDCALL;
1224 hr = ID3DXConstantTable_GetConstantDesc(iface, constant, &desc, &count);
1228 elements = bytes / (desc.Bytes / desc.Elements);
1233 return set_scalar_array(iface, device, constant, data, elements, desc.Type);
1235 return set_vector_array(iface, device, constant, data,elements, desc.Type);
1236 case D3DXPC_MATRIX_ROWS:
1237 case D3DXPC_MATRIX_COLUMNS:
1238 return set_matrix_array(iface, device, constant, data, elements,
1239 D3DXPC_MATRIX_ROWS, desc.Type, desc.Rows, desc.Columns);
1241 FIXME("Unhandled parameter class %#x\n", desc.Class);
1242 return D3DERR_INVALIDCALL;
1246 static HRESULT WINAPI ID3DXConstantTableImpl_SetBool(ID3DXConstantTable *iface, LPDIRECT3DDEVICE9 device,
1247 D3DXHANDLE constant, BOOL b)
1249 struct ID3DXConstantTableImpl *This = impl_from_ID3DXConstantTable(iface);
1251 TRACE("(%p)->(%p, %p, %d)\n", This, device, constant, b);
1253 return set_scalar_array(iface, device, constant, &b, 1, D3DXPT_BOOL);
1256 static HRESULT WINAPI ID3DXConstantTableImpl_SetBoolArray(ID3DXConstantTable *iface, LPDIRECT3DDEVICE9 device,
1257 D3DXHANDLE constant, CONST BOOL* b, UINT count)
1259 struct ID3DXConstantTableImpl *This = impl_from_ID3DXConstantTable(iface);
1261 TRACE("(%p)->(%p, %p, %p, %d)\n", This, device, constant, b, count);
1263 return set_scalar_array(iface, device, constant, b, count, D3DXPT_BOOL);
1266 static HRESULT WINAPI ID3DXConstantTableImpl_SetInt(ID3DXConstantTable *iface, LPDIRECT3DDEVICE9 device, D3DXHANDLE constant, INT n)
1268 struct ID3DXConstantTableImpl *This = impl_from_ID3DXConstantTable(iface);
1270 TRACE("(%p)->(%p, %p, %d)\n", This, device, constant, n);
1272 return set_scalar_array(iface, device, constant, &n, 1, D3DXPT_INT);
1275 static HRESULT WINAPI ID3DXConstantTableImpl_SetIntArray(ID3DXConstantTable *iface, LPDIRECT3DDEVICE9 device,
1276 D3DXHANDLE constant, CONST INT* n, UINT count)
1278 struct ID3DXConstantTableImpl *This = impl_from_ID3DXConstantTable(iface);
1280 TRACE("(%p)->(%p, %p, %p, %d)\n", This, device, constant, n, count);
1282 return set_scalar_array(iface, device, constant, n, count, D3DXPT_INT);
1285 static HRESULT WINAPI ID3DXConstantTableImpl_SetFloat(ID3DXConstantTable *iface, LPDIRECT3DDEVICE9 device,
1286 D3DXHANDLE constant, FLOAT f)
1288 struct ID3DXConstantTableImpl *This = impl_from_ID3DXConstantTable(iface);
1290 TRACE("(%p)->(%p, %p, %f)\n", This, device, constant, f);
1292 return set_scalar_array(iface, device, constant, &f, 1, D3DXPT_FLOAT);
1295 static HRESULT WINAPI ID3DXConstantTableImpl_SetFloatArray(ID3DXConstantTable *iface, LPDIRECT3DDEVICE9 device,
1296 D3DXHANDLE constant, CONST FLOAT *f, UINT count)
1298 struct ID3DXConstantTableImpl *This = impl_from_ID3DXConstantTable(iface);
1300 TRACE("(%p)->(%p, %p, %p, %d)\n", This, device, constant, f, count);
1302 return set_scalar_array(iface, device, constant, f, count, D3DXPT_FLOAT);
1305 static HRESULT WINAPI ID3DXConstantTableImpl_SetVector(ID3DXConstantTable *iface, LPDIRECT3DDEVICE9 device,
1306 D3DXHANDLE constant, CONST D3DXVECTOR4 *vector)
1308 struct ID3DXConstantTableImpl *This = impl_from_ID3DXConstantTable(iface);
1310 TRACE("(%p)->(%p, %p, %p)\n", This, device, constant, vector);
1312 return set_vector_array(iface, device, constant, vector, 1, D3DXPT_FLOAT);
1315 static HRESULT WINAPI ID3DXConstantTableImpl_SetVectorArray(ID3DXConstantTable *iface, LPDIRECT3DDEVICE9 device,
1316 D3DXHANDLE constant, CONST D3DXVECTOR4 *vector, UINT count)
1318 struct ID3DXConstantTableImpl *This = impl_from_ID3DXConstantTable(iface);
1320 TRACE("(%p)->(%p, %p, %p, %d)\n", This, device, constant, vector, count);
1322 return set_vector_array(iface, device, constant, vector, count, D3DXPT_FLOAT);
1325 static HRESULT WINAPI ID3DXConstantTableImpl_SetMatrix(ID3DXConstantTable *iface, LPDIRECT3DDEVICE9 device,
1326 D3DXHANDLE constant, CONST D3DXMATRIX *matrix)
1328 struct ID3DXConstantTableImpl *This = impl_from_ID3DXConstantTable(iface);
1330 TRACE("(%p)->(%p, %p, %p)\n", This, device, constant, matrix);
1332 return set_matrix_array(iface, device, constant, matrix, 1, D3DXPC_MATRIX_ROWS, D3DXPT_FLOAT, 4, 4);
1335 static HRESULT WINAPI ID3DXConstantTableImpl_SetMatrixArray(ID3DXConstantTable *iface, LPDIRECT3DDEVICE9 device,
1336 D3DXHANDLE constant, CONST D3DXMATRIX *matrix, UINT count)
1338 struct ID3DXConstantTableImpl *This = impl_from_ID3DXConstantTable(iface);
1340 TRACE("(%p)->(%p, %p, %p, %d)\n", This, device, constant, matrix, count);
1342 return set_matrix_array(iface, device, constant, matrix, count, D3DXPC_MATRIX_ROWS, D3DXPT_FLOAT, 4, 4);
1345 static HRESULT WINAPI ID3DXConstantTableImpl_SetMatrixPointerArray(ID3DXConstantTable *iface, LPDIRECT3DDEVICE9 device,
1346 D3DXHANDLE constant, CONST D3DXMATRIX **matrix, UINT count)
1348 struct ID3DXConstantTableImpl *This = impl_from_ID3DXConstantTable(iface);
1350 TRACE("(%p)->(%p, %p, %p, %d)\n", This, device, constant, matrix, count);
1352 return set_matrix_pointer_array(iface, device, constant, matrix, count, D3DXPC_MATRIX_ROWS);
1355 static HRESULT WINAPI ID3DXConstantTableImpl_SetMatrixTranspose(ID3DXConstantTable *iface, LPDIRECT3DDEVICE9 device,
1356 D3DXHANDLE constant, CONST D3DXMATRIX *matrix)
1358 struct ID3DXConstantTableImpl *This = impl_from_ID3DXConstantTable(iface);
1360 TRACE("(%p)->(%p, %p, %p)\n", This, device, constant, matrix);
1362 return set_matrix_array(iface, device, constant, matrix, 1, D3DXPC_MATRIX_COLUMNS, D3DXPT_FLOAT, 4, 4);
1365 static HRESULT WINAPI ID3DXConstantTableImpl_SetMatrixTransposeArray(ID3DXConstantTable *iface, LPDIRECT3DDEVICE9 device,
1366 D3DXHANDLE constant, CONST D3DXMATRIX *matrix, UINT count)
1368 struct ID3DXConstantTableImpl *This = impl_from_ID3DXConstantTable(iface);
1370 TRACE("(%p)->(%p, %p, %p, %d)\n", This, device, constant, matrix, count);
1372 return set_matrix_array(iface, device, constant, matrix, count, D3DXPC_MATRIX_COLUMNS, D3DXPT_FLOAT, 4, 4);
1375 static HRESULT WINAPI ID3DXConstantTableImpl_SetMatrixTransposePointerArray(ID3DXConstantTable *iface, LPDIRECT3DDEVICE9 device,
1376 D3DXHANDLE constant, CONST D3DXMATRIX **matrix, UINT count)
1378 struct ID3DXConstantTableImpl *This = impl_from_ID3DXConstantTable(iface);
1380 TRACE("(%p)->(%p, %p, %p, %d)\n", This, device, constant, matrix, count);
1382 return set_matrix_pointer_array(iface, device, constant, matrix, count, D3DXPC_MATRIX_COLUMNS);
1385 static const struct ID3DXConstantTableVtbl ID3DXConstantTable_Vtbl =
1387 /*** IUnknown methods ***/
1388 ID3DXConstantTableImpl_QueryInterface,
1389 ID3DXConstantTableImpl_AddRef,
1390 ID3DXConstantTableImpl_Release,
1391 /*** ID3DXBuffer methods ***/
1392 ID3DXConstantTableImpl_GetBufferPointer,
1393 ID3DXConstantTableImpl_GetBufferSize,
1394 /*** ID3DXConstantTable methods ***/
1395 ID3DXConstantTableImpl_GetDesc,
1396 ID3DXConstantTableImpl_GetConstantDesc,
1397 ID3DXConstantTableImpl_GetSamplerIndex,
1398 ID3DXConstantTableImpl_GetConstant,
1399 ID3DXConstantTableImpl_GetConstantByName,
1400 ID3DXConstantTableImpl_GetConstantElement,
1401 ID3DXConstantTableImpl_SetDefaults,
1402 ID3DXConstantTableImpl_SetValue,
1403 ID3DXConstantTableImpl_SetBool,
1404 ID3DXConstantTableImpl_SetBoolArray,
1405 ID3DXConstantTableImpl_SetInt,
1406 ID3DXConstantTableImpl_SetIntArray,
1407 ID3DXConstantTableImpl_SetFloat,
1408 ID3DXConstantTableImpl_SetFloatArray,
1409 ID3DXConstantTableImpl_SetVector,
1410 ID3DXConstantTableImpl_SetVectorArray,
1411 ID3DXConstantTableImpl_SetMatrix,
1412 ID3DXConstantTableImpl_SetMatrixArray,
1413 ID3DXConstantTableImpl_SetMatrixPointerArray,
1414 ID3DXConstantTableImpl_SetMatrixTranspose,
1415 ID3DXConstantTableImpl_SetMatrixTransposeArray,
1416 ID3DXConstantTableImpl_SetMatrixTransposePointerArray
1419 static HRESULT parse_ctab_constant_type(const D3DXSHADER_TYPEINFO *type, ctab_constant *constant)
1421 constant->desc.Class = type->Class;
1422 constant->desc.Type = type->Type;
1423 constant->desc.Rows = type->Rows;
1424 constant->desc.Columns = type->Columns;
1425 constant->desc.Elements = type->Elements;
1426 constant->desc.StructMembers = type->StructMembers;
1427 constant->desc.Bytes = calc_bytes(&constant->desc);
1429 TRACE("class = %d, type = %d, rows = %d, columns = %d, elements = %d, struct_members = %d\n",
1430 constant->desc.Class, constant->desc.Type, constant->desc.Rows,
1431 constant->desc.Columns, constant->desc.Elements, constant->desc.StructMembers);
1433 if ((constant->desc.Class == D3DXPC_STRUCT) && constant->desc.StructMembers)
1435 FIXME("Struct not supported yet\n");
1442 HRESULT WINAPI D3DXGetShaderConstantTableEx(CONST DWORD *byte_code,
1444 LPD3DXCONSTANTTABLE *constant_table)
1446 struct ID3DXConstantTableImpl *object = NULL;
1450 const D3DXSHADER_CONSTANTTABLE* ctab_header;
1451 D3DXSHADER_CONSTANTINFO* constant_info;
1454 TRACE("(%p, %x, %p)\n", byte_code, flags, constant_table);
1456 if (!byte_code || !constant_table)
1458 WARN("Invalid argument specified.\n");
1459 return D3DERR_INVALIDCALL;
1462 hr = D3DXFindShaderComment(byte_code, MAKEFOURCC('C','T','A','B'), &data, &size);
1465 WARN("CTAB not found.\n");
1466 return D3DXERR_INVALIDDATA;
1469 if (size < sizeof(D3DXSHADER_CONSTANTTABLE))
1471 WARN("Invalid CTAB size.\n");
1472 return D3DXERR_INVALIDDATA;
1475 ctab_header = (const D3DXSHADER_CONSTANTTABLE *)data;
1476 if (ctab_header->Size != sizeof(D3DXSHADER_CONSTANTTABLE))
1478 WARN("Invalid D3DXSHADER_CONSTANTTABLE size.\n");
1479 return D3DXERR_INVALIDDATA;
1482 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
1485 ERR("Out of memory\n");
1486 return E_OUTOFMEMORY;
1489 object->ID3DXConstantTable_iface.lpVtbl = &ID3DXConstantTable_Vtbl;
1492 object->ctab = HeapAlloc(GetProcessHeap(), 0, size);
1495 ERR("Out of memory\n");
1496 HeapFree(GetProcessHeap(), 0, object);
1497 return E_OUTOFMEMORY;
1499 object->size = size;
1500 memcpy(object->ctab, data, object->size);
1502 object->desc.Creator = ctab_header->Creator ? object->ctab + ctab_header->Creator : NULL;
1503 object->desc.Version = ctab_header->Version;
1504 object->desc.Constants = ctab_header->Constants;
1505 TRACE("Creator %s, Version %x, Constants %u, Target %s\n",
1506 debugstr_a(object->desc.Creator), object->desc.Version, object->desc.Constants,
1507 debugstr_a(ctab_header->Target ? object->ctab + ctab_header->Target : NULL));
1509 if (object->desc.Constants > 65535)
1511 FIXME("Too many constants (%u)\n", object->desc.Constants);
1516 object->constants = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
1517 sizeof(*object->constants) * object->desc.Constants);
1518 if (!object->constants)
1520 ERR("Out of memory\n");
1525 constant_info = (LPD3DXSHADER_CONSTANTINFO)(object->ctab + ctab_header->ConstantInfo);
1526 for (i = 0; i < ctab_header->Constants; i++)
1528 TRACE("name = %s\n", object->ctab + constant_info[i].Name);
1529 object->constants[i].desc.Name = object->ctab + constant_info[i].Name;
1530 object->constants[i].desc.RegisterSet = constant_info[i].RegisterSet;
1531 object->constants[i].desc.RegisterIndex = constant_info[i].RegisterIndex;
1532 object->constants[i].desc.RegisterCount = constant_info[i].RegisterCount;
1533 object->constants[i].desc.DefaultValue = constant_info[i].DefaultValue
1534 ? object->ctab + constant_info[i].DefaultValue : NULL;
1536 hr = parse_ctab_constant_type((LPD3DXSHADER_TYPEINFO)(object->ctab + constant_info[i].TypeInfo),
1537 &object->constants[i]);
1542 *constant_table = &object->ID3DXConstantTable_iface;
1548 free_constant_table(object);
1549 HeapFree(GetProcessHeap(), 0, object);
1554 HRESULT WINAPI D3DXGetShaderConstantTable(CONST DWORD* byte_code,
1555 LPD3DXCONSTANTTABLE* constant_table)
1557 TRACE("(%p, %p): Forwarded to D3DXGetShaderConstantTableEx\n", byte_code, constant_table);
1559 return D3DXGetShaderConstantTableEx(byte_code, 0, constant_table);
1562 HRESULT WINAPI D3DXGetShaderSamplers(CONST DWORD *byte_code, LPCSTR *samplers, UINT *count)
1565 UINT i, sampler_count = 0;
1568 const D3DXSHADER_CONSTANTTABLE *ctab_header;
1569 const D3DXSHADER_CONSTANTINFO *constant_info;
1571 TRACE("byte_code %p, samplers %p, count %p\n", byte_code, samplers, count);
1573 if (count) *count = 0;
1575 hr = D3DXFindShaderComment(byte_code, MAKEFOURCC('C','T','A','B'), (LPCVOID *)&data, &size);
1576 if (hr != D3D_OK) return D3D_OK;
1578 if (size < sizeof(D3DXSHADER_CONSTANTTABLE)) return D3D_OK;
1580 ctab_header = (const D3DXSHADER_CONSTANTTABLE *)data;
1581 if (ctab_header->Size != sizeof(*ctab_header)) return D3D_OK;
1583 constant_info = (D3DXSHADER_CONSTANTINFO *)(data + ctab_header->ConstantInfo);
1584 for (i = 0; i < ctab_header->Constants; i++)
1586 const D3DXSHADER_TYPEINFO *type;
1588 TRACE("name = %s\n", data + constant_info[i].Name);
1590 type = (D3DXSHADER_TYPEINFO *)(data + constant_info[i].TypeInfo);
1592 if (type->Type == D3DXPT_SAMPLER
1593 || type->Type == D3DXPT_SAMPLER1D
1594 || type->Type == D3DXPT_SAMPLER2D
1595 || type->Type == D3DXPT_SAMPLER3D
1596 || type->Type == D3DXPT_SAMPLERCUBE)
1598 if (samplers) samplers[sampler_count] = data + constant_info[i].Name;
1604 TRACE("Found %u samplers\n", sampler_count);
1606 if (count) *count = sampler_count;