2 * Copyright 2008 Luis Busquets
3 * Copyright 2009 Matteo Bruni
4 * Copyright 2010, 2013 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 ctab_constant
{
718 D3DXCONSTANT_DESC desc
;
719 struct ctab_constant
*constants
;
722 struct ID3DXConstantTableImpl
{
723 ID3DXConstantTable ID3DXConstantTable_iface
;
727 D3DXCONSTANTTABLE_DESC desc
;
728 struct ctab_constant
*constants
;
731 static void free_constant(struct ctab_constant
*constant
)
733 if (constant
->constants
)
735 UINT i
, count
= constant
->desc
.Elements
> 1 ? constant
->desc
.Elements
: constant
->desc
.StructMembers
;
737 for (i
= 0; i
< count
; ++i
)
739 free_constant(&constant
->constants
[i
]);
741 HeapFree(GetProcessHeap(), 0, constant
->constants
);
745 static void free_constant_table(struct ID3DXConstantTableImpl
*table
)
747 if (table
->constants
)
751 for (i
= 0; i
< table
->desc
.Constants
; ++i
)
753 free_constant(&table
->constants
[i
]);
755 HeapFree(GetProcessHeap(), 0, table
->constants
);
757 HeapFree(GetProcessHeap(), 0, table
->ctab
);
760 static inline struct ID3DXConstantTableImpl
*impl_from_ID3DXConstantTable(ID3DXConstantTable
*iface
)
762 return CONTAINING_RECORD(iface
, struct ID3DXConstantTableImpl
, ID3DXConstantTable_iface
);
765 static inline BOOL
is_vertex_shader(DWORD version
)
767 return (version
& 0xffff0000) == 0xfffe0000;
770 static inline D3DXHANDLE
handle_from_constant(struct ctab_constant
*constant
)
772 return (D3DXHANDLE
)constant
;
775 static struct ctab_constant
*get_constant_by_name(struct ID3DXConstantTableImpl
*table
,
776 struct ctab_constant
*constant
, const char *name
);
778 static struct ctab_constant
*get_constant_element_by_name(struct ctab_constant
*constant
, const char *name
)
783 TRACE("constant %p, name %s\n", constant
, debugstr_a(name
));
785 if (!name
|| !*name
) return NULL
;
787 element
= atoi(name
);
788 part
= strchr(name
, ']') + 1;
790 if (constant
->desc
.Elements
> element
)
792 struct ctab_constant
*c
= constant
->constants
? &constant
->constants
[element
] : constant
;
797 return get_constant_by_name(NULL
, c
, part
);
800 return get_constant_element_by_name(c
, part
);
803 TRACE("Returning parameter %p\n", c
);
807 FIXME("Unhandled case \"%c\"\n", *--part
);
812 TRACE("Constant not found\n");
816 static struct ctab_constant
*get_constant_by_name(struct ID3DXConstantTableImpl
*table
,
817 struct ctab_constant
*constant
, const char *name
)
819 UINT i
, count
, length
;
820 struct ctab_constant
*handles
;
823 TRACE("table %p, constant %p, name %s\n", table
, constant
, debugstr_a(name
));
825 if (!name
|| !*name
) return NULL
;
829 count
= table
->desc
.Constants
;
830 handles
= table
->constants
;
834 count
= constant
->desc
.StructMembers
;
835 handles
= constant
->constants
;
838 length
= strcspn(name
, "[.");
839 part
= name
+ length
;
841 for (i
= 0; i
< count
; i
++)
843 if (strlen(handles
[i
].desc
.Name
) == length
&& !strncmp(handles
[i
].desc
.Name
, name
, length
))
848 return get_constant_by_name(NULL
, &handles
[i
], part
);
851 return get_constant_element_by_name(&handles
[i
], part
);
854 TRACE("Returning parameter %p\n", &handles
[i
]);
860 TRACE("Constant not found\n");
864 static struct ctab_constant
*is_valid_sub_constant(struct ctab_constant
*parent
, D3DXHANDLE handle
)
866 struct ctab_constant
*c
;
869 /* all variable have at least elements = 1, but not always elements */
870 if (!parent
->constants
) return NULL
;
872 count
= parent
->desc
.Elements
> 1 ? parent
->desc
.Elements
: parent
->desc
.StructMembers
;
873 for (i
= 0; i
< count
; ++i
)
875 if (handle_from_constant(&parent
->constants
[i
]) == handle
)
876 return &parent
->constants
[i
];
878 c
= is_valid_sub_constant(&parent
->constants
[i
], handle
);
885 static inline struct ctab_constant
*get_valid_constant(struct ID3DXConstantTableImpl
*table
, D3DXHANDLE handle
)
887 struct ctab_constant
*c
;
890 if (!handle
) return NULL
;
892 for (i
= 0; i
< table
->desc
.Constants
; ++i
)
894 if (handle_from_constant(&table
->constants
[i
]) == handle
)
895 return &table
->constants
[i
];
897 c
= is_valid_sub_constant(&table
->constants
[i
], handle
);
901 return get_constant_by_name(table
, NULL
, handle
);
904 /*** IUnknown methods ***/
905 static HRESULT WINAPI
ID3DXConstantTableImpl_QueryInterface(ID3DXConstantTable
*iface
, REFIID riid
, void **out
)
907 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
909 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
910 IsEqualGUID(riid
, &IID_ID3DXBuffer
) ||
911 IsEqualGUID(riid
, &IID_ID3DXConstantTable
))
913 ID3DXConstantTable_AddRef(iface
);
918 WARN("Interface %s not found.\n", debugstr_guid(riid
));
920 return E_NOINTERFACE
;
923 static ULONG WINAPI
ID3DXConstantTableImpl_AddRef(ID3DXConstantTable
*iface
)
925 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
927 TRACE("(%p)->(): AddRef from %d\n", This
, This
->ref
);
929 return InterlockedIncrement(&This
->ref
);
932 static ULONG WINAPI
ID3DXConstantTableImpl_Release(ID3DXConstantTable
*iface
)
934 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
935 ULONG ref
= InterlockedDecrement(&This
->ref
);
937 TRACE("(%p)->(): Release from %d\n", This
, ref
+ 1);
941 free_constant_table(This
);
942 HeapFree(GetProcessHeap(), 0, This
);
948 /*** ID3DXBuffer methods ***/
949 static void * WINAPI
ID3DXConstantTableImpl_GetBufferPointer(ID3DXConstantTable
*iface
)
951 struct ID3DXConstantTableImpl
*table
= impl_from_ID3DXConstantTable(iface
);
953 TRACE("iface %p.\n", iface
);
958 static DWORD WINAPI
ID3DXConstantTableImpl_GetBufferSize(ID3DXConstantTable
*iface
)
960 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
962 TRACE("(%p)->()\n", This
);
967 /*** ID3DXConstantTable methods ***/
968 static HRESULT WINAPI
ID3DXConstantTableImpl_GetDesc(ID3DXConstantTable
*iface
, D3DXCONSTANTTABLE_DESC
*desc
)
970 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
972 TRACE("(%p)->(%p)\n", This
, desc
);
975 return D3DERR_INVALIDCALL
;
982 static HRESULT WINAPI
ID3DXConstantTableImpl_GetConstantDesc(ID3DXConstantTable
*iface
, D3DXHANDLE constant
,
983 D3DXCONSTANT_DESC
*desc
, UINT
*count
)
985 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
986 struct ctab_constant
*c
= get_valid_constant(This
, constant
);
988 TRACE("(%p)->(%p, %p, %p)\n", This
, constant
, desc
, count
);
992 WARN("Invalid argument specified\n");
993 return D3DERR_INVALIDCALL
;
996 if (desc
) *desc
= c
->desc
;
997 if (count
) *count
= 1;
1002 static UINT WINAPI
ID3DXConstantTableImpl_GetSamplerIndex(ID3DXConstantTable
*iface
, D3DXHANDLE constant
)
1004 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1005 struct ctab_constant
*c
= get_valid_constant(This
, constant
);
1007 TRACE("(%p)->(%p)\n", This
, constant
);
1009 if (!c
|| c
->desc
.RegisterSet
!= D3DXRS_SAMPLER
)
1011 WARN("Invalid argument specified\n");
1015 TRACE("Returning RegisterIndex %u\n", c
->desc
.RegisterIndex
);
1016 return c
->desc
.RegisterIndex
;
1019 static D3DXHANDLE WINAPI
ID3DXConstantTableImpl_GetConstant(ID3DXConstantTable
*iface
, D3DXHANDLE constant
, UINT index
)
1021 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1022 struct ctab_constant
*c
;
1024 TRACE("(%p)->(%p, %d)\n", This
, constant
, index
);
1028 c
= get_valid_constant(This
, constant
);
1029 if (c
&& index
< c
->desc
.StructMembers
)
1031 c
= &c
->constants
[index
];
1032 TRACE("Returning constant %p\n", c
);
1033 return handle_from_constant(c
);
1038 if (index
< This
->desc
.Constants
)
1040 c
= &This
->constants
[index
];
1041 TRACE("Returning constant %p\n", c
);
1042 return handle_from_constant(c
);
1046 WARN("Index out of range\n");
1050 static D3DXHANDLE WINAPI
ID3DXConstantTableImpl_GetConstantByName(ID3DXConstantTable
*iface
,
1051 D3DXHANDLE constant
, const char *name
)
1053 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1054 struct ctab_constant
*c
= get_valid_constant(This
, constant
);
1056 TRACE("iface %p, constant %p, name %s.\n", iface
, constant
, debugstr_a(name
));
1058 c
= get_constant_by_name(This
, c
, name
);
1059 TRACE("Returning constant %p\n", c
);
1061 return handle_from_constant(c
);
1064 static D3DXHANDLE WINAPI
ID3DXConstantTableImpl_GetConstantElement(ID3DXConstantTable
*iface
, D3DXHANDLE constant
, UINT index
)
1066 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1067 struct ctab_constant
*c
= get_valid_constant(This
, constant
);
1069 TRACE("(%p)->(%p, %d)\n", This
, constant
, index
);
1071 if (c
&& index
< c
->desc
.Elements
)
1073 if (c
->desc
.Elements
> 1) c
= &c
->constants
[index
];
1074 TRACE("Returning constant %p\n", c
);
1075 return handle_from_constant(c
);
1078 WARN("Invalid argument specified\n");
1082 static inline DWORD
get_index(const void **indata
, UINT index
, BOOL is_pointer
)
1088 return ((DWORD
**)indata
)[index
/ 16][index
% 16];
1090 return (*((DWORD
**)indata
))[index
];
1093 static UINT
set(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
, struct ctab_constant
*constant
,
1094 const void **indata
, D3DXPARAMETER_TYPE intype
, UINT
*size
, UINT incol
, D3DXPARAMETER_CLASS inclass
, UINT index
,
1097 D3DXCONSTANT_DESC
*desc
= &constant
->desc
;
1098 UINT l
, i
, regcount
= 1, regsize
= 1, cin
= 1, rin
= 1, ret
, last
= 0;
1101 /* size too small to set anything */
1102 if (*size
< desc
->Rows
* desc
->Columns
)
1108 /* D3DXPC_STRUCT is somewhat special */
1109 if (desc
->Class
== D3DXPC_STRUCT
)
1112 * Struct array sets the last complete input to the first struct element, all other
1113 * elements are not set.
1114 * E.g.: struct {int i;} s1[2];
1115 * SetValue(device, "s1", [1, 2], 8) => s1 = {2, x};
1117 * struct {int i; int n} s2[2];
1118 * SetValue(device, "s2", [1, 2, 3, 4, 5], 20) => s1 = {{3, 4}, {x, x}};
1120 if (desc
->Elements
> 1)
1122 UINT offset
= *size
/ (desc
->Rows
* desc
->Columns
) - 1;
1124 offset
= min(desc
->Elements
- 1, offset
);
1125 last
= offset
* desc
->Rows
* desc
->Columns
;
1127 if ((is_pointer
|| inclass
== D3DXPC_MATRIX_ROWS
) && desc
->RegisterSet
!= D3DXRS_BOOL
)
1129 set(table
, device
, &constant
->constants
[0], NULL
, intype
, size
, incol
, inclass
, 0, is_pointer
);
1133 last
+= set(table
, device
, &constant
->constants
[0], indata
, intype
, size
, incol
, inclass
,
1134 index
+ last
, is_pointer
);
1140 * D3DXRS_BOOL is always set. As there are only 16 bools and there are
1141 * exactly 16 input values, use matrix transpose.
1143 if (inclass
== D3DXPC_MATRIX_ROWS
&& desc
->RegisterSet
== D3DXRS_BOOL
)
1145 D3DXMATRIX mat
, *m
, min
;
1146 D3DXMatrixTranspose(&mat
, &min
);
1149 min
= *(D3DXMATRIX
*)(indata
[index
/ 16]);
1151 min
= **(D3DXMATRIX
**)indata
;
1153 D3DXMatrixTranspose(&mat
, &min
);
1155 for (i
= 0; i
< desc
->StructMembers
; ++i
)
1157 last
+= set(table
, device
, &constant
->constants
[i
], (const void **)&m
, intype
, size
, incol
,
1158 D3DXPC_SCALAR
, index
+ last
, is_pointer
);
1162 * For pointers or for matrix rows, only the first member is set.
1163 * All other members are set to 0. This is not true for D3DXRS_BOOL.
1164 * E.g.: struct {int i; int n} s;
1165 * SetValue(device, "s", [1, 2], 8) => s = {1, 0};
1167 else if ((is_pointer
|| inclass
== D3DXPC_MATRIX_ROWS
) && desc
->RegisterSet
!= D3DXRS_BOOL
)
1169 last
= set(table
, device
, &constant
->constants
[0], indata
, intype
, size
, incol
, inclass
,
1170 index
+ last
, is_pointer
);
1172 for (i
= 1; i
< desc
->StructMembers
; ++i
)
1174 set(table
, device
, &constant
->constants
[i
], NULL
, intype
, size
, incol
, inclass
, 0, is_pointer
);
1179 for (i
= 0; i
< desc
->StructMembers
; ++i
)
1181 last
+= set(table
, device
, &constant
->constants
[i
], indata
, intype
, size
, incol
, D3DXPC_SCALAR
,
1182 index
+ last
, is_pointer
);
1191 if (desc
->Elements
> 1)
1193 for (i
= 0; i
< desc
->Elements
&& *size
> 0; ++i
)
1195 last
+= set(table
, device
, &constant
->constants
[i
], indata
, intype
, size
, incol
, inclass
,
1196 index
+ last
, is_pointer
);
1198 /* adjust the vector size for matrix rows */
1199 if (inclass
== D3DXPC_MATRIX_ROWS
&& desc
->Class
== D3DXPC_VECTOR
&& (i
% 4) == 3)
1202 *size
= *size
< 12 ? 0 : *size
- 12;
1209 switch (desc
->Class
)
1213 case D3DXPC_MATRIX_ROWS
:
1214 regcount
= min(desc
->RegisterCount
, desc
->Rows
);
1215 if (inclass
== D3DXPC_MATRIX_ROWS
) cin
= incol
;
1217 regsize
= desc
->Columns
;
1220 case D3DXPC_MATRIX_COLUMNS
:
1221 regcount
= min(desc
->RegisterCount
, desc
->Columns
);
1222 if (inclass
== D3DXPC_MATRIX_ROWS
) rin
= incol
;
1224 regsize
= desc
->Rows
;
1228 FIXME("Unhandled variable class %s\n", debug_d3dxparameter_class(desc
->Class
));
1232 /* specific stuff for different in types */
1236 ret
= desc
->Columns
* desc
->Rows
;
1237 *size
-= desc
->Columns
* desc
->Rows
;
1241 switch (desc
->Class
)
1243 case D3DXPC_MATRIX_ROWS
:
1244 if (*size
< regcount
* 4)
1250 *size
-= 4 * regcount
;
1253 case D3DXPC_MATRIX_COLUMNS
:
1255 *size
-= 4 * regcount
;
1269 FIXME("Unhandled variable class %s\n", debug_d3dxparameter_class(desc
->Class
));
1274 case D3DXPC_MATRIX_ROWS
:
1275 switch (desc
->Class
)
1277 case D3DXPC_MATRIX_ROWS
:
1278 case D3DXPC_MATRIX_COLUMNS
:
1296 FIXME("Unhandled variable class %s\n", debug_d3dxparameter_class(desc
->Class
));
1302 case D3DXPC_MATRIX_COLUMNS
:
1303 switch (desc
->Class
)
1305 case D3DXPC_MATRIX_ROWS
:
1306 case D3DXPC_MATRIX_COLUMNS
:
1324 FIXME("Unhandled variable class %s\n", debug_d3dxparameter_class(desc
->Class
));
1331 FIXME("Unhandled variable class %s\n", debug_d3dxparameter_class(inclass
));
1335 /* set the registers */
1336 switch (desc
->RegisterSet
)
1339 regcount
= min(desc
->RegisterCount
, desc
->Columns
* desc
->Rows
);
1341 for (i
= 0; i
< regcount
; ++i
)
1344 DWORD t
= get_index(indata
, index
+ i
/ regsize
* rin
+ l
* cin
, is_pointer
);
1346 set_number(&tmp
, desc
->Type
, &t
, intype
);
1347 set_number(&out
, D3DXPT_BOOL
, &tmp
, desc
->Type
);
1348 if (is_vertex_shader(table
->desc
.Version
))
1349 IDirect3DDevice9_SetVertexShaderConstantB(device
, desc
->RegisterIndex
+ i
, &out
, 1);
1351 IDirect3DDevice9_SetPixelShaderConstantB(device
, desc
->RegisterIndex
+ i
, &out
, 1);
1353 if (++l
>= regsize
) l
= 0;
1358 for (i
= 0; i
< regcount
; ++i
)
1360 INT vec
[4] = {0, 0, 1, 0};
1362 for (l
= 0; l
< regsize
; ++l
)
1364 DWORD t
= get_index(indata
, index
+ i
* rin
+ l
* cin
, is_pointer
);
1366 set_number(&tmp
, desc
->Type
, &t
, intype
);
1367 set_number(&vec
[l
], D3DXPT_INT
, &tmp
, desc
->Type
);
1369 if (is_vertex_shader(table
->desc
.Version
))
1370 IDirect3DDevice9_SetVertexShaderConstantI(device
, desc
->RegisterIndex
+ i
, vec
, 1);
1372 IDirect3DDevice9_SetPixelShaderConstantI(device
, desc
->RegisterIndex
+ i
, vec
, 1);
1377 for (i
= 0; i
< regcount
; ++i
)
1381 for (l
= 0; l
< regsize
; ++l
)
1383 DWORD t
= get_index(indata
, index
+ i
* rin
+ l
* cin
, is_pointer
);
1385 set_number(&tmp
, desc
->Type
, &t
, intype
);
1386 set_number(&vec
[l
], D3DXPT_FLOAT
, &tmp
, desc
->Type
);
1388 if (is_vertex_shader(table
->desc
.Version
))
1389 IDirect3DDevice9_SetVertexShaderConstantF(device
, desc
->RegisterIndex
+ i
, vec
, 1);
1391 IDirect3DDevice9_SetPixelShaderConstantF(device
, desc
->RegisterIndex
+ i
, vec
, 1);
1396 FIXME("Unhandled register set %s\n", debug_d3dxparameter_registerset(desc
->RegisterSet
));
1401 static HRESULT
set_scalar(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
, D3DXHANDLE constant
,
1402 const void *indata
, D3DXPARAMETER_TYPE intype
)
1404 struct ctab_constant
*c
= get_valid_constant(table
, constant
);
1409 WARN("Invalid argument specified\n");
1410 return D3DERR_INVALIDCALL
;
1413 switch (c
->desc
.Class
)
1416 set(table
, device
, c
, &indata
, intype
, &count
, c
->desc
.Columns
, D3DXPC_SCALAR
, 0, FALSE
);
1420 case D3DXPC_MATRIX_ROWS
:
1421 case D3DXPC_MATRIX_COLUMNS
:
1426 FIXME("Unhandled parameter class %s\n", debug_d3dxparameter_class(c
->desc
.Class
));
1427 return D3DERR_INVALIDCALL
;
1431 static HRESULT
set_scalar_array(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
, D3DXHANDLE constant
,
1432 const void *indata
, UINT count
, D3DXPARAMETER_TYPE intype
)
1434 struct ctab_constant
*c
= get_valid_constant(table
, constant
);
1438 WARN("Invalid argument specified\n");
1439 return D3DERR_INVALIDCALL
;
1442 switch (c
->desc
.Class
)
1446 case D3DXPC_MATRIX_ROWS
:
1447 case D3DXPC_MATRIX_COLUMNS
:
1449 set(table
, device
, c
, &indata
, intype
, &count
, c
->desc
.Columns
, D3DXPC_SCALAR
, 0, FALSE
);
1453 FIXME("Unhandled parameter class %s\n", debug_d3dxparameter_class(c
->desc
.Class
));
1454 return D3DERR_INVALIDCALL
;
1458 static HRESULT
set_vector(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
, D3DXHANDLE constant
,
1459 const void *indata
, D3DXPARAMETER_TYPE intype
)
1461 struct ctab_constant
*c
= get_valid_constant(table
, constant
);
1466 WARN("Invalid argument specified\n");
1467 return D3DERR_INVALIDCALL
;
1470 switch (c
->desc
.Class
)
1475 set(table
, device
, c
, &indata
, intype
, &count
, 4, D3DXPC_VECTOR
, 0, FALSE
);
1478 case D3DXPC_MATRIX_ROWS
:
1479 case D3DXPC_MATRIX_COLUMNS
:
1483 FIXME("Unhandled parameter class %s\n", debug_d3dxparameter_class(c
->desc
.Class
));
1484 return D3DERR_INVALIDCALL
;
1488 static HRESULT
set_vector_array(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
, D3DXHANDLE constant
,
1489 const void *indata
, UINT count
, D3DXPARAMETER_TYPE intype
)
1491 struct ctab_constant
*c
= get_valid_constant(table
, constant
);
1495 WARN("Invalid argument specified\n");
1496 return D3DERR_INVALIDCALL
;
1499 switch (c
->desc
.Class
)
1503 case D3DXPC_MATRIX_ROWS
:
1504 case D3DXPC_MATRIX_COLUMNS
:
1507 set(table
, device
, c
, &indata
, intype
, &count
, 4, D3DXPC_VECTOR
, 0, FALSE
);
1511 FIXME("Unhandled parameter class %s\n", debug_d3dxparameter_class(c
->desc
.Class
));
1512 return D3DERR_INVALIDCALL
;
1516 static HRESULT
set_matrix_array(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
, D3DXHANDLE constant
,
1517 const void *indata
, UINT count
, BOOL transpose
)
1519 struct ctab_constant
*c
= get_valid_constant(table
, constant
);
1523 WARN("Invalid argument specified\n");
1524 return D3DERR_INVALIDCALL
;
1527 switch (c
->desc
.Class
)
1531 case D3DXPC_MATRIX_ROWS
:
1532 case D3DXPC_MATRIX_COLUMNS
:
1535 set(table
, device
, c
, &indata
, D3DXPT_FLOAT
, &count
, 4,
1536 transpose
? D3DXPC_MATRIX_ROWS
: D3DXPC_MATRIX_COLUMNS
, 0, FALSE
);
1540 FIXME("Unhandled parameter class %s\n", debug_d3dxparameter_class(c
->desc
.Class
));
1541 return D3DERR_INVALIDCALL
;
1545 static HRESULT
set_matrix_pointer_array(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
,
1546 D3DXHANDLE constant
, const void **indata
, UINT count
, BOOL transpose
)
1548 struct ctab_constant
*c
= get_valid_constant(table
, constant
);
1552 WARN("Invalid argument specified\n");
1553 return D3DERR_INVALIDCALL
;
1556 switch (c
->desc
.Class
)
1560 case D3DXPC_MATRIX_ROWS
:
1561 case D3DXPC_MATRIX_COLUMNS
:
1564 set(table
, device
, c
, indata
, D3DXPT_FLOAT
, &count
, 4,
1565 transpose
? D3DXPC_MATRIX_ROWS
: D3DXPC_MATRIX_COLUMNS
, 0, TRUE
);
1569 FIXME("Unhandled parameter class %s\n", debug_d3dxparameter_class(c
->desc
.Class
));
1570 return D3DERR_INVALIDCALL
;
1574 static HRESULT WINAPI
ID3DXConstantTableImpl_SetDefaults(struct ID3DXConstantTable
*iface
,
1575 struct IDirect3DDevice9
*device
)
1577 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1580 TRACE("iface %p, device %p\n", iface
, device
);
1584 WARN("Invalid argument specified\n");
1585 return D3DERR_INVALIDCALL
;
1588 for (i
= 0; i
< This
->desc
.Constants
; i
++)
1590 D3DXCONSTANT_DESC
*desc
= &This
->constants
[i
].desc
;
1593 if (!desc
->DefaultValue
)
1596 switch (desc
->RegisterSet
)
1599 if (is_vertex_shader(This
->desc
.Version
))
1600 hr
= IDirect3DDevice9_SetVertexShaderConstantB(device
, desc
->RegisterIndex
, desc
->DefaultValue
,
1601 desc
->RegisterCount
);
1603 hr
= IDirect3DDevice9_SetPixelShaderConstantB(device
, desc
->RegisterIndex
, desc
->DefaultValue
,
1604 desc
->RegisterCount
);
1608 if (is_vertex_shader(This
->desc
.Version
))
1609 hr
= IDirect3DDevice9_SetVertexShaderConstantI(device
, desc
->RegisterIndex
, desc
->DefaultValue
,
1610 desc
->RegisterCount
);
1612 hr
= IDirect3DDevice9_SetPixelShaderConstantI(device
, desc
->RegisterIndex
, desc
->DefaultValue
,
1613 desc
->RegisterCount
);
1617 if (is_vertex_shader(This
->desc
.Version
))
1618 hr
= IDirect3DDevice9_SetVertexShaderConstantF(device
, desc
->RegisterIndex
, desc
->DefaultValue
,
1619 desc
->RegisterCount
);
1621 hr
= IDirect3DDevice9_SetPixelShaderConstantF(device
, desc
->RegisterIndex
, desc
->DefaultValue
,
1622 desc
->RegisterCount
);
1626 FIXME("Unhandled register set %s\n", debug_d3dxparameter_registerset(desc
->RegisterSet
));
1638 static HRESULT WINAPI
ID3DXConstantTableImpl_SetValue(struct ID3DXConstantTable
*iface
,
1639 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const void *data
, unsigned int bytes
)
1641 struct ID3DXConstantTableImpl
*table
= impl_from_ID3DXConstantTable(iface
);
1642 struct ctab_constant
*c
= get_valid_constant(table
, constant
);
1643 D3DXCONSTANT_DESC
*desc
;
1645 TRACE("iface %p, device %p, constant %p, data %p, bytes %u\n", iface
, device
, constant
, data
, bytes
);
1647 if (!device
|| !c
|| !data
)
1649 WARN("Invalid argument specified\n");
1650 return D3DERR_INVALIDCALL
;
1655 switch (desc
->Class
)
1659 case D3DXPC_MATRIX_ROWS
:
1660 case D3DXPC_MATRIX_COLUMNS
:
1663 set(table
, device
, c
, &data
, desc
->Type
, &bytes
, desc
->Columns
, D3DXPC_SCALAR
, 0, FALSE
);
1667 FIXME("Unhandled parameter class %s\n", debug_d3dxparameter_class(desc
->Class
));
1668 return D3DERR_INVALIDCALL
;
1672 static HRESULT WINAPI
ID3DXConstantTableImpl_SetBool(struct ID3DXConstantTable
*iface
,
1673 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, BOOL b
)
1675 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1677 TRACE("iface %p, device %p, constant %p, b %d\n", iface
, device
, constant
, b
);
1679 return set_scalar(This
, device
, constant
, &b
, D3DXPT_BOOL
);
1682 static HRESULT WINAPI
ID3DXConstantTableImpl_SetBoolArray(struct ID3DXConstantTable
*iface
,
1683 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const BOOL
*b
, UINT count
)
1685 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1687 TRACE("iface %p, device %p, constant %p, b %p, count %d\n", iface
, device
, constant
, b
, count
);
1689 return set_scalar_array(This
, device
, constant
, b
, count
, D3DXPT_BOOL
);
1692 static HRESULT WINAPI
ID3DXConstantTableImpl_SetInt(struct ID3DXConstantTable
*iface
,
1693 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, INT n
)
1695 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1697 TRACE("iface %p, device %p, constant %p, n %d\n", iface
, device
, constant
, n
);
1699 return set_scalar(This
, device
, constant
, &n
, D3DXPT_INT
);
1702 static HRESULT WINAPI
ID3DXConstantTableImpl_SetIntArray(struct ID3DXConstantTable
*iface
,
1703 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const INT
*n
, UINT count
)
1705 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1707 TRACE("iface %p, device %p, constant %p, n %p, count %d\n", iface
, device
, constant
, n
, count
);
1709 return set_scalar_array(This
, device
, constant
, n
, count
, D3DXPT_INT
);
1712 static HRESULT WINAPI
ID3DXConstantTableImpl_SetFloat(struct ID3DXConstantTable
*iface
,
1713 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, float f
)
1715 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1717 TRACE("iface %p, device %p, constant %p, f %f\n", iface
, device
, constant
, f
);
1719 return set_scalar(This
, device
, constant
, &f
, D3DXPT_FLOAT
);
1722 static HRESULT WINAPI
ID3DXConstantTableImpl_SetFloatArray(struct ID3DXConstantTable
*iface
,
1723 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const float *f
, UINT count
)
1725 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1727 TRACE("iface %p, device %p, constant %p, f %p, count %d\n", iface
, device
, constant
, f
, count
);
1729 return set_scalar_array(This
, device
, constant
, f
, count
, D3DXPT_FLOAT
);
1732 static HRESULT WINAPI
ID3DXConstantTableImpl_SetVector(struct ID3DXConstantTable
*iface
,
1733 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXVECTOR4
*vector
)
1735 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1737 TRACE("iface %p, device %p, constant %p, vector %p\n", iface
, device
, constant
, vector
);
1739 return set_vector(This
, device
, constant
, vector
, D3DXPT_FLOAT
);
1742 static HRESULT WINAPI
ID3DXConstantTableImpl_SetVectorArray(struct ID3DXConstantTable
*iface
,
1743 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXVECTOR4
*vector
, UINT count
)
1745 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1747 TRACE("iface %p, device %p, constant %p, vector %p, count %u\n", iface
, device
, constant
, vector
, count
);
1749 return set_vector_array(This
, device
, constant
, vector
, count
, D3DXPT_FLOAT
);
1752 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrix(struct ID3DXConstantTable
*iface
,
1753 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXMATRIX
*matrix
)
1755 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1757 TRACE("iface %p, device %p, constant %p, matrix %p\n", iface
, device
, constant
, matrix
);
1759 return set_matrix_array(This
, device
, constant
, matrix
, 1, FALSE
);
1762 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrixArray(struct ID3DXConstantTable
*iface
,
1763 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXMATRIX
*matrix
, UINT count
)
1765 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1767 TRACE("iface %p, device %p, constant %p, matrix %p, count %u\n", iface
, device
, constant
, matrix
, count
);
1769 return set_matrix_array(This
, device
, constant
, matrix
, count
, FALSE
);
1772 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrixPointerArray(struct ID3DXConstantTable
*iface
,
1773 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXMATRIX
**matrix
, UINT count
)
1775 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1777 TRACE("iface %p, device %p, constant %p, matrix %p, count %u)\n", iface
, device
, constant
, matrix
, count
);
1779 return set_matrix_pointer_array(This
, device
, constant
, (const void **)matrix
, count
, FALSE
);
1782 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrixTranspose(struct ID3DXConstantTable
*iface
,
1783 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXMATRIX
*matrix
)
1785 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1787 TRACE("iface %p, device %p, constant %p, matrix %p\n", iface
, device
, constant
, matrix
);
1789 return set_matrix_array(This
, device
, constant
, matrix
, 1, TRUE
);
1792 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrixTransposeArray(struct ID3DXConstantTable
*iface
,
1793 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXMATRIX
*matrix
, UINT count
)
1795 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1797 TRACE("iface %p, device %p, constant %p, matrix %p, count %u\n", iface
, device
, constant
, matrix
, count
);
1799 return set_matrix_array(This
, device
, constant
, matrix
, count
, TRUE
);
1802 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrixTransposePointerArray(struct ID3DXConstantTable
*iface
,
1803 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXMATRIX
**matrix
, UINT count
)
1805 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1807 TRACE("iface %p, device %p, constant %p, matrix %p, count %u)\n", iface
, device
, constant
, matrix
, count
);
1809 return set_matrix_pointer_array(This
, device
, constant
, (const void **)matrix
, count
, TRUE
);
1812 static const struct ID3DXConstantTableVtbl ID3DXConstantTable_Vtbl
=
1814 /*** IUnknown methods ***/
1815 ID3DXConstantTableImpl_QueryInterface
,
1816 ID3DXConstantTableImpl_AddRef
,
1817 ID3DXConstantTableImpl_Release
,
1818 /*** ID3DXBuffer methods ***/
1819 ID3DXConstantTableImpl_GetBufferPointer
,
1820 ID3DXConstantTableImpl_GetBufferSize
,
1821 /*** ID3DXConstantTable methods ***/
1822 ID3DXConstantTableImpl_GetDesc
,
1823 ID3DXConstantTableImpl_GetConstantDesc
,
1824 ID3DXConstantTableImpl_GetSamplerIndex
,
1825 ID3DXConstantTableImpl_GetConstant
,
1826 ID3DXConstantTableImpl_GetConstantByName
,
1827 ID3DXConstantTableImpl_GetConstantElement
,
1828 ID3DXConstantTableImpl_SetDefaults
,
1829 ID3DXConstantTableImpl_SetValue
,
1830 ID3DXConstantTableImpl_SetBool
,
1831 ID3DXConstantTableImpl_SetBoolArray
,
1832 ID3DXConstantTableImpl_SetInt
,
1833 ID3DXConstantTableImpl_SetIntArray
,
1834 ID3DXConstantTableImpl_SetFloat
,
1835 ID3DXConstantTableImpl_SetFloatArray
,
1836 ID3DXConstantTableImpl_SetVector
,
1837 ID3DXConstantTableImpl_SetVectorArray
,
1838 ID3DXConstantTableImpl_SetMatrix
,
1839 ID3DXConstantTableImpl_SetMatrixArray
,
1840 ID3DXConstantTableImpl_SetMatrixPointerArray
,
1841 ID3DXConstantTableImpl_SetMatrixTranspose
,
1842 ID3DXConstantTableImpl_SetMatrixTransposeArray
,
1843 ID3DXConstantTableImpl_SetMatrixTransposePointerArray
1846 static HRESULT
parse_ctab_constant_type(const char *ctab
, DWORD typeoffset
, struct ctab_constant
*constant
,
1847 BOOL is_element
, WORD index
, WORD max_index
, DWORD
*offset
, DWORD nameoffset
, UINT regset
)
1849 const D3DXSHADER_TYPEINFO
*type
= (LPD3DXSHADER_TYPEINFO
)(ctab
+ typeoffset
);
1850 const D3DXSHADER_STRUCTMEMBERINFO
*memberinfo
= NULL
;
1851 HRESULT hr
= D3D_OK
;
1855 constant
->desc
.DefaultValue
= offset
? ctab
+ *offset
: NULL
;
1856 constant
->desc
.Class
= type
->Class
;
1857 constant
->desc
.Type
= type
->Type
;
1858 constant
->desc
.Rows
= type
->Rows
;
1859 constant
->desc
.Columns
= type
->Columns
;
1860 constant
->desc
.Elements
= is_element
? 1 : type
->Elements
;
1861 constant
->desc
.StructMembers
= type
->StructMembers
;
1862 constant
->desc
.Name
= ctab
+ nameoffset
;
1863 constant
->desc
.RegisterSet
= regset
;
1864 constant
->desc
.RegisterIndex
= index
;
1866 TRACE("name %s, elements %u, index %u, defaultvalue %p, regset %s\n", constant
->desc
.Name
,
1867 constant
->desc
.Elements
, index
, constant
->desc
.DefaultValue
,
1868 debug_d3dxparameter_registerset(regset
));
1869 TRACE("class %s, type %s, rows %d, columns %d, elements %d, struct_members %d\n",
1870 debug_d3dxparameter_class(type
->Class
), debug_d3dxparameter_type(type
->Type
),
1871 type
->Rows
, type
->Columns
, type
->Elements
, type
->StructMembers
);
1873 if (type
->Elements
> 1 && !is_element
)
1875 count
= type
->Elements
;
1877 else if ((type
->Class
== D3DXPC_STRUCT
) && type
->StructMembers
)
1879 memberinfo
= (D3DXSHADER_STRUCTMEMBERINFO
*)(ctab
+ type
->StructMemberInfo
);
1880 count
= type
->StructMembers
;
1885 constant
->constants
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*constant
->constants
) * count
);
1886 if (!constant
->constants
)
1888 ERR("Out of memory\n");
1893 for (i
= 0; i
< count
; ++i
)
1895 hr
= parse_ctab_constant_type(ctab
, memberinfo
? memberinfo
[i
].TypeInfo
: typeoffset
,
1896 &constant
->constants
[i
], memberinfo
== NULL
, index
+ size
, max_index
, offset
,
1897 memberinfo
? memberinfo
[i
].Name
: nameoffset
, regset
);
1901 size
+= constant
->constants
[i
].desc
.RegisterCount
;
1906 WORD offsetdiff
= type
->Columns
* type
->Rows
;
1909 size
= type
->Columns
* type
->Rows
;
1914 fail
= type
->Class
!= D3DXPC_SCALAR
&& type
->Class
!= D3DXPC_VECTOR
1915 && type
->Class
!= D3DXPC_MATRIX_ROWS
&& type
->Class
!= D3DXPC_MATRIX_COLUMNS
;
1920 switch (type
->Class
)
1926 offsetdiff
= type
->Rows
* 4;
1929 case D3DXPC_MATRIX_ROWS
:
1930 offsetdiff
= type
->Rows
* 4;
1934 case D3DXPC_MATRIX_COLUMNS
:
1935 offsetdiff
= type
->Columns
* 4;
1936 size
= type
->Columns
;
1945 case D3DXRS_SAMPLER
:
1947 fail
= type
->Class
!= D3DXPC_OBJECT
;
1957 FIXME("Unhandled register set %s, type class %s\n", debug_d3dxparameter_registerset(regset
),
1958 debug_d3dxparameter_class(type
->Class
));
1961 /* offset in bytes => offsetdiff * sizeof(DWORD) */
1962 if (offset
) *offset
+= offsetdiff
* 4;
1965 constant
->desc
.RegisterCount
= max(0, min(max_index
- index
, size
));
1966 constant
->desc
.Bytes
= 4 * constant
->desc
.Elements
* type
->Rows
* type
->Columns
;
1971 if (constant
->constants
)
1973 for (i
= 0; i
< count
; ++i
)
1975 free_constant(&constant
->constants
[i
]);
1977 HeapFree(GetProcessHeap(), 0, constant
->constants
);
1978 constant
->constants
= NULL
;
1984 HRESULT WINAPI
D3DXGetShaderConstantTableEx(const DWORD
*byte_code
, DWORD flags
, ID3DXConstantTable
**constant_table
)
1986 struct ID3DXConstantTableImpl
*object
= NULL
;
1990 const D3DXSHADER_CONSTANTTABLE
*ctab_header
;
1991 const D3DXSHADER_CONSTANTINFO
*constant_info
;
1994 TRACE("byte_code %p, flags %x, constant_table %p\n", byte_code
, flags
, constant_table
);
1996 if (constant_table
) *constant_table
= NULL
;
1998 if (!byte_code
|| !constant_table
)
2000 WARN("Invalid argument specified.\n");
2001 return D3DERR_INVALIDCALL
;
2004 if (!is_valid_bytecode(*byte_code
))
2006 WARN("Invalid byte_code specified.\n");
2010 if (flags
) FIXME("Flags (%#x) are not handled, yet!\n", flags
);
2012 hr
= D3DXFindShaderComment(byte_code
, MAKEFOURCC('C','T','A','B'), &data
, &size
);
2015 WARN("CTAB not found.\n");
2016 return D3DXERR_INVALIDDATA
;
2019 if (size
< sizeof(*ctab_header
))
2021 WARN("Invalid CTAB size.\n");
2022 return D3DXERR_INVALIDDATA
;
2025 ctab_header
= (const D3DXSHADER_CONSTANTTABLE
*)data
;
2026 if (ctab_header
->Size
!= sizeof(*ctab_header
))
2028 WARN("Invalid D3DXSHADER_CONSTANTTABLE size.\n");
2029 return D3DXERR_INVALIDDATA
;
2032 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*object
));
2034 return E_OUTOFMEMORY
;
2036 object
->ID3DXConstantTable_iface
.lpVtbl
= &ID3DXConstantTable_Vtbl
;
2039 object
->ctab
= HeapAlloc(GetProcessHeap(), 0, size
);
2042 ERR("Out of memory\n");
2043 HeapFree(GetProcessHeap(), 0, object
);
2044 return E_OUTOFMEMORY
;
2046 object
->size
= size
;
2047 memcpy(object
->ctab
, data
, object
->size
);
2049 object
->desc
.Creator
= ctab_header
->Creator
? object
->ctab
+ ctab_header
->Creator
: NULL
;
2050 object
->desc
.Version
= ctab_header
->Version
;
2051 object
->desc
.Constants
= ctab_header
->Constants
;
2052 TRACE("Creator %s, Version %x, Constants %u, Target %s\n",
2053 debugstr_a(object
->desc
.Creator
), object
->desc
.Version
, object
->desc
.Constants
,
2054 debugstr_a(ctab_header
->Target
? object
->ctab
+ ctab_header
->Target
: NULL
));
2056 object
->constants
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
2057 sizeof(*object
->constants
) * object
->desc
.Constants
);
2058 if (!object
->constants
)
2060 ERR("Out of memory\n");
2065 constant_info
= (const D3DXSHADER_CONSTANTINFO
*)(object
->ctab
+ ctab_header
->ConstantInfo
);
2066 for (i
= 0; i
< ctab_header
->Constants
; i
++)
2068 DWORD offset
= constant_info
[i
].DefaultValue
;
2070 hr
= parse_ctab_constant_type(object
->ctab
, constant_info
[i
].TypeInfo
,
2071 &object
->constants
[i
], FALSE
, constant_info
[i
].RegisterIndex
,
2072 constant_info
[i
].RegisterIndex
+ constant_info
[i
].RegisterCount
,
2073 offset
? &offset
: NULL
, constant_info
[i
].Name
, constant_info
[i
].RegisterSet
);
2078 * Set the register count, it may differ for D3DXRS_INT4, because somehow
2079 * it makes the assumption that the register size is 1 instead of 4, so the
2080 * count is 4 times bigger. This holds true only for toplevel shader
2081 * constants. The count of elements and members is always based on a
2082 * register size of 4.
2084 if (object
->constants
[i
].desc
.RegisterSet
== D3DXRS_INT4
)
2086 object
->constants
[i
].desc
.RegisterCount
= constant_info
[i
].RegisterCount
;
2090 *constant_table
= &object
->ID3DXConstantTable_iface
;
2095 free_constant_table(object
);
2096 HeapFree(GetProcessHeap(), 0, object
);
2101 HRESULT WINAPI
D3DXGetShaderConstantTable(const DWORD
*byte_code
, ID3DXConstantTable
**constant_table
)
2103 TRACE("(%p, %p): Forwarded to D3DXGetShaderConstantTableEx\n", byte_code
, constant_table
);
2105 return D3DXGetShaderConstantTableEx(byte_code
, 0, constant_table
);
2108 HRESULT WINAPI
D3DXCreateFragmentLinker(IDirect3DDevice9
*device
, UINT size
, ID3DXFragmentLinker
**linker
)
2110 FIXME("device %p, size %u, linker %p: stub.\n", device
, size
, linker
);
2119 HRESULT WINAPI
D3DXCreateFragmentLinkerEx(IDirect3DDevice9
*device
, UINT size
, DWORD flags
, ID3DXFragmentLinker
**linker
)
2121 FIXME("device %p, size %u, flags %#x, linker %p: stub.\n", device
, size
, flags
, linker
);
2129 HRESULT WINAPI
D3DXGetShaderSamplers(const DWORD
*byte_code
, const char **samplers
, UINT
*count
)
2131 UINT i
, sampler_count
= 0;
2134 const D3DXSHADER_CONSTANTTABLE
*ctab_header
;
2135 const D3DXSHADER_CONSTANTINFO
*constant_info
;
2137 TRACE("byte_code %p, samplers %p, count %p\n", byte_code
, samplers
, count
);
2139 if (count
) *count
= 0;
2141 if (D3DXFindShaderComment(byte_code
, MAKEFOURCC('C','T','A','B'), (const void **)&data
, &size
) != D3D_OK
)
2144 if (size
< sizeof(*ctab_header
)) return D3D_OK
;
2146 ctab_header
= (const D3DXSHADER_CONSTANTTABLE
*)data
;
2147 if (ctab_header
->Size
!= sizeof(*ctab_header
)) return D3D_OK
;
2149 constant_info
= (const D3DXSHADER_CONSTANTINFO
*)(data
+ ctab_header
->ConstantInfo
);
2150 for (i
= 0; i
< ctab_header
->Constants
; i
++)
2152 const D3DXSHADER_TYPEINFO
*type
;
2154 TRACE("name = %s\n", data
+ constant_info
[i
].Name
);
2156 type
= (const D3DXSHADER_TYPEINFO
*)(data
+ constant_info
[i
].TypeInfo
);
2158 if (type
->Type
== D3DXPT_SAMPLER
2159 || type
->Type
== D3DXPT_SAMPLER1D
2160 || type
->Type
== D3DXPT_SAMPLER2D
2161 || type
->Type
== D3DXPT_SAMPLER3D
2162 || type
->Type
== D3DXPT_SAMPLERCUBE
)
2164 if (samplers
) samplers
[sampler_count
] = data
+ constant_info
[i
].Name
;
2170 TRACE("Found %u samplers\n", sampler_count
);
2172 if (count
) *count
= sampler_count
;
2184 { "nop", 0 }, /* D3DSIO_NOP */
2185 { "mov", 2 }, /* D3DSIO_MOV */
2186 { "add", 3 }, /* D3DSIO_ADD */
2187 { "sub", 3 }, /* D3DSIO_SUB */
2188 { "mad", 4 }, /* D3DSIO_MAD */
2189 { "mul", 3 }, /* D3DSIO_MUL */
2190 { "rcp", 2 }, /* D3DSIO_RCP */
2191 { "rsq", 2 }, /* D3DSIO_RSQ */
2192 { "dp3", 3 }, /* D3DSIO_DP3 */
2193 { "dp4", 3 }, /* D3DSIO_DP4 */
2194 { "min", 3 }, /* D3DSIO_MIN */
2195 { "max", 3 }, /* D3DSIO_MAX */
2196 { "slt", 3 }, /* D3DSIO_SLT */
2197 { "sge", 3 }, /* D3DSIO_SGE */
2198 { "exp", 2 }, /* D3DSIO_EXP */
2199 { "log", 2 }, /* D3DSIO_LOG */
2200 { "lit", 2 }, /* D3DSIO_LIT */
2201 { "dst", 3 }, /* D3DSIO_DST */
2202 { "lrp", 4 }, /* D3DSIO_LRP */
2203 { "frc", 2 }, /* D3DSIO_FRC */
2204 { "m4x4", 3 }, /* D3DSIO_M4x4 */
2205 { "m4x3", 3 }, /* D3DSIO_M4x3 */
2206 { "m3x4", 3 }, /* D3DSIO_M3x4 */
2207 { "m3x3", 3 }, /* D3DSIO_M3x3 */
2208 { "m3x2", 3 }, /* D3DSIO_M3x2 */
2209 { "call", 1 }, /* D3DSIO_CALL */
2210 { "callnz", 2 }, /* D3DSIO_CALLNZ */
2211 { "loop", 2 }, /* D3DSIO_LOOP */
2212 { "ret", 0 }, /* D3DSIO_RET */
2213 { "endloop", 1 }, /* D3DSIO_ENDLOOP */
2214 { "label", 1 }, /* D3DSIO_LABEL */
2215 { "dcl", 1 }, /* D3DSIO_DCL (handled separately) */
2216 { "pow", 3 }, /* D3DSIO_POW */
2217 { "crs", 3 }, /* D3DSIO_CRS */
2218 { "sgn", 4 }, /* D3DSIO_SGN */
2219 { "abs", 2 }, /* D3DSIO_ABS */
2220 { "nrm", 2 }, /* D3DSIO_NRM */
2221 { "sincos", 4 }, /* D3DSIO_SINCOS */
2222 { "rep", 1 }, /* D3DSIO_REP */
2223 { "endrep", 0 }, /* D3DSIO_ENDREP */
2224 { "if", 1 }, /* D3DSIO_IF */
2225 { "if", 2 }, /* D3DSIO_IFC */
2226 { "else", 0 }, /* D3DSIO_ELSE */
2227 { "endif", 0 }, /* D3DSIO_ENDIF */
2228 { "break", 0 }, /* D3DSIO_BREAK */
2229 { "break", 2 }, /* D3DSIO_BREAKC */
2230 { "mova", 2 }, /* D3DSIO_MOVA */
2231 { "defb", 2 }, /* D3DSIO_DEFB */
2232 { "defi", 2 }, /* D3DSIO_DEFI */
2233 { "texcoord", 1 }, /* D3DSIO_TEXCOORD */
2234 { "texkill", 1 }, /* D3DSIO_TEXKILL */
2235 { "texld", 3 }, /* D3DSIO_TEX */
2236 { "texbem", 2 }, /* D3DSIO_TEXBEM */
2237 { "texbeml", 2 }, /* D3DSIO_TEXBEML */
2238 { "texreg2ar", 2 }, /* D3DSIO_TEXREG2AR */
2239 { "texreg2gb", 2 }, /* D3DSIO_TEXREG2GB */
2240 { "texm3x2pad", 2 }, /* D3DSIO_TEXM3x2PAD */
2241 { "texm3x2tex", 2 }, /* D3DSIO_TEXM3x2TEX */
2242 { "texm3x3pad", 2 }, /* D3DSIO_TEXM3x3PAD */
2243 { "texm3x3tex", 2 }, /* D3DSIO_TEXM3x3TEX */
2244 { "texm3x3diff", 2 }, /* D3DSIO_TEXM3x3DIFF */
2245 { "texm3x3spec", 3 }, /* D3DSIO_TEXM3x3SPEC */
2246 { "texm3x3vspec", 2 }, /* D3DSIO_TEXM3x3VSPEC */
2247 { "expp", 2 }, /* D3DSIO_EXPP */
2248 { "logp", 2 }, /* D3DSIO_LOGP */
2249 { "cnd", 4 }, /* D3DSIO_CND */
2250 { "def", 5 }, /* D3DSIO_DEF (handled separately) */
2251 { "texreg2rgb", 2 }, /* D3DSIO_TEXREG2RGB */
2252 { "texdp3tex", 2 }, /* D3DSIO_TEXDP3TEX */
2253 { "texm3x2depth", 2 }, /* D3DSIO_TEXM3x2DEPTH */
2254 { "texdp3", 2 }, /* D3DSIO_TEXDP3 */
2255 { "texm3x3", 2 }, /* D3DSIO_TEXM3x3 */
2256 { "texdepth", 1 }, /* D3DSIO_TEXDEPTH */
2257 { "cmp", 4 }, /* D3DSIO_CMP */
2258 { "bem", 3 }, /* D3DSIO_BEM */
2259 { "dp2add", 4 }, /* D3DSIO_DP2ADD */
2260 { "dsx", 2 }, /* D3DSIO_DSX */
2261 { "dsy", 2 }, /* D3DSIO_DSY */
2262 { "texldd", 5 }, /* D3DSIO_TEXLDD */
2263 { "setp", 3 }, /* D3DSIO_SETP */
2264 { "texldl", 3 }, /* D3DSIO_TEXLDL */
2265 { "breakp", 1 } /* D3DSIO_BREAKP */
2268 static const char *decl_usage
[] = { "position", "blendweight", "blendindices", "normal", "psize", "texcoord",
2269 "tangent", "binormal", "tessfactor", "positiont", "color" };
2271 static const char *tex_type
[] = { "", "1d", "2d", "cube", "volume" };
2273 static int add_modifier(char *buffer
, DWORD param
)
2276 DWORD dst_mod
= param
& D3DSP_DSTMOD_MASK
;
2278 if (dst_mod
& D3DSPDM_SATURATE
)
2279 buf
+= sprintf(buf
, "_sat");
2280 if (dst_mod
& D3DSPDM_PARTIALPRECISION
)
2281 buf
+= sprintf(buf
, "_pp");
2282 if (dst_mod
& D3DSPDM_MSAMPCENTROID
)
2283 buf
+= sprintf(buf
, "_centroid");
2285 return buf
- buffer
;
2288 static int add_register(char *buffer
, DWORD param
, BOOL dst
, BOOL ps
)
2291 DWORD reg_type
= ((param
& D3DSP_REGTYPE_MASK2
) >> D3DSP_REGTYPE_SHIFT2
)
2292 | ((param
& D3DSP_REGTYPE_MASK
) >> D3DSP_REGTYPE_SHIFT
);
2293 DWORD reg_num
= param
& D3DSP_REGNUM_MASK
;
2295 if (reg_type
== D3DSPR_INPUT
)
2296 buf
+= sprintf(buf
, "v%d", reg_num
);
2297 else if (reg_type
== D3DSPR_CONST
)
2298 buf
+= sprintf(buf
, "c%d", reg_num
);
2299 else if (reg_type
== D3DSPR_TEMP
)
2300 buf
+= sprintf(buf
, "r%d", reg_num
);
2301 else if (reg_type
== D3DSPR_ADDR
)
2302 buf
+= sprintf(buf
, "%s%d", ps
? "t" : "a", reg_num
);
2303 else if (reg_type
== D3DSPR_SAMPLER
)
2304 buf
+= sprintf(buf
, "s%d", reg_num
);
2305 else if (reg_type
== D3DSPR_RASTOUT
)
2306 buf
+= sprintf(buf
, "oPos");
2307 else if (reg_type
== D3DSPR_COLOROUT
)
2308 buf
+= sprintf(buf
, "oC%d", reg_num
);
2309 else if (reg_type
== D3DSPR_TEXCRDOUT
)
2310 buf
+= sprintf(buf
, "oT%d", reg_num
);
2311 else if (reg_type
== D3DSPR_ATTROUT
)
2312 buf
+= sprintf(buf
, "oD%d", reg_num
);
2314 buf
+= sprintf(buf
, "? (%d)", reg_type
);
2318 if ((param
& D3DSP_WRITEMASK_ALL
) != D3DSP_WRITEMASK_ALL
)
2320 buf
+= sprintf(buf
, ".%s%s%s%s", param
& D3DSP_WRITEMASK_0
? "x" : "",
2321 param
& D3DSP_WRITEMASK_1
? "y" : "",
2322 param
& D3DSP_WRITEMASK_2
? "z" : "",
2323 param
& D3DSP_WRITEMASK_3
? "w" : "");
2328 if ((param
& D3DVS_SWIZZLE_MASK
) != D3DVS_NOSWIZZLE
)
2330 if ( ((param
& D3DSP_SWIZZLE_MASK
) == (D3DVS_X_X
| D3DVS_Y_X
| D3DVS_Z_X
| D3DVS_W_X
)) ||
2331 ((param
& D3DSP_SWIZZLE_MASK
) == (D3DVS_X_Y
| D3DVS_Y_Y
| D3DVS_Z_Y
| D3DVS_W_Y
)) ||
2332 ((param
& D3DSP_SWIZZLE_MASK
) == (D3DVS_X_Z
| D3DVS_Y_Z
| D3DVS_Z_Z
| D3DVS_W_Z
)) ||
2333 ((param
& D3DSP_SWIZZLE_MASK
) == (D3DVS_X_W
| D3DVS_Y_W
| D3DVS_Z_W
| D3DVS_W_W
)) )
2334 buf
+= sprintf(buf
, ".%c", 'w' + (((param
>> D3DVS_SWIZZLE_SHIFT
) + 1) & 0x3));
2336 buf
+= sprintf(buf
, ".%c%c%c%c", 'w' + (((param
>> (D3DVS_SWIZZLE_SHIFT
+0)) + 1) & 0x3),
2337 'w' + (((param
>> (D3DVS_SWIZZLE_SHIFT
+2)) + 1) & 0x3),
2338 'w' + (((param
>> (D3DVS_SWIZZLE_SHIFT
+4)) + 1) & 0x3),
2339 'w' + (((param
>> (D3DVS_SWIZZLE_SHIFT
+6)) + 1) & 0x3));
2343 return buf
- buffer
;
2346 HRESULT WINAPI
D3DXDisassembleShader(const DWORD
*shader
, BOOL colorcode
, const char *comments
, ID3DXBuffer
**disassembly
)
2348 DWORD
*ptr
= (DWORD
*)shader
;
2350 UINT capacity
= 4096;
2354 TRACE("%p %d %s %p\n", shader
, colorcode
, debugstr_a(comments
), disassembly
);
2356 if (!shader
|| !disassembly
)
2357 return D3DERR_INVALIDCALL
;
2359 buf
= buffer
= HeapAlloc(GetProcessHeap(), 0, capacity
);
2361 return E_OUTOFMEMORY
;
2363 ps
= (*ptr
>> 16) & 1;
2364 buf
+= sprintf(buf
, " %s_%d_%d\n", ps
? "ps" : "vs", D3DSHADER_VERSION_MAJOR(*ptr
), D3DSHADER_VERSION_MINOR(*ptr
));
2367 while (*ptr
!= D3DSIO_END
)
2369 if ((buf
- buffer
+ 128) > capacity
)
2371 UINT count
= buf
- buffer
;
2372 char *new_buffer
= HeapReAlloc(GetProcessHeap(), 0, buffer
, capacity
* 2);
2375 HeapFree(GetProcessHeap(), 0, buffer
);
2376 return E_OUTOFMEMORY
;
2379 buffer
= new_buffer
;
2380 buf
= buffer
+ count
;
2383 if ((*ptr
& D3DSI_OPCODE_MASK
) == D3DSIO_COMMENT
)
2385 ptr
+= 1 + ((*ptr
& D3DSI_COMMENTSIZE_MASK
) >> D3DSI_COMMENTSIZE_SHIFT
);
2387 else if ((*ptr
& D3DSI_OPCODE_MASK
) == D3DSIO_DEF
)
2389 buf
+= sprintf(buf
, " def c%d, %g, %g, %g, %g\n", *(ptr
+1) & D3DSP_REGNUM_MASK
,
2390 (double)*(float*)(ptr
+2), (double)*(float*)(ptr
+3),
2391 (double)*(float*)(ptr
+4), (double)*(float*)(ptr
+5));
2394 else if ((*ptr
& D3DSI_OPCODE_MASK
) == D3DSIO_DCL
)
2396 DWORD param1
= *++ptr
;
2397 DWORD param2
= *++ptr
;
2398 DWORD usage
= (param1
& D3DSP_DCL_USAGE_MASK
) >> D3DSP_DCL_USAGE_SHIFT
;
2399 DWORD usage_index
= (param1
& D3DSP_DCL_USAGEINDEX_MASK
) >> D3DSP_DCL_USAGEINDEX_SHIFT
;
2401 buf
+= sprintf(buf
, " dcl");
2404 if (param1
& D3DSP_TEXTURETYPE_MASK
)
2405 buf
+= sprintf(buf
, "_%s", (usage
<= D3DSTT_VOLUME
) ?
2406 tex_type
[(param1
& D3DSP_TEXTURETYPE_MASK
) >> D3DSP_TEXTURETYPE_SHIFT
] : "???");
2410 buf
+= sprintf(buf
, "_%s", (usage
<= D3DDECLUSAGE_COLOR
) ? decl_usage
[usage
] : "???");
2412 buf
+= sprintf(buf
, "%d", usage_index
);
2415 buf
+= add_modifier(buf
, param2
);
2416 buf
+= sprintf(buf
, " ");
2417 buf
+= add_register(buf
, param2
, TRUE
, TRUE
);
2418 buf
+= sprintf(buf
, "\n");
2421 else if ((*ptr
& D3DSI_OPCODE_MASK
) <= D3DSIO_BREAKP
)
2423 DWORD index
= *ptr
& D3DSI_OPCODE_MASK
;
2428 buf
+= sprintf(buf
, " %s", opcode
[index
].name
);
2431 if (opcode
[index
].length
)
2433 buf
+= add_modifier(buf
, *ptr
);
2435 for (j
= 0; j
< opcode
[index
].length
; j
++)
2437 buf
+= sprintf(buf
, "%s ", j
? "," : "");
2439 if ((j
!= 0) && ((*ptr
& D3DSP_SRCMOD_MASK
) != D3DSPSM_NONE
))
2441 if ((*ptr
& D3DSP_SRCMOD_MASK
) == D3DSPSM_NEG
)
2442 buf
+= sprintf(buf
, "-");
2444 buf
+= sprintf(buf
, "*");
2447 buf
+= add_register(buf
, *ptr
, j
== 0, ps
);
2449 if (*ptr
++ & D3DVS_ADDRESSMODE_MASK
)
2451 buf
+= sprintf(buf
, "[");
2452 buf
+= add_register(buf
, *ptr
, FALSE
, FALSE
);
2453 buf
+= sprintf(buf
, "]");
2458 buf
+= sprintf(buf
, "\n");
2462 buf
+= sprintf(buf
, " ???\n");
2467 hr
= D3DXCreateBuffer(buf
- buffer
+ 1 , disassembly
);
2469 strcpy(ID3DXBuffer_GetBufferPointer(*disassembly
), buffer
);
2470 HeapFree(GetProcessHeap(), 0, buffer
);
2475 static const DWORD
* skip_instruction(const DWORD
*byte_code
, UINT shader_model
)
2477 TRACE("Shader model %u\n", shader_model
);
2479 /* Handle all special instructions whose arguments may contain D3DSIO_DCL */
2480 if ((*byte_code
& D3DSI_OPCODE_MASK
) == D3DSIO_COMMENT
)
2482 byte_code
+= 1 + ((*byte_code
& D3DSI_COMMENTSIZE_MASK
) >> D3DSI_COMMENTSIZE_SHIFT
);
2484 else if (shader_model
>= 2)
2486 byte_code
+= 1 + ((*byte_code
& D3DSI_INSTLENGTH_MASK
) >> D3DSI_INSTLENGTH_SHIFT
);
2488 else if ((*byte_code
& D3DSI_OPCODE_MASK
) == D3DSIO_DEF
)
2494 /* Handle remaining safe instructions */
2495 while (*++byte_code
& (1u << 31));
2501 static UINT
get_shader_semantics(const DWORD
*byte_code
, D3DXSEMANTIC
*semantics
, DWORD type
)
2503 const DWORD
*ptr
= byte_code
;
2504 UINT shader_model
= (*ptr
>> 8) & 0xff;
2507 TRACE("Shader version: %#x\n", *ptr
);
2510 while (*ptr
!= D3DSIO_END
)
2512 if (*ptr
& (1u << 31))
2514 FIXME("Opcode expected but got %#x\n", *ptr
);
2517 else if ((*ptr
& D3DSI_OPCODE_MASK
) == D3DSIO_DCL
)
2519 DWORD param1
= *++ptr
;
2520 DWORD param2
= *++ptr
;
2521 DWORD usage
= (param1
& D3DSP_DCL_USAGE_MASK
) >> D3DSP_DCL_USAGE_SHIFT
;
2522 DWORD usage_index
= (param1
& D3DSP_DCL_USAGEINDEX_MASK
) >> D3DSP_DCL_USAGEINDEX_SHIFT
;
2523 DWORD reg_type
= ((param2
& D3DSP_REGTYPE_MASK2
) >> D3DSP_REGTYPE_SHIFT2
)
2524 | ((param2
& D3DSP_REGTYPE_MASK
) >> D3DSP_REGTYPE_SHIFT
);
2526 TRACE("D3DSIO_DCL param1: %#x, param2: %#x, usage: %u, usage_index: %u, reg_type: %u\n",
2527 param1
, param2
, usage
, usage_index
, reg_type
);
2529 if (reg_type
== type
)
2533 semantics
[i
].Usage
= usage
;
2534 semantics
[i
].UsageIndex
= usage_index
;
2543 ptr
= skip_instruction(ptr
, shader_model
);
2550 HRESULT WINAPI
D3DXGetShaderInputSemantics(const DWORD
*byte_code
, D3DXSEMANTIC
*semantics
, UINT
*count
)
2554 TRACE("byte_code %p, semantics %p, count %p\n", byte_code
, semantics
, count
);
2557 return D3DERR_INVALIDCALL
;
2559 nb_semantics
= get_shader_semantics(byte_code
, semantics
, D3DSPR_INPUT
);
2562 *count
= nb_semantics
;
2568 HRESULT WINAPI
D3DXGetShaderOutputSemantics(const DWORD
*byte_code
, D3DXSEMANTIC
*semantics
, UINT
*count
)
2572 TRACE("byte_code %p, semantics %p, count %p\n", byte_code
, semantics
, count
);
2575 return D3DERR_INVALIDCALL
;
2577 nb_semantics
= get_shader_semantics(byte_code
, semantics
, D3DSPR_OUTPUT
);
2580 *count
= nb_semantics
;
2585 struct d3dx9_texture_shader
2587 ID3DXTextureShader ID3DXTextureShader_iface
;
2591 static inline struct d3dx9_texture_shader
*impl_from_ID3DXTextureShader(ID3DXTextureShader
*iface
)
2593 return CONTAINING_RECORD(iface
, struct d3dx9_texture_shader
, ID3DXTextureShader_iface
);
2596 static HRESULT WINAPI
d3dx9_texture_shader_QueryInterface(ID3DXTextureShader
*iface
, REFIID riid
, void **out
)
2598 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
2600 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
2601 IsEqualGUID(riid
, &IID_ID3DXTextureShader
))
2603 iface
->lpVtbl
->AddRef(iface
);
2608 WARN("Interface %s not found.\n", debugstr_guid(riid
));
2610 return E_NOINTERFACE
;
2613 static ULONG WINAPI
d3dx9_texture_shader_AddRef(ID3DXTextureShader
*iface
)
2615 struct d3dx9_texture_shader
*texture_shader
= impl_from_ID3DXTextureShader(iface
);
2616 ULONG refcount
= InterlockedIncrement(&texture_shader
->ref
);
2618 TRACE("%p increasing refcount to %u.\n", texture_shader
, refcount
);
2623 static ULONG WINAPI
d3dx9_texture_shader_Release(ID3DXTextureShader
*iface
)
2625 struct d3dx9_texture_shader
*texture_shader
= impl_from_ID3DXTextureShader(iface
);
2626 ULONG refcount
= InterlockedDecrement(&texture_shader
->ref
);
2628 TRACE("%p decreasing refcount to %u.\n", texture_shader
, refcount
);
2632 HeapFree(GetProcessHeap(), 0, texture_shader
);
2638 static HRESULT WINAPI
d3dx9_texture_shader_GetFunction(ID3DXTextureShader
*iface
, struct ID3DXBuffer
**function
)
2640 FIXME("iface %p, function %p stub.\n", iface
, function
);
2645 static HRESULT WINAPI
d3dx9_texture_shader_GetConstantBuffer(ID3DXTextureShader
*iface
, struct ID3DXBuffer
**constant_buffer
)
2647 FIXME("iface %p, constant_buffer %p stub.\n", iface
, constant_buffer
);
2652 static HRESULT WINAPI
d3dx9_texture_shader_GetDesc(ID3DXTextureShader
*iface
, D3DXCONSTANTTABLE_DESC
*desc
)
2654 FIXME("iface %p, desc %p stub.\n", iface
, desc
);
2659 static HRESULT WINAPI
d3dx9_texture_shader_GetConstantDesc(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, D3DXCONSTANT_DESC
*constant_desc
, UINT
*count
)
2661 FIXME("iface %p, constant %p, constant_desc %p, count %p stub.\n", iface
, constant
, constant_desc
, count
);
2666 static D3DXHANDLE WINAPI
d3dx9_texture_shader_GetConstant(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, UINT index
)
2668 FIXME("iface %p, constant %p, index %u stub.\n", iface
, constant
, index
);
2673 static D3DXHANDLE WINAPI
d3dx9_texture_shader_GetConstantByName(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const char *name
)
2675 FIXME("iface %p, constant %p, name %s stub.\n", iface
, constant
, debugstr_a(name
));
2680 static D3DXHANDLE WINAPI
d3dx9_texture_shader_GetConstantElement(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, UINT index
)
2682 FIXME("iface %p, constant %p, index %u stub.\n", iface
, constant
, index
);
2687 static HRESULT WINAPI
d3dx9_texture_shader_SetDefaults(ID3DXTextureShader
*iface
)
2689 FIXME("iface %p stub.\n", iface
);
2694 static HRESULT WINAPI
d3dx9_texture_shader_SetValue(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const void *data
, UINT bytes
)
2696 FIXME("iface %p, constant %p, data %p, bytes %u stub.\n", iface
, constant
, data
, bytes
);
2701 static HRESULT WINAPI
d3dx9_texture_shader_SetBool(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, BOOL b
)
2703 FIXME("iface %p, constant %p, b %u stub.\n", iface
, constant
, b
);
2708 static HRESULT WINAPI
d3dx9_texture_shader_SetBoolArray(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const BOOL
*b
, UINT count
)
2710 FIXME("iface %p, constant %p, b %p, count %u stub.\n", iface
, constant
, b
, count
);
2715 static HRESULT WINAPI
d3dx9_texture_shader_SetInt(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, INT n
)
2717 FIXME("iface %p, constant %p, n %d stub.\n", iface
, constant
, n
);
2722 static HRESULT WINAPI
d3dx9_texture_shader_SetIntArray(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const INT
*n
, UINT count
)
2724 FIXME("iface %p, constant %p, n %p, count %u stub.\n", iface
, constant
, n
, count
);
2729 static HRESULT WINAPI
d3dx9_texture_shader_SetFloat(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, FLOAT f
)
2731 FIXME("iface %p, constant %p, f %f stub.\n", iface
, constant
, f
);
2736 static HRESULT WINAPI
d3dx9_texture_shader_SetFloatArray(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const FLOAT
*f
, UINT count
)
2738 FIXME("iface %p, constant %p, f %p, count %u stub.\n", iface
, constant
, f
, count
);
2743 static HRESULT WINAPI
d3dx9_texture_shader_SetVector(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const D3DXVECTOR4
*vector
)
2745 FIXME("iface %p, constant %p, vector %p stub.\n", iface
, constant
, vector
);
2750 static HRESULT WINAPI
d3dx9_texture_shader_SetVectorArray(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const D3DXVECTOR4
*vector
, UINT count
)
2752 FIXME("iface %p, constant %p, vector %p, count %u stub.\n", iface
, constant
, vector
, count
);
2757 static HRESULT WINAPI
d3dx9_texture_shader_SetMatrix(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const D3DXMATRIX
*matrix
)
2759 FIXME("iface %p, constant %p, matrix %p stub.\n", iface
, constant
, matrix
);
2764 static HRESULT WINAPI
d3dx9_texture_shader_SetMatrixArray(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const D3DXMATRIX
*matrix
, UINT count
)
2766 FIXME("iface %p, constant %p, matrix %p, count %u stub.\n", iface
, constant
, matrix
, count
);
2771 static HRESULT WINAPI
d3dx9_texture_shader_SetMatrixPointerArray(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const D3DXMATRIX
**matrix
, UINT count
)
2773 FIXME("iface %p, constant %p, matrix %p, count %u stub.\n", iface
, constant
, matrix
, count
);
2778 static HRESULT WINAPI
d3dx9_texture_shader_SetMatrixTranspose(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const D3DXMATRIX
*matrix
)
2780 FIXME("iface %p, constant %p, matrix %p stub.\n", iface
, constant
, matrix
);
2785 static HRESULT WINAPI
d3dx9_texture_shader_SetMatrixTransposeArray(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const D3DXMATRIX
*matrix
, UINT count
)
2787 FIXME("iface %p, constant %p, matrix %p, count %u stub.\n", iface
, constant
, matrix
, count
);
2792 static HRESULT WINAPI
d3dx9_texture_shader_SetMatrixTransposePointerArray(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const D3DXMATRIX
**matrix
, UINT count
)
2794 FIXME("iface %p, constant %p, matrix %p, count %u stub.\n", iface
, constant
, matrix
, count
);
2799 static const struct ID3DXTextureShaderVtbl d3dx9_texture_shader_vtbl
=
2801 /*** IUnknown methods ***/
2802 d3dx9_texture_shader_QueryInterface
,
2803 d3dx9_texture_shader_AddRef
,
2804 d3dx9_texture_shader_Release
,
2805 /*** ID3DXTextureShader methods ***/
2806 d3dx9_texture_shader_GetFunction
,
2807 d3dx9_texture_shader_GetConstantBuffer
,
2808 d3dx9_texture_shader_GetDesc
,
2809 d3dx9_texture_shader_GetConstantDesc
,
2810 d3dx9_texture_shader_GetConstant
,
2811 d3dx9_texture_shader_GetConstantByName
,
2812 d3dx9_texture_shader_GetConstantElement
,
2813 d3dx9_texture_shader_SetDefaults
,
2814 d3dx9_texture_shader_SetValue
,
2815 d3dx9_texture_shader_SetBool
,
2816 d3dx9_texture_shader_SetBoolArray
,
2817 d3dx9_texture_shader_SetInt
,
2818 d3dx9_texture_shader_SetIntArray
,
2819 d3dx9_texture_shader_SetFloat
,
2820 d3dx9_texture_shader_SetFloatArray
,
2821 d3dx9_texture_shader_SetVector
,
2822 d3dx9_texture_shader_SetVectorArray
,
2823 d3dx9_texture_shader_SetMatrix
,
2824 d3dx9_texture_shader_SetMatrixArray
,
2825 d3dx9_texture_shader_SetMatrixPointerArray
,
2826 d3dx9_texture_shader_SetMatrixTranspose
,
2827 d3dx9_texture_shader_SetMatrixTransposeArray
,
2828 d3dx9_texture_shader_SetMatrixTransposePointerArray
2831 HRESULT WINAPI
D3DXCreateTextureShader(const DWORD
*function
, ID3DXTextureShader
**texture_shader
)
2833 struct d3dx9_texture_shader
*object
;
2835 TRACE("function %p, texture_shader %p.\n", function
, texture_shader
);
2837 if (!function
|| !texture_shader
)
2838 return D3DERR_INVALIDCALL
;
2840 object
= HeapAlloc(GetProcessHeap(), 0, sizeof(*object
));
2842 return E_OUTOFMEMORY
;
2844 object
->ID3DXTextureShader_iface
.lpVtbl
= &d3dx9_texture_shader_vtbl
;
2847 *texture_shader
= &object
->ID3DXTextureShader_iface
;
2852 HRESULT WINAPI
D3DXFillCubeTextureTX(IDirect3DCubeTexture9
*texture
, ID3DXTextureShader
*texture_shader
)
2854 FIXME("texture %p, texture_shader %p stub.\n", texture
, texture_shader
);
2856 if (!texture
|| !texture_shader
)