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 #include "wine/debug.h"
25 #include "wine/unicode.h"
29 #include "d3dcommon.h"
30 #include "d3dcompiler.h"
31 #include "d3dx9_36_private.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(d3dx
);
35 /* This function is not declared in the SDK headers yet. */
36 HRESULT WINAPI
D3DAssemble(const void *data
, SIZE_T datasize
, const char *filename
,
37 const D3D_SHADER_MACRO
*defines
, ID3DInclude
*include
, UINT flags
,
38 ID3DBlob
**shader
, ID3DBlob
**error_messages
);
40 static inline BOOL
is_valid_bytecode(DWORD token
)
42 return (token
& 0xfffe0000) == 0xfffe0000;
45 const char * WINAPI
D3DXGetPixelShaderProfile(struct IDirect3DDevice9
*device
)
49 TRACE("device %p\n", device
);
51 if (!device
) return NULL
;
53 IDirect3DDevice9_GetDeviceCaps(device
,&caps
);
55 switch (caps
.PixelShaderVersion
)
57 case D3DPS_VERSION(1, 1):
60 case D3DPS_VERSION(1, 2):
63 case D3DPS_VERSION(1, 3):
66 case D3DPS_VERSION(1, 4):
69 case D3DPS_VERSION(2, 0):
70 if ((caps
.PS20Caps
.NumTemps
>=22) &&
71 (caps
.PS20Caps
.Caps
&D3DPS20CAPS_ARBITRARYSWIZZLE
) &&
72 (caps
.PS20Caps
.Caps
&D3DPS20CAPS_GRADIENTINSTRUCTIONS
) &&
73 (caps
.PS20Caps
.Caps
&D3DPS20CAPS_PREDICATION
) &&
74 (caps
.PS20Caps
.Caps
&D3DPS20CAPS_NODEPENDENTREADLIMIT
) &&
75 (caps
.PS20Caps
.Caps
&D3DPS20CAPS_NOTEXINSTRUCTIONLIMIT
))
79 if ((caps
.PS20Caps
.NumTemps
>=32) &&
80 (caps
.PS20Caps
.Caps
&D3DPS20CAPS_NOTEXINSTRUCTIONLIMIT
))
86 case D3DPS_VERSION(3, 0):
93 UINT WINAPI
D3DXGetShaderSize(const DWORD
*byte_code
)
95 const DWORD
*ptr
= byte_code
;
97 TRACE("byte_code %p\n", byte_code
);
101 /* Look for the END token, skipping the VERSION token */
102 while (*++ptr
!= D3DSIO_END
)
105 if ((*ptr
& D3DSI_OPCODE_MASK
) == D3DSIO_COMMENT
)
107 ptr
+= ((*ptr
& D3DSI_COMMENTSIZE_MASK
) >> D3DSI_COMMENTSIZE_SHIFT
);
112 /* Return the shader size in bytes */
113 return (ptr
- byte_code
) * sizeof(*ptr
);
116 DWORD WINAPI
D3DXGetShaderVersion(const DWORD
*byte_code
)
118 TRACE("byte_code %p\n", byte_code
);
120 return byte_code
? *byte_code
: 0;
123 const char * WINAPI
D3DXGetVertexShaderProfile(struct IDirect3DDevice9
*device
)
127 TRACE("device %p\n", device
);
129 if (!device
) return NULL
;
131 IDirect3DDevice9_GetDeviceCaps(device
,&caps
);
133 switch (caps
.VertexShaderVersion
)
135 case D3DVS_VERSION(1, 1):
137 case D3DVS_VERSION(2, 0):
138 if ((caps
.VS20Caps
.NumTemps
>=13) &&
139 (caps
.VS20Caps
.DynamicFlowControlDepth
==24) &&
140 (caps
.VS20Caps
.Caps
&D3DPS20CAPS_PREDICATION
))
145 case D3DVS_VERSION(3, 0):
152 HRESULT WINAPI
D3DXFindShaderComment(const DWORD
*byte_code
, DWORD fourcc
, const void **data
, UINT
*size
)
154 const DWORD
*ptr
= byte_code
;
157 TRACE("byte_code %p, fourcc %x, data %p, size %p\n", byte_code
, fourcc
, data
, size
);
159 if (data
) *data
= NULL
;
162 if (!byte_code
) return D3DERR_INVALIDCALL
;
164 version
= *ptr
>> 16;
165 if (version
!= 0x4658 /* FX */
166 && version
!= 0x5458 /* TX */
169 && version
!= 0xfffe /* VS */
170 && version
!= 0xffff) /* PS */
172 WARN("Invalid data supplied\n");
173 return D3DXERR_INVALIDDATA
;
176 while (*++ptr
!= D3DSIO_END
)
178 /* Check if it is a comment */
179 if ((*ptr
& D3DSI_OPCODE_MASK
) == D3DSIO_COMMENT
)
181 DWORD comment_size
= (*ptr
& D3DSI_COMMENTSIZE_MASK
) >> D3DSI_COMMENTSIZE_SHIFT
;
183 /* Check if this is the comment we are looking for */
184 if (*(ptr
+ 1) == fourcc
)
186 UINT ctab_size
= (comment_size
- 1) * sizeof(DWORD
);
187 const void *ctab_data
= ptr
+ 2;
192 TRACE("Returning comment data at %p with size %d\n", ctab_data
, ctab_size
);
202 HRESULT WINAPI
D3DXAssembleShader(const char *data
, UINT data_len
, const D3DXMACRO
*defines
,
203 ID3DXInclude
*include
, DWORD flags
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
207 TRACE("data %p, data_len %u, defines %p, include %p, flags %#x, shader %p, error_messages %p\n",
208 data
, data_len
, defines
, include
, flags
, shader
, error_messages
);
210 /* Forward to d3dcompiler: the parameter types aren't really different,
211 the actual data types are equivalent */
212 hr
= D3DAssemble(data
, data_len
, NULL
, (D3D_SHADER_MACRO
*)defines
,
213 (ID3DInclude
*)include
, flags
, (ID3DBlob
**)shader
,
214 (ID3DBlob
**)error_messages
);
216 if(hr
== E_FAIL
) hr
= D3DXERR_INVALIDDATA
;
220 static const void *main_file_data
;
222 static CRITICAL_SECTION from_file_mutex
;
223 static CRITICAL_SECTION_DEBUG from_file_mutex_debug
=
225 0, 0, &from_file_mutex
,
227 &from_file_mutex_debug
.ProcessLocksList
,
228 &from_file_mutex_debug
.ProcessLocksList
230 0, 0, {(DWORD_PTR
)(__FILE__
": from_file_mutex")}
232 static CRITICAL_SECTION from_file_mutex
= {&from_file_mutex_debug
, -1, 0, 0, 0, 0};
234 /* D3DXInclude private implementation, used to implement
235 * D3DXAssembleShaderFromFile() from D3DXAssembleShader(). */
236 /* To be able to correctly resolve include search paths we have to store the
237 * pathname of each include file. We store the pathname pointer right before
239 static HRESULT WINAPI
d3dincludefromfile_open(ID3DXInclude
*iface
, D3DXINCLUDE_TYPE include_type
,
240 const char *filename
, const void *parent_data
, const void **data
, UINT
*bytes
)
242 const char *p
, *parent_name
= "";
243 char *pathname
= NULL
, *ptr
;
244 char **buffer
= NULL
;
250 parent_name
= *((const char **)parent_data
- 1);
255 parent_name
= *((const char **)main_file_data
- 1);
258 TRACE("Looking up for include file %s, parent %s\n", debugstr_a(filename
), debugstr_a(parent_name
));
260 if ((p
= strrchr(parent_name
, '\\')))
264 pathname
= HeapAlloc(GetProcessHeap(), 0, (p
- parent_name
) + strlen(filename
) + 1);
266 return HRESULT_FROM_WIN32(GetLastError());
268 memcpy(pathname
, parent_name
, p
- parent_name
);
269 strcpy(pathname
+ (p
- parent_name
), filename
);
270 ptr
= pathname
+ (p
- parent_name
);
278 file
= CreateFileA(pathname
, GENERIC_READ
, FILE_SHARE_READ
, 0, OPEN_EXISTING
, 0, 0);
279 if(file
== INVALID_HANDLE_VALUE
)
282 TRACE("Include file found at pathname = %s\n", debugstr_a(pathname
));
284 size
= GetFileSize(file
, NULL
);
285 if(size
== INVALID_FILE_SIZE
)
288 buffer
= HeapAlloc(GetProcessHeap(), 0, size
+ sizeof(char *));
292 if(!ReadFile(file
, buffer
+ 1, size
, bytes
, NULL
))
297 main_file_data
= *data
;
304 HeapFree(GetProcessHeap(), 0, pathname
);
305 HeapFree(GetProcessHeap(), 0, buffer
);
306 return HRESULT_FROM_WIN32(GetLastError());
309 static HRESULT WINAPI
d3dincludefromfile_close(ID3DXInclude
*iface
, const void *data
)
311 HeapFree(GetProcessHeap(), 0, *((char **)data
- 1));
312 HeapFree(GetProcessHeap(), 0, (char **)data
- 1);
313 if (main_file_data
== data
)
314 main_file_data
= NULL
;
318 static const struct ID3DXIncludeVtbl D3DXInclude_Vtbl
= {
319 d3dincludefromfile_open
,
320 d3dincludefromfile_close
323 struct D3DXIncludeImpl
{
324 ID3DXInclude ID3DXInclude_iface
;
327 HRESULT WINAPI
D3DXAssembleShaderFromFileA(const char *filename
, const D3DXMACRO
*defines
,
328 ID3DXInclude
*include
, DWORD flags
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
334 TRACE("filename %s, defines %p, include %p, flags %#x, shader %p, error_messages %p.\n",
335 debugstr_a(filename
), defines
, include
, flags
, shader
, error_messages
);
337 if (!filename
) return D3DXERR_INVALIDDATA
;
339 len
= MultiByteToWideChar(CP_ACP
, 0, filename
, -1, NULL
, 0);
340 filename_w
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
341 if (!filename_w
) return E_OUTOFMEMORY
;
342 MultiByteToWideChar(CP_ACP
, 0, filename
, -1, filename_w
, len
);
344 ret
= D3DXAssembleShaderFromFileW(filename_w
, defines
, include
, flags
, shader
, error_messages
);
346 HeapFree(GetProcessHeap(), 0, filename_w
);
350 HRESULT WINAPI
D3DXAssembleShaderFromFileW(const WCHAR
*filename
, const D3DXMACRO
*defines
,
351 ID3DXInclude
*include
, DWORD flags
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
356 struct D3DXIncludeImpl includefromfile
;
359 TRACE("filename %s, defines %p, include %p, flags %#x, shader %p, error_messages %p.\n",
360 debugstr_w(filename
), defines
, include
, flags
, shader
, error_messages
);
364 includefromfile
.ID3DXInclude_iface
.lpVtbl
= &D3DXInclude_Vtbl
;
365 include
= &includefromfile
.ID3DXInclude_iface
;
368 len
= WideCharToMultiByte(CP_ACP
, 0, filename
, -1, NULL
, 0, NULL
, NULL
);
369 filename_a
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(char));
371 return E_OUTOFMEMORY
;
372 WideCharToMultiByte(CP_ACP
, 0, filename
, -1, filename_a
, len
, NULL
, NULL
);
374 EnterCriticalSection(&from_file_mutex
);
375 hr
= ID3DXInclude_Open(include
, D3D_INCLUDE_LOCAL
, filename_a
, NULL
, &buffer
, &len
);
378 LeaveCriticalSection(&from_file_mutex
);
379 HeapFree(GetProcessHeap(), 0, filename_a
);
380 return D3DXERR_INVALIDDATA
;
383 hr
= D3DXAssembleShader(buffer
, len
, defines
, include
, flags
, shader
, error_messages
);
385 ID3DXInclude_Close(include
, buffer
);
386 LeaveCriticalSection(&from_file_mutex
);
387 HeapFree(GetProcessHeap(), 0, filename_a
);
391 HRESULT WINAPI
D3DXAssembleShaderFromResourceA(HMODULE module
, const char *resource
, const D3DXMACRO
*defines
,
392 ID3DXInclude
*include
, DWORD flags
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
398 TRACE("module %p, resource %s, defines %p, include %p, flags %#x, shader %p, error_messages %p.\n",
399 module
, debugstr_a(resource
), defines
, include
, flags
, shader
, error_messages
);
401 if (!(res
= FindResourceA(module
, resource
, (const char *)RT_RCDATA
)))
402 return D3DXERR_INVALIDDATA
;
403 if (FAILED(load_resource_into_memory(module
, res
, &buffer
, &len
)))
404 return D3DXERR_INVALIDDATA
;
405 return D3DXAssembleShader(buffer
, len
, defines
, include
, flags
,
406 shader
, error_messages
);
409 HRESULT WINAPI
D3DXAssembleShaderFromResourceW(HMODULE module
, const WCHAR
*resource
, const D3DXMACRO
*defines
,
410 ID3DXInclude
*include
, DWORD flags
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
416 TRACE("module %p, resource %s, defines %p, include %p, flags %#x, shader %p, error_messages %p.\n",
417 module
, debugstr_w(resource
), defines
, include
, flags
, shader
, error_messages
);
419 if (!(res
= FindResourceW(module
, resource
, (const WCHAR
*)RT_RCDATA
)))
420 return D3DXERR_INVALIDDATA
;
421 if (FAILED(load_resource_into_memory(module
, res
, &buffer
, &len
)))
422 return D3DXERR_INVALIDDATA
;
423 return D3DXAssembleShader(buffer
, len
, defines
, include
, flags
,
424 shader
, error_messages
);
427 HRESULT WINAPI
D3DXCompileShader(const char *data
, UINT length
, const D3DXMACRO
*defines
,
428 ID3DXInclude
*include
, const char *function
, const char *profile
, DWORD flags
,
429 ID3DXBuffer
**shader
, ID3DXBuffer
**error_msgs
, ID3DXConstantTable
**constant_table
)
433 TRACE("data %s, length %u, defines %p, include %p, function %s, profile %s, "
434 "flags %#x, shader %p, error_msgs %p, constant_table %p.\n",
435 debugstr_a(data
), length
, defines
, include
, debugstr_a(function
), debugstr_a(profile
),
436 flags
, shader
, error_msgs
, constant_table
);
438 hr
= D3DCompile(data
, length
, NULL
, (D3D_SHADER_MACRO
*)defines
, (ID3DInclude
*)include
,
439 function
, profile
, flags
, 0, (ID3DBlob
**)shader
, (ID3DBlob
**)error_msgs
);
441 if (SUCCEEDED(hr
) && constant_table
)
443 hr
= D3DXGetShaderConstantTable(ID3DXBuffer_GetBufferPointer(*shader
), constant_table
);
446 ID3DXBuffer_Release(*shader
);
454 HRESULT WINAPI
D3DXCompileShaderFromFileA(const char *filename
, const D3DXMACRO
*defines
,
455 ID3DXInclude
*include
, const char *entrypoint
, const char *profile
, DWORD flags
,
456 ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
, ID3DXConstantTable
**constant_table
)
462 TRACE("filename %s, defines %p, include %p, entrypoint %s, profile %s, "
463 "flags %#x, shader %p, error_messages %p, constant_table %p.\n",
464 debugstr_a(filename
), defines
, include
, debugstr_a(entrypoint
),
465 debugstr_a(profile
), flags
, shader
, error_messages
, constant_table
);
467 if (!filename
) return D3DXERR_INVALIDDATA
;
469 len
= MultiByteToWideChar(CP_ACP
, 0, filename
, -1, NULL
, 0);
470 filename_w
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
471 if (!filename_w
) return E_OUTOFMEMORY
;
472 MultiByteToWideChar(CP_ACP
, 0, filename
, -1, filename_w
, len
);
474 ret
= D3DXCompileShaderFromFileW(filename_w
, defines
, include
,
475 entrypoint
, profile
, flags
,
476 shader
, error_messages
, constant_table
);
478 HeapFree(GetProcessHeap(), 0, filename_w
);
482 HRESULT WINAPI
D3DXCompileShaderFromFileW(const WCHAR
*filename
, const D3DXMACRO
*defines
,
483 ID3DXInclude
*include
, const char *entrypoint
, const char *profile
, DWORD flags
,
484 ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
, ID3DXConstantTable
**constant_table
)
487 DWORD len
, filename_len
;
489 struct D3DXIncludeImpl includefromfile
;
492 TRACE("filename %s, defines %p, include %p, entrypoint %s, profile %s, "
493 "flags %#x, shader %p, error_messages %p, constant_table %p.\n",
494 debugstr_w(filename
), defines
, include
, debugstr_a(entrypoint
), debugstr_a(profile
),
495 flags
, shader
, error_messages
, constant_table
);
499 includefromfile
.ID3DXInclude_iface
.lpVtbl
= &D3DXInclude_Vtbl
;
500 include
= &includefromfile
.ID3DXInclude_iface
;
503 filename_len
= WideCharToMultiByte(CP_ACP
, 0, filename
, -1, NULL
, 0, NULL
, NULL
);
504 filename_a
= HeapAlloc(GetProcessHeap(), 0, filename_len
* sizeof(char));
506 return E_OUTOFMEMORY
;
507 WideCharToMultiByte(CP_ACP
, 0, filename
, -1, filename_a
, filename_len
, NULL
, NULL
);
509 EnterCriticalSection(&from_file_mutex
);
510 hr
= ID3DXInclude_Open(include
, D3D_INCLUDE_LOCAL
, filename_a
, NULL
, &buffer
, &len
);
513 LeaveCriticalSection(&from_file_mutex
);
514 HeapFree(GetProcessHeap(), 0, filename_a
);
515 return D3DXERR_INVALIDDATA
;
518 hr
= D3DCompile(buffer
, len
, filename_a
, (const D3D_SHADER_MACRO
*)defines
,
519 (ID3DInclude
*)include
, entrypoint
, profile
, flags
, 0,
520 (ID3DBlob
**)shader
, (ID3DBlob
**)error_messages
);
522 if (SUCCEEDED(hr
) && constant_table
)
523 hr
= D3DXGetShaderConstantTable(ID3DXBuffer_GetBufferPointer(*shader
),
526 ID3DXInclude_Close(include
, buffer
);
527 LeaveCriticalSection(&from_file_mutex
);
528 HeapFree(GetProcessHeap(), 0, filename_a
);
532 HRESULT WINAPI
D3DXCompileShaderFromResourceA(HMODULE module
, const char *resource
, const D3DXMACRO
*defines
,
533 ID3DXInclude
*include
, const char *entrypoint
, const char *profile
, DWORD flags
,
534 ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
, ID3DXConstantTable
**constant_table
)
540 TRACE("module %p, resource %s, defines %p, include %p, entrypoint %s, profile %s, "
541 "flags %#x, shader %p, error_messages %p, constant_table %p.\n",
542 module
, debugstr_a(resource
), defines
, include
, debugstr_a(entrypoint
), debugstr_a(profile
),
543 flags
, shader
, error_messages
, constant_table
);
545 if (!(res
= FindResourceA(module
, resource
, (const char *)RT_RCDATA
)))
546 return D3DXERR_INVALIDDATA
;
547 if (FAILED(load_resource_into_memory(module
, res
, &buffer
, &len
)))
548 return D3DXERR_INVALIDDATA
;
549 return D3DXCompileShader(buffer
, len
, defines
, include
, entrypoint
, profile
,
550 flags
, shader
, error_messages
, constant_table
);
553 HRESULT WINAPI
D3DXCompileShaderFromResourceW(HMODULE module
, const WCHAR
*resource
, const D3DXMACRO
*defines
,
554 ID3DXInclude
*include
, const char *entrypoint
, const char *profile
, DWORD flags
,
555 ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
, ID3DXConstantTable
**constant_table
)
561 TRACE("module %p, resource %s, defines %p, include %p, entrypoint %s, profile %s, "
562 "flags %#x, shader %p, error_messages %p, constant_table %p.\n",
563 module
, debugstr_w(resource
), defines
, include
, debugstr_a(entrypoint
), debugstr_a(profile
),
564 flags
, shader
, error_messages
, constant_table
);
566 if (!(res
= FindResourceW(module
, resource
, (const WCHAR
*)RT_RCDATA
)))
567 return D3DXERR_INVALIDDATA
;
568 if (FAILED(load_resource_into_memory(module
, res
, &buffer
, &len
)))
569 return D3DXERR_INVALIDDATA
;
570 return D3DXCompileShader(buffer
, len
, defines
, include
, entrypoint
, profile
,
571 flags
, shader
, error_messages
, constant_table
);
574 HRESULT WINAPI
D3DXPreprocessShader(const char *data
, UINT data_len
, const D3DXMACRO
*defines
,
575 ID3DXInclude
*include
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
577 TRACE("data %s, data_len %u, defines %p, include %p, shader %p, error_messages %p.\n",
578 debugstr_a(data
), data_len
, defines
, include
, shader
, error_messages
);
580 return D3DPreprocess(data
, data_len
, NULL
,
581 (const D3D_SHADER_MACRO
*)defines
, (ID3DInclude
*)include
,
582 (ID3DBlob
**)shader
, (ID3DBlob
**)error_messages
);
585 HRESULT WINAPI
D3DXPreprocessShaderFromFileA(const char *filename
, const D3DXMACRO
*defines
,
586 ID3DXInclude
*include
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
588 WCHAR
*filename_w
= NULL
;
592 TRACE("filename %s, defines %p, include %p, shader %p, error_messages %p.\n",
593 debugstr_a(filename
), defines
, include
, shader
, error_messages
);
595 if (!filename
) return D3DXERR_INVALIDDATA
;
597 len
= MultiByteToWideChar(CP_ACP
, 0, filename
, -1, NULL
, 0);
598 filename_w
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
599 if (!filename_w
) return E_OUTOFMEMORY
;
600 MultiByteToWideChar(CP_ACP
, 0, filename
, -1, filename_w
, len
);
602 ret
= D3DXPreprocessShaderFromFileW(filename_w
, defines
, include
, shader
, error_messages
);
604 HeapFree(GetProcessHeap(), 0, filename_w
);
608 HRESULT WINAPI
D3DXPreprocessShaderFromFileW(const WCHAR
*filename
, const D3DXMACRO
*defines
,
609 ID3DXInclude
*include
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
614 struct D3DXIncludeImpl includefromfile
;
617 TRACE("filename %s, defines %p, include %p, shader %p, error_messages %p.\n",
618 debugstr_w(filename
), defines
, include
, shader
, error_messages
);
622 includefromfile
.ID3DXInclude_iface
.lpVtbl
= &D3DXInclude_Vtbl
;
623 include
= &includefromfile
.ID3DXInclude_iface
;
626 len
= WideCharToMultiByte(CP_ACP
, 0, filename
, -1, NULL
, 0, NULL
, NULL
);
627 filename_a
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(char));
629 return E_OUTOFMEMORY
;
630 WideCharToMultiByte(CP_ACP
, 0, filename
, -1, filename_a
, len
, NULL
, NULL
);
632 EnterCriticalSection(&from_file_mutex
);
633 hr
= ID3DXInclude_Open(include
, D3D_INCLUDE_LOCAL
, filename_a
, NULL
, &buffer
, &len
);
636 LeaveCriticalSection(&from_file_mutex
);
637 HeapFree(GetProcessHeap(), 0, filename_a
);
638 return D3DXERR_INVALIDDATA
;
641 hr
= D3DPreprocess(buffer
, len
, NULL
,
642 (const D3D_SHADER_MACRO
*)defines
,
643 (ID3DInclude
*) include
,
644 (ID3DBlob
**)shader
, (ID3DBlob
**)error_messages
);
646 ID3DXInclude_Close(include
, buffer
);
647 LeaveCriticalSection(&from_file_mutex
);
648 HeapFree(GetProcessHeap(), 0, filename_a
);
652 HRESULT WINAPI
D3DXPreprocessShaderFromResourceA(HMODULE module
, const char *resource
, const D3DXMACRO
*defines
,
653 ID3DXInclude
*include
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
659 TRACE("module %p, resource %s, defines %p, include %p, shader %p, error_messages %p.\n",
660 module
, debugstr_a(resource
), defines
, include
, shader
, error_messages
);
662 if (!(res
= FindResourceA(module
, resource
, (const char *)RT_RCDATA
)))
663 return D3DXERR_INVALIDDATA
;
664 if (FAILED(load_resource_into_memory(module
, res
, &buffer
, &len
)))
665 return D3DXERR_INVALIDDATA
;
666 return D3DXPreprocessShader(buffer
, len
, defines
, include
,
667 shader
, error_messages
);
670 HRESULT WINAPI
D3DXPreprocessShaderFromResourceW(HMODULE module
, const WCHAR
*resource
, const D3DXMACRO
*defines
,
671 ID3DXInclude
*include
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
677 TRACE("module %p, resource %s, defines %p, include %p, shader %p, error_messages %p.\n",
678 module
, debugstr_w(resource
), defines
, include
, shader
, error_messages
);
680 if (!(res
= FindResourceW(module
, resource
, (const WCHAR
*)RT_RCDATA
)))
681 return D3DXERR_INVALIDDATA
;
682 if (FAILED(load_resource_into_memory(module
, res
, &buffer
, &len
)))
683 return D3DXERR_INVALIDDATA
;
684 return D3DXPreprocessShader(buffer
, len
, defines
, include
,
685 shader
, error_messages
);
689 struct ctab_constant
{
690 D3DXCONSTANT_DESC desc
;
691 struct ctab_constant
*constants
;
694 struct ID3DXConstantTableImpl
{
695 ID3DXConstantTable ID3DXConstantTable_iface
;
699 D3DXCONSTANTTABLE_DESC desc
;
700 struct ctab_constant
*constants
;
703 static void free_constant(struct ctab_constant
*constant
)
705 if (constant
->constants
)
707 UINT i
, count
= constant
->desc
.Elements
> 1 ? constant
->desc
.Elements
: constant
->desc
.StructMembers
;
709 for (i
= 0; i
< count
; ++i
)
711 free_constant(&constant
->constants
[i
]);
713 HeapFree(GetProcessHeap(), 0, constant
->constants
);
717 static void free_constant_table(struct ID3DXConstantTableImpl
*table
)
719 if (table
->constants
)
723 for (i
= 0; i
< table
->desc
.Constants
; ++i
)
725 free_constant(&table
->constants
[i
]);
727 HeapFree(GetProcessHeap(), 0, table
->constants
);
729 HeapFree(GetProcessHeap(), 0, table
->ctab
);
732 static inline struct ID3DXConstantTableImpl
*impl_from_ID3DXConstantTable(ID3DXConstantTable
*iface
)
734 return CONTAINING_RECORD(iface
, struct ID3DXConstantTableImpl
, ID3DXConstantTable_iface
);
737 static inline BOOL
is_vertex_shader(DWORD version
)
739 return (version
& 0xffff0000) == 0xfffe0000;
742 static inline D3DXHANDLE
handle_from_constant(struct ctab_constant
*constant
)
744 return (D3DXHANDLE
)constant
;
747 static struct ctab_constant
*get_constant_by_name(struct ID3DXConstantTableImpl
*table
,
748 struct ctab_constant
*constant
, const char *name
);
750 static struct ctab_constant
*get_constant_element_by_name(struct ctab_constant
*constant
, const char *name
)
755 TRACE("constant %p, name %s\n", constant
, debugstr_a(name
));
757 if (!name
|| !*name
) return NULL
;
759 element
= atoi(name
);
760 part
= strchr(name
, ']') + 1;
762 if (constant
->desc
.Elements
> element
)
764 struct ctab_constant
*c
= constant
->constants
? &constant
->constants
[element
] : constant
;
769 return get_constant_by_name(NULL
, c
, part
);
772 return get_constant_element_by_name(c
, part
);
775 TRACE("Returning parameter %p\n", c
);
779 FIXME("Unhandled case \"%c\"\n", *--part
);
784 TRACE("Constant not found\n");
788 static struct ctab_constant
*get_constant_by_name(struct ID3DXConstantTableImpl
*table
,
789 struct ctab_constant
*constant
, const char *name
)
791 UINT i
, count
, length
;
792 struct ctab_constant
*handles
;
795 TRACE("table %p, constant %p, name %s\n", table
, constant
, debugstr_a(name
));
797 if (!name
|| !*name
) return NULL
;
801 count
= table
->desc
.Constants
;
802 handles
= table
->constants
;
806 count
= constant
->desc
.StructMembers
;
807 handles
= constant
->constants
;
810 length
= strcspn(name
, "[.");
811 part
= name
+ length
;
813 for (i
= 0; i
< count
; i
++)
815 if (strlen(handles
[i
].desc
.Name
) == length
&& !strncmp(handles
[i
].desc
.Name
, name
, length
))
820 return get_constant_by_name(NULL
, &handles
[i
], part
);
823 return get_constant_element_by_name(&handles
[i
], part
);
826 TRACE("Returning parameter %p\n", &handles
[i
]);
832 TRACE("Constant not found\n");
836 static struct ctab_constant
*is_valid_sub_constant(struct ctab_constant
*parent
, D3DXHANDLE handle
)
838 struct ctab_constant
*c
;
841 /* all variable have at least elements = 1, but not always elements */
842 if (!parent
->constants
) return NULL
;
844 count
= parent
->desc
.Elements
> 1 ? parent
->desc
.Elements
: parent
->desc
.StructMembers
;
845 for (i
= 0; i
< count
; ++i
)
847 if (handle_from_constant(&parent
->constants
[i
]) == handle
)
848 return &parent
->constants
[i
];
850 c
= is_valid_sub_constant(&parent
->constants
[i
], handle
);
857 static inline struct ctab_constant
*get_valid_constant(struct ID3DXConstantTableImpl
*table
, D3DXHANDLE handle
)
859 struct ctab_constant
*c
;
862 if (!handle
) return NULL
;
864 for (i
= 0; i
< table
->desc
.Constants
; ++i
)
866 if (handle_from_constant(&table
->constants
[i
]) == handle
)
867 return &table
->constants
[i
];
869 c
= is_valid_sub_constant(&table
->constants
[i
], handle
);
873 return get_constant_by_name(table
, NULL
, handle
);
876 /*** IUnknown methods ***/
877 static HRESULT WINAPI
ID3DXConstantTableImpl_QueryInterface(ID3DXConstantTable
*iface
, REFIID riid
, void **out
)
879 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
881 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
882 IsEqualGUID(riid
, &IID_ID3DXBuffer
) ||
883 IsEqualGUID(riid
, &IID_ID3DXConstantTable
))
885 ID3DXConstantTable_AddRef(iface
);
890 WARN("Interface %s not found.\n", debugstr_guid(riid
));
892 return E_NOINTERFACE
;
895 static ULONG WINAPI
ID3DXConstantTableImpl_AddRef(ID3DXConstantTable
*iface
)
897 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
899 TRACE("(%p)->(): AddRef from %d\n", This
, This
->ref
);
901 return InterlockedIncrement(&This
->ref
);
904 static ULONG WINAPI
ID3DXConstantTableImpl_Release(ID3DXConstantTable
*iface
)
906 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
907 ULONG ref
= InterlockedDecrement(&This
->ref
);
909 TRACE("(%p)->(): Release from %d\n", This
, ref
+ 1);
913 free_constant_table(This
);
914 HeapFree(GetProcessHeap(), 0, This
);
920 /*** ID3DXBuffer methods ***/
921 static void * WINAPI
ID3DXConstantTableImpl_GetBufferPointer(ID3DXConstantTable
*iface
)
923 struct ID3DXConstantTableImpl
*table
= impl_from_ID3DXConstantTable(iface
);
925 TRACE("iface %p.\n", iface
);
930 static DWORD WINAPI
ID3DXConstantTableImpl_GetBufferSize(ID3DXConstantTable
*iface
)
932 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
934 TRACE("(%p)->()\n", This
);
939 /*** ID3DXConstantTable methods ***/
940 static HRESULT WINAPI
ID3DXConstantTableImpl_GetDesc(ID3DXConstantTable
*iface
, D3DXCONSTANTTABLE_DESC
*desc
)
942 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
944 TRACE("(%p)->(%p)\n", This
, desc
);
947 return D3DERR_INVALIDCALL
;
954 static HRESULT WINAPI
ID3DXConstantTableImpl_GetConstantDesc(ID3DXConstantTable
*iface
, D3DXHANDLE constant
,
955 D3DXCONSTANT_DESC
*desc
, UINT
*count
)
957 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
958 struct ctab_constant
*c
= get_valid_constant(This
, constant
);
960 TRACE("(%p)->(%p, %p, %p)\n", This
, constant
, desc
, count
);
964 WARN("Invalid argument specified\n");
965 return D3DERR_INVALIDCALL
;
968 if (desc
) *desc
= c
->desc
;
969 if (count
) *count
= 1;
974 static UINT WINAPI
ID3DXConstantTableImpl_GetSamplerIndex(ID3DXConstantTable
*iface
, D3DXHANDLE constant
)
976 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
977 struct ctab_constant
*c
= get_valid_constant(This
, constant
);
979 TRACE("(%p)->(%p)\n", This
, constant
);
981 if (!c
|| c
->desc
.RegisterSet
!= D3DXRS_SAMPLER
)
983 WARN("Invalid argument specified\n");
987 TRACE("Returning RegisterIndex %u\n", c
->desc
.RegisterIndex
);
988 return c
->desc
.RegisterIndex
;
991 static D3DXHANDLE WINAPI
ID3DXConstantTableImpl_GetConstant(ID3DXConstantTable
*iface
, D3DXHANDLE constant
, UINT index
)
993 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
994 struct ctab_constant
*c
;
996 TRACE("(%p)->(%p, %d)\n", This
, constant
, index
);
1000 c
= get_valid_constant(This
, constant
);
1001 if (c
&& index
< c
->desc
.StructMembers
)
1003 c
= &c
->constants
[index
];
1004 TRACE("Returning constant %p\n", c
);
1005 return handle_from_constant(c
);
1010 if (index
< This
->desc
.Constants
)
1012 c
= &This
->constants
[index
];
1013 TRACE("Returning constant %p\n", c
);
1014 return handle_from_constant(c
);
1018 WARN("Index out of range\n");
1022 static D3DXHANDLE WINAPI
ID3DXConstantTableImpl_GetConstantByName(ID3DXConstantTable
*iface
,
1023 D3DXHANDLE constant
, const char *name
)
1025 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1026 struct ctab_constant
*c
= get_valid_constant(This
, constant
);
1028 TRACE("iface %p, constant %p, name %s.\n", iface
, constant
, debugstr_a(name
));
1030 c
= get_constant_by_name(This
, c
, name
);
1031 TRACE("Returning constant %p\n", c
);
1033 return handle_from_constant(c
);
1036 static D3DXHANDLE WINAPI
ID3DXConstantTableImpl_GetConstantElement(ID3DXConstantTable
*iface
, D3DXHANDLE constant
, UINT index
)
1038 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1039 struct ctab_constant
*c
= get_valid_constant(This
, constant
);
1041 TRACE("(%p)->(%p, %d)\n", This
, constant
, index
);
1043 if (c
&& index
< c
->desc
.Elements
)
1045 if (c
->desc
.Elements
> 1) c
= &c
->constants
[index
];
1046 TRACE("Returning constant %p\n", c
);
1047 return handle_from_constant(c
);
1050 WARN("Invalid argument specified\n");
1054 static inline DWORD
get_index(const void **indata
, UINT index
, BOOL is_pointer
)
1060 return ((DWORD
**)indata
)[index
/ 16][index
% 16];
1062 return (*((DWORD
**)indata
))[index
];
1065 static UINT
set(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
, struct ctab_constant
*constant
,
1066 const void **indata
, D3DXPARAMETER_TYPE intype
, UINT
*size
, UINT incol
, D3DXPARAMETER_CLASS inclass
, UINT index
,
1069 D3DXCONSTANT_DESC
*desc
= &constant
->desc
;
1070 UINT l
, i
, regcount
= 1, regsize
= 1, cin
= 1, rin
= 1, ret
, last
= 0;
1073 /* size too small to set anything */
1074 if (*size
< desc
->Rows
* desc
->Columns
)
1080 /* D3DXPC_STRUCT is somewhat special */
1081 if (desc
->Class
== D3DXPC_STRUCT
)
1084 * Struct array sets the last complete input to the first struct element, all other
1085 * elements are not set.
1086 * E.g.: struct {int i;} s1[2];
1087 * SetValue(device, "s1", [1, 2], 8) => s1 = {2, x};
1089 * struct {int i; int n} s2[2];
1090 * SetValue(device, "s2", [1, 2, 3, 4, 5], 20) => s1 = {{3, 4}, {x, x}};
1092 if (desc
->Elements
> 1)
1094 UINT offset
= *size
/ (desc
->Rows
* desc
->Columns
) - 1;
1096 offset
= min(desc
->Elements
- 1, offset
);
1097 last
= offset
* desc
->Rows
* desc
->Columns
;
1099 if ((is_pointer
|| (!is_pointer
&& inclass
== D3DXPC_MATRIX_ROWS
)) && desc
->RegisterSet
!= D3DXRS_BOOL
)
1101 set(table
, device
, &constant
->constants
[0], NULL
, intype
, size
, incol
, inclass
, 0, is_pointer
);
1105 last
+= set(table
, device
, &constant
->constants
[0], indata
, intype
, size
, incol
, inclass
,
1106 index
+ last
, is_pointer
);
1112 * D3DXRS_BOOL is always set. As there are only 16 bools and there are
1113 * exactly 16 input values, use matrix transpose.
1115 if (inclass
== D3DXPC_MATRIX_ROWS
&& desc
->RegisterSet
== D3DXRS_BOOL
)
1117 D3DXMATRIX mat
, *m
, min
;
1118 D3DXMatrixTranspose(&mat
, &min
);
1121 min
= *(D3DXMATRIX
*)(indata
[index
/ 16]);
1123 min
= **(D3DXMATRIX
**)indata
;
1125 D3DXMatrixTranspose(&mat
, &min
);
1127 for (i
= 0; i
< desc
->StructMembers
; ++i
)
1129 last
+= set(table
, device
, &constant
->constants
[i
], (const void **)&m
, intype
, size
, incol
,
1130 D3DXPC_SCALAR
, index
+ last
, is_pointer
);
1134 * For pointers or for matrix rows, only the first member is set.
1135 * All other members are set to 0. This is not true for D3DXRS_BOOL.
1136 * E.g.: struct {int i; int n} s;
1137 * SetValue(device, "s", [1, 2], 8) => s = {1, 0};
1139 else if ((is_pointer
|| (!is_pointer
&& inclass
== D3DXPC_MATRIX_ROWS
)) && desc
->RegisterSet
!= D3DXRS_BOOL
)
1141 last
= set(table
, device
, &constant
->constants
[0], indata
, intype
, size
, incol
, inclass
,
1142 index
+ last
, is_pointer
);
1144 for (i
= 1; i
< desc
->StructMembers
; ++i
)
1146 set(table
, device
, &constant
->constants
[i
], NULL
, intype
, size
, incol
, inclass
, 0, is_pointer
);
1151 for (i
= 0; i
< desc
->StructMembers
; ++i
)
1153 last
+= set(table
, device
, &constant
->constants
[i
], indata
, intype
, size
, incol
, D3DXPC_SCALAR
,
1154 index
+ last
, is_pointer
);
1163 if (desc
->Elements
> 1)
1165 for (i
= 0; i
< desc
->Elements
&& *size
> 0; ++i
)
1167 last
+= set(table
, device
, &constant
->constants
[i
], indata
, intype
, size
, incol
, inclass
,
1168 index
+ last
, is_pointer
);
1170 /* adjust the vector size for matrix rows */
1171 if (inclass
== D3DXPC_MATRIX_ROWS
&& desc
->Class
== D3DXPC_VECTOR
&& (i
% 4) == 3)
1174 *size
= *size
< 12 ? 0 : *size
- 12;
1181 switch (desc
->Class
)
1185 case D3DXPC_MATRIX_ROWS
:
1186 regcount
= min(desc
->RegisterCount
, desc
->Rows
);
1187 if (inclass
== D3DXPC_MATRIX_ROWS
) cin
= incol
;
1189 regsize
= desc
->Columns
;
1192 case D3DXPC_MATRIX_COLUMNS
:
1193 regcount
= min(desc
->RegisterCount
, desc
->Columns
);
1194 if (inclass
== D3DXPC_MATRIX_ROWS
) rin
= incol
;
1196 regsize
= desc
->Rows
;
1200 FIXME("Unhandled variable class %s\n", debug_d3dxparameter_class(desc
->Class
));
1204 /* specific stuff for different in types */
1208 ret
= desc
->Columns
* desc
->Rows
;
1209 *size
-= desc
->Columns
* desc
->Rows
;
1213 switch (desc
->Class
)
1215 case D3DXPC_MATRIX_ROWS
:
1216 if (*size
< regcount
* 4)
1222 *size
-= 4 * regcount
;
1225 case D3DXPC_MATRIX_COLUMNS
:
1227 *size
-= 4 * regcount
;
1241 FIXME("Unhandled variable class %s\n", debug_d3dxparameter_class(desc
->Class
));
1246 case D3DXPC_MATRIX_ROWS
:
1247 switch (desc
->Class
)
1249 case D3DXPC_MATRIX_ROWS
:
1250 case D3DXPC_MATRIX_COLUMNS
:
1268 FIXME("Unhandled variable class %s\n", debug_d3dxparameter_class(desc
->Class
));
1274 case D3DXPC_MATRIX_COLUMNS
:
1275 switch (desc
->Class
)
1277 case D3DXPC_MATRIX_ROWS
:
1278 case D3DXPC_MATRIX_COLUMNS
:
1296 FIXME("Unhandled variable class %s\n", debug_d3dxparameter_class(desc
->Class
));
1303 FIXME("Unhandled variable class %s\n", debug_d3dxparameter_class(inclass
));
1307 /* set the registers */
1308 switch (desc
->RegisterSet
)
1311 regcount
= min(desc
->RegisterCount
, desc
->Columns
* desc
->Rows
);
1313 for (i
= 0; i
< regcount
; ++i
)
1316 DWORD t
= get_index(indata
, index
+ i
/ regsize
* rin
+ l
* cin
, is_pointer
);
1318 set_number(&tmp
, desc
->Type
, &t
, intype
);
1319 set_number(&out
, D3DXPT_BOOL
, &tmp
, desc
->Type
);
1320 if (is_vertex_shader(table
->desc
.Version
))
1321 IDirect3DDevice9_SetVertexShaderConstantB(device
, desc
->RegisterIndex
+ i
, &out
, 1);
1323 IDirect3DDevice9_SetPixelShaderConstantB(device
, desc
->RegisterIndex
+ i
, &out
, 1);
1325 if (++l
>= regsize
) l
= 0;
1330 for (i
= 0; i
< regcount
; ++i
)
1332 INT vec
[4] = {0, 0, 1, 0};
1334 for (l
= 0; l
< regsize
; ++l
)
1336 DWORD t
= get_index(indata
, index
+ i
* rin
+ l
* cin
, is_pointer
);
1338 set_number(&tmp
, desc
->Type
, &t
, intype
);
1339 set_number(&vec
[l
], D3DXPT_INT
, &tmp
, desc
->Type
);
1341 if (is_vertex_shader(table
->desc
.Version
))
1342 IDirect3DDevice9_SetVertexShaderConstantI(device
, desc
->RegisterIndex
+ i
, vec
, 1);
1344 IDirect3DDevice9_SetPixelShaderConstantI(device
, desc
->RegisterIndex
+ i
, vec
, 1);
1349 for (i
= 0; i
< regcount
; ++i
)
1353 for (l
= 0; l
< regsize
; ++l
)
1355 DWORD t
= get_index(indata
, index
+ i
* rin
+ l
* cin
, is_pointer
);
1357 set_number(&tmp
, desc
->Type
, &t
, intype
);
1358 set_number(&vec
[l
], D3DXPT_FLOAT
, &tmp
, desc
->Type
);
1360 if (is_vertex_shader(table
->desc
.Version
))
1361 IDirect3DDevice9_SetVertexShaderConstantF(device
, desc
->RegisterIndex
+ i
, vec
, 1);
1363 IDirect3DDevice9_SetPixelShaderConstantF(device
, desc
->RegisterIndex
+ i
, vec
, 1);
1368 FIXME("Unhandled register set %s\n", debug_d3dxparameter_registerset(desc
->RegisterSet
));
1373 static HRESULT
set_scalar(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
, D3DXHANDLE constant
,
1374 const void *indata
, D3DXPARAMETER_TYPE intype
)
1376 struct ctab_constant
*c
= get_valid_constant(table
, constant
);
1381 WARN("Invalid argument specified\n");
1382 return D3DERR_INVALIDCALL
;
1385 switch (c
->desc
.Class
)
1388 set(table
, device
, c
, &indata
, intype
, &count
, c
->desc
.Columns
, D3DXPC_SCALAR
, 0, FALSE
);
1392 case D3DXPC_MATRIX_ROWS
:
1393 case D3DXPC_MATRIX_COLUMNS
:
1398 FIXME("Unhandled parameter class %s\n", debug_d3dxparameter_class(c
->desc
.Class
));
1399 return D3DERR_INVALIDCALL
;
1403 static HRESULT
set_scalar_array(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
, D3DXHANDLE constant
,
1404 const void *indata
, UINT count
, D3DXPARAMETER_TYPE intype
)
1406 struct ctab_constant
*c
= get_valid_constant(table
, constant
);
1410 WARN("Invalid argument specified\n");
1411 return D3DERR_INVALIDCALL
;
1414 switch (c
->desc
.Class
)
1418 case D3DXPC_MATRIX_ROWS
:
1419 case D3DXPC_MATRIX_COLUMNS
:
1421 set(table
, device
, c
, &indata
, intype
, &count
, c
->desc
.Columns
, D3DXPC_SCALAR
, 0, FALSE
);
1425 FIXME("Unhandled parameter class %s\n", debug_d3dxparameter_class(c
->desc
.Class
));
1426 return D3DERR_INVALIDCALL
;
1430 static HRESULT
set_vector(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
, D3DXHANDLE constant
,
1431 const void *indata
, D3DXPARAMETER_TYPE intype
)
1433 struct ctab_constant
*c
= get_valid_constant(table
, constant
);
1438 WARN("Invalid argument specified\n");
1439 return D3DERR_INVALIDCALL
;
1442 switch (c
->desc
.Class
)
1447 set(table
, device
, c
, &indata
, intype
, &count
, 4, D3DXPC_VECTOR
, 0, FALSE
);
1450 case D3DXPC_MATRIX_ROWS
:
1451 case D3DXPC_MATRIX_COLUMNS
:
1455 FIXME("Unhandled parameter class %s\n", debug_d3dxparameter_class(c
->desc
.Class
));
1456 return D3DERR_INVALIDCALL
;
1460 static HRESULT
set_vector_array(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
, D3DXHANDLE constant
,
1461 const void *indata
, UINT count
, D3DXPARAMETER_TYPE intype
)
1463 struct ctab_constant
*c
= get_valid_constant(table
, constant
);
1467 WARN("Invalid argument specified\n");
1468 return D3DERR_INVALIDCALL
;
1471 switch (c
->desc
.Class
)
1475 case D3DXPC_MATRIX_ROWS
:
1476 case D3DXPC_MATRIX_COLUMNS
:
1479 set(table
, device
, c
, &indata
, intype
, &count
, 4, D3DXPC_VECTOR
, 0, FALSE
);
1483 FIXME("Unhandled parameter class %s\n", debug_d3dxparameter_class(c
->desc
.Class
));
1484 return D3DERR_INVALIDCALL
;
1488 static HRESULT
set_matrix_array(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
, D3DXHANDLE constant
,
1489 const void *indata
, UINT count
, BOOL transpose
)
1491 struct ctab_constant
*c
= get_valid_constant(table
, constant
);
1495 WARN("Invalid argument specified\n");
1496 return D3DERR_INVALIDCALL
;
1499 switch (c
->desc
.Class
)
1503 case D3DXPC_MATRIX_ROWS
:
1504 case D3DXPC_MATRIX_COLUMNS
:
1507 set(table
, device
, c
, &indata
, D3DXPT_FLOAT
, &count
, 4,
1508 transpose
? D3DXPC_MATRIX_ROWS
: D3DXPC_MATRIX_COLUMNS
, 0, FALSE
);
1512 FIXME("Unhandled parameter class %s\n", debug_d3dxparameter_class(c
->desc
.Class
));
1513 return D3DERR_INVALIDCALL
;
1517 static HRESULT
set_matrix_pointer_array(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
,
1518 D3DXHANDLE constant
, const void **indata
, UINT count
, BOOL transpose
)
1520 struct ctab_constant
*c
= get_valid_constant(table
, constant
);
1524 WARN("Invalid argument specified\n");
1525 return D3DERR_INVALIDCALL
;
1528 switch (c
->desc
.Class
)
1532 case D3DXPC_MATRIX_ROWS
:
1533 case D3DXPC_MATRIX_COLUMNS
:
1536 set(table
, device
, c
, indata
, D3DXPT_FLOAT
, &count
, 4,
1537 transpose
? D3DXPC_MATRIX_ROWS
: D3DXPC_MATRIX_COLUMNS
, 0, TRUE
);
1541 FIXME("Unhandled parameter class %s\n", debug_d3dxparameter_class(c
->desc
.Class
));
1542 return D3DERR_INVALIDCALL
;
1546 static HRESULT WINAPI
ID3DXConstantTableImpl_SetDefaults(struct ID3DXConstantTable
*iface
,
1547 struct IDirect3DDevice9
*device
)
1549 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1552 TRACE("iface %p, device %p\n", iface
, device
);
1556 WARN("Invalid argument specified\n");
1557 return D3DERR_INVALIDCALL
;
1560 for (i
= 0; i
< This
->desc
.Constants
; i
++)
1562 D3DXCONSTANT_DESC
*desc
= &This
->constants
[i
].desc
;
1565 if (!desc
->DefaultValue
)
1568 switch (desc
->RegisterSet
)
1571 if (is_vertex_shader(This
->desc
.Version
))
1572 hr
= IDirect3DDevice9_SetVertexShaderConstantB(device
, desc
->RegisterIndex
, desc
->DefaultValue
,
1573 desc
->RegisterCount
);
1575 hr
= IDirect3DDevice9_SetPixelShaderConstantB(device
, desc
->RegisterIndex
, desc
->DefaultValue
,
1576 desc
->RegisterCount
);
1580 if (is_vertex_shader(This
->desc
.Version
))
1581 hr
= IDirect3DDevice9_SetVertexShaderConstantI(device
, desc
->RegisterIndex
, desc
->DefaultValue
,
1582 desc
->RegisterCount
);
1584 hr
= IDirect3DDevice9_SetPixelShaderConstantI(device
, desc
->RegisterIndex
, desc
->DefaultValue
,
1585 desc
->RegisterCount
);
1589 if (is_vertex_shader(This
->desc
.Version
))
1590 hr
= IDirect3DDevice9_SetVertexShaderConstantF(device
, desc
->RegisterIndex
, desc
->DefaultValue
,
1591 desc
->RegisterCount
);
1593 hr
= IDirect3DDevice9_SetPixelShaderConstantF(device
, desc
->RegisterIndex
, desc
->DefaultValue
,
1594 desc
->RegisterCount
);
1598 FIXME("Unhandled register set %s\n", debug_d3dxparameter_registerset(desc
->RegisterSet
));
1610 static HRESULT WINAPI
ID3DXConstantTableImpl_SetValue(struct ID3DXConstantTable
*iface
,
1611 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const void *data
, unsigned int bytes
)
1613 struct ID3DXConstantTableImpl
*table
= impl_from_ID3DXConstantTable(iface
);
1614 struct ctab_constant
*c
= get_valid_constant(table
, constant
);
1615 D3DXCONSTANT_DESC
*desc
;
1617 TRACE("iface %p, device %p, constant %p, data %p, bytes %u\n", iface
, device
, constant
, data
, bytes
);
1619 if (!device
|| !c
|| !data
)
1621 WARN("Invalid argument specified\n");
1622 return D3DERR_INVALIDCALL
;
1627 switch (desc
->Class
)
1631 case D3DXPC_MATRIX_ROWS
:
1632 case D3DXPC_MATRIX_COLUMNS
:
1635 set(table
, device
, c
, &data
, desc
->Type
, &bytes
, desc
->Columns
, D3DXPC_SCALAR
, 0, FALSE
);
1639 FIXME("Unhandled parameter class %s\n", debug_d3dxparameter_class(desc
->Class
));
1640 return D3DERR_INVALIDCALL
;
1644 static HRESULT WINAPI
ID3DXConstantTableImpl_SetBool(struct ID3DXConstantTable
*iface
,
1645 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, BOOL b
)
1647 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1649 TRACE("iface %p, device %p, constant %p, b %d\n", iface
, device
, constant
, b
);
1651 return set_scalar(This
, device
, constant
, &b
, D3DXPT_BOOL
);
1654 static HRESULT WINAPI
ID3DXConstantTableImpl_SetBoolArray(struct ID3DXConstantTable
*iface
,
1655 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const BOOL
*b
, UINT count
)
1657 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1659 TRACE("iface %p, device %p, constant %p, b %p, count %d\n", iface
, device
, constant
, b
, count
);
1661 return set_scalar_array(This
, device
, constant
, b
, count
, D3DXPT_BOOL
);
1664 static HRESULT WINAPI
ID3DXConstantTableImpl_SetInt(struct ID3DXConstantTable
*iface
,
1665 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, INT n
)
1667 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1669 TRACE("iface %p, device %p, constant %p, n %d\n", iface
, device
, constant
, n
);
1671 return set_scalar(This
, device
, constant
, &n
, D3DXPT_INT
);
1674 static HRESULT WINAPI
ID3DXConstantTableImpl_SetIntArray(struct ID3DXConstantTable
*iface
,
1675 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const INT
*n
, UINT count
)
1677 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1679 TRACE("iface %p, device %p, constant %p, n %p, count %d\n", iface
, device
, constant
, n
, count
);
1681 return set_scalar_array(This
, device
, constant
, n
, count
, D3DXPT_INT
);
1684 static HRESULT WINAPI
ID3DXConstantTableImpl_SetFloat(struct ID3DXConstantTable
*iface
,
1685 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, float f
)
1687 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1689 TRACE("iface %p, device %p, constant %p, f %f\n", iface
, device
, constant
, f
);
1691 return set_scalar(This
, device
, constant
, &f
, D3DXPT_FLOAT
);
1694 static HRESULT WINAPI
ID3DXConstantTableImpl_SetFloatArray(struct ID3DXConstantTable
*iface
,
1695 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const float *f
, UINT count
)
1697 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1699 TRACE("iface %p, device %p, constant %p, f %p, count %d\n", iface
, device
, constant
, f
, count
);
1701 return set_scalar_array(This
, device
, constant
, f
, count
, D3DXPT_FLOAT
);
1704 static HRESULT WINAPI
ID3DXConstantTableImpl_SetVector(struct ID3DXConstantTable
*iface
,
1705 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXVECTOR4
*vector
)
1707 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1709 TRACE("iface %p, device %p, constant %p, vector %p\n", iface
, device
, constant
, vector
);
1711 return set_vector(This
, device
, constant
, vector
, D3DXPT_FLOAT
);
1714 static HRESULT WINAPI
ID3DXConstantTableImpl_SetVectorArray(struct ID3DXConstantTable
*iface
,
1715 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXVECTOR4
*vector
, UINT count
)
1717 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1719 TRACE("iface %p, device %p, constant %p, vector %p, count %u\n", iface
, device
, constant
, vector
, count
);
1721 return set_vector_array(This
, device
, constant
, vector
, count
, D3DXPT_FLOAT
);
1724 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrix(struct ID3DXConstantTable
*iface
,
1725 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXMATRIX
*matrix
)
1727 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1729 TRACE("iface %p, device %p, constant %p, matrix %p\n", iface
, device
, constant
, matrix
);
1731 return set_matrix_array(This
, device
, constant
, matrix
, 1, FALSE
);
1734 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrixArray(struct ID3DXConstantTable
*iface
,
1735 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXMATRIX
*matrix
, UINT count
)
1737 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1739 TRACE("iface %p, device %p, constant %p, matrix %p, count %u\n", iface
, device
, constant
, matrix
, count
);
1741 return set_matrix_array(This
, device
, constant
, matrix
, count
, FALSE
);
1744 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrixPointerArray(struct ID3DXConstantTable
*iface
,
1745 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXMATRIX
**matrix
, UINT count
)
1747 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1749 TRACE("iface %p, device %p, constant %p, matrix %p, count %u)\n", iface
, device
, constant
, matrix
, count
);
1751 return set_matrix_pointer_array(This
, device
, constant
, (const void **)matrix
, count
, FALSE
);
1754 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrixTranspose(struct ID3DXConstantTable
*iface
,
1755 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXMATRIX
*matrix
)
1757 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1759 TRACE("iface %p, device %p, constant %p, matrix %p\n", iface
, device
, constant
, matrix
);
1761 return set_matrix_array(This
, device
, constant
, matrix
, 1, TRUE
);
1764 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrixTransposeArray(struct ID3DXConstantTable
*iface
,
1765 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXMATRIX
*matrix
, UINT count
)
1767 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1769 TRACE("iface %p, device %p, constant %p, matrix %p, count %u\n", iface
, device
, constant
, matrix
, count
);
1771 return set_matrix_array(This
, device
, constant
, matrix
, count
, TRUE
);
1774 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrixTransposePointerArray(struct ID3DXConstantTable
*iface
,
1775 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXMATRIX
**matrix
, UINT count
)
1777 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1779 TRACE("iface %p, device %p, constant %p, matrix %p, count %u)\n", iface
, device
, constant
, matrix
, count
);
1781 return set_matrix_pointer_array(This
, device
, constant
, (const void **)matrix
, count
, TRUE
);
1784 static const struct ID3DXConstantTableVtbl ID3DXConstantTable_Vtbl
=
1786 /*** IUnknown methods ***/
1787 ID3DXConstantTableImpl_QueryInterface
,
1788 ID3DXConstantTableImpl_AddRef
,
1789 ID3DXConstantTableImpl_Release
,
1790 /*** ID3DXBuffer methods ***/
1791 ID3DXConstantTableImpl_GetBufferPointer
,
1792 ID3DXConstantTableImpl_GetBufferSize
,
1793 /*** ID3DXConstantTable methods ***/
1794 ID3DXConstantTableImpl_GetDesc
,
1795 ID3DXConstantTableImpl_GetConstantDesc
,
1796 ID3DXConstantTableImpl_GetSamplerIndex
,
1797 ID3DXConstantTableImpl_GetConstant
,
1798 ID3DXConstantTableImpl_GetConstantByName
,
1799 ID3DXConstantTableImpl_GetConstantElement
,
1800 ID3DXConstantTableImpl_SetDefaults
,
1801 ID3DXConstantTableImpl_SetValue
,
1802 ID3DXConstantTableImpl_SetBool
,
1803 ID3DXConstantTableImpl_SetBoolArray
,
1804 ID3DXConstantTableImpl_SetInt
,
1805 ID3DXConstantTableImpl_SetIntArray
,
1806 ID3DXConstantTableImpl_SetFloat
,
1807 ID3DXConstantTableImpl_SetFloatArray
,
1808 ID3DXConstantTableImpl_SetVector
,
1809 ID3DXConstantTableImpl_SetVectorArray
,
1810 ID3DXConstantTableImpl_SetMatrix
,
1811 ID3DXConstantTableImpl_SetMatrixArray
,
1812 ID3DXConstantTableImpl_SetMatrixPointerArray
,
1813 ID3DXConstantTableImpl_SetMatrixTranspose
,
1814 ID3DXConstantTableImpl_SetMatrixTransposeArray
,
1815 ID3DXConstantTableImpl_SetMatrixTransposePointerArray
1818 static HRESULT
parse_ctab_constant_type(const char *ctab
, DWORD typeoffset
, struct ctab_constant
*constant
,
1819 BOOL is_element
, WORD index
, WORD max_index
, DWORD
*offset
, DWORD nameoffset
, UINT regset
)
1821 const D3DXSHADER_TYPEINFO
*type
= (LPD3DXSHADER_TYPEINFO
)(ctab
+ typeoffset
);
1822 const D3DXSHADER_STRUCTMEMBERINFO
*memberinfo
= NULL
;
1823 HRESULT hr
= D3D_OK
;
1827 constant
->desc
.DefaultValue
= offset
? ctab
+ *offset
: NULL
;
1828 constant
->desc
.Class
= type
->Class
;
1829 constant
->desc
.Type
= type
->Type
;
1830 constant
->desc
.Rows
= type
->Rows
;
1831 constant
->desc
.Columns
= type
->Columns
;
1832 constant
->desc
.Elements
= is_element
? 1 : type
->Elements
;
1833 constant
->desc
.StructMembers
= type
->StructMembers
;
1834 constant
->desc
.Name
= ctab
+ nameoffset
;
1835 constant
->desc
.RegisterSet
= regset
;
1836 constant
->desc
.RegisterIndex
= index
;
1838 TRACE("name %s, elements %u, index %u, defaultvalue %p, regset %s\n", constant
->desc
.Name
,
1839 constant
->desc
.Elements
, index
, constant
->desc
.DefaultValue
,
1840 debug_d3dxparameter_registerset(regset
));
1841 TRACE("class %s, type %s, rows %d, columns %d, elements %d, struct_members %d\n",
1842 debug_d3dxparameter_class(type
->Class
), debug_d3dxparameter_type(type
->Type
),
1843 type
->Rows
, type
->Columns
, type
->Elements
, type
->StructMembers
);
1845 if (type
->Elements
> 1 && !is_element
)
1847 count
= type
->Elements
;
1849 else if ((type
->Class
== D3DXPC_STRUCT
) && type
->StructMembers
)
1851 memberinfo
= (D3DXSHADER_STRUCTMEMBERINFO
*)(ctab
+ type
->StructMemberInfo
);
1852 count
= type
->StructMembers
;
1857 constant
->constants
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*constant
->constants
) * count
);
1858 if (!constant
->constants
)
1860 ERR("Out of memory\n");
1865 for (i
= 0; i
< count
; ++i
)
1867 hr
= parse_ctab_constant_type(ctab
, memberinfo
? memberinfo
[i
].TypeInfo
: typeoffset
,
1868 &constant
->constants
[i
], memberinfo
== NULL
, index
+ size
, max_index
, offset
,
1869 memberinfo
? memberinfo
[i
].Name
: nameoffset
, regset
);
1873 size
+= constant
->constants
[i
].desc
.RegisterCount
;
1878 WORD offsetdiff
= type
->Columns
* type
->Rows
;
1881 size
= type
->Columns
* type
->Rows
;
1886 fail
= type
->Class
!= D3DXPC_SCALAR
&& type
->Class
!= D3DXPC_VECTOR
1887 && type
->Class
!= D3DXPC_MATRIX_ROWS
&& type
->Class
!= D3DXPC_MATRIX_COLUMNS
;
1892 switch (type
->Class
)
1898 offsetdiff
= type
->Rows
* 4;
1901 case D3DXPC_MATRIX_ROWS
:
1902 offsetdiff
= type
->Rows
* 4;
1906 case D3DXPC_MATRIX_COLUMNS
:
1907 offsetdiff
= type
->Columns
* 4;
1908 size
= type
->Columns
;
1917 case D3DXRS_SAMPLER
:
1919 fail
= type
->Class
!= D3DXPC_OBJECT
;
1929 FIXME("Unhandled register set %s, type class %s\n", debug_d3dxparameter_registerset(regset
),
1930 debug_d3dxparameter_class(type
->Class
));
1933 /* offset in bytes => offsetdiff * sizeof(DWORD) */
1934 if (offset
) *offset
+= offsetdiff
* 4;
1937 constant
->desc
.RegisterCount
= max(0, min(max_index
- index
, size
));
1938 constant
->desc
.Bytes
= 4 * constant
->desc
.Elements
* type
->Rows
* type
->Columns
;
1943 if (constant
->constants
)
1945 for (i
= 0; i
< count
; ++i
)
1947 free_constant(&constant
->constants
[i
]);
1949 HeapFree(GetProcessHeap(), 0, constant
->constants
);
1950 constant
->constants
= NULL
;
1956 HRESULT WINAPI
D3DXGetShaderConstantTableEx(const DWORD
*byte_code
, DWORD flags
, ID3DXConstantTable
**constant_table
)
1958 struct ID3DXConstantTableImpl
*object
= NULL
;
1962 const D3DXSHADER_CONSTANTTABLE
*ctab_header
;
1963 const D3DXSHADER_CONSTANTINFO
*constant_info
;
1966 TRACE("byte_code %p, flags %x, constant_table %p\n", byte_code
, flags
, constant_table
);
1968 if (constant_table
) *constant_table
= NULL
;
1970 if (!byte_code
|| !constant_table
)
1972 WARN("Invalid argument specified.\n");
1973 return D3DERR_INVALIDCALL
;
1976 if (!is_valid_bytecode(*byte_code
))
1978 WARN("Invalid byte_code specified.\n");
1982 if (flags
) FIXME("Flags (%#x) are not handled, yet!\n", flags
);
1984 hr
= D3DXFindShaderComment(byte_code
, MAKEFOURCC('C','T','A','B'), &data
, &size
);
1987 WARN("CTAB not found.\n");
1988 return D3DXERR_INVALIDDATA
;
1991 if (size
< sizeof(*ctab_header
))
1993 WARN("Invalid CTAB size.\n");
1994 return D3DXERR_INVALIDDATA
;
1997 ctab_header
= (const D3DXSHADER_CONSTANTTABLE
*)data
;
1998 if (ctab_header
->Size
!= sizeof(*ctab_header
))
2000 WARN("Invalid D3DXSHADER_CONSTANTTABLE size.\n");
2001 return D3DXERR_INVALIDDATA
;
2004 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*object
));
2006 return E_OUTOFMEMORY
;
2008 object
->ID3DXConstantTable_iface
.lpVtbl
= &ID3DXConstantTable_Vtbl
;
2011 object
->ctab
= HeapAlloc(GetProcessHeap(), 0, size
);
2014 ERR("Out of memory\n");
2015 HeapFree(GetProcessHeap(), 0, object
);
2016 return E_OUTOFMEMORY
;
2018 object
->size
= size
;
2019 memcpy(object
->ctab
, data
, object
->size
);
2021 object
->desc
.Creator
= ctab_header
->Creator
? object
->ctab
+ ctab_header
->Creator
: NULL
;
2022 object
->desc
.Version
= ctab_header
->Version
;
2023 object
->desc
.Constants
= ctab_header
->Constants
;
2024 TRACE("Creator %s, Version %x, Constants %u, Target %s\n",
2025 debugstr_a(object
->desc
.Creator
), object
->desc
.Version
, object
->desc
.Constants
,
2026 debugstr_a(ctab_header
->Target
? object
->ctab
+ ctab_header
->Target
: NULL
));
2028 object
->constants
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
2029 sizeof(*object
->constants
) * object
->desc
.Constants
);
2030 if (!object
->constants
)
2032 ERR("Out of memory\n");
2037 constant_info
= (const D3DXSHADER_CONSTANTINFO
*)(object
->ctab
+ ctab_header
->ConstantInfo
);
2038 for (i
= 0; i
< ctab_header
->Constants
; i
++)
2040 DWORD offset
= constant_info
[i
].DefaultValue
;
2042 hr
= parse_ctab_constant_type(object
->ctab
, constant_info
[i
].TypeInfo
,
2043 &object
->constants
[i
], FALSE
, constant_info
[i
].RegisterIndex
,
2044 constant_info
[i
].RegisterIndex
+ constant_info
[i
].RegisterCount
,
2045 offset
? &offset
: NULL
, constant_info
[i
].Name
, constant_info
[i
].RegisterSet
);
2050 * Set the register count, it may differ for D3DXRS_INT4, because somehow
2051 * it makes the assumption that the register size is 1 instead of 4, so the
2052 * count is 4 times bigger. This holds true only for toplevel shader
2053 * constants. The count of elements and members is always based on a
2054 * register size of 4.
2056 if (object
->constants
[i
].desc
.RegisterSet
== D3DXRS_INT4
)
2058 object
->constants
[i
].desc
.RegisterCount
= constant_info
[i
].RegisterCount
;
2062 *constant_table
= &object
->ID3DXConstantTable_iface
;
2067 free_constant_table(object
);
2068 HeapFree(GetProcessHeap(), 0, object
);
2073 HRESULT WINAPI
D3DXGetShaderConstantTable(const DWORD
*byte_code
, ID3DXConstantTable
**constant_table
)
2075 TRACE("(%p, %p): Forwarded to D3DXGetShaderConstantTableEx\n", byte_code
, constant_table
);
2077 return D3DXGetShaderConstantTableEx(byte_code
, 0, constant_table
);
2080 HRESULT WINAPI
D3DXCreateFragmentLinker(IDirect3DDevice9
*device
, UINT size
, ID3DXFragmentLinker
**linker
)
2082 FIXME("device %p, size %u, linker %p: stub.\n", device
, size
, linker
);
2091 HRESULT WINAPI
D3DXCreateFragmentLinkerEx(IDirect3DDevice9
*device
, UINT size
, DWORD flags
, ID3DXFragmentLinker
**linker
)
2093 FIXME("device %p, size %u, flags %#x, linker %p: stub.\n", device
, size
, flags
, linker
);
2101 HRESULT WINAPI
D3DXGetShaderSamplers(const DWORD
*byte_code
, const char **samplers
, UINT
*count
)
2103 UINT i
, sampler_count
= 0;
2106 const D3DXSHADER_CONSTANTTABLE
*ctab_header
;
2107 const D3DXSHADER_CONSTANTINFO
*constant_info
;
2109 TRACE("byte_code %p, samplers %p, count %p\n", byte_code
, samplers
, count
);
2111 if (count
) *count
= 0;
2113 if (D3DXFindShaderComment(byte_code
, MAKEFOURCC('C','T','A','B'), (const void **)&data
, &size
) != D3D_OK
)
2116 if (size
< sizeof(*ctab_header
)) return D3D_OK
;
2118 ctab_header
= (const D3DXSHADER_CONSTANTTABLE
*)data
;
2119 if (ctab_header
->Size
!= sizeof(*ctab_header
)) return D3D_OK
;
2121 constant_info
= (const D3DXSHADER_CONSTANTINFO
*)(data
+ ctab_header
->ConstantInfo
);
2122 for (i
= 0; i
< ctab_header
->Constants
; i
++)
2124 const D3DXSHADER_TYPEINFO
*type
;
2126 TRACE("name = %s\n", data
+ constant_info
[i
].Name
);
2128 type
= (const D3DXSHADER_TYPEINFO
*)(data
+ constant_info
[i
].TypeInfo
);
2130 if (type
->Type
== D3DXPT_SAMPLER
2131 || type
->Type
== D3DXPT_SAMPLER1D
2132 || type
->Type
== D3DXPT_SAMPLER2D
2133 || type
->Type
== D3DXPT_SAMPLER3D
2134 || type
->Type
== D3DXPT_SAMPLERCUBE
)
2136 if (samplers
) samplers
[sampler_count
] = data
+ constant_info
[i
].Name
;
2142 TRACE("Found %u samplers\n", sampler_count
);
2144 if (count
) *count
= sampler_count
;
2149 HRESULT WINAPI
D3DXDisassembleShader(const DWORD
*shader
, BOOL colorcode
, const char *comments
, ID3DXBuffer
**disassembly
)
2151 FIXME("%p %d %s %p: stub\n", shader
, colorcode
, debugstr_a(comments
), disassembly
);
2152 return E_OUTOFMEMORY
;