2 * Copyright 2008 Luis Busquets
3 * Copyright 2009 Matteo Bruni
4 * Copyright 2010, 2013, 2016 Christian Costa
5 * Copyright 2011 Travis Athougies
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include "d3dx9_36_private.h"
26 #include "d3dcompiler.h"
28 /* This function is not declared in the SDK headers yet. */
29 HRESULT WINAPI
D3DAssemble(const void *data
, SIZE_T datasize
, const char *filename
,
30 const D3D_SHADER_MACRO
*defines
, ID3DInclude
*include
, UINT flags
,
31 ID3DBlob
**shader
, ID3DBlob
**error_messages
);
33 static inline BOOL
is_valid_bytecode(DWORD token
)
35 return (token
& 0xfffe0000) == 0xfffe0000;
38 const char * WINAPI
D3DXGetPixelShaderProfile(struct IDirect3DDevice9
*device
)
42 TRACE("device %p\n", device
);
44 if (!device
) return NULL
;
46 IDirect3DDevice9_GetDeviceCaps(device
,&caps
);
48 switch (caps
.PixelShaderVersion
)
50 case D3DPS_VERSION(1, 1):
53 case D3DPS_VERSION(1, 2):
56 case D3DPS_VERSION(1, 3):
59 case D3DPS_VERSION(1, 4):
62 case D3DPS_VERSION(2, 0):
63 if ((caps
.PS20Caps
.NumTemps
>=22) &&
64 (caps
.PS20Caps
.Caps
&D3DPS20CAPS_ARBITRARYSWIZZLE
) &&
65 (caps
.PS20Caps
.Caps
&D3DPS20CAPS_GRADIENTINSTRUCTIONS
) &&
66 (caps
.PS20Caps
.Caps
&D3DPS20CAPS_PREDICATION
) &&
67 (caps
.PS20Caps
.Caps
&D3DPS20CAPS_NODEPENDENTREADLIMIT
) &&
68 (caps
.PS20Caps
.Caps
&D3DPS20CAPS_NOTEXINSTRUCTIONLIMIT
))
72 if ((caps
.PS20Caps
.NumTemps
>=32) &&
73 (caps
.PS20Caps
.Caps
&D3DPS20CAPS_NOTEXINSTRUCTIONLIMIT
))
79 case D3DPS_VERSION(3, 0):
86 UINT WINAPI
D3DXGetShaderSize(const DWORD
*byte_code
)
88 const DWORD
*ptr
= byte_code
;
90 TRACE("byte_code %p\n", byte_code
);
94 /* Look for the END token, skipping the VERSION token */
95 while (*++ptr
!= D3DSIO_END
)
98 if ((*ptr
& D3DSI_OPCODE_MASK
) == D3DSIO_COMMENT
)
100 ptr
+= ((*ptr
& D3DSI_COMMENTSIZE_MASK
) >> D3DSI_COMMENTSIZE_SHIFT
);
105 /* Return the shader size in bytes */
106 return (ptr
- byte_code
) * sizeof(*ptr
);
109 DWORD WINAPI
D3DXGetShaderVersion(const DWORD
*byte_code
)
111 TRACE("byte_code %p\n", byte_code
);
113 return byte_code
? *byte_code
: 0;
116 const char * WINAPI
D3DXGetVertexShaderProfile(struct IDirect3DDevice9
*device
)
120 TRACE("device %p\n", device
);
122 if (!device
) return NULL
;
124 IDirect3DDevice9_GetDeviceCaps(device
,&caps
);
126 switch (caps
.VertexShaderVersion
)
128 case D3DVS_VERSION(1, 1):
130 case D3DVS_VERSION(2, 0):
131 if ((caps
.VS20Caps
.NumTemps
>=13) &&
132 (caps
.VS20Caps
.DynamicFlowControlDepth
==24) &&
133 (caps
.VS20Caps
.Caps
&D3DPS20CAPS_PREDICATION
))
138 case D3DVS_VERSION(3, 0):
145 HRESULT WINAPI
D3DXFindShaderComment(const DWORD
*byte_code
, DWORD fourcc
, const void **data
, UINT
*size
)
147 const DWORD
*ptr
= byte_code
;
150 TRACE("byte_code %p, fourcc %x, data %p, size %p\n", byte_code
, fourcc
, data
, size
);
152 if (data
) *data
= NULL
;
155 if (!byte_code
) return D3DERR_INVALIDCALL
;
157 version
= *ptr
>> 16;
158 if (version
!= 0x4658 /* FX */
159 && version
!= 0x5458 /* TX */
162 && version
!= 0xfffe /* VS */
163 && version
!= 0xffff) /* PS */
165 WARN("Invalid data supplied\n");
166 return D3DXERR_INVALIDDATA
;
169 while (*++ptr
!= D3DSIO_END
)
171 /* Check if it is a comment */
172 if ((*ptr
& D3DSI_OPCODE_MASK
) == D3DSIO_COMMENT
)
174 DWORD comment_size
= (*ptr
& D3DSI_COMMENTSIZE_MASK
) >> D3DSI_COMMENTSIZE_SHIFT
;
176 /* Check if this is the comment we are looking for */
177 if (*(ptr
+ 1) == fourcc
)
179 UINT ctab_size
= (comment_size
- 1) * sizeof(DWORD
);
180 const void *ctab_data
= ptr
+ 2;
185 TRACE("Returning comment data at %p with size %d\n", ctab_data
, ctab_size
);
195 HRESULT WINAPI
D3DXAssembleShader(const char *data
, UINT data_len
, const D3DXMACRO
*defines
,
196 ID3DXInclude
*include
, DWORD flags
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
200 TRACE("data %p, data_len %u, defines %p, include %p, flags %#x, shader %p, error_messages %p\n",
201 data
, data_len
, defines
, include
, flags
, shader
, error_messages
);
203 /* Forward to d3dcompiler: the parameter types aren't really different,
204 the actual data types are equivalent */
205 hr
= D3DAssemble(data
, data_len
, NULL
, (D3D_SHADER_MACRO
*)defines
,
206 (ID3DInclude
*)include
, flags
, (ID3DBlob
**)shader
,
207 (ID3DBlob
**)error_messages
);
209 if(hr
== E_FAIL
) hr
= D3DXERR_INVALIDDATA
;
213 static const void *main_file_data
;
215 static CRITICAL_SECTION from_file_mutex
;
216 static CRITICAL_SECTION_DEBUG from_file_mutex_debug
=
218 0, 0, &from_file_mutex
,
220 &from_file_mutex_debug
.ProcessLocksList
,
221 &from_file_mutex_debug
.ProcessLocksList
223 0, 0, {(DWORD_PTR
)(__FILE__
": from_file_mutex")}
225 static CRITICAL_SECTION from_file_mutex
= {&from_file_mutex_debug
, -1, 0, 0, 0, 0};
227 /* D3DXInclude private implementation, used to implement
228 * D3DXAssembleShaderFromFile() from D3DXAssembleShader(). */
229 /* To be able to correctly resolve include search paths we have to store the
230 * pathname of each include file. We store the pathname pointer right before
232 static HRESULT WINAPI
d3dincludefromfile_open(ID3DXInclude
*iface
, D3DXINCLUDE_TYPE include_type
,
233 const char *filename
, const void *parent_data
, const void **data
, UINT
*bytes
)
235 const char *p
, *parent_name
= "";
236 char *pathname
= NULL
, *ptr
;
237 char **buffer
= NULL
;
243 parent_name
= *((const char **)parent_data
- 1);
248 parent_name
= *((const char **)main_file_data
- 1);
251 TRACE("Looking up for include file %s, parent %s\n", debugstr_a(filename
), debugstr_a(parent_name
));
253 if ((p
= strrchr(parent_name
, '\\')))
257 pathname
= HeapAlloc(GetProcessHeap(), 0, (p
- parent_name
) + strlen(filename
) + 1);
259 return HRESULT_FROM_WIN32(GetLastError());
261 memcpy(pathname
, parent_name
, p
- parent_name
);
262 strcpy(pathname
+ (p
- parent_name
), filename
);
263 ptr
= pathname
+ (p
- parent_name
);
271 file
= CreateFileA(pathname
, GENERIC_READ
, FILE_SHARE_READ
, 0, OPEN_EXISTING
, 0, 0);
272 if(file
== INVALID_HANDLE_VALUE
)
275 TRACE("Include file found at pathname = %s\n", debugstr_a(pathname
));
277 size
= GetFileSize(file
, NULL
);
278 if(size
== INVALID_FILE_SIZE
)
281 buffer
= HeapAlloc(GetProcessHeap(), 0, size
+ sizeof(char *));
285 if(!ReadFile(file
, buffer
+ 1, size
, bytes
, NULL
))
290 main_file_data
= *data
;
297 HeapFree(GetProcessHeap(), 0, pathname
);
298 HeapFree(GetProcessHeap(), 0, buffer
);
299 return HRESULT_FROM_WIN32(GetLastError());
302 static HRESULT WINAPI
d3dincludefromfile_close(ID3DXInclude
*iface
, const void *data
)
304 HeapFree(GetProcessHeap(), 0, *((char **)data
- 1));
305 HeapFree(GetProcessHeap(), 0, (char **)data
- 1);
306 if (main_file_data
== data
)
307 main_file_data
= NULL
;
311 static const struct ID3DXIncludeVtbl D3DXInclude_Vtbl
= {
312 d3dincludefromfile_open
,
313 d3dincludefromfile_close
316 struct D3DXIncludeImpl
{
317 ID3DXInclude ID3DXInclude_iface
;
320 HRESULT WINAPI
D3DXAssembleShaderFromFileA(const char *filename
, const D3DXMACRO
*defines
,
321 ID3DXInclude
*include
, DWORD flags
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
327 TRACE("filename %s, defines %p, include %p, flags %#x, shader %p, error_messages %p.\n",
328 debugstr_a(filename
), defines
, include
, flags
, shader
, error_messages
);
330 if (!filename
) return D3DXERR_INVALIDDATA
;
332 len
= MultiByteToWideChar(CP_ACP
, 0, filename
, -1, NULL
, 0);
333 filename_w
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
334 if (!filename_w
) return E_OUTOFMEMORY
;
335 MultiByteToWideChar(CP_ACP
, 0, filename
, -1, filename_w
, len
);
337 ret
= D3DXAssembleShaderFromFileW(filename_w
, defines
, include
, flags
, shader
, error_messages
);
339 HeapFree(GetProcessHeap(), 0, filename_w
);
343 HRESULT WINAPI
D3DXAssembleShaderFromFileW(const WCHAR
*filename
, const D3DXMACRO
*defines
,
344 ID3DXInclude
*include
, DWORD flags
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
349 struct D3DXIncludeImpl includefromfile
;
352 TRACE("filename %s, defines %p, include %p, flags %#x, shader %p, error_messages %p.\n",
353 debugstr_w(filename
), defines
, include
, flags
, shader
, error_messages
);
357 includefromfile
.ID3DXInclude_iface
.lpVtbl
= &D3DXInclude_Vtbl
;
358 include
= &includefromfile
.ID3DXInclude_iface
;
361 len
= WideCharToMultiByte(CP_ACP
, 0, filename
, -1, NULL
, 0, NULL
, NULL
);
362 filename_a
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(char));
364 return E_OUTOFMEMORY
;
365 WideCharToMultiByte(CP_ACP
, 0, filename
, -1, filename_a
, len
, NULL
, NULL
);
367 EnterCriticalSection(&from_file_mutex
);
368 hr
= ID3DXInclude_Open(include
, D3DXINC_LOCAL
, filename_a
, NULL
, &buffer
, &len
);
371 LeaveCriticalSection(&from_file_mutex
);
372 HeapFree(GetProcessHeap(), 0, filename_a
);
373 return D3DXERR_INVALIDDATA
;
376 hr
= D3DXAssembleShader(buffer
, len
, defines
, include
, flags
, shader
, error_messages
);
378 ID3DXInclude_Close(include
, buffer
);
379 LeaveCriticalSection(&from_file_mutex
);
380 HeapFree(GetProcessHeap(), 0, filename_a
);
384 HRESULT WINAPI
D3DXAssembleShaderFromResourceA(HMODULE module
, const char *resource
, const D3DXMACRO
*defines
,
385 ID3DXInclude
*include
, DWORD flags
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
391 TRACE("module %p, resource %s, defines %p, include %p, flags %#x, shader %p, error_messages %p.\n",
392 module
, debugstr_a(resource
), defines
, include
, flags
, shader
, error_messages
);
394 if (!(res
= FindResourceA(module
, resource
, (const char *)RT_RCDATA
)))
395 return D3DXERR_INVALIDDATA
;
396 if (FAILED(load_resource_into_memory(module
, res
, &buffer
, &len
)))
397 return D3DXERR_INVALIDDATA
;
398 return D3DXAssembleShader(buffer
, len
, defines
, include
, flags
,
399 shader
, error_messages
);
402 HRESULT WINAPI
D3DXAssembleShaderFromResourceW(HMODULE module
, const WCHAR
*resource
, const D3DXMACRO
*defines
,
403 ID3DXInclude
*include
, DWORD flags
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
409 TRACE("module %p, resource %s, defines %p, include %p, flags %#x, shader %p, error_messages %p.\n",
410 module
, debugstr_w(resource
), defines
, include
, flags
, shader
, error_messages
);
412 if (!(res
= FindResourceW(module
, resource
, (const WCHAR
*)RT_RCDATA
)))
413 return D3DXERR_INVALIDDATA
;
414 if (FAILED(load_resource_into_memory(module
, res
, &buffer
, &len
)))
415 return D3DXERR_INVALIDDATA
;
416 return D3DXAssembleShader(buffer
, len
, defines
, include
, flags
,
417 shader
, error_messages
);
420 HRESULT WINAPI
D3DXCompileShader(const char *data
, UINT length
, const D3DXMACRO
*defines
,
421 ID3DXInclude
*include
, const char *function
, const char *profile
, DWORD flags
,
422 ID3DXBuffer
**shader
, ID3DXBuffer
**error_msgs
, ID3DXConstantTable
**constant_table
)
426 TRACE("data %s, length %u, defines %p, include %p, function %s, profile %s, "
427 "flags %#x, shader %p, error_msgs %p, constant_table %p.\n",
428 debugstr_a(data
), length
, defines
, include
, debugstr_a(function
), debugstr_a(profile
),
429 flags
, shader
, error_msgs
, constant_table
);
431 hr
= D3DCompile(data
, length
, NULL
, (D3D_SHADER_MACRO
*)defines
, (ID3DInclude
*)include
,
432 function
, profile
, flags
, 0, (ID3DBlob
**)shader
, (ID3DBlob
**)error_msgs
);
434 if (SUCCEEDED(hr
) && constant_table
)
436 hr
= D3DXGetShaderConstantTable(ID3DXBuffer_GetBufferPointer(*shader
), constant_table
);
439 ID3DXBuffer_Release(*shader
);
444 /* Filter out D3DCompile warning messages that are not present with D3DCompileShader */
445 if (SUCCEEDED(hr
) && error_msgs
&& *error_msgs
)
447 char *messages
= ID3DXBuffer_GetBufferPointer(*error_msgs
);
448 DWORD size
= ID3DXBuffer_GetBufferSize(*error_msgs
);
450 /* Ensure messages are null terminated for safe processing */
451 if (size
) messages
[size
- 1] = 0;
457 /* Warning has the form "warning X3206: ... implicit truncation of vector type"
458 but we only search for "X3206:" in case d3dcompiler_43 has localization */
459 prev
= next
= strstr(messages
, "X3206:");
462 /* get pointer to beginning and end of current line */
463 while (prev
> messages
&& *(prev
- 1) != '\n') prev
--;
464 while (next
< messages
+ size
- 1 && *next
!= '\n') next
++;
465 if (next
< messages
+ size
- 1 && *next
== '\n') next
++;
467 memmove(prev
, next
, messages
+ size
- next
);
468 size
-= (next
- prev
);
471 /* Only return a buffer if the resulting string is not empty as some apps depend on that */
474 ID3DXBuffer_Release(*error_msgs
);
482 HRESULT WINAPI
D3DXCompileShaderFromFileA(const char *filename
, const D3DXMACRO
*defines
,
483 ID3DXInclude
*include
, const char *entrypoint
, const char *profile
, DWORD flags
,
484 ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
, ID3DXConstantTable
**constant_table
)
490 TRACE("filename %s, defines %p, include %p, entrypoint %s, profile %s, "
491 "flags %#x, shader %p, error_messages %p, constant_table %p.\n",
492 debugstr_a(filename
), defines
, include
, debugstr_a(entrypoint
),
493 debugstr_a(profile
), flags
, shader
, error_messages
, constant_table
);
495 if (!filename
) return D3DXERR_INVALIDDATA
;
497 len
= MultiByteToWideChar(CP_ACP
, 0, filename
, -1, NULL
, 0);
498 filename_w
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
499 if (!filename_w
) return E_OUTOFMEMORY
;
500 MultiByteToWideChar(CP_ACP
, 0, filename
, -1, filename_w
, len
);
502 ret
= D3DXCompileShaderFromFileW(filename_w
, defines
, include
,
503 entrypoint
, profile
, flags
,
504 shader
, error_messages
, constant_table
);
506 HeapFree(GetProcessHeap(), 0, filename_w
);
510 HRESULT WINAPI
D3DXCompileShaderFromFileW(const WCHAR
*filename
, const D3DXMACRO
*defines
,
511 ID3DXInclude
*include
, const char *entrypoint
, const char *profile
, DWORD flags
,
512 ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
, ID3DXConstantTable
**constant_table
)
515 DWORD len
, filename_len
;
517 struct D3DXIncludeImpl includefromfile
;
520 TRACE("filename %s, defines %p, include %p, entrypoint %s, profile %s, "
521 "flags %#x, shader %p, error_messages %p, constant_table %p.\n",
522 debugstr_w(filename
), defines
, include
, debugstr_a(entrypoint
), debugstr_a(profile
),
523 flags
, shader
, error_messages
, constant_table
);
527 includefromfile
.ID3DXInclude_iface
.lpVtbl
= &D3DXInclude_Vtbl
;
528 include
= &includefromfile
.ID3DXInclude_iface
;
531 filename_len
= WideCharToMultiByte(CP_ACP
, 0, filename
, -1, NULL
, 0, NULL
, NULL
);
532 filename_a
= HeapAlloc(GetProcessHeap(), 0, filename_len
* sizeof(char));
534 return E_OUTOFMEMORY
;
535 WideCharToMultiByte(CP_ACP
, 0, filename
, -1, filename_a
, filename_len
, NULL
, NULL
);
537 EnterCriticalSection(&from_file_mutex
);
538 hr
= ID3DXInclude_Open(include
, D3DXINC_LOCAL
, filename_a
, NULL
, &buffer
, &len
);
541 LeaveCriticalSection(&from_file_mutex
);
542 HeapFree(GetProcessHeap(), 0, filename_a
);
543 return D3DXERR_INVALIDDATA
;
546 hr
= D3DCompile(buffer
, len
, filename_a
, (const D3D_SHADER_MACRO
*)defines
,
547 (ID3DInclude
*)include
, entrypoint
, profile
, flags
, 0,
548 (ID3DBlob
**)shader
, (ID3DBlob
**)error_messages
);
550 if (SUCCEEDED(hr
) && constant_table
)
551 hr
= D3DXGetShaderConstantTable(ID3DXBuffer_GetBufferPointer(*shader
),
554 ID3DXInclude_Close(include
, buffer
);
555 LeaveCriticalSection(&from_file_mutex
);
556 HeapFree(GetProcessHeap(), 0, filename_a
);
560 HRESULT WINAPI
D3DXCompileShaderFromResourceA(HMODULE module
, const char *resource
, const D3DXMACRO
*defines
,
561 ID3DXInclude
*include
, const char *entrypoint
, const char *profile
, DWORD flags
,
562 ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
, ID3DXConstantTable
**constant_table
)
568 TRACE("module %p, resource %s, defines %p, include %p, entrypoint %s, profile %s, "
569 "flags %#x, shader %p, error_messages %p, constant_table %p.\n",
570 module
, debugstr_a(resource
), defines
, include
, debugstr_a(entrypoint
), debugstr_a(profile
),
571 flags
, shader
, error_messages
, constant_table
);
573 if (!(res
= FindResourceA(module
, resource
, (const char *)RT_RCDATA
)))
574 return D3DXERR_INVALIDDATA
;
575 if (FAILED(load_resource_into_memory(module
, res
, &buffer
, &len
)))
576 return D3DXERR_INVALIDDATA
;
577 return D3DXCompileShader(buffer
, len
, defines
, include
, entrypoint
, profile
,
578 flags
, shader
, error_messages
, constant_table
);
581 HRESULT WINAPI
D3DXCompileShaderFromResourceW(HMODULE module
, const WCHAR
*resource
, const D3DXMACRO
*defines
,
582 ID3DXInclude
*include
, const char *entrypoint
, const char *profile
, DWORD flags
,
583 ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
, ID3DXConstantTable
**constant_table
)
589 TRACE("module %p, resource %s, defines %p, include %p, entrypoint %s, profile %s, "
590 "flags %#x, shader %p, error_messages %p, constant_table %p.\n",
591 module
, debugstr_w(resource
), defines
, include
, debugstr_a(entrypoint
), debugstr_a(profile
),
592 flags
, shader
, error_messages
, constant_table
);
594 if (!(res
= FindResourceW(module
, resource
, (const WCHAR
*)RT_RCDATA
)))
595 return D3DXERR_INVALIDDATA
;
596 if (FAILED(load_resource_into_memory(module
, res
, &buffer
, &len
)))
597 return D3DXERR_INVALIDDATA
;
598 return D3DXCompileShader(buffer
, len
, defines
, include
, entrypoint
, profile
,
599 flags
, shader
, error_messages
, constant_table
);
602 HRESULT WINAPI
D3DXPreprocessShader(const char *data
, UINT data_len
, const D3DXMACRO
*defines
,
603 ID3DXInclude
*include
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
605 TRACE("data %s, data_len %u, defines %p, include %p, shader %p, error_messages %p.\n",
606 debugstr_a(data
), data_len
, defines
, include
, shader
, error_messages
);
608 return D3DPreprocess(data
, data_len
, NULL
,
609 (const D3D_SHADER_MACRO
*)defines
, (ID3DInclude
*)include
,
610 (ID3DBlob
**)shader
, (ID3DBlob
**)error_messages
);
613 HRESULT WINAPI
D3DXPreprocessShaderFromFileA(const char *filename
, const D3DXMACRO
*defines
,
614 ID3DXInclude
*include
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
616 WCHAR
*filename_w
= NULL
;
620 TRACE("filename %s, defines %p, include %p, shader %p, error_messages %p.\n",
621 debugstr_a(filename
), defines
, include
, shader
, error_messages
);
623 if (!filename
) return D3DXERR_INVALIDDATA
;
625 len
= MultiByteToWideChar(CP_ACP
, 0, filename
, -1, NULL
, 0);
626 filename_w
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
627 if (!filename_w
) return E_OUTOFMEMORY
;
628 MultiByteToWideChar(CP_ACP
, 0, filename
, -1, filename_w
, len
);
630 ret
= D3DXPreprocessShaderFromFileW(filename_w
, defines
, include
, shader
, error_messages
);
632 HeapFree(GetProcessHeap(), 0, filename_w
);
636 HRESULT WINAPI
D3DXPreprocessShaderFromFileW(const WCHAR
*filename
, const D3DXMACRO
*defines
,
637 ID3DXInclude
*include
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
642 struct D3DXIncludeImpl includefromfile
;
645 TRACE("filename %s, defines %p, include %p, shader %p, error_messages %p.\n",
646 debugstr_w(filename
), defines
, include
, shader
, error_messages
);
650 includefromfile
.ID3DXInclude_iface
.lpVtbl
= &D3DXInclude_Vtbl
;
651 include
= &includefromfile
.ID3DXInclude_iface
;
654 len
= WideCharToMultiByte(CP_ACP
, 0, filename
, -1, NULL
, 0, NULL
, NULL
);
655 filename_a
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(char));
657 return E_OUTOFMEMORY
;
658 WideCharToMultiByte(CP_ACP
, 0, filename
, -1, filename_a
, len
, NULL
, NULL
);
660 EnterCriticalSection(&from_file_mutex
);
661 hr
= ID3DXInclude_Open(include
, D3DXINC_LOCAL
, filename_a
, NULL
, &buffer
, &len
);
664 LeaveCriticalSection(&from_file_mutex
);
665 HeapFree(GetProcessHeap(), 0, filename_a
);
666 return D3DXERR_INVALIDDATA
;
669 hr
= D3DPreprocess(buffer
, len
, NULL
,
670 (const D3D_SHADER_MACRO
*)defines
,
671 (ID3DInclude
*) include
,
672 (ID3DBlob
**)shader
, (ID3DBlob
**)error_messages
);
674 ID3DXInclude_Close(include
, buffer
);
675 LeaveCriticalSection(&from_file_mutex
);
676 HeapFree(GetProcessHeap(), 0, filename_a
);
680 HRESULT WINAPI
D3DXPreprocessShaderFromResourceA(HMODULE module
, const char *resource
, const D3DXMACRO
*defines
,
681 ID3DXInclude
*include
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
687 TRACE("module %p, resource %s, defines %p, include %p, shader %p, error_messages %p.\n",
688 module
, debugstr_a(resource
), defines
, include
, shader
, error_messages
);
690 if (!(res
= FindResourceA(module
, resource
, (const char *)RT_RCDATA
)))
691 return D3DXERR_INVALIDDATA
;
692 if (FAILED(load_resource_into_memory(module
, res
, &buffer
, &len
)))
693 return D3DXERR_INVALIDDATA
;
694 return D3DXPreprocessShader(buffer
, len
, defines
, include
,
695 shader
, error_messages
);
698 HRESULT WINAPI
D3DXPreprocessShaderFromResourceW(HMODULE module
, const WCHAR
*resource
, const D3DXMACRO
*defines
,
699 ID3DXInclude
*include
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
705 TRACE("module %p, resource %s, defines %p, include %p, shader %p, error_messages %p.\n",
706 module
, debugstr_w(resource
), defines
, include
, shader
, error_messages
);
708 if (!(res
= FindResourceW(module
, resource
, (const WCHAR
*)RT_RCDATA
)))
709 return D3DXERR_INVALIDDATA
;
710 if (FAILED(load_resource_into_memory(module
, res
, &buffer
, &len
)))
711 return D3DXERR_INVALIDDATA
;
712 return D3DXPreprocessShader(buffer
, len
, defines
, include
,
713 shader
, error_messages
);
717 struct ID3DXConstantTableImpl
{
718 ID3DXConstantTable ID3DXConstantTable_iface
;
722 D3DXCONSTANTTABLE_DESC desc
;
723 struct ctab_constant
*constants
;
726 static void free_constant(struct ctab_constant
*constant
)
728 if (constant
->constants
)
730 UINT i
, count
= constant
->desc
.Elements
> 1 ? constant
->desc
.Elements
: constant
->desc
.StructMembers
;
732 for (i
= 0; i
< count
; ++i
)
734 free_constant(&constant
->constants
[i
]);
736 HeapFree(GetProcessHeap(), 0, constant
->constants
);
740 static void free_constant_table(struct ID3DXConstantTableImpl
*table
)
742 if (table
->constants
)
746 for (i
= 0; i
< table
->desc
.Constants
; ++i
)
748 free_constant(&table
->constants
[i
]);
750 HeapFree(GetProcessHeap(), 0, table
->constants
);
752 HeapFree(GetProcessHeap(), 0, table
->ctab
);
755 static inline struct ID3DXConstantTableImpl
*impl_from_ID3DXConstantTable(ID3DXConstantTable
*iface
)
757 return CONTAINING_RECORD(iface
, struct ID3DXConstantTableImpl
, ID3DXConstantTable_iface
);
760 static inline BOOL
is_vertex_shader(DWORD version
)
762 return (version
& 0xffff0000) == 0xfffe0000;
765 static inline D3DXHANDLE
handle_from_constant(struct ctab_constant
*constant
)
767 return (D3DXHANDLE
)constant
;
770 static struct ctab_constant
*get_constant_by_name(struct ID3DXConstantTableImpl
*table
,
771 struct ctab_constant
*constant
, const char *name
);
773 static struct ctab_constant
*get_constant_element_by_name(struct ctab_constant
*constant
, const char *name
)
778 TRACE("constant %p, name %s\n", constant
, debugstr_a(name
));
780 if (!name
|| !*name
) return NULL
;
782 element
= atoi(name
);
783 part
= strchr(name
, ']') + 1;
785 if (constant
->desc
.Elements
> element
)
787 struct ctab_constant
*c
= constant
->constants
? &constant
->constants
[element
] : constant
;
792 return get_constant_by_name(NULL
, c
, part
);
795 return get_constant_element_by_name(c
, part
);
798 TRACE("Returning parameter %p\n", c
);
802 FIXME("Unhandled case \"%c\"\n", *--part
);
807 TRACE("Constant not found\n");
811 static struct ctab_constant
*get_constant_by_name(struct ID3DXConstantTableImpl
*table
,
812 struct ctab_constant
*constant
, const char *name
)
814 UINT i
, count
, length
;
815 struct ctab_constant
*handles
;
818 TRACE("table %p, constant %p, name %s\n", table
, constant
, debugstr_a(name
));
820 if (!name
|| !*name
) return NULL
;
824 count
= table
->desc
.Constants
;
825 handles
= table
->constants
;
829 count
= constant
->desc
.StructMembers
;
830 handles
= constant
->constants
;
833 length
= strcspn(name
, "[.");
834 part
= name
+ length
;
836 for (i
= 0; i
< count
; i
++)
838 if (strlen(handles
[i
].desc
.Name
) == length
&& !strncmp(handles
[i
].desc
.Name
, name
, length
))
843 return get_constant_by_name(NULL
, &handles
[i
], part
);
846 return get_constant_element_by_name(&handles
[i
], part
);
849 TRACE("Returning parameter %p\n", &handles
[i
]);
855 TRACE("Constant not found\n");
859 static struct ctab_constant
*is_valid_sub_constant(struct ctab_constant
*parent
, D3DXHANDLE handle
)
861 struct ctab_constant
*c
;
864 /* all variable have at least elements = 1, but not always elements */
865 if (!parent
->constants
) return NULL
;
867 count
= parent
->desc
.Elements
> 1 ? parent
->desc
.Elements
: parent
->desc
.StructMembers
;
868 for (i
= 0; i
< count
; ++i
)
870 if (handle_from_constant(&parent
->constants
[i
]) == handle
)
871 return &parent
->constants
[i
];
873 c
= is_valid_sub_constant(&parent
->constants
[i
], handle
);
880 static inline struct ctab_constant
*get_valid_constant(struct ID3DXConstantTableImpl
*table
, D3DXHANDLE handle
)
882 struct ctab_constant
*c
;
885 if (!handle
) return NULL
;
887 for (i
= 0; i
< table
->desc
.Constants
; ++i
)
889 if (handle_from_constant(&table
->constants
[i
]) == handle
)
890 return &table
->constants
[i
];
892 c
= is_valid_sub_constant(&table
->constants
[i
], handle
);
896 return get_constant_by_name(table
, NULL
, handle
);
899 /*** IUnknown methods ***/
900 static HRESULT WINAPI
ID3DXConstantTableImpl_QueryInterface(ID3DXConstantTable
*iface
, REFIID riid
, void **out
)
902 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
904 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
905 IsEqualGUID(riid
, &IID_ID3DXBuffer
) ||
906 IsEqualGUID(riid
, &IID_ID3DXConstantTable
))
908 ID3DXConstantTable_AddRef(iface
);
913 WARN("Interface %s not found.\n", debugstr_guid(riid
));
915 return E_NOINTERFACE
;
918 static ULONG WINAPI
ID3DXConstantTableImpl_AddRef(ID3DXConstantTable
*iface
)
920 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
922 TRACE("(%p)->(): AddRef from %d\n", This
, This
->ref
);
924 return InterlockedIncrement(&This
->ref
);
927 static ULONG WINAPI
ID3DXConstantTableImpl_Release(ID3DXConstantTable
*iface
)
929 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
930 ULONG ref
= InterlockedDecrement(&This
->ref
);
932 TRACE("(%p)->(): Release from %d\n", This
, ref
+ 1);
936 free_constant_table(This
);
937 HeapFree(GetProcessHeap(), 0, This
);
943 /*** ID3DXBuffer methods ***/
944 static void * WINAPI
ID3DXConstantTableImpl_GetBufferPointer(ID3DXConstantTable
*iface
)
946 struct ID3DXConstantTableImpl
*table
= impl_from_ID3DXConstantTable(iface
);
948 TRACE("iface %p.\n", iface
);
953 static DWORD WINAPI
ID3DXConstantTableImpl_GetBufferSize(ID3DXConstantTable
*iface
)
955 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
957 TRACE("(%p)->()\n", This
);
962 /*** ID3DXConstantTable methods ***/
963 static HRESULT WINAPI
ID3DXConstantTableImpl_GetDesc(ID3DXConstantTable
*iface
, D3DXCONSTANTTABLE_DESC
*desc
)
965 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
967 TRACE("(%p)->(%p)\n", This
, desc
);
970 return D3DERR_INVALIDCALL
;
977 const struct ctab_constant
*d3dx_shader_get_ctab_constant(ID3DXConstantTable
*iface
, D3DXHANDLE constant
)
979 struct ID3DXConstantTableImpl
*ctab
= impl_from_ID3DXConstantTable(iface
);
981 return get_valid_constant(ctab
, constant
);
984 static HRESULT WINAPI
ID3DXConstantTableImpl_GetConstantDesc(ID3DXConstantTable
*iface
, D3DXHANDLE constant
,
985 D3DXCONSTANT_DESC
*desc
, UINT
*count
)
987 struct ID3DXConstantTableImpl
*ctab
= impl_from_ID3DXConstantTable(iface
);
988 struct ctab_constant
*c
= get_valid_constant(ctab
, constant
);
990 TRACE("(%p)->(%p, %p, %p)\n", ctab
, constant
, desc
, count
);
994 WARN("Invalid argument specified\n");
995 return D3DERR_INVALIDCALL
;
998 if (desc
) *desc
= c
->desc
;
999 if (count
) *count
= 1;
1004 static UINT WINAPI
ID3DXConstantTableImpl_GetSamplerIndex(ID3DXConstantTable
*iface
, D3DXHANDLE constant
)
1006 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1007 struct ctab_constant
*c
= get_valid_constant(This
, constant
);
1009 TRACE("(%p)->(%p)\n", This
, constant
);
1011 if (!c
|| c
->desc
.RegisterSet
!= D3DXRS_SAMPLER
)
1013 WARN("Invalid argument specified\n");
1017 TRACE("Returning RegisterIndex %u\n", c
->desc
.RegisterIndex
);
1018 return c
->desc
.RegisterIndex
;
1021 static D3DXHANDLE WINAPI
ID3DXConstantTableImpl_GetConstant(ID3DXConstantTable
*iface
, D3DXHANDLE constant
, UINT index
)
1023 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1024 struct ctab_constant
*c
;
1026 TRACE("(%p)->(%p, %d)\n", This
, constant
, index
);
1030 c
= get_valid_constant(This
, constant
);
1031 if (c
&& index
< c
->desc
.StructMembers
)
1033 c
= &c
->constants
[index
];
1034 TRACE("Returning constant %p\n", c
);
1035 return handle_from_constant(c
);
1040 if (index
< This
->desc
.Constants
)
1042 c
= &This
->constants
[index
];
1043 TRACE("Returning constant %p\n", c
);
1044 return handle_from_constant(c
);
1048 WARN("Index out of range\n");
1052 static D3DXHANDLE WINAPI
ID3DXConstantTableImpl_GetConstantByName(ID3DXConstantTable
*iface
,
1053 D3DXHANDLE constant
, const char *name
)
1055 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1056 struct ctab_constant
*c
= get_valid_constant(This
, constant
);
1058 TRACE("iface %p, constant %p, name %s.\n", iface
, constant
, debugstr_a(name
));
1060 c
= get_constant_by_name(This
, c
, name
);
1061 TRACE("Returning constant %p\n", c
);
1063 return handle_from_constant(c
);
1066 static D3DXHANDLE WINAPI
ID3DXConstantTableImpl_GetConstantElement(ID3DXConstantTable
*iface
, D3DXHANDLE constant
, UINT index
)
1068 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1069 struct ctab_constant
*c
= get_valid_constant(This
, constant
);
1071 TRACE("(%p)->(%p, %d)\n", This
, constant
, index
);
1073 if (c
&& index
< c
->desc
.Elements
)
1075 if (c
->desc
.Elements
> 1) c
= &c
->constants
[index
];
1076 TRACE("Returning constant %p\n", c
);
1077 return handle_from_constant(c
);
1080 WARN("Invalid argument specified\n");
1084 static inline DWORD
get_index(const void **indata
, UINT index
, BOOL is_pointer
)
1090 return ((DWORD
**)indata
)[index
/ 16][index
% 16];
1092 return (*((DWORD
**)indata
))[index
];
1095 static UINT
set(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
, struct ctab_constant
*constant
,
1096 const void **indata
, D3DXPARAMETER_TYPE intype
, UINT
*size
, UINT incol
, D3DXPARAMETER_CLASS inclass
, UINT index
,
1099 D3DXCONSTANT_DESC
*desc
= &constant
->desc
;
1100 UINT l
, i
, regcount
= 1, regsize
= 1, cin
= 1, rin
= 1, ret
, last
= 0;
1103 /* size too small to set anything */
1104 if (*size
< desc
->Rows
* desc
->Columns
)
1110 /* D3DXPC_STRUCT is somewhat special */
1111 if (desc
->Class
== D3DXPC_STRUCT
)
1114 * Struct array sets the last complete input to the first struct element, all other
1115 * elements are not set.
1116 * E.g.: struct {int i;} s1[2];
1117 * SetValue(device, "s1", [1, 2], 8) => s1 = {2, x};
1119 * struct {int i; int n} s2[2];
1120 * SetValue(device, "s2", [1, 2, 3, 4, 5], 20) => s1 = {{3, 4}, {x, x}};
1122 if (desc
->Elements
> 1)
1124 UINT offset
= *size
/ (desc
->Rows
* desc
->Columns
) - 1;
1126 offset
= min(desc
->Elements
- 1, offset
);
1127 last
= offset
* desc
->Rows
* desc
->Columns
;
1129 if ((is_pointer
|| inclass
== D3DXPC_MATRIX_ROWS
) && desc
->RegisterSet
!= D3DXRS_BOOL
)
1131 set(table
, device
, &constant
->constants
[0], NULL
, intype
, size
, incol
, inclass
, 0, is_pointer
);
1135 last
+= set(table
, device
, &constant
->constants
[0], indata
, intype
, size
, incol
, inclass
,
1136 index
+ last
, is_pointer
);
1142 * D3DXRS_BOOL is always set. As there are only 16 bools and there are
1143 * exactly 16 input values, use matrix transpose.
1145 if (inclass
== D3DXPC_MATRIX_ROWS
&& desc
->RegisterSet
== D3DXRS_BOOL
)
1147 D3DXMATRIX mat
, *m
, min
;
1148 D3DXMatrixTranspose(&mat
, &min
);
1151 min
= *(D3DXMATRIX
*)(indata
[index
/ 16]);
1153 min
= **(D3DXMATRIX
**)indata
;
1155 D3DXMatrixTranspose(&mat
, &min
);
1157 for (i
= 0; i
< desc
->StructMembers
; ++i
)
1159 last
+= set(table
, device
, &constant
->constants
[i
], (const void **)&m
, intype
, size
, incol
,
1160 D3DXPC_SCALAR
, index
+ last
, is_pointer
);
1164 * For pointers or for matrix rows, only the first member is set.
1165 * All other members are set to 0. This is not true for D3DXRS_BOOL.
1166 * E.g.: struct {int i; int n} s;
1167 * SetValue(device, "s", [1, 2], 8) => s = {1, 0};
1169 else if ((is_pointer
|| inclass
== D3DXPC_MATRIX_ROWS
) && desc
->RegisterSet
!= D3DXRS_BOOL
)
1171 last
= set(table
, device
, &constant
->constants
[0], indata
, intype
, size
, incol
, inclass
,
1172 index
+ last
, is_pointer
);
1174 for (i
= 1; i
< desc
->StructMembers
; ++i
)
1176 set(table
, device
, &constant
->constants
[i
], NULL
, intype
, size
, incol
, inclass
, 0, is_pointer
);
1181 for (i
= 0; i
< desc
->StructMembers
; ++i
)
1183 last
+= set(table
, device
, &constant
->constants
[i
], indata
, intype
, size
, incol
, D3DXPC_SCALAR
,
1184 index
+ last
, is_pointer
);
1193 if (desc
->Elements
> 1)
1195 for (i
= 0; i
< desc
->Elements
&& *size
> 0; ++i
)
1197 last
+= set(table
, device
, &constant
->constants
[i
], indata
, intype
, size
, incol
, inclass
,
1198 index
+ last
, is_pointer
);
1200 /* adjust the vector size for matrix rows */
1201 if (inclass
== D3DXPC_MATRIX_ROWS
&& desc
->Class
== D3DXPC_VECTOR
&& (i
% 4) == 3)
1204 *size
= *size
< 12 ? 0 : *size
- 12;
1211 switch (desc
->Class
)
1215 case D3DXPC_MATRIX_ROWS
:
1216 regcount
= min(desc
->RegisterCount
, desc
->Rows
);
1217 if (inclass
== D3DXPC_MATRIX_ROWS
) cin
= incol
;
1219 regsize
= desc
->Columns
;
1222 case D3DXPC_MATRIX_COLUMNS
:
1223 regcount
= min(desc
->RegisterCount
, desc
->Columns
);
1224 if (inclass
== D3DXPC_MATRIX_ROWS
) rin
= incol
;
1226 regsize
= desc
->Rows
;
1230 FIXME("Unhandled variable class %s\n", debug_d3dxparameter_class(desc
->Class
));
1234 /* specific stuff for different in types */
1238 ret
= desc
->Columns
* desc
->Rows
;
1239 *size
-= desc
->Columns
* desc
->Rows
;
1243 switch (desc
->Class
)
1245 case D3DXPC_MATRIX_ROWS
:
1246 if (*size
< regcount
* 4)
1252 *size
-= 4 * regcount
;
1255 case D3DXPC_MATRIX_COLUMNS
:
1257 *size
-= 4 * regcount
;
1271 FIXME("Unhandled variable class %s\n", debug_d3dxparameter_class(desc
->Class
));
1276 case D3DXPC_MATRIX_ROWS
:
1277 switch (desc
->Class
)
1279 case D3DXPC_MATRIX_ROWS
:
1280 case D3DXPC_MATRIX_COLUMNS
:
1298 FIXME("Unhandled variable class %s\n", debug_d3dxparameter_class(desc
->Class
));
1304 case D3DXPC_MATRIX_COLUMNS
:
1305 switch (desc
->Class
)
1307 case D3DXPC_MATRIX_ROWS
:
1308 case D3DXPC_MATRIX_COLUMNS
:
1326 FIXME("Unhandled variable class %s\n", debug_d3dxparameter_class(desc
->Class
));
1333 FIXME("Unhandled variable class %s\n", debug_d3dxparameter_class(inclass
));
1337 /* set the registers */
1338 switch (desc
->RegisterSet
)
1341 regcount
= min(desc
->RegisterCount
, desc
->Columns
* desc
->Rows
);
1343 for (i
= 0; i
< regcount
; ++i
)
1346 DWORD t
= get_index(indata
, index
+ i
/ regsize
* rin
+ l
* cin
, is_pointer
);
1348 set_number(&tmp
, desc
->Type
, &t
, intype
);
1349 set_number(&out
, D3DXPT_BOOL
, &tmp
, desc
->Type
);
1350 if (is_vertex_shader(table
->desc
.Version
))
1351 IDirect3DDevice9_SetVertexShaderConstantB(device
, desc
->RegisterIndex
+ i
, &out
, 1);
1353 IDirect3DDevice9_SetPixelShaderConstantB(device
, desc
->RegisterIndex
+ i
, &out
, 1);
1355 if (++l
>= regsize
) l
= 0;
1360 for (i
= 0; i
< regcount
; ++i
)
1362 INT vec
[4] = {0, 0, 1, 0};
1364 for (l
= 0; l
< regsize
; ++l
)
1366 DWORD t
= get_index(indata
, index
+ i
* rin
+ l
* cin
, is_pointer
);
1368 set_number(&tmp
, desc
->Type
, &t
, intype
);
1369 set_number(&vec
[l
], D3DXPT_INT
, &tmp
, desc
->Type
);
1371 if (is_vertex_shader(table
->desc
.Version
))
1372 IDirect3DDevice9_SetVertexShaderConstantI(device
, desc
->RegisterIndex
+ i
, vec
, 1);
1374 IDirect3DDevice9_SetPixelShaderConstantI(device
, desc
->RegisterIndex
+ i
, vec
, 1);
1379 for (i
= 0; i
< regcount
; ++i
)
1383 for (l
= 0; l
< regsize
; ++l
)
1385 DWORD t
= get_index(indata
, index
+ i
* rin
+ l
* cin
, is_pointer
);
1387 set_number(&tmp
, desc
->Type
, &t
, intype
);
1388 set_number(&vec
[l
], D3DXPT_FLOAT
, &tmp
, desc
->Type
);
1390 if (is_vertex_shader(table
->desc
.Version
))
1391 IDirect3DDevice9_SetVertexShaderConstantF(device
, desc
->RegisterIndex
+ i
, vec
, 1);
1393 IDirect3DDevice9_SetPixelShaderConstantF(device
, desc
->RegisterIndex
+ i
, vec
, 1);
1398 FIXME("Unhandled register set %s\n", debug_d3dxparameter_registerset(desc
->RegisterSet
));
1403 static HRESULT
set_scalar(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
, D3DXHANDLE constant
,
1404 const void *indata
, D3DXPARAMETER_TYPE intype
)
1406 struct ctab_constant
*c
= get_valid_constant(table
, constant
);
1411 WARN("Invalid argument specified\n");
1412 return D3DERR_INVALIDCALL
;
1415 switch (c
->desc
.Class
)
1418 set(table
, device
, c
, &indata
, intype
, &count
, c
->desc
.Columns
, D3DXPC_SCALAR
, 0, FALSE
);
1422 case D3DXPC_MATRIX_ROWS
:
1423 case D3DXPC_MATRIX_COLUMNS
:
1428 FIXME("Unhandled parameter class %s\n", debug_d3dxparameter_class(c
->desc
.Class
));
1429 return D3DERR_INVALIDCALL
;
1433 static HRESULT
set_scalar_array(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
, D3DXHANDLE constant
,
1434 const void *indata
, UINT count
, D3DXPARAMETER_TYPE intype
)
1436 struct ctab_constant
*c
= get_valid_constant(table
, constant
);
1440 WARN("Invalid argument specified\n");
1441 return D3DERR_INVALIDCALL
;
1444 switch (c
->desc
.Class
)
1448 case D3DXPC_MATRIX_ROWS
:
1449 case D3DXPC_MATRIX_COLUMNS
:
1451 set(table
, device
, c
, &indata
, intype
, &count
, c
->desc
.Columns
, D3DXPC_SCALAR
, 0, FALSE
);
1455 FIXME("Unhandled parameter class %s\n", debug_d3dxparameter_class(c
->desc
.Class
));
1456 return D3DERR_INVALIDCALL
;
1460 static HRESULT
set_vector(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
, D3DXHANDLE constant
,
1461 const void *indata
, D3DXPARAMETER_TYPE intype
)
1463 struct ctab_constant
*c
= get_valid_constant(table
, constant
);
1468 WARN("Invalid argument specified\n");
1469 return D3DERR_INVALIDCALL
;
1472 switch (c
->desc
.Class
)
1477 set(table
, device
, c
, &indata
, intype
, &count
, 4, D3DXPC_VECTOR
, 0, FALSE
);
1480 case D3DXPC_MATRIX_ROWS
:
1481 case D3DXPC_MATRIX_COLUMNS
:
1485 FIXME("Unhandled parameter class %s\n", debug_d3dxparameter_class(c
->desc
.Class
));
1486 return D3DERR_INVALIDCALL
;
1490 static HRESULT
set_vector_array(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
, D3DXHANDLE constant
,
1491 const void *indata
, UINT count
, D3DXPARAMETER_TYPE intype
)
1493 struct ctab_constant
*c
= get_valid_constant(table
, constant
);
1497 WARN("Invalid argument specified\n");
1498 return D3DERR_INVALIDCALL
;
1501 switch (c
->desc
.Class
)
1505 case D3DXPC_MATRIX_ROWS
:
1506 case D3DXPC_MATRIX_COLUMNS
:
1509 set(table
, device
, c
, &indata
, intype
, &count
, 4, D3DXPC_VECTOR
, 0, FALSE
);
1513 FIXME("Unhandled parameter class %s\n", debug_d3dxparameter_class(c
->desc
.Class
));
1514 return D3DERR_INVALIDCALL
;
1518 static HRESULT
set_matrix_array(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
, D3DXHANDLE constant
,
1519 const void *indata
, UINT count
, BOOL transpose
)
1521 struct ctab_constant
*c
= get_valid_constant(table
, constant
);
1525 WARN("Invalid argument specified\n");
1526 return D3DERR_INVALIDCALL
;
1529 switch (c
->desc
.Class
)
1533 case D3DXPC_MATRIX_ROWS
:
1534 case D3DXPC_MATRIX_COLUMNS
:
1537 set(table
, device
, c
, &indata
, D3DXPT_FLOAT
, &count
, 4,
1538 transpose
? D3DXPC_MATRIX_ROWS
: D3DXPC_MATRIX_COLUMNS
, 0, FALSE
);
1542 FIXME("Unhandled parameter class %s\n", debug_d3dxparameter_class(c
->desc
.Class
));
1543 return D3DERR_INVALIDCALL
;
1547 static HRESULT
set_matrix_pointer_array(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
,
1548 D3DXHANDLE constant
, const void **indata
, UINT count
, BOOL transpose
)
1550 struct ctab_constant
*c
= get_valid_constant(table
, constant
);
1554 WARN("Invalid argument specified\n");
1555 return D3DERR_INVALIDCALL
;
1558 switch (c
->desc
.Class
)
1562 case D3DXPC_MATRIX_ROWS
:
1563 case D3DXPC_MATRIX_COLUMNS
:
1566 set(table
, device
, c
, indata
, D3DXPT_FLOAT
, &count
, 4,
1567 transpose
? D3DXPC_MATRIX_ROWS
: D3DXPC_MATRIX_COLUMNS
, 0, TRUE
);
1571 FIXME("Unhandled parameter class %s\n", debug_d3dxparameter_class(c
->desc
.Class
));
1572 return D3DERR_INVALIDCALL
;
1576 static HRESULT WINAPI
ID3DXConstantTableImpl_SetDefaults(struct ID3DXConstantTable
*iface
,
1577 struct IDirect3DDevice9
*device
)
1579 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1582 TRACE("iface %p, device %p\n", iface
, device
);
1586 WARN("Invalid argument specified\n");
1587 return D3DERR_INVALIDCALL
;
1590 for (i
= 0; i
< This
->desc
.Constants
; i
++)
1592 D3DXCONSTANT_DESC
*desc
= &This
->constants
[i
].desc
;
1595 if (!desc
->DefaultValue
)
1598 switch (desc
->RegisterSet
)
1601 if (is_vertex_shader(This
->desc
.Version
))
1602 hr
= IDirect3DDevice9_SetVertexShaderConstantB(device
, desc
->RegisterIndex
, desc
->DefaultValue
,
1603 desc
->RegisterCount
);
1605 hr
= IDirect3DDevice9_SetPixelShaderConstantB(device
, desc
->RegisterIndex
, desc
->DefaultValue
,
1606 desc
->RegisterCount
);
1610 if (is_vertex_shader(This
->desc
.Version
))
1611 hr
= IDirect3DDevice9_SetVertexShaderConstantI(device
, desc
->RegisterIndex
, desc
->DefaultValue
,
1612 desc
->RegisterCount
);
1614 hr
= IDirect3DDevice9_SetPixelShaderConstantI(device
, desc
->RegisterIndex
, desc
->DefaultValue
,
1615 desc
->RegisterCount
);
1619 if (is_vertex_shader(This
->desc
.Version
))
1620 hr
= IDirect3DDevice9_SetVertexShaderConstantF(device
, desc
->RegisterIndex
, desc
->DefaultValue
,
1621 desc
->RegisterCount
);
1623 hr
= IDirect3DDevice9_SetPixelShaderConstantF(device
, desc
->RegisterIndex
, desc
->DefaultValue
,
1624 desc
->RegisterCount
);
1628 FIXME("Unhandled register set %s\n", debug_d3dxparameter_registerset(desc
->RegisterSet
));
1640 static HRESULT WINAPI
ID3DXConstantTableImpl_SetValue(struct ID3DXConstantTable
*iface
,
1641 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const void *data
, unsigned int bytes
)
1643 struct ID3DXConstantTableImpl
*table
= impl_from_ID3DXConstantTable(iface
);
1644 struct ctab_constant
*c
= get_valid_constant(table
, constant
);
1645 D3DXCONSTANT_DESC
*desc
;
1647 TRACE("iface %p, device %p, constant %p, data %p, bytes %u\n", iface
, device
, constant
, data
, bytes
);
1649 if (!device
|| !c
|| !data
)
1651 WARN("Invalid argument specified\n");
1652 return D3DERR_INVALIDCALL
;
1657 switch (desc
->Class
)
1661 case D3DXPC_MATRIX_ROWS
:
1662 case D3DXPC_MATRIX_COLUMNS
:
1665 set(table
, device
, c
, &data
, desc
->Type
, &bytes
, desc
->Columns
, D3DXPC_SCALAR
, 0, FALSE
);
1669 FIXME("Unhandled parameter class %s\n", debug_d3dxparameter_class(desc
->Class
));
1670 return D3DERR_INVALIDCALL
;
1674 static HRESULT WINAPI
ID3DXConstantTableImpl_SetBool(struct ID3DXConstantTable
*iface
,
1675 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, BOOL b
)
1677 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1679 TRACE("iface %p, device %p, constant %p, b %d\n", iface
, device
, constant
, b
);
1681 return set_scalar(This
, device
, constant
, &b
, D3DXPT_BOOL
);
1684 static HRESULT WINAPI
ID3DXConstantTableImpl_SetBoolArray(struct ID3DXConstantTable
*iface
,
1685 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const BOOL
*b
, UINT count
)
1687 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1689 TRACE("iface %p, device %p, constant %p, b %p, count %d\n", iface
, device
, constant
, b
, count
);
1691 return set_scalar_array(This
, device
, constant
, b
, count
, D3DXPT_BOOL
);
1694 static HRESULT WINAPI
ID3DXConstantTableImpl_SetInt(struct ID3DXConstantTable
*iface
,
1695 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, INT n
)
1697 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1699 TRACE("iface %p, device %p, constant %p, n %d\n", iface
, device
, constant
, n
);
1701 return set_scalar(This
, device
, constant
, &n
, D3DXPT_INT
);
1704 static HRESULT WINAPI
ID3DXConstantTableImpl_SetIntArray(struct ID3DXConstantTable
*iface
,
1705 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const INT
*n
, UINT count
)
1707 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1709 TRACE("iface %p, device %p, constant %p, n %p, count %d\n", iface
, device
, constant
, n
, count
);
1711 return set_scalar_array(This
, device
, constant
, n
, count
, D3DXPT_INT
);
1714 static HRESULT WINAPI
ID3DXConstantTableImpl_SetFloat(struct ID3DXConstantTable
*iface
,
1715 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, float f
)
1717 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1719 TRACE("iface %p, device %p, constant %p, f %f\n", iface
, device
, constant
, f
);
1721 return set_scalar(This
, device
, constant
, &f
, D3DXPT_FLOAT
);
1724 static HRESULT WINAPI
ID3DXConstantTableImpl_SetFloatArray(struct ID3DXConstantTable
*iface
,
1725 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const float *f
, UINT count
)
1727 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1729 TRACE("iface %p, device %p, constant %p, f %p, count %d\n", iface
, device
, constant
, f
, count
);
1731 return set_scalar_array(This
, device
, constant
, f
, count
, D3DXPT_FLOAT
);
1734 static HRESULT WINAPI
ID3DXConstantTableImpl_SetVector(struct ID3DXConstantTable
*iface
,
1735 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXVECTOR4
*vector
)
1737 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1739 TRACE("iface %p, device %p, constant %p, vector %p\n", iface
, device
, constant
, vector
);
1741 return set_vector(This
, device
, constant
, vector
, D3DXPT_FLOAT
);
1744 static HRESULT WINAPI
ID3DXConstantTableImpl_SetVectorArray(struct ID3DXConstantTable
*iface
,
1745 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXVECTOR4
*vector
, UINT count
)
1747 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1749 TRACE("iface %p, device %p, constant %p, vector %p, count %u\n", iface
, device
, constant
, vector
, count
);
1751 return set_vector_array(This
, device
, constant
, vector
, count
, D3DXPT_FLOAT
);
1754 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrix(struct ID3DXConstantTable
*iface
,
1755 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXMATRIX
*matrix
)
1757 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1759 TRACE("iface %p, device %p, constant %p, matrix %p\n", iface
, device
, constant
, matrix
);
1761 return set_matrix_array(This
, device
, constant
, matrix
, 1, FALSE
);
1764 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrixArray(struct ID3DXConstantTable
*iface
,
1765 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXMATRIX
*matrix
, UINT count
)
1767 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1769 TRACE("iface %p, device %p, constant %p, matrix %p, count %u\n", iface
, device
, constant
, matrix
, count
);
1771 return set_matrix_array(This
, device
, constant
, matrix
, count
, FALSE
);
1774 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrixPointerArray(struct ID3DXConstantTable
*iface
,
1775 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXMATRIX
**matrix
, UINT count
)
1777 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1779 TRACE("iface %p, device %p, constant %p, matrix %p, count %u)\n", iface
, device
, constant
, matrix
, count
);
1781 return set_matrix_pointer_array(This
, device
, constant
, (const void **)matrix
, count
, FALSE
);
1784 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrixTranspose(struct ID3DXConstantTable
*iface
,
1785 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXMATRIX
*matrix
)
1787 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1789 TRACE("iface %p, device %p, constant %p, matrix %p\n", iface
, device
, constant
, matrix
);
1791 return set_matrix_array(This
, device
, constant
, matrix
, 1, TRUE
);
1794 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrixTransposeArray(struct ID3DXConstantTable
*iface
,
1795 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXMATRIX
*matrix
, UINT count
)
1797 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1799 TRACE("iface %p, device %p, constant %p, matrix %p, count %u\n", iface
, device
, constant
, matrix
, count
);
1801 return set_matrix_array(This
, device
, constant
, matrix
, count
, TRUE
);
1804 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrixTransposePointerArray(struct ID3DXConstantTable
*iface
,
1805 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXMATRIX
**matrix
, UINT count
)
1807 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1809 TRACE("iface %p, device %p, constant %p, matrix %p, count %u)\n", iface
, device
, constant
, matrix
, count
);
1811 return set_matrix_pointer_array(This
, device
, constant
, (const void **)matrix
, count
, TRUE
);
1814 static const struct ID3DXConstantTableVtbl ID3DXConstantTable_Vtbl
=
1816 /*** IUnknown methods ***/
1817 ID3DXConstantTableImpl_QueryInterface
,
1818 ID3DXConstantTableImpl_AddRef
,
1819 ID3DXConstantTableImpl_Release
,
1820 /*** ID3DXBuffer methods ***/
1821 ID3DXConstantTableImpl_GetBufferPointer
,
1822 ID3DXConstantTableImpl_GetBufferSize
,
1823 /*** ID3DXConstantTable methods ***/
1824 ID3DXConstantTableImpl_GetDesc
,
1825 ID3DXConstantTableImpl_GetConstantDesc
,
1826 ID3DXConstantTableImpl_GetSamplerIndex
,
1827 ID3DXConstantTableImpl_GetConstant
,
1828 ID3DXConstantTableImpl_GetConstantByName
,
1829 ID3DXConstantTableImpl_GetConstantElement
,
1830 ID3DXConstantTableImpl_SetDefaults
,
1831 ID3DXConstantTableImpl_SetValue
,
1832 ID3DXConstantTableImpl_SetBool
,
1833 ID3DXConstantTableImpl_SetBoolArray
,
1834 ID3DXConstantTableImpl_SetInt
,
1835 ID3DXConstantTableImpl_SetIntArray
,
1836 ID3DXConstantTableImpl_SetFloat
,
1837 ID3DXConstantTableImpl_SetFloatArray
,
1838 ID3DXConstantTableImpl_SetVector
,
1839 ID3DXConstantTableImpl_SetVectorArray
,
1840 ID3DXConstantTableImpl_SetMatrix
,
1841 ID3DXConstantTableImpl_SetMatrixArray
,
1842 ID3DXConstantTableImpl_SetMatrixPointerArray
,
1843 ID3DXConstantTableImpl_SetMatrixTranspose
,
1844 ID3DXConstantTableImpl_SetMatrixTransposeArray
,
1845 ID3DXConstantTableImpl_SetMatrixTransposePointerArray
1848 static HRESULT
parse_ctab_constant_type(const char *ctab
, DWORD typeoffset
, struct ctab_constant
*constant
,
1849 BOOL is_element
, WORD index
, WORD max_index
, DWORD
*offset
, DWORD nameoffset
, UINT regset
)
1851 const D3DXSHADER_TYPEINFO
*type
= (LPD3DXSHADER_TYPEINFO
)(ctab
+ typeoffset
);
1852 const D3DXSHADER_STRUCTMEMBERINFO
*memberinfo
= NULL
;
1853 HRESULT hr
= D3D_OK
;
1857 constant
->desc
.DefaultValue
= offset
? ctab
+ *offset
: NULL
;
1858 constant
->desc
.Class
= type
->Class
;
1859 constant
->desc
.Type
= type
->Type
;
1860 constant
->desc
.Rows
= type
->Rows
;
1861 constant
->desc
.Columns
= type
->Columns
;
1862 constant
->desc
.Elements
= is_element
? 1 : type
->Elements
;
1863 constant
->desc
.StructMembers
= type
->StructMembers
;
1864 constant
->desc
.Name
= ctab
+ nameoffset
;
1865 constant
->desc
.RegisterSet
= regset
;
1866 constant
->desc
.RegisterIndex
= index
;
1868 TRACE("name %s, elements %u, index %u, defaultvalue %p, regset %s\n", constant
->desc
.Name
,
1869 constant
->desc
.Elements
, index
, constant
->desc
.DefaultValue
,
1870 debug_d3dxparameter_registerset(regset
));
1871 TRACE("class %s, type %s, rows %d, columns %d, elements %d, struct_members %d\n",
1872 debug_d3dxparameter_class(type
->Class
), debug_d3dxparameter_type(type
->Type
),
1873 type
->Rows
, type
->Columns
, type
->Elements
, type
->StructMembers
);
1875 if (type
->Elements
> 1 && !is_element
)
1877 count
= type
->Elements
;
1879 else if ((type
->Class
== D3DXPC_STRUCT
) && type
->StructMembers
)
1881 memberinfo
= (D3DXSHADER_STRUCTMEMBERINFO
*)(ctab
+ type
->StructMemberInfo
);
1882 count
= type
->StructMembers
;
1887 constant
->constants
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*constant
->constants
) * count
);
1888 if (!constant
->constants
)
1890 ERR("Out of memory\n");
1895 for (i
= 0; i
< count
; ++i
)
1897 hr
= parse_ctab_constant_type(ctab
, memberinfo
? memberinfo
[i
].TypeInfo
: typeoffset
,
1898 &constant
->constants
[i
], memberinfo
== NULL
, index
+ size
, max_index
, offset
,
1899 memberinfo
? memberinfo
[i
].Name
: nameoffset
, regset
);
1903 size
+= constant
->constants
[i
].desc
.RegisterCount
;
1908 WORD offsetdiff
= type
->Columns
* type
->Rows
;
1911 size
= type
->Columns
* type
->Rows
;
1916 fail
= type
->Class
!= D3DXPC_SCALAR
&& type
->Class
!= D3DXPC_VECTOR
1917 && type
->Class
!= D3DXPC_MATRIX_ROWS
&& type
->Class
!= D3DXPC_MATRIX_COLUMNS
;
1922 switch (type
->Class
)
1928 offsetdiff
= type
->Rows
* 4;
1931 case D3DXPC_MATRIX_ROWS
:
1932 offsetdiff
= type
->Rows
* 4;
1936 case D3DXPC_MATRIX_COLUMNS
:
1937 offsetdiff
= type
->Columns
* 4;
1938 size
= type
->Columns
;
1947 case D3DXRS_SAMPLER
:
1949 fail
= type
->Class
!= D3DXPC_OBJECT
;
1959 FIXME("Unhandled register set %s, type class %s\n", debug_d3dxparameter_registerset(regset
),
1960 debug_d3dxparameter_class(type
->Class
));
1963 /* offset in bytes => offsetdiff * sizeof(DWORD) */
1964 if (offset
) *offset
+= offsetdiff
* 4;
1967 constant
->desc
.RegisterCount
= max(0, min(max_index
- index
, size
));
1968 constant
->desc
.Bytes
= 4 * constant
->desc
.Elements
* type
->Rows
* type
->Columns
;
1973 if (constant
->constants
)
1975 for (i
= 0; i
< count
; ++i
)
1977 free_constant(&constant
->constants
[i
]);
1979 HeapFree(GetProcessHeap(), 0, constant
->constants
);
1980 constant
->constants
= NULL
;
1986 HRESULT WINAPI
D3DXGetShaderConstantTableEx(const DWORD
*byte_code
, DWORD flags
, ID3DXConstantTable
**constant_table
)
1988 struct ID3DXConstantTableImpl
*object
= NULL
;
1992 const D3DXSHADER_CONSTANTTABLE
*ctab_header
;
1993 const D3DXSHADER_CONSTANTINFO
*constant_info
;
1996 TRACE("byte_code %p, flags %x, constant_table %p\n", byte_code
, flags
, constant_table
);
1998 if (constant_table
) *constant_table
= NULL
;
2000 if (!byte_code
|| !constant_table
)
2002 WARN("Invalid argument specified.\n");
2003 return D3DERR_INVALIDCALL
;
2006 if (!is_valid_bytecode(*byte_code
))
2008 WARN("Invalid byte_code specified.\n");
2012 if (flags
) FIXME("Flags (%#x) are not handled, yet!\n", flags
);
2014 hr
= D3DXFindShaderComment(byte_code
, MAKEFOURCC('C','T','A','B'), &data
, &size
);
2017 WARN("CTAB not found.\n");
2018 return D3DXERR_INVALIDDATA
;
2021 if (size
< sizeof(*ctab_header
))
2023 WARN("Invalid CTAB size.\n");
2024 return D3DXERR_INVALIDDATA
;
2027 ctab_header
= (const D3DXSHADER_CONSTANTTABLE
*)data
;
2028 if (ctab_header
->Size
!= sizeof(*ctab_header
))
2030 WARN("Invalid D3DXSHADER_CONSTANTTABLE size.\n");
2031 return D3DXERR_INVALIDDATA
;
2034 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*object
));
2036 return E_OUTOFMEMORY
;
2038 object
->ID3DXConstantTable_iface
.lpVtbl
= &ID3DXConstantTable_Vtbl
;
2041 object
->ctab
= HeapAlloc(GetProcessHeap(), 0, size
);
2044 ERR("Out of memory\n");
2045 HeapFree(GetProcessHeap(), 0, object
);
2046 return E_OUTOFMEMORY
;
2048 object
->size
= size
;
2049 memcpy(object
->ctab
, data
, object
->size
);
2051 object
->desc
.Creator
= ctab_header
->Creator
? object
->ctab
+ ctab_header
->Creator
: NULL
;
2052 object
->desc
.Version
= ctab_header
->Version
;
2053 object
->desc
.Constants
= ctab_header
->Constants
;
2054 TRACE("Creator %s, Version %x, Constants %u, Target %s\n",
2055 debugstr_a(object
->desc
.Creator
), object
->desc
.Version
, object
->desc
.Constants
,
2056 debugstr_a(ctab_header
->Target
? object
->ctab
+ ctab_header
->Target
: NULL
));
2058 object
->constants
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
2059 sizeof(*object
->constants
) * object
->desc
.Constants
);
2060 if (!object
->constants
)
2062 ERR("Out of memory\n");
2067 constant_info
= (const D3DXSHADER_CONSTANTINFO
*)(object
->ctab
+ ctab_header
->ConstantInfo
);
2068 for (i
= 0; i
< ctab_header
->Constants
; i
++)
2070 DWORD offset
= constant_info
[i
].DefaultValue
;
2072 hr
= parse_ctab_constant_type(object
->ctab
, constant_info
[i
].TypeInfo
,
2073 &object
->constants
[i
], FALSE
, constant_info
[i
].RegisterIndex
,
2074 constant_info
[i
].RegisterIndex
+ constant_info
[i
].RegisterCount
,
2075 offset
? &offset
: NULL
, constant_info
[i
].Name
, constant_info
[i
].RegisterSet
);
2080 * Set the register count, it may differ for D3DXRS_INT4, because somehow
2081 * it makes the assumption that the register size is 1 instead of 4, so the
2082 * count is 4 times bigger. This holds true only for toplevel shader
2083 * constants. The count of elements and members is always based on a
2084 * register size of 4.
2086 if (object
->constants
[i
].desc
.RegisterSet
== D3DXRS_INT4
)
2088 object
->constants
[i
].desc
.RegisterCount
= constant_info
[i
].RegisterCount
;
2090 object
->constants
[i
].constantinfo_reserved
= constant_info
[i
].Reserved
;
2093 *constant_table
= &object
->ID3DXConstantTable_iface
;
2098 free_constant_table(object
);
2099 HeapFree(GetProcessHeap(), 0, object
);
2104 HRESULT WINAPI
D3DXGetShaderConstantTable(const DWORD
*byte_code
, ID3DXConstantTable
**constant_table
)
2106 TRACE("(%p, %p): Forwarded to D3DXGetShaderConstantTableEx\n", byte_code
, constant_table
);
2108 return D3DXGetShaderConstantTableEx(byte_code
, 0, constant_table
);
2111 HRESULT WINAPI
D3DXCreateFragmentLinker(IDirect3DDevice9
*device
, UINT size
, ID3DXFragmentLinker
**linker
)
2113 FIXME("device %p, size %u, linker %p: stub.\n", device
, size
, linker
);
2122 HRESULT WINAPI
D3DXCreateFragmentLinkerEx(IDirect3DDevice9
*device
, UINT size
, DWORD flags
, ID3DXFragmentLinker
**linker
)
2124 FIXME("device %p, size %u, flags %#x, linker %p: stub.\n", device
, size
, flags
, linker
);
2132 HRESULT WINAPI
D3DXGetShaderSamplers(const DWORD
*byte_code
, const char **samplers
, UINT
*count
)
2134 UINT i
, sampler_count
= 0;
2137 const D3DXSHADER_CONSTANTTABLE
*ctab_header
;
2138 const D3DXSHADER_CONSTANTINFO
*constant_info
;
2140 TRACE("byte_code %p, samplers %p, count %p\n", byte_code
, samplers
, count
);
2142 if (count
) *count
= 0;
2144 if (D3DXFindShaderComment(byte_code
, MAKEFOURCC('C','T','A','B'), (const void **)&data
, &size
) != D3D_OK
)
2147 if (size
< sizeof(*ctab_header
)) return D3D_OK
;
2149 ctab_header
= (const D3DXSHADER_CONSTANTTABLE
*)data
;
2150 if (ctab_header
->Size
!= sizeof(*ctab_header
)) return D3D_OK
;
2152 constant_info
= (const D3DXSHADER_CONSTANTINFO
*)(data
+ ctab_header
->ConstantInfo
);
2153 for (i
= 0; i
< ctab_header
->Constants
; i
++)
2155 const D3DXSHADER_TYPEINFO
*type
;
2157 TRACE("name = %s\n", data
+ constant_info
[i
].Name
);
2159 type
= (const D3DXSHADER_TYPEINFO
*)(data
+ constant_info
[i
].TypeInfo
);
2161 if (type
->Type
== D3DXPT_SAMPLER
2162 || type
->Type
== D3DXPT_SAMPLER1D
2163 || type
->Type
== D3DXPT_SAMPLER2D
2164 || type
->Type
== D3DXPT_SAMPLER3D
2165 || type
->Type
== D3DXPT_SAMPLERCUBE
)
2167 if (samplers
) samplers
[sampler_count
] = data
+ constant_info
[i
].Name
;
2173 TRACE("Found %u samplers\n", sampler_count
);
2175 if (count
) *count
= sampler_count
;
2181 static const char *decl_usage
[] = { "position", "blendweight", "blendindices", "normal", "psize", "texcoord",
2182 "tangent", "binormal", "tessfactor", "positiont", "color" };
2184 static const char *tex_type
[] = { "", "1d", "2d", "cube", "volume" };
2186 static int add_modifier(char *buffer
, DWORD param
)
2189 DWORD dst_mod
= param
& D3DSP_DSTMOD_MASK
;
2191 if (dst_mod
& D3DSPDM_SATURATE
)
2192 buf
+= sprintf(buf
, "_sat");
2193 if (dst_mod
& D3DSPDM_PARTIALPRECISION
)
2194 buf
+= sprintf(buf
, "_pp");
2195 if (dst_mod
& D3DSPDM_MSAMPCENTROID
)
2196 buf
+= sprintf(buf
, "_centroid");
2198 return buf
- buffer
;
2201 static int add_register(char *buffer
, DWORD param
, BOOL dst
, BOOL ps
)
2204 DWORD reg_type
= ((param
& D3DSP_REGTYPE_MASK2
) >> D3DSP_REGTYPE_SHIFT2
)
2205 | ((param
& D3DSP_REGTYPE_MASK
) >> D3DSP_REGTYPE_SHIFT
);
2206 DWORD reg_num
= param
& D3DSP_REGNUM_MASK
;
2208 if (reg_type
== D3DSPR_INPUT
)
2209 buf
+= sprintf(buf
, "v%d", reg_num
);
2210 else if (reg_type
== D3DSPR_CONST
)
2211 buf
+= sprintf(buf
, "c%d", reg_num
);
2212 else if (reg_type
== D3DSPR_TEMP
)
2213 buf
+= sprintf(buf
, "r%d", reg_num
);
2214 else if (reg_type
== D3DSPR_ADDR
)
2215 buf
+= sprintf(buf
, "%s%d", ps
? "t" : "a", reg_num
);
2216 else if (reg_type
== D3DSPR_SAMPLER
)
2217 buf
+= sprintf(buf
, "s%d", reg_num
);
2218 else if (reg_type
== D3DSPR_RASTOUT
)
2219 buf
+= sprintf(buf
, "oPos");
2220 else if (reg_type
== D3DSPR_COLOROUT
)
2221 buf
+= sprintf(buf
, "oC%d", reg_num
);
2222 else if (reg_type
== D3DSPR_TEXCRDOUT
)
2223 buf
+= sprintf(buf
, "oT%d", reg_num
);
2224 else if (reg_type
== D3DSPR_ATTROUT
)
2225 buf
+= sprintf(buf
, "oD%d", reg_num
);
2227 buf
+= sprintf(buf
, "? (%d)", reg_type
);
2231 if ((param
& D3DSP_WRITEMASK_ALL
) != D3DSP_WRITEMASK_ALL
)
2233 buf
+= sprintf(buf
, ".%s%s%s%s", param
& D3DSP_WRITEMASK_0
? "x" : "",
2234 param
& D3DSP_WRITEMASK_1
? "y" : "",
2235 param
& D3DSP_WRITEMASK_2
? "z" : "",
2236 param
& D3DSP_WRITEMASK_3
? "w" : "");
2241 if ((param
& D3DVS_SWIZZLE_MASK
) != D3DVS_NOSWIZZLE
)
2243 if ( ((param
& D3DSP_SWIZZLE_MASK
) == (D3DVS_X_X
| D3DVS_Y_X
| D3DVS_Z_X
| D3DVS_W_X
)) ||
2244 ((param
& D3DSP_SWIZZLE_MASK
) == (D3DVS_X_Y
| D3DVS_Y_Y
| D3DVS_Z_Y
| D3DVS_W_Y
)) ||
2245 ((param
& D3DSP_SWIZZLE_MASK
) == (D3DVS_X_Z
| D3DVS_Y_Z
| D3DVS_Z_Z
| D3DVS_W_Z
)) ||
2246 ((param
& D3DSP_SWIZZLE_MASK
) == (D3DVS_X_W
| D3DVS_Y_W
| D3DVS_Z_W
| D3DVS_W_W
)) )
2247 buf
+= sprintf(buf
, ".%c", 'w' + (((param
>> D3DVS_SWIZZLE_SHIFT
) + 1) & 0x3));
2249 buf
+= sprintf(buf
, ".%c%c%c%c", 'w' + (((param
>> (D3DVS_SWIZZLE_SHIFT
+0)) + 1) & 0x3),
2250 'w' + (((param
>> (D3DVS_SWIZZLE_SHIFT
+2)) + 1) & 0x3),
2251 'w' + (((param
>> (D3DVS_SWIZZLE_SHIFT
+4)) + 1) & 0x3),
2252 'w' + (((param
>> (D3DVS_SWIZZLE_SHIFT
+6)) + 1) & 0x3));
2256 return buf
- buffer
;
2264 int (*function
)(const struct instr_info
*info
, DWORD
**ptr
, char *buffer
, BOOL ps
);
2269 static int instr_comment(const struct instr_info
*info
, DWORD
**ptr
, char *buffer
, BOOL ps
)
2271 *ptr
+= 1 + ((**ptr
& D3DSI_COMMENTSIZE_MASK
) >> D3DSI_COMMENTSIZE_SHIFT
);
2275 static int instr_def(const struct instr_info
*info
, DWORD
**ptr
, char *buffer
, BOOL ps
)
2277 int len
= sprintf(buffer
, " def c%d, %g, %g, %g, %g\n", *(*ptr
+1) & D3DSP_REGNUM_MASK
,
2278 (double)*(float*)(*ptr
+2), (double)*(float*)(*ptr
+3),
2279 (double)*(float*)(*ptr
+4), (double)*(float*)(*ptr
+5));
2284 static int instr_dcl(const struct instr_info
*info
, DWORD
**ptr
, char *buffer
, BOOL ps
)
2286 DWORD param1
= *++*ptr
;
2287 DWORD param2
= *++*ptr
;
2288 DWORD usage
= (param1
& D3DSP_DCL_USAGE_MASK
) >> D3DSP_DCL_USAGE_SHIFT
;
2289 DWORD usage_index
= (param1
& D3DSP_DCL_USAGEINDEX_MASK
) >> D3DSP_DCL_USAGEINDEX_SHIFT
;
2292 buf
+= sprintf(buf
, " dcl");
2295 if (param1
& D3DSP_TEXTURETYPE_MASK
)
2296 buf
+= sprintf(buf
, "_%s", (usage
<= D3DSTT_VOLUME
) ?
2297 tex_type
[(param1
& D3DSP_TEXTURETYPE_MASK
) >> D3DSP_TEXTURETYPE_SHIFT
] : "???");
2301 buf
+= sprintf(buf
, "_%s", (usage
<= D3DDECLUSAGE_COLOR
) ? decl_usage
[usage
] : "???");
2303 buf
+= sprintf(buf
, "%d", usage_index
);
2306 buf
+= add_modifier(buf
, param2
);
2307 buf
+= sprintf(buf
, " ");
2308 buf
+= add_register(buf
, param2
, TRUE
, TRUE
);
2309 buf
+= sprintf(buf
, "\n");
2311 return buf
- buffer
;
2314 static int instr_generic(const struct instr_info
*info
, DWORD
**ptr
, char *buffer
, BOOL ps
)
2319 buf
+= sprintf(buf
, " %s", info
->name
);
2324 buf
+= add_modifier(buf
, **ptr
);
2326 for (j
= 0; j
< info
->length
; j
++)
2328 buf
+= sprintf(buf
, "%s ", j
? "," : "");
2330 if ((j
!= 0) && ((**ptr
& D3DSP_SRCMOD_MASK
) != D3DSPSM_NONE
))
2332 if ((**ptr
& D3DSP_SRCMOD_MASK
) == D3DSPSM_NEG
)
2333 buf
+= sprintf(buf
, "-");
2335 buf
+= sprintf(buf
, "*");
2338 buf
+= add_register(buf
, **ptr
, j
== 0, ps
);
2340 if (*(*ptr
)++ & D3DVS_ADDRESSMODE_MASK
)
2342 buf
+= sprintf(buf
, "[");
2343 buf
+= add_register(buf
, **ptr
, FALSE
, FALSE
);
2344 buf
+= sprintf(buf
, "]");
2349 buf
+= sprintf(buf
, "\n");
2350 return buf
- buffer
;
2353 const struct instr_info instructions
[] =
2355 { D3DSIO_NOP
, "nop", 0, instr_generic
, 0x0100, 0xFFFF },
2356 { D3DSIO_MOV
, "mov", 2, instr_generic
, 0x0100, 0xFFFF },
2357 { D3DSIO_ADD
, "add", 3, instr_generic
, 0x0100, 0xFFFF },
2358 { D3DSIO_SUB
, "sub", 3, instr_generic
, 0x0100, 0xFFFF },
2359 { D3DSIO_MAD
, "mad", 4, instr_generic
, 0x0100, 0xFFFF },
2360 { D3DSIO_MUL
, "mul", 3, instr_generic
, 0x0100, 0xFFFF },
2361 { D3DSIO_RCP
, "rcp", 2, instr_generic
, 0x0100, 0xFFFF }, /* >= 2.0 for PS */
2362 { D3DSIO_RSQ
, "rsq", 2, instr_generic
, 0x0100, 0xFFFF }, /* >= 2.0 for PS */
2363 { D3DSIO_DP3
, "dp3", 3, instr_generic
, 0x0100, 0xFFFF },
2364 { D3DSIO_DP4
, "dp4", 3, instr_generic
, 0x0100, 0xFFFF }, /* >= 1.2 for PS */
2365 { D3DSIO_MIN
, "min", 3, instr_generic
, 0x0100, 0xFFFF }, /* >= 2.0 for PS */
2366 { D3DSIO_MAX
, "max", 3, instr_generic
, 0x0100, 0xFFFF }, /* >= 2.0 for PS */
2367 { D3DSIO_SLT
, "slt", 3, instr_generic
, 0x0100, 0xFFFF },
2368 { D3DSIO_SGE
, "sge", 3, instr_generic
, 0x0100, 0xFFFF }, /* VS only */
2369 { D3DSIO_EXP
, "exp", 2, instr_generic
, 0x0100, 0xFFFF }, /* >= 2.0 for PS */
2370 { D3DSIO_LOG
, "log", 2, instr_generic
, 0x0100, 0xFFFF }, /* >= 2.0 for PS */
2371 { D3DSIO_LIT
, "lit", 2, instr_generic
, 0x0100, 0xFFFF }, /* VS only */
2372 { D3DSIO_DST
, "dst", 3, instr_generic
, 0x0100, 0xFFFF }, /* VS only */
2373 { D3DSIO_LRP
, "lrp", 4, instr_generic
, 0x0100, 0xFFFF }, /* >= 2.0 for VS */
2374 { D3DSIO_FRC
, "frc", 2, instr_generic
, 0x0100, 0xFFFF }, /* >= 2.0 for PS */
2375 { D3DSIO_M4x4
, "m4x4", 3, instr_generic
, 0x0100, 0xFFFF }, /* >= 2.0 for PS */
2376 { D3DSIO_M4x3
, "m4x3", 3, instr_generic
, 0x0100, 0xFFFF }, /* >= 2.0 for PS */
2377 { D3DSIO_M3x4
, "m3x4", 3, instr_generic
, 0x0100, 0xFFFF }, /* >= 2.0 for PS */
2378 { D3DSIO_M3x3
, "m3x3", 3, instr_generic
, 0x0100, 0xFFFF }, /* >= 2.0 for PS */
2379 { D3DSIO_M3x2
, "m3x2", 3, instr_generic
, 0x0100, 0xFFFF }, /* >= 2.0 for PS */
2380 { D3DSIO_CALL
, "call", 1, instr_generic
, 0x0200, 0xFFFF }, /* >= 2.a for PS */
2381 { D3DSIO_CALLNZ
, "callnz", 2, instr_generic
, 0x0200, 0xFFFF }, /* >= 2.a for PS */
2382 { D3DSIO_LOOP
, "loop", 2, instr_generic
, 0x0200, 0xFFFF }, /* >= 3.0 for PS */
2383 { D3DSIO_RET
, "ret", 0, instr_generic
, 0x0200, 0xFFFF }, /* >= 2.a for PS */
2384 { D3DSIO_ENDLOOP
, "endloop", 1, instr_generic
, 0x0200, 0xFFFF }, /* >= 3.0 for PS */
2385 { D3DSIO_LABEL
, "label", 1, instr_generic
, 0x0200, 0xFFFF }, /* >= 2.a for PS */
2386 { D3DSIO_DCL
, "dcl", 1, instr_dcl
, 0x0100, 0xFFFF },
2387 { D3DSIO_POW
, "pow", 3, instr_generic
, 0x0200, 0xFFFF },
2388 { D3DSIO_CRS
, "crs", 3, instr_generic
, 0x0200, 0xFFFF },
2389 { D3DSIO_SGN
, "sgn", 4, instr_generic
, 0x0200, 0xFFFF }, /* VS only */
2390 { D3DSIO_ABS
, "abs", 2, instr_generic
, 0x0200, 0xFFFF },
2391 { D3DSIO_NRM
, "nrm", 2, instr_generic
, 0x0200, 0xFFFF },
2392 { D3DSIO_SINCOS
, "sincos", 4, instr_generic
, 0x0200, 0x02FF },
2393 { D3DSIO_SINCOS
, "sincos", 2, instr_generic
, 0x0300, 0xFFFF },
2394 { D3DSIO_REP
, "rep", 1, instr_generic
, 0x0200, 0xFFFF }, /* >= 2.a for PS */
2395 { D3DSIO_ENDREP
, "endrep", 0, instr_generic
, 0x0200, 0xFFFF }, /* >= 2.a for PS */
2396 { D3DSIO_IF
, "if", 1, instr_generic
, 0x0200, 0xFFFF }, /* >= 2.a for PS */
2397 { D3DSIO_IFC
, "if_comp", 2, instr_generic
, 0x0200, 0xFFFF },
2398 { D3DSIO_ELSE
, "else", 0, instr_generic
, 0x0200, 0xFFFF }, /* >= 2.a for PS */
2399 { D3DSIO_ENDIF
, "endif", 0, instr_generic
, 0x0200, 0xFFFF }, /* >= 2.a for PS */
2400 { D3DSIO_BREAK
, "break", 0, instr_generic
, 0x0201, 0xFFFF },
2401 { D3DSIO_BREAKC
, "break_comp", 2, instr_generic
, 0x0201, 0xFFFF },
2402 { D3DSIO_MOVA
, "mova", 2, instr_generic
, 0x0200, 0xFFFF }, /* VS only */
2403 { D3DSIO_DEFB
, "defb", 2, instr_generic
, 0x0100, 0xFFFF },
2404 { D3DSIO_DEFI
, "defi", 2, instr_generic
, 0x0100, 0xFFFF },
2405 { D3DSIO_TEXCOORD
, "texcoord", 1, instr_generic
, 0x0100, 0x0103 }, /* PS only */
2406 { D3DSIO_TEXCOORD
, "texcrd", 2, instr_generic
, 0x0104, 0x0104 }, /* PS only */
2407 { D3DSIO_TEXKILL
, "texkill", 1, instr_generic
, 0x0100, 0xFFFF }, /* PS only */
2408 { D3DSIO_TEX
, "tex", 1, instr_generic
, 0x0100, 0x0103 }, /* PS only */
2409 { D3DSIO_TEX
, "texld", 2, instr_generic
, 0x0104, 0x0104 }, /* PS only */
2410 { D3DSIO_TEX
, "texld", 3, instr_generic
, 0x0200, 0xFFFF }, /* PS only */
2411 { D3DSIO_TEXBEM
, "texbem", 2, instr_generic
, 0x0100, 0x0103 }, /* PS only */
2412 { D3DSIO_TEXBEML
, "texbeml", 2, instr_generic
, 0x0100, 0x0103 }, /* PS only */
2413 { D3DSIO_TEXREG2AR
, "texreg2ar", 2, instr_generic
, 0x0100, 0x0103 }, /* PS only */
2414 { D3DSIO_TEXREG2GB
, "texreg2gb", 2, instr_generic
, 0x0102, 0x0103 }, /* PS only */
2415 { D3DSIO_TEXM3x2PAD
, "texm3x2pad", 2, instr_generic
, 0x0100, 0x0103 }, /* PS only */
2416 { D3DSIO_TEXM3x2TEX
, "texm3x2tex", 2, instr_generic
, 0x0100, 0x0103 }, /* PS only */
2417 { D3DSIO_TEXM3x3PAD
, "texm3x3pad", 2, instr_generic
, 0x0100, 0x0103 }, /* PS only */
2418 { D3DSIO_TEXM3x3TEX
, "texm3x3tex", 2, instr_generic
, 0x0100, 0x0103 }, /* PS only */
2419 { D3DSIO_TEXM3x3DIFF
, "texm3x3diff", 2, instr_generic
, 0x0100, 0xFFFF }, /* PS only - Not documented */
2420 { D3DSIO_TEXM3x3SPEC
, "texm3x3spec", 3, instr_generic
, 0x0100, 0x0103 }, /* PS only */
2421 { D3DSIO_TEXM3x3VSPEC
, "texm3x3vspec", 2, instr_generic
, 0x0100, 0x0103 }, /* PS only */
2422 { D3DSIO_EXPP
, "expp", 2, instr_generic
, 0x0100, 0xFFFF }, /* VS only */
2423 { D3DSIO_LOGP
, "logp", 2, instr_generic
, 0x0100, 0xFFFF }, /* VS only */
2424 { D3DSIO_CND
, "cnd", 4, instr_generic
, 0x0100, 0x0104 }, /* PS only */
2425 { D3DSIO_DEF
, "def", 5, instr_def
, 0x0100, 0xFFFF },
2426 { D3DSIO_TEXREG2RGB
, "texreg2rgb", 2, instr_generic
, 0x0102, 0x0103 }, /* PS only */
2427 { D3DSIO_TEXDP3TEX
, "texdp3tex", 2, instr_generic
, 0x0102, 0x0103 }, /* PS only */
2428 { D3DSIO_TEXM3x2DEPTH
, "texm3x2depth", 2, instr_generic
, 0x0103, 0x0103 }, /* PS only */
2429 { D3DSIO_TEXDP3
, "texdp3", 2, instr_generic
, 0x0102, 0x0103 }, /* PS only */
2430 { D3DSIO_TEXM3x3
, "texm3x3", 2, instr_generic
, 0x0102, 0x0103 }, /* PS only */
2431 { D3DSIO_TEXDEPTH
, "texdepth", 1, instr_generic
, 0x0104, 0x0104 }, /* PS only */
2432 { D3DSIO_CMP
, "cmp", 4, instr_generic
, 0x0102, 0xFFFF }, /* PS only */
2433 { D3DSIO_BEM
, "bem", 3, instr_generic
, 0x0104, 0x0104 }, /* PS only */
2434 { D3DSIO_DP2ADD
, "dp2add", 4, instr_generic
, 0x0200, 0xFFFF }, /* PS only */
2435 { D3DSIO_DSX
, "dsx", 2, instr_generic
, 0x0201, 0xFFFF }, /* PS only */
2436 { D3DSIO_DSY
, "dsy", 2, instr_generic
, 0x0201, 0xFFFF }, /* PS only */
2437 { D3DSIO_TEXLDD
, "texldd", 5, instr_generic
, 0x0201, 0xFFFF }, /* PS only - not existing for 2.b */
2438 { D3DSIO_SETP
, "setp_comp", 3, instr_generic
, 0x0201, 0xFFFF },
2439 { D3DSIO_TEXLDL
, "texldl", 3, instr_generic
, 0x0300, 0xFFFF },
2440 { D3DSIO_BREAKP
, "breakp", 1, instr_generic
, 0x0201, 0xFFFF },
2441 { D3DSIO_PHASE
, "phase", 0, instr_generic
, 0x0104, 0x0104 }, /* PS only */
2442 { D3DSIO_COMMENT
, "", 0, instr_comment
, 0x0100, 0xFFFF }
2445 HRESULT WINAPI
D3DXDisassembleShader(const DWORD
*shader
, BOOL colorcode
, const char *comments
, ID3DXBuffer
**disassembly
)
2447 DWORD
*ptr
= (DWORD
*)shader
;
2449 UINT capacity
= 4096;
2454 TRACE("%p %d %s %p\n", shader
, colorcode
, debugstr_a(comments
), disassembly
);
2456 if (!shader
|| !disassembly
)
2457 return D3DERR_INVALIDCALL
;
2459 buf
= buffer
= HeapAlloc(GetProcessHeap(), 0, capacity
);
2461 return E_OUTOFMEMORY
;
2463 ps
= (*ptr
>> 16) & 1;
2464 version
= *ptr
& 0xFFFF;
2465 buf
+= sprintf(buf
, " %s_%d_%d\n", ps
? "ps" : "vs", D3DSHADER_VERSION_MAJOR(*ptr
), D3DSHADER_VERSION_MINOR(*ptr
));
2468 while (*ptr
!= D3DSIO_END
)
2472 if ((buf
- buffer
+ 128) > capacity
)
2474 UINT count
= buf
- buffer
;
2475 char *new_buffer
= HeapReAlloc(GetProcessHeap(), 0, buffer
, capacity
* 2);
2478 HeapFree(GetProcessHeap(), 0, buffer
);
2479 return E_OUTOFMEMORY
;
2482 buffer
= new_buffer
;
2483 buf
= buffer
+ count
;
2486 for (index
= 0; index
< sizeof(instructions
)/sizeof(instructions
[0]); index
++)
2487 if (((*ptr
& D3DSI_OPCODE_MASK
) == instructions
[index
].opcode
) &&
2488 (version
>= instructions
[index
].min_version
) && (version
<= instructions
[index
].max_version
))
2491 if (index
!= sizeof(instructions
)/sizeof(instructions
[0]))
2493 buf
+= instructions
[index
].function(&(instructions
[index
]), &ptr
, buf
, ps
);
2497 buf
+= sprintf(buf
, " ??? (Unknown opcode %x)\n", *ptr
);
2498 while (*++ptr
& (1u << 31));
2502 hr
= D3DXCreateBuffer(buf
- buffer
+ 1 , disassembly
);
2504 strcpy(ID3DXBuffer_GetBufferPointer(*disassembly
), buffer
);
2505 HeapFree(GetProcessHeap(), 0, buffer
);
2510 struct d3dx9_texture_shader
2512 ID3DXTextureShader ID3DXTextureShader_iface
;
2516 static inline struct d3dx9_texture_shader
*impl_from_ID3DXTextureShader(ID3DXTextureShader
*iface
)
2518 return CONTAINING_RECORD(iface
, struct d3dx9_texture_shader
, ID3DXTextureShader_iface
);
2521 static HRESULT WINAPI
d3dx9_texture_shader_QueryInterface(ID3DXTextureShader
*iface
, REFIID riid
, void **out
)
2523 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
2525 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
2526 IsEqualGUID(riid
, &IID_ID3DXTextureShader
))
2528 iface
->lpVtbl
->AddRef(iface
);
2533 WARN("Interface %s not found.\n", debugstr_guid(riid
));
2535 return E_NOINTERFACE
;
2538 static ULONG WINAPI
d3dx9_texture_shader_AddRef(ID3DXTextureShader
*iface
)
2540 struct d3dx9_texture_shader
*texture_shader
= impl_from_ID3DXTextureShader(iface
);
2541 ULONG refcount
= InterlockedIncrement(&texture_shader
->ref
);
2543 TRACE("%p increasing refcount to %u.\n", texture_shader
, refcount
);
2548 static ULONG WINAPI
d3dx9_texture_shader_Release(ID3DXTextureShader
*iface
)
2550 struct d3dx9_texture_shader
*texture_shader
= impl_from_ID3DXTextureShader(iface
);
2551 ULONG refcount
= InterlockedDecrement(&texture_shader
->ref
);
2553 TRACE("%p decreasing refcount to %u.\n", texture_shader
, refcount
);
2557 HeapFree(GetProcessHeap(), 0, texture_shader
);
2563 static HRESULT WINAPI
d3dx9_texture_shader_GetFunction(ID3DXTextureShader
*iface
, struct ID3DXBuffer
**function
)
2565 FIXME("iface %p, function %p stub.\n", iface
, function
);
2570 static HRESULT WINAPI
d3dx9_texture_shader_GetConstantBuffer(ID3DXTextureShader
*iface
, struct ID3DXBuffer
**constant_buffer
)
2572 FIXME("iface %p, constant_buffer %p stub.\n", iface
, constant_buffer
);
2577 static HRESULT WINAPI
d3dx9_texture_shader_GetDesc(ID3DXTextureShader
*iface
, D3DXCONSTANTTABLE_DESC
*desc
)
2579 FIXME("iface %p, desc %p stub.\n", iface
, desc
);
2584 static HRESULT WINAPI
d3dx9_texture_shader_GetConstantDesc(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, D3DXCONSTANT_DESC
*constant_desc
, UINT
*count
)
2586 FIXME("iface %p, constant %p, constant_desc %p, count %p stub.\n", iface
, constant
, constant_desc
, count
);
2591 static D3DXHANDLE WINAPI
d3dx9_texture_shader_GetConstant(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, UINT index
)
2593 FIXME("iface %p, constant %p, index %u stub.\n", iface
, constant
, index
);
2598 static D3DXHANDLE WINAPI
d3dx9_texture_shader_GetConstantByName(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const char *name
)
2600 FIXME("iface %p, constant %p, name %s stub.\n", iface
, constant
, debugstr_a(name
));
2605 static D3DXHANDLE WINAPI
d3dx9_texture_shader_GetConstantElement(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, UINT index
)
2607 FIXME("iface %p, constant %p, index %u stub.\n", iface
, constant
, index
);
2612 static HRESULT WINAPI
d3dx9_texture_shader_SetDefaults(ID3DXTextureShader
*iface
)
2614 FIXME("iface %p stub.\n", iface
);
2619 static HRESULT WINAPI
d3dx9_texture_shader_SetValue(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const void *data
, UINT bytes
)
2621 FIXME("iface %p, constant %p, data %p, bytes %u stub.\n", iface
, constant
, data
, bytes
);
2626 static HRESULT WINAPI
d3dx9_texture_shader_SetBool(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, BOOL b
)
2628 FIXME("iface %p, constant %p, b %u stub.\n", iface
, constant
, b
);
2633 static HRESULT WINAPI
d3dx9_texture_shader_SetBoolArray(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const BOOL
*b
, UINT count
)
2635 FIXME("iface %p, constant %p, b %p, count %u stub.\n", iface
, constant
, b
, count
);
2640 static HRESULT WINAPI
d3dx9_texture_shader_SetInt(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, INT n
)
2642 FIXME("iface %p, constant %p, n %d stub.\n", iface
, constant
, n
);
2647 static HRESULT WINAPI
d3dx9_texture_shader_SetIntArray(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const INT
*n
, UINT count
)
2649 FIXME("iface %p, constant %p, n %p, count %u stub.\n", iface
, constant
, n
, count
);
2654 static HRESULT WINAPI
d3dx9_texture_shader_SetFloat(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, FLOAT f
)
2656 FIXME("iface %p, constant %p, f %f stub.\n", iface
, constant
, f
);
2661 static HRESULT WINAPI
d3dx9_texture_shader_SetFloatArray(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const FLOAT
*f
, UINT count
)
2663 FIXME("iface %p, constant %p, f %p, count %u stub.\n", iface
, constant
, f
, count
);
2668 static HRESULT WINAPI
d3dx9_texture_shader_SetVector(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const D3DXVECTOR4
*vector
)
2670 FIXME("iface %p, constant %p, vector %p stub.\n", iface
, constant
, vector
);
2675 static HRESULT WINAPI
d3dx9_texture_shader_SetVectorArray(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const D3DXVECTOR4
*vector
, UINT count
)
2677 FIXME("iface %p, constant %p, vector %p, count %u stub.\n", iface
, constant
, vector
, count
);
2682 static HRESULT WINAPI
d3dx9_texture_shader_SetMatrix(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const D3DXMATRIX
*matrix
)
2684 FIXME("iface %p, constant %p, matrix %p stub.\n", iface
, constant
, matrix
);
2689 static HRESULT WINAPI
d3dx9_texture_shader_SetMatrixArray(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const D3DXMATRIX
*matrix
, UINT count
)
2691 FIXME("iface %p, constant %p, matrix %p, count %u stub.\n", iface
, constant
, matrix
, count
);
2696 static HRESULT WINAPI
d3dx9_texture_shader_SetMatrixPointerArray(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const D3DXMATRIX
**matrix
, UINT count
)
2698 FIXME("iface %p, constant %p, matrix %p, count %u stub.\n", iface
, constant
, matrix
, count
);
2703 static HRESULT WINAPI
d3dx9_texture_shader_SetMatrixTranspose(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const D3DXMATRIX
*matrix
)
2705 FIXME("iface %p, constant %p, matrix %p stub.\n", iface
, constant
, matrix
);
2710 static HRESULT WINAPI
d3dx9_texture_shader_SetMatrixTransposeArray(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const D3DXMATRIX
*matrix
, UINT count
)
2712 FIXME("iface %p, constant %p, matrix %p, count %u stub.\n", iface
, constant
, matrix
, count
);
2717 static HRESULT WINAPI
d3dx9_texture_shader_SetMatrixTransposePointerArray(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const D3DXMATRIX
**matrix
, UINT count
)
2719 FIXME("iface %p, constant %p, matrix %p, count %u stub.\n", iface
, constant
, matrix
, count
);
2724 static const struct ID3DXTextureShaderVtbl d3dx9_texture_shader_vtbl
=
2726 /*** IUnknown methods ***/
2727 d3dx9_texture_shader_QueryInterface
,
2728 d3dx9_texture_shader_AddRef
,
2729 d3dx9_texture_shader_Release
,
2730 /*** ID3DXTextureShader methods ***/
2731 d3dx9_texture_shader_GetFunction
,
2732 d3dx9_texture_shader_GetConstantBuffer
,
2733 d3dx9_texture_shader_GetDesc
,
2734 d3dx9_texture_shader_GetConstantDesc
,
2735 d3dx9_texture_shader_GetConstant
,
2736 d3dx9_texture_shader_GetConstantByName
,
2737 d3dx9_texture_shader_GetConstantElement
,
2738 d3dx9_texture_shader_SetDefaults
,
2739 d3dx9_texture_shader_SetValue
,
2740 d3dx9_texture_shader_SetBool
,
2741 d3dx9_texture_shader_SetBoolArray
,
2742 d3dx9_texture_shader_SetInt
,
2743 d3dx9_texture_shader_SetIntArray
,
2744 d3dx9_texture_shader_SetFloat
,
2745 d3dx9_texture_shader_SetFloatArray
,
2746 d3dx9_texture_shader_SetVector
,
2747 d3dx9_texture_shader_SetVectorArray
,
2748 d3dx9_texture_shader_SetMatrix
,
2749 d3dx9_texture_shader_SetMatrixArray
,
2750 d3dx9_texture_shader_SetMatrixPointerArray
,
2751 d3dx9_texture_shader_SetMatrixTranspose
,
2752 d3dx9_texture_shader_SetMatrixTransposeArray
,
2753 d3dx9_texture_shader_SetMatrixTransposePointerArray
2756 HRESULT WINAPI
D3DXCreateTextureShader(const DWORD
*function
, ID3DXTextureShader
**texture_shader
)
2758 struct d3dx9_texture_shader
*object
;
2760 TRACE("function %p, texture_shader %p.\n", function
, texture_shader
);
2762 if (!function
|| !texture_shader
)
2763 return D3DERR_INVALIDCALL
;
2765 object
= HeapAlloc(GetProcessHeap(), 0, sizeof(*object
));
2767 return E_OUTOFMEMORY
;
2769 object
->ID3DXTextureShader_iface
.lpVtbl
= &d3dx9_texture_shader_vtbl
;
2772 *texture_shader
= &object
->ID3DXTextureShader_iface
;
2777 static const DWORD
* skip_instruction(const DWORD
*byte_code
, UINT shader_model
)
2779 TRACE("Shader model %u\n", shader_model
);
2781 /* Handle all special instructions whose arguments may contain D3DSIO_DCL */
2782 if ((*byte_code
& D3DSI_OPCODE_MASK
) == D3DSIO_COMMENT
)
2784 byte_code
+= 1 + ((*byte_code
& D3DSI_COMMENTSIZE_MASK
) >> D3DSI_COMMENTSIZE_SHIFT
);
2786 else if (shader_model
>= 2)
2788 byte_code
+= 1 + ((*byte_code
& D3DSI_INSTLENGTH_MASK
) >> D3DSI_INSTLENGTH_SHIFT
);
2790 else if ((*byte_code
& D3DSI_OPCODE_MASK
) == D3DSIO_DEF
)
2796 /* Handle remaining safe instructions */
2797 while (*++byte_code
& (1u << 31));
2803 static UINT
get_shader_semantics(const DWORD
*byte_code
, D3DXSEMANTIC
*semantics
, DWORD type
)
2805 const DWORD
*ptr
= byte_code
;
2806 UINT shader_model
= (*ptr
>> 8) & 0xff;
2809 TRACE("Shader version: %#x\n", *ptr
);
2812 while (*ptr
!= D3DSIO_END
)
2814 if (*ptr
& (1u << 31))
2816 FIXME("Opcode expected but got %#x\n", *ptr
);
2819 else if ((*ptr
& D3DSI_OPCODE_MASK
) == D3DSIO_DCL
)
2821 DWORD param1
= *++ptr
;
2822 DWORD param2
= *++ptr
;
2823 DWORD usage
= (param1
& D3DSP_DCL_USAGE_MASK
) >> D3DSP_DCL_USAGE_SHIFT
;
2824 DWORD usage_index
= (param1
& D3DSP_DCL_USAGEINDEX_MASK
) >> D3DSP_DCL_USAGEINDEX_SHIFT
;
2825 DWORD reg_type
= ((param2
& D3DSP_REGTYPE_MASK2
) >> D3DSP_REGTYPE_SHIFT2
)
2826 | ((param2
& D3DSP_REGTYPE_MASK
) >> D3DSP_REGTYPE_SHIFT
);
2828 TRACE("D3DSIO_DCL param1: %#x, param2: %#x, usage: %u, usage_index: %u, reg_type: %u\n",
2829 param1
, param2
, usage
, usage_index
, reg_type
);
2831 if (reg_type
== type
)
2835 semantics
[i
].Usage
= usage
;
2836 semantics
[i
].UsageIndex
= usage_index
;
2845 ptr
= skip_instruction(ptr
, shader_model
);
2852 HRESULT WINAPI
D3DXGetShaderInputSemantics(const DWORD
*byte_code
, D3DXSEMANTIC
*semantics
, UINT
*count
)
2856 TRACE("byte_code %p, semantics %p, count %p\n", byte_code
, semantics
, count
);
2859 return D3DERR_INVALIDCALL
;
2861 nb_semantics
= get_shader_semantics(byte_code
, semantics
, D3DSPR_INPUT
);
2864 *count
= nb_semantics
;
2870 HRESULT WINAPI
D3DXGetShaderOutputSemantics(const DWORD
*byte_code
, D3DXSEMANTIC
*semantics
, UINT
*count
)
2874 TRACE("byte_code %p, semantics %p, count %p\n", byte_code
, semantics
, count
);
2877 return D3DERR_INVALIDCALL
;
2879 nb_semantics
= get_shader_semantics(byte_code
, semantics
, D3DSPR_OUTPUT
);
2882 *count
= nb_semantics
;