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(const void *data
, SIZE_T datasize
, const char *filename
,
39 const D3D_SHADER_MACRO
*defines
, ID3DInclude
*include
, UINT flags
,
40 ID3DBlob
**shader
, ID3DBlob
**error_messages
);
42 static inline BOOL
is_valid_bytecode(DWORD token
)
44 return (token
& 0xfffe0000) == 0xfffe0000;
47 const char * WINAPI
D3DXGetPixelShaderProfile(struct IDirect3DDevice9
*device
)
51 TRACE("device %p\n", device
);
53 if (!device
) return NULL
;
55 IDirect3DDevice9_GetDeviceCaps(device
,&caps
);
57 switch (caps
.PixelShaderVersion
)
59 case D3DPS_VERSION(1, 1):
62 case D3DPS_VERSION(1, 2):
65 case D3DPS_VERSION(1, 3):
68 case D3DPS_VERSION(1, 4):
71 case D3DPS_VERSION(2, 0):
72 if ((caps
.PS20Caps
.NumTemps
>=22) &&
73 (caps
.PS20Caps
.Caps
&D3DPS20CAPS_ARBITRARYSWIZZLE
) &&
74 (caps
.PS20Caps
.Caps
&D3DPS20CAPS_GRADIENTINSTRUCTIONS
) &&
75 (caps
.PS20Caps
.Caps
&D3DPS20CAPS_PREDICATION
) &&
76 (caps
.PS20Caps
.Caps
&D3DPS20CAPS_NODEPENDENTREADLIMIT
) &&
77 (caps
.PS20Caps
.Caps
&D3DPS20CAPS_NOTEXINSTRUCTIONLIMIT
))
81 if ((caps
.PS20Caps
.NumTemps
>=32) &&
82 (caps
.PS20Caps
.Caps
&D3DPS20CAPS_NOTEXINSTRUCTIONLIMIT
))
88 case D3DPS_VERSION(3, 0):
95 UINT WINAPI
D3DXGetShaderSize(const DWORD
*byte_code
)
97 const DWORD
*ptr
= byte_code
;
99 TRACE("byte_code %p\n", byte_code
);
103 /* Look for the END token, skipping the VERSION token */
104 while (*++ptr
!= D3DSIO_END
)
107 if ((*ptr
& D3DSI_OPCODE_MASK
) == D3DSIO_COMMENT
)
109 ptr
+= ((*ptr
& D3DSI_COMMENTSIZE_MASK
) >> D3DSI_COMMENTSIZE_SHIFT
);
114 /* Return the shader size in bytes */
115 return (ptr
- byte_code
) * sizeof(*ptr
);
118 DWORD WINAPI
D3DXGetShaderVersion(const DWORD
*byte_code
)
120 TRACE("byte_code %p\n", byte_code
);
122 return byte_code
? *byte_code
: 0;
125 const char * WINAPI
D3DXGetVertexShaderProfile(struct IDirect3DDevice9
*device
)
129 TRACE("device %p\n", device
);
131 if (!device
) return NULL
;
133 IDirect3DDevice9_GetDeviceCaps(device
,&caps
);
135 switch (caps
.VertexShaderVersion
)
137 case D3DVS_VERSION(1, 1):
139 case D3DVS_VERSION(2, 0):
140 if ((caps
.VS20Caps
.NumTemps
>=13) &&
141 (caps
.VS20Caps
.DynamicFlowControlDepth
==24) &&
142 (caps
.VS20Caps
.Caps
&D3DPS20CAPS_PREDICATION
))
147 case D3DVS_VERSION(3, 0):
154 HRESULT WINAPI
D3DXFindShaderComment(const DWORD
*byte_code
, DWORD fourcc
, const void **data
, UINT
*size
)
156 const DWORD
*ptr
= byte_code
;
159 TRACE("byte_code %p, fourcc %x, data %p, size %p\n", byte_code
, fourcc
, data
, size
);
161 if (data
) *data
= NULL
;
164 if (!byte_code
) return D3DERR_INVALIDCALL
;
166 version
= *ptr
>> 16;
167 if (version
!= 0x4658 /* FX */
168 && version
!= 0x5458 /* TX */
171 && version
!= 0xfffe /* VS */
172 && version
!= 0xffff) /* PS */
174 WARN("Invalid data supplied\n");
175 return D3DXERR_INVALIDDATA
;
178 while (*++ptr
!= D3DSIO_END
)
180 /* Check if it is a comment */
181 if ((*ptr
& D3DSI_OPCODE_MASK
) == D3DSIO_COMMENT
)
183 DWORD comment_size
= (*ptr
& D3DSI_COMMENTSIZE_MASK
) >> D3DSI_COMMENTSIZE_SHIFT
;
185 /* Check if this is the comment we are looking for */
186 if (*(ptr
+ 1) == fourcc
)
188 UINT ctab_size
= (comment_size
- 1) * sizeof(DWORD
);
189 const void *ctab_data
= ptr
+ 2;
194 TRACE("Returning comment data at %p with size %d\n", ctab_data
, ctab_size
);
204 HRESULT WINAPI
D3DXAssembleShader(const char *data
, UINT data_len
, const D3DXMACRO
*defines
,
205 ID3DXInclude
*include
, DWORD flags
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
209 TRACE("data %p, data_len %u, defines %p, include %p, flags %#x, shader %p, error_messages %p\n",
210 data
, data_len
, defines
, include
, flags
, shader
, error_messages
);
212 /* Forward to d3dcompiler: the parameter types aren't really different,
213 the actual data types are equivalent */
214 hr
= D3DAssemble(data
, data_len
, NULL
, (D3D_SHADER_MACRO
*)defines
,
215 (ID3DInclude
*)include
, flags
, (ID3DBlob
**)shader
,
216 (ID3DBlob
**)error_messages
);
218 if(hr
== E_FAIL
) hr
= D3DXERR_INVALIDDATA
;
222 /* D3DXInclude private implementation, used to implement
223 * D3DXAssembleShaderFromFile() from D3DXAssembleShader(). */
224 /* To be able to correctly resolve include search paths we have to store the
225 * pathname of each include file. We store the pathname pointer right before
227 static HRESULT WINAPI
d3dincludefromfile_open(ID3DXInclude
*iface
, D3DXINCLUDE_TYPE include_type
,
228 const char *filename
, const void *parent_data
, const void **data
, UINT
*bytes
)
230 const char *p
, *parent_name
= "";
231 char *pathname
= NULL
;
232 char **buffer
= NULL
;
236 if(parent_data
!= NULL
)
237 parent_name
= *((const char **)parent_data
- 1);
239 TRACE("Looking up for include file %s, parent %s\n", debugstr_a(filename
), debugstr_a(parent_name
));
241 if ((p
= strrchr(parent_name
, '\\')) || (p
= strrchr(parent_name
, '/'))) p
++;
242 else p
= parent_name
;
243 pathname
= HeapAlloc(GetProcessHeap(), 0, (p
- parent_name
) + strlen(filename
) + 1);
245 return HRESULT_FROM_WIN32(GetLastError());
247 memcpy(pathname
, parent_name
, p
- parent_name
);
248 strcpy(pathname
+ (p
- parent_name
), filename
);
250 file
= CreateFileA(pathname
, GENERIC_READ
, FILE_SHARE_READ
, 0, OPEN_EXISTING
, 0, 0);
251 if(file
== INVALID_HANDLE_VALUE
)
254 TRACE("Include file found at pathname = %s\n", debugstr_a(pathname
));
256 size
= GetFileSize(file
, NULL
);
257 if(size
== INVALID_FILE_SIZE
)
260 buffer
= HeapAlloc(GetProcessHeap(), 0, size
+ sizeof(char *));
264 if(!ReadFile(file
, buffer
+ 1, size
, bytes
, NULL
))
274 HeapFree(GetProcessHeap(), 0, pathname
);
275 HeapFree(GetProcessHeap(), 0, buffer
);
276 return HRESULT_FROM_WIN32(GetLastError());
279 static HRESULT WINAPI
d3dincludefromfile_close(ID3DXInclude
*iface
, const void *data
)
281 HeapFree(GetProcessHeap(), 0, *((char **)data
- 1));
282 HeapFree(GetProcessHeap(), 0, (char **)data
- 1);
286 static const struct ID3DXIncludeVtbl D3DXInclude_Vtbl
= {
287 d3dincludefromfile_open
,
288 d3dincludefromfile_close
291 struct D3DXIncludeImpl
{
292 ID3DXInclude ID3DXInclude_iface
;
295 HRESULT WINAPI
D3DXAssembleShaderFromFileA(const char *filename
, const D3DXMACRO
*defines
,
296 ID3DXInclude
*include
, DWORD flags
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
302 TRACE("filename %s, defines %p, include %p, flags %#x, shader %p, error_messages %p.\n",
303 debugstr_a(filename
), defines
, include
, flags
, shader
, error_messages
);
305 if (!filename
) return D3DXERR_INVALIDDATA
;
307 len
= MultiByteToWideChar(CP_ACP
, 0, filename
, -1, NULL
, 0);
308 filename_w
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
309 if (!filename_w
) return E_OUTOFMEMORY
;
310 MultiByteToWideChar(CP_ACP
, 0, filename
, -1, filename_w
, len
);
312 ret
= D3DXAssembleShaderFromFileW(filename_w
, defines
, include
, flags
, shader
, error_messages
);
314 HeapFree(GetProcessHeap(), 0, filename_w
);
318 HRESULT WINAPI
D3DXAssembleShaderFromFileW(const WCHAR
*filename
, const D3DXMACRO
*defines
,
319 ID3DXInclude
*include
, DWORD flags
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
324 struct D3DXIncludeImpl includefromfile
;
327 TRACE("filename %s, defines %p, include %p, flags %#x, shader %p, error_messages %p.\n",
328 debugstr_w(filename
), defines
, include
, flags
, shader
, error_messages
);
332 includefromfile
.ID3DXInclude_iface
.lpVtbl
= &D3DXInclude_Vtbl
;
333 include
= &includefromfile
.ID3DXInclude_iface
;
336 len
= WideCharToMultiByte(CP_ACP
, 0, filename
, -1, NULL
, 0, NULL
, NULL
);
337 filename_a
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(char));
339 return E_OUTOFMEMORY
;
340 WideCharToMultiByte(CP_ACP
, 0, filename
, -1, filename_a
, len
, NULL
, NULL
);
342 hr
= ID3DXInclude_Open(include
, D3D_INCLUDE_LOCAL
, filename_a
, NULL
, &buffer
, &len
);
345 HeapFree(GetProcessHeap(), 0, filename_a
);
346 return D3DXERR_INVALIDDATA
;
349 hr
= D3DXAssembleShader(buffer
, len
, defines
, include
, flags
, shader
, error_messages
);
351 ID3DXInclude_Close(include
, buffer
);
352 HeapFree(GetProcessHeap(), 0, filename_a
);
356 HRESULT WINAPI
D3DXAssembleShaderFromResourceA(HMODULE module
, const char *resource
, const D3DXMACRO
*defines
,
357 ID3DXInclude
*include
, DWORD flags
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
363 TRACE("module %p, resource %s, defines %p, include %p, flags %#x, shader %p, error_messages %p.\n",
364 module
, debugstr_a(resource
), defines
, include
, flags
, shader
, error_messages
);
366 if (!(res
= FindResourceA(module
, resource
, (const char *)RT_RCDATA
)))
367 return D3DXERR_INVALIDDATA
;
368 if (FAILED(load_resource_into_memory(module
, res
, &buffer
, &len
)))
369 return D3DXERR_INVALIDDATA
;
370 return D3DXAssembleShader(buffer
, len
, defines
, include
, flags
,
371 shader
, error_messages
);
374 HRESULT WINAPI
D3DXAssembleShaderFromResourceW(HMODULE module
, const WCHAR
*resource
, const D3DXMACRO
*defines
,
375 ID3DXInclude
*include
, DWORD flags
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
381 TRACE("module %p, resource %s, defines %p, include %p, flags %#x, shader %p, error_messages %p.\n",
382 module
, debugstr_w(resource
), defines
, include
, flags
, shader
, error_messages
);
384 if (!(res
= FindResourceW(module
, resource
, (const WCHAR
*)RT_RCDATA
)))
385 return D3DXERR_INVALIDDATA
;
386 if (FAILED(load_resource_into_memory(module
, res
, &buffer
, &len
)))
387 return D3DXERR_INVALIDDATA
;
388 return D3DXAssembleShader(buffer
, len
, defines
, include
, flags
,
389 shader
, error_messages
);
392 HRESULT WINAPI
D3DXCompileShader(const char *data
, UINT length
, const D3DXMACRO
*defines
,
393 ID3DXInclude
*include
, const char *function
, const char *profile
, DWORD flags
,
394 ID3DXBuffer
**shader
, ID3DXBuffer
**error_msgs
, ID3DXConstantTable
**constant_table
)
398 TRACE("data %s, length %u, defines %p, include %p, function %s, profile %s, "
399 "flags %#x, shader %p, error_msgs %p, constant_table %p.\n",
400 debugstr_a(data
), length
, defines
, include
, debugstr_a(function
), debugstr_a(profile
),
401 flags
, shader
, error_msgs
, constant_table
);
403 hr
= D3DCompile(data
, length
, NULL
, (D3D_SHADER_MACRO
*)defines
, (ID3DInclude
*)include
,
404 function
, profile
, flags
, 0, (ID3DBlob
**)shader
, (ID3DBlob
**)error_msgs
);
406 if (SUCCEEDED(hr
) && constant_table
)
408 hr
= D3DXGetShaderConstantTable(ID3DXBuffer_GetBufferPointer(*shader
), constant_table
);
411 ID3DXBuffer_Release(*shader
);
419 HRESULT WINAPI
D3DXCompileShaderFromFileA(const char *filename
, const D3DXMACRO
*defines
,
420 ID3DXInclude
*include
, const char *entrypoint
, const char *profile
, DWORD flags
,
421 ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
, ID3DXConstantTable
**constant_table
)
427 TRACE("filename %s, defines %p, include %p, entrypoint %s, profile %s, "
428 "flags %#x, shader %p, error_messages %p, constant_table %p.\n",
429 debugstr_a(filename
), defines
, include
, debugstr_a(entrypoint
),
430 debugstr_a(profile
), flags
, shader
, error_messages
, constant_table
);
432 if (!filename
) return D3DXERR_INVALIDDATA
;
434 len
= MultiByteToWideChar(CP_ACP
, 0, filename
, -1, NULL
, 0);
435 filename_w
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
436 if (!filename_w
) return E_OUTOFMEMORY
;
437 MultiByteToWideChar(CP_ACP
, 0, filename
, -1, filename_w
, len
);
439 ret
= D3DXCompileShaderFromFileW(filename_w
, defines
, include
,
440 entrypoint
, profile
, flags
,
441 shader
, error_messages
, constant_table
);
443 HeapFree(GetProcessHeap(), 0, filename_w
);
447 HRESULT WINAPI
D3DXCompileShaderFromFileW(const WCHAR
*filename
, const D3DXMACRO
*defines
,
448 ID3DXInclude
*include
, const char *entrypoint
, const char *profile
, DWORD flags
,
449 ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
, ID3DXConstantTable
**constant_table
)
452 DWORD len
, filename_len
;
454 struct D3DXIncludeImpl includefromfile
;
457 TRACE("filename %s, defines %p, include %p, entrypoint %s, profile %s, "
458 "flags %#x, shader %p, error_messages %p, constant_table %p.\n",
459 debugstr_w(filename
), defines
, include
, debugstr_a(entrypoint
), debugstr_a(profile
),
460 flags
, shader
, error_messages
, constant_table
);
464 includefromfile
.ID3DXInclude_iface
.lpVtbl
= &D3DXInclude_Vtbl
;
465 include
= &includefromfile
.ID3DXInclude_iface
;
468 filename_len
= WideCharToMultiByte(CP_ACP
, 0, filename
, -1, NULL
, 0, NULL
, NULL
);
469 filename_a
= HeapAlloc(GetProcessHeap(), 0, filename_len
* sizeof(char));
471 return E_OUTOFMEMORY
;
472 WideCharToMultiByte(CP_ACP
, 0, filename
, -1, filename_a
, filename_len
, NULL
, NULL
);
474 hr
= ID3DXInclude_Open(include
, D3D_INCLUDE_LOCAL
, filename_a
, NULL
, &buffer
, &len
);
477 HeapFree(GetProcessHeap(), 0, filename_a
);
478 return D3DXERR_INVALIDDATA
;
481 hr
= D3DCompile(buffer
, len
, filename_a
, (const D3D_SHADER_MACRO
*)defines
,
482 (ID3DInclude
*)include
, entrypoint
, profile
, flags
, 0,
483 (ID3DBlob
**)shader
, (ID3DBlob
**)error_messages
);
485 if (SUCCEEDED(hr
) && constant_table
)
486 hr
= D3DXGetShaderConstantTable(ID3DXBuffer_GetBufferPointer(*shader
),
489 ID3DXInclude_Close(include
, buffer
);
490 HeapFree(GetProcessHeap(), 0, filename_a
);
494 HRESULT WINAPI
D3DXCompileShaderFromResourceA(HMODULE module
, const char *resource
, const D3DXMACRO
*defines
,
495 ID3DXInclude
*include
, const char *entrypoint
, const char *profile
, DWORD flags
,
496 ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
, ID3DXConstantTable
**constant_table
)
502 TRACE("module %p, resource %s, defines %p, include %p, entrypoint %s, profile %s, "
503 "flags %#x, shader %p, error_messages %p, constant_table %p.\n",
504 module
, debugstr_a(resource
), defines
, include
, debugstr_a(entrypoint
), debugstr_a(profile
),
505 flags
, shader
, error_messages
, constant_table
);
507 if (!(res
= FindResourceA(module
, resource
, (const char *)RT_RCDATA
)))
508 return D3DXERR_INVALIDDATA
;
509 if (FAILED(load_resource_into_memory(module
, res
, &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
D3DXCompileShaderFromResourceW(HMODULE module
, const WCHAR
*resource
, const D3DXMACRO
*defines
,
516 ID3DXInclude
*include
, const char *entrypoint
, const char *profile
, DWORD flags
,
517 ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
, ID3DXConstantTable
**constant_table
)
523 TRACE("module %p, resource %s, defines %p, include %p, entrypoint %s, profile %s, "
524 "flags %#x, shader %p, error_messages %p, constant_table %p.\n",
525 module
, debugstr_w(resource
), defines
, include
, debugstr_a(entrypoint
), debugstr_a(profile
),
526 flags
, shader
, error_messages
, constant_table
);
528 if (!(res
= FindResourceW(module
, resource
, (const WCHAR
*)RT_RCDATA
)))
529 return D3DXERR_INVALIDDATA
;
530 if (FAILED(load_resource_into_memory(module
, res
, &buffer
, &len
)))
531 return D3DXERR_INVALIDDATA
;
532 return D3DXCompileShader(buffer
, len
, defines
, include
, entrypoint
, profile
,
533 flags
, shader
, error_messages
, constant_table
);
536 HRESULT WINAPI
D3DXPreprocessShader(const char *data
, UINT data_len
, const D3DXMACRO
*defines
,
537 ID3DXInclude
*include
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
539 TRACE("data %s, data_len %u, defines %p, include %p, shader %p, error_messages %p.\n",
540 debugstr_a(data
), data_len
, defines
, include
, shader
, error_messages
);
542 return D3DPreprocess(data
, data_len
, NULL
,
543 (const D3D_SHADER_MACRO
*)defines
, (ID3DInclude
*)include
,
544 (ID3DBlob
**)shader
, (ID3DBlob
**)error_messages
);
547 HRESULT WINAPI
D3DXPreprocessShaderFromFileA(const char *filename
, const D3DXMACRO
*defines
,
548 ID3DXInclude
*include
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
550 WCHAR
*filename_w
= NULL
;
554 TRACE("filename %s, defines %p, include %p, shader %p, error_messages %p.\n",
555 debugstr_a(filename
), defines
, include
, shader
, error_messages
);
557 if (!filename
) return D3DXERR_INVALIDDATA
;
559 len
= MultiByteToWideChar(CP_ACP
, 0, filename
, -1, NULL
, 0);
560 filename_w
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
561 if (!filename_w
) return E_OUTOFMEMORY
;
562 MultiByteToWideChar(CP_ACP
, 0, filename
, -1, filename_w
, len
);
564 ret
= D3DXPreprocessShaderFromFileW(filename_w
, defines
, include
, shader
, error_messages
);
566 HeapFree(GetProcessHeap(), 0, filename_w
);
570 HRESULT WINAPI
D3DXPreprocessShaderFromFileW(const WCHAR
*filename
, const D3DXMACRO
*defines
,
571 ID3DXInclude
*include
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
576 struct D3DXIncludeImpl includefromfile
;
579 TRACE("filename %s, defines %p, include %p, shader %p, error_messages %p.\n",
580 debugstr_w(filename
), defines
, include
, shader
, error_messages
);
584 includefromfile
.ID3DXInclude_iface
.lpVtbl
= &D3DXInclude_Vtbl
;
585 include
= &includefromfile
.ID3DXInclude_iface
;
588 len
= WideCharToMultiByte(CP_ACP
, 0, filename
, -1, NULL
, 0, NULL
, NULL
);
589 filename_a
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(char));
591 return E_OUTOFMEMORY
;
592 WideCharToMultiByte(CP_ACP
, 0, filename
, -1, filename_a
, len
, NULL
, NULL
);
594 hr
= ID3DXInclude_Open(include
, D3D_INCLUDE_LOCAL
, filename_a
, NULL
, &buffer
, &len
);
597 HeapFree(GetProcessHeap(), 0, filename_a
);
598 return D3DXERR_INVALIDDATA
;
601 hr
= D3DPreprocess(buffer
, len
, NULL
,
602 (const D3D_SHADER_MACRO
*)defines
,
603 (ID3DInclude
*) include
,
604 (ID3DBlob
**)shader
, (ID3DBlob
**)error_messages
);
606 ID3DXInclude_Close(include
, buffer
);
607 HeapFree(GetProcessHeap(), 0, filename_a
);
611 HRESULT WINAPI
D3DXPreprocessShaderFromResourceA(HMODULE module
, const char *resource
, const D3DXMACRO
*defines
,
612 ID3DXInclude
*include
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
618 TRACE("module %p, resource %s, defines %p, include %p, shader %p, error_messages %p.\n",
619 module
, debugstr_a(resource
), defines
, include
, shader
, error_messages
);
621 if (!(res
= FindResourceA(module
, resource
, (const char *)RT_RCDATA
)))
622 return D3DXERR_INVALIDDATA
;
623 if (FAILED(load_resource_into_memory(module
, res
, &buffer
, &len
)))
624 return D3DXERR_INVALIDDATA
;
625 return D3DXPreprocessShader(buffer
, len
, defines
, include
,
626 shader
, error_messages
);
629 HRESULT WINAPI
D3DXPreprocessShaderFromResourceW(HMODULE module
, const WCHAR
*resource
, const D3DXMACRO
*defines
,
630 ID3DXInclude
*include
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
636 TRACE("module %p, resource %s, defines %p, include %p, shader %p, error_messages %p.\n",
637 module
, debugstr_w(resource
), defines
, include
, shader
, error_messages
);
639 if (!(res
= FindResourceW(module
, resource
, (const WCHAR
*)RT_RCDATA
)))
640 return D3DXERR_INVALIDDATA
;
641 if (FAILED(load_resource_into_memory(module
, res
, &buffer
, &len
)))
642 return D3DXERR_INVALIDDATA
;
643 return D3DXPreprocessShader(buffer
, len
, defines
, include
,
644 shader
, error_messages
);
648 struct ctab_constant
{
649 D3DXCONSTANT_DESC desc
;
650 struct ctab_constant
*constants
;
653 struct ID3DXConstantTableImpl
{
654 ID3DXConstantTable ID3DXConstantTable_iface
;
658 D3DXCONSTANTTABLE_DESC desc
;
659 struct ctab_constant
*constants
;
662 static void free_constant(struct ctab_constant
*constant
)
664 if (constant
->constants
)
666 UINT i
, count
= constant
->desc
.Elements
> 1 ? constant
->desc
.Elements
: constant
->desc
.StructMembers
;
668 for (i
= 0; i
< count
; ++i
)
670 free_constant(&constant
->constants
[i
]);
672 HeapFree(GetProcessHeap(), 0, constant
->constants
);
676 static void free_constant_table(struct ID3DXConstantTableImpl
*table
)
678 if (table
->constants
)
682 for (i
= 0; i
< table
->desc
.Constants
; ++i
)
684 free_constant(&table
->constants
[i
]);
686 HeapFree(GetProcessHeap(), 0, table
->constants
);
688 HeapFree(GetProcessHeap(), 0, table
->ctab
);
691 static inline struct ID3DXConstantTableImpl
*impl_from_ID3DXConstantTable(ID3DXConstantTable
*iface
)
693 return CONTAINING_RECORD(iface
, struct ID3DXConstantTableImpl
, ID3DXConstantTable_iface
);
696 static inline BOOL
is_vertex_shader(DWORD version
)
698 return (version
& 0xffff0000) == 0xfffe0000;
701 static inline D3DXHANDLE
handle_from_constant(struct ctab_constant
*constant
)
703 return (D3DXHANDLE
)constant
;
706 static struct ctab_constant
*get_constant_by_name(struct ID3DXConstantTableImpl
*table
,
707 struct ctab_constant
*constant
, const char *name
);
709 static struct ctab_constant
*get_constant_element_by_name(struct ctab_constant
*constant
, const char *name
)
714 TRACE("constant %p, name %s\n", constant
, debugstr_a(name
));
716 if (!name
|| !*name
) return NULL
;
718 element
= atoi(name
);
719 part
= strchr(name
, ']') + 1;
721 if (constant
->desc
.Elements
> element
)
723 struct ctab_constant
*c
= constant
->constants
? &constant
->constants
[element
] : constant
;
728 return get_constant_by_name(NULL
, c
, part
);
731 return get_constant_element_by_name(c
, part
);
734 TRACE("Returning parameter %p\n", c
);
738 FIXME("Unhandled case \"%c\"\n", *--part
);
743 TRACE("Constant not found\n");
747 static struct ctab_constant
*get_constant_by_name(struct ID3DXConstantTableImpl
*table
,
748 struct ctab_constant
*constant
, const char *name
)
750 UINT i
, count
, length
;
751 struct ctab_constant
*handles
;
754 TRACE("table %p, constant %p, name %s\n", table
, constant
, debugstr_a(name
));
756 if (!name
|| !*name
) return NULL
;
760 count
= table
->desc
.Constants
;
761 handles
= table
->constants
;
765 count
= constant
->desc
.StructMembers
;
766 handles
= constant
->constants
;
769 length
= strcspn(name
, "[.");
770 part
= name
+ length
;
772 for (i
= 0; i
< count
; i
++)
774 if (strlen(handles
[i
].desc
.Name
) == length
&& !strncmp(handles
[i
].desc
.Name
, name
, length
))
779 return get_constant_by_name(NULL
, &handles
[i
], part
);
782 return get_constant_element_by_name(&handles
[i
], part
);
785 TRACE("Returning parameter %p\n", &handles
[i
]);
791 TRACE("Constant not found\n");
795 static struct ctab_constant
*is_valid_sub_constant(struct ctab_constant
*parent
, D3DXHANDLE handle
)
797 struct ctab_constant
*c
;
800 /* all variable have at least elements = 1, but not always elements */
801 if (!parent
->constants
) return NULL
;
803 count
= parent
->desc
.Elements
> 1 ? parent
->desc
.Elements
: parent
->desc
.StructMembers
;
804 for (i
= 0; i
< count
; ++i
)
806 if (handle_from_constant(&parent
->constants
[i
]) == handle
)
807 return &parent
->constants
[i
];
809 c
= is_valid_sub_constant(&parent
->constants
[i
], handle
);
816 static inline struct ctab_constant
*get_valid_constant(struct ID3DXConstantTableImpl
*table
, D3DXHANDLE handle
)
818 struct ctab_constant
*c
;
821 if (!handle
) return NULL
;
823 for (i
= 0; i
< table
->desc
.Constants
; ++i
)
825 if (handle_from_constant(&table
->constants
[i
]) == handle
)
826 return &table
->constants
[i
];
828 c
= is_valid_sub_constant(&table
->constants
[i
], handle
);
832 return get_constant_by_name(table
, NULL
, handle
);
835 /*** IUnknown methods ***/
836 static HRESULT WINAPI
ID3DXConstantTableImpl_QueryInterface(ID3DXConstantTable
*iface
, REFIID riid
, void **out
)
838 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
840 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
841 IsEqualGUID(riid
, &IID_ID3DXBuffer
) ||
842 IsEqualGUID(riid
, &IID_ID3DXConstantTable
))
844 ID3DXConstantTable_AddRef(iface
);
849 WARN("Interface %s not found.\n", debugstr_guid(riid
));
851 return E_NOINTERFACE
;
854 static ULONG WINAPI
ID3DXConstantTableImpl_AddRef(ID3DXConstantTable
*iface
)
856 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
858 TRACE("(%p)->(): AddRef from %d\n", This
, This
->ref
);
860 return InterlockedIncrement(&This
->ref
);
863 static ULONG WINAPI
ID3DXConstantTableImpl_Release(ID3DXConstantTable
*iface
)
865 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
866 ULONG ref
= InterlockedDecrement(&This
->ref
);
868 TRACE("(%p)->(): Release from %d\n", This
, ref
+ 1);
872 free_constant_table(This
);
873 HeapFree(GetProcessHeap(), 0, This
);
879 /*** ID3DXBuffer methods ***/
880 static void * WINAPI
ID3DXConstantTableImpl_GetBufferPointer(ID3DXConstantTable
*iface
)
882 struct ID3DXConstantTableImpl
*table
= impl_from_ID3DXConstantTable(iface
);
884 TRACE("iface %p.\n", iface
);
889 static DWORD WINAPI
ID3DXConstantTableImpl_GetBufferSize(ID3DXConstantTable
*iface
)
891 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
893 TRACE("(%p)->()\n", This
);
898 /*** ID3DXConstantTable methods ***/
899 static HRESULT WINAPI
ID3DXConstantTableImpl_GetDesc(ID3DXConstantTable
*iface
, D3DXCONSTANTTABLE_DESC
*desc
)
901 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
903 TRACE("(%p)->(%p)\n", This
, desc
);
906 return D3DERR_INVALIDCALL
;
913 static HRESULT WINAPI
ID3DXConstantTableImpl_GetConstantDesc(ID3DXConstantTable
*iface
, D3DXHANDLE constant
,
914 D3DXCONSTANT_DESC
*desc
, UINT
*count
)
916 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
917 struct ctab_constant
*c
= get_valid_constant(This
, constant
);
919 TRACE("(%p)->(%p, %p, %p)\n", This
, constant
, desc
, count
);
923 WARN("Invalid argument specified\n");
924 return D3DERR_INVALIDCALL
;
927 if (desc
) *desc
= c
->desc
;
928 if (count
) *count
= 1;
933 static UINT WINAPI
ID3DXConstantTableImpl_GetSamplerIndex(ID3DXConstantTable
*iface
, D3DXHANDLE constant
)
935 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
936 struct ctab_constant
*c
= get_valid_constant(This
, constant
);
938 TRACE("(%p)->(%p)\n", This
, constant
);
940 if (!c
|| c
->desc
.RegisterSet
!= D3DXRS_SAMPLER
)
942 WARN("Invalid argument specified\n");
946 TRACE("Returning RegisterIndex %u\n", c
->desc
.RegisterIndex
);
947 return c
->desc
.RegisterIndex
;
950 static D3DXHANDLE WINAPI
ID3DXConstantTableImpl_GetConstant(ID3DXConstantTable
*iface
, D3DXHANDLE constant
, UINT index
)
952 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
953 struct ctab_constant
*c
;
955 TRACE("(%p)->(%p, %d)\n", This
, constant
, index
);
959 c
= get_valid_constant(This
, constant
);
960 if (c
&& index
< c
->desc
.StructMembers
)
962 c
= &c
->constants
[index
];
963 TRACE("Returning constant %p\n", c
);
964 return handle_from_constant(c
);
969 if (index
< This
->desc
.Constants
)
971 c
= &This
->constants
[index
];
972 TRACE("Returning constant %p\n", c
);
973 return handle_from_constant(c
);
977 WARN("Index out of range\n");
981 static D3DXHANDLE WINAPI
ID3DXConstantTableImpl_GetConstantByName(ID3DXConstantTable
*iface
,
982 D3DXHANDLE constant
, const char *name
)
984 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
985 struct ctab_constant
*c
= get_valid_constant(This
, constant
);
987 TRACE("iface %p, constant %p, name %s.\n", iface
, constant
, debugstr_a(name
));
989 c
= get_constant_by_name(This
, c
, name
);
990 TRACE("Returning constant %p\n", c
);
992 return handle_from_constant(c
);
995 static D3DXHANDLE WINAPI
ID3DXConstantTableImpl_GetConstantElement(ID3DXConstantTable
*iface
, D3DXHANDLE constant
, UINT index
)
997 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
998 struct ctab_constant
*c
= get_valid_constant(This
, constant
);
1000 TRACE("(%p)->(%p, %d)\n", This
, constant
, index
);
1002 if (c
&& index
< c
->desc
.Elements
)
1004 if (c
->desc
.Elements
> 1) c
= &c
->constants
[index
];
1005 TRACE("Returning constant %p\n", c
);
1006 return handle_from_constant(c
);
1009 WARN("Invalid argument specified\n");
1013 static inline DWORD
get_index(const void **indata
, UINT index
, BOOL is_pointer
)
1019 return ((DWORD
**)indata
)[index
/ 16][index
% 16];
1021 return (*((DWORD
**)indata
))[index
];
1024 static UINT
set(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
, struct ctab_constant
*constant
,
1025 const void **indata
, D3DXPARAMETER_TYPE intype
, UINT
*size
, UINT incol
, D3DXPARAMETER_CLASS inclass
, UINT index
,
1028 D3DXCONSTANT_DESC
*desc
= &constant
->desc
;
1029 UINT l
, i
, regcount
= 1, regsize
= 1, cin
= 1, rin
= 1, ret
, last
= 0;
1032 /* size too small to set anything */
1033 if (*size
< desc
->Rows
* desc
->Columns
)
1039 /* D3DXPC_STRUCT is somewhat special */
1040 if (desc
->Class
== D3DXPC_STRUCT
)
1043 * Struct array sets the last complete input to the first struct element, all other
1044 * elements are not set.
1045 * E.g.: struct {int i;} s1[2];
1046 * SetValue(device, "s1", [1, 2], 8) => s1 = {2, x};
1048 * struct {int i; int n} s2[2];
1049 * SetValue(device, "s2", [1, 2, 3, 4, 5], 20) => s1 = {{3, 4}, {x, x}};
1051 if (desc
->Elements
> 1)
1053 UINT offset
= *size
/ (desc
->Rows
* desc
->Columns
) - 1;
1055 offset
= min(desc
->Elements
- 1, offset
);
1056 last
= offset
* desc
->Rows
* desc
->Columns
;
1058 if ((is_pointer
|| (!is_pointer
&& inclass
== D3DXPC_MATRIX_ROWS
)) && desc
->RegisterSet
!= D3DXRS_BOOL
)
1060 set(table
, device
, &constant
->constants
[0], NULL
, intype
, size
, incol
, inclass
, 0, is_pointer
);
1064 last
+= set(table
, device
, &constant
->constants
[0], indata
, intype
, size
, incol
, inclass
,
1065 index
+ last
, is_pointer
);
1071 * D3DXRS_BOOL is always set. As there are only 16 bools and there are
1072 * exactly 16 input values, use matrix transpose.
1074 if (inclass
== D3DXPC_MATRIX_ROWS
&& desc
->RegisterSet
== D3DXRS_BOOL
)
1076 D3DXMATRIX mat
, *m
, min
;
1077 D3DXMatrixTranspose(&mat
, &min
);
1080 min
= *(D3DXMATRIX
*)(indata
[index
/ 16]);
1082 min
= **(D3DXMATRIX
**)indata
;
1084 D3DXMatrixTranspose(&mat
, &min
);
1086 for (i
= 0; i
< desc
->StructMembers
; ++i
)
1088 last
+= set(table
, device
, &constant
->constants
[i
], (const void **)&m
, intype
, size
, incol
,
1089 D3DXPC_SCALAR
, index
+ last
, is_pointer
);
1093 * For pointers or for matrix rows, only the first member is set.
1094 * All other members are set to 0. This is not true for D3DXRS_BOOL.
1095 * E.g.: struct {int i; int n} s;
1096 * SetValue(device, "s", [1, 2], 8) => s = {1, 0};
1098 else if ((is_pointer
|| (!is_pointer
&& inclass
== D3DXPC_MATRIX_ROWS
)) && desc
->RegisterSet
!= D3DXRS_BOOL
)
1100 last
= set(table
, device
, &constant
->constants
[0], indata
, intype
, size
, incol
, inclass
,
1101 index
+ last
, is_pointer
);
1103 for (i
= 1; i
< desc
->StructMembers
; ++i
)
1105 set(table
, device
, &constant
->constants
[i
], NULL
, intype
, size
, incol
, inclass
, 0, is_pointer
);
1110 for (i
= 0; i
< desc
->StructMembers
; ++i
)
1112 last
+= set(table
, device
, &constant
->constants
[i
], indata
, intype
, size
, incol
, D3DXPC_SCALAR
,
1113 index
+ last
, is_pointer
);
1122 if (desc
->Elements
> 1)
1124 for (i
= 0; i
< desc
->Elements
&& *size
> 0; ++i
)
1126 last
+= set(table
, device
, &constant
->constants
[i
], indata
, intype
, size
, incol
, inclass
,
1127 index
+ last
, is_pointer
);
1129 /* adjust the vector size for matrix rows */
1130 if (inclass
== D3DXPC_MATRIX_ROWS
&& desc
->Class
== D3DXPC_VECTOR
&& (i
% 4) == 3)
1133 *size
= *size
< 12 ? 0 : *size
- 12;
1140 switch (desc
->Class
)
1144 case D3DXPC_MATRIX_ROWS
:
1145 regcount
= min(desc
->RegisterCount
, desc
->Rows
);
1146 if (inclass
== D3DXPC_MATRIX_ROWS
) cin
= incol
;
1148 regsize
= desc
->Columns
;
1151 case D3DXPC_MATRIX_COLUMNS
:
1152 regcount
= min(desc
->RegisterCount
, desc
->Columns
);
1153 if (inclass
== D3DXPC_MATRIX_ROWS
) rin
= incol
;
1155 regsize
= desc
->Rows
;
1159 FIXME("Unhandled variable class %s\n", debug_d3dxparameter_class(desc
->Class
));
1163 /* specific stuff for different in types */
1167 ret
= desc
->Columns
* desc
->Rows
;
1168 *size
-= desc
->Columns
* desc
->Rows
;
1172 switch (desc
->Class
)
1174 case D3DXPC_MATRIX_ROWS
:
1175 if (*size
< regcount
* 4)
1181 *size
-= 4 * regcount
;
1184 case D3DXPC_MATRIX_COLUMNS
:
1186 *size
-= 4 * regcount
;
1200 FIXME("Unhandled variable class %s\n", debug_d3dxparameter_class(desc
->Class
));
1205 case D3DXPC_MATRIX_ROWS
:
1206 switch (desc
->Class
)
1208 case D3DXPC_MATRIX_ROWS
:
1209 case D3DXPC_MATRIX_COLUMNS
:
1227 FIXME("Unhandled variable class %s\n", debug_d3dxparameter_class(desc
->Class
));
1233 case D3DXPC_MATRIX_COLUMNS
:
1234 switch (desc
->Class
)
1236 case D3DXPC_MATRIX_ROWS
:
1237 case D3DXPC_MATRIX_COLUMNS
:
1255 FIXME("Unhandled variable class %s\n", debug_d3dxparameter_class(desc
->Class
));
1262 FIXME("Unhandled variable class %s\n", debug_d3dxparameter_class(inclass
));
1266 /* set the registers */
1267 switch (desc
->RegisterSet
)
1270 regcount
= min(desc
->RegisterCount
, desc
->Columns
* desc
->Rows
);
1272 for (i
= 0; i
< regcount
; ++i
)
1275 DWORD t
= get_index(indata
, index
+ i
/ regsize
* rin
+ l
* cin
, is_pointer
);
1277 set_number(&tmp
, desc
->Type
, &t
, intype
);
1278 set_number(&out
, D3DXPT_BOOL
, &tmp
, desc
->Type
);
1279 if (is_vertex_shader(table
->desc
.Version
))
1280 IDirect3DDevice9_SetVertexShaderConstantB(device
, desc
->RegisterIndex
+ i
, &out
, 1);
1282 IDirect3DDevice9_SetPixelShaderConstantB(device
, desc
->RegisterIndex
+ i
, &out
, 1);
1284 if (++l
>= regsize
) l
= 0;
1289 for (i
= 0; i
< regcount
; ++i
)
1291 INT vec
[4] = {0, 0, 1, 0};
1293 for (l
= 0; l
< regsize
; ++l
)
1295 DWORD t
= get_index(indata
, index
+ i
* rin
+ l
* cin
, is_pointer
);
1297 set_number(&tmp
, desc
->Type
, &t
, intype
);
1298 set_number(&vec
[l
], D3DXPT_INT
, &tmp
, desc
->Type
);
1300 if (is_vertex_shader(table
->desc
.Version
))
1301 IDirect3DDevice9_SetVertexShaderConstantI(device
, desc
->RegisterIndex
+ i
, vec
, 1);
1303 IDirect3DDevice9_SetPixelShaderConstantI(device
, desc
->RegisterIndex
+ i
, vec
, 1);
1308 for (i
= 0; i
< regcount
; ++i
)
1312 for (l
= 0; l
< regsize
; ++l
)
1314 DWORD t
= get_index(indata
, index
+ i
* rin
+ l
* cin
, is_pointer
);
1316 set_number(&tmp
, desc
->Type
, &t
, intype
);
1317 set_number(&vec
[l
], D3DXPT_FLOAT
, &tmp
, desc
->Type
);
1319 if (is_vertex_shader(table
->desc
.Version
))
1320 IDirect3DDevice9_SetVertexShaderConstantF(device
, desc
->RegisterIndex
+ i
, vec
, 1);
1322 IDirect3DDevice9_SetPixelShaderConstantF(device
, desc
->RegisterIndex
+ i
, vec
, 1);
1327 FIXME("Unhandled register set %s\n", debug_d3dxparameter_registerset(desc
->RegisterSet
));
1332 static HRESULT
set_scalar(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
, D3DXHANDLE constant
,
1333 const void *indata
, D3DXPARAMETER_TYPE intype
)
1335 struct ctab_constant
*c
= get_valid_constant(table
, constant
);
1340 WARN("Invalid argument specified\n");
1341 return D3DERR_INVALIDCALL
;
1344 switch (c
->desc
.Class
)
1347 set(table
, device
, c
, &indata
, intype
, &count
, c
->desc
.Columns
, D3DXPC_SCALAR
, 0, FALSE
);
1351 case D3DXPC_MATRIX_ROWS
:
1352 case D3DXPC_MATRIX_COLUMNS
:
1357 FIXME("Unhandled parameter class %s\n", debug_d3dxparameter_class(c
->desc
.Class
));
1358 return D3DERR_INVALIDCALL
;
1362 static HRESULT
set_scalar_array(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
, D3DXHANDLE constant
,
1363 const void *indata
, UINT count
, D3DXPARAMETER_TYPE intype
)
1365 struct ctab_constant
*c
= get_valid_constant(table
, constant
);
1369 WARN("Invalid argument specified\n");
1370 return D3DERR_INVALIDCALL
;
1373 switch (c
->desc
.Class
)
1377 case D3DXPC_MATRIX_ROWS
:
1378 case D3DXPC_MATRIX_COLUMNS
:
1380 set(table
, device
, c
, &indata
, intype
, &count
, c
->desc
.Columns
, D3DXPC_SCALAR
, 0, FALSE
);
1384 FIXME("Unhandled parameter class %s\n", debug_d3dxparameter_class(c
->desc
.Class
));
1385 return D3DERR_INVALIDCALL
;
1389 static HRESULT
set_vector(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
, D3DXHANDLE constant
,
1390 const void *indata
, D3DXPARAMETER_TYPE intype
)
1392 struct ctab_constant
*c
= get_valid_constant(table
, constant
);
1397 WARN("Invalid argument specified\n");
1398 return D3DERR_INVALIDCALL
;
1401 switch (c
->desc
.Class
)
1406 set(table
, device
, c
, &indata
, intype
, &count
, 4, D3DXPC_VECTOR
, 0, FALSE
);
1409 case D3DXPC_MATRIX_ROWS
:
1410 case D3DXPC_MATRIX_COLUMNS
:
1414 FIXME("Unhandled parameter class %s\n", debug_d3dxparameter_class(c
->desc
.Class
));
1415 return D3DERR_INVALIDCALL
;
1419 static HRESULT
set_vector_array(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
, D3DXHANDLE constant
,
1420 const void *indata
, UINT count
, D3DXPARAMETER_TYPE intype
)
1422 struct ctab_constant
*c
= get_valid_constant(table
, constant
);
1426 WARN("Invalid argument specified\n");
1427 return D3DERR_INVALIDCALL
;
1430 switch (c
->desc
.Class
)
1434 case D3DXPC_MATRIX_ROWS
:
1435 case D3DXPC_MATRIX_COLUMNS
:
1438 set(table
, device
, c
, &indata
, intype
, &count
, 4, D3DXPC_VECTOR
, 0, FALSE
);
1442 FIXME("Unhandled parameter class %s\n", debug_d3dxparameter_class(c
->desc
.Class
));
1443 return D3DERR_INVALIDCALL
;
1447 static HRESULT
set_matrix_array(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
, D3DXHANDLE constant
,
1448 const void *indata
, UINT count
, BOOL transpose
)
1450 struct ctab_constant
*c
= get_valid_constant(table
, constant
);
1454 WARN("Invalid argument specified\n");
1455 return D3DERR_INVALIDCALL
;
1458 switch (c
->desc
.Class
)
1462 case D3DXPC_MATRIX_ROWS
:
1463 case D3DXPC_MATRIX_COLUMNS
:
1466 set(table
, device
, c
, &indata
, D3DXPT_FLOAT
, &count
, 4,
1467 transpose
? D3DXPC_MATRIX_ROWS
: D3DXPC_MATRIX_COLUMNS
, 0, FALSE
);
1471 FIXME("Unhandled parameter class %s\n", debug_d3dxparameter_class(c
->desc
.Class
));
1472 return D3DERR_INVALIDCALL
;
1476 static HRESULT
set_matrix_pointer_array(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
,
1477 D3DXHANDLE constant
, const void **indata
, UINT count
, BOOL transpose
)
1479 struct ctab_constant
*c
= get_valid_constant(table
, constant
);
1483 WARN("Invalid argument specified\n");
1484 return D3DERR_INVALIDCALL
;
1487 switch (c
->desc
.Class
)
1491 case D3DXPC_MATRIX_ROWS
:
1492 case D3DXPC_MATRIX_COLUMNS
:
1495 set(table
, device
, c
, indata
, D3DXPT_FLOAT
, &count
, 4,
1496 transpose
? D3DXPC_MATRIX_ROWS
: D3DXPC_MATRIX_COLUMNS
, 0, TRUE
);
1500 FIXME("Unhandled parameter class %s\n", debug_d3dxparameter_class(c
->desc
.Class
));
1501 return D3DERR_INVALIDCALL
;
1505 static HRESULT WINAPI
ID3DXConstantTableImpl_SetDefaults(struct ID3DXConstantTable
*iface
,
1506 struct IDirect3DDevice9
*device
)
1508 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1511 TRACE("iface %p, device %p\n", iface
, device
);
1515 WARN("Invalid argument specified\n");
1516 return D3DERR_INVALIDCALL
;
1519 for (i
= 0; i
< This
->desc
.Constants
; i
++)
1521 D3DXCONSTANT_DESC
*desc
= &This
->constants
[i
].desc
;
1524 if (!desc
->DefaultValue
)
1527 switch (desc
->RegisterSet
)
1530 if (is_vertex_shader(This
->desc
.Version
))
1531 hr
= IDirect3DDevice9_SetVertexShaderConstantB(device
, desc
->RegisterIndex
, desc
->DefaultValue
,
1532 desc
->RegisterCount
);
1534 hr
= IDirect3DDevice9_SetPixelShaderConstantB(device
, desc
->RegisterIndex
, desc
->DefaultValue
,
1535 desc
->RegisterCount
);
1539 if (is_vertex_shader(This
->desc
.Version
))
1540 hr
= IDirect3DDevice9_SetVertexShaderConstantI(device
, desc
->RegisterIndex
, desc
->DefaultValue
,
1541 desc
->RegisterCount
);
1543 hr
= IDirect3DDevice9_SetPixelShaderConstantI(device
, desc
->RegisterIndex
, desc
->DefaultValue
,
1544 desc
->RegisterCount
);
1548 if (is_vertex_shader(This
->desc
.Version
))
1549 hr
= IDirect3DDevice9_SetVertexShaderConstantF(device
, desc
->RegisterIndex
, desc
->DefaultValue
,
1550 desc
->RegisterCount
);
1552 hr
= IDirect3DDevice9_SetPixelShaderConstantF(device
, desc
->RegisterIndex
, desc
->DefaultValue
,
1553 desc
->RegisterCount
);
1557 FIXME("Unhandled register set %s\n", debug_d3dxparameter_registerset(desc
->RegisterSet
));
1569 static HRESULT WINAPI
ID3DXConstantTableImpl_SetValue(struct ID3DXConstantTable
*iface
,
1570 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const void *data
, unsigned int bytes
)
1572 struct ID3DXConstantTableImpl
*table
= impl_from_ID3DXConstantTable(iface
);
1573 struct ctab_constant
*c
= get_valid_constant(table
, constant
);
1574 D3DXCONSTANT_DESC
*desc
;
1576 TRACE("iface %p, device %p, constant %p, data %p, bytes %u\n", iface
, device
, constant
, data
, bytes
);
1578 if (!device
|| !c
|| !data
)
1580 WARN("Invalid argument specified\n");
1581 return D3DERR_INVALIDCALL
;
1586 switch (desc
->Class
)
1590 case D3DXPC_MATRIX_ROWS
:
1591 case D3DXPC_MATRIX_COLUMNS
:
1594 set(table
, device
, c
, &data
, desc
->Type
, &bytes
, desc
->Columns
, D3DXPC_SCALAR
, 0, FALSE
);
1598 FIXME("Unhandled parameter class %s\n", debug_d3dxparameter_class(desc
->Class
));
1599 return D3DERR_INVALIDCALL
;
1603 static HRESULT WINAPI
ID3DXConstantTableImpl_SetBool(struct ID3DXConstantTable
*iface
,
1604 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, BOOL b
)
1606 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1608 TRACE("iface %p, device %p, constant %p, b %d\n", iface
, device
, constant
, b
);
1610 return set_scalar(This
, device
, constant
, &b
, D3DXPT_BOOL
);
1613 static HRESULT WINAPI
ID3DXConstantTableImpl_SetBoolArray(struct ID3DXConstantTable
*iface
,
1614 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const BOOL
*b
, UINT count
)
1616 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1618 TRACE("iface %p, device %p, constant %p, b %p, count %d\n", iface
, device
, constant
, b
, count
);
1620 return set_scalar_array(This
, device
, constant
, b
, count
, D3DXPT_BOOL
);
1623 static HRESULT WINAPI
ID3DXConstantTableImpl_SetInt(struct ID3DXConstantTable
*iface
,
1624 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, INT n
)
1626 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1628 TRACE("iface %p, device %p, constant %p, n %d\n", iface
, device
, constant
, n
);
1630 return set_scalar(This
, device
, constant
, &n
, D3DXPT_INT
);
1633 static HRESULT WINAPI
ID3DXConstantTableImpl_SetIntArray(struct ID3DXConstantTable
*iface
,
1634 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const INT
*n
, UINT count
)
1636 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1638 TRACE("iface %p, device %p, constant %p, n %p, count %d\n", iface
, device
, constant
, n
, count
);
1640 return set_scalar_array(This
, device
, constant
, n
, count
, D3DXPT_INT
);
1643 static HRESULT WINAPI
ID3DXConstantTableImpl_SetFloat(struct ID3DXConstantTable
*iface
,
1644 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, float f
)
1646 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1648 TRACE("iface %p, device %p, constant %p, f %f\n", iface
, device
, constant
, f
);
1650 return set_scalar(This
, device
, constant
, &f
, D3DXPT_FLOAT
);
1653 static HRESULT WINAPI
ID3DXConstantTableImpl_SetFloatArray(struct ID3DXConstantTable
*iface
,
1654 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const float *f
, UINT count
)
1656 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1658 TRACE("iface %p, device %p, constant %p, f %p, count %d\n", iface
, device
, constant
, f
, count
);
1660 return set_scalar_array(This
, device
, constant
, f
, count
, D3DXPT_FLOAT
);
1663 static HRESULT WINAPI
ID3DXConstantTableImpl_SetVector(struct ID3DXConstantTable
*iface
,
1664 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXVECTOR4
*vector
)
1666 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1668 TRACE("iface %p, device %p, constant %p, vector %p\n", iface
, device
, constant
, vector
);
1670 return set_vector(This
, device
, constant
, vector
, D3DXPT_FLOAT
);
1673 static HRESULT WINAPI
ID3DXConstantTableImpl_SetVectorArray(struct ID3DXConstantTable
*iface
,
1674 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXVECTOR4
*vector
, UINT count
)
1676 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1678 TRACE("iface %p, device %p, constant %p, vector %p, count %u\n", iface
, device
, constant
, vector
, count
);
1680 return set_vector_array(This
, device
, constant
, vector
, count
, D3DXPT_FLOAT
);
1683 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrix(struct ID3DXConstantTable
*iface
,
1684 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXMATRIX
*matrix
)
1686 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1688 TRACE("iface %p, device %p, constant %p, matrix %p\n", iface
, device
, constant
, matrix
);
1690 return set_matrix_array(This
, device
, constant
, matrix
, 1, FALSE
);
1693 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrixArray(struct ID3DXConstantTable
*iface
,
1694 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXMATRIX
*matrix
, UINT count
)
1696 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1698 TRACE("iface %p, device %p, constant %p, matrix %p, count %u\n", iface
, device
, constant
, matrix
, count
);
1700 return set_matrix_array(This
, device
, constant
, matrix
, count
, FALSE
);
1703 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrixPointerArray(struct ID3DXConstantTable
*iface
,
1704 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXMATRIX
**matrix
, UINT count
)
1706 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1708 TRACE("iface %p, device %p, constant %p, matrix %p, count %u)\n", iface
, device
, constant
, matrix
, count
);
1710 return set_matrix_pointer_array(This
, device
, constant
, (const void **)matrix
, count
, FALSE
);
1713 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrixTranspose(struct ID3DXConstantTable
*iface
,
1714 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXMATRIX
*matrix
)
1716 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1718 TRACE("iface %p, device %p, constant %p, matrix %p\n", iface
, device
, constant
, matrix
);
1720 return set_matrix_array(This
, device
, constant
, matrix
, 1, TRUE
);
1723 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrixTransposeArray(struct ID3DXConstantTable
*iface
,
1724 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXMATRIX
*matrix
, UINT count
)
1726 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1728 TRACE("iface %p, device %p, constant %p, matrix %p, count %u\n", iface
, device
, constant
, matrix
, count
);
1730 return set_matrix_array(This
, device
, constant
, matrix
, count
, TRUE
);
1733 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrixTransposePointerArray(struct ID3DXConstantTable
*iface
,
1734 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXMATRIX
**matrix
, UINT count
)
1736 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1738 TRACE("iface %p, device %p, constant %p, matrix %p, count %u)\n", iface
, device
, constant
, matrix
, count
);
1740 return set_matrix_pointer_array(This
, device
, constant
, (const void **)matrix
, count
, TRUE
);
1743 static const struct ID3DXConstantTableVtbl ID3DXConstantTable_Vtbl
=
1745 /*** IUnknown methods ***/
1746 ID3DXConstantTableImpl_QueryInterface
,
1747 ID3DXConstantTableImpl_AddRef
,
1748 ID3DXConstantTableImpl_Release
,
1749 /*** ID3DXBuffer methods ***/
1750 ID3DXConstantTableImpl_GetBufferPointer
,
1751 ID3DXConstantTableImpl_GetBufferSize
,
1752 /*** ID3DXConstantTable methods ***/
1753 ID3DXConstantTableImpl_GetDesc
,
1754 ID3DXConstantTableImpl_GetConstantDesc
,
1755 ID3DXConstantTableImpl_GetSamplerIndex
,
1756 ID3DXConstantTableImpl_GetConstant
,
1757 ID3DXConstantTableImpl_GetConstantByName
,
1758 ID3DXConstantTableImpl_GetConstantElement
,
1759 ID3DXConstantTableImpl_SetDefaults
,
1760 ID3DXConstantTableImpl_SetValue
,
1761 ID3DXConstantTableImpl_SetBool
,
1762 ID3DXConstantTableImpl_SetBoolArray
,
1763 ID3DXConstantTableImpl_SetInt
,
1764 ID3DXConstantTableImpl_SetIntArray
,
1765 ID3DXConstantTableImpl_SetFloat
,
1766 ID3DXConstantTableImpl_SetFloatArray
,
1767 ID3DXConstantTableImpl_SetVector
,
1768 ID3DXConstantTableImpl_SetVectorArray
,
1769 ID3DXConstantTableImpl_SetMatrix
,
1770 ID3DXConstantTableImpl_SetMatrixArray
,
1771 ID3DXConstantTableImpl_SetMatrixPointerArray
,
1772 ID3DXConstantTableImpl_SetMatrixTranspose
,
1773 ID3DXConstantTableImpl_SetMatrixTransposeArray
,
1774 ID3DXConstantTableImpl_SetMatrixTransposePointerArray
1777 static HRESULT
parse_ctab_constant_type(const char *ctab
, DWORD typeoffset
, struct ctab_constant
*constant
,
1778 BOOL is_element
, WORD index
, WORD max_index
, DWORD
*offset
, DWORD nameoffset
, UINT regset
)
1780 const D3DXSHADER_TYPEINFO
*type
= (LPD3DXSHADER_TYPEINFO
)(ctab
+ typeoffset
);
1781 const D3DXSHADER_STRUCTMEMBERINFO
*memberinfo
= NULL
;
1782 HRESULT hr
= D3D_OK
;
1786 constant
->desc
.DefaultValue
= offset
? ctab
+ *offset
: NULL
;
1787 constant
->desc
.Class
= type
->Class
;
1788 constant
->desc
.Type
= type
->Type
;
1789 constant
->desc
.Rows
= type
->Rows
;
1790 constant
->desc
.Columns
= type
->Columns
;
1791 constant
->desc
.Elements
= is_element
? 1 : type
->Elements
;
1792 constant
->desc
.StructMembers
= type
->StructMembers
;
1793 constant
->desc
.Name
= ctab
+ nameoffset
;
1794 constant
->desc
.RegisterSet
= regset
;
1795 constant
->desc
.RegisterIndex
= index
;
1797 TRACE("name %s, elements %u, index %u, defaultvalue %p, regset %s\n", constant
->desc
.Name
,
1798 constant
->desc
.Elements
, index
, constant
->desc
.DefaultValue
,
1799 debug_d3dxparameter_registerset(regset
));
1800 TRACE("class %s, type %s, rows %d, columns %d, elements %d, struct_members %d\n",
1801 debug_d3dxparameter_class(type
->Class
), debug_d3dxparameter_type(type
->Type
),
1802 type
->Rows
, type
->Columns
, type
->Elements
, type
->StructMembers
);
1804 if (type
->Elements
> 1 && !is_element
)
1806 count
= type
->Elements
;
1808 else if ((type
->Class
== D3DXPC_STRUCT
) && type
->StructMembers
)
1810 memberinfo
= (D3DXSHADER_STRUCTMEMBERINFO
*)(ctab
+ type
->StructMemberInfo
);
1811 count
= type
->StructMembers
;
1816 constant
->constants
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*constant
->constants
) * count
);
1817 if (!constant
->constants
)
1819 ERR("Out of memory\n");
1824 for (i
= 0; i
< count
; ++i
)
1826 hr
= parse_ctab_constant_type(ctab
, memberinfo
? memberinfo
[i
].TypeInfo
: typeoffset
,
1827 &constant
->constants
[i
], memberinfo
== NULL
, index
+ size
, max_index
, offset
,
1828 memberinfo
? memberinfo
[i
].Name
: nameoffset
, regset
);
1832 size
+= constant
->constants
[i
].desc
.RegisterCount
;
1837 WORD offsetdiff
= type
->Columns
* type
->Rows
;
1840 size
= type
->Columns
* type
->Rows
;
1845 fail
= type
->Class
!= D3DXPC_SCALAR
&& type
->Class
!= D3DXPC_VECTOR
1846 && type
->Class
!= D3DXPC_MATRIX_ROWS
&& type
->Class
!= D3DXPC_MATRIX_COLUMNS
;
1851 switch (type
->Class
)
1857 offsetdiff
= type
->Rows
* 4;
1860 case D3DXPC_MATRIX_ROWS
:
1861 offsetdiff
= type
->Rows
* 4;
1865 case D3DXPC_MATRIX_COLUMNS
:
1866 offsetdiff
= type
->Columns
* 4;
1867 size
= type
->Columns
;
1876 case D3DXRS_SAMPLER
:
1878 fail
= type
->Class
!= D3DXPC_OBJECT
;
1888 FIXME("Unhandled register set %s, type class %s\n", debug_d3dxparameter_registerset(regset
),
1889 debug_d3dxparameter_class(type
->Class
));
1892 /* offset in bytes => offsetdiff * sizeof(DWORD) */
1893 if (offset
) *offset
+= offsetdiff
* 4;
1896 constant
->desc
.RegisterCount
= max(0, min(max_index
- index
, size
));
1897 constant
->desc
.Bytes
= 4 * constant
->desc
.Elements
* type
->Rows
* type
->Columns
;
1902 if (constant
->constants
)
1904 for (i
= 0; i
< count
; ++i
)
1906 free_constant(&constant
->constants
[i
]);
1908 HeapFree(GetProcessHeap(), 0, constant
->constants
);
1909 constant
->constants
= NULL
;
1915 HRESULT WINAPI
D3DXGetShaderConstantTableEx(const DWORD
*byte_code
, DWORD flags
, ID3DXConstantTable
**constant_table
)
1917 struct ID3DXConstantTableImpl
*object
= NULL
;
1921 const D3DXSHADER_CONSTANTTABLE
*ctab_header
;
1922 const D3DXSHADER_CONSTANTINFO
*constant_info
;
1925 TRACE("byte_code %p, flags %x, constant_table %p\n", byte_code
, flags
, constant_table
);
1927 if (constant_table
) *constant_table
= NULL
;
1929 if (!byte_code
|| !constant_table
)
1931 WARN("Invalid argument specified.\n");
1932 return D3DERR_INVALIDCALL
;
1935 if (!is_valid_bytecode(*byte_code
))
1937 WARN("Invalid byte_code specified.\n");
1941 if (flags
) FIXME("Flags (%#x) are not handled, yet!\n", flags
);
1943 hr
= D3DXFindShaderComment(byte_code
, MAKEFOURCC('C','T','A','B'), &data
, &size
);
1946 WARN("CTAB not found.\n");
1947 return D3DXERR_INVALIDDATA
;
1950 if (size
< sizeof(*ctab_header
))
1952 WARN("Invalid CTAB size.\n");
1953 return D3DXERR_INVALIDDATA
;
1956 ctab_header
= (const D3DXSHADER_CONSTANTTABLE
*)data
;
1957 if (ctab_header
->Size
!= sizeof(*ctab_header
))
1959 WARN("Invalid D3DXSHADER_CONSTANTTABLE size.\n");
1960 return D3DXERR_INVALIDDATA
;
1963 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*object
));
1965 return E_OUTOFMEMORY
;
1967 object
->ID3DXConstantTable_iface
.lpVtbl
= &ID3DXConstantTable_Vtbl
;
1970 object
->ctab
= HeapAlloc(GetProcessHeap(), 0, size
);
1973 ERR("Out of memory\n");
1974 HeapFree(GetProcessHeap(), 0, object
);
1975 return E_OUTOFMEMORY
;
1977 object
->size
= size
;
1978 memcpy(object
->ctab
, data
, object
->size
);
1980 object
->desc
.Creator
= ctab_header
->Creator
? object
->ctab
+ ctab_header
->Creator
: NULL
;
1981 object
->desc
.Version
= ctab_header
->Version
;
1982 object
->desc
.Constants
= ctab_header
->Constants
;
1983 TRACE("Creator %s, Version %x, Constants %u, Target %s\n",
1984 debugstr_a(object
->desc
.Creator
), object
->desc
.Version
, object
->desc
.Constants
,
1985 debugstr_a(ctab_header
->Target
? object
->ctab
+ ctab_header
->Target
: NULL
));
1987 object
->constants
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
1988 sizeof(*object
->constants
) * object
->desc
.Constants
);
1989 if (!object
->constants
)
1991 ERR("Out of memory\n");
1996 constant_info
= (const D3DXSHADER_CONSTANTINFO
*)(object
->ctab
+ ctab_header
->ConstantInfo
);
1997 for (i
= 0; i
< ctab_header
->Constants
; i
++)
1999 DWORD offset
= constant_info
[i
].DefaultValue
;
2001 hr
= parse_ctab_constant_type(object
->ctab
, constant_info
[i
].TypeInfo
,
2002 &object
->constants
[i
], FALSE
, constant_info
[i
].RegisterIndex
,
2003 constant_info
[i
].RegisterIndex
+ constant_info
[i
].RegisterCount
,
2004 offset
? &offset
: NULL
, constant_info
[i
].Name
, constant_info
[i
].RegisterSet
);
2009 * Set the register count, it may differ for D3DXRS_INT4, because somehow
2010 * it makes the assumption that the register size is 1 instead of 4, so the
2011 * count is 4 times bigger. This holds true only for toplevel shader
2012 * constants. The count of elements and members is always based on a
2013 * register size of 4.
2015 if (object
->constants
[i
].desc
.RegisterSet
== D3DXRS_INT4
)
2017 object
->constants
[i
].desc
.RegisterCount
= constant_info
[i
].RegisterCount
;
2021 *constant_table
= &object
->ID3DXConstantTable_iface
;
2026 free_constant_table(object
);
2027 HeapFree(GetProcessHeap(), 0, object
);
2032 HRESULT WINAPI
D3DXGetShaderConstantTable(const DWORD
*byte_code
, ID3DXConstantTable
**constant_table
)
2034 TRACE("(%p, %p): Forwarded to D3DXGetShaderConstantTableEx\n", byte_code
, constant_table
);
2036 return D3DXGetShaderConstantTableEx(byte_code
, 0, constant_table
);
2039 HRESULT WINAPI
D3DXGetShaderSamplers(const DWORD
*byte_code
, const char **samplers
, UINT
*count
)
2041 UINT i
, sampler_count
= 0;
2044 const D3DXSHADER_CONSTANTTABLE
*ctab_header
;
2045 const D3DXSHADER_CONSTANTINFO
*constant_info
;
2047 TRACE("byte_code %p, samplers %p, count %p\n", byte_code
, samplers
, count
);
2049 if (count
) *count
= 0;
2051 if (D3DXFindShaderComment(byte_code
, MAKEFOURCC('C','T','A','B'), (const void **)&data
, &size
) != D3D_OK
)
2054 if (size
< sizeof(*ctab_header
)) return D3D_OK
;
2056 ctab_header
= (const D3DXSHADER_CONSTANTTABLE
*)data
;
2057 if (ctab_header
->Size
!= sizeof(*ctab_header
)) return D3D_OK
;
2059 constant_info
= (const D3DXSHADER_CONSTANTINFO
*)(data
+ ctab_header
->ConstantInfo
);
2060 for (i
= 0; i
< ctab_header
->Constants
; i
++)
2062 const D3DXSHADER_TYPEINFO
*type
;
2064 TRACE("name = %s\n", data
+ constant_info
[i
].Name
);
2066 type
= (const D3DXSHADER_TYPEINFO
*)(data
+ constant_info
[i
].TypeInfo
);
2068 if (type
->Type
== D3DXPT_SAMPLER
2069 || type
->Type
== D3DXPT_SAMPLER1D
2070 || type
->Type
== D3DXPT_SAMPLER2D
2071 || type
->Type
== D3DXPT_SAMPLER3D
2072 || type
->Type
== D3DXPT_SAMPLERCUBE
)
2074 if (samplers
) samplers
[sampler_count
] = data
+ constant_info
[i
].Name
;
2080 TRACE("Found %u samplers\n", sampler_count
);
2082 if (count
) *count
= sampler_count
;