2 * Copyright 2008 Luis Busquets
3 * Copyright 2009 Matteo Bruni
4 * Copyright 2011 Travis Athougies
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include "wine/port.h"
24 #include "d3dx9_private.h"
25 #include "d3dcommon.h"
26 #include "d3dcompiler.h"
28 WINE_DEFAULT_DEBUG_CHANNEL(d3dx
);
30 /* This function is not declared in the SDK headers yet. */
31 HRESULT WINAPI
D3DAssemble(const void *data
, SIZE_T datasize
, const char *filename
,
32 const D3D_SHADER_MACRO
*defines
, ID3DInclude
*include
, UINT flags
,
33 ID3DBlob
**shader
, ID3DBlob
**error_messages
);
35 static inline BOOL
is_valid_bytecode(DWORD token
)
37 return (token
& 0xfffe0000) == 0xfffe0000;
40 const char * WINAPI
D3DXGetPixelShaderProfile(struct IDirect3DDevice9
*device
)
44 TRACE("device %p\n", device
);
46 if (!device
) return NULL
;
48 IDirect3DDevice9_GetDeviceCaps(device
,&caps
);
50 switch (caps
.PixelShaderVersion
)
52 case D3DPS_VERSION(1, 1):
55 case D3DPS_VERSION(1, 2):
58 case D3DPS_VERSION(1, 3):
61 case D3DPS_VERSION(1, 4):
64 case D3DPS_VERSION(2, 0):
65 if ((caps
.PS20Caps
.NumTemps
>=22) &&
66 (caps
.PS20Caps
.Caps
&D3DPS20CAPS_ARBITRARYSWIZZLE
) &&
67 (caps
.PS20Caps
.Caps
&D3DPS20CAPS_GRADIENTINSTRUCTIONS
) &&
68 (caps
.PS20Caps
.Caps
&D3DPS20CAPS_PREDICATION
) &&
69 (caps
.PS20Caps
.Caps
&D3DPS20CAPS_NODEPENDENTREADLIMIT
) &&
70 (caps
.PS20Caps
.Caps
&D3DPS20CAPS_NOTEXINSTRUCTIONLIMIT
))
74 if ((caps
.PS20Caps
.NumTemps
>=32) &&
75 (caps
.PS20Caps
.Caps
&D3DPS20CAPS_NOTEXINSTRUCTIONLIMIT
))
81 case D3DPS_VERSION(3, 0):
88 UINT WINAPI
D3DXGetShaderSize(const DWORD
*byte_code
)
90 const DWORD
*ptr
= byte_code
;
92 TRACE("byte_code %p\n", byte_code
);
96 /* Look for the END token, skipping the VERSION token */
97 while (*++ptr
!= D3DSIO_END
)
100 if ((*ptr
& D3DSI_OPCODE_MASK
) == D3DSIO_COMMENT
)
102 ptr
+= ((*ptr
& D3DSI_COMMENTSIZE_MASK
) >> D3DSI_COMMENTSIZE_SHIFT
);
107 /* Return the shader size in bytes */
108 return (ptr
- byte_code
) * sizeof(*ptr
);
111 DWORD WINAPI
D3DXGetShaderVersion(const DWORD
*byte_code
)
113 TRACE("byte_code %p\n", byte_code
);
115 return byte_code
? *byte_code
: 0;
118 const char * WINAPI
D3DXGetVertexShaderProfile(struct IDirect3DDevice9
*device
)
122 TRACE("device %p\n", device
);
124 if (!device
) return NULL
;
126 IDirect3DDevice9_GetDeviceCaps(device
,&caps
);
128 switch (caps
.VertexShaderVersion
)
130 case D3DVS_VERSION(1, 1):
132 case D3DVS_VERSION(2, 0):
133 if ((caps
.VS20Caps
.NumTemps
>=13) &&
134 (caps
.VS20Caps
.DynamicFlowControlDepth
==24) &&
135 (caps
.VS20Caps
.Caps
&D3DPS20CAPS_PREDICATION
))
140 case D3DVS_VERSION(3, 0):
147 HRESULT WINAPI
D3DXFindShaderComment(const DWORD
*byte_code
, DWORD fourcc
, const void **data
, UINT
*size
)
149 const DWORD
*ptr
= byte_code
;
152 TRACE("byte_code %p, fourcc %x, data %p, size %p\n", byte_code
, fourcc
, data
, size
);
154 if (data
) *data
= NULL
;
157 if (!byte_code
) return D3DERR_INVALIDCALL
;
159 version
= *ptr
>> 16;
160 if (version
!= 0x4658 /* FX */
161 && version
!= 0x5458 /* TX */
164 && version
!= 0xfffe /* VS */
165 && version
!= 0xffff) /* PS */
167 WARN("Invalid data supplied\n");
168 return D3DXERR_INVALIDDATA
;
171 while (*++ptr
!= D3DSIO_END
)
173 /* Check if it is a comment */
174 if ((*ptr
& D3DSI_OPCODE_MASK
) == D3DSIO_COMMENT
)
176 DWORD comment_size
= (*ptr
& D3DSI_COMMENTSIZE_MASK
) >> D3DSI_COMMENTSIZE_SHIFT
;
178 /* Check if this is the comment we are looking for */
179 if (*(ptr
+ 1) == fourcc
)
181 UINT ctab_size
= (comment_size
- 1) * sizeof(DWORD
);
182 const void *ctab_data
= ptr
+ 2;
187 TRACE("Returning comment data at %p with size %d\n", ctab_data
, ctab_size
);
197 HRESULT WINAPI
D3DXAssembleShader(const char *data
, UINT data_len
, const D3DXMACRO
*defines
,
198 ID3DXInclude
*include
, DWORD flags
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
202 TRACE("data %p, data_len %u, defines %p, include %p, flags %#x, shader %p, error_messages %p\n",
203 data
, data_len
, defines
, include
, flags
, shader
, error_messages
);
205 /* Forward to d3dcompiler: the parameter types aren't really different,
206 the actual data types are equivalent */
207 hr
= D3DAssemble(data
, data_len
, NULL
, (D3D_SHADER_MACRO
*)defines
,
208 (ID3DInclude
*)include
, flags
, (ID3DBlob
**)shader
,
209 (ID3DBlob
**)error_messages
);
211 if(hr
== E_FAIL
) hr
= D3DXERR_INVALIDDATA
;
215 static const void *main_file_data
;
217 static CRITICAL_SECTION_DEBUG from_file_mutex_debug
=
219 0, 0, &from_file_mutex
,
221 &from_file_mutex_debug
.ProcessLocksList
,
222 &from_file_mutex_debug
.ProcessLocksList
224 0, 0, {(DWORD_PTR
)(__FILE__
": from_file_mutex")}
226 CRITICAL_SECTION from_file_mutex
= {&from_file_mutex_debug
, -1, 0, 0, 0, 0};
228 /* D3DXInclude private implementation, used to implement
229 * D3DXAssembleShaderFromFile() from D3DXAssembleShader(). */
230 /* To be able to correctly resolve include search paths we have to store the
231 * pathname of each include file. We store the pathname pointer right before
233 static HRESULT WINAPI
d3dx_include_from_file_open(ID3DXInclude
*iface
, D3DXINCLUDE_TYPE include_type
,
234 const char *filename
, const void *parent_data
, const void **data
, UINT
*bytes
)
236 const char *p
, *parent_name
= "";
237 char *pathname
= NULL
, *ptr
;
238 char **buffer
= NULL
;
244 parent_name
= *((const char **)parent_data
- 1);
249 parent_name
= *((const char **)main_file_data
- 1);
252 TRACE("Looking up include file %s, parent %s.\n", debugstr_a(filename
), debugstr_a(parent_name
));
254 if ((p
= strrchr(parent_name
, '\\')))
258 pathname
= HeapAlloc(GetProcessHeap(), 0, (p
- parent_name
) + strlen(filename
) + 1);
260 return HRESULT_FROM_WIN32(GetLastError());
262 memcpy(pathname
, parent_name
, p
- parent_name
);
263 strcpy(pathname
+ (p
- parent_name
), filename
);
264 ptr
= pathname
+ (p
- parent_name
);
272 file
= CreateFileA(pathname
, GENERIC_READ
, FILE_SHARE_READ
, 0, OPEN_EXISTING
, 0, 0);
273 if(file
== INVALID_HANDLE_VALUE
)
276 TRACE("Include file found at pathname = %s\n", debugstr_a(pathname
));
278 size
= GetFileSize(file
, NULL
);
279 if(size
== INVALID_FILE_SIZE
)
282 buffer
= HeapAlloc(GetProcessHeap(), 0, size
+ sizeof(char *));
286 if(!ReadFile(file
, buffer
+ 1, size
, bytes
, NULL
))
291 main_file_data
= *data
;
298 HeapFree(GetProcessHeap(), 0, pathname
);
299 HeapFree(GetProcessHeap(), 0, buffer
);
300 return HRESULT_FROM_WIN32(GetLastError());
303 static HRESULT WINAPI
d3dx_include_from_file_close(ID3DXInclude
*iface
, const void *data
)
305 HeapFree(GetProcessHeap(), 0, *((char **)data
- 1));
306 HeapFree(GetProcessHeap(), 0, (char **)data
- 1);
307 if (main_file_data
== data
)
308 main_file_data
= NULL
;
312 const struct ID3DXIncludeVtbl d3dx_include_from_file_vtbl
=
314 d3dx_include_from_file_open
,
315 d3dx_include_from_file_close
318 HRESULT WINAPI
D3DXAssembleShaderFromFileA(const char *filename
, const D3DXMACRO
*defines
,
319 ID3DXInclude
*include
, DWORD flags
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
325 TRACE("filename %s, defines %p, include %p, flags %#x, shader %p, error_messages %p.\n",
326 debugstr_a(filename
), defines
, include
, flags
, shader
, error_messages
);
328 if (!filename
) return D3DXERR_INVALIDDATA
;
330 len
= MultiByteToWideChar(CP_ACP
, 0, filename
, -1, NULL
, 0);
331 filename_w
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
332 if (!filename_w
) return E_OUTOFMEMORY
;
333 MultiByteToWideChar(CP_ACP
, 0, filename
, -1, filename_w
, len
);
335 ret
= D3DXAssembleShaderFromFileW(filename_w
, defines
, include
, flags
, shader
, error_messages
);
337 HeapFree(GetProcessHeap(), 0, filename_w
);
341 HRESULT WINAPI
D3DXAssembleShaderFromFileW(const WCHAR
*filename
, const D3DXMACRO
*defines
,
342 ID3DXInclude
*include
, DWORD flags
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
347 struct d3dx_include_from_file include_from_file
;
350 TRACE("filename %s, defines %p, include %p, flags %#x, shader %p, error_messages %p.\n",
351 debugstr_w(filename
), defines
, include
, flags
, shader
, error_messages
);
355 include_from_file
.ID3DXInclude_iface
.lpVtbl
= &d3dx_include_from_file_vtbl
;
356 include
= &include_from_file
.ID3DXInclude_iface
;
359 len
= WideCharToMultiByte(CP_ACP
, 0, filename
, -1, NULL
, 0, NULL
, NULL
);
360 filename_a
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(char));
362 return E_OUTOFMEMORY
;
363 WideCharToMultiByte(CP_ACP
, 0, filename
, -1, filename_a
, len
, NULL
, NULL
);
365 EnterCriticalSection(&from_file_mutex
);
366 hr
= ID3DXInclude_Open(include
, D3DXINC_LOCAL
, filename_a
, NULL
, &buffer
, &len
);
369 LeaveCriticalSection(&from_file_mutex
);
370 HeapFree(GetProcessHeap(), 0, filename_a
);
371 return D3DXERR_INVALIDDATA
;
374 hr
= D3DXAssembleShader(buffer
, len
, defines
, include
, flags
, shader
, error_messages
);
376 ID3DXInclude_Close(include
, buffer
);
377 LeaveCriticalSection(&from_file_mutex
);
378 HeapFree(GetProcessHeap(), 0, filename_a
);
382 HRESULT WINAPI
D3DXAssembleShaderFromResourceA(HMODULE module
, const char *resource
, const D3DXMACRO
*defines
,
383 ID3DXInclude
*include
, DWORD flags
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
389 TRACE("module %p, resource %s, defines %p, include %p, flags %#x, shader %p, error_messages %p.\n",
390 module
, debugstr_a(resource
), defines
, include
, flags
, shader
, error_messages
);
392 if (!(res
= FindResourceA(module
, resource
, (const char *)RT_RCDATA
)))
393 return D3DXERR_INVALIDDATA
;
394 if (FAILED(load_resource_into_memory(module
, res
, &buffer
, &len
)))
395 return D3DXERR_INVALIDDATA
;
396 return D3DXAssembleShader(buffer
, len
, defines
, include
, flags
,
397 shader
, error_messages
);
400 HRESULT WINAPI
D3DXAssembleShaderFromResourceW(HMODULE module
, const WCHAR
*resource
, const D3DXMACRO
*defines
,
401 ID3DXInclude
*include
, DWORD flags
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
407 TRACE("module %p, resource %s, defines %p, include %p, flags %#x, shader %p, error_messages %p.\n",
408 module
, debugstr_w(resource
), defines
, include
, flags
, shader
, error_messages
);
410 if (!(res
= FindResourceW(module
, resource
, (const WCHAR
*)RT_RCDATA
)))
411 return D3DXERR_INVALIDDATA
;
412 if (FAILED(load_resource_into_memory(module
, res
, &buffer
, &len
)))
413 return D3DXERR_INVALIDDATA
;
414 return D3DXAssembleShader(buffer
, len
, defines
, include
, flags
,
415 shader
, error_messages
);
418 HRESULT WINAPI
D3DXCompileShader(const char *data
, UINT length
, const D3DXMACRO
*defines
,
419 ID3DXInclude
*include
, const char *function
, const char *profile
, DWORD flags
,
420 ID3DXBuffer
**shader
, ID3DXBuffer
**error_msgs
, ID3DXConstantTable
**constant_table
)
424 TRACE("data %s, length %u, defines %p, include %p, function %s, profile %s, "
425 "flags %#x, shader %p, error_msgs %p, constant_table %p.\n",
426 debugstr_a(data
), length
, defines
, include
, debugstr_a(function
), debugstr_a(profile
),
427 flags
, shader
, error_msgs
, constant_table
);
429 hr
= D3DCompile(data
, length
, NULL
, (D3D_SHADER_MACRO
*)defines
, (ID3DInclude
*)include
,
430 function
, profile
, flags
, 0, (ID3DBlob
**)shader
, (ID3DBlob
**)error_msgs
);
432 if (SUCCEEDED(hr
) && constant_table
)
434 hr
= D3DXGetShaderConstantTable(ID3DXBuffer_GetBufferPointer(*shader
), constant_table
);
437 ID3DXBuffer_Release(*shader
);
445 HRESULT WINAPI
D3DXCompileShaderFromFileA(const char *filename
, const D3DXMACRO
*defines
,
446 ID3DXInclude
*include
, const char *entrypoint
, const char *profile
, DWORD flags
,
447 ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
, ID3DXConstantTable
**constant_table
)
453 TRACE("filename %s, defines %p, include %p, entrypoint %s, profile %s, "
454 "flags %#x, shader %p, error_messages %p, constant_table %p.\n",
455 debugstr_a(filename
), defines
, include
, debugstr_a(entrypoint
),
456 debugstr_a(profile
), flags
, shader
, error_messages
, constant_table
);
458 if (!filename
) return D3DXERR_INVALIDDATA
;
460 len
= MultiByteToWideChar(CP_ACP
, 0, filename
, -1, NULL
, 0);
461 filename_w
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
462 if (!filename_w
) return E_OUTOFMEMORY
;
463 MultiByteToWideChar(CP_ACP
, 0, filename
, -1, filename_w
, len
);
465 ret
= D3DXCompileShaderFromFileW(filename_w
, defines
, include
,
466 entrypoint
, profile
, flags
,
467 shader
, error_messages
, constant_table
);
469 HeapFree(GetProcessHeap(), 0, filename_w
);
473 HRESULT WINAPI
D3DXCompileShaderFromFileW(const WCHAR
*filename
, const D3DXMACRO
*defines
,
474 ID3DXInclude
*include
, const char *entrypoint
, const char *profile
, DWORD flags
,
475 ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
, ID3DXConstantTable
**constant_table
)
478 DWORD len
, filename_len
;
480 struct d3dx_include_from_file include_from_file
;
483 TRACE("filename %s, defines %p, include %p, entrypoint %s, profile %s, "
484 "flags %#x, shader %p, error_messages %p, constant_table %p.\n",
485 debugstr_w(filename
), defines
, include
, debugstr_a(entrypoint
), debugstr_a(profile
),
486 flags
, shader
, error_messages
, constant_table
);
490 include_from_file
.ID3DXInclude_iface
.lpVtbl
= &d3dx_include_from_file_vtbl
;
491 include
= &include_from_file
.ID3DXInclude_iface
;
494 filename_len
= WideCharToMultiByte(CP_ACP
, 0, filename
, -1, NULL
, 0, NULL
, NULL
);
495 filename_a
= HeapAlloc(GetProcessHeap(), 0, filename_len
* sizeof(char));
497 return E_OUTOFMEMORY
;
498 WideCharToMultiByte(CP_ACP
, 0, filename
, -1, filename_a
, filename_len
, NULL
, NULL
);
500 EnterCriticalSection(&from_file_mutex
);
501 hr
= ID3DXInclude_Open(include
, D3DXINC_LOCAL
, filename_a
, NULL
, &buffer
, &len
);
504 LeaveCriticalSection(&from_file_mutex
);
505 HeapFree(GetProcessHeap(), 0, filename_a
);
506 return D3DXERR_INVALIDDATA
;
509 hr
= D3DCompile(buffer
, len
, filename_a
, (const D3D_SHADER_MACRO
*)defines
,
510 (ID3DInclude
*)include
, entrypoint
, profile
, flags
, 0,
511 (ID3DBlob
**)shader
, (ID3DBlob
**)error_messages
);
513 if (SUCCEEDED(hr
) && constant_table
)
514 hr
= D3DXGetShaderConstantTable(ID3DXBuffer_GetBufferPointer(*shader
),
517 ID3DXInclude_Close(include
, buffer
);
518 LeaveCriticalSection(&from_file_mutex
);
519 HeapFree(GetProcessHeap(), 0, filename_a
);
523 HRESULT WINAPI
D3DXCompileShaderFromResourceA(HMODULE module
, const char *resource
, const D3DXMACRO
*defines
,
524 ID3DXInclude
*include
, const char *entrypoint
, const char *profile
, DWORD flags
,
525 ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
, ID3DXConstantTable
**constant_table
)
531 TRACE("module %p, resource %s, defines %p, include %p, entrypoint %s, profile %s, "
532 "flags %#x, shader %p, error_messages %p, constant_table %p.\n",
533 module
, debugstr_a(resource
), defines
, include
, debugstr_a(entrypoint
), debugstr_a(profile
),
534 flags
, shader
, error_messages
, constant_table
);
536 if (!(res
= FindResourceA(module
, resource
, (const char *)RT_RCDATA
)))
537 return D3DXERR_INVALIDDATA
;
538 if (FAILED(load_resource_into_memory(module
, res
, &buffer
, &len
)))
539 return D3DXERR_INVALIDDATA
;
540 return D3DXCompileShader(buffer
, len
, defines
, include
, entrypoint
, profile
,
541 flags
, shader
, error_messages
, constant_table
);
544 HRESULT WINAPI
D3DXCompileShaderFromResourceW(HMODULE module
, const WCHAR
*resource
, const D3DXMACRO
*defines
,
545 ID3DXInclude
*include
, const char *entrypoint
, const char *profile
, DWORD flags
,
546 ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
, ID3DXConstantTable
**constant_table
)
552 TRACE("module %p, resource %s, defines %p, include %p, entrypoint %s, profile %s, "
553 "flags %#x, shader %p, error_messages %p, constant_table %p.\n",
554 module
, debugstr_w(resource
), defines
, include
, debugstr_a(entrypoint
), debugstr_a(profile
),
555 flags
, shader
, error_messages
, constant_table
);
557 if (!(res
= FindResourceW(module
, resource
, (const WCHAR
*)RT_RCDATA
)))
558 return D3DXERR_INVALIDDATA
;
559 if (FAILED(load_resource_into_memory(module
, res
, &buffer
, &len
)))
560 return D3DXERR_INVALIDDATA
;
561 return D3DXCompileShader(buffer
, len
, defines
, include
, entrypoint
, profile
,
562 flags
, shader
, error_messages
, constant_table
);
565 HRESULT WINAPI
D3DXPreprocessShader(const char *data
, UINT data_len
, const D3DXMACRO
*defines
,
566 ID3DXInclude
*include
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
568 TRACE("data %s, data_len %u, defines %p, include %p, shader %p, error_messages %p.\n",
569 debugstr_a(data
), data_len
, defines
, include
, shader
, error_messages
);
571 return D3DPreprocess(data
, data_len
, NULL
,
572 (const D3D_SHADER_MACRO
*)defines
, (ID3DInclude
*)include
,
573 (ID3DBlob
**)shader
, (ID3DBlob
**)error_messages
);
576 HRESULT WINAPI
D3DXPreprocessShaderFromFileA(const char *filename
, const D3DXMACRO
*defines
,
577 ID3DXInclude
*include
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
579 WCHAR
*filename_w
= NULL
;
583 TRACE("filename %s, defines %p, include %p, shader %p, error_messages %p.\n",
584 debugstr_a(filename
), defines
, include
, shader
, error_messages
);
586 if (!filename
) return D3DXERR_INVALIDDATA
;
588 len
= MultiByteToWideChar(CP_ACP
, 0, filename
, -1, NULL
, 0);
589 filename_w
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
590 if (!filename_w
) return E_OUTOFMEMORY
;
591 MultiByteToWideChar(CP_ACP
, 0, filename
, -1, filename_w
, len
);
593 ret
= D3DXPreprocessShaderFromFileW(filename_w
, defines
, include
, shader
, error_messages
);
595 HeapFree(GetProcessHeap(), 0, filename_w
);
599 HRESULT WINAPI
D3DXPreprocessShaderFromFileW(const WCHAR
*filename
, const D3DXMACRO
*defines
,
600 ID3DXInclude
*include
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
605 struct d3dx_include_from_file include_from_file
;
608 TRACE("filename %s, defines %p, include %p, shader %p, error_messages %p.\n",
609 debugstr_w(filename
), defines
, include
, shader
, error_messages
);
613 include_from_file
.ID3DXInclude_iface
.lpVtbl
= &d3dx_include_from_file_vtbl
;
614 include
= &include_from_file
.ID3DXInclude_iface
;
617 len
= WideCharToMultiByte(CP_ACP
, 0, filename
, -1, NULL
, 0, NULL
, NULL
);
618 filename_a
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(char));
620 return E_OUTOFMEMORY
;
621 WideCharToMultiByte(CP_ACP
, 0, filename
, -1, filename_a
, len
, NULL
, NULL
);
623 EnterCriticalSection(&from_file_mutex
);
624 hr
= ID3DXInclude_Open(include
, D3DXINC_LOCAL
, filename_a
, NULL
, &buffer
, &len
);
627 LeaveCriticalSection(&from_file_mutex
);
628 HeapFree(GetProcessHeap(), 0, filename_a
);
629 return D3DXERR_INVALIDDATA
;
632 hr
= D3DPreprocess(buffer
, len
, NULL
,
633 (const D3D_SHADER_MACRO
*)defines
,
634 (ID3DInclude
*) include
,
635 (ID3DBlob
**)shader
, (ID3DBlob
**)error_messages
);
637 ID3DXInclude_Close(include
, buffer
);
638 LeaveCriticalSection(&from_file_mutex
);
639 HeapFree(GetProcessHeap(), 0, filename_a
);
643 HRESULT WINAPI
D3DXPreprocessShaderFromResourceA(HMODULE module
, const char *resource
, const D3DXMACRO
*defines
,
644 ID3DXInclude
*include
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
650 TRACE("module %p, resource %s, defines %p, include %p, shader %p, error_messages %p.\n",
651 module
, debugstr_a(resource
), defines
, include
, shader
, error_messages
);
653 if (!(res
= FindResourceA(module
, resource
, (const char *)RT_RCDATA
)))
654 return D3DXERR_INVALIDDATA
;
655 if (FAILED(load_resource_into_memory(module
, res
, &buffer
, &len
)))
656 return D3DXERR_INVALIDDATA
;
657 return D3DXPreprocessShader(buffer
, len
, defines
, include
,
658 shader
, error_messages
);
661 HRESULT WINAPI
D3DXPreprocessShaderFromResourceW(HMODULE module
, const WCHAR
*resource
, const D3DXMACRO
*defines
,
662 ID3DXInclude
*include
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
668 TRACE("module %p, resource %s, defines %p, include %p, shader %p, error_messages %p.\n",
669 module
, debugstr_w(resource
), defines
, include
, shader
, error_messages
);
671 if (!(res
= FindResourceW(module
, resource
, (const WCHAR
*)RT_RCDATA
)))
672 return D3DXERR_INVALIDDATA
;
673 if (FAILED(load_resource_into_memory(module
, res
, &buffer
, &len
)))
674 return D3DXERR_INVALIDDATA
;
675 return D3DXPreprocessShader(buffer
, len
, defines
, include
,
676 shader
, error_messages
);
680 struct ID3DXConstantTableImpl
{
681 ID3DXConstantTable ID3DXConstantTable_iface
;
685 D3DXCONSTANTTABLE_DESC desc
;
686 struct ctab_constant
*constants
;
689 static void free_constant(struct ctab_constant
*constant
)
691 if (constant
->constants
)
693 UINT i
, count
= constant
->desc
.Elements
> 1 ? constant
->desc
.Elements
: constant
->desc
.StructMembers
;
695 for (i
= 0; i
< count
; ++i
)
697 free_constant(&constant
->constants
[i
]);
699 HeapFree(GetProcessHeap(), 0, constant
->constants
);
703 static void free_constant_table(struct ID3DXConstantTableImpl
*table
)
705 if (table
->constants
)
709 for (i
= 0; i
< table
->desc
.Constants
; ++i
)
711 free_constant(&table
->constants
[i
]);
713 HeapFree(GetProcessHeap(), 0, table
->constants
);
715 HeapFree(GetProcessHeap(), 0, table
->ctab
);
718 static inline struct ID3DXConstantTableImpl
*impl_from_ID3DXConstantTable(ID3DXConstantTable
*iface
)
720 return CONTAINING_RECORD(iface
, struct ID3DXConstantTableImpl
, ID3DXConstantTable_iface
);
723 static inline BOOL
is_vertex_shader(DWORD version
)
725 return (version
& 0xffff0000) == 0xfffe0000;
728 static inline D3DXHANDLE
handle_from_constant(struct ctab_constant
*constant
)
730 return (D3DXHANDLE
)constant
;
733 static struct ctab_constant
*get_constant_by_name(struct ID3DXConstantTableImpl
*table
,
734 struct ctab_constant
*constant
, const char *name
);
736 static struct ctab_constant
*get_constant_element_by_name(struct ctab_constant
*constant
, const char *name
)
741 TRACE("constant %p, name %s\n", constant
, debugstr_a(name
));
743 if (!name
|| !*name
) return NULL
;
745 element
= atoi(name
);
746 part
= strchr(name
, ']') + 1;
748 if (constant
->desc
.Elements
> element
)
750 struct ctab_constant
*c
= constant
->constants
? &constant
->constants
[element
] : constant
;
755 return get_constant_by_name(NULL
, c
, part
);
758 return get_constant_element_by_name(c
, part
);
761 TRACE("Returning parameter %p\n", c
);
765 FIXME("Unhandled case \"%c\"\n", *--part
);
770 TRACE("Constant not found\n");
774 static struct ctab_constant
*get_constant_by_name(struct ID3DXConstantTableImpl
*table
,
775 struct ctab_constant
*constant
, const char *name
)
777 UINT i
, count
, length
;
778 struct ctab_constant
*handles
;
781 TRACE("table %p, constant %p, name %s\n", table
, constant
, debugstr_a(name
));
783 if (!name
|| !*name
) return NULL
;
787 count
= table
->desc
.Constants
;
788 handles
= table
->constants
;
792 count
= constant
->desc
.StructMembers
;
793 handles
= constant
->constants
;
796 length
= strcspn(name
, "[.");
797 part
= name
+ length
;
799 for (i
= 0; i
< count
; i
++)
801 if (strlen(handles
[i
].desc
.Name
) == length
&& !strncmp(handles
[i
].desc
.Name
, name
, length
))
806 return get_constant_by_name(NULL
, &handles
[i
], part
);
809 return get_constant_element_by_name(&handles
[i
], part
);
812 TRACE("Returning parameter %p\n", &handles
[i
]);
818 TRACE("Constant not found\n");
822 static struct ctab_constant
*is_valid_sub_constant(struct ctab_constant
*parent
, D3DXHANDLE handle
)
824 struct ctab_constant
*c
;
827 /* all variable have at least elements = 1, but not always elements */
828 if (!parent
->constants
) return NULL
;
830 count
= parent
->desc
.Elements
> 1 ? parent
->desc
.Elements
: parent
->desc
.StructMembers
;
831 for (i
= 0; i
< count
; ++i
)
833 if (handle_from_constant(&parent
->constants
[i
]) == handle
)
834 return &parent
->constants
[i
];
836 c
= is_valid_sub_constant(&parent
->constants
[i
], handle
);
843 static inline struct ctab_constant
*get_valid_constant(struct ID3DXConstantTableImpl
*table
, D3DXHANDLE handle
)
845 struct ctab_constant
*c
;
848 if (!handle
) return NULL
;
850 for (i
= 0; i
< table
->desc
.Constants
; ++i
)
852 if (handle_from_constant(&table
->constants
[i
]) == handle
)
853 return &table
->constants
[i
];
855 c
= is_valid_sub_constant(&table
->constants
[i
], handle
);
859 return get_constant_by_name(table
, NULL
, handle
);
862 /*** IUnknown methods ***/
863 static HRESULT WINAPI
ID3DXConstantTableImpl_QueryInterface(ID3DXConstantTable
*iface
, REFIID riid
, void **out
)
865 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
867 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
868 IsEqualGUID(riid
, &IID_ID3DXBuffer
) ||
869 IsEqualGUID(riid
, &IID_ID3DXConstantTable
))
871 ID3DXConstantTable_AddRef(iface
);
876 WARN("Interface %s not found.\n", debugstr_guid(riid
));
878 return E_NOINTERFACE
;
881 static ULONG WINAPI
ID3DXConstantTableImpl_AddRef(ID3DXConstantTable
*iface
)
883 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
885 TRACE("(%p)->(): AddRef from %d\n", This
, This
->ref
);
887 return InterlockedIncrement(&This
->ref
);
890 static ULONG WINAPI
ID3DXConstantTableImpl_Release(ID3DXConstantTable
*iface
)
892 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
893 ULONG ref
= InterlockedDecrement(&This
->ref
);
895 TRACE("(%p)->(): Release from %d\n", This
, ref
+ 1);
899 free_constant_table(This
);
900 HeapFree(GetProcessHeap(), 0, This
);
906 /*** ID3DXBuffer methods ***/
907 static void * WINAPI
ID3DXConstantTableImpl_GetBufferPointer(ID3DXConstantTable
*iface
)
909 struct ID3DXConstantTableImpl
*table
= impl_from_ID3DXConstantTable(iface
);
911 TRACE("iface %p.\n", iface
);
916 static DWORD WINAPI
ID3DXConstantTableImpl_GetBufferSize(ID3DXConstantTable
*iface
)
918 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
920 TRACE("(%p)->()\n", This
);
925 /*** ID3DXConstantTable methods ***/
926 static HRESULT WINAPI
ID3DXConstantTableImpl_GetDesc(ID3DXConstantTable
*iface
, D3DXCONSTANTTABLE_DESC
*desc
)
928 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
930 TRACE("(%p)->(%p)\n", This
, desc
);
933 return D3DERR_INVALIDCALL
;
940 const struct ctab_constant
*d3dx_shader_get_ctab_constant(ID3DXConstantTable
*iface
, D3DXHANDLE constant
)
942 struct ID3DXConstantTableImpl
*ctab
= impl_from_ID3DXConstantTable(iface
);
944 return get_valid_constant(ctab
, constant
);
947 static HRESULT WINAPI
ID3DXConstantTableImpl_GetConstantDesc(ID3DXConstantTable
*iface
, D3DXHANDLE constant
,
948 D3DXCONSTANT_DESC
*desc
, UINT
*count
)
950 struct ID3DXConstantTableImpl
*ctab
= impl_from_ID3DXConstantTable(iface
);
951 struct ctab_constant
*c
= get_valid_constant(ctab
, constant
);
953 TRACE("(%p)->(%p, %p, %p)\n", ctab
, constant
, desc
, count
);
957 WARN("Invalid argument specified\n");
958 return D3DERR_INVALIDCALL
;
961 if (desc
) *desc
= c
->desc
;
962 if (count
) *count
= 1;
967 static UINT WINAPI
ID3DXConstantTableImpl_GetSamplerIndex(ID3DXConstantTable
*iface
, D3DXHANDLE constant
)
969 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
970 struct ctab_constant
*c
= get_valid_constant(This
, constant
);
972 TRACE("(%p)->(%p)\n", This
, constant
);
974 if (!c
|| c
->desc
.RegisterSet
!= D3DXRS_SAMPLER
)
976 WARN("Invalid argument specified\n");
980 TRACE("Returning RegisterIndex %u\n", c
->desc
.RegisterIndex
);
981 return c
->desc
.RegisterIndex
;
984 static D3DXHANDLE WINAPI
ID3DXConstantTableImpl_GetConstant(ID3DXConstantTable
*iface
, D3DXHANDLE constant
, UINT index
)
986 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
987 struct ctab_constant
*c
;
989 TRACE("(%p)->(%p, %d)\n", This
, constant
, index
);
993 c
= get_valid_constant(This
, constant
);
994 if (c
&& index
< c
->desc
.StructMembers
)
996 c
= &c
->constants
[index
];
997 TRACE("Returning constant %p\n", c
);
998 return handle_from_constant(c
);
1003 if (index
< This
->desc
.Constants
)
1005 c
= &This
->constants
[index
];
1006 TRACE("Returning constant %p\n", c
);
1007 return handle_from_constant(c
);
1011 WARN("Index out of range\n");
1015 static D3DXHANDLE WINAPI
ID3DXConstantTableImpl_GetConstantByName(ID3DXConstantTable
*iface
,
1016 D3DXHANDLE constant
, const char *name
)
1018 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1019 struct ctab_constant
*c
= get_valid_constant(This
, constant
);
1021 TRACE("iface %p, constant %p, name %s.\n", iface
, constant
, debugstr_a(name
));
1023 c
= get_constant_by_name(This
, c
, name
);
1024 TRACE("Returning constant %p\n", c
);
1026 return handle_from_constant(c
);
1029 static D3DXHANDLE WINAPI
ID3DXConstantTableImpl_GetConstantElement(ID3DXConstantTable
*iface
, D3DXHANDLE constant
, UINT index
)
1031 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1032 struct ctab_constant
*c
= get_valid_constant(This
, constant
);
1034 TRACE("(%p)->(%p, %d)\n", This
, constant
, index
);
1036 if (c
&& index
< c
->desc
.Elements
)
1038 if (c
->desc
.Elements
> 1) c
= &c
->constants
[index
];
1039 TRACE("Returning constant %p\n", c
);
1040 return handle_from_constant(c
);
1043 WARN("Invalid argument specified\n");
1047 static inline DWORD
get_index(const void **indata
, UINT index
, BOOL is_pointer
)
1053 return ((DWORD
**)indata
)[index
/ 16][index
% 16];
1055 return (*((DWORD
**)indata
))[index
];
1058 static UINT
set(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
, struct ctab_constant
*constant
,
1059 const void **indata
, D3DXPARAMETER_TYPE intype
, UINT
*size
, UINT incol
, D3DXPARAMETER_CLASS inclass
, UINT index
,
1062 D3DXCONSTANT_DESC
*desc
= &constant
->desc
;
1063 UINT l
, i
, regcount
= 1, regsize
= 1, cin
= 1, rin
= 1, ret
, last
= 0;
1066 /* size too small to set anything */
1067 if (*size
< desc
->Rows
* desc
->Columns
)
1073 /* D3DXPC_STRUCT is somewhat special */
1074 if (desc
->Class
== D3DXPC_STRUCT
)
1077 * Struct array sets the last complete input to the first struct element, all other
1078 * elements are not set.
1079 * E.g.: struct {int i;} s1[2];
1080 * SetValue(device, "s1", [1, 2], 8) => s1 = {2, x};
1082 * struct {int i; int n} s2[2];
1083 * SetValue(device, "s2", [1, 2, 3, 4, 5], 20) => s1 = {{3, 4}, {x, x}};
1085 if (desc
->Elements
> 1)
1087 UINT offset
= *size
/ (desc
->Rows
* desc
->Columns
) - 1;
1089 offset
= min(desc
->Elements
- 1, offset
);
1090 last
= offset
* desc
->Rows
* desc
->Columns
;
1092 if ((is_pointer
|| inclass
== D3DXPC_MATRIX_ROWS
) && desc
->RegisterSet
!= D3DXRS_BOOL
)
1094 set(table
, device
, &constant
->constants
[0], NULL
, intype
, size
, incol
, inclass
, 0, is_pointer
);
1098 last
+= set(table
, device
, &constant
->constants
[0], indata
, intype
, size
, incol
, inclass
,
1099 index
+ last
, is_pointer
);
1105 * D3DXRS_BOOL is always set. As there are only 16 bools and there are
1106 * exactly 16 input values, use matrix transpose.
1108 if (inclass
== D3DXPC_MATRIX_ROWS
&& desc
->RegisterSet
== D3DXRS_BOOL
)
1110 D3DXMATRIX mat
, *m
, min
;
1111 D3DXMatrixTranspose(&mat
, &min
);
1114 min
= *(D3DXMATRIX
*)(indata
[index
/ 16]);
1116 min
= **(D3DXMATRIX
**)indata
;
1118 D3DXMatrixTranspose(&mat
, &min
);
1120 for (i
= 0; i
< desc
->StructMembers
; ++i
)
1122 last
+= set(table
, device
, &constant
->constants
[i
], (const void **)&m
, intype
, size
, incol
,
1123 D3DXPC_SCALAR
, index
+ last
, is_pointer
);
1127 * For pointers or for matrix rows, only the first member is set.
1128 * All other members are set to 0. This is not true for D3DXRS_BOOL.
1129 * E.g.: struct {int i; int n} s;
1130 * SetValue(device, "s", [1, 2], 8) => s = {1, 0};
1132 else if ((is_pointer
|| inclass
== D3DXPC_MATRIX_ROWS
) && desc
->RegisterSet
!= D3DXRS_BOOL
)
1134 last
= set(table
, device
, &constant
->constants
[0], indata
, intype
, size
, incol
, inclass
,
1135 index
+ last
, is_pointer
);
1137 for (i
= 1; i
< desc
->StructMembers
; ++i
)
1139 set(table
, device
, &constant
->constants
[i
], NULL
, intype
, size
, incol
, inclass
, 0, is_pointer
);
1144 for (i
= 0; i
< desc
->StructMembers
; ++i
)
1146 last
+= set(table
, device
, &constant
->constants
[i
], indata
, intype
, size
, incol
, D3DXPC_SCALAR
,
1147 index
+ last
, is_pointer
);
1156 if (desc
->Elements
> 1)
1158 for (i
= 0; i
< desc
->Elements
&& *size
> 0; ++i
)
1160 last
+= set(table
, device
, &constant
->constants
[i
], indata
, intype
, size
, incol
, inclass
,
1161 index
+ last
, is_pointer
);
1163 /* adjust the vector size for matrix rows */
1164 if (inclass
== D3DXPC_MATRIX_ROWS
&& desc
->Class
== D3DXPC_VECTOR
&& (i
% 4) == 3)
1167 *size
= *size
< 12 ? 0 : *size
- 12;
1174 switch (desc
->Class
)
1178 case D3DXPC_MATRIX_ROWS
:
1179 regcount
= min(desc
->RegisterCount
, desc
->Rows
);
1180 if (inclass
== D3DXPC_MATRIX_ROWS
) cin
= incol
;
1182 regsize
= desc
->Columns
;
1185 case D3DXPC_MATRIX_COLUMNS
:
1186 regcount
= min(desc
->RegisterCount
, desc
->Columns
);
1187 if (inclass
== D3DXPC_MATRIX_ROWS
) rin
= incol
;
1189 regsize
= desc
->Rows
;
1193 FIXME("Unhandled variable class %s\n", debug_d3dxparameter_class(desc
->Class
));
1197 /* specific stuff for different in types */
1201 ret
= desc
->Columns
* desc
->Rows
;
1202 *size
-= desc
->Columns
* desc
->Rows
;
1206 switch (desc
->Class
)
1208 case D3DXPC_MATRIX_ROWS
:
1209 if (*size
< regcount
* 4)
1215 *size
-= 4 * regcount
;
1218 case D3DXPC_MATRIX_COLUMNS
:
1220 *size
-= 4 * regcount
;
1234 FIXME("Unhandled variable class %s\n", debug_d3dxparameter_class(desc
->Class
));
1239 case D3DXPC_MATRIX_ROWS
:
1240 switch (desc
->Class
)
1242 case D3DXPC_MATRIX_ROWS
:
1243 case D3DXPC_MATRIX_COLUMNS
:
1261 FIXME("Unhandled variable class %s\n", debug_d3dxparameter_class(desc
->Class
));
1267 case D3DXPC_MATRIX_COLUMNS
:
1268 switch (desc
->Class
)
1270 case D3DXPC_MATRIX_ROWS
:
1271 case D3DXPC_MATRIX_COLUMNS
:
1289 FIXME("Unhandled variable class %s\n", debug_d3dxparameter_class(desc
->Class
));
1296 FIXME("Unhandled variable class %s\n", debug_d3dxparameter_class(inclass
));
1300 /* set the registers */
1301 switch (desc
->RegisterSet
)
1304 regcount
= min(desc
->RegisterCount
, desc
->Columns
* desc
->Rows
);
1306 for (i
= 0; i
< regcount
; ++i
)
1309 DWORD t
= get_index(indata
, index
+ i
/ regsize
* rin
+ l
* cin
, is_pointer
);
1311 set_number(&tmp
, desc
->Type
, &t
, intype
);
1312 set_number(&out
, D3DXPT_BOOL
, &tmp
, desc
->Type
);
1313 if (is_vertex_shader(table
->desc
.Version
))
1314 IDirect3DDevice9_SetVertexShaderConstantB(device
, desc
->RegisterIndex
+ i
, &out
, 1);
1316 IDirect3DDevice9_SetPixelShaderConstantB(device
, desc
->RegisterIndex
+ i
, &out
, 1);
1318 if (++l
>= regsize
) l
= 0;
1323 for (i
= 0; i
< regcount
; ++i
)
1325 INT vec
[4] = {0, 0, 1, 0};
1327 for (l
= 0; l
< regsize
; ++l
)
1329 DWORD t
= get_index(indata
, index
+ i
* rin
+ l
* cin
, is_pointer
);
1331 set_number(&tmp
, desc
->Type
, &t
, intype
);
1332 set_number(&vec
[l
], D3DXPT_INT
, &tmp
, desc
->Type
);
1334 if (is_vertex_shader(table
->desc
.Version
))
1335 IDirect3DDevice9_SetVertexShaderConstantI(device
, desc
->RegisterIndex
+ i
, vec
, 1);
1337 IDirect3DDevice9_SetPixelShaderConstantI(device
, desc
->RegisterIndex
+ i
, vec
, 1);
1342 for (i
= 0; i
< regcount
; ++i
)
1346 for (l
= 0; l
< regsize
; ++l
)
1348 DWORD t
= get_index(indata
, index
+ i
* rin
+ l
* cin
, is_pointer
);
1350 set_number(&tmp
, desc
->Type
, &t
, intype
);
1351 set_number(&vec
[l
], D3DXPT_FLOAT
, &tmp
, desc
->Type
);
1353 if (is_vertex_shader(table
->desc
.Version
))
1354 IDirect3DDevice9_SetVertexShaderConstantF(device
, desc
->RegisterIndex
+ i
, vec
, 1);
1356 IDirect3DDevice9_SetPixelShaderConstantF(device
, desc
->RegisterIndex
+ i
, vec
, 1);
1361 FIXME("Unhandled register set %s\n", debug_d3dxparameter_registerset(desc
->RegisterSet
));
1366 static HRESULT
set_scalar(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
, D3DXHANDLE constant
,
1367 const void *indata
, D3DXPARAMETER_TYPE intype
)
1369 struct ctab_constant
*c
= get_valid_constant(table
, constant
);
1374 WARN("Invalid argument specified\n");
1375 return D3DERR_INVALIDCALL
;
1378 switch (c
->desc
.Class
)
1381 set(table
, device
, c
, &indata
, intype
, &count
, c
->desc
.Columns
, D3DXPC_SCALAR
, 0, FALSE
);
1385 case D3DXPC_MATRIX_ROWS
:
1386 case D3DXPC_MATRIX_COLUMNS
:
1391 FIXME("Unhandled parameter class %s\n", debug_d3dxparameter_class(c
->desc
.Class
));
1392 return D3DERR_INVALIDCALL
;
1396 static HRESULT
set_scalar_array(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
, D3DXHANDLE constant
,
1397 const void *indata
, UINT count
, D3DXPARAMETER_TYPE intype
)
1399 struct ctab_constant
*c
= get_valid_constant(table
, constant
);
1403 WARN("Invalid argument specified\n");
1404 return D3DERR_INVALIDCALL
;
1407 switch (c
->desc
.Class
)
1411 case D3DXPC_MATRIX_ROWS
:
1412 case D3DXPC_MATRIX_COLUMNS
:
1414 set(table
, device
, c
, &indata
, intype
, &count
, c
->desc
.Columns
, D3DXPC_SCALAR
, 0, FALSE
);
1418 FIXME("Unhandled parameter class %s\n", debug_d3dxparameter_class(c
->desc
.Class
));
1419 return D3DERR_INVALIDCALL
;
1423 static HRESULT
set_vector(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
, D3DXHANDLE constant
,
1424 const void *indata
, D3DXPARAMETER_TYPE intype
)
1426 struct ctab_constant
*c
= get_valid_constant(table
, constant
);
1431 WARN("Invalid argument specified\n");
1432 return D3DERR_INVALIDCALL
;
1435 switch (c
->desc
.Class
)
1440 set(table
, device
, c
, &indata
, intype
, &count
, 4, D3DXPC_VECTOR
, 0, FALSE
);
1443 case D3DXPC_MATRIX_ROWS
:
1444 case D3DXPC_MATRIX_COLUMNS
:
1448 FIXME("Unhandled parameter class %s\n", debug_d3dxparameter_class(c
->desc
.Class
));
1449 return D3DERR_INVALIDCALL
;
1453 static HRESULT
set_vector_array(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
, D3DXHANDLE constant
,
1454 const void *indata
, UINT count
, D3DXPARAMETER_TYPE intype
)
1456 struct ctab_constant
*c
= get_valid_constant(table
, constant
);
1460 WARN("Invalid argument specified\n");
1461 return D3DERR_INVALIDCALL
;
1464 switch (c
->desc
.Class
)
1468 case D3DXPC_MATRIX_ROWS
:
1469 case D3DXPC_MATRIX_COLUMNS
:
1472 set(table
, device
, c
, &indata
, intype
, &count
, 4, D3DXPC_VECTOR
, 0, FALSE
);
1476 FIXME("Unhandled parameter class %s\n", debug_d3dxparameter_class(c
->desc
.Class
));
1477 return D3DERR_INVALIDCALL
;
1481 static HRESULT
set_matrix_array(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
, D3DXHANDLE constant
,
1482 const void *indata
, UINT count
, BOOL transpose
)
1484 struct ctab_constant
*c
= get_valid_constant(table
, constant
);
1488 WARN("Invalid argument specified\n");
1489 return D3DERR_INVALIDCALL
;
1492 switch (c
->desc
.Class
)
1496 case D3DXPC_MATRIX_ROWS
:
1497 case D3DXPC_MATRIX_COLUMNS
:
1500 set(table
, device
, c
, &indata
, D3DXPT_FLOAT
, &count
, 4,
1501 transpose
? D3DXPC_MATRIX_ROWS
: D3DXPC_MATRIX_COLUMNS
, 0, FALSE
);
1505 FIXME("Unhandled parameter class %s\n", debug_d3dxparameter_class(c
->desc
.Class
));
1506 return D3DERR_INVALIDCALL
;
1510 static HRESULT
set_matrix_pointer_array(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
,
1511 D3DXHANDLE constant
, const void **indata
, UINT count
, BOOL transpose
)
1513 struct ctab_constant
*c
= get_valid_constant(table
, constant
);
1517 WARN("Invalid argument specified\n");
1518 return D3DERR_INVALIDCALL
;
1521 switch (c
->desc
.Class
)
1525 case D3DXPC_MATRIX_ROWS
:
1526 case D3DXPC_MATRIX_COLUMNS
:
1529 set(table
, device
, c
, indata
, D3DXPT_FLOAT
, &count
, 4,
1530 transpose
? D3DXPC_MATRIX_ROWS
: D3DXPC_MATRIX_COLUMNS
, 0, TRUE
);
1534 FIXME("Unhandled parameter class %s\n", debug_d3dxparameter_class(c
->desc
.Class
));
1535 return D3DERR_INVALIDCALL
;
1539 static HRESULT WINAPI
ID3DXConstantTableImpl_SetDefaults(struct ID3DXConstantTable
*iface
,
1540 struct IDirect3DDevice9
*device
)
1542 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1545 TRACE("iface %p, device %p\n", iface
, device
);
1549 WARN("Invalid argument specified\n");
1550 return D3DERR_INVALIDCALL
;
1553 for (i
= 0; i
< This
->desc
.Constants
; i
++)
1555 D3DXCONSTANT_DESC
*desc
= &This
->constants
[i
].desc
;
1558 if (!desc
->DefaultValue
)
1561 switch (desc
->RegisterSet
)
1564 if (is_vertex_shader(This
->desc
.Version
))
1565 hr
= IDirect3DDevice9_SetVertexShaderConstantB(device
, desc
->RegisterIndex
, desc
->DefaultValue
,
1566 desc
->RegisterCount
);
1568 hr
= IDirect3DDevice9_SetPixelShaderConstantB(device
, desc
->RegisterIndex
, desc
->DefaultValue
,
1569 desc
->RegisterCount
);
1573 if (is_vertex_shader(This
->desc
.Version
))
1574 hr
= IDirect3DDevice9_SetVertexShaderConstantI(device
, desc
->RegisterIndex
, desc
->DefaultValue
,
1575 desc
->RegisterCount
);
1577 hr
= IDirect3DDevice9_SetPixelShaderConstantI(device
, desc
->RegisterIndex
, desc
->DefaultValue
,
1578 desc
->RegisterCount
);
1582 if (is_vertex_shader(This
->desc
.Version
))
1583 hr
= IDirect3DDevice9_SetVertexShaderConstantF(device
, desc
->RegisterIndex
, desc
->DefaultValue
,
1584 desc
->RegisterCount
);
1586 hr
= IDirect3DDevice9_SetPixelShaderConstantF(device
, desc
->RegisterIndex
, desc
->DefaultValue
,
1587 desc
->RegisterCount
);
1591 FIXME("Unhandled register set %s\n", debug_d3dxparameter_registerset(desc
->RegisterSet
));
1603 static HRESULT WINAPI
ID3DXConstantTableImpl_SetValue(struct ID3DXConstantTable
*iface
,
1604 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const void *data
, unsigned int bytes
)
1606 struct ID3DXConstantTableImpl
*table
= impl_from_ID3DXConstantTable(iface
);
1607 struct ctab_constant
*c
= get_valid_constant(table
, constant
);
1608 D3DXCONSTANT_DESC
*desc
;
1610 TRACE("iface %p, device %p, constant %p, data %p, bytes %u\n", iface
, device
, constant
, data
, bytes
);
1612 if (!device
|| !c
|| !data
)
1614 WARN("Invalid argument specified\n");
1615 return D3DERR_INVALIDCALL
;
1620 switch (desc
->Class
)
1624 case D3DXPC_MATRIX_ROWS
:
1625 case D3DXPC_MATRIX_COLUMNS
:
1628 set(table
, device
, c
, &data
, desc
->Type
, &bytes
, desc
->Columns
, D3DXPC_SCALAR
, 0, FALSE
);
1632 FIXME("Unhandled parameter class %s\n", debug_d3dxparameter_class(desc
->Class
));
1633 return D3DERR_INVALIDCALL
;
1637 static HRESULT WINAPI
ID3DXConstantTableImpl_SetBool(struct ID3DXConstantTable
*iface
,
1638 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, BOOL b
)
1640 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1642 TRACE("iface %p, device %p, constant %p, b %d\n", iface
, device
, constant
, b
);
1644 return set_scalar(This
, device
, constant
, &b
, D3DXPT_BOOL
);
1647 static HRESULT WINAPI
ID3DXConstantTableImpl_SetBoolArray(struct ID3DXConstantTable
*iface
,
1648 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const BOOL
*b
, UINT count
)
1650 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1652 TRACE("iface %p, device %p, constant %p, b %p, count %d\n", iface
, device
, constant
, b
, count
);
1654 return set_scalar_array(This
, device
, constant
, b
, count
, D3DXPT_BOOL
);
1657 static HRESULT WINAPI
ID3DXConstantTableImpl_SetInt(struct ID3DXConstantTable
*iface
,
1658 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, INT n
)
1660 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1662 TRACE("iface %p, device %p, constant %p, n %d\n", iface
, device
, constant
, n
);
1664 return set_scalar(This
, device
, constant
, &n
, D3DXPT_INT
);
1667 static HRESULT WINAPI
ID3DXConstantTableImpl_SetIntArray(struct ID3DXConstantTable
*iface
,
1668 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const INT
*n
, UINT count
)
1670 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1672 TRACE("iface %p, device %p, constant %p, n %p, count %d\n", iface
, device
, constant
, n
, count
);
1674 return set_scalar_array(This
, device
, constant
, n
, count
, D3DXPT_INT
);
1677 static HRESULT WINAPI
ID3DXConstantTableImpl_SetFloat(struct ID3DXConstantTable
*iface
,
1678 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, float f
)
1680 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1682 TRACE("iface %p, device %p, constant %p, f %f\n", iface
, device
, constant
, f
);
1684 return set_scalar(This
, device
, constant
, &f
, D3DXPT_FLOAT
);
1687 static HRESULT WINAPI
ID3DXConstantTableImpl_SetFloatArray(struct ID3DXConstantTable
*iface
,
1688 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const float *f
, UINT count
)
1690 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1692 TRACE("iface %p, device %p, constant %p, f %p, count %d\n", iface
, device
, constant
, f
, count
);
1694 return set_scalar_array(This
, device
, constant
, f
, count
, D3DXPT_FLOAT
);
1697 static HRESULT WINAPI
ID3DXConstantTableImpl_SetVector(struct ID3DXConstantTable
*iface
,
1698 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXVECTOR4
*vector
)
1700 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1702 TRACE("iface %p, device %p, constant %p, vector %p\n", iface
, device
, constant
, vector
);
1704 return set_vector(This
, device
, constant
, vector
, D3DXPT_FLOAT
);
1707 static HRESULT WINAPI
ID3DXConstantTableImpl_SetVectorArray(struct ID3DXConstantTable
*iface
,
1708 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXVECTOR4
*vector
, UINT count
)
1710 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1712 TRACE("iface %p, device %p, constant %p, vector %p, count %u\n", iface
, device
, constant
, vector
, count
);
1714 return set_vector_array(This
, device
, constant
, vector
, count
, D3DXPT_FLOAT
);
1717 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrix(struct ID3DXConstantTable
*iface
,
1718 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXMATRIX
*matrix
)
1720 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1722 TRACE("iface %p, device %p, constant %p, matrix %p\n", iface
, device
, constant
, matrix
);
1724 return set_matrix_array(This
, device
, constant
, matrix
, 1, FALSE
);
1727 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrixArray(struct ID3DXConstantTable
*iface
,
1728 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXMATRIX
*matrix
, UINT count
)
1730 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1732 TRACE("iface %p, device %p, constant %p, matrix %p, count %u\n", iface
, device
, constant
, matrix
, count
);
1734 return set_matrix_array(This
, device
, constant
, matrix
, count
, FALSE
);
1737 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrixPointerArray(struct ID3DXConstantTable
*iface
,
1738 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXMATRIX
**matrix
, UINT count
)
1740 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1742 TRACE("iface %p, device %p, constant %p, matrix %p, count %u)\n", iface
, device
, constant
, matrix
, count
);
1744 return set_matrix_pointer_array(This
, device
, constant
, (const void **)matrix
, count
, FALSE
);
1747 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrixTranspose(struct ID3DXConstantTable
*iface
,
1748 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXMATRIX
*matrix
)
1750 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1752 TRACE("iface %p, device %p, constant %p, matrix %p\n", iface
, device
, constant
, matrix
);
1754 return set_matrix_array(This
, device
, constant
, matrix
, 1, TRUE
);
1757 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrixTransposeArray(struct ID3DXConstantTable
*iface
,
1758 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXMATRIX
*matrix
, UINT count
)
1760 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1762 TRACE("iface %p, device %p, constant %p, matrix %p, count %u\n", iface
, device
, constant
, matrix
, count
);
1764 return set_matrix_array(This
, device
, constant
, matrix
, count
, TRUE
);
1767 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrixTransposePointerArray(struct ID3DXConstantTable
*iface
,
1768 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXMATRIX
**matrix
, UINT count
)
1770 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1772 TRACE("iface %p, device %p, constant %p, matrix %p, count %u)\n", iface
, device
, constant
, matrix
, count
);
1774 return set_matrix_pointer_array(This
, device
, constant
, (const void **)matrix
, count
, TRUE
);
1777 static const struct ID3DXConstantTableVtbl ID3DXConstantTable_Vtbl
=
1779 /*** IUnknown methods ***/
1780 ID3DXConstantTableImpl_QueryInterface
,
1781 ID3DXConstantTableImpl_AddRef
,
1782 ID3DXConstantTableImpl_Release
,
1783 /*** ID3DXBuffer methods ***/
1784 ID3DXConstantTableImpl_GetBufferPointer
,
1785 ID3DXConstantTableImpl_GetBufferSize
,
1786 /*** ID3DXConstantTable methods ***/
1787 ID3DXConstantTableImpl_GetDesc
,
1788 ID3DXConstantTableImpl_GetConstantDesc
,
1789 ID3DXConstantTableImpl_GetSamplerIndex
,
1790 ID3DXConstantTableImpl_GetConstant
,
1791 ID3DXConstantTableImpl_GetConstantByName
,
1792 ID3DXConstantTableImpl_GetConstantElement
,
1793 ID3DXConstantTableImpl_SetDefaults
,
1794 ID3DXConstantTableImpl_SetValue
,
1795 ID3DXConstantTableImpl_SetBool
,
1796 ID3DXConstantTableImpl_SetBoolArray
,
1797 ID3DXConstantTableImpl_SetInt
,
1798 ID3DXConstantTableImpl_SetIntArray
,
1799 ID3DXConstantTableImpl_SetFloat
,
1800 ID3DXConstantTableImpl_SetFloatArray
,
1801 ID3DXConstantTableImpl_SetVector
,
1802 ID3DXConstantTableImpl_SetVectorArray
,
1803 ID3DXConstantTableImpl_SetMatrix
,
1804 ID3DXConstantTableImpl_SetMatrixArray
,
1805 ID3DXConstantTableImpl_SetMatrixPointerArray
,
1806 ID3DXConstantTableImpl_SetMatrixTranspose
,
1807 ID3DXConstantTableImpl_SetMatrixTransposeArray
,
1808 ID3DXConstantTableImpl_SetMatrixTransposePointerArray
1811 static HRESULT
parse_ctab_constant_type(const char *ctab
, DWORD typeoffset
, struct ctab_constant
*constant
,
1812 BOOL is_element
, WORD index
, WORD max_index
, DWORD
*offset
, DWORD nameoffset
, UINT regset
)
1814 const D3DXSHADER_TYPEINFO
*type
= (LPD3DXSHADER_TYPEINFO
)(ctab
+ typeoffset
);
1815 const D3DXSHADER_STRUCTMEMBERINFO
*memberinfo
= NULL
;
1816 HRESULT hr
= D3D_OK
;
1820 constant
->desc
.DefaultValue
= offset
? ctab
+ *offset
: NULL
;
1821 constant
->desc
.Class
= type
->Class
;
1822 constant
->desc
.Type
= type
->Type
;
1823 constant
->desc
.Rows
= type
->Rows
;
1824 constant
->desc
.Columns
= type
->Columns
;
1825 constant
->desc
.Elements
= is_element
? 1 : type
->Elements
;
1826 constant
->desc
.StructMembers
= type
->StructMembers
;
1827 constant
->desc
.Name
= ctab
+ nameoffset
;
1828 constant
->desc
.RegisterSet
= regset
;
1829 constant
->desc
.RegisterIndex
= index
;
1831 TRACE("name %s, elements %u, index %u, defaultvalue %p, regset %s\n", constant
->desc
.Name
,
1832 constant
->desc
.Elements
, index
, constant
->desc
.DefaultValue
,
1833 debug_d3dxparameter_registerset(regset
));
1834 TRACE("class %s, type %s, rows %d, columns %d, elements %d, struct_members %d\n",
1835 debug_d3dxparameter_class(type
->Class
), debug_d3dxparameter_type(type
->Type
),
1836 type
->Rows
, type
->Columns
, type
->Elements
, type
->StructMembers
);
1838 if (type
->Elements
> 1 && !is_element
)
1840 count
= type
->Elements
;
1842 else if ((type
->Class
== D3DXPC_STRUCT
) && type
->StructMembers
)
1844 memberinfo
= (D3DXSHADER_STRUCTMEMBERINFO
*)(ctab
+ type
->StructMemberInfo
);
1845 count
= type
->StructMembers
;
1850 constant
->constants
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*constant
->constants
) * count
);
1851 if (!constant
->constants
)
1853 ERR("Out of memory\n");
1858 for (i
= 0; i
< count
; ++i
)
1860 hr
= parse_ctab_constant_type(ctab
, memberinfo
? memberinfo
[i
].TypeInfo
: typeoffset
,
1861 &constant
->constants
[i
], memberinfo
== NULL
, index
+ size
, max_index
, offset
,
1862 memberinfo
? memberinfo
[i
].Name
: nameoffset
, regset
);
1866 size
+= constant
->constants
[i
].desc
.RegisterCount
;
1871 WORD offsetdiff
= type
->Columns
* type
->Rows
;
1874 size
= type
->Columns
* type
->Rows
;
1879 fail
= type
->Class
!= D3DXPC_SCALAR
&& type
->Class
!= D3DXPC_VECTOR
1880 && type
->Class
!= D3DXPC_MATRIX_ROWS
&& type
->Class
!= D3DXPC_MATRIX_COLUMNS
;
1885 switch (type
->Class
)
1891 offsetdiff
= type
->Rows
* 4;
1894 case D3DXPC_MATRIX_ROWS
:
1895 offsetdiff
= type
->Rows
* 4;
1899 case D3DXPC_MATRIX_COLUMNS
:
1900 offsetdiff
= type
->Columns
* 4;
1901 size
= type
->Columns
;
1910 case D3DXRS_SAMPLER
:
1912 fail
= type
->Class
!= D3DXPC_OBJECT
;
1922 FIXME("Unhandled register set %s, type class %s\n", debug_d3dxparameter_registerset(regset
),
1923 debug_d3dxparameter_class(type
->Class
));
1926 /* offset in bytes => offsetdiff * sizeof(DWORD) */
1927 if (offset
) *offset
+= offsetdiff
* 4;
1930 constant
->desc
.RegisterCount
= max(0, min(max_index
- index
, size
));
1931 constant
->desc
.Bytes
= 4 * constant
->desc
.Elements
* type
->Rows
* type
->Columns
;
1936 if (constant
->constants
)
1938 for (i
= 0; i
< count
; ++i
)
1940 free_constant(&constant
->constants
[i
]);
1942 HeapFree(GetProcessHeap(), 0, constant
->constants
);
1943 constant
->constants
= NULL
;
1949 HRESULT WINAPI
D3DXGetShaderConstantTableEx(const DWORD
*byte_code
, DWORD flags
, ID3DXConstantTable
**constant_table
)
1951 struct ID3DXConstantTableImpl
*object
= NULL
;
1955 const D3DXSHADER_CONSTANTTABLE
*ctab_header
;
1956 const D3DXSHADER_CONSTANTINFO
*constant_info
;
1959 TRACE("byte_code %p, flags %x, constant_table %p\n", byte_code
, flags
, constant_table
);
1961 if (constant_table
) *constant_table
= NULL
;
1963 if (!byte_code
|| !constant_table
)
1965 WARN("Invalid argument specified.\n");
1966 return D3DERR_INVALIDCALL
;
1969 if (!is_valid_bytecode(*byte_code
))
1971 WARN("Invalid byte_code specified.\n");
1975 if (flags
) FIXME("Flags (%#x) are not handled, yet!\n", flags
);
1977 hr
= D3DXFindShaderComment(byte_code
, MAKEFOURCC('C','T','A','B'), &data
, &size
);
1980 WARN("CTAB not found.\n");
1981 return D3DXERR_INVALIDDATA
;
1984 if (size
< sizeof(*ctab_header
))
1986 WARN("Invalid CTAB size.\n");
1987 return D3DXERR_INVALIDDATA
;
1990 ctab_header
= (const D3DXSHADER_CONSTANTTABLE
*)data
;
1991 if (ctab_header
->Size
!= sizeof(*ctab_header
))
1993 WARN("Invalid D3DXSHADER_CONSTANTTABLE size.\n");
1994 return D3DXERR_INVALIDDATA
;
1997 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*object
));
1999 return E_OUTOFMEMORY
;
2001 object
->ID3DXConstantTable_iface
.lpVtbl
= &ID3DXConstantTable_Vtbl
;
2004 object
->ctab
= HeapAlloc(GetProcessHeap(), 0, size
);
2007 ERR("Out of memory\n");
2008 HeapFree(GetProcessHeap(), 0, object
);
2009 return E_OUTOFMEMORY
;
2011 object
->size
= size
;
2012 memcpy(object
->ctab
, data
, object
->size
);
2014 object
->desc
.Creator
= ctab_header
->Creator
? object
->ctab
+ ctab_header
->Creator
: NULL
;
2015 object
->desc
.Version
= ctab_header
->Version
;
2016 object
->desc
.Constants
= ctab_header
->Constants
;
2017 TRACE("Creator %s, Version %x, Constants %u, Target %s\n",
2018 debugstr_a(object
->desc
.Creator
), object
->desc
.Version
, object
->desc
.Constants
,
2019 debugstr_a(ctab_header
->Target
? object
->ctab
+ ctab_header
->Target
: NULL
));
2021 object
->constants
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
2022 sizeof(*object
->constants
) * object
->desc
.Constants
);
2023 if (!object
->constants
)
2025 ERR("Out of memory\n");
2030 constant_info
= (const D3DXSHADER_CONSTANTINFO
*)(object
->ctab
+ ctab_header
->ConstantInfo
);
2031 for (i
= 0; i
< ctab_header
->Constants
; i
++)
2033 DWORD offset
= constant_info
[i
].DefaultValue
;
2035 hr
= parse_ctab_constant_type(object
->ctab
, constant_info
[i
].TypeInfo
,
2036 &object
->constants
[i
], FALSE
, constant_info
[i
].RegisterIndex
,
2037 constant_info
[i
].RegisterIndex
+ constant_info
[i
].RegisterCount
,
2038 offset
? &offset
: NULL
, constant_info
[i
].Name
, constant_info
[i
].RegisterSet
);
2043 * Set the register count, it may differ for D3DXRS_INT4, because somehow
2044 * it makes the assumption that the register size is 1 instead of 4, so the
2045 * count is 4 times bigger. This holds true only for toplevel shader
2046 * constants. The count of elements and members is always based on a
2047 * register size of 4.
2049 if (object
->constants
[i
].desc
.RegisterSet
== D3DXRS_INT4
)
2051 object
->constants
[i
].desc
.RegisterCount
= constant_info
[i
].RegisterCount
;
2053 object
->constants
[i
].constantinfo_reserved
= constant_info
[i
].Reserved
;
2056 *constant_table
= &object
->ID3DXConstantTable_iface
;
2061 free_constant_table(object
);
2062 HeapFree(GetProcessHeap(), 0, object
);
2067 HRESULT WINAPI
D3DXGetShaderConstantTable(const DWORD
*byte_code
, ID3DXConstantTable
**constant_table
)
2069 TRACE("(%p, %p): Forwarded to D3DXGetShaderConstantTableEx\n", byte_code
, constant_table
);
2071 return D3DXGetShaderConstantTableEx(byte_code
, 0, constant_table
);
2074 HRESULT WINAPI
D3DXCreateFragmentLinker(IDirect3DDevice9
*device
, UINT size
, ID3DXFragmentLinker
**linker
)
2076 FIXME("device %p, size %u, linker %p: stub.\n", device
, size
, linker
);
2085 HRESULT WINAPI
D3DXCreateFragmentLinkerEx(IDirect3DDevice9
*device
, UINT size
, DWORD flags
, ID3DXFragmentLinker
**linker
)
2087 FIXME("device %p, size %u, flags %#x, linker %p: stub.\n", device
, size
, flags
, linker
);
2095 HRESULT WINAPI
D3DXGetShaderSamplers(const DWORD
*byte_code
, const char **samplers
, UINT
*count
)
2097 UINT i
, sampler_count
= 0;
2100 const D3DXSHADER_CONSTANTTABLE
*ctab_header
;
2101 const D3DXSHADER_CONSTANTINFO
*constant_info
;
2103 TRACE("byte_code %p, samplers %p, count %p\n", byte_code
, samplers
, count
);
2105 if (count
) *count
= 0;
2107 if (D3DXFindShaderComment(byte_code
, MAKEFOURCC('C','T','A','B'), (const void **)&data
, &size
) != D3D_OK
)
2110 if (size
< sizeof(*ctab_header
)) return D3D_OK
;
2112 ctab_header
= (const D3DXSHADER_CONSTANTTABLE
*)data
;
2113 if (ctab_header
->Size
!= sizeof(*ctab_header
)) return D3D_OK
;
2115 constant_info
= (const D3DXSHADER_CONSTANTINFO
*)(data
+ ctab_header
->ConstantInfo
);
2116 for (i
= 0; i
< ctab_header
->Constants
; i
++)
2118 const D3DXSHADER_TYPEINFO
*type
;
2120 TRACE("name = %s\n", data
+ constant_info
[i
].Name
);
2122 type
= (const D3DXSHADER_TYPEINFO
*)(data
+ constant_info
[i
].TypeInfo
);
2124 if (type
->Type
== D3DXPT_SAMPLER
2125 || type
->Type
== D3DXPT_SAMPLER1D
2126 || type
->Type
== D3DXPT_SAMPLER2D
2127 || type
->Type
== D3DXPT_SAMPLER3D
2128 || type
->Type
== D3DXPT_SAMPLERCUBE
)
2130 if (samplers
) samplers
[sampler_count
] = data
+ constant_info
[i
].Name
;
2136 TRACE("Found %u samplers\n", sampler_count
);
2138 if (count
) *count
= sampler_count
;
2143 HRESULT WINAPI
D3DXDisassembleShader(const DWORD
*shader
, BOOL colorcode
, const char *comments
, ID3DXBuffer
**disassembly
)
2145 FIXME("%p %d %s %p: stub\n", shader
, colorcode
, debugstr_a(comments
), disassembly
);
2146 return E_OUTOFMEMORY
;
2149 struct d3dx9_texture_shader
2151 ID3DXTextureShader ID3DXTextureShader_iface
;
2155 static inline struct d3dx9_texture_shader
*impl_from_ID3DXTextureShader(ID3DXTextureShader
*iface
)
2157 return CONTAINING_RECORD(iface
, struct d3dx9_texture_shader
, ID3DXTextureShader_iface
);
2160 static HRESULT WINAPI
d3dx9_texture_shader_QueryInterface(ID3DXTextureShader
*iface
, REFIID riid
, void **out
)
2162 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
2164 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
2165 IsEqualGUID(riid
, &IID_ID3DXTextureShader
))
2167 iface
->lpVtbl
->AddRef(iface
);
2172 WARN("Interface %s not found.\n", debugstr_guid(riid
));
2174 return E_NOINTERFACE
;
2177 static ULONG WINAPI
d3dx9_texture_shader_AddRef(ID3DXTextureShader
*iface
)
2179 struct d3dx9_texture_shader
*texture_shader
= impl_from_ID3DXTextureShader(iface
);
2180 ULONG refcount
= InterlockedIncrement(&texture_shader
->ref
);
2182 TRACE("%p increasing refcount to %u.\n", texture_shader
, refcount
);
2187 static ULONG WINAPI
d3dx9_texture_shader_Release(ID3DXTextureShader
*iface
)
2189 struct d3dx9_texture_shader
*texture_shader
= impl_from_ID3DXTextureShader(iface
);
2190 ULONG refcount
= InterlockedDecrement(&texture_shader
->ref
);
2192 TRACE("%p decreasing refcount to %u.\n", texture_shader
, refcount
);
2196 HeapFree(GetProcessHeap(), 0, texture_shader
);
2202 static HRESULT WINAPI
d3dx9_texture_shader_GetFunction(ID3DXTextureShader
*iface
, struct ID3DXBuffer
**function
)
2204 FIXME("iface %p, function %p stub.\n", iface
, function
);
2209 static HRESULT WINAPI
d3dx9_texture_shader_GetConstantBuffer(ID3DXTextureShader
*iface
, struct ID3DXBuffer
**constant_buffer
)
2211 FIXME("iface %p, constant_buffer %p stub.\n", iface
, constant_buffer
);
2216 static HRESULT WINAPI
d3dx9_texture_shader_GetDesc(ID3DXTextureShader
*iface
, D3DXCONSTANTTABLE_DESC
*desc
)
2218 FIXME("iface %p, desc %p stub.\n", iface
, desc
);
2223 static HRESULT WINAPI
d3dx9_texture_shader_GetConstantDesc(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, D3DXCONSTANT_DESC
*constant_desc
, UINT
*count
)
2225 FIXME("iface %p, constant %p, constant_desc %p, count %p stub.\n", iface
, constant
, constant_desc
, count
);
2230 static D3DXHANDLE WINAPI
d3dx9_texture_shader_GetConstant(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, UINT index
)
2232 FIXME("iface %p, constant %p, index %u stub.\n", iface
, constant
, index
);
2237 static D3DXHANDLE WINAPI
d3dx9_texture_shader_GetConstantByName(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const char *name
)
2239 FIXME("iface %p, constant %p, name %s stub.\n", iface
, constant
, debugstr_a(name
));
2244 static D3DXHANDLE WINAPI
d3dx9_texture_shader_GetConstantElement(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, UINT index
)
2246 FIXME("iface %p, constant %p, index %u stub.\n", iface
, constant
, index
);
2251 static HRESULT WINAPI
d3dx9_texture_shader_SetDefaults(ID3DXTextureShader
*iface
)
2253 FIXME("iface %p stub.\n", iface
);
2258 static HRESULT WINAPI
d3dx9_texture_shader_SetValue(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const void *data
, UINT bytes
)
2260 FIXME("iface %p, constant %p, data %p, bytes %u stub.\n", iface
, constant
, data
, bytes
);
2265 static HRESULT WINAPI
d3dx9_texture_shader_SetBool(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, BOOL b
)
2267 FIXME("iface %p, constant %p, b %u stub.\n", iface
, constant
, b
);
2272 static HRESULT WINAPI
d3dx9_texture_shader_SetBoolArray(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const BOOL
*b
, UINT count
)
2274 FIXME("iface %p, constant %p, b %p, count %u stub.\n", iface
, constant
, b
, count
);
2279 static HRESULT WINAPI
d3dx9_texture_shader_SetInt(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, INT n
)
2281 FIXME("iface %p, constant %p, n %d stub.\n", iface
, constant
, n
);
2286 static HRESULT WINAPI
d3dx9_texture_shader_SetIntArray(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const INT
*n
, UINT count
)
2288 FIXME("iface %p, constant %p, n %p, count %u stub.\n", iface
, constant
, n
, count
);
2293 static HRESULT WINAPI
d3dx9_texture_shader_SetFloat(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, FLOAT f
)
2295 FIXME("iface %p, constant %p, f %f stub.\n", iface
, constant
, f
);
2300 static HRESULT WINAPI
d3dx9_texture_shader_SetFloatArray(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const FLOAT
*f
, UINT count
)
2302 FIXME("iface %p, constant %p, f %p, count %u stub.\n", iface
, constant
, f
, count
);
2307 static HRESULT WINAPI
d3dx9_texture_shader_SetVector(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const D3DXVECTOR4
*vector
)
2309 FIXME("iface %p, constant %p, vector %p stub.\n", iface
, constant
, vector
);
2314 static HRESULT WINAPI
d3dx9_texture_shader_SetVectorArray(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const D3DXVECTOR4
*vector
, UINT count
)
2316 FIXME("iface %p, constant %p, vector %p, count %u stub.\n", iface
, constant
, vector
, count
);
2321 static HRESULT WINAPI
d3dx9_texture_shader_SetMatrix(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const D3DXMATRIX
*matrix
)
2323 FIXME("iface %p, constant %p, matrix %p stub.\n", iface
, constant
, matrix
);
2328 static HRESULT WINAPI
d3dx9_texture_shader_SetMatrixArray(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const D3DXMATRIX
*matrix
, UINT count
)
2330 FIXME("iface %p, constant %p, matrix %p, count %u stub.\n", iface
, constant
, matrix
, count
);
2335 static HRESULT WINAPI
d3dx9_texture_shader_SetMatrixPointerArray(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const D3DXMATRIX
**matrix
, UINT count
)
2337 FIXME("iface %p, constant %p, matrix %p, count %u stub.\n", iface
, constant
, matrix
, count
);
2342 static HRESULT WINAPI
d3dx9_texture_shader_SetMatrixTranspose(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const D3DXMATRIX
*matrix
)
2344 FIXME("iface %p, constant %p, matrix %p stub.\n", iface
, constant
, matrix
);
2349 static HRESULT WINAPI
d3dx9_texture_shader_SetMatrixTransposeArray(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const D3DXMATRIX
*matrix
, UINT count
)
2351 FIXME("iface %p, constant %p, matrix %p, count %u stub.\n", iface
, constant
, matrix
, count
);
2356 static HRESULT WINAPI
d3dx9_texture_shader_SetMatrixTransposePointerArray(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const D3DXMATRIX
**matrix
, UINT count
)
2358 FIXME("iface %p, constant %p, matrix %p, count %u stub.\n", iface
, constant
, matrix
, count
);
2363 static const struct ID3DXTextureShaderVtbl d3dx9_texture_shader_vtbl
=
2365 /*** IUnknown methods ***/
2366 d3dx9_texture_shader_QueryInterface
,
2367 d3dx9_texture_shader_AddRef
,
2368 d3dx9_texture_shader_Release
,
2369 /*** ID3DXTextureShader methods ***/
2370 d3dx9_texture_shader_GetFunction
,
2371 d3dx9_texture_shader_GetConstantBuffer
,
2372 d3dx9_texture_shader_GetDesc
,
2373 d3dx9_texture_shader_GetConstantDesc
,
2374 d3dx9_texture_shader_GetConstant
,
2375 d3dx9_texture_shader_GetConstantByName
,
2376 d3dx9_texture_shader_GetConstantElement
,
2377 d3dx9_texture_shader_SetDefaults
,
2378 d3dx9_texture_shader_SetValue
,
2379 d3dx9_texture_shader_SetBool
,
2380 d3dx9_texture_shader_SetBoolArray
,
2381 d3dx9_texture_shader_SetInt
,
2382 d3dx9_texture_shader_SetIntArray
,
2383 d3dx9_texture_shader_SetFloat
,
2384 d3dx9_texture_shader_SetFloatArray
,
2385 d3dx9_texture_shader_SetVector
,
2386 d3dx9_texture_shader_SetVectorArray
,
2387 d3dx9_texture_shader_SetMatrix
,
2388 d3dx9_texture_shader_SetMatrixArray
,
2389 d3dx9_texture_shader_SetMatrixPointerArray
,
2390 d3dx9_texture_shader_SetMatrixTranspose
,
2391 d3dx9_texture_shader_SetMatrixTransposeArray
,
2392 d3dx9_texture_shader_SetMatrixTransposePointerArray
2395 HRESULT WINAPI
D3DXCreateTextureShader(const DWORD
*function
, ID3DXTextureShader
**texture_shader
)
2397 struct d3dx9_texture_shader
*object
;
2399 TRACE("function %p, texture_shader %p.\n", function
, texture_shader
);
2401 if (!function
|| !texture_shader
)
2402 return D3DERR_INVALIDCALL
;
2404 object
= HeapAlloc(GetProcessHeap(), 0, sizeof(*object
));
2406 return E_OUTOFMEMORY
;
2408 object
->ID3DXTextureShader_iface
.lpVtbl
= &d3dx9_texture_shader_vtbl
;
2411 *texture_shader
= &object
->ID3DXTextureShader_iface
;
2416 static unsigned int get_instr_length(const DWORD
*byte_code
, unsigned int major
, unsigned int minor
)
2418 unsigned int len
= 0;
2421 return (*byte_code
& D3DSI_INSTLENGTH_MASK
) >> D3DSI_INSTLENGTH_SHIFT
;
2423 switch (*byte_code
& 0xffff)
2426 ERR("Unexpected END token.\n");
2428 case D3DSIO_COMMENT
:
2429 return (*byte_code
& D3DSI_COMMENTSIZE_MASK
) >> D3DSI_COMMENTSIZE_SHIFT
;
2437 while (*byte_code
& 0x80000000)
2447 static HRESULT
get_shader_semantics(const DWORD
*byte_code
, D3DXSEMANTIC
*semantics
, UINT
*count
, BOOL output
)
2449 static const D3DDECLUSAGE regtype_usage
[] =
2454 D3DDECLUSAGE_TEXCOORD
,
2457 D3DDECLUSAGE_TEXCOORD
,
2462 static const D3DDECLUSAGE rast_usage
[] =
2464 D3DDECLUSAGE_POSITION
,
2468 DWORD reg_type
, usage
, index
, version_token
= *byte_code
;
2469 BOOL is_ps
= version_token
>> 16 == 0xffff;
2470 unsigned int major
, minor
, i
= 0, j
;
2471 BYTE colors
= 0, rastout
= 0;
2472 BOOL has_dcl
, depth
= 0;
2475 if ((version_token
& 0xffff0000) != 0xfffe0000 && (version_token
& 0xffff0000) != 0xffff0000)
2476 return D3DXERR_INVALIDDATA
;
2478 major
= version_token
>> 8 & 0xff;
2479 minor
= version_token
& 0xff;
2481 TRACE("%s shader, version %u.%u.\n", is_ps
? "Pixel" : "Vertex", major
, minor
);
2484 has_dcl
= (!is_ps
&& (!output
|| major
== 3)) || (is_ps
&& !output
&& major
>= 2);
2486 while (*byte_code
!= D3DSIO_END
)
2488 if (has_dcl
&& (*byte_code
& 0xffff) == D3DSIO_DCL
)
2490 DWORD usage_token
= byte_code
[1];
2491 DWORD reg
= byte_code
[2];
2493 reg_type
= ((reg
& D3DSP_REGTYPE_MASK
) >> D3DSP_REGTYPE_SHIFT
)
2494 | ((reg
& D3DSP_REGTYPE_MASK2
) >> D3DSP_REGTYPE_SHIFT2
);
2496 if (is_ps
&& !output
&& major
== 2)
2498 /* dcl with no explicit usage, look at the register. */
2499 reg_type
= ((reg
& D3DSP_REGTYPE_MASK
) >> D3DSP_REGTYPE_SHIFT
)
2500 | ((reg
& D3DSP_REGTYPE_MASK2
) >> D3DSP_REGTYPE_SHIFT2
);
2501 index
= reg
& D3DSP_REGNUM_MASK
;
2502 if (reg_type
>= ARRAY_SIZE(regtype_usage
))
2504 WARN("Invalid register type %u.\n", reg_type
);
2507 usage
= regtype_usage
[reg_type
];
2510 semantics
[i
].Usage
= usage
;
2511 semantics
[i
].UsageIndex
= index
;
2515 else if ((!output
&& reg_type
== D3DSPR_INPUT
) || (output
&& reg_type
== D3DSPR_OUTPUT
))
2519 semantics
[i
].Usage
=
2520 (usage_token
& D3DSP_DCL_USAGE_MASK
) >> D3DSP_DCL_USAGE_SHIFT
;
2521 semantics
[i
].UsageIndex
=
2522 (usage_token
& D3DSP_DCL_USAGEINDEX_MASK
) >> D3DSP_DCL_USAGEINDEX_SHIFT
;
2530 unsigned int len
= get_instr_length(byte_code
, major
, minor
) + 1;
2532 switch (*byte_code
& 0xffff)
2534 case D3DSIO_COMMENT
:
2542 while (*byte_code
& 0x80000000)
2544 reg_type
= ((*byte_code
& D3DSP_REGTYPE_MASK
) >> D3DSP_REGTYPE_SHIFT
)
2545 | ((*byte_code
& D3DSP_REGTYPE_MASK2
) >> D3DSP_REGTYPE_SHIFT2
);
2546 index
= *byte_code
& D3DSP_REGNUM_MASK
;
2548 if ((reg_type
== D3DSPR_TEMP
&& is_ps
&& major
== 1)
2549 || (reg_type
== D3DSPR_INPUT
&& is_ps
)
2550 || (reg_type
== D3DSPR_TEXTURE
&& is_ps
&& !output
)
2551 || reg_type
== D3DSPR_RASTOUT
2552 || reg_type
== D3DSPR_ATTROUT
2553 || reg_type
== D3DSPR_OUTPUT
2554 || reg_type
== D3DSPR_DEPTHOUT
)
2556 if (reg_type
== D3DSPR_RASTOUT
)
2557 rastout
|= 1u << index
;
2558 else if (reg_type
== D3DSPR_DEPTHOUT
)
2560 else if (reg_type
== D3DSPR_TEXTURE
|| reg_type
== D3DSPR_OUTPUT
)
2561 texcoords
|= 1u << index
;
2563 colors
|= 1u << index
;
2571 byte_code
+= get_instr_length(byte_code
, major
, minor
) + 1;
2584 semantics
[i
].Usage
= D3DDECLUSAGE_TEXCOORD
;
2585 semantics
[i
].UsageIndex
= j
;
2599 semantics
[i
].Usage
= D3DDECLUSAGE_COLOR
;
2600 semantics
[i
].UsageIndex
= j
;
2612 if (j
>= ARRAY_SIZE(rast_usage
))
2614 WARN("Invalid RASTOUT register index.\n");
2619 usage
= rast_usage
[j
];
2623 semantics
[i
].Usage
= usage
;
2624 semantics
[i
].UsageIndex
= 0;
2635 semantics
[i
].Usage
= D3DDECLUSAGE_DEPTH
;
2636 semantics
[i
].UsageIndex
= 0;
2648 HRESULT WINAPI
D3DXGetShaderInputSemantics(const DWORD
*byte_code
, D3DXSEMANTIC
*semantics
, UINT
*count
)
2650 TRACE("byte_code %p, semantics %p, count %p.\n", byte_code
, semantics
, count
);
2652 return get_shader_semantics(byte_code
, semantics
, count
, FALSE
);
2655 HRESULT WINAPI
D3DXGetShaderOutputSemantics(const DWORD
*byte_code
, D3DXSEMANTIC
*semantics
, UINT
*count
)
2657 TRACE("byte_code %p, semantics %p, count %p.\n", byte_code
, semantics
, count
);
2659 return get_shader_semantics(byte_code
, semantics
, count
, TRUE
);