5 * Copyright 2008 Luis Busquets
6 * Copyright 2009 Matteo Bruni
7 * Copyright 2010, 2013, 2016 Christian Costa
8 * Copyright 2011 Travis Athougies
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
26 #include "d3dx9_private.h"
27 #include "d3dcommon.h"
28 #include "d3dcompiler.h"
29 #endif /* __REACTOS__ */
31 WINE_DEFAULT_DEBUG_CHANNEL(d3dx
);
33 /* This function is not declared in the SDK headers yet. */
34 HRESULT WINAPI
D3DAssemble(const void *data
, SIZE_T datasize
, const char *filename
,
35 const D3D_SHADER_MACRO
*defines
, ID3DInclude
*include
, UINT flags
,
36 ID3DBlob
**shader
, ID3DBlob
**error_messages
);
38 static inline BOOL
is_valid_bytecode(DWORD token
)
40 return (token
& 0xfffe0000) == 0xfffe0000;
43 const char * WINAPI
D3DXGetPixelShaderProfile(struct IDirect3DDevice9
*device
)
47 TRACE("device %p\n", device
);
49 if (!device
) return NULL
;
51 IDirect3DDevice9_GetDeviceCaps(device
,&caps
);
53 switch (caps
.PixelShaderVersion
)
55 case D3DPS_VERSION(1, 1):
58 case D3DPS_VERSION(1, 2):
61 case D3DPS_VERSION(1, 3):
64 case D3DPS_VERSION(1, 4):
67 case D3DPS_VERSION(2, 0):
68 if ((caps
.PS20Caps
.NumTemps
>=22) &&
69 (caps
.PS20Caps
.Caps
&D3DPS20CAPS_ARBITRARYSWIZZLE
) &&
70 (caps
.PS20Caps
.Caps
&D3DPS20CAPS_GRADIENTINSTRUCTIONS
) &&
71 (caps
.PS20Caps
.Caps
&D3DPS20CAPS_PREDICATION
) &&
72 (caps
.PS20Caps
.Caps
&D3DPS20CAPS_NODEPENDENTREADLIMIT
) &&
73 (caps
.PS20Caps
.Caps
&D3DPS20CAPS_NOTEXINSTRUCTIONLIMIT
))
77 if ((caps
.PS20Caps
.NumTemps
>=32) &&
78 (caps
.PS20Caps
.Caps
&D3DPS20CAPS_NOTEXINSTRUCTIONLIMIT
))
84 case D3DPS_VERSION(3, 0):
91 UINT WINAPI
D3DXGetShaderSize(const DWORD
*byte_code
)
93 const DWORD
*ptr
= byte_code
;
95 TRACE("byte_code %p\n", byte_code
);
99 /* Look for the END token, skipping the VERSION token */
100 while (*++ptr
!= D3DSIO_END
)
103 if ((*ptr
& D3DSI_OPCODE_MASK
) == D3DSIO_COMMENT
)
105 ptr
+= ((*ptr
& D3DSI_COMMENTSIZE_MASK
) >> D3DSI_COMMENTSIZE_SHIFT
);
110 /* Return the shader size in bytes */
111 return (ptr
- byte_code
) * sizeof(*ptr
);
114 DWORD WINAPI
D3DXGetShaderVersion(const DWORD
*byte_code
)
116 TRACE("byte_code %p\n", byte_code
);
118 return byte_code
? *byte_code
: 0;
121 const char * WINAPI
D3DXGetVertexShaderProfile(struct IDirect3DDevice9
*device
)
125 TRACE("device %p\n", device
);
127 if (!device
) return NULL
;
129 IDirect3DDevice9_GetDeviceCaps(device
,&caps
);
131 switch (caps
.VertexShaderVersion
)
133 case D3DVS_VERSION(1, 1):
135 case D3DVS_VERSION(2, 0):
136 if ((caps
.VS20Caps
.NumTemps
>=13) &&
137 (caps
.VS20Caps
.DynamicFlowControlDepth
==24) &&
138 (caps
.VS20Caps
.Caps
&D3DPS20CAPS_PREDICATION
))
143 case D3DVS_VERSION(3, 0):
150 HRESULT WINAPI
D3DXFindShaderComment(const DWORD
*byte_code
, DWORD fourcc
, const void **data
, UINT
*size
)
152 const DWORD
*ptr
= byte_code
;
155 TRACE("byte_code %p, fourcc %x, data %p, size %p\n", byte_code
, fourcc
, data
, size
);
157 if (data
) *data
= NULL
;
160 if (!byte_code
) return D3DERR_INVALIDCALL
;
162 version
= *ptr
>> 16;
163 if (version
!= 0x4658 /* FX */
164 && version
!= 0x5458 /* TX */
167 && version
!= 0xfffe /* VS */
168 && version
!= 0xffff) /* PS */
170 WARN("Invalid data supplied\n");
171 return D3DXERR_INVALIDDATA
;
174 while (*++ptr
!= D3DSIO_END
)
176 /* Check if it is a comment */
177 if ((*ptr
& D3DSI_OPCODE_MASK
) == D3DSIO_COMMENT
)
179 DWORD comment_size
= (*ptr
& D3DSI_COMMENTSIZE_MASK
) >> D3DSI_COMMENTSIZE_SHIFT
;
181 /* Check if this is the comment we are looking for */
182 if (*(ptr
+ 1) == fourcc
)
184 UINT ctab_size
= (comment_size
- 1) * sizeof(DWORD
);
185 const void *ctab_data
= ptr
+ 2;
190 TRACE("Returning comment data at %p with size %d\n", ctab_data
, ctab_size
);
200 HRESULT WINAPI
D3DXAssembleShader(const char *data
, UINT data_len
, const D3DXMACRO
*defines
,
201 ID3DXInclude
*include
, DWORD flags
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
205 TRACE("data %p, data_len %u, defines %p, include %p, flags %#x, shader %p, error_messages %p\n",
206 data
, data_len
, defines
, include
, flags
, shader
, error_messages
);
208 /* Forward to d3dcompiler: the parameter types aren't really different,
209 the actual data types are equivalent */
210 hr
= D3DAssemble(data
, data_len
, NULL
, (D3D_SHADER_MACRO
*)defines
,
211 (ID3DInclude
*)include
, flags
, (ID3DBlob
**)shader
,
212 (ID3DBlob
**)error_messages
);
214 if(hr
== E_FAIL
) hr
= D3DXERR_INVALIDDATA
;
218 static const void *main_file_data
;
220 static CRITICAL_SECTION_DEBUG from_file_mutex_debug
=
222 0, 0, &from_file_mutex
,
224 &from_file_mutex_debug
.ProcessLocksList
,
225 &from_file_mutex_debug
.ProcessLocksList
227 0, 0, {(DWORD_PTR
)(__FILE__
": from_file_mutex")}
229 CRITICAL_SECTION from_file_mutex
= {&from_file_mutex_debug
, -1, 0, 0, 0, 0};
231 /* D3DXInclude private implementation, used to implement
232 * D3DXAssembleShaderFromFile() from D3DXAssembleShader(). */
233 /* To be able to correctly resolve include search paths we have to store the
234 * pathname of each include file. We store the pathname pointer right before
236 static HRESULT WINAPI
d3dx_include_from_file_open(ID3DXInclude
*iface
, D3DXINCLUDE_TYPE include_type
,
237 const char *filename
, const void *parent_data
, const void **data
, UINT
*bytes
)
239 const char *p
, *parent_name
= "";
240 char *pathname
= NULL
, *ptr
;
241 char **buffer
= NULL
;
247 parent_name
= *((const char **)parent_data
- 1);
252 parent_name
= *((const char **)main_file_data
- 1);
255 TRACE("Looking up include file %s, parent %s.\n", debugstr_a(filename
), debugstr_a(parent_name
));
257 if ((p
= strrchr(parent_name
, '\\')))
261 pathname
= HeapAlloc(GetProcessHeap(), 0, (p
- parent_name
) + strlen(filename
) + 1);
263 return HRESULT_FROM_WIN32(GetLastError());
265 memcpy(pathname
, parent_name
, p
- parent_name
);
266 strcpy(pathname
+ (p
- parent_name
), filename
);
267 ptr
= pathname
+ (p
- parent_name
);
275 file
= CreateFileA(pathname
, GENERIC_READ
, FILE_SHARE_READ
, 0, OPEN_EXISTING
, 0, 0);
276 if(file
== INVALID_HANDLE_VALUE
)
279 TRACE("Include file found at pathname = %s\n", debugstr_a(pathname
));
281 size
= GetFileSize(file
, NULL
);
282 if(size
== INVALID_FILE_SIZE
)
285 buffer
= HeapAlloc(GetProcessHeap(), 0, size
+ sizeof(char *));
289 if(!ReadFile(file
, buffer
+ 1, size
, bytes
, NULL
))
294 main_file_data
= *data
;
301 HeapFree(GetProcessHeap(), 0, pathname
);
302 HeapFree(GetProcessHeap(), 0, buffer
);
303 return HRESULT_FROM_WIN32(GetLastError());
306 static HRESULT WINAPI
d3dx_include_from_file_close(ID3DXInclude
*iface
, const void *data
)
308 HeapFree(GetProcessHeap(), 0, *((char **)data
- 1));
309 HeapFree(GetProcessHeap(), 0, (char **)data
- 1);
310 if (main_file_data
== data
)
311 main_file_data
= NULL
;
315 const struct ID3DXIncludeVtbl d3dx_include_from_file_vtbl
=
317 d3dx_include_from_file_open
,
318 d3dx_include_from_file_close
321 HRESULT WINAPI
D3DXAssembleShaderFromFileA(const char *filename
, const D3DXMACRO
*defines
,
322 ID3DXInclude
*include
, DWORD flags
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
328 TRACE("filename %s, defines %p, include %p, flags %#x, shader %p, error_messages %p.\n",
329 debugstr_a(filename
), defines
, include
, flags
, shader
, error_messages
);
331 if (!filename
) return D3DXERR_INVALIDDATA
;
333 len
= MultiByteToWideChar(CP_ACP
, 0, filename
, -1, NULL
, 0);
334 filename_w
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
335 if (!filename_w
) return E_OUTOFMEMORY
;
336 MultiByteToWideChar(CP_ACP
, 0, filename
, -1, filename_w
, len
);
338 ret
= D3DXAssembleShaderFromFileW(filename_w
, defines
, include
, flags
, shader
, error_messages
);
340 HeapFree(GetProcessHeap(), 0, filename_w
);
344 HRESULT WINAPI
D3DXAssembleShaderFromFileW(const WCHAR
*filename
, const D3DXMACRO
*defines
,
345 ID3DXInclude
*include
, DWORD flags
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
350 struct d3dx_include_from_file include_from_file
;
353 TRACE("filename %s, defines %p, include %p, flags %#x, shader %p, error_messages %p.\n",
354 debugstr_w(filename
), defines
, include
, flags
, shader
, error_messages
);
358 include_from_file
.ID3DXInclude_iface
.lpVtbl
= &d3dx_include_from_file_vtbl
;
359 include
= &include_from_file
.ID3DXInclude_iface
;
362 len
= WideCharToMultiByte(CP_ACP
, 0, filename
, -1, NULL
, 0, NULL
, NULL
);
363 filename_a
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(char));
365 return E_OUTOFMEMORY
;
366 WideCharToMultiByte(CP_ACP
, 0, filename
, -1, filename_a
, len
, NULL
, NULL
);
368 EnterCriticalSection(&from_file_mutex
);
369 hr
= ID3DXInclude_Open(include
, D3DXINC_LOCAL
, filename_a
, NULL
, &buffer
, &len
);
372 LeaveCriticalSection(&from_file_mutex
);
373 HeapFree(GetProcessHeap(), 0, filename_a
);
374 return D3DXERR_INVALIDDATA
;
377 hr
= D3DXAssembleShader(buffer
, len
, defines
, include
, flags
, shader
, error_messages
);
379 ID3DXInclude_Close(include
, buffer
);
380 LeaveCriticalSection(&from_file_mutex
);
381 HeapFree(GetProcessHeap(), 0, filename_a
);
385 HRESULT WINAPI
D3DXAssembleShaderFromResourceA(HMODULE module
, const char *resource
, const D3DXMACRO
*defines
,
386 ID3DXInclude
*include
, DWORD flags
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
392 TRACE("module %p, resource %s, defines %p, include %p, flags %#x, shader %p, error_messages %p.\n",
393 module
, debugstr_a(resource
), defines
, include
, flags
, shader
, error_messages
);
395 if (!(res
= FindResourceA(module
, resource
, (const char *)RT_RCDATA
)))
396 return D3DXERR_INVALIDDATA
;
397 if (FAILED(load_resource_into_memory(module
, res
, &buffer
, &len
)))
398 return D3DXERR_INVALIDDATA
;
399 return D3DXAssembleShader(buffer
, len
, defines
, include
, flags
,
400 shader
, error_messages
);
403 HRESULT WINAPI
D3DXAssembleShaderFromResourceW(HMODULE module
, const WCHAR
*resource
, const D3DXMACRO
*defines
,
404 ID3DXInclude
*include
, DWORD flags
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
410 TRACE("module %p, resource %s, defines %p, include %p, flags %#x, shader %p, error_messages %p.\n",
411 module
, debugstr_w(resource
), defines
, include
, flags
, shader
, error_messages
);
413 if (!(res
= FindResourceW(module
, resource
, (const WCHAR
*)RT_RCDATA
)))
414 return D3DXERR_INVALIDDATA
;
415 if (FAILED(load_resource_into_memory(module
, res
, &buffer
, &len
)))
416 return D3DXERR_INVALIDDATA
;
417 return D3DXAssembleShader(buffer
, len
, defines
, include
, flags
,
418 shader
, error_messages
);
421 HRESULT WINAPI
D3DXCompileShader(const char *data
, UINT length
, const D3DXMACRO
*defines
,
422 ID3DXInclude
*include
, const char *function
, const char *profile
, DWORD flags
,
423 ID3DXBuffer
**shader
, ID3DXBuffer
**error_msgs
, ID3DXConstantTable
**constant_table
)
427 TRACE("data %s, length %u, defines %p, include %p, function %s, profile %s, "
428 "flags %#x, shader %p, error_msgs %p, constant_table %p.\n",
429 debugstr_a(data
), length
, defines
, include
, debugstr_a(function
), debugstr_a(profile
),
430 flags
, shader
, error_msgs
, constant_table
);
432 if (D3DX_SDK_VERSION
<= 36)
433 flags
|= D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY
;
435 hr
= D3DCompile(data
, length
, NULL
, (D3D_SHADER_MACRO
*)defines
, (ID3DInclude
*)include
,
436 function
, profile
, flags
, 0, (ID3DBlob
**)shader
, (ID3DBlob
**)error_msgs
);
438 if (SUCCEEDED(hr
) && constant_table
)
440 hr
= D3DXGetShaderConstantTable(ID3DXBuffer_GetBufferPointer(*shader
), constant_table
);
443 ID3DXBuffer_Release(*shader
);
448 /* Filter out D3DCompile warning messages that are not present with D3DCompileShader */
449 if (SUCCEEDED(hr
) && error_msgs
&& *error_msgs
)
451 char *messages
= ID3DXBuffer_GetBufferPointer(*error_msgs
);
452 DWORD size
= ID3DXBuffer_GetBufferSize(*error_msgs
);
454 /* Ensure messages are null terminated for safe processing */
455 if (size
) messages
[size
- 1] = 0;
461 /* Warning has the form "warning X3206: ... implicit truncation of vector type"
462 but we only search for "X3206:" in case d3dcompiler_43 has localization */
463 prev
= next
= strstr(messages
, "X3206:");
466 /* get pointer to beginning and end of current line */
467 while (prev
> messages
&& *(prev
- 1) != '\n') prev
--;
468 while (next
< messages
+ size
- 1 && *next
!= '\n') next
++;
469 if (next
< messages
+ size
- 1 && *next
== '\n') next
++;
471 memmove(prev
, next
, messages
+ size
- next
);
472 size
-= (next
- prev
);
475 /* Only return a buffer if the resulting string is not empty as some apps depend on that */
478 ID3DXBuffer_Release(*error_msgs
);
486 HRESULT WINAPI
D3DXCompileShaderFromFileA(const char *filename
, const D3DXMACRO
*defines
,
487 ID3DXInclude
*include
, const char *entrypoint
, const char *profile
, DWORD flags
,
488 ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
, ID3DXConstantTable
**constant_table
)
494 TRACE("filename %s, defines %p, include %p, entrypoint %s, profile %s, "
495 "flags %#x, shader %p, error_messages %p, constant_table %p.\n",
496 debugstr_a(filename
), defines
, include
, debugstr_a(entrypoint
),
497 debugstr_a(profile
), flags
, shader
, error_messages
, constant_table
);
499 if (!filename
) return D3DXERR_INVALIDDATA
;
501 len
= MultiByteToWideChar(CP_ACP
, 0, filename
, -1, NULL
, 0);
502 filename_w
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
503 if (!filename_w
) return E_OUTOFMEMORY
;
504 MultiByteToWideChar(CP_ACP
, 0, filename
, -1, filename_w
, len
);
506 ret
= D3DXCompileShaderFromFileW(filename_w
, defines
, include
,
507 entrypoint
, profile
, flags
,
508 shader
, error_messages
, constant_table
);
510 HeapFree(GetProcessHeap(), 0, filename_w
);
514 HRESULT WINAPI
D3DXCompileShaderFromFileW(const WCHAR
*filename
, const D3DXMACRO
*defines
,
515 ID3DXInclude
*include
, const char *entrypoint
, const char *profile
, DWORD flags
,
516 ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
, ID3DXConstantTable
**constant_table
)
519 DWORD len
, filename_len
;
521 struct d3dx_include_from_file include_from_file
;
524 TRACE("filename %s, defines %p, include %p, entrypoint %s, profile %s, "
525 "flags %#x, shader %p, error_messages %p, constant_table %p.\n",
526 debugstr_w(filename
), defines
, include
, debugstr_a(entrypoint
), debugstr_a(profile
),
527 flags
, shader
, error_messages
, constant_table
);
531 include_from_file
.ID3DXInclude_iface
.lpVtbl
= &d3dx_include_from_file_vtbl
;
532 include
= &include_from_file
.ID3DXInclude_iface
;
535 filename_len
= WideCharToMultiByte(CP_ACP
, 0, filename
, -1, NULL
, 0, NULL
, NULL
);
536 filename_a
= HeapAlloc(GetProcessHeap(), 0, filename_len
* sizeof(char));
538 return E_OUTOFMEMORY
;
539 WideCharToMultiByte(CP_ACP
, 0, filename
, -1, filename_a
, filename_len
, NULL
, NULL
);
541 EnterCriticalSection(&from_file_mutex
);
542 hr
= ID3DXInclude_Open(include
, D3DXINC_LOCAL
, filename_a
, NULL
, &buffer
, &len
);
545 LeaveCriticalSection(&from_file_mutex
);
546 HeapFree(GetProcessHeap(), 0, filename_a
);
547 return D3DXERR_INVALIDDATA
;
550 if (D3DX_SDK_VERSION
<= 36)
551 flags
|= D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY
;
553 hr
= D3DCompile(buffer
, len
, filename_a
, (const D3D_SHADER_MACRO
*)defines
,
554 (ID3DInclude
*)include
, entrypoint
, profile
, flags
, 0,
555 (ID3DBlob
**)shader
, (ID3DBlob
**)error_messages
);
557 if (SUCCEEDED(hr
) && constant_table
)
558 hr
= D3DXGetShaderConstantTable(ID3DXBuffer_GetBufferPointer(*shader
),
561 ID3DXInclude_Close(include
, buffer
);
562 LeaveCriticalSection(&from_file_mutex
);
563 HeapFree(GetProcessHeap(), 0, filename_a
);
567 HRESULT WINAPI
D3DXCompileShaderFromResourceA(HMODULE module
, const char *resource
, const D3DXMACRO
*defines
,
568 ID3DXInclude
*include
, const char *entrypoint
, const char *profile
, DWORD flags
,
569 ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
, ID3DXConstantTable
**constant_table
)
575 TRACE("module %p, resource %s, defines %p, include %p, entrypoint %s, profile %s, "
576 "flags %#x, shader %p, error_messages %p, constant_table %p.\n",
577 module
, debugstr_a(resource
), defines
, include
, debugstr_a(entrypoint
), debugstr_a(profile
),
578 flags
, shader
, error_messages
, constant_table
);
580 if (!(res
= FindResourceA(module
, resource
, (const char *)RT_RCDATA
)))
581 return D3DXERR_INVALIDDATA
;
582 if (FAILED(load_resource_into_memory(module
, res
, &buffer
, &len
)))
583 return D3DXERR_INVALIDDATA
;
584 return D3DXCompileShader(buffer
, len
, defines
, include
, entrypoint
, profile
,
585 flags
, shader
, error_messages
, constant_table
);
588 HRESULT WINAPI
D3DXCompileShaderFromResourceW(HMODULE module
, const WCHAR
*resource
, const D3DXMACRO
*defines
,
589 ID3DXInclude
*include
, const char *entrypoint
, const char *profile
, DWORD flags
,
590 ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
, ID3DXConstantTable
**constant_table
)
596 TRACE("module %p, resource %s, defines %p, include %p, entrypoint %s, profile %s, "
597 "flags %#x, shader %p, error_messages %p, constant_table %p.\n",
598 module
, debugstr_w(resource
), defines
, include
, debugstr_a(entrypoint
), debugstr_a(profile
),
599 flags
, shader
, error_messages
, constant_table
);
601 if (!(res
= FindResourceW(module
, resource
, (const WCHAR
*)RT_RCDATA
)))
602 return D3DXERR_INVALIDDATA
;
603 if (FAILED(load_resource_into_memory(module
, res
, &buffer
, &len
)))
604 return D3DXERR_INVALIDDATA
;
605 return D3DXCompileShader(buffer
, len
, defines
, include
, entrypoint
, profile
,
606 flags
, shader
, error_messages
, constant_table
);
609 HRESULT WINAPI
D3DXPreprocessShader(const char *data
, UINT data_len
, const D3DXMACRO
*defines
,
610 ID3DXInclude
*include
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
612 TRACE("data %s, data_len %u, defines %p, include %p, shader %p, error_messages %p.\n",
613 debugstr_a(data
), data_len
, defines
, include
, shader
, error_messages
);
615 return D3DPreprocess(data
, data_len
, NULL
,
616 (const D3D_SHADER_MACRO
*)defines
, (ID3DInclude
*)include
,
617 (ID3DBlob
**)shader
, (ID3DBlob
**)error_messages
);
620 HRESULT WINAPI
D3DXPreprocessShaderFromFileA(const char *filename
, const D3DXMACRO
*defines
,
621 ID3DXInclude
*include
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
623 WCHAR
*filename_w
= NULL
;
627 TRACE("filename %s, defines %p, include %p, shader %p, error_messages %p.\n",
628 debugstr_a(filename
), defines
, include
, shader
, error_messages
);
630 if (!filename
) return D3DXERR_INVALIDDATA
;
632 len
= MultiByteToWideChar(CP_ACP
, 0, filename
, -1, NULL
, 0);
633 filename_w
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
634 if (!filename_w
) return E_OUTOFMEMORY
;
635 MultiByteToWideChar(CP_ACP
, 0, filename
, -1, filename_w
, len
);
637 ret
= D3DXPreprocessShaderFromFileW(filename_w
, defines
, include
, shader
, error_messages
);
639 HeapFree(GetProcessHeap(), 0, filename_w
);
643 HRESULT WINAPI
D3DXPreprocessShaderFromFileW(const WCHAR
*filename
, const D3DXMACRO
*defines
,
644 ID3DXInclude
*include
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
649 struct d3dx_include_from_file include_from_file
;
652 TRACE("filename %s, defines %p, include %p, shader %p, error_messages %p.\n",
653 debugstr_w(filename
), defines
, include
, shader
, error_messages
);
657 include_from_file
.ID3DXInclude_iface
.lpVtbl
= &d3dx_include_from_file_vtbl
;
658 include
= &include_from_file
.ID3DXInclude_iface
;
661 len
= WideCharToMultiByte(CP_ACP
, 0, filename
, -1, NULL
, 0, NULL
, NULL
);
662 filename_a
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(char));
664 return E_OUTOFMEMORY
;
665 WideCharToMultiByte(CP_ACP
, 0, filename
, -1, filename_a
, len
, NULL
, NULL
);
667 EnterCriticalSection(&from_file_mutex
);
668 hr
= ID3DXInclude_Open(include
, D3DXINC_LOCAL
, filename_a
, NULL
, &buffer
, &len
);
671 LeaveCriticalSection(&from_file_mutex
);
672 HeapFree(GetProcessHeap(), 0, filename_a
);
673 return D3DXERR_INVALIDDATA
;
676 hr
= D3DPreprocess(buffer
, len
, NULL
,
677 (const D3D_SHADER_MACRO
*)defines
,
678 (ID3DInclude
*) include
,
679 (ID3DBlob
**)shader
, (ID3DBlob
**)error_messages
);
681 ID3DXInclude_Close(include
, buffer
);
682 LeaveCriticalSection(&from_file_mutex
);
683 HeapFree(GetProcessHeap(), 0, filename_a
);
687 HRESULT WINAPI
D3DXPreprocessShaderFromResourceA(HMODULE module
, const char *resource
, const D3DXMACRO
*defines
,
688 ID3DXInclude
*include
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
694 TRACE("module %p, resource %s, defines %p, include %p, shader %p, error_messages %p.\n",
695 module
, debugstr_a(resource
), defines
, include
, shader
, error_messages
);
697 if (!(res
= FindResourceA(module
, resource
, (const char *)RT_RCDATA
)))
698 return D3DXERR_INVALIDDATA
;
699 if (FAILED(load_resource_into_memory(module
, res
, &buffer
, &len
)))
700 return D3DXERR_INVALIDDATA
;
701 return D3DXPreprocessShader(buffer
, len
, defines
, include
,
702 shader
, error_messages
);
705 HRESULT WINAPI
D3DXPreprocessShaderFromResourceW(HMODULE module
, const WCHAR
*resource
, const D3DXMACRO
*defines
,
706 ID3DXInclude
*include
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
712 TRACE("module %p, resource %s, defines %p, include %p, shader %p, error_messages %p.\n",
713 module
, debugstr_w(resource
), defines
, include
, shader
, error_messages
);
715 if (!(res
= FindResourceW(module
, resource
, (const WCHAR
*)RT_RCDATA
)))
716 return D3DXERR_INVALIDDATA
;
717 if (FAILED(load_resource_into_memory(module
, res
, &buffer
, &len
)))
718 return D3DXERR_INVALIDDATA
;
719 return D3DXPreprocessShader(buffer
, len
, defines
, include
,
720 shader
, error_messages
);
724 struct ID3DXConstantTableImpl
{
725 ID3DXConstantTable ID3DXConstantTable_iface
;
729 D3DXCONSTANTTABLE_DESC desc
;
730 struct ctab_constant
*constants
;
733 static void free_constant(struct ctab_constant
*constant
)
735 if (constant
->constants
)
737 UINT i
, count
= constant
->desc
.Elements
> 1 ? constant
->desc
.Elements
: constant
->desc
.StructMembers
;
739 for (i
= 0; i
< count
; ++i
)
741 free_constant(&constant
->constants
[i
]);
743 HeapFree(GetProcessHeap(), 0, constant
->constants
);
747 static void free_constant_table(struct ID3DXConstantTableImpl
*table
)
749 if (table
->constants
)
753 for (i
= 0; i
< table
->desc
.Constants
; ++i
)
755 free_constant(&table
->constants
[i
]);
757 HeapFree(GetProcessHeap(), 0, table
->constants
);
759 HeapFree(GetProcessHeap(), 0, table
->ctab
);
762 static inline struct ID3DXConstantTableImpl
*impl_from_ID3DXConstantTable(ID3DXConstantTable
*iface
)
764 return CONTAINING_RECORD(iface
, struct ID3DXConstantTableImpl
, ID3DXConstantTable_iface
);
767 static inline BOOL
is_vertex_shader(DWORD version
)
769 return (version
& 0xffff0000) == 0xfffe0000;
772 static inline D3DXHANDLE
handle_from_constant(struct ctab_constant
*constant
)
774 return (D3DXHANDLE
)constant
;
777 static struct ctab_constant
*get_constant_by_name(struct ID3DXConstantTableImpl
*table
,
778 struct ctab_constant
*constant
, const char *name
);
780 static struct ctab_constant
*get_constant_element_by_name(struct ctab_constant
*constant
, const char *name
)
785 TRACE("constant %p, name %s\n", constant
, debugstr_a(name
));
787 if (!name
|| !*name
) return NULL
;
789 element
= atoi(name
);
790 part
= strchr(name
, ']') + 1;
792 if (constant
->desc
.Elements
> element
)
794 struct ctab_constant
*c
= constant
->constants
? &constant
->constants
[element
] : constant
;
799 return get_constant_by_name(NULL
, c
, part
);
802 return get_constant_element_by_name(c
, part
);
805 TRACE("Returning parameter %p\n", c
);
809 FIXME("Unhandled case \"%c\"\n", *--part
);
814 TRACE("Constant not found\n");
818 static struct ctab_constant
*get_constant_by_name(struct ID3DXConstantTableImpl
*table
,
819 struct ctab_constant
*constant
, const char *name
)
821 UINT i
, count
, length
;
822 struct ctab_constant
*handles
;
825 TRACE("table %p, constant %p, name %s\n", table
, constant
, debugstr_a(name
));
827 if (!name
|| !*name
) return NULL
;
831 count
= table
->desc
.Constants
;
832 handles
= table
->constants
;
836 count
= constant
->desc
.StructMembers
;
837 handles
= constant
->constants
;
840 length
= strcspn(name
, "[.");
841 part
= name
+ length
;
843 for (i
= 0; i
< count
; i
++)
845 if (strlen(handles
[i
].desc
.Name
) == length
&& !strncmp(handles
[i
].desc
.Name
, name
, length
))
850 return get_constant_by_name(NULL
, &handles
[i
], part
);
853 return get_constant_element_by_name(&handles
[i
], part
);
856 TRACE("Returning parameter %p\n", &handles
[i
]);
862 TRACE("Constant not found\n");
866 static struct ctab_constant
*is_valid_sub_constant(struct ctab_constant
*parent
, D3DXHANDLE handle
)
868 struct ctab_constant
*c
;
871 /* all variable have at least elements = 1, but not always elements */
872 if (!parent
->constants
) return NULL
;
874 count
= parent
->desc
.Elements
> 1 ? parent
->desc
.Elements
: parent
->desc
.StructMembers
;
875 for (i
= 0; i
< count
; ++i
)
877 if (handle_from_constant(&parent
->constants
[i
]) == handle
)
878 return &parent
->constants
[i
];
880 c
= is_valid_sub_constant(&parent
->constants
[i
], handle
);
887 static inline struct ctab_constant
*get_valid_constant(struct ID3DXConstantTableImpl
*table
, D3DXHANDLE handle
)
889 struct ctab_constant
*c
;
892 if (!handle
) return NULL
;
894 for (i
= 0; i
< table
->desc
.Constants
; ++i
)
896 if (handle_from_constant(&table
->constants
[i
]) == handle
)
897 return &table
->constants
[i
];
899 c
= is_valid_sub_constant(&table
->constants
[i
], handle
);
903 return get_constant_by_name(table
, NULL
, handle
);
906 /*** IUnknown methods ***/
907 static HRESULT WINAPI
ID3DXConstantTableImpl_QueryInterface(ID3DXConstantTable
*iface
, REFIID riid
, void **out
)
909 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
911 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
912 IsEqualGUID(riid
, &IID_ID3DXBuffer
) ||
913 IsEqualGUID(riid
, &IID_ID3DXConstantTable
))
915 ID3DXConstantTable_AddRef(iface
);
920 WARN("Interface %s not found.\n", debugstr_guid(riid
));
922 return E_NOINTERFACE
;
925 static ULONG WINAPI
ID3DXConstantTableImpl_AddRef(ID3DXConstantTable
*iface
)
927 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
929 TRACE("(%p)->(): AddRef from %d\n", This
, This
->ref
);
931 return InterlockedIncrement(&This
->ref
);
934 static ULONG WINAPI
ID3DXConstantTableImpl_Release(ID3DXConstantTable
*iface
)
936 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
937 ULONG ref
= InterlockedDecrement(&This
->ref
);
939 TRACE("(%p)->(): Release from %d\n", This
, ref
+ 1);
943 free_constant_table(This
);
944 HeapFree(GetProcessHeap(), 0, This
);
950 /*** ID3DXBuffer methods ***/
951 static void * WINAPI
ID3DXConstantTableImpl_GetBufferPointer(ID3DXConstantTable
*iface
)
953 struct ID3DXConstantTableImpl
*table
= impl_from_ID3DXConstantTable(iface
);
955 TRACE("iface %p.\n", iface
);
960 static DWORD WINAPI
ID3DXConstantTableImpl_GetBufferSize(ID3DXConstantTable
*iface
)
962 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
964 TRACE("(%p)->()\n", This
);
969 /*** ID3DXConstantTable methods ***/
970 static HRESULT WINAPI
ID3DXConstantTableImpl_GetDesc(ID3DXConstantTable
*iface
, D3DXCONSTANTTABLE_DESC
*desc
)
972 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
974 TRACE("(%p)->(%p)\n", This
, desc
);
977 return D3DERR_INVALIDCALL
;
984 const struct ctab_constant
*d3dx_shader_get_ctab_constant(ID3DXConstantTable
*iface
, D3DXHANDLE constant
)
986 struct ID3DXConstantTableImpl
*ctab
= impl_from_ID3DXConstantTable(iface
);
988 return get_valid_constant(ctab
, constant
);
991 static HRESULT WINAPI
ID3DXConstantTableImpl_GetConstantDesc(ID3DXConstantTable
*iface
, D3DXHANDLE constant
,
992 D3DXCONSTANT_DESC
*desc
, UINT
*count
)
994 struct ID3DXConstantTableImpl
*ctab
= impl_from_ID3DXConstantTable(iface
);
995 struct ctab_constant
*c
= get_valid_constant(ctab
, constant
);
997 TRACE("(%p)->(%p, %p, %p)\n", ctab
, constant
, desc
, count
);
1001 WARN("Invalid argument specified\n");
1002 return D3DERR_INVALIDCALL
;
1005 if (desc
) *desc
= c
->desc
;
1006 if (count
) *count
= 1;
1011 static UINT WINAPI
ID3DXConstantTableImpl_GetSamplerIndex(ID3DXConstantTable
*iface
, D3DXHANDLE constant
)
1013 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1014 struct ctab_constant
*c
= get_valid_constant(This
, constant
);
1016 TRACE("(%p)->(%p)\n", This
, constant
);
1018 if (!c
|| c
->desc
.RegisterSet
!= D3DXRS_SAMPLER
)
1020 WARN("Invalid argument specified\n");
1024 TRACE("Returning RegisterIndex %u\n", c
->desc
.RegisterIndex
);
1025 return c
->desc
.RegisterIndex
;
1028 static D3DXHANDLE WINAPI
ID3DXConstantTableImpl_GetConstant(ID3DXConstantTable
*iface
, D3DXHANDLE constant
, UINT index
)
1030 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1031 struct ctab_constant
*c
;
1033 TRACE("(%p)->(%p, %d)\n", This
, constant
, index
);
1037 c
= get_valid_constant(This
, constant
);
1038 if (c
&& index
< c
->desc
.StructMembers
)
1040 c
= &c
->constants
[index
];
1041 TRACE("Returning constant %p\n", c
);
1042 return handle_from_constant(c
);
1047 if (index
< This
->desc
.Constants
)
1049 c
= &This
->constants
[index
];
1050 TRACE("Returning constant %p\n", c
);
1051 return handle_from_constant(c
);
1055 WARN("Index out of range\n");
1059 static D3DXHANDLE WINAPI
ID3DXConstantTableImpl_GetConstantByName(ID3DXConstantTable
*iface
,
1060 D3DXHANDLE constant
, const char *name
)
1062 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1063 struct ctab_constant
*c
= get_valid_constant(This
, constant
);
1065 TRACE("iface %p, constant %p, name %s.\n", iface
, constant
, debugstr_a(name
));
1067 c
= get_constant_by_name(This
, c
, name
);
1068 TRACE("Returning constant %p\n", c
);
1070 return handle_from_constant(c
);
1073 static D3DXHANDLE WINAPI
ID3DXConstantTableImpl_GetConstantElement(ID3DXConstantTable
*iface
, D3DXHANDLE constant
, UINT index
)
1075 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1076 struct ctab_constant
*c
= get_valid_constant(This
, constant
);
1078 TRACE("(%p)->(%p, %d)\n", This
, constant
, index
);
1080 if (c
&& index
< c
->desc
.Elements
)
1082 if (c
->desc
.Elements
> 1) c
= &c
->constants
[index
];
1083 TRACE("Returning constant %p\n", c
);
1084 return handle_from_constant(c
);
1087 WARN("Invalid argument specified\n");
1091 static inline DWORD
get_index(const void **indata
, UINT index
, BOOL is_pointer
)
1097 return ((DWORD
**)indata
)[index
/ 16][index
% 16];
1099 return (*((DWORD
**)indata
))[index
];
1102 static UINT
set(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
, struct ctab_constant
*constant
,
1103 const void **indata
, D3DXPARAMETER_TYPE intype
, UINT
*size
, UINT incol
, D3DXPARAMETER_CLASS inclass
, UINT index
,
1106 D3DXCONSTANT_DESC
*desc
= &constant
->desc
;
1107 UINT l
, i
, regcount
= 1, regsize
= 1, cin
= 1, rin
= 1, ret
, last
= 0;
1110 /* size too small to set anything */
1111 if (*size
< desc
->Rows
* desc
->Columns
)
1117 /* D3DXPC_STRUCT is somewhat special */
1118 if (desc
->Class
== D3DXPC_STRUCT
)
1121 * Struct array sets the last complete input to the first struct element, all other
1122 * elements are not set.
1123 * E.g.: struct {int i;} s1[2];
1124 * SetValue(device, "s1", [1, 2], 8) => s1 = {2, x};
1126 * struct {int i; int n} s2[2];
1127 * SetValue(device, "s2", [1, 2, 3, 4, 5], 20) => s1 = {{3, 4}, {x, x}};
1129 if (desc
->Elements
> 1)
1131 UINT offset
= *size
/ (desc
->Rows
* desc
->Columns
) - 1;
1133 offset
= min(desc
->Elements
- 1, offset
);
1134 last
= offset
* desc
->Rows
* desc
->Columns
;
1136 if ((is_pointer
|| inclass
== D3DXPC_MATRIX_ROWS
) && desc
->RegisterSet
!= D3DXRS_BOOL
)
1138 set(table
, device
, &constant
->constants
[0], NULL
, intype
, size
, incol
, inclass
, 0, is_pointer
);
1142 last
+= set(table
, device
, &constant
->constants
[0], indata
, intype
, size
, incol
, inclass
,
1143 index
+ last
, is_pointer
);
1149 * D3DXRS_BOOL is always set. As there are only 16 bools and there are
1150 * exactly 16 input values, use matrix transpose.
1152 if (inclass
== D3DXPC_MATRIX_ROWS
&& desc
->RegisterSet
== D3DXRS_BOOL
)
1154 D3DXMATRIX mat
, *m
, min
;
1155 D3DXMatrixTranspose(&mat
, &min
);
1158 min
= *(D3DXMATRIX
*)(indata
[index
/ 16]);
1160 min
= **(D3DXMATRIX
**)indata
;
1162 D3DXMatrixTranspose(&mat
, &min
);
1164 for (i
= 0; i
< desc
->StructMembers
; ++i
)
1166 last
+= set(table
, device
, &constant
->constants
[i
], (const void **)&m
, intype
, size
, incol
,
1167 D3DXPC_SCALAR
, index
+ last
, is_pointer
);
1171 * For pointers or for matrix rows, only the first member is set.
1172 * All other members are set to 0. This is not true for D3DXRS_BOOL.
1173 * E.g.: struct {int i; int n} s;
1174 * SetValue(device, "s", [1, 2], 8) => s = {1, 0};
1176 else if ((is_pointer
|| inclass
== D3DXPC_MATRIX_ROWS
) && desc
->RegisterSet
!= D3DXRS_BOOL
)
1178 last
= set(table
, device
, &constant
->constants
[0], indata
, intype
, size
, incol
, inclass
,
1179 index
+ last
, is_pointer
);
1181 for (i
= 1; i
< desc
->StructMembers
; ++i
)
1183 set(table
, device
, &constant
->constants
[i
], NULL
, intype
, size
, incol
, inclass
, 0, is_pointer
);
1188 for (i
= 0; i
< desc
->StructMembers
; ++i
)
1190 last
+= set(table
, device
, &constant
->constants
[i
], indata
, intype
, size
, incol
, D3DXPC_SCALAR
,
1191 index
+ last
, is_pointer
);
1200 if (desc
->Elements
> 1)
1202 for (i
= 0; i
< desc
->Elements
&& *size
> 0; ++i
)
1204 last
+= set(table
, device
, &constant
->constants
[i
], indata
, intype
, size
, incol
, inclass
,
1205 index
+ last
, is_pointer
);
1207 /* adjust the vector size for matrix rows */
1208 if (inclass
== D3DXPC_MATRIX_ROWS
&& desc
->Class
== D3DXPC_VECTOR
&& (i
% 4) == 3)
1211 *size
= *size
< 12 ? 0 : *size
- 12;
1218 switch (desc
->Class
)
1222 case D3DXPC_MATRIX_ROWS
:
1223 regcount
= min(desc
->RegisterCount
, desc
->Rows
);
1224 if (inclass
== D3DXPC_MATRIX_ROWS
) cin
= incol
;
1226 regsize
= desc
->Columns
;
1229 case D3DXPC_MATRIX_COLUMNS
:
1230 regcount
= min(desc
->RegisterCount
, desc
->Columns
);
1231 if (inclass
== D3DXPC_MATRIX_ROWS
) rin
= incol
;
1233 regsize
= desc
->Rows
;
1237 FIXME("Unhandled variable class %s\n", debug_d3dxparameter_class(desc
->Class
));
1241 /* specific stuff for different in types */
1245 ret
= desc
->Columns
* desc
->Rows
;
1246 *size
-= desc
->Columns
* desc
->Rows
;
1250 switch (desc
->Class
)
1252 case D3DXPC_MATRIX_ROWS
:
1253 if (*size
< regcount
* 4)
1259 *size
-= 4 * regcount
;
1262 case D3DXPC_MATRIX_COLUMNS
:
1264 *size
-= 4 * regcount
;
1278 FIXME("Unhandled variable class %s\n", debug_d3dxparameter_class(desc
->Class
));
1283 case D3DXPC_MATRIX_ROWS
:
1284 switch (desc
->Class
)
1286 case D3DXPC_MATRIX_ROWS
:
1287 case D3DXPC_MATRIX_COLUMNS
:
1305 FIXME("Unhandled variable class %s\n", debug_d3dxparameter_class(desc
->Class
));
1311 case D3DXPC_MATRIX_COLUMNS
:
1312 switch (desc
->Class
)
1314 case D3DXPC_MATRIX_ROWS
:
1315 case D3DXPC_MATRIX_COLUMNS
:
1333 FIXME("Unhandled variable class %s\n", debug_d3dxparameter_class(desc
->Class
));
1340 FIXME("Unhandled variable class %s\n", debug_d3dxparameter_class(inclass
));
1344 /* set the registers */
1345 switch (desc
->RegisterSet
)
1348 regcount
= min(desc
->RegisterCount
, desc
->Columns
* desc
->Rows
);
1350 for (i
= 0; i
< regcount
; ++i
)
1353 DWORD t
= get_index(indata
, index
+ i
/ regsize
* rin
+ l
* cin
, is_pointer
);
1355 set_number(&tmp
, desc
->Type
, &t
, intype
);
1356 set_number(&out
, D3DXPT_BOOL
, &tmp
, desc
->Type
);
1357 if (is_vertex_shader(table
->desc
.Version
))
1358 IDirect3DDevice9_SetVertexShaderConstantB(device
, desc
->RegisterIndex
+ i
, &out
, 1);
1360 IDirect3DDevice9_SetPixelShaderConstantB(device
, desc
->RegisterIndex
+ i
, &out
, 1);
1362 if (++l
>= regsize
) l
= 0;
1367 for (i
= 0; i
< regcount
; ++i
)
1369 INT vec
[4] = {0, 0, 1, 0};
1371 for (l
= 0; l
< regsize
; ++l
)
1373 DWORD t
= get_index(indata
, index
+ i
* rin
+ l
* cin
, is_pointer
);
1375 set_number(&tmp
, desc
->Type
, &t
, intype
);
1376 set_number(&vec
[l
], D3DXPT_INT
, &tmp
, desc
->Type
);
1378 if (is_vertex_shader(table
->desc
.Version
))
1379 IDirect3DDevice9_SetVertexShaderConstantI(device
, desc
->RegisterIndex
+ i
, vec
, 1);
1381 IDirect3DDevice9_SetPixelShaderConstantI(device
, desc
->RegisterIndex
+ i
, vec
, 1);
1386 for (i
= 0; i
< regcount
; ++i
)
1390 for (l
= 0; l
< regsize
; ++l
)
1392 DWORD t
= get_index(indata
, index
+ i
* rin
+ l
* cin
, is_pointer
);
1394 set_number(&tmp
, desc
->Type
, &t
, intype
);
1395 set_number(&vec
[l
], D3DXPT_FLOAT
, &tmp
, desc
->Type
);
1397 if (is_vertex_shader(table
->desc
.Version
))
1398 IDirect3DDevice9_SetVertexShaderConstantF(device
, desc
->RegisterIndex
+ i
, vec
, 1);
1400 IDirect3DDevice9_SetPixelShaderConstantF(device
, desc
->RegisterIndex
+ i
, vec
, 1);
1405 FIXME("Unhandled register set %s\n", debug_d3dxparameter_registerset(desc
->RegisterSet
));
1410 static HRESULT
set_scalar(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
, D3DXHANDLE constant
,
1411 const void *indata
, D3DXPARAMETER_TYPE intype
)
1413 struct ctab_constant
*c
= get_valid_constant(table
, constant
);
1418 WARN("Invalid argument specified\n");
1419 return D3DERR_INVALIDCALL
;
1422 switch (c
->desc
.Class
)
1425 set(table
, device
, c
, &indata
, intype
, &count
, c
->desc
.Columns
, D3DXPC_SCALAR
, 0, FALSE
);
1429 case D3DXPC_MATRIX_ROWS
:
1430 case D3DXPC_MATRIX_COLUMNS
:
1435 FIXME("Unhandled parameter class %s\n", debug_d3dxparameter_class(c
->desc
.Class
));
1436 return D3DERR_INVALIDCALL
;
1440 static HRESULT
set_scalar_array(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
, D3DXHANDLE constant
,
1441 const void *indata
, UINT count
, D3DXPARAMETER_TYPE intype
)
1443 struct ctab_constant
*c
= get_valid_constant(table
, constant
);
1447 WARN("Invalid argument specified\n");
1448 return D3DERR_INVALIDCALL
;
1451 switch (c
->desc
.Class
)
1455 case D3DXPC_MATRIX_ROWS
:
1456 case D3DXPC_MATRIX_COLUMNS
:
1458 set(table
, device
, c
, &indata
, intype
, &count
, c
->desc
.Columns
, D3DXPC_SCALAR
, 0, FALSE
);
1462 FIXME("Unhandled parameter class %s\n", debug_d3dxparameter_class(c
->desc
.Class
));
1463 return D3DERR_INVALIDCALL
;
1467 static HRESULT
set_vector(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
, D3DXHANDLE constant
,
1468 const void *indata
, D3DXPARAMETER_TYPE intype
)
1470 struct ctab_constant
*c
= get_valid_constant(table
, constant
);
1475 WARN("Invalid argument specified\n");
1476 return D3DERR_INVALIDCALL
;
1479 switch (c
->desc
.Class
)
1484 set(table
, device
, c
, &indata
, intype
, &count
, 4, D3DXPC_VECTOR
, 0, FALSE
);
1487 case D3DXPC_MATRIX_ROWS
:
1488 case D3DXPC_MATRIX_COLUMNS
:
1492 FIXME("Unhandled parameter class %s\n", debug_d3dxparameter_class(c
->desc
.Class
));
1493 return D3DERR_INVALIDCALL
;
1497 static HRESULT
set_vector_array(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
, D3DXHANDLE constant
,
1498 const void *indata
, UINT count
, D3DXPARAMETER_TYPE intype
)
1500 struct ctab_constant
*c
= get_valid_constant(table
, constant
);
1504 WARN("Invalid argument specified\n");
1505 return D3DERR_INVALIDCALL
;
1508 switch (c
->desc
.Class
)
1512 case D3DXPC_MATRIX_ROWS
:
1513 case D3DXPC_MATRIX_COLUMNS
:
1516 set(table
, device
, c
, &indata
, intype
, &count
, 4, D3DXPC_VECTOR
, 0, FALSE
);
1520 FIXME("Unhandled parameter class %s\n", debug_d3dxparameter_class(c
->desc
.Class
));
1521 return D3DERR_INVALIDCALL
;
1525 static HRESULT
set_matrix_array(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
, D3DXHANDLE constant
,
1526 const void *indata
, UINT count
, BOOL transpose
)
1528 struct ctab_constant
*c
= get_valid_constant(table
, constant
);
1532 WARN("Invalid argument specified\n");
1533 return D3DERR_INVALIDCALL
;
1536 switch (c
->desc
.Class
)
1540 case D3DXPC_MATRIX_ROWS
:
1541 case D3DXPC_MATRIX_COLUMNS
:
1544 set(table
, device
, c
, &indata
, D3DXPT_FLOAT
, &count
, 4,
1545 transpose
? D3DXPC_MATRIX_ROWS
: D3DXPC_MATRIX_COLUMNS
, 0, FALSE
);
1549 FIXME("Unhandled parameter class %s\n", debug_d3dxparameter_class(c
->desc
.Class
));
1550 return D3DERR_INVALIDCALL
;
1554 static HRESULT
set_matrix_pointer_array(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
,
1555 D3DXHANDLE constant
, const void **indata
, UINT count
, BOOL transpose
)
1557 struct ctab_constant
*c
= get_valid_constant(table
, constant
);
1561 WARN("Invalid argument specified\n");
1562 return D3DERR_INVALIDCALL
;
1565 switch (c
->desc
.Class
)
1569 case D3DXPC_MATRIX_ROWS
:
1570 case D3DXPC_MATRIX_COLUMNS
:
1573 set(table
, device
, c
, indata
, D3DXPT_FLOAT
, &count
, 4,
1574 transpose
? D3DXPC_MATRIX_ROWS
: D3DXPC_MATRIX_COLUMNS
, 0, TRUE
);
1578 FIXME("Unhandled parameter class %s\n", debug_d3dxparameter_class(c
->desc
.Class
));
1579 return D3DERR_INVALIDCALL
;
1583 static HRESULT WINAPI
ID3DXConstantTableImpl_SetDefaults(struct ID3DXConstantTable
*iface
,
1584 struct IDirect3DDevice9
*device
)
1586 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1589 TRACE("iface %p, device %p\n", iface
, device
);
1593 WARN("Invalid argument specified\n");
1594 return D3DERR_INVALIDCALL
;
1597 for (i
= 0; i
< This
->desc
.Constants
; i
++)
1599 D3DXCONSTANT_DESC
*desc
= &This
->constants
[i
].desc
;
1602 if (!desc
->DefaultValue
)
1605 switch (desc
->RegisterSet
)
1608 if (is_vertex_shader(This
->desc
.Version
))
1609 hr
= IDirect3DDevice9_SetVertexShaderConstantB(device
, desc
->RegisterIndex
, desc
->DefaultValue
,
1610 desc
->RegisterCount
);
1612 hr
= IDirect3DDevice9_SetPixelShaderConstantB(device
, desc
->RegisterIndex
, desc
->DefaultValue
,
1613 desc
->RegisterCount
);
1617 if (is_vertex_shader(This
->desc
.Version
))
1618 hr
= IDirect3DDevice9_SetVertexShaderConstantI(device
, desc
->RegisterIndex
, desc
->DefaultValue
,
1619 desc
->RegisterCount
);
1621 hr
= IDirect3DDevice9_SetPixelShaderConstantI(device
, desc
->RegisterIndex
, desc
->DefaultValue
,
1622 desc
->RegisterCount
);
1626 if (is_vertex_shader(This
->desc
.Version
))
1627 hr
= IDirect3DDevice9_SetVertexShaderConstantF(device
, desc
->RegisterIndex
, desc
->DefaultValue
,
1628 desc
->RegisterCount
);
1630 hr
= IDirect3DDevice9_SetPixelShaderConstantF(device
, desc
->RegisterIndex
, desc
->DefaultValue
,
1631 desc
->RegisterCount
);
1635 FIXME("Unhandled register set %s\n", debug_d3dxparameter_registerset(desc
->RegisterSet
));
1647 static HRESULT WINAPI
ID3DXConstantTableImpl_SetValue(struct ID3DXConstantTable
*iface
,
1648 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const void *data
, unsigned int bytes
)
1650 struct ID3DXConstantTableImpl
*table
= impl_from_ID3DXConstantTable(iface
);
1651 struct ctab_constant
*c
= get_valid_constant(table
, constant
);
1652 D3DXCONSTANT_DESC
*desc
;
1654 TRACE("iface %p, device %p, constant %p, data %p, bytes %u\n", iface
, device
, constant
, data
, bytes
);
1656 if (!device
|| !c
|| !data
)
1658 WARN("Invalid argument specified\n");
1659 return D3DERR_INVALIDCALL
;
1664 switch (desc
->Class
)
1668 case D3DXPC_MATRIX_ROWS
:
1669 case D3DXPC_MATRIX_COLUMNS
:
1672 set(table
, device
, c
, &data
, desc
->Type
, &bytes
, desc
->Columns
, D3DXPC_SCALAR
, 0, FALSE
);
1676 FIXME("Unhandled parameter class %s\n", debug_d3dxparameter_class(desc
->Class
));
1677 return D3DERR_INVALIDCALL
;
1681 static HRESULT WINAPI
ID3DXConstantTableImpl_SetBool(struct ID3DXConstantTable
*iface
,
1682 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, BOOL b
)
1684 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1686 TRACE("iface %p, device %p, constant %p, b %d\n", iface
, device
, constant
, b
);
1688 return set_scalar(This
, device
, constant
, &b
, D3DXPT_BOOL
);
1691 static HRESULT WINAPI
ID3DXConstantTableImpl_SetBoolArray(struct ID3DXConstantTable
*iface
,
1692 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const BOOL
*b
, UINT count
)
1694 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1696 TRACE("iface %p, device %p, constant %p, b %p, count %d\n", iface
, device
, constant
, b
, count
);
1698 return set_scalar_array(This
, device
, constant
, b
, count
, D3DXPT_BOOL
);
1701 static HRESULT WINAPI
ID3DXConstantTableImpl_SetInt(struct ID3DXConstantTable
*iface
,
1702 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, INT n
)
1704 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1706 TRACE("iface %p, device %p, constant %p, n %d\n", iface
, device
, constant
, n
);
1708 return set_scalar(This
, device
, constant
, &n
, D3DXPT_INT
);
1711 static HRESULT WINAPI
ID3DXConstantTableImpl_SetIntArray(struct ID3DXConstantTable
*iface
,
1712 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const INT
*n
, UINT count
)
1714 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1716 TRACE("iface %p, device %p, constant %p, n %p, count %d\n", iface
, device
, constant
, n
, count
);
1718 return set_scalar_array(This
, device
, constant
, n
, count
, D3DXPT_INT
);
1721 static HRESULT WINAPI
ID3DXConstantTableImpl_SetFloat(struct ID3DXConstantTable
*iface
,
1722 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, float f
)
1724 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1726 TRACE("iface %p, device %p, constant %p, f %f\n", iface
, device
, constant
, f
);
1728 return set_scalar(This
, device
, constant
, &f
, D3DXPT_FLOAT
);
1731 static HRESULT WINAPI
ID3DXConstantTableImpl_SetFloatArray(struct ID3DXConstantTable
*iface
,
1732 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const float *f
, UINT count
)
1734 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1736 TRACE("iface %p, device %p, constant %p, f %p, count %d\n", iface
, device
, constant
, f
, count
);
1738 return set_scalar_array(This
, device
, constant
, f
, count
, D3DXPT_FLOAT
);
1741 static HRESULT WINAPI
ID3DXConstantTableImpl_SetVector(struct ID3DXConstantTable
*iface
,
1742 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXVECTOR4
*vector
)
1744 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1746 TRACE("iface %p, device %p, constant %p, vector %p\n", iface
, device
, constant
, vector
);
1748 return set_vector(This
, device
, constant
, vector
, D3DXPT_FLOAT
);
1751 static HRESULT WINAPI
ID3DXConstantTableImpl_SetVectorArray(struct ID3DXConstantTable
*iface
,
1752 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXVECTOR4
*vector
, UINT count
)
1754 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1756 TRACE("iface %p, device %p, constant %p, vector %p, count %u\n", iface
, device
, constant
, vector
, count
);
1758 return set_vector_array(This
, device
, constant
, vector
, count
, D3DXPT_FLOAT
);
1761 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrix(struct ID3DXConstantTable
*iface
,
1762 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXMATRIX
*matrix
)
1764 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1766 TRACE("iface %p, device %p, constant %p, matrix %p\n", iface
, device
, constant
, matrix
);
1768 return set_matrix_array(This
, device
, constant
, matrix
, 1, FALSE
);
1771 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrixArray(struct ID3DXConstantTable
*iface
,
1772 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXMATRIX
*matrix
, UINT count
)
1774 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1776 TRACE("iface %p, device %p, constant %p, matrix %p, count %u\n", iface
, device
, constant
, matrix
, count
);
1778 return set_matrix_array(This
, device
, constant
, matrix
, count
, FALSE
);
1781 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrixPointerArray(struct ID3DXConstantTable
*iface
,
1782 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXMATRIX
**matrix
, UINT count
)
1784 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1786 TRACE("iface %p, device %p, constant %p, matrix %p, count %u)\n", iface
, device
, constant
, matrix
, count
);
1788 return set_matrix_pointer_array(This
, device
, constant
, (const void **)matrix
, count
, FALSE
);
1791 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrixTranspose(struct ID3DXConstantTable
*iface
,
1792 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXMATRIX
*matrix
)
1794 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1796 TRACE("iface %p, device %p, constant %p, matrix %p\n", iface
, device
, constant
, matrix
);
1798 return set_matrix_array(This
, device
, constant
, matrix
, 1, TRUE
);
1801 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrixTransposeArray(struct ID3DXConstantTable
*iface
,
1802 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXMATRIX
*matrix
, UINT count
)
1804 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1806 TRACE("iface %p, device %p, constant %p, matrix %p, count %u\n", iface
, device
, constant
, matrix
, count
);
1808 return set_matrix_array(This
, device
, constant
, matrix
, count
, TRUE
);
1811 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrixTransposePointerArray(struct ID3DXConstantTable
*iface
,
1812 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXMATRIX
**matrix
, UINT count
)
1814 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1816 TRACE("iface %p, device %p, constant %p, matrix %p, count %u)\n", iface
, device
, constant
, matrix
, count
);
1818 return set_matrix_pointer_array(This
, device
, constant
, (const void **)matrix
, count
, TRUE
);
1821 static const struct ID3DXConstantTableVtbl ID3DXConstantTable_Vtbl
=
1823 /*** IUnknown methods ***/
1824 ID3DXConstantTableImpl_QueryInterface
,
1825 ID3DXConstantTableImpl_AddRef
,
1826 ID3DXConstantTableImpl_Release
,
1827 /*** ID3DXBuffer methods ***/
1828 ID3DXConstantTableImpl_GetBufferPointer
,
1829 ID3DXConstantTableImpl_GetBufferSize
,
1830 /*** ID3DXConstantTable methods ***/
1831 ID3DXConstantTableImpl_GetDesc
,
1832 ID3DXConstantTableImpl_GetConstantDesc
,
1833 ID3DXConstantTableImpl_GetSamplerIndex
,
1834 ID3DXConstantTableImpl_GetConstant
,
1835 ID3DXConstantTableImpl_GetConstantByName
,
1836 ID3DXConstantTableImpl_GetConstantElement
,
1837 ID3DXConstantTableImpl_SetDefaults
,
1838 ID3DXConstantTableImpl_SetValue
,
1839 ID3DXConstantTableImpl_SetBool
,
1840 ID3DXConstantTableImpl_SetBoolArray
,
1841 ID3DXConstantTableImpl_SetInt
,
1842 ID3DXConstantTableImpl_SetIntArray
,
1843 ID3DXConstantTableImpl_SetFloat
,
1844 ID3DXConstantTableImpl_SetFloatArray
,
1845 ID3DXConstantTableImpl_SetVector
,
1846 ID3DXConstantTableImpl_SetVectorArray
,
1847 ID3DXConstantTableImpl_SetMatrix
,
1848 ID3DXConstantTableImpl_SetMatrixArray
,
1849 ID3DXConstantTableImpl_SetMatrixPointerArray
,
1850 ID3DXConstantTableImpl_SetMatrixTranspose
,
1851 ID3DXConstantTableImpl_SetMatrixTransposeArray
,
1852 ID3DXConstantTableImpl_SetMatrixTransposePointerArray
1855 static HRESULT
parse_ctab_constant_type(const char *ctab
, DWORD typeoffset
, struct ctab_constant
*constant
,
1856 BOOL is_element
, WORD index
, WORD max_index
, DWORD
*offset
, DWORD nameoffset
, UINT regset
)
1858 const D3DXSHADER_TYPEINFO
*type
= (LPD3DXSHADER_TYPEINFO
)(ctab
+ typeoffset
);
1859 const D3DXSHADER_STRUCTMEMBERINFO
*memberinfo
= NULL
;
1860 HRESULT hr
= D3D_OK
;
1864 constant
->desc
.DefaultValue
= offset
? ctab
+ *offset
: NULL
;
1865 constant
->desc
.Class
= type
->Class
;
1866 constant
->desc
.Type
= type
->Type
;
1867 constant
->desc
.Rows
= type
->Rows
;
1868 constant
->desc
.Columns
= type
->Columns
;
1869 constant
->desc
.Elements
= is_element
? 1 : type
->Elements
;
1870 constant
->desc
.StructMembers
= type
->StructMembers
;
1871 constant
->desc
.Name
= ctab
+ nameoffset
;
1872 constant
->desc
.RegisterSet
= regset
;
1873 constant
->desc
.RegisterIndex
= index
;
1875 TRACE("name %s, elements %u, index %u, defaultvalue %p, regset %s\n", constant
->desc
.Name
,
1876 constant
->desc
.Elements
, index
, constant
->desc
.DefaultValue
,
1877 debug_d3dxparameter_registerset(regset
));
1878 TRACE("class %s, type %s, rows %d, columns %d, elements %d, struct_members %d\n",
1879 debug_d3dxparameter_class(type
->Class
), debug_d3dxparameter_type(type
->Type
),
1880 type
->Rows
, type
->Columns
, type
->Elements
, type
->StructMembers
);
1882 if (type
->Elements
> 1 && !is_element
)
1884 count
= type
->Elements
;
1886 else if ((type
->Class
== D3DXPC_STRUCT
) && type
->StructMembers
)
1888 memberinfo
= (D3DXSHADER_STRUCTMEMBERINFO
*)(ctab
+ type
->StructMemberInfo
);
1889 count
= type
->StructMembers
;
1894 constant
->constants
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*constant
->constants
) * count
);
1895 if (!constant
->constants
)
1897 ERR("Out of memory\n");
1902 for (i
= 0; i
< count
; ++i
)
1904 hr
= parse_ctab_constant_type(ctab
, memberinfo
? memberinfo
[i
].TypeInfo
: typeoffset
,
1905 &constant
->constants
[i
], memberinfo
== NULL
, index
+ size
, max_index
, offset
,
1906 memberinfo
? memberinfo
[i
].Name
: nameoffset
, regset
);
1910 size
+= constant
->constants
[i
].desc
.RegisterCount
;
1915 WORD offsetdiff
= type
->Columns
* type
->Rows
;
1918 size
= type
->Columns
* type
->Rows
;
1923 fail
= type
->Class
!= D3DXPC_SCALAR
&& type
->Class
!= D3DXPC_VECTOR
1924 && type
->Class
!= D3DXPC_MATRIX_ROWS
&& type
->Class
!= D3DXPC_MATRIX_COLUMNS
;
1929 switch (type
->Class
)
1935 offsetdiff
= type
->Rows
* 4;
1938 case D3DXPC_MATRIX_ROWS
:
1939 offsetdiff
= type
->Rows
* 4;
1943 case D3DXPC_MATRIX_COLUMNS
:
1944 offsetdiff
= type
->Columns
* 4;
1945 size
= type
->Columns
;
1954 case D3DXRS_SAMPLER
:
1956 fail
= type
->Class
!= D3DXPC_OBJECT
;
1966 FIXME("Unhandled register set %s, type class %s\n", debug_d3dxparameter_registerset(regset
),
1967 debug_d3dxparameter_class(type
->Class
));
1970 /* offset in bytes => offsetdiff * sizeof(DWORD) */
1971 if (offset
) *offset
+= offsetdiff
* 4;
1974 constant
->desc
.RegisterCount
= max(0, min(max_index
- index
, size
));
1975 constant
->desc
.Bytes
= 4 * constant
->desc
.Elements
* type
->Rows
* type
->Columns
;
1980 if (constant
->constants
)
1982 for (i
= 0; i
< count
; ++i
)
1984 free_constant(&constant
->constants
[i
]);
1986 HeapFree(GetProcessHeap(), 0, constant
->constants
);
1987 constant
->constants
= NULL
;
1993 HRESULT WINAPI
D3DXGetShaderConstantTableEx(const DWORD
*byte_code
, DWORD flags
, ID3DXConstantTable
**constant_table
)
1995 struct ID3DXConstantTableImpl
*object
= NULL
;
1999 const D3DXSHADER_CONSTANTTABLE
*ctab_header
;
2000 const D3DXSHADER_CONSTANTINFO
*constant_info
;
2003 TRACE("byte_code %p, flags %x, constant_table %p\n", byte_code
, flags
, constant_table
);
2005 if (constant_table
) *constant_table
= NULL
;
2007 if (!byte_code
|| !constant_table
)
2009 WARN("Invalid argument specified.\n");
2010 return D3DERR_INVALIDCALL
;
2013 if (!is_valid_bytecode(*byte_code
))
2015 WARN("Invalid byte_code specified.\n");
2019 if (flags
) FIXME("Flags (%#x) are not handled, yet!\n", flags
);
2021 hr
= D3DXFindShaderComment(byte_code
, MAKEFOURCC('C','T','A','B'), &data
, &size
);
2024 WARN("CTAB not found.\n");
2025 return D3DXERR_INVALIDDATA
;
2028 if (size
< sizeof(*ctab_header
))
2030 WARN("Invalid CTAB size.\n");
2031 return D3DXERR_INVALIDDATA
;
2034 ctab_header
= (const D3DXSHADER_CONSTANTTABLE
*)data
;
2035 if (ctab_header
->Size
!= sizeof(*ctab_header
))
2037 WARN("Invalid D3DXSHADER_CONSTANTTABLE size.\n");
2038 return D3DXERR_INVALIDDATA
;
2041 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*object
));
2043 return E_OUTOFMEMORY
;
2045 object
->ID3DXConstantTable_iface
.lpVtbl
= &ID3DXConstantTable_Vtbl
;
2048 object
->ctab
= HeapAlloc(GetProcessHeap(), 0, size
);
2051 ERR("Out of memory\n");
2052 HeapFree(GetProcessHeap(), 0, object
);
2053 return E_OUTOFMEMORY
;
2055 object
->size
= size
;
2056 memcpy(object
->ctab
, data
, object
->size
);
2058 object
->desc
.Creator
= ctab_header
->Creator
? object
->ctab
+ ctab_header
->Creator
: NULL
;
2059 object
->desc
.Version
= ctab_header
->Version
;
2060 object
->desc
.Constants
= ctab_header
->Constants
;
2061 TRACE("Creator %s, Version %x, Constants %u, Target %s\n",
2062 debugstr_a(object
->desc
.Creator
), object
->desc
.Version
, object
->desc
.Constants
,
2063 debugstr_a(ctab_header
->Target
? object
->ctab
+ ctab_header
->Target
: NULL
));
2065 object
->constants
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
2066 sizeof(*object
->constants
) * object
->desc
.Constants
);
2067 if (!object
->constants
)
2069 ERR("Out of memory\n");
2074 constant_info
= (const D3DXSHADER_CONSTANTINFO
*)(object
->ctab
+ ctab_header
->ConstantInfo
);
2075 for (i
= 0; i
< ctab_header
->Constants
; i
++)
2077 DWORD offset
= constant_info
[i
].DefaultValue
;
2079 hr
= parse_ctab_constant_type(object
->ctab
, constant_info
[i
].TypeInfo
,
2080 &object
->constants
[i
], FALSE
, constant_info
[i
].RegisterIndex
,
2081 constant_info
[i
].RegisterIndex
+ constant_info
[i
].RegisterCount
,
2082 offset
? &offset
: NULL
, constant_info
[i
].Name
, constant_info
[i
].RegisterSet
);
2087 * Set the register count, it may differ for D3DXRS_INT4, because somehow
2088 * it makes the assumption that the register size is 1 instead of 4, so the
2089 * count is 4 times bigger. This holds true only for toplevel shader
2090 * constants. The count of elements and members is always based on a
2091 * register size of 4.
2093 if (object
->constants
[i
].desc
.RegisterSet
== D3DXRS_INT4
)
2095 object
->constants
[i
].desc
.RegisterCount
= constant_info
[i
].RegisterCount
;
2097 object
->constants
[i
].constantinfo_reserved
= constant_info
[i
].Reserved
;
2100 *constant_table
= &object
->ID3DXConstantTable_iface
;
2105 free_constant_table(object
);
2106 HeapFree(GetProcessHeap(), 0, object
);
2111 HRESULT WINAPI
D3DXGetShaderConstantTable(const DWORD
*byte_code
, ID3DXConstantTable
**constant_table
)
2113 TRACE("(%p, %p): Forwarded to D3DXGetShaderConstantTableEx\n", byte_code
, constant_table
);
2115 return D3DXGetShaderConstantTableEx(byte_code
, 0, constant_table
);
2118 struct d3dx9_fragment_linker
2120 ID3DXFragmentLinker ID3DXFragmentLinker_iface
;
2123 struct IDirect3DDevice9
*device
;
2127 static inline struct d3dx9_fragment_linker
*impl_from_ID3DXFragmentLinker(ID3DXFragmentLinker
*iface
)
2129 return CONTAINING_RECORD(iface
, struct d3dx9_fragment_linker
, ID3DXFragmentLinker_iface
);
2132 static HRESULT WINAPI
d3dx9_fragment_linker_QueryInterface(ID3DXFragmentLinker
*iface
, REFIID riid
, void **out
)
2134 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
2136 if (IsEqualGUID(riid
, &IID_IUnknown
)
2137 || IsEqualGUID(riid
, &IID_ID3DXFragmentLinker
))
2139 iface
->lpVtbl
->AddRef(iface
);
2144 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
2146 return E_NOINTERFACE
;
2149 static ULONG WINAPI
d3dx9_fragment_linker_AddRef(ID3DXFragmentLinker
*iface
)
2151 struct d3dx9_fragment_linker
*linker
= impl_from_ID3DXFragmentLinker(iface
);
2152 ULONG refcount
= InterlockedIncrement(&linker
->ref
);
2154 TRACE("%p increasing refcount to %u.\n", linker
, refcount
);
2159 static ULONG WINAPI
d3dx9_fragment_linker_Release(ID3DXFragmentLinker
*iface
)
2161 struct d3dx9_fragment_linker
*linker
= impl_from_ID3DXFragmentLinker(iface
);
2162 ULONG refcount
= InterlockedDecrement(&linker
->ref
);
2164 TRACE("%p decreasing refcount to %u.\n", linker
, refcount
);
2168 IDirect3DDevice9_Release(linker
->device
);
2175 static HRESULT WINAPI
d3dx9_fragment_linker_GetDevice(ID3DXFragmentLinker
*iface
, struct IDirect3DDevice9
**device
)
2177 struct d3dx9_fragment_linker
*linker
= impl_from_ID3DXFragmentLinker(iface
);
2179 TRACE("iface %p, device %p.\n", linker
, device
);
2183 WARN("Invalid argument supplied.\n");
2184 return D3DERR_INVALIDCALL
;
2187 IDirect3DDevice9_AddRef(linker
->device
);
2188 *device
= linker
->device
;
2189 TRACE("Returning device %p.\n", *device
);
2194 static UINT WINAPI
d3dx9_fragment_linker_GetNumberOfFragments(ID3DXFragmentLinker
*iface
)
2196 FIXME("iface %p: stub.\n", iface
);
2201 static D3DXHANDLE WINAPI
d3dx9_fragment_linker_GetFragmentHandleByIndex(ID3DXFragmentLinker
*iface
, UINT index
)
2203 FIXME("iface %p, index %u: stub.\n", iface
, index
);
2208 static D3DXHANDLE WINAPI
d3dx9_fragment_linker_GetFragmentHandleByName(ID3DXFragmentLinker
*iface
,
2211 FIXME("iface %p, name %s: stub.\n", iface
, debugstr_a(name
));
2216 static HRESULT WINAPI
d3dx9_fragment_linker_GetFragmentDesc(ID3DXFragmentLinker
*iface
, D3DXHANDLE name
,
2217 D3DXFRAGMENT_DESC
*desc
)
2219 FIXME("iface %p, name %p, desc %p: stub.\n", iface
, name
, desc
);
2224 static HRESULT WINAPI
d3dx9_fragment_linker_AddFragments(ID3DXFragmentLinker
*iface
, const DWORD
*fragments
)
2226 FIXME("iface %p, fragments %p: stub.\n", iface
, fragments
);
2231 static HRESULT WINAPI
d3dx9_fragment_linker_GetAllFragments(ID3DXFragmentLinker
*iface
, ID3DXBuffer
**buffer
)
2233 FIXME("iface %p, buffer %p: stub.\n", iface
, buffer
);
2238 static HRESULT WINAPI
d3dx9_fragment_linker_GetFragment(ID3DXFragmentLinker
*iface
, D3DXHANDLE name
,
2239 ID3DXBuffer
**buffer
)
2241 FIXME("iface %p, name %p, buffer %p: stub.\n", iface
, name
, buffer
);
2246 static HRESULT WINAPI
d3dx9_fragment_linker_LinkShader(ID3DXFragmentLinker
*iface
, const char *profile
,
2247 DWORD flags
, const D3DXHANDLE
*handles
, UINT fragment_count
, ID3DXBuffer
**buffer
,
2248 ID3DXBuffer
**errors
)
2250 FIXME("iface %p, profile %s, flags %#x, handles %p, fragment_count %u, buffer %p, errors %p: stub.\n",
2251 iface
, debugstr_a(profile
), flags
, handles
, fragment_count
, buffer
, errors
);
2256 static HRESULT WINAPI
d3dx9_fragment_linker_LinkVertexShader(ID3DXFragmentLinker
*iface
, const char *profile
,
2257 DWORD flags
, const D3DXHANDLE
*handles
, UINT fragment_count
, IDirect3DVertexShader9
**shader
,
2258 ID3DXBuffer
**errors
)
2260 FIXME("iface %p, profile %s, flags %#x, handles %p, fragment_count %u, shader %p, errors %p: stub.\n",
2261 iface
, debugstr_a(profile
), flags
, handles
, fragment_count
, shader
, errors
);
2266 static HRESULT WINAPI
d3dx9_fragment_linker_LinkPixelShader(ID3DXFragmentLinker
*iface
, const char *profile
,
2267 DWORD flags
, const D3DXHANDLE
*handles
, UINT fragment_count
, IDirect3DPixelShader9
**shader
,
2268 ID3DXBuffer
**errors
)
2270 FIXME("iface %p, profile %s, flags %#x, handles %p, fragment_count %u, shader %p, errors %p: stub.\n",
2271 iface
, debugstr_a(profile
), flags
, handles
, fragment_count
, shader
, errors
);
2276 static HRESULT WINAPI
d3dx9_fragment_linker_ClearCache(ID3DXFragmentLinker
*iface
)
2278 FIXME("iface %p: stub.\n", iface
);
2283 static const struct ID3DXFragmentLinkerVtbl d3dx9_fragment_linker_vtbl
=
2285 d3dx9_fragment_linker_QueryInterface
,
2286 d3dx9_fragment_linker_AddRef
,
2287 d3dx9_fragment_linker_Release
,
2288 d3dx9_fragment_linker_GetDevice
,
2289 d3dx9_fragment_linker_GetNumberOfFragments
,
2290 d3dx9_fragment_linker_GetFragmentHandleByIndex
,
2291 d3dx9_fragment_linker_GetFragmentHandleByName
,
2292 d3dx9_fragment_linker_GetFragmentDesc
,
2293 d3dx9_fragment_linker_AddFragments
,
2294 d3dx9_fragment_linker_GetAllFragments
,
2295 d3dx9_fragment_linker_GetFragment
,
2296 d3dx9_fragment_linker_LinkShader
,
2297 d3dx9_fragment_linker_LinkVertexShader
,
2298 d3dx9_fragment_linker_LinkPixelShader
,
2299 d3dx9_fragment_linker_ClearCache
2302 HRESULT WINAPI
D3DXCreateFragmentLinkerEx(IDirect3DDevice9
*device
, UINT size
, DWORD flags
,
2303 ID3DXFragmentLinker
**linker
)
2305 struct d3dx9_fragment_linker
*object
;
2307 TRACE("device %p, size %u, flags %#x, linker %p.\n", device
, size
, flags
, linker
);
2309 object
= heap_alloc(sizeof(*object
));
2311 return E_OUTOFMEMORY
;
2313 object
->ID3DXFragmentLinker_iface
.lpVtbl
= &d3dx9_fragment_linker_vtbl
;
2316 IDirect3DDevice9_AddRef(device
);
2317 object
->device
= device
;
2318 object
->flags
= flags
;
2320 *linker
= &object
->ID3DXFragmentLinker_iface
;
2325 HRESULT WINAPI
D3DXCreateFragmentLinker(IDirect3DDevice9
*device
, UINT size
, ID3DXFragmentLinker
**linker
)
2327 TRACE("device %p, size %u, linker %p.\n", device
, size
, linker
);
2329 return D3DXCreateFragmentLinkerEx(device
, size
, 0, linker
);
2332 HRESULT WINAPI
D3DXGetShaderSamplers(const DWORD
*byte_code
, const char **samplers
, UINT
*count
)
2334 UINT i
, sampler_count
= 0;
2337 const D3DXSHADER_CONSTANTTABLE
*ctab_header
;
2338 const D3DXSHADER_CONSTANTINFO
*constant_info
;
2340 TRACE("byte_code %p, samplers %p, count %p\n", byte_code
, samplers
, count
);
2342 if (count
) *count
= 0;
2344 if (D3DXFindShaderComment(byte_code
, MAKEFOURCC('C','T','A','B'), (const void **)&data
, &size
) != D3D_OK
)
2347 if (size
< sizeof(*ctab_header
)) return D3D_OK
;
2349 ctab_header
= (const D3DXSHADER_CONSTANTTABLE
*)data
;
2350 if (ctab_header
->Size
!= sizeof(*ctab_header
)) return D3D_OK
;
2352 constant_info
= (const D3DXSHADER_CONSTANTINFO
*)(data
+ ctab_header
->ConstantInfo
);
2353 for (i
= 0; i
< ctab_header
->Constants
; i
++)
2355 const D3DXSHADER_TYPEINFO
*type
;
2357 TRACE("name = %s\n", data
+ constant_info
[i
].Name
);
2359 type
= (const D3DXSHADER_TYPEINFO
*)(data
+ constant_info
[i
].TypeInfo
);
2361 if (type
->Type
== D3DXPT_SAMPLER
2362 || type
->Type
== D3DXPT_SAMPLER1D
2363 || type
->Type
== D3DXPT_SAMPLER2D
2364 || type
->Type
== D3DXPT_SAMPLER3D
2365 || type
->Type
== D3DXPT_SAMPLERCUBE
)
2367 if (samplers
) samplers
[sampler_count
] = data
+ constant_info
[i
].Name
;
2373 TRACE("Found %u samplers\n", sampler_count
);
2375 if (count
) *count
= sampler_count
;
2381 static const char *decl_usage
[] = { "position", "blendweight", "blendindices", "normal", "psize", "texcoord",
2382 "tangent", "binormal", "tessfactor", "positiont", "color" };
2384 static const char *tex_type
[] = { "", "1d", "2d", "cube", "volume" };
2386 static int add_modifier(char *buffer
, DWORD param
)
2389 DWORD dst_mod
= param
& D3DSP_DSTMOD_MASK
;
2391 if (dst_mod
& D3DSPDM_SATURATE
)
2392 buf
+= sprintf(buf
, "_sat");
2393 if (dst_mod
& D3DSPDM_PARTIALPRECISION
)
2394 buf
+= sprintf(buf
, "_pp");
2395 if (dst_mod
& D3DSPDM_MSAMPCENTROID
)
2396 buf
+= sprintf(buf
, "_centroid");
2398 return buf
- buffer
;
2401 static int add_register(char *buffer
, DWORD param
, BOOL dst
, BOOL ps
)
2404 DWORD reg_type
= ((param
& D3DSP_REGTYPE_MASK2
) >> D3DSP_REGTYPE_SHIFT2
)
2405 | ((param
& D3DSP_REGTYPE_MASK
) >> D3DSP_REGTYPE_SHIFT
);
2406 DWORD reg_num
= param
& D3DSP_REGNUM_MASK
;
2408 if (reg_type
== D3DSPR_INPUT
)
2409 buf
+= sprintf(buf
, "v%d", reg_num
);
2410 else if (reg_type
== D3DSPR_CONST
)
2411 buf
+= sprintf(buf
, "c%d", reg_num
);
2412 else if (reg_type
== D3DSPR_TEMP
)
2413 buf
+= sprintf(buf
, "r%d", reg_num
);
2414 else if (reg_type
== D3DSPR_ADDR
)
2415 buf
+= sprintf(buf
, "%s%d", ps
? "t" : "a", reg_num
);
2416 else if (reg_type
== D3DSPR_SAMPLER
)
2417 buf
+= sprintf(buf
, "s%d", reg_num
);
2418 else if (reg_type
== D3DSPR_RASTOUT
)
2419 buf
+= sprintf(buf
, "oPos");
2420 else if (reg_type
== D3DSPR_COLOROUT
)
2421 buf
+= sprintf(buf
, "oC%d", reg_num
);
2422 else if (reg_type
== D3DSPR_TEXCRDOUT
)
2423 buf
+= sprintf(buf
, "oT%d", reg_num
);
2424 else if (reg_type
== D3DSPR_ATTROUT
)
2425 buf
+= sprintf(buf
, "oD%d", reg_num
);
2427 buf
+= sprintf(buf
, "? (%d)", reg_type
);
2431 if ((param
& D3DSP_WRITEMASK_ALL
) != D3DSP_WRITEMASK_ALL
)
2433 buf
+= sprintf(buf
, ".%s%s%s%s", param
& D3DSP_WRITEMASK_0
? "x" : "",
2434 param
& D3DSP_WRITEMASK_1
? "y" : "",
2435 param
& D3DSP_WRITEMASK_2
? "z" : "",
2436 param
& D3DSP_WRITEMASK_3
? "w" : "");
2441 if ((param
& D3DVS_SWIZZLE_MASK
) != D3DVS_NOSWIZZLE
)
2443 if ( ((param
& D3DSP_SWIZZLE_MASK
) == (D3DVS_X_X
| D3DVS_Y_X
| D3DVS_Z_X
| D3DVS_W_X
)) ||
2444 ((param
& D3DSP_SWIZZLE_MASK
) == (D3DVS_X_Y
| D3DVS_Y_Y
| D3DVS_Z_Y
| D3DVS_W_Y
)) ||
2445 ((param
& D3DSP_SWIZZLE_MASK
) == (D3DVS_X_Z
| D3DVS_Y_Z
| D3DVS_Z_Z
| D3DVS_W_Z
)) ||
2446 ((param
& D3DSP_SWIZZLE_MASK
) == (D3DVS_X_W
| D3DVS_Y_W
| D3DVS_Z_W
| D3DVS_W_W
)) )
2447 buf
+= sprintf(buf
, ".%c", 'w' + (((param
>> D3DVS_SWIZZLE_SHIFT
) + 1) & 0x3));
2449 buf
+= sprintf(buf
, ".%c%c%c%c", 'w' + (((param
>> (D3DVS_SWIZZLE_SHIFT
+0)) + 1) & 0x3),
2450 'w' + (((param
>> (D3DVS_SWIZZLE_SHIFT
+2)) + 1) & 0x3),
2451 'w' + (((param
>> (D3DVS_SWIZZLE_SHIFT
+4)) + 1) & 0x3),
2452 'w' + (((param
>> (D3DVS_SWIZZLE_SHIFT
+6)) + 1) & 0x3));
2456 return buf
- buffer
;
2464 int (*function
)(const struct instr_info
*info
, DWORD
**ptr
, char *buffer
, BOOL ps
);
2469 static int instr_comment(const struct instr_info
*info
, DWORD
**ptr
, char *buffer
, BOOL ps
)
2471 *ptr
+= 1 + ((**ptr
& D3DSI_COMMENTSIZE_MASK
) >> D3DSI_COMMENTSIZE_SHIFT
);
2475 static int instr_def(const struct instr_info
*info
, DWORD
**ptr
, char *buffer
, BOOL ps
)
2477 int len
= sprintf(buffer
, " def c%d, %g, %g, %g, %g\n", *(*ptr
+1) & D3DSP_REGNUM_MASK
,
2478 (double)*(float*)(*ptr
+2), (double)*(float*)(*ptr
+3),
2479 (double)*(float*)(*ptr
+4), (double)*(float*)(*ptr
+5));
2484 static int instr_dcl(const struct instr_info
*info
, DWORD
**ptr
, char *buffer
, BOOL ps
)
2486 DWORD param1
= *++*ptr
;
2487 DWORD param2
= *++*ptr
;
2488 DWORD usage
= (param1
& D3DSP_DCL_USAGE_MASK
) >> D3DSP_DCL_USAGE_SHIFT
;
2489 DWORD usage_index
= (param1
& D3DSP_DCL_USAGEINDEX_MASK
) >> D3DSP_DCL_USAGEINDEX_SHIFT
;
2492 buf
+= sprintf(buf
, " dcl");
2495 if (param1
& D3DSP_TEXTURETYPE_MASK
)
2496 buf
+= sprintf(buf
, "_%s", (usage
<= D3DSTT_VOLUME
) ?
2497 tex_type
[(param1
& D3DSP_TEXTURETYPE_MASK
) >> D3DSP_TEXTURETYPE_SHIFT
] : "???");
2501 buf
+= sprintf(buf
, "_%s", (usage
<= D3DDECLUSAGE_COLOR
) ? decl_usage
[usage
] : "???");
2503 buf
+= sprintf(buf
, "%d", usage_index
);
2506 buf
+= add_modifier(buf
, param2
);
2507 buf
+= sprintf(buf
, " ");
2508 buf
+= add_register(buf
, param2
, TRUE
, TRUE
);
2509 buf
+= sprintf(buf
, "\n");
2511 return buf
- buffer
;
2514 static int instr_generic(const struct instr_info
*info
, DWORD
**ptr
, char *buffer
, BOOL ps
)
2519 buf
+= sprintf(buf
, " %s", info
->name
);
2524 buf
+= add_modifier(buf
, **ptr
);
2526 for (j
= 0; j
< info
->length
; j
++)
2528 buf
+= sprintf(buf
, "%s ", j
? "," : "");
2530 if ((j
!= 0) && ((**ptr
& D3DSP_SRCMOD_MASK
) != D3DSPSM_NONE
))
2532 if ((**ptr
& D3DSP_SRCMOD_MASK
) == D3DSPSM_NEG
)
2533 buf
+= sprintf(buf
, "-");
2535 buf
+= sprintf(buf
, "*");
2538 buf
+= add_register(buf
, **ptr
, j
== 0, ps
);
2540 if (*(*ptr
)++ & D3DVS_ADDRESSMODE_MASK
)
2542 buf
+= sprintf(buf
, "[");
2543 buf
+= add_register(buf
, **ptr
, FALSE
, FALSE
);
2544 buf
+= sprintf(buf
, "]");
2549 buf
+= sprintf(buf
, "\n");
2550 return buf
- buffer
;
2553 const struct instr_info instructions
[] =
2555 { D3DSIO_NOP
, "nop", 0, instr_generic
, 0x0100, 0xFFFF },
2556 { D3DSIO_MOV
, "mov", 2, instr_generic
, 0x0100, 0xFFFF },
2557 { D3DSIO_ADD
, "add", 3, instr_generic
, 0x0100, 0xFFFF },
2558 { D3DSIO_SUB
, "sub", 3, instr_generic
, 0x0100, 0xFFFF },
2559 { D3DSIO_MAD
, "mad", 4, instr_generic
, 0x0100, 0xFFFF },
2560 { D3DSIO_MUL
, "mul", 3, instr_generic
, 0x0100, 0xFFFF },
2561 { D3DSIO_RCP
, "rcp", 2, instr_generic
, 0x0100, 0xFFFF }, /* >= 2.0 for PS */
2562 { D3DSIO_RSQ
, "rsq", 2, instr_generic
, 0x0100, 0xFFFF }, /* >= 2.0 for PS */
2563 { D3DSIO_DP3
, "dp3", 3, instr_generic
, 0x0100, 0xFFFF },
2564 { D3DSIO_DP4
, "dp4", 3, instr_generic
, 0x0100, 0xFFFF }, /* >= 1.2 for PS */
2565 { D3DSIO_MIN
, "min", 3, instr_generic
, 0x0100, 0xFFFF }, /* >= 2.0 for PS */
2566 { D3DSIO_MAX
, "max", 3, instr_generic
, 0x0100, 0xFFFF }, /* >= 2.0 for PS */
2567 { D3DSIO_SLT
, "slt", 3, instr_generic
, 0x0100, 0xFFFF },
2568 { D3DSIO_SGE
, "sge", 3, instr_generic
, 0x0100, 0xFFFF }, /* VS only */
2569 { D3DSIO_EXP
, "exp", 2, instr_generic
, 0x0100, 0xFFFF }, /* >= 2.0 for PS */
2570 { D3DSIO_LOG
, "log", 2, instr_generic
, 0x0100, 0xFFFF }, /* >= 2.0 for PS */
2571 { D3DSIO_LIT
, "lit", 2, instr_generic
, 0x0100, 0xFFFF }, /* VS only */
2572 { D3DSIO_DST
, "dst", 3, instr_generic
, 0x0100, 0xFFFF }, /* VS only */
2573 { D3DSIO_LRP
, "lrp", 4, instr_generic
, 0x0100, 0xFFFF }, /* >= 2.0 for VS */
2574 { D3DSIO_FRC
, "frc", 2, instr_generic
, 0x0100, 0xFFFF }, /* >= 2.0 for PS */
2575 { D3DSIO_M4x4
, "m4x4", 3, instr_generic
, 0x0100, 0xFFFF }, /* >= 2.0 for PS */
2576 { D3DSIO_M4x3
, "m4x3", 3, instr_generic
, 0x0100, 0xFFFF }, /* >= 2.0 for PS */
2577 { D3DSIO_M3x4
, "m3x4", 3, instr_generic
, 0x0100, 0xFFFF }, /* >= 2.0 for PS */
2578 { D3DSIO_M3x3
, "m3x3", 3, instr_generic
, 0x0100, 0xFFFF }, /* >= 2.0 for PS */
2579 { D3DSIO_M3x2
, "m3x2", 3, instr_generic
, 0x0100, 0xFFFF }, /* >= 2.0 for PS */
2580 { D3DSIO_CALL
, "call", 1, instr_generic
, 0x0200, 0xFFFF }, /* >= 2.a for PS */
2581 { D3DSIO_CALLNZ
, "callnz", 2, instr_generic
, 0x0200, 0xFFFF }, /* >= 2.a for PS */
2582 { D3DSIO_LOOP
, "loop", 2, instr_generic
, 0x0200, 0xFFFF }, /* >= 3.0 for PS */
2583 { D3DSIO_RET
, "ret", 0, instr_generic
, 0x0200, 0xFFFF }, /* >= 2.a for PS */
2584 { D3DSIO_ENDLOOP
, "endloop", 1, instr_generic
, 0x0200, 0xFFFF }, /* >= 3.0 for PS */
2585 { D3DSIO_LABEL
, "label", 1, instr_generic
, 0x0200, 0xFFFF }, /* >= 2.a for PS */
2586 { D3DSIO_DCL
, "dcl", 1, instr_dcl
, 0x0100, 0xFFFF },
2587 { D3DSIO_POW
, "pow", 3, instr_generic
, 0x0200, 0xFFFF },
2588 { D3DSIO_CRS
, "crs", 3, instr_generic
, 0x0200, 0xFFFF },
2589 { D3DSIO_SGN
, "sgn", 4, instr_generic
, 0x0200, 0xFFFF }, /* VS only */
2590 { D3DSIO_ABS
, "abs", 2, instr_generic
, 0x0200, 0xFFFF },
2591 { D3DSIO_NRM
, "nrm", 2, instr_generic
, 0x0200, 0xFFFF },
2592 { D3DSIO_SINCOS
, "sincos", 4, instr_generic
, 0x0200, 0x02FF },
2593 { D3DSIO_SINCOS
, "sincos", 2, instr_generic
, 0x0300, 0xFFFF },
2594 { D3DSIO_REP
, "rep", 1, instr_generic
, 0x0200, 0xFFFF }, /* >= 2.a for PS */
2595 { D3DSIO_ENDREP
, "endrep", 0, instr_generic
, 0x0200, 0xFFFF }, /* >= 2.a for PS */
2596 { D3DSIO_IF
, "if", 1, instr_generic
, 0x0200, 0xFFFF }, /* >= 2.a for PS */
2597 { D3DSIO_IFC
, "if_comp", 2, instr_generic
, 0x0200, 0xFFFF },
2598 { D3DSIO_ELSE
, "else", 0, instr_generic
, 0x0200, 0xFFFF }, /* >= 2.a for PS */
2599 { D3DSIO_ENDIF
, "endif", 0, instr_generic
, 0x0200, 0xFFFF }, /* >= 2.a for PS */
2600 { D3DSIO_BREAK
, "break", 0, instr_generic
, 0x0201, 0xFFFF },
2601 { D3DSIO_BREAKC
, "break_comp", 2, instr_generic
, 0x0201, 0xFFFF },
2602 { D3DSIO_MOVA
, "mova", 2, instr_generic
, 0x0200, 0xFFFF }, /* VS only */
2603 { D3DSIO_DEFB
, "defb", 2, instr_generic
, 0x0100, 0xFFFF },
2604 { D3DSIO_DEFI
, "defi", 2, instr_generic
, 0x0100, 0xFFFF },
2605 { D3DSIO_TEXCOORD
, "texcoord", 1, instr_generic
, 0x0100, 0x0103 }, /* PS only */
2606 { D3DSIO_TEXCOORD
, "texcrd", 2, instr_generic
, 0x0104, 0x0104 }, /* PS only */
2607 { D3DSIO_TEXKILL
, "texkill", 1, instr_generic
, 0x0100, 0xFFFF }, /* PS only */
2608 { D3DSIO_TEX
, "tex", 1, instr_generic
, 0x0100, 0x0103 }, /* PS only */
2609 { D3DSIO_TEX
, "texld", 2, instr_generic
, 0x0104, 0x0104 }, /* PS only */
2610 { D3DSIO_TEX
, "texld", 3, instr_generic
, 0x0200, 0xFFFF }, /* PS only */
2611 { D3DSIO_TEXBEM
, "texbem", 2, instr_generic
, 0x0100, 0x0103 }, /* PS only */
2612 { D3DSIO_TEXBEML
, "texbeml", 2, instr_generic
, 0x0100, 0x0103 }, /* PS only */
2613 { D3DSIO_TEXREG2AR
, "texreg2ar", 2, instr_generic
, 0x0100, 0x0103 }, /* PS only */
2614 { D3DSIO_TEXREG2GB
, "texreg2gb", 2, instr_generic
, 0x0102, 0x0103 }, /* PS only */
2615 { D3DSIO_TEXM3x2PAD
, "texm3x2pad", 2, instr_generic
, 0x0100, 0x0103 }, /* PS only */
2616 { D3DSIO_TEXM3x2TEX
, "texm3x2tex", 2, instr_generic
, 0x0100, 0x0103 }, /* PS only */
2617 { D3DSIO_TEXM3x3PAD
, "texm3x3pad", 2, instr_generic
, 0x0100, 0x0103 }, /* PS only */
2618 { D3DSIO_TEXM3x3TEX
, "texm3x3tex", 2, instr_generic
, 0x0100, 0x0103 }, /* PS only */
2619 { D3DSIO_TEXM3x3DIFF
, "texm3x3diff", 2, instr_generic
, 0x0100, 0xFFFF }, /* PS only - Not documented */
2620 { D3DSIO_TEXM3x3SPEC
, "texm3x3spec", 3, instr_generic
, 0x0100, 0x0103 }, /* PS only */
2621 { D3DSIO_TEXM3x3VSPEC
, "texm3x3vspec", 2, instr_generic
, 0x0100, 0x0103 }, /* PS only */
2622 { D3DSIO_EXPP
, "expp", 2, instr_generic
, 0x0100, 0xFFFF }, /* VS only */
2623 { D3DSIO_LOGP
, "logp", 2, instr_generic
, 0x0100, 0xFFFF }, /* VS only */
2624 { D3DSIO_CND
, "cnd", 4, instr_generic
, 0x0100, 0x0104 }, /* PS only */
2625 { D3DSIO_DEF
, "def", 5, instr_def
, 0x0100, 0xFFFF },
2626 { D3DSIO_TEXREG2RGB
, "texreg2rgb", 2, instr_generic
, 0x0102, 0x0103 }, /* PS only */
2627 { D3DSIO_TEXDP3TEX
, "texdp3tex", 2, instr_generic
, 0x0102, 0x0103 }, /* PS only */
2628 { D3DSIO_TEXM3x2DEPTH
, "texm3x2depth", 2, instr_generic
, 0x0103, 0x0103 }, /* PS only */
2629 { D3DSIO_TEXDP3
, "texdp3", 2, instr_generic
, 0x0102, 0x0103 }, /* PS only */
2630 { D3DSIO_TEXM3x3
, "texm3x3", 2, instr_generic
, 0x0102, 0x0103 }, /* PS only */
2631 { D3DSIO_TEXDEPTH
, "texdepth", 1, instr_generic
, 0x0104, 0x0104 }, /* PS only */
2632 { D3DSIO_CMP
, "cmp", 4, instr_generic
, 0x0102, 0xFFFF }, /* PS only */
2633 { D3DSIO_BEM
, "bem", 3, instr_generic
, 0x0104, 0x0104 }, /* PS only */
2634 { D3DSIO_DP2ADD
, "dp2add", 4, instr_generic
, 0x0200, 0xFFFF }, /* PS only */
2635 { D3DSIO_DSX
, "dsx", 2, instr_generic
, 0x0201, 0xFFFF }, /* PS only */
2636 { D3DSIO_DSY
, "dsy", 2, instr_generic
, 0x0201, 0xFFFF }, /* PS only */
2637 { D3DSIO_TEXLDD
, "texldd", 5, instr_generic
, 0x0201, 0xFFFF }, /* PS only - not existing for 2.b */
2638 { D3DSIO_SETP
, "setp_comp", 3, instr_generic
, 0x0201, 0xFFFF },
2639 { D3DSIO_TEXLDL
, "texldl", 3, instr_generic
, 0x0300, 0xFFFF },
2640 { D3DSIO_BREAKP
, "breakp", 1, instr_generic
, 0x0201, 0xFFFF },
2641 { D3DSIO_PHASE
, "phase", 0, instr_generic
, 0x0104, 0x0104 }, /* PS only */
2642 { D3DSIO_COMMENT
, "", 0, instr_comment
, 0x0100, 0xFFFF }
2645 HRESULT WINAPI
D3DXDisassembleShader(const DWORD
*shader
, BOOL colorcode
, const char *comments
, ID3DXBuffer
**disassembly
)
2647 DWORD
*ptr
= (DWORD
*)shader
;
2649 UINT capacity
= 4096;
2654 TRACE("%p %d %s %p\n", shader
, colorcode
, debugstr_a(comments
), disassembly
);
2656 if (!shader
|| !disassembly
)
2657 return D3DERR_INVALIDCALL
;
2659 buf
= buffer
= HeapAlloc(GetProcessHeap(), 0, capacity
);
2661 return E_OUTOFMEMORY
;
2663 ps
= (*ptr
>> 16) & 1;
2664 version
= *ptr
& 0xFFFF;
2665 buf
+= sprintf(buf
, " %s_%d_%d\n", ps
? "ps" : "vs", D3DSHADER_VERSION_MAJOR(*ptr
), D3DSHADER_VERSION_MINOR(*ptr
));
2668 while (*ptr
!= D3DSIO_END
)
2672 if ((buf
- buffer
+ 128) > capacity
)
2674 UINT count
= buf
- buffer
;
2675 char *new_buffer
= HeapReAlloc(GetProcessHeap(), 0, buffer
, capacity
* 2);
2678 HeapFree(GetProcessHeap(), 0, buffer
);
2679 return E_OUTOFMEMORY
;
2682 buffer
= new_buffer
;
2683 buf
= buffer
+ count
;
2686 for (index
= 0; index
< sizeof(instructions
)/sizeof(instructions
[0]); index
++)
2687 if (((*ptr
& D3DSI_OPCODE_MASK
) == instructions
[index
].opcode
) &&
2688 (version
>= instructions
[index
].min_version
) && (version
<= instructions
[index
].max_version
))
2691 if (index
!= sizeof(instructions
)/sizeof(instructions
[0]))
2693 buf
+= instructions
[index
].function(&(instructions
[index
]), &ptr
, buf
, ps
);
2697 buf
+= sprintf(buf
, " ??? (Unknown opcode %x)\n", *ptr
);
2698 while (*++ptr
& (1u << 31));
2702 hr
= D3DXCreateBuffer(buf
- buffer
+ 1 , disassembly
);
2704 strcpy(ID3DXBuffer_GetBufferPointer(*disassembly
), buffer
);
2705 HeapFree(GetProcessHeap(), 0, buffer
);
2710 struct d3dx9_texture_shader
2712 ID3DXTextureShader ID3DXTextureShader_iface
;
2716 static inline struct d3dx9_texture_shader
*impl_from_ID3DXTextureShader(ID3DXTextureShader
*iface
)
2718 return CONTAINING_RECORD(iface
, struct d3dx9_texture_shader
, ID3DXTextureShader_iface
);
2721 static HRESULT WINAPI
d3dx9_texture_shader_QueryInterface(ID3DXTextureShader
*iface
, REFIID riid
, void **out
)
2723 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
2725 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
2726 IsEqualGUID(riid
, &IID_ID3DXTextureShader
))
2728 iface
->lpVtbl
->AddRef(iface
);
2733 WARN("Interface %s not found.\n", debugstr_guid(riid
));
2735 return E_NOINTERFACE
;
2738 static ULONG WINAPI
d3dx9_texture_shader_AddRef(ID3DXTextureShader
*iface
)
2740 struct d3dx9_texture_shader
*texture_shader
= impl_from_ID3DXTextureShader(iface
);
2741 ULONG refcount
= InterlockedIncrement(&texture_shader
->ref
);
2743 TRACE("%p increasing refcount to %u.\n", texture_shader
, refcount
);
2748 static ULONG WINAPI
d3dx9_texture_shader_Release(ID3DXTextureShader
*iface
)
2750 struct d3dx9_texture_shader
*texture_shader
= impl_from_ID3DXTextureShader(iface
);
2751 ULONG refcount
= InterlockedDecrement(&texture_shader
->ref
);
2753 TRACE("%p decreasing refcount to %u.\n", texture_shader
, refcount
);
2757 HeapFree(GetProcessHeap(), 0, texture_shader
);
2763 static HRESULT WINAPI
d3dx9_texture_shader_GetFunction(ID3DXTextureShader
*iface
, struct ID3DXBuffer
**function
)
2765 FIXME("iface %p, function %p stub.\n", iface
, function
);
2770 static HRESULT WINAPI
d3dx9_texture_shader_GetConstantBuffer(ID3DXTextureShader
*iface
, struct ID3DXBuffer
**constant_buffer
)
2772 FIXME("iface %p, constant_buffer %p stub.\n", iface
, constant_buffer
);
2777 static HRESULT WINAPI
d3dx9_texture_shader_GetDesc(ID3DXTextureShader
*iface
, D3DXCONSTANTTABLE_DESC
*desc
)
2779 FIXME("iface %p, desc %p stub.\n", iface
, desc
);
2784 static HRESULT WINAPI
d3dx9_texture_shader_GetConstantDesc(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, D3DXCONSTANT_DESC
*constant_desc
, UINT
*count
)
2786 FIXME("iface %p, constant %p, constant_desc %p, count %p stub.\n", iface
, constant
, constant_desc
, count
);
2791 static D3DXHANDLE WINAPI
d3dx9_texture_shader_GetConstant(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, UINT index
)
2793 FIXME("iface %p, constant %p, index %u stub.\n", iface
, constant
, index
);
2798 static D3DXHANDLE WINAPI
d3dx9_texture_shader_GetConstantByName(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const char *name
)
2800 FIXME("iface %p, constant %p, name %s stub.\n", iface
, constant
, debugstr_a(name
));
2805 static D3DXHANDLE WINAPI
d3dx9_texture_shader_GetConstantElement(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, UINT index
)
2807 FIXME("iface %p, constant %p, index %u stub.\n", iface
, constant
, index
);
2812 static HRESULT WINAPI
d3dx9_texture_shader_SetDefaults(ID3DXTextureShader
*iface
)
2814 FIXME("iface %p stub.\n", iface
);
2819 static HRESULT WINAPI
d3dx9_texture_shader_SetValue(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const void *data
, UINT bytes
)
2821 FIXME("iface %p, constant %p, data %p, bytes %u stub.\n", iface
, constant
, data
, bytes
);
2826 static HRESULT WINAPI
d3dx9_texture_shader_SetBool(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, BOOL b
)
2828 FIXME("iface %p, constant %p, b %u stub.\n", iface
, constant
, b
);
2833 static HRESULT WINAPI
d3dx9_texture_shader_SetBoolArray(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const BOOL
*b
, UINT count
)
2835 FIXME("iface %p, constant %p, b %p, count %u stub.\n", iface
, constant
, b
, count
);
2840 static HRESULT WINAPI
d3dx9_texture_shader_SetInt(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, INT n
)
2842 FIXME("iface %p, constant %p, n %d stub.\n", iface
, constant
, n
);
2847 static HRESULT WINAPI
d3dx9_texture_shader_SetIntArray(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const INT
*n
, UINT count
)
2849 FIXME("iface %p, constant %p, n %p, count %u stub.\n", iface
, constant
, n
, count
);
2854 static HRESULT WINAPI
d3dx9_texture_shader_SetFloat(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, FLOAT f
)
2856 FIXME("iface %p, constant %p, f %f stub.\n", iface
, constant
, f
);
2861 static HRESULT WINAPI
d3dx9_texture_shader_SetFloatArray(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const FLOAT
*f
, UINT count
)
2863 FIXME("iface %p, constant %p, f %p, count %u stub.\n", iface
, constant
, f
, count
);
2868 static HRESULT WINAPI
d3dx9_texture_shader_SetVector(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const D3DXVECTOR4
*vector
)
2870 FIXME("iface %p, constant %p, vector %p stub.\n", iface
, constant
, vector
);
2875 static HRESULT WINAPI
d3dx9_texture_shader_SetVectorArray(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const D3DXVECTOR4
*vector
, UINT count
)
2877 FIXME("iface %p, constant %p, vector %p, count %u stub.\n", iface
, constant
, vector
, count
);
2882 static HRESULT WINAPI
d3dx9_texture_shader_SetMatrix(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const D3DXMATRIX
*matrix
)
2884 FIXME("iface %p, constant %p, matrix %p stub.\n", iface
, constant
, matrix
);
2889 static HRESULT WINAPI
d3dx9_texture_shader_SetMatrixArray(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const D3DXMATRIX
*matrix
, UINT count
)
2891 FIXME("iface %p, constant %p, matrix %p, count %u stub.\n", iface
, constant
, matrix
, count
);
2896 static HRESULT WINAPI
d3dx9_texture_shader_SetMatrixPointerArray(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const D3DXMATRIX
**matrix
, UINT count
)
2898 FIXME("iface %p, constant %p, matrix %p, count %u stub.\n", iface
, constant
, matrix
, count
);
2903 static HRESULT WINAPI
d3dx9_texture_shader_SetMatrixTranspose(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const D3DXMATRIX
*matrix
)
2905 FIXME("iface %p, constant %p, matrix %p stub.\n", iface
, constant
, matrix
);
2910 static HRESULT WINAPI
d3dx9_texture_shader_SetMatrixTransposeArray(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const D3DXMATRIX
*matrix
, UINT count
)
2912 FIXME("iface %p, constant %p, matrix %p, count %u stub.\n", iface
, constant
, matrix
, count
);
2917 static HRESULT WINAPI
d3dx9_texture_shader_SetMatrixTransposePointerArray(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const D3DXMATRIX
**matrix
, UINT count
)
2919 FIXME("iface %p, constant %p, matrix %p, count %u stub.\n", iface
, constant
, matrix
, count
);
2924 static const struct ID3DXTextureShaderVtbl d3dx9_texture_shader_vtbl
=
2926 /*** IUnknown methods ***/
2927 d3dx9_texture_shader_QueryInterface
,
2928 d3dx9_texture_shader_AddRef
,
2929 d3dx9_texture_shader_Release
,
2930 /*** ID3DXTextureShader methods ***/
2931 d3dx9_texture_shader_GetFunction
,
2932 d3dx9_texture_shader_GetConstantBuffer
,
2933 d3dx9_texture_shader_GetDesc
,
2934 d3dx9_texture_shader_GetConstantDesc
,
2935 d3dx9_texture_shader_GetConstant
,
2936 d3dx9_texture_shader_GetConstantByName
,
2937 d3dx9_texture_shader_GetConstantElement
,
2938 d3dx9_texture_shader_SetDefaults
,
2939 d3dx9_texture_shader_SetValue
,
2940 d3dx9_texture_shader_SetBool
,
2941 d3dx9_texture_shader_SetBoolArray
,
2942 d3dx9_texture_shader_SetInt
,
2943 d3dx9_texture_shader_SetIntArray
,
2944 d3dx9_texture_shader_SetFloat
,
2945 d3dx9_texture_shader_SetFloatArray
,
2946 d3dx9_texture_shader_SetVector
,
2947 d3dx9_texture_shader_SetVectorArray
,
2948 d3dx9_texture_shader_SetMatrix
,
2949 d3dx9_texture_shader_SetMatrixArray
,
2950 d3dx9_texture_shader_SetMatrixPointerArray
,
2951 d3dx9_texture_shader_SetMatrixTranspose
,
2952 d3dx9_texture_shader_SetMatrixTransposeArray
,
2953 d3dx9_texture_shader_SetMatrixTransposePointerArray
2956 HRESULT WINAPI
D3DXCreateTextureShader(const DWORD
*function
, ID3DXTextureShader
**texture_shader
)
2958 struct d3dx9_texture_shader
*object
;
2960 TRACE("function %p, texture_shader %p.\n", function
, texture_shader
);
2962 if (!function
|| !texture_shader
)
2963 return D3DERR_INVALIDCALL
;
2965 object
= HeapAlloc(GetProcessHeap(), 0, sizeof(*object
));
2967 return E_OUTOFMEMORY
;
2969 object
->ID3DXTextureShader_iface
.lpVtbl
= &d3dx9_texture_shader_vtbl
;
2972 *texture_shader
= &object
->ID3DXTextureShader_iface
;
2977 static unsigned int get_instr_length(const DWORD
*byte_code
, unsigned int major
, unsigned int minor
)
2979 DWORD opcode
= *byte_code
& 0xffff;
2980 unsigned int len
= 0;
2982 if (opcode
== D3DSIO_COMMENT
)
2983 return (*byte_code
& D3DSI_COMMENTSIZE_MASK
) >> D3DSI_COMMENTSIZE_SHIFT
;
2986 return (*byte_code
& D3DSI_INSTLENGTH_MASK
) >> D3DSI_INSTLENGTH_SHIFT
;
2991 ERR("Unexpected END token.\n");
3000 while (*byte_code
& 0x80000000)
3010 static HRESULT
get_shader_semantics(const DWORD
*byte_code
, D3DXSEMANTIC
*semantics
, UINT
*count
, BOOL output
)
3012 static const D3DDECLUSAGE regtype_usage
[] =
3017 D3DDECLUSAGE_TEXCOORD
,
3020 D3DDECLUSAGE_TEXCOORD
,
3025 static const D3DDECLUSAGE rast_usage
[] =
3027 D3DDECLUSAGE_POSITION
,
3031 DWORD reg_type
, usage
, index
, version_token
= *byte_code
;
3032 BOOL is_ps
= version_token
>> 16 == 0xffff;
3033 unsigned int major
, minor
, i
= 0, j
;
3034 BYTE colors
= 0, rastout
= 0;
3035 BOOL has_dcl
, depth
= 0;
3038 if ((version_token
& 0xffff0000) != 0xfffe0000 && (version_token
& 0xffff0000) != 0xffff0000)
3039 return D3DXERR_INVALIDDATA
;
3041 major
= version_token
>> 8 & 0xff;
3042 minor
= version_token
& 0xff;
3044 TRACE("%s shader, version %u.%u.\n", is_ps
? "Pixel" : "Vertex", major
, minor
);
3047 has_dcl
= (!is_ps
&& (!output
|| major
== 3)) || (is_ps
&& !output
&& major
>= 2);
3049 while (*byte_code
!= D3DSIO_END
)
3051 if (has_dcl
&& (*byte_code
& 0xffff) == D3DSIO_DCL
)
3053 DWORD usage_token
= byte_code
[1];
3054 DWORD reg
= byte_code
[2];
3056 reg_type
= ((reg
& D3DSP_REGTYPE_MASK
) >> D3DSP_REGTYPE_SHIFT
)
3057 | ((reg
& D3DSP_REGTYPE_MASK2
) >> D3DSP_REGTYPE_SHIFT2
);
3059 if (is_ps
&& !output
&& major
== 2)
3061 /* dcl with no explicit usage, look at the register. */
3062 reg_type
= ((reg
& D3DSP_REGTYPE_MASK
) >> D3DSP_REGTYPE_SHIFT
)
3063 | ((reg
& D3DSP_REGTYPE_MASK2
) >> D3DSP_REGTYPE_SHIFT2
);
3064 index
= reg
& D3DSP_REGNUM_MASK
;
3065 if (reg_type
>= ARRAY_SIZE(regtype_usage
))
3067 WARN("Invalid register type %u.\n", reg_type
);
3070 usage
= regtype_usage
[reg_type
];
3073 semantics
[i
].Usage
= usage
;
3074 semantics
[i
].UsageIndex
= index
;
3078 else if ((!output
&& reg_type
== D3DSPR_INPUT
) || (output
&& reg_type
== D3DSPR_OUTPUT
))
3082 semantics
[i
].Usage
=
3083 (usage_token
& D3DSP_DCL_USAGE_MASK
) >> D3DSP_DCL_USAGE_SHIFT
;
3084 semantics
[i
].UsageIndex
=
3085 (usage_token
& D3DSP_DCL_USAGEINDEX_MASK
) >> D3DSP_DCL_USAGEINDEX_SHIFT
;
3093 unsigned int len
= get_instr_length(byte_code
, major
, minor
) + 1;
3095 switch (*byte_code
& 0xffff)
3097 case D3DSIO_COMMENT
:
3105 while (*byte_code
& 0x80000000)
3107 reg_type
= ((*byte_code
& D3DSP_REGTYPE_MASK
) >> D3DSP_REGTYPE_SHIFT
)
3108 | ((*byte_code
& D3DSP_REGTYPE_MASK2
) >> D3DSP_REGTYPE_SHIFT2
);
3109 index
= *byte_code
& D3DSP_REGNUM_MASK
;
3111 if ((reg_type
== D3DSPR_TEMP
&& is_ps
&& major
== 1)
3112 || (reg_type
== D3DSPR_INPUT
&& is_ps
)
3113 || (reg_type
== D3DSPR_TEXTURE
&& is_ps
&& !output
)
3114 || reg_type
== D3DSPR_RASTOUT
3115 || reg_type
== D3DSPR_ATTROUT
3116 || reg_type
== D3DSPR_OUTPUT
3117 || reg_type
== D3DSPR_DEPTHOUT
)
3119 if (reg_type
== D3DSPR_RASTOUT
)
3120 rastout
|= 1u << index
;
3121 else if (reg_type
== D3DSPR_DEPTHOUT
)
3123 else if (reg_type
== D3DSPR_TEXTURE
|| reg_type
== D3DSPR_OUTPUT
)
3124 texcoords
|= 1u << index
;
3126 colors
|= 1u << index
;
3134 byte_code
+= get_instr_length(byte_code
, major
, minor
) + 1;
3147 semantics
[i
].Usage
= D3DDECLUSAGE_TEXCOORD
;
3148 semantics
[i
].UsageIndex
= j
;
3162 semantics
[i
].Usage
= D3DDECLUSAGE_COLOR
;
3163 semantics
[i
].UsageIndex
= j
;
3175 if (j
>= ARRAY_SIZE(rast_usage
))
3177 WARN("Invalid RASTOUT register index.\n");
3182 usage
= rast_usage
[j
];
3186 semantics
[i
].Usage
= usage
;
3187 semantics
[i
].UsageIndex
= 0;
3198 semantics
[i
].Usage
= D3DDECLUSAGE_DEPTH
;
3199 semantics
[i
].UsageIndex
= 0;
3211 HRESULT WINAPI
D3DXGetShaderInputSemantics(const DWORD
*byte_code
, D3DXSEMANTIC
*semantics
, UINT
*count
)
3213 TRACE("byte_code %p, semantics %p, count %p.\n", byte_code
, semantics
, count
);
3215 return get_shader_semantics(byte_code
, semantics
, count
, FALSE
);
3218 HRESULT WINAPI
D3DXGetShaderOutputSemantics(const DWORD
*byte_code
, D3DXSEMANTIC
*semantics
, UINT
*count
)
3220 TRACE("byte_code %p, semantics %p, count %p.\n", byte_code
, semantics
, count
);
3222 return get_shader_semantics(byte_code
, semantics
, count
, TRUE
);