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
23 #include "d3dx9_private.h"
24 #include "d3dcommon.h"
25 #include "d3dcompiler.h"
27 WINE_DEFAULT_DEBUG_CHANNEL(d3dx
);
29 static inline BOOL
is_valid_bytecode(DWORD token
)
31 return (token
& 0xfffe0000) == 0xfffe0000;
34 const char * WINAPI
D3DXGetPixelShaderProfile(struct IDirect3DDevice9
*device
)
38 TRACE("device %p\n", device
);
40 if (!device
) return NULL
;
42 IDirect3DDevice9_GetDeviceCaps(device
,&caps
);
44 switch (caps
.PixelShaderVersion
)
46 case D3DPS_VERSION(1, 1):
49 case D3DPS_VERSION(1, 2):
52 case D3DPS_VERSION(1, 3):
55 case D3DPS_VERSION(1, 4):
58 case D3DPS_VERSION(2, 0):
59 if ((caps
.PS20Caps
.NumTemps
>=22) &&
60 (caps
.PS20Caps
.Caps
&D3DPS20CAPS_ARBITRARYSWIZZLE
) &&
61 (caps
.PS20Caps
.Caps
&D3DPS20CAPS_GRADIENTINSTRUCTIONS
) &&
62 (caps
.PS20Caps
.Caps
&D3DPS20CAPS_PREDICATION
) &&
63 (caps
.PS20Caps
.Caps
&D3DPS20CAPS_NODEPENDENTREADLIMIT
) &&
64 (caps
.PS20Caps
.Caps
&D3DPS20CAPS_NOTEXINSTRUCTIONLIMIT
))
68 if ((caps
.PS20Caps
.NumTemps
>=32) &&
69 (caps
.PS20Caps
.Caps
&D3DPS20CAPS_NOTEXINSTRUCTIONLIMIT
))
75 case D3DPS_VERSION(3, 0):
82 UINT WINAPI
D3DXGetShaderSize(const DWORD
*byte_code
)
84 const DWORD
*ptr
= byte_code
;
86 TRACE("byte_code %p\n", byte_code
);
90 /* Look for the END token, skipping the VERSION token */
91 while (*++ptr
!= D3DSIO_END
)
94 if ((*ptr
& D3DSI_OPCODE_MASK
) == D3DSIO_COMMENT
)
96 ptr
+= ((*ptr
& D3DSI_COMMENTSIZE_MASK
) >> D3DSI_COMMENTSIZE_SHIFT
);
101 /* Return the shader size in bytes */
102 return (ptr
- byte_code
) * sizeof(*ptr
);
105 DWORD WINAPI
D3DXGetShaderVersion(const DWORD
*byte_code
)
107 TRACE("byte_code %p\n", byte_code
);
109 return byte_code
? *byte_code
: 0;
112 const char * WINAPI
D3DXGetVertexShaderProfile(struct IDirect3DDevice9
*device
)
116 TRACE("device %p\n", device
);
118 if (!device
) return NULL
;
120 IDirect3DDevice9_GetDeviceCaps(device
,&caps
);
122 switch (caps
.VertexShaderVersion
)
124 case D3DVS_VERSION(1, 1):
126 case D3DVS_VERSION(2, 0):
127 if ((caps
.VS20Caps
.NumTemps
>=13) &&
128 (caps
.VS20Caps
.DynamicFlowControlDepth
==24) &&
129 (caps
.VS20Caps
.Caps
&D3DPS20CAPS_PREDICATION
))
134 case D3DVS_VERSION(3, 0):
141 HRESULT WINAPI
D3DXFindShaderComment(const DWORD
*byte_code
, DWORD fourcc
, const void **data
, UINT
*size
)
143 const DWORD
*ptr
= byte_code
;
146 TRACE("byte_code %p, fourcc %#lx, data %p, size %p.\n", byte_code
, fourcc
, data
, size
);
148 if (data
) *data
= NULL
;
151 if (!byte_code
) return D3DERR_INVALIDCALL
;
153 version
= *ptr
>> 16;
154 if (version
!= 0x4658 /* FX */
155 && version
!= 0x5458 /* TX */
158 && version
!= 0xfffe /* VS */
159 && version
!= 0xffff) /* PS */
161 WARN("Invalid data supplied\n");
162 return D3DXERR_INVALIDDATA
;
165 while (*++ptr
!= D3DSIO_END
)
167 /* Check if it is a comment */
168 if ((*ptr
& D3DSI_OPCODE_MASK
) == D3DSIO_COMMENT
)
170 DWORD comment_size
= (*ptr
& D3DSI_COMMENTSIZE_MASK
) >> D3DSI_COMMENTSIZE_SHIFT
;
172 /* Check if this is the comment we are looking for */
173 if (*(ptr
+ 1) == fourcc
)
175 UINT ctab_size
= (comment_size
- 1) * sizeof(DWORD
);
176 const void *ctab_data
= ptr
+ 2;
181 TRACE("Returning comment data at %p with size %d\n", ctab_data
, ctab_size
);
191 static BOOL WINAPI
load_d3dassemble_once(INIT_ONCE
*once
, void *param
, void **context
)
193 /* FIXME: This assumes that d3dcompiler.h and dlls/d3dcompiler_XX/Makefile.in stay
194 * in sync regarding which library creates the unnumbered d3dcompiler.lib implib.
195 * GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, D3DCompile) would
196 * be nice, but "D3DCompile" will point to the IAT stub, not d3dcompiler_xy.dll */
197 HMODULE mod
= GetModuleHandleW(D3DCOMPILER_DLL_W
);
198 void **assemble
= param
;
201 ERR("%s not found - which d3dcompiler are we linked against?\n", D3DCOMPILER_DLL_A
);
203 *assemble
= (void *)GetProcAddress(mod
, "D3DAssemble");
207 HRESULT WINAPI
D3DXAssembleShader(const char *data
, UINT data_len
, const D3DXMACRO
*defines
,
208 ID3DXInclude
*include
, DWORD flags
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
210 static HRESULT (WINAPI
*pD3DAssemble
)(const void *data
, SIZE_T datasize
, const char *filename
,
211 const D3D_SHADER_MACRO
* defines
, ID3DInclude
* include
, UINT flags
,
212 ID3DBlob
* *shader
, ID3DBlob
* *error_messages
);
213 static INIT_ONCE init_once
= INIT_ONCE_STATIC_INIT
;
216 TRACE("data %p, data_len %u, defines %p, include %p, flags %#lx, shader %p, error_messages %p.\n",
217 data
, data_len
, defines
, include
, flags
, shader
, error_messages
);
219 InitOnceExecuteOnce(&init_once
, load_d3dassemble_once
, &pD3DAssemble
, NULL
);
221 /* Forward to d3dcompiler: the parameter types aren't really different,
222 the actual data types are equivalent */
223 hr
= pD3DAssemble(data
, data_len
, NULL
, (D3D_SHADER_MACRO
*)defines
,
224 (ID3DInclude
*)include
, flags
, (ID3DBlob
**)shader
,
225 (ID3DBlob
**)error_messages
);
227 if(hr
== E_FAIL
) hr
= D3DXERR_INVALIDDATA
;
231 static const void *main_file_data
;
233 static CRITICAL_SECTION_DEBUG from_file_mutex_debug
=
235 0, 0, &from_file_mutex
,
237 &from_file_mutex_debug
.ProcessLocksList
,
238 &from_file_mutex_debug
.ProcessLocksList
240 0, 0, {(DWORD_PTR
)(__FILE__
": from_file_mutex")}
242 CRITICAL_SECTION from_file_mutex
= {&from_file_mutex_debug
, -1, 0, 0, 0, 0};
244 /* D3DXInclude private implementation, used to implement
245 * D3DXAssembleShaderFromFile() from D3DXAssembleShader(). */
246 /* To be able to correctly resolve include search paths we have to store the
247 * pathname of each include file. We store the pathname pointer right before
249 static HRESULT WINAPI
d3dx_include_from_file_open(ID3DXInclude
*iface
, D3DXINCLUDE_TYPE include_type
,
250 const char *filename
, const void *parent_data
, const void **data
, UINT
*bytes
)
252 const char *p
, *parent_name
= "";
253 char *pathname
= NULL
, *ptr
;
254 char **buffer
= NULL
;
260 parent_name
= *((const char **)parent_data
- 1);
265 parent_name
= *((const char **)main_file_data
- 1);
268 TRACE("Looking up include file %s, parent %s.\n", debugstr_a(filename
), debugstr_a(parent_name
));
270 if ((p
= strrchr(parent_name
, '\\')))
274 pathname
= HeapAlloc(GetProcessHeap(), 0, (p
- parent_name
) + strlen(filename
) + 1);
276 return HRESULT_FROM_WIN32(GetLastError());
278 memcpy(pathname
, parent_name
, p
- parent_name
);
279 strcpy(pathname
+ (p
- parent_name
), filename
);
280 ptr
= pathname
+ (p
- parent_name
);
288 file
= CreateFileA(pathname
, GENERIC_READ
, FILE_SHARE_READ
, 0, OPEN_EXISTING
, 0, 0);
289 if(file
== INVALID_HANDLE_VALUE
)
292 TRACE("Include file found at pathname = %s\n", debugstr_a(pathname
));
294 size
= GetFileSize(file
, NULL
);
295 if(size
== INVALID_FILE_SIZE
)
298 buffer
= HeapAlloc(GetProcessHeap(), 0, size
+ sizeof(char *));
302 if (!ReadFile(file
, buffer
+ 1, size
, (DWORD
*)bytes
, NULL
))
307 main_file_data
= *data
;
314 HeapFree(GetProcessHeap(), 0, pathname
);
315 HeapFree(GetProcessHeap(), 0, buffer
);
316 return HRESULT_FROM_WIN32(GetLastError());
319 static HRESULT WINAPI
d3dx_include_from_file_close(ID3DXInclude
*iface
, const void *data
)
321 HeapFree(GetProcessHeap(), 0, *((char **)data
- 1));
322 HeapFree(GetProcessHeap(), 0, (char **)data
- 1);
323 if (main_file_data
== data
)
324 main_file_data
= NULL
;
328 const struct ID3DXIncludeVtbl d3dx_include_from_file_vtbl
=
330 d3dx_include_from_file_open
,
331 d3dx_include_from_file_close
334 HRESULT WINAPI
D3DXAssembleShaderFromFileA(const char *filename
, const D3DXMACRO
*defines
,
335 ID3DXInclude
*include
, DWORD flags
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
341 TRACE("filename %s, defines %p, include %p, flags %#lx, shader %p, error_messages %p.\n",
342 debugstr_a(filename
), defines
, include
, flags
, shader
, error_messages
);
344 if (!filename
) return D3DXERR_INVALIDDATA
;
346 len
= MultiByteToWideChar(CP_ACP
, 0, filename
, -1, NULL
, 0);
347 filename_w
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
348 if (!filename_w
) return E_OUTOFMEMORY
;
349 MultiByteToWideChar(CP_ACP
, 0, filename
, -1, filename_w
, len
);
351 ret
= D3DXAssembleShaderFromFileW(filename_w
, defines
, include
, flags
, shader
, error_messages
);
353 HeapFree(GetProcessHeap(), 0, filename_w
);
357 HRESULT WINAPI
D3DXAssembleShaderFromFileW(const WCHAR
*filename
, const D3DXMACRO
*defines
,
358 ID3DXInclude
*include
, DWORD flags
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
360 struct d3dx_include_from_file include_from_file
;
366 TRACE("filename %s, defines %p, include %p, flags %#lx, shader %p, error_messages %p.\n",
367 debugstr_w(filename
), defines
, include
, flags
, shader
, error_messages
);
371 include_from_file
.ID3DXInclude_iface
.lpVtbl
= &d3dx_include_from_file_vtbl
;
372 include
= &include_from_file
.ID3DXInclude_iface
;
375 len
= WideCharToMultiByte(CP_ACP
, 0, filename
, -1, NULL
, 0, NULL
, NULL
);
376 filename_a
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(char));
378 return E_OUTOFMEMORY
;
379 WideCharToMultiByte(CP_ACP
, 0, filename
, -1, filename_a
, len
, NULL
, NULL
);
381 EnterCriticalSection(&from_file_mutex
);
382 hr
= ID3DXInclude_Open(include
, D3DXINC_LOCAL
, filename_a
, NULL
, &buffer
, &len
);
385 LeaveCriticalSection(&from_file_mutex
);
386 HeapFree(GetProcessHeap(), 0, filename_a
);
387 return D3DXERR_INVALIDDATA
;
390 hr
= D3DXAssembleShader(buffer
, len
, defines
, include
, flags
, shader
, error_messages
);
392 ID3DXInclude_Close(include
, buffer
);
393 LeaveCriticalSection(&from_file_mutex
);
394 HeapFree(GetProcessHeap(), 0, filename_a
);
398 HRESULT WINAPI
D3DXAssembleShaderFromResourceA(HMODULE module
, const char *resource
, const D3DXMACRO
*defines
,
399 ID3DXInclude
*include
, DWORD flags
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
405 TRACE("module %p, resource %s, defines %p, include %p, flags %#lx, shader %p, error_messages %p.\n",
406 module
, debugstr_a(resource
), defines
, include
, flags
, shader
, error_messages
);
408 if (!(res
= FindResourceA(module
, resource
, (const char *)RT_RCDATA
)))
409 return D3DXERR_INVALIDDATA
;
410 if (FAILED(load_resource_into_memory(module
, res
, &buffer
, &len
)))
411 return D3DXERR_INVALIDDATA
;
412 return D3DXAssembleShader(buffer
, len
, defines
, include
, flags
,
413 shader
, error_messages
);
416 HRESULT WINAPI
D3DXAssembleShaderFromResourceW(HMODULE module
, const WCHAR
*resource
, const D3DXMACRO
*defines
,
417 ID3DXInclude
*include
, DWORD flags
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
423 TRACE("module %p, resource %s, defines %p, include %p, flags %#lx, shader %p, error_messages %p.\n",
424 module
, debugstr_w(resource
), defines
, include
, flags
, shader
, error_messages
);
426 if (!(res
= FindResourceW(module
, resource
, (const WCHAR
*)RT_RCDATA
)))
427 return D3DXERR_INVALIDDATA
;
428 if (FAILED(load_resource_into_memory(module
, res
, &buffer
, &len
)))
429 return D3DXERR_INVALIDDATA
;
430 return D3DXAssembleShader(buffer
, len
, defines
, include
, flags
,
431 shader
, error_messages
);
434 HRESULT WINAPI
D3DXCompileShader(const char *data
, UINT length
, const D3DXMACRO
*defines
,
435 ID3DXInclude
*include
, const char *function
, const char *profile
, DWORD flags
,
436 ID3DXBuffer
**shader
, ID3DXBuffer
**error_msgs
, ID3DXConstantTable
**constant_table
)
440 TRACE("data %s, length %u, defines %p, include %p, function %s, profile %s, "
441 "flags %#lx, shader %p, error_msgs %p, constant_table %p.\n",
442 debugstr_a(data
), length
, defines
, include
, debugstr_a(function
), debugstr_a(profile
),
443 flags
, shader
, error_msgs
, constant_table
);
445 if (D3DX_SDK_VERSION
<= 36)
446 flags
|= D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY
;
448 hr
= D3DCompile(data
, length
, NULL
, (D3D_SHADER_MACRO
*)defines
, (ID3DInclude
*)include
,
449 function
, profile
, flags
, 0, (ID3DBlob
**)shader
, (ID3DBlob
**)error_msgs
);
451 if (SUCCEEDED(hr
) && constant_table
)
453 hr
= D3DXGetShaderConstantTable(ID3DXBuffer_GetBufferPointer(*shader
), constant_table
);
456 ID3DXBuffer_Release(*shader
);
464 HRESULT WINAPI
D3DXCompileShaderFromFileA(const char *filename
, const D3DXMACRO
*defines
,
465 ID3DXInclude
*include
, const char *entrypoint
, const char *profile
, DWORD flags
,
466 ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
, ID3DXConstantTable
**constant_table
)
472 TRACE("filename %s, defines %p, include %p, entrypoint %s, profile %s, "
473 "flags %#lx, shader %p, error_messages %p, constant_table %p.\n",
474 debugstr_a(filename
), defines
, include
, debugstr_a(entrypoint
),
475 debugstr_a(profile
), flags
, shader
, error_messages
, constant_table
);
477 if (!filename
) return D3DXERR_INVALIDDATA
;
479 len
= MultiByteToWideChar(CP_ACP
, 0, filename
, -1, NULL
, 0);
480 filename_w
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
481 if (!filename_w
) return E_OUTOFMEMORY
;
482 MultiByteToWideChar(CP_ACP
, 0, filename
, -1, filename_w
, len
);
484 ret
= D3DXCompileShaderFromFileW(filename_w
, defines
, include
,
485 entrypoint
, profile
, flags
,
486 shader
, error_messages
, constant_table
);
488 HeapFree(GetProcessHeap(), 0, filename_w
);
492 HRESULT WINAPI
D3DXCompileShaderFromFileW(const WCHAR
*filename
, const D3DXMACRO
*defines
,
493 ID3DXInclude
*include
, const char *entrypoint
, const char *profile
, DWORD flags
,
494 ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
, ID3DXConstantTable
**constant_table
)
496 struct d3dx_include_from_file include_from_file
;
497 unsigned int filename_len
;
503 TRACE("filename %s, defines %p, include %p, entrypoint %s, profile %s, "
504 "flags %#lx, shader %p, error_messages %p, constant_table %p.\n",
505 debugstr_w(filename
), defines
, include
, debugstr_a(entrypoint
), debugstr_a(profile
),
506 flags
, shader
, error_messages
, constant_table
);
510 include_from_file
.ID3DXInclude_iface
.lpVtbl
= &d3dx_include_from_file_vtbl
;
511 include
= &include_from_file
.ID3DXInclude_iface
;
514 filename_len
= WideCharToMultiByte(CP_ACP
, 0, filename
, -1, NULL
, 0, NULL
, NULL
);
515 filename_a
= HeapAlloc(GetProcessHeap(), 0, filename_len
* sizeof(char));
517 return E_OUTOFMEMORY
;
518 WideCharToMultiByte(CP_ACP
, 0, filename
, -1, filename_a
, filename_len
, NULL
, NULL
);
520 EnterCriticalSection(&from_file_mutex
);
521 hr
= ID3DXInclude_Open(include
, D3DXINC_LOCAL
, filename_a
, NULL
, &buffer
, &len
);
524 LeaveCriticalSection(&from_file_mutex
);
525 HeapFree(GetProcessHeap(), 0, filename_a
);
526 return D3DXERR_INVALIDDATA
;
529 if (D3DX_SDK_VERSION
<= 36)
530 flags
|= D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY
;
532 hr
= D3DCompile(buffer
, len
, filename_a
, (const D3D_SHADER_MACRO
*)defines
,
533 (ID3DInclude
*)include
, entrypoint
, profile
, flags
, 0,
534 (ID3DBlob
**)shader
, (ID3DBlob
**)error_messages
);
536 if (SUCCEEDED(hr
) && constant_table
)
537 hr
= D3DXGetShaderConstantTable(ID3DXBuffer_GetBufferPointer(*shader
),
540 ID3DXInclude_Close(include
, buffer
);
541 LeaveCriticalSection(&from_file_mutex
);
542 HeapFree(GetProcessHeap(), 0, filename_a
);
546 HRESULT WINAPI
D3DXCompileShaderFromResourceA(HMODULE module
, const char *resource
, const D3DXMACRO
*defines
,
547 ID3DXInclude
*include
, const char *entrypoint
, const char *profile
, DWORD flags
,
548 ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
, ID3DXConstantTable
**constant_table
)
554 TRACE("module %p, resource %s, defines %p, include %p, entrypoint %s, profile %s, "
555 "flags %#lx, shader %p, error_messages %p, constant_table %p.\n",
556 module
, debugstr_a(resource
), defines
, include
, debugstr_a(entrypoint
), debugstr_a(profile
),
557 flags
, shader
, error_messages
, constant_table
);
559 if (!(res
= FindResourceA(module
, resource
, (const char *)RT_RCDATA
)))
560 return D3DXERR_INVALIDDATA
;
561 if (FAILED(load_resource_into_memory(module
, res
, &buffer
, &len
)))
562 return D3DXERR_INVALIDDATA
;
563 return D3DXCompileShader(buffer
, len
, defines
, include
, entrypoint
, profile
,
564 flags
, shader
, error_messages
, constant_table
);
567 HRESULT WINAPI
D3DXCompileShaderFromResourceW(HMODULE module
, const WCHAR
*resource
, const D3DXMACRO
*defines
,
568 ID3DXInclude
*include
, const char *entrypoint
, const char *profile
, DWORD flags
,
569 ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
, ID3DXConstantTable
**constant_table
)
575 TRACE("module %p, resource %s, defines %p, include %p, entrypoint %s, profile %s, "
576 "flags %#lx, shader %p, error_messages %p, constant_table %p.\n",
577 module
, debugstr_w(resource
), defines
, include
, debugstr_a(entrypoint
), debugstr_a(profile
),
578 flags
, shader
, error_messages
, constant_table
);
580 if (!(res
= FindResourceW(module
, resource
, (const WCHAR
*)RT_RCDATA
)))
581 return D3DXERR_INVALIDDATA
;
582 if (FAILED(load_resource_into_memory(module
, res
, &buffer
, &len
)))
583 return D3DXERR_INVALIDDATA
;
584 return D3DXCompileShader(buffer
, len
, defines
, include
, entrypoint
, profile
,
585 flags
, shader
, error_messages
, constant_table
);
588 HRESULT WINAPI
D3DXPreprocessShader(const char *data
, UINT data_len
, const D3DXMACRO
*defines
,
589 ID3DXInclude
*include
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
591 TRACE("data %s, data_len %u, defines %p, include %p, shader %p, error_messages %p.\n",
592 debugstr_a(data
), data_len
, defines
, include
, shader
, error_messages
);
594 return D3DPreprocess(data
, data_len
, NULL
,
595 (const D3D_SHADER_MACRO
*)defines
, (ID3DInclude
*)include
,
596 (ID3DBlob
**)shader
, (ID3DBlob
**)error_messages
);
599 HRESULT WINAPI
D3DXPreprocessShaderFromFileA(const char *filename
, const D3DXMACRO
*defines
,
600 ID3DXInclude
*include
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
602 WCHAR
*filename_w
= NULL
;
606 TRACE("filename %s, defines %p, include %p, shader %p, error_messages %p.\n",
607 debugstr_a(filename
), defines
, include
, shader
, error_messages
);
609 if (!filename
) return D3DXERR_INVALIDDATA
;
611 len
= MultiByteToWideChar(CP_ACP
, 0, filename
, -1, NULL
, 0);
612 filename_w
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
613 if (!filename_w
) return E_OUTOFMEMORY
;
614 MultiByteToWideChar(CP_ACP
, 0, filename
, -1, filename_w
, len
);
616 ret
= D3DXPreprocessShaderFromFileW(filename_w
, defines
, include
, shader
, error_messages
);
618 HeapFree(GetProcessHeap(), 0, filename_w
);
622 HRESULT WINAPI
D3DXPreprocessShaderFromFileW(const WCHAR
*filename
, const D3DXMACRO
*defines
,
623 ID3DXInclude
*include
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
625 struct d3dx_include_from_file include_from_file
;
631 TRACE("filename %s, defines %p, include %p, shader %p, error_messages %p.\n",
632 debugstr_w(filename
), defines
, include
, shader
, error_messages
);
636 include_from_file
.ID3DXInclude_iface
.lpVtbl
= &d3dx_include_from_file_vtbl
;
637 include
= &include_from_file
.ID3DXInclude_iface
;
640 len
= WideCharToMultiByte(CP_ACP
, 0, filename
, -1, NULL
, 0, NULL
, NULL
);
641 filename_a
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(char));
643 return E_OUTOFMEMORY
;
644 WideCharToMultiByte(CP_ACP
, 0, filename
, -1, filename_a
, len
, NULL
, NULL
);
646 EnterCriticalSection(&from_file_mutex
);
647 hr
= ID3DXInclude_Open(include
, D3DXINC_LOCAL
, filename_a
, NULL
, &buffer
, &len
);
650 LeaveCriticalSection(&from_file_mutex
);
651 HeapFree(GetProcessHeap(), 0, filename_a
);
652 return D3DXERR_INVALIDDATA
;
655 hr
= D3DPreprocess(buffer
, len
, NULL
,
656 (const D3D_SHADER_MACRO
*)defines
,
657 (ID3DInclude
*) include
,
658 (ID3DBlob
**)shader
, (ID3DBlob
**)error_messages
);
660 ID3DXInclude_Close(include
, buffer
);
661 LeaveCriticalSection(&from_file_mutex
);
662 HeapFree(GetProcessHeap(), 0, filename_a
);
666 HRESULT WINAPI
D3DXPreprocessShaderFromResourceA(HMODULE module
, const char *resource
, const D3DXMACRO
*defines
,
667 ID3DXInclude
*include
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
673 TRACE("module %p, resource %s, defines %p, include %p, shader %p, error_messages %p.\n",
674 module
, debugstr_a(resource
), defines
, include
, shader
, error_messages
);
676 if (!(res
= FindResourceA(module
, resource
, (const char *)RT_RCDATA
)))
677 return D3DXERR_INVALIDDATA
;
678 if (FAILED(load_resource_into_memory(module
, res
, &buffer
, &len
)))
679 return D3DXERR_INVALIDDATA
;
680 return D3DXPreprocessShader(buffer
, len
, defines
, include
,
681 shader
, error_messages
);
684 HRESULT WINAPI
D3DXPreprocessShaderFromResourceW(HMODULE module
, const WCHAR
*resource
, const D3DXMACRO
*defines
,
685 ID3DXInclude
*include
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
691 TRACE("module %p, resource %s, defines %p, include %p, shader %p, error_messages %p.\n",
692 module
, debugstr_w(resource
), defines
, include
, shader
, error_messages
);
694 if (!(res
= FindResourceW(module
, resource
, (const WCHAR
*)RT_RCDATA
)))
695 return D3DXERR_INVALIDDATA
;
696 if (FAILED(load_resource_into_memory(module
, res
, &buffer
, &len
)))
697 return D3DXERR_INVALIDDATA
;
698 return D3DXPreprocessShader(buffer
, len
, defines
, include
,
699 shader
, error_messages
);
703 struct ID3DXConstantTableImpl
705 ID3DXConstantTable ID3DXConstantTable_iface
;
710 D3DXCONSTANTTABLE_DESC desc
;
711 struct ctab_constant
*constants
;
714 static void free_constant(struct ctab_constant
*constant
)
716 if (constant
->constants
)
718 UINT i
, count
= constant
->desc
.Elements
> 1 ? constant
->desc
.Elements
: constant
->desc
.StructMembers
;
720 for (i
= 0; i
< count
; ++i
)
722 free_constant(&constant
->constants
[i
]);
724 HeapFree(GetProcessHeap(), 0, constant
->constants
);
728 static void free_constant_table(struct ID3DXConstantTableImpl
*table
)
730 if (table
->constants
)
734 for (i
= 0; i
< table
->desc
.Constants
; ++i
)
736 free_constant(&table
->constants
[i
]);
738 HeapFree(GetProcessHeap(), 0, table
->constants
);
740 HeapFree(GetProcessHeap(), 0, table
->ctab
);
743 static inline struct ID3DXConstantTableImpl
*impl_from_ID3DXConstantTable(ID3DXConstantTable
*iface
)
745 return CONTAINING_RECORD(iface
, struct ID3DXConstantTableImpl
, ID3DXConstantTable_iface
);
748 static inline BOOL
is_vertex_shader(DWORD version
)
750 return (version
& 0xffff0000) == 0xfffe0000;
753 static inline D3DXHANDLE
handle_from_constant(struct ctab_constant
*constant
)
755 return (D3DXHANDLE
)constant
;
758 static struct ctab_constant
*get_constant_by_name(struct ID3DXConstantTableImpl
*table
,
759 struct ctab_constant
*constant
, const char *name
);
761 static struct ctab_constant
*get_constant_element_by_name(struct ctab_constant
*constant
, const char *name
)
766 TRACE("constant %p, name %s\n", constant
, debugstr_a(name
));
768 if (!name
|| !*name
) return NULL
;
770 element
= atoi(name
);
771 part
= strchr(name
, ']') + 1;
773 if (constant
->desc
.Elements
> element
)
775 struct ctab_constant
*c
= constant
->constants
? &constant
->constants
[element
] : constant
;
780 return get_constant_by_name(NULL
, c
, part
);
783 return get_constant_element_by_name(c
, part
);
786 TRACE("Returning parameter %p\n", c
);
790 FIXME("Unhandled case \"%c\"\n", *--part
);
795 TRACE("Constant not found\n");
799 static struct ctab_constant
*get_constant_by_name(struct ID3DXConstantTableImpl
*table
,
800 struct ctab_constant
*constant
, const char *name
)
802 UINT i
, count
, length
;
803 struct ctab_constant
*handles
;
806 TRACE("table %p, constant %p, name %s\n", table
, constant
, debugstr_a(name
));
808 if (!name
|| !*name
) return NULL
;
812 count
= table
->desc
.Constants
;
813 handles
= table
->constants
;
817 count
= constant
->desc
.StructMembers
;
818 handles
= constant
->constants
;
821 length
= strcspn(name
, "[.");
822 part
= name
+ length
;
824 for (i
= 0; i
< count
; i
++)
826 if (strlen(handles
[i
].desc
.Name
) == length
&& !strncmp(handles
[i
].desc
.Name
, name
, length
))
831 return get_constant_by_name(NULL
, &handles
[i
], part
);
834 return get_constant_element_by_name(&handles
[i
], part
);
837 TRACE("Returning parameter %p\n", &handles
[i
]);
843 TRACE("Constant not found\n");
847 static struct ctab_constant
*is_valid_sub_constant(struct ctab_constant
*parent
, D3DXHANDLE handle
)
849 struct ctab_constant
*c
;
852 /* all variable have at least elements = 1, but not always elements */
853 if (!parent
->constants
) return NULL
;
855 count
= parent
->desc
.Elements
> 1 ? parent
->desc
.Elements
: parent
->desc
.StructMembers
;
856 for (i
= 0; i
< count
; ++i
)
858 if (handle_from_constant(&parent
->constants
[i
]) == handle
)
859 return &parent
->constants
[i
];
861 c
= is_valid_sub_constant(&parent
->constants
[i
], handle
);
868 static inline struct ctab_constant
*get_valid_constant(struct ID3DXConstantTableImpl
*table
, D3DXHANDLE handle
)
870 struct ctab_constant
*c
;
873 if (!handle
) return NULL
;
875 for (i
= 0; i
< table
->desc
.Constants
; ++i
)
877 if (handle_from_constant(&table
->constants
[i
]) == handle
)
878 return &table
->constants
[i
];
880 c
= is_valid_sub_constant(&table
->constants
[i
], handle
);
884 if (table
->flags
& D3DXCONSTTABLE_LARGEADDRESSAWARE
)
887 return get_constant_by_name(table
, NULL
, handle
);
890 /*** IUnknown methods ***/
891 static HRESULT WINAPI
ID3DXConstantTableImpl_QueryInterface(ID3DXConstantTable
*iface
, REFIID riid
, void **out
)
893 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
895 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
896 IsEqualGUID(riid
, &IID_ID3DXBuffer
) ||
897 IsEqualGUID(riid
, &IID_ID3DXConstantTable
))
899 ID3DXConstantTable_AddRef(iface
);
904 WARN("Interface %s not found.\n", debugstr_guid(riid
));
906 return E_NOINTERFACE
;
909 static ULONG WINAPI
ID3DXConstantTableImpl_AddRef(ID3DXConstantTable
*iface
)
911 struct ID3DXConstantTableImpl
*table
= impl_from_ID3DXConstantTable(iface
);
912 ULONG refcount
= InterlockedIncrement(&table
->ref
);
914 TRACE("%p increasing refcount to %lu.\n", table
, refcount
);
919 static ULONG WINAPI
ID3DXConstantTableImpl_Release(ID3DXConstantTable
*iface
)
921 struct ID3DXConstantTableImpl
*table
= impl_from_ID3DXConstantTable(iface
);
922 ULONG refcount
= InterlockedDecrement(&table
->ref
);
924 TRACE("%p decreasing refcount to %lu.\n", table
, refcount
);
928 free_constant_table(table
);
929 HeapFree(GetProcessHeap(), 0, table
);
935 /*** ID3DXBuffer methods ***/
936 static void * WINAPI
ID3DXConstantTableImpl_GetBufferPointer(ID3DXConstantTable
*iface
)
938 struct ID3DXConstantTableImpl
*table
= impl_from_ID3DXConstantTable(iface
);
940 TRACE("iface %p.\n", iface
);
945 static DWORD WINAPI
ID3DXConstantTableImpl_GetBufferSize(ID3DXConstantTable
*iface
)
947 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
949 TRACE("(%p)->()\n", This
);
954 /*** ID3DXConstantTable methods ***/
955 static HRESULT WINAPI
ID3DXConstantTableImpl_GetDesc(ID3DXConstantTable
*iface
, D3DXCONSTANTTABLE_DESC
*desc
)
957 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
959 TRACE("(%p)->(%p)\n", This
, desc
);
962 return D3DERR_INVALIDCALL
;
969 const struct ctab_constant
*d3dx_shader_get_ctab_constant(ID3DXConstantTable
*iface
, D3DXHANDLE constant
)
971 struct ID3DXConstantTableImpl
*ctab
= impl_from_ID3DXConstantTable(iface
);
973 return get_valid_constant(ctab
, constant
);
976 static HRESULT WINAPI
ID3DXConstantTableImpl_GetConstantDesc(ID3DXConstantTable
*iface
, D3DXHANDLE constant
,
977 D3DXCONSTANT_DESC
*desc
, UINT
*count
)
979 struct ID3DXConstantTableImpl
*ctab
= impl_from_ID3DXConstantTable(iface
);
980 struct ctab_constant
*c
= get_valid_constant(ctab
, constant
);
982 TRACE("(%p)->(%p, %p, %p)\n", ctab
, constant
, desc
, count
);
986 WARN("Invalid argument specified\n");
987 return D3DERR_INVALIDCALL
;
990 if (desc
) *desc
= c
->desc
;
991 if (count
) *count
= 1;
996 static UINT WINAPI
ID3DXConstantTableImpl_GetSamplerIndex(ID3DXConstantTable
*iface
, D3DXHANDLE constant
)
998 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
999 struct ctab_constant
*c
= get_valid_constant(This
, constant
);
1001 TRACE("(%p)->(%p)\n", This
, constant
);
1003 if (!c
|| c
->desc
.RegisterSet
!= D3DXRS_SAMPLER
)
1005 WARN("Invalid argument specified\n");
1009 TRACE("Returning RegisterIndex %u\n", c
->desc
.RegisterIndex
);
1010 return c
->desc
.RegisterIndex
;
1013 static D3DXHANDLE WINAPI
ID3DXConstantTableImpl_GetConstant(ID3DXConstantTable
*iface
, D3DXHANDLE constant
, UINT index
)
1015 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1016 struct ctab_constant
*c
;
1018 TRACE("(%p)->(%p, %d)\n", This
, constant
, index
);
1022 c
= get_valid_constant(This
, constant
);
1023 if (c
&& index
< c
->desc
.StructMembers
)
1025 c
= &c
->constants
[index
];
1026 TRACE("Returning constant %p\n", c
);
1027 return handle_from_constant(c
);
1032 if (index
< This
->desc
.Constants
)
1034 c
= &This
->constants
[index
];
1035 TRACE("Returning constant %p\n", c
);
1036 return handle_from_constant(c
);
1040 WARN("Index out of range\n");
1044 static D3DXHANDLE WINAPI
ID3DXConstantTableImpl_GetConstantByName(ID3DXConstantTable
*iface
,
1045 D3DXHANDLE constant
, const char *name
)
1047 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1048 struct ctab_constant
*c
= get_valid_constant(This
, constant
);
1050 TRACE("iface %p, constant %p, name %s.\n", iface
, constant
, debugstr_a(name
));
1052 c
= get_constant_by_name(This
, c
, name
);
1053 TRACE("Returning constant %p\n", c
);
1055 return handle_from_constant(c
);
1058 static D3DXHANDLE WINAPI
ID3DXConstantTableImpl_GetConstantElement(ID3DXConstantTable
*iface
, D3DXHANDLE constant
, UINT index
)
1060 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1061 struct ctab_constant
*c
= get_valid_constant(This
, constant
);
1063 TRACE("(%p)->(%p, %d)\n", This
, constant
, index
);
1065 if (c
&& index
< c
->desc
.Elements
)
1067 if (c
->desc
.Elements
> 1) c
= &c
->constants
[index
];
1068 TRACE("Returning constant %p\n", c
);
1069 return handle_from_constant(c
);
1072 WARN("Invalid argument specified\n");
1076 static inline DWORD
get_index(const void **indata
, UINT index
, BOOL is_pointer
)
1082 return ((DWORD
**)indata
)[index
/ 16][index
% 16];
1084 return (*((DWORD
**)indata
))[index
];
1087 static UINT
set(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
, struct ctab_constant
*constant
,
1088 const void **indata
, D3DXPARAMETER_TYPE intype
, UINT
*size
, UINT incol
, D3DXPARAMETER_CLASS inclass
, UINT index
,
1091 D3DXCONSTANT_DESC
*desc
= &constant
->desc
;
1092 UINT l
, i
, regcount
= 1, regsize
= 1, cin
= 1, rin
= 1, ret
, last
= 0;
1095 /* size too small to set anything */
1096 if (*size
< desc
->Rows
* desc
->Columns
)
1102 /* D3DXPC_STRUCT is somewhat special */
1103 if (desc
->Class
== D3DXPC_STRUCT
)
1106 * Struct array sets the last complete input to the first struct element, all other
1107 * elements are not set.
1108 * E.g.: struct {int i;} s1[2];
1109 * SetValue(device, "s1", [1, 2], 8) => s1 = {2, x};
1111 * struct {int i; int n} s2[2];
1112 * SetValue(device, "s2", [1, 2, 3, 4, 5], 20) => s1 = {{3, 4}, {x, x}};
1114 if (desc
->Elements
> 1)
1116 UINT offset
= *size
/ (desc
->Rows
* desc
->Columns
) - 1;
1118 offset
= min(desc
->Elements
- 1, offset
);
1119 last
= offset
* desc
->Rows
* desc
->Columns
;
1121 if ((is_pointer
|| inclass
== D3DXPC_MATRIX_ROWS
) && desc
->RegisterSet
!= D3DXRS_BOOL
)
1123 set(table
, device
, &constant
->constants
[0], NULL
, intype
, size
, incol
, inclass
, 0, is_pointer
);
1127 last
+= set(table
, device
, &constant
->constants
[0], indata
, intype
, size
, incol
, inclass
,
1128 index
+ last
, is_pointer
);
1134 * D3DXRS_BOOL is always set. As there are only 16 bools and there are
1135 * exactly 16 input values, use matrix transpose.
1137 if (inclass
== D3DXPC_MATRIX_ROWS
&& desc
->RegisterSet
== D3DXRS_BOOL
)
1139 D3DXMATRIX mat
, *m
, min
;
1142 min
= *(D3DXMATRIX
*)(indata
[index
/ 16]);
1144 min
= **(D3DXMATRIX
**)indata
;
1146 D3DXMatrixTranspose(&mat
, &min
);
1148 for (i
= 0; i
< desc
->StructMembers
; ++i
)
1150 last
+= set(table
, device
, &constant
->constants
[i
], (const void **)&m
, intype
, size
, incol
,
1151 D3DXPC_SCALAR
, index
+ last
, is_pointer
);
1155 * For pointers or for matrix rows, only the first member is set.
1156 * All other members are set to 0. This is not true for D3DXRS_BOOL.
1157 * E.g.: struct {int i; int n} s;
1158 * SetValue(device, "s", [1, 2], 8) => s = {1, 0};
1160 else if ((is_pointer
|| inclass
== D3DXPC_MATRIX_ROWS
) && desc
->RegisterSet
!= D3DXRS_BOOL
)
1162 last
= set(table
, device
, &constant
->constants
[0], indata
, intype
, size
, incol
, inclass
,
1163 index
+ last
, is_pointer
);
1165 for (i
= 1; i
< desc
->StructMembers
; ++i
)
1167 set(table
, device
, &constant
->constants
[i
], NULL
, intype
, size
, incol
, inclass
, 0, is_pointer
);
1172 for (i
= 0; i
< desc
->StructMembers
; ++i
)
1174 last
+= set(table
, device
, &constant
->constants
[i
], indata
, intype
, size
, incol
, D3DXPC_SCALAR
,
1175 index
+ last
, is_pointer
);
1184 if (desc
->Elements
> 1)
1186 for (i
= 0; i
< desc
->Elements
&& *size
> 0; ++i
)
1188 last
+= set(table
, device
, &constant
->constants
[i
], indata
, intype
, size
, incol
, inclass
,
1189 index
+ last
, is_pointer
);
1191 /* adjust the vector size for matrix rows */
1192 if (inclass
== D3DXPC_MATRIX_ROWS
&& desc
->Class
== D3DXPC_VECTOR
&& (i
% 4) == 3)
1195 *size
= *size
< 12 ? 0 : *size
- 12;
1202 switch (desc
->Class
)
1206 case D3DXPC_MATRIX_ROWS
:
1207 regcount
= min(desc
->RegisterCount
, desc
->Rows
);
1208 if (inclass
== D3DXPC_MATRIX_ROWS
) cin
= incol
;
1210 regsize
= desc
->Columns
;
1213 case D3DXPC_MATRIX_COLUMNS
:
1214 regcount
= min(desc
->RegisterCount
, desc
->Columns
);
1215 if (inclass
== D3DXPC_MATRIX_ROWS
) rin
= incol
;
1217 regsize
= desc
->Rows
;
1221 FIXME("Unhandled variable class %s\n", debug_d3dxparameter_class(desc
->Class
));
1225 /* specific stuff for different in types */
1229 ret
= desc
->Columns
* desc
->Rows
;
1230 *size
-= desc
->Columns
* desc
->Rows
;
1234 switch (desc
->Class
)
1236 case D3DXPC_MATRIX_ROWS
:
1237 if (*size
< regcount
* 4)
1243 *size
-= 4 * regcount
;
1246 case D3DXPC_MATRIX_COLUMNS
:
1248 *size
-= 4 * regcount
;
1262 FIXME("Unhandled variable class %s\n", debug_d3dxparameter_class(desc
->Class
));
1267 case D3DXPC_MATRIX_ROWS
:
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
));
1295 case D3DXPC_MATRIX_COLUMNS
:
1296 switch (desc
->Class
)
1298 case D3DXPC_MATRIX_ROWS
:
1299 case D3DXPC_MATRIX_COLUMNS
:
1317 FIXME("Unhandled variable class %s\n", debug_d3dxparameter_class(desc
->Class
));
1324 FIXME("Unhandled variable class %s\n", debug_d3dxparameter_class(inclass
));
1328 /* set the registers */
1329 switch (desc
->RegisterSet
)
1332 regcount
= min(desc
->RegisterCount
, desc
->Columns
* desc
->Rows
);
1334 for (i
= 0; i
< regcount
; ++i
)
1337 DWORD t
= get_index(indata
, index
+ i
/ regsize
* rin
+ l
* cin
, is_pointer
);
1339 set_number(&tmp
, desc
->Type
, &t
, intype
);
1340 set_number(&out
, D3DXPT_BOOL
, &tmp
, desc
->Type
);
1341 if (is_vertex_shader(table
->desc
.Version
))
1342 IDirect3DDevice9_SetVertexShaderConstantB(device
, desc
->RegisterIndex
+ i
, &out
, 1);
1344 IDirect3DDevice9_SetPixelShaderConstantB(device
, desc
->RegisterIndex
+ i
, &out
, 1);
1346 if (++l
>= regsize
) l
= 0;
1351 for (i
= 0; i
< regcount
; ++i
)
1353 INT vec
[4] = {0, 0, 1, 0};
1355 for (l
= 0; l
< regsize
; ++l
)
1357 DWORD t
= get_index(indata
, index
+ i
* rin
+ l
* cin
, is_pointer
);
1359 set_number(&tmp
, desc
->Type
, &t
, intype
);
1360 set_number(&vec
[l
], D3DXPT_INT
, &tmp
, desc
->Type
);
1362 if (is_vertex_shader(table
->desc
.Version
))
1363 IDirect3DDevice9_SetVertexShaderConstantI(device
, desc
->RegisterIndex
+ i
, vec
, 1);
1365 IDirect3DDevice9_SetPixelShaderConstantI(device
, desc
->RegisterIndex
+ i
, vec
, 1);
1370 for (i
= 0; i
< regcount
; ++i
)
1374 for (l
= 0; l
< regsize
; ++l
)
1376 DWORD t
= get_index(indata
, index
+ i
* rin
+ l
* cin
, is_pointer
);
1378 set_number(&tmp
, desc
->Type
, &t
, intype
);
1379 set_number(&vec
[l
], D3DXPT_FLOAT
, &tmp
, desc
->Type
);
1381 if (is_vertex_shader(table
->desc
.Version
))
1382 IDirect3DDevice9_SetVertexShaderConstantF(device
, desc
->RegisterIndex
+ i
, vec
, 1);
1384 IDirect3DDevice9_SetPixelShaderConstantF(device
, desc
->RegisterIndex
+ i
, vec
, 1);
1389 FIXME("Unhandled register set %s\n", debug_d3dxparameter_registerset(desc
->RegisterSet
));
1394 static HRESULT
set_scalar(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
, D3DXHANDLE constant
,
1395 const void *indata
, D3DXPARAMETER_TYPE intype
)
1397 struct ctab_constant
*c
= get_valid_constant(table
, constant
);
1402 WARN("Invalid argument specified\n");
1403 return D3DERR_INVALIDCALL
;
1406 switch (c
->desc
.Class
)
1409 set(table
, device
, c
, &indata
, intype
, &count
, c
->desc
.Columns
, D3DXPC_SCALAR
, 0, FALSE
);
1413 case D3DXPC_MATRIX_ROWS
:
1414 case D3DXPC_MATRIX_COLUMNS
:
1419 FIXME("Unhandled parameter class %s\n", debug_d3dxparameter_class(c
->desc
.Class
));
1420 return D3DERR_INVALIDCALL
;
1424 static HRESULT
set_scalar_array(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
, D3DXHANDLE constant
,
1425 const void *indata
, UINT count
, D3DXPARAMETER_TYPE intype
)
1427 struct ctab_constant
*c
= get_valid_constant(table
, constant
);
1431 WARN("Invalid argument specified\n");
1432 return D3DERR_INVALIDCALL
;
1435 switch (c
->desc
.Class
)
1439 case D3DXPC_MATRIX_ROWS
:
1440 case D3DXPC_MATRIX_COLUMNS
:
1442 set(table
, device
, c
, &indata
, intype
, &count
, c
->desc
.Columns
, D3DXPC_SCALAR
, 0, FALSE
);
1446 FIXME("Unhandled parameter class %s\n", debug_d3dxparameter_class(c
->desc
.Class
));
1447 return D3DERR_INVALIDCALL
;
1451 static HRESULT
set_vector(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
, D3DXHANDLE constant
,
1452 const void *indata
, D3DXPARAMETER_TYPE intype
)
1454 struct ctab_constant
*c
= get_valid_constant(table
, constant
);
1459 WARN("Invalid argument specified\n");
1460 return D3DERR_INVALIDCALL
;
1463 switch (c
->desc
.Class
)
1468 set(table
, device
, c
, &indata
, intype
, &count
, 4, D3DXPC_VECTOR
, 0, FALSE
);
1471 case D3DXPC_MATRIX_ROWS
:
1472 case D3DXPC_MATRIX_COLUMNS
:
1476 FIXME("Unhandled parameter class %s\n", debug_d3dxparameter_class(c
->desc
.Class
));
1477 return D3DERR_INVALIDCALL
;
1481 static HRESULT
set_vector_array(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
, D3DXHANDLE constant
,
1482 const void *indata
, UINT count
, D3DXPARAMETER_TYPE intype
)
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
, intype
, &count
, 4, D3DXPC_VECTOR
, 0, FALSE
);
1504 FIXME("Unhandled parameter class %s\n", debug_d3dxparameter_class(c
->desc
.Class
));
1505 return D3DERR_INVALIDCALL
;
1509 static HRESULT
set_matrix_array(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
, D3DXHANDLE constant
,
1510 const void *indata
, UINT count
, BOOL transpose
)
1512 struct ctab_constant
*c
= get_valid_constant(table
, constant
);
1516 WARN("Invalid argument specified\n");
1517 return D3DERR_INVALIDCALL
;
1520 switch (c
->desc
.Class
)
1524 case D3DXPC_MATRIX_ROWS
:
1525 case D3DXPC_MATRIX_COLUMNS
:
1528 set(table
, device
, c
, &indata
, D3DXPT_FLOAT
, &count
, 4,
1529 transpose
? D3DXPC_MATRIX_ROWS
: D3DXPC_MATRIX_COLUMNS
, 0, FALSE
);
1533 FIXME("Unhandled parameter class %s\n", debug_d3dxparameter_class(c
->desc
.Class
));
1534 return D3DERR_INVALIDCALL
;
1538 static HRESULT
set_matrix_pointer_array(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
,
1539 D3DXHANDLE constant
, const void **indata
, UINT count
, BOOL transpose
)
1541 struct ctab_constant
*c
= get_valid_constant(table
, constant
);
1545 WARN("Invalid argument specified\n");
1546 return D3DERR_INVALIDCALL
;
1549 switch (c
->desc
.Class
)
1553 case D3DXPC_MATRIX_ROWS
:
1554 case D3DXPC_MATRIX_COLUMNS
:
1557 set(table
, device
, c
, indata
, D3DXPT_FLOAT
, &count
, 4,
1558 transpose
? D3DXPC_MATRIX_ROWS
: D3DXPC_MATRIX_COLUMNS
, 0, TRUE
);
1562 FIXME("Unhandled parameter class %s\n", debug_d3dxparameter_class(c
->desc
.Class
));
1563 return D3DERR_INVALIDCALL
;
1567 static HRESULT WINAPI
ID3DXConstantTableImpl_SetDefaults(struct ID3DXConstantTable
*iface
,
1568 struct IDirect3DDevice9
*device
)
1570 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1573 TRACE("iface %p, device %p\n", iface
, device
);
1577 WARN("Invalid argument specified\n");
1578 return D3DERR_INVALIDCALL
;
1581 for (i
= 0; i
< This
->desc
.Constants
; i
++)
1583 D3DXCONSTANT_DESC
*desc
= &This
->constants
[i
].desc
;
1586 if (!desc
->DefaultValue
)
1589 switch (desc
->RegisterSet
)
1592 if (is_vertex_shader(This
->desc
.Version
))
1593 hr
= IDirect3DDevice9_SetVertexShaderConstantB(device
, desc
->RegisterIndex
, desc
->DefaultValue
,
1594 desc
->RegisterCount
);
1596 hr
= IDirect3DDevice9_SetPixelShaderConstantB(device
, desc
->RegisterIndex
, desc
->DefaultValue
,
1597 desc
->RegisterCount
);
1601 if (is_vertex_shader(This
->desc
.Version
))
1602 hr
= IDirect3DDevice9_SetVertexShaderConstantI(device
, desc
->RegisterIndex
, desc
->DefaultValue
,
1603 desc
->RegisterCount
);
1605 hr
= IDirect3DDevice9_SetPixelShaderConstantI(device
, desc
->RegisterIndex
, desc
->DefaultValue
,
1606 desc
->RegisterCount
);
1610 if (is_vertex_shader(This
->desc
.Version
))
1611 hr
= IDirect3DDevice9_SetVertexShaderConstantF(device
, desc
->RegisterIndex
, desc
->DefaultValue
,
1612 desc
->RegisterCount
);
1614 hr
= IDirect3DDevice9_SetPixelShaderConstantF(device
, desc
->RegisterIndex
, desc
->DefaultValue
,
1615 desc
->RegisterCount
);
1619 FIXME("Unhandled register set %s\n", debug_d3dxparameter_registerset(desc
->RegisterSet
));
1631 static HRESULT WINAPI
ID3DXConstantTableImpl_SetValue(struct ID3DXConstantTable
*iface
,
1632 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const void *data
, unsigned int bytes
)
1634 struct ID3DXConstantTableImpl
*table
= impl_from_ID3DXConstantTable(iface
);
1635 struct ctab_constant
*c
= get_valid_constant(table
, constant
);
1636 D3DXCONSTANT_DESC
*desc
;
1638 TRACE("iface %p, device %p, constant %p, data %p, bytes %u\n", iface
, device
, constant
, data
, bytes
);
1640 if (!device
|| !c
|| !data
)
1642 WARN("Invalid argument specified\n");
1643 return D3DERR_INVALIDCALL
;
1648 switch (desc
->Class
)
1652 case D3DXPC_MATRIX_ROWS
:
1653 case D3DXPC_MATRIX_COLUMNS
:
1656 set(table
, device
, c
, &data
, desc
->Type
, &bytes
, desc
->Columns
, D3DXPC_SCALAR
, 0, FALSE
);
1660 FIXME("Unhandled parameter class %s\n", debug_d3dxparameter_class(desc
->Class
));
1661 return D3DERR_INVALIDCALL
;
1665 static HRESULT WINAPI
ID3DXConstantTableImpl_SetBool(struct ID3DXConstantTable
*iface
,
1666 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, BOOL b
)
1668 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1670 TRACE("iface %p, device %p, constant %p, b %d\n", iface
, device
, constant
, b
);
1672 return set_scalar(This
, device
, constant
, &b
, D3DXPT_BOOL
);
1675 static HRESULT WINAPI
ID3DXConstantTableImpl_SetBoolArray(struct ID3DXConstantTable
*iface
,
1676 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const BOOL
*b
, UINT count
)
1678 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1680 TRACE("iface %p, device %p, constant %p, b %p, count %d\n", iface
, device
, constant
, b
, count
);
1682 return set_scalar_array(This
, device
, constant
, b
, count
, D3DXPT_BOOL
);
1685 static HRESULT WINAPI
ID3DXConstantTableImpl_SetInt(struct ID3DXConstantTable
*iface
,
1686 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, INT n
)
1688 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1690 TRACE("iface %p, device %p, constant %p, n %d\n", iface
, device
, constant
, n
);
1692 return set_scalar(This
, device
, constant
, &n
, D3DXPT_INT
);
1695 static HRESULT WINAPI
ID3DXConstantTableImpl_SetIntArray(struct ID3DXConstantTable
*iface
,
1696 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const INT
*n
, UINT count
)
1698 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1700 TRACE("iface %p, device %p, constant %p, n %p, count %d\n", iface
, device
, constant
, n
, count
);
1702 return set_scalar_array(This
, device
, constant
, n
, count
, D3DXPT_INT
);
1705 static HRESULT WINAPI
ID3DXConstantTableImpl_SetFloat(struct ID3DXConstantTable
*iface
,
1706 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, float f
)
1708 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1710 TRACE("iface %p, device %p, constant %p, f %f\n", iface
, device
, constant
, f
);
1712 return set_scalar(This
, device
, constant
, &f
, D3DXPT_FLOAT
);
1715 static HRESULT WINAPI
ID3DXConstantTableImpl_SetFloatArray(struct ID3DXConstantTable
*iface
,
1716 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const float *f
, UINT count
)
1718 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1720 TRACE("iface %p, device %p, constant %p, f %p, count %d\n", iface
, device
, constant
, f
, count
);
1722 return set_scalar_array(This
, device
, constant
, f
, count
, D3DXPT_FLOAT
);
1725 static HRESULT WINAPI
ID3DXConstantTableImpl_SetVector(struct ID3DXConstantTable
*iface
,
1726 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXVECTOR4
*vector
)
1728 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1730 TRACE("iface %p, device %p, constant %p, vector %p\n", iface
, device
, constant
, vector
);
1732 return set_vector(This
, device
, constant
, vector
, D3DXPT_FLOAT
);
1735 static HRESULT WINAPI
ID3DXConstantTableImpl_SetVectorArray(struct ID3DXConstantTable
*iface
,
1736 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXVECTOR4
*vector
, UINT count
)
1738 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1740 TRACE("iface %p, device %p, constant %p, vector %p, count %u\n", iface
, device
, constant
, vector
, count
);
1742 return set_vector_array(This
, device
, constant
, vector
, count
, D3DXPT_FLOAT
);
1745 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrix(struct ID3DXConstantTable
*iface
,
1746 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXMATRIX
*matrix
)
1748 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1750 TRACE("iface %p, device %p, constant %p, matrix %p\n", iface
, device
, constant
, matrix
);
1752 return set_matrix_array(This
, device
, constant
, matrix
, 1, FALSE
);
1755 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrixArray(struct ID3DXConstantTable
*iface
,
1756 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXMATRIX
*matrix
, UINT count
)
1758 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1760 TRACE("iface %p, device %p, constant %p, matrix %p, count %u\n", iface
, device
, constant
, matrix
, count
);
1762 return set_matrix_array(This
, device
, constant
, matrix
, count
, FALSE
);
1765 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrixPointerArray(struct ID3DXConstantTable
*iface
,
1766 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXMATRIX
**matrix
, UINT count
)
1768 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1770 TRACE("iface %p, device %p, constant %p, matrix %p, count %u)\n", iface
, device
, constant
, matrix
, count
);
1772 return set_matrix_pointer_array(This
, device
, constant
, (const void **)matrix
, count
, FALSE
);
1775 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrixTranspose(struct ID3DXConstantTable
*iface
,
1776 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXMATRIX
*matrix
)
1778 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1780 TRACE("iface %p, device %p, constant %p, matrix %p\n", iface
, device
, constant
, matrix
);
1782 return set_matrix_array(This
, device
, constant
, matrix
, 1, TRUE
);
1785 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrixTransposeArray(struct ID3DXConstantTable
*iface
,
1786 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXMATRIX
*matrix
, UINT count
)
1788 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1790 TRACE("iface %p, device %p, constant %p, matrix %p, count %u\n", iface
, device
, constant
, matrix
, count
);
1792 return set_matrix_array(This
, device
, constant
, matrix
, count
, TRUE
);
1795 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrixTransposePointerArray(struct ID3DXConstantTable
*iface
,
1796 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXMATRIX
**matrix
, UINT count
)
1798 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1800 TRACE("iface %p, device %p, constant %p, matrix %p, count %u)\n", iface
, device
, constant
, matrix
, count
);
1802 return set_matrix_pointer_array(This
, device
, constant
, (const void **)matrix
, count
, TRUE
);
1805 static const struct ID3DXConstantTableVtbl ID3DXConstantTable_Vtbl
=
1807 /*** IUnknown methods ***/
1808 ID3DXConstantTableImpl_QueryInterface
,
1809 ID3DXConstantTableImpl_AddRef
,
1810 ID3DXConstantTableImpl_Release
,
1811 /*** ID3DXBuffer methods ***/
1812 ID3DXConstantTableImpl_GetBufferPointer
,
1813 ID3DXConstantTableImpl_GetBufferSize
,
1814 /*** ID3DXConstantTable methods ***/
1815 ID3DXConstantTableImpl_GetDesc
,
1816 ID3DXConstantTableImpl_GetConstantDesc
,
1817 ID3DXConstantTableImpl_GetSamplerIndex
,
1818 ID3DXConstantTableImpl_GetConstant
,
1819 ID3DXConstantTableImpl_GetConstantByName
,
1820 ID3DXConstantTableImpl_GetConstantElement
,
1821 ID3DXConstantTableImpl_SetDefaults
,
1822 ID3DXConstantTableImpl_SetValue
,
1823 ID3DXConstantTableImpl_SetBool
,
1824 ID3DXConstantTableImpl_SetBoolArray
,
1825 ID3DXConstantTableImpl_SetInt
,
1826 ID3DXConstantTableImpl_SetIntArray
,
1827 ID3DXConstantTableImpl_SetFloat
,
1828 ID3DXConstantTableImpl_SetFloatArray
,
1829 ID3DXConstantTableImpl_SetVector
,
1830 ID3DXConstantTableImpl_SetVectorArray
,
1831 ID3DXConstantTableImpl_SetMatrix
,
1832 ID3DXConstantTableImpl_SetMatrixArray
,
1833 ID3DXConstantTableImpl_SetMatrixPointerArray
,
1834 ID3DXConstantTableImpl_SetMatrixTranspose
,
1835 ID3DXConstantTableImpl_SetMatrixTransposeArray
,
1836 ID3DXConstantTableImpl_SetMatrixTransposePointerArray
1839 static HRESULT
parse_ctab_constant_type(const char *ctab
, DWORD typeoffset
, struct ctab_constant
*constant
,
1840 BOOL is_element
, WORD index
, WORD max_index
, DWORD
*offset
, DWORD nameoffset
, UINT regset
)
1842 const D3DXSHADER_TYPEINFO
*type
= (LPD3DXSHADER_TYPEINFO
)(ctab
+ typeoffset
);
1843 const D3DXSHADER_STRUCTMEMBERINFO
*memberinfo
= NULL
;
1844 HRESULT hr
= D3D_OK
;
1848 constant
->desc
.DefaultValue
= offset
? ctab
+ *offset
: NULL
;
1849 constant
->desc
.Class
= type
->Class
;
1850 constant
->desc
.Type
= type
->Type
;
1851 constant
->desc
.Rows
= type
->Rows
;
1852 constant
->desc
.Columns
= type
->Columns
;
1853 constant
->desc
.Elements
= is_element
? 1 : type
->Elements
;
1854 constant
->desc
.StructMembers
= type
->StructMembers
;
1855 constant
->desc
.Name
= ctab
+ nameoffset
;
1856 constant
->desc
.RegisterSet
= regset
;
1857 constant
->desc
.RegisterIndex
= index
;
1859 TRACE("name %s, elements %u, index %u, defaultvalue %p, regset %s\n", constant
->desc
.Name
,
1860 constant
->desc
.Elements
, index
, constant
->desc
.DefaultValue
,
1861 debug_d3dxparameter_registerset(regset
));
1862 TRACE("class %s, type %s, rows %d, columns %d, elements %d, struct_members %d\n",
1863 debug_d3dxparameter_class(type
->Class
), debug_d3dxparameter_type(type
->Type
),
1864 type
->Rows
, type
->Columns
, type
->Elements
, type
->StructMembers
);
1866 if (type
->Elements
> 1 && !is_element
)
1868 count
= type
->Elements
;
1870 else if ((type
->Class
== D3DXPC_STRUCT
) && type
->StructMembers
)
1872 memberinfo
= (D3DXSHADER_STRUCTMEMBERINFO
*)(ctab
+ type
->StructMemberInfo
);
1873 count
= type
->StructMembers
;
1878 constant
->constants
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*constant
->constants
) * count
);
1879 if (!constant
->constants
)
1881 ERR("Out of memory\n");
1886 for (i
= 0; i
< count
; ++i
)
1888 hr
= parse_ctab_constant_type(ctab
, memberinfo
? memberinfo
[i
].TypeInfo
: typeoffset
,
1889 &constant
->constants
[i
], memberinfo
== NULL
, index
+ size
, max_index
, offset
,
1890 memberinfo
? memberinfo
[i
].Name
: nameoffset
, regset
);
1894 size
+= constant
->constants
[i
].desc
.RegisterCount
;
1899 WORD offsetdiff
= type
->Columns
* type
->Rows
;
1902 size
= type
->Columns
* type
->Rows
;
1907 fail
= type
->Class
!= D3DXPC_SCALAR
&& type
->Class
!= D3DXPC_VECTOR
1908 && type
->Class
!= D3DXPC_MATRIX_ROWS
&& type
->Class
!= D3DXPC_MATRIX_COLUMNS
;
1913 switch (type
->Class
)
1919 offsetdiff
= type
->Rows
* 4;
1922 case D3DXPC_MATRIX_ROWS
:
1923 offsetdiff
= type
->Rows
* 4;
1927 case D3DXPC_MATRIX_COLUMNS
:
1928 offsetdiff
= type
->Columns
* 4;
1929 size
= type
->Columns
;
1938 case D3DXRS_SAMPLER
:
1940 fail
= type
->Class
!= D3DXPC_OBJECT
;
1950 FIXME("Unhandled register set %s, type class %s\n", debug_d3dxparameter_registerset(regset
),
1951 debug_d3dxparameter_class(type
->Class
));
1954 /* offset in bytes => offsetdiff * sizeof(DWORD) */
1955 if (offset
) *offset
+= offsetdiff
* 4;
1958 constant
->desc
.RegisterCount
= max(0, min(max_index
- index
, size
));
1959 constant
->desc
.Bytes
= 4 * constant
->desc
.Elements
* type
->Rows
* type
->Columns
;
1964 if (constant
->constants
)
1966 for (i
= 0; i
< count
; ++i
)
1968 free_constant(&constant
->constants
[i
]);
1970 HeapFree(GetProcessHeap(), 0, constant
->constants
);
1971 constant
->constants
= NULL
;
1977 HRESULT WINAPI
D3DXGetShaderConstantTableEx(const DWORD
*byte_code
, DWORD flags
, ID3DXConstantTable
**constant_table
)
1979 struct ID3DXConstantTableImpl
*object
= NULL
;
1983 const D3DXSHADER_CONSTANTTABLE
*ctab_header
;
1984 const D3DXSHADER_CONSTANTINFO
*constant_info
;
1987 TRACE("byte_code %p, flags %#lx, constant_table %p.\n", byte_code
, flags
, constant_table
);
1990 *constant_table
= NULL
;
1992 if (!byte_code
|| !constant_table
)
1994 WARN("Invalid argument specified.\n");
1995 return D3DERR_INVALIDCALL
;
1998 if (!is_valid_bytecode(*byte_code
))
2000 WARN("Invalid byte_code specified.\n");
2004 if (flags
& ~D3DXCONSTTABLE_LARGEADDRESSAWARE
)
2005 FIXME("Flags %#lx not handled.\n", flags
);
2007 hr
= D3DXFindShaderComment(byte_code
, MAKEFOURCC('C','T','A','B'), &data
, &size
);
2010 WARN("CTAB not found.\n");
2011 return D3DXERR_INVALIDDATA
;
2014 if (size
< sizeof(*ctab_header
))
2016 WARN("Invalid CTAB size.\n");
2017 return D3DXERR_INVALIDDATA
;
2020 ctab_header
= (const D3DXSHADER_CONSTANTTABLE
*)data
;
2021 if (ctab_header
->Size
!= sizeof(*ctab_header
))
2023 WARN("Invalid D3DXSHADER_CONSTANTTABLE size.\n");
2024 return D3DXERR_INVALIDDATA
;
2027 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*object
));
2029 return E_OUTOFMEMORY
;
2031 object
->ID3DXConstantTable_iface
.lpVtbl
= &ID3DXConstantTable_Vtbl
;
2034 object
->ctab
= HeapAlloc(GetProcessHeap(), 0, size
);
2037 ERR("Out of memory\n");
2038 HeapFree(GetProcessHeap(), 0, object
);
2039 return E_OUTOFMEMORY
;
2041 object
->size
= size
;
2042 memcpy(object
->ctab
, data
, object
->size
);
2044 object
->flags
= flags
;
2045 object
->desc
.Creator
= ctab_header
->Creator
? object
->ctab
+ ctab_header
->Creator
: NULL
;
2046 object
->desc
.Version
= ctab_header
->Version
;
2047 object
->desc
.Constants
= ctab_header
->Constants
;
2048 TRACE("Creator %s, Version %#lx, Constants %u, Target %s.\n",
2049 debugstr_a(object
->desc
.Creator
), object
->desc
.Version
, object
->desc
.Constants
,
2050 debugstr_a(ctab_header
->Target
? object
->ctab
+ ctab_header
->Target
: NULL
));
2052 object
->constants
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
2053 sizeof(*object
->constants
) * object
->desc
.Constants
);
2054 if (!object
->constants
)
2056 ERR("Out of memory\n");
2061 constant_info
= (const D3DXSHADER_CONSTANTINFO
*)(object
->ctab
+ ctab_header
->ConstantInfo
);
2062 for (i
= 0; i
< ctab_header
->Constants
; i
++)
2064 DWORD offset
= constant_info
[i
].DefaultValue
;
2066 hr
= parse_ctab_constant_type(object
->ctab
, constant_info
[i
].TypeInfo
,
2067 &object
->constants
[i
], FALSE
, constant_info
[i
].RegisterIndex
,
2068 constant_info
[i
].RegisterIndex
+ constant_info
[i
].RegisterCount
,
2069 offset
? &offset
: NULL
, constant_info
[i
].Name
, constant_info
[i
].RegisterSet
);
2074 * Set the register count, it may differ for D3DXRS_INT4, because somehow
2075 * it makes the assumption that the register size is 1 instead of 4, so the
2076 * count is 4 times bigger. This holds true only for toplevel shader
2077 * constants. The count of elements and members is always based on a
2078 * register size of 4.
2080 if (object
->constants
[i
].desc
.RegisterSet
== D3DXRS_INT4
)
2082 object
->constants
[i
].desc
.RegisterCount
= constant_info
[i
].RegisterCount
;
2084 object
->constants
[i
].constantinfo_reserved
= constant_info
[i
].Reserved
;
2087 *constant_table
= &object
->ID3DXConstantTable_iface
;
2092 free_constant_table(object
);
2093 HeapFree(GetProcessHeap(), 0, object
);
2098 HRESULT WINAPI
D3DXGetShaderConstantTable(const DWORD
*byte_code
, ID3DXConstantTable
**constant_table
)
2100 TRACE("(%p, %p): Forwarded to D3DXGetShaderConstantTableEx\n", byte_code
, constant_table
);
2102 return D3DXGetShaderConstantTableEx(byte_code
, 0, constant_table
);
2105 struct d3dx9_fragment_linker
2107 ID3DXFragmentLinker ID3DXFragmentLinker_iface
;
2110 struct IDirect3DDevice9
*device
;
2114 static inline struct d3dx9_fragment_linker
*impl_from_ID3DXFragmentLinker(ID3DXFragmentLinker
*iface
)
2116 return CONTAINING_RECORD(iface
, struct d3dx9_fragment_linker
, ID3DXFragmentLinker_iface
);
2119 static HRESULT WINAPI
d3dx9_fragment_linker_QueryInterface(ID3DXFragmentLinker
*iface
, REFIID riid
, void **out
)
2121 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
2123 if (IsEqualGUID(riid
, &IID_IUnknown
)
2124 || IsEqualGUID(riid
, &IID_ID3DXFragmentLinker
))
2126 iface
->lpVtbl
->AddRef(iface
);
2131 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
2133 return E_NOINTERFACE
;
2136 static ULONG WINAPI
d3dx9_fragment_linker_AddRef(ID3DXFragmentLinker
*iface
)
2138 struct d3dx9_fragment_linker
*linker
= impl_from_ID3DXFragmentLinker(iface
);
2139 ULONG refcount
= InterlockedIncrement(&linker
->ref
);
2141 TRACE("%p increasing refcount to %lu.\n", linker
, refcount
);
2146 static ULONG WINAPI
d3dx9_fragment_linker_Release(ID3DXFragmentLinker
*iface
)
2148 struct d3dx9_fragment_linker
*linker
= impl_from_ID3DXFragmentLinker(iface
);
2149 ULONG refcount
= InterlockedDecrement(&linker
->ref
);
2151 TRACE("%p decreasing refcount to %lu.\n", linker
, refcount
);
2155 IDirect3DDevice9_Release(linker
->device
);
2162 static HRESULT WINAPI
d3dx9_fragment_linker_GetDevice(ID3DXFragmentLinker
*iface
, struct IDirect3DDevice9
**device
)
2164 struct d3dx9_fragment_linker
*linker
= impl_from_ID3DXFragmentLinker(iface
);
2166 TRACE("iface %p, device %p.\n", linker
, device
);
2170 WARN("Invalid argument supplied.\n");
2171 return D3DERR_INVALIDCALL
;
2174 IDirect3DDevice9_AddRef(linker
->device
);
2175 *device
= linker
->device
;
2176 TRACE("Returning device %p.\n", *device
);
2181 static UINT WINAPI
d3dx9_fragment_linker_GetNumberOfFragments(ID3DXFragmentLinker
*iface
)
2183 FIXME("iface %p: stub.\n", iface
);
2188 static D3DXHANDLE WINAPI
d3dx9_fragment_linker_GetFragmentHandleByIndex(ID3DXFragmentLinker
*iface
, UINT index
)
2190 FIXME("iface %p, index %u: stub.\n", iface
, index
);
2195 static D3DXHANDLE WINAPI
d3dx9_fragment_linker_GetFragmentHandleByName(ID3DXFragmentLinker
*iface
,
2198 FIXME("iface %p, name %s: stub.\n", iface
, debugstr_a(name
));
2203 static HRESULT WINAPI
d3dx9_fragment_linker_GetFragmentDesc(ID3DXFragmentLinker
*iface
, D3DXHANDLE name
,
2204 D3DXFRAGMENT_DESC
*desc
)
2206 FIXME("iface %p, name %p, desc %p: stub.\n", iface
, name
, desc
);
2211 static HRESULT WINAPI
d3dx9_fragment_linker_AddFragments(ID3DXFragmentLinker
*iface
, const DWORD
*fragments
)
2213 FIXME("iface %p, fragments %p: stub.\n", iface
, fragments
);
2218 static HRESULT WINAPI
d3dx9_fragment_linker_GetAllFragments(ID3DXFragmentLinker
*iface
, ID3DXBuffer
**buffer
)
2220 FIXME("iface %p, buffer %p: stub.\n", iface
, buffer
);
2225 static HRESULT WINAPI
d3dx9_fragment_linker_GetFragment(ID3DXFragmentLinker
*iface
, D3DXHANDLE name
,
2226 ID3DXBuffer
**buffer
)
2228 FIXME("iface %p, name %p, buffer %p: stub.\n", iface
, name
, buffer
);
2233 static HRESULT WINAPI
d3dx9_fragment_linker_LinkShader(ID3DXFragmentLinker
*iface
, const char *profile
,
2234 DWORD flags
, const D3DXHANDLE
*handles
, UINT fragment_count
, ID3DXBuffer
**buffer
,
2235 ID3DXBuffer
**errors
)
2237 FIXME("iface %p, profile %s, flags %#lx, handles %p, fragment_count %u, buffer %p, errors %p: stub.\n",
2238 iface
, debugstr_a(profile
), flags
, handles
, fragment_count
, buffer
, errors
);
2243 static HRESULT WINAPI
d3dx9_fragment_linker_LinkVertexShader(ID3DXFragmentLinker
*iface
, const char *profile
,
2244 DWORD flags
, const D3DXHANDLE
*handles
, UINT fragment_count
, IDirect3DVertexShader9
**shader
,
2245 ID3DXBuffer
**errors
)
2247 FIXME("iface %p, profile %s, flags %#lx, handles %p, fragment_count %u, shader %p, errors %p: stub.\n",
2248 iface
, debugstr_a(profile
), flags
, handles
, fragment_count
, shader
, errors
);
2253 static HRESULT WINAPI
d3dx9_fragment_linker_LinkPixelShader(ID3DXFragmentLinker
*iface
, const char *profile
,
2254 DWORD flags
, const D3DXHANDLE
*handles
, UINT fragment_count
, IDirect3DPixelShader9
**shader
,
2255 ID3DXBuffer
**errors
)
2257 FIXME("iface %p, profile %s, flags %#lx, handles %p, fragment_count %u, shader %p, errors %p: stub.\n",
2258 iface
, debugstr_a(profile
), flags
, handles
, fragment_count
, shader
, errors
);
2263 static HRESULT WINAPI
d3dx9_fragment_linker_ClearCache(ID3DXFragmentLinker
*iface
)
2265 FIXME("iface %p: stub.\n", iface
);
2270 static const struct ID3DXFragmentLinkerVtbl d3dx9_fragment_linker_vtbl
=
2272 d3dx9_fragment_linker_QueryInterface
,
2273 d3dx9_fragment_linker_AddRef
,
2274 d3dx9_fragment_linker_Release
,
2275 d3dx9_fragment_linker_GetDevice
,
2276 d3dx9_fragment_linker_GetNumberOfFragments
,
2277 d3dx9_fragment_linker_GetFragmentHandleByIndex
,
2278 d3dx9_fragment_linker_GetFragmentHandleByName
,
2279 d3dx9_fragment_linker_GetFragmentDesc
,
2280 d3dx9_fragment_linker_AddFragments
,
2281 d3dx9_fragment_linker_GetAllFragments
,
2282 d3dx9_fragment_linker_GetFragment
,
2283 d3dx9_fragment_linker_LinkShader
,
2284 d3dx9_fragment_linker_LinkVertexShader
,
2285 d3dx9_fragment_linker_LinkPixelShader
,
2286 d3dx9_fragment_linker_ClearCache
2289 HRESULT WINAPI
D3DXCreateFragmentLinkerEx(IDirect3DDevice9
*device
, UINT size
, DWORD flags
,
2290 ID3DXFragmentLinker
**linker
)
2292 struct d3dx9_fragment_linker
*object
;
2294 TRACE("device %p, size %u, flags %#lx, linker %p.\n", device
, size
, flags
, linker
);
2296 object
= heap_alloc(sizeof(*object
));
2298 return E_OUTOFMEMORY
;
2300 object
->ID3DXFragmentLinker_iface
.lpVtbl
= &d3dx9_fragment_linker_vtbl
;
2303 IDirect3DDevice9_AddRef(device
);
2304 object
->device
= device
;
2305 object
->flags
= flags
;
2307 *linker
= &object
->ID3DXFragmentLinker_iface
;
2312 HRESULT WINAPI
D3DXCreateFragmentLinker(IDirect3DDevice9
*device
, UINT size
, ID3DXFragmentLinker
**linker
)
2314 TRACE("device %p, size %u, linker %p.\n", device
, size
, linker
);
2316 return D3DXCreateFragmentLinkerEx(device
, size
, 0, linker
);
2319 HRESULT WINAPI
D3DXGetShaderSamplers(const DWORD
*byte_code
, const char **samplers
, UINT
*count
)
2321 UINT i
, sampler_count
= 0;
2324 const D3DXSHADER_CONSTANTTABLE
*ctab_header
;
2325 const D3DXSHADER_CONSTANTINFO
*constant_info
;
2327 TRACE("byte_code %p, samplers %p, count %p\n", byte_code
, samplers
, count
);
2329 if (count
) *count
= 0;
2331 if (D3DXFindShaderComment(byte_code
, MAKEFOURCC('C','T','A','B'), (const void **)&data
, &size
) != D3D_OK
)
2334 if (size
< sizeof(*ctab_header
)) return D3D_OK
;
2336 ctab_header
= (const D3DXSHADER_CONSTANTTABLE
*)data
;
2337 if (ctab_header
->Size
!= sizeof(*ctab_header
)) return D3D_OK
;
2339 constant_info
= (const D3DXSHADER_CONSTANTINFO
*)(data
+ ctab_header
->ConstantInfo
);
2340 for (i
= 0; i
< ctab_header
->Constants
; i
++)
2342 const D3DXSHADER_TYPEINFO
*type
;
2344 TRACE("name = %s\n", data
+ constant_info
[i
].Name
);
2346 type
= (const D3DXSHADER_TYPEINFO
*)(data
+ constant_info
[i
].TypeInfo
);
2348 if (type
->Type
== D3DXPT_SAMPLER
2349 || type
->Type
== D3DXPT_SAMPLER1D
2350 || type
->Type
== D3DXPT_SAMPLER2D
2351 || type
->Type
== D3DXPT_SAMPLER3D
2352 || type
->Type
== D3DXPT_SAMPLERCUBE
)
2354 if (samplers
) samplers
[sampler_count
] = data
+ constant_info
[i
].Name
;
2360 TRACE("Found %u samplers\n", sampler_count
);
2362 if (count
) *count
= sampler_count
;
2367 HRESULT WINAPI
D3DXDisassembleShader(const DWORD
*shader
, BOOL colorcode
, const char *comments
,
2368 ID3DXBuffer
**buffer
)
2370 TRACE("shader %p, colorcode %d, comments %s, buffer %p.\n", shader
, colorcode
, debugstr_a(comments
), buffer
);
2372 return D3DDisassemble(shader
, D3DXGetShaderSize(shader
), colorcode
? D3D_DISASM_ENABLE_COLOR_CODE
: 0,
2373 comments
, (ID3DBlob
**)buffer
);
2376 struct d3dx9_texture_shader
2378 ID3DXTextureShader ID3DXTextureShader_iface
;
2381 ID3DXBuffer
*byte_code
;
2382 ULONG64 version_counter
;
2383 struct d3dx_parameters_store parameters
;
2384 struct d3dx_param_eval
*eval
;
2387 static inline struct d3dx9_texture_shader
*impl_from_ID3DXTextureShader(ID3DXTextureShader
*iface
)
2389 return CONTAINING_RECORD(iface
, struct d3dx9_texture_shader
, ID3DXTextureShader_iface
);
2392 static HRESULT WINAPI
d3dx9_texture_shader_QueryInterface(ID3DXTextureShader
*iface
, REFIID riid
, void **out
)
2394 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
2396 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
2397 IsEqualGUID(riid
, &IID_ID3DXTextureShader
))
2399 iface
->lpVtbl
->AddRef(iface
);
2404 WARN("Interface %s not found.\n", debugstr_guid(riid
));
2406 return E_NOINTERFACE
;
2409 static ULONG WINAPI
d3dx9_texture_shader_AddRef(ID3DXTextureShader
*iface
)
2411 struct d3dx9_texture_shader
*texture_shader
= impl_from_ID3DXTextureShader(iface
);
2412 ULONG refcount
= InterlockedIncrement(&texture_shader
->ref
);
2414 TRACE("%p increasing refcount to %lu.\n", texture_shader
, refcount
);
2419 static ULONG WINAPI
d3dx9_texture_shader_Release(ID3DXTextureShader
*iface
)
2421 struct d3dx9_texture_shader
*texture_shader
= impl_from_ID3DXTextureShader(iface
);
2422 ULONG refcount
= InterlockedDecrement(&texture_shader
->ref
);
2424 TRACE("%p decreasing refcount to %lu.\n", texture_shader
, refcount
);
2428 if (texture_shader
->byte_code
)
2429 ID3DXBuffer_Release(texture_shader
->byte_code
);
2430 d3dx_free_param_eval(texture_shader
->eval
);
2431 d3dx_parameters_store_cleanup(&texture_shader
->parameters
);
2432 HeapFree(GetProcessHeap(), 0, texture_shader
);
2438 static HRESULT WINAPI
d3dx9_texture_shader_GetFunction(ID3DXTextureShader
*iface
, struct ID3DXBuffer
**function
)
2440 struct d3dx9_texture_shader
*texture_shader
= impl_from_ID3DXTextureShader(iface
);
2442 TRACE("iface %p, function %p.\n", iface
, function
);
2444 *function
= texture_shader
->byte_code
;
2445 ID3DXBuffer_AddRef(*function
);
2450 static HRESULT WINAPI
d3dx9_texture_shader_GetConstantBuffer(ID3DXTextureShader
*iface
, struct ID3DXBuffer
**constant_buffer
)
2452 FIXME("iface %p, constant_buffer %p stub.\n", iface
, constant_buffer
);
2457 static HRESULT WINAPI
d3dx9_texture_shader_GetDesc(ID3DXTextureShader
*iface
, D3DXCONSTANTTABLE_DESC
*desc
)
2459 FIXME("iface %p, desc %p stub.\n", iface
, desc
);
2464 static HRESULT WINAPI
d3dx9_texture_shader_GetConstantDesc(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, D3DXCONSTANT_DESC
*constant_desc
, UINT
*count
)
2466 FIXME("iface %p, constant %p, constant_desc %p, count %p stub.\n", iface
, constant
, constant_desc
, count
);
2471 static D3DXHANDLE WINAPI
d3dx9_texture_shader_GetConstant(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, UINT index
)
2473 FIXME("iface %p, constant %p, index %u stub.\n", iface
, constant
, index
);
2478 static D3DXHANDLE WINAPI
d3dx9_texture_shader_GetConstantByName(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const char *name
)
2480 FIXME("iface %p, constant %p, name %s stub.\n", iface
, constant
, debugstr_a(name
));
2485 static D3DXHANDLE WINAPI
d3dx9_texture_shader_GetConstantElement(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, UINT index
)
2487 FIXME("iface %p, constant %p, index %u stub.\n", iface
, constant
, index
);
2492 static HRESULT WINAPI
d3dx9_texture_shader_SetDefaults(ID3DXTextureShader
*iface
)
2494 FIXME("iface %p stub.\n", iface
);
2499 static HRESULT WINAPI
d3dx9_texture_shader_SetValue(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const void *data
, UINT bytes
)
2501 FIXME("iface %p, constant %p, data %p, bytes %u stub.\n", iface
, constant
, data
, bytes
);
2506 static HRESULT WINAPI
d3dx9_texture_shader_SetBool(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, BOOL b
)
2508 FIXME("iface %p, constant %p, b %u stub.\n", iface
, constant
, b
);
2513 static HRESULT WINAPI
d3dx9_texture_shader_SetBoolArray(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const BOOL
*b
, UINT count
)
2515 FIXME("iface %p, constant %p, b %p, count %u stub.\n", iface
, constant
, b
, count
);
2520 static HRESULT WINAPI
d3dx9_texture_shader_SetInt(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, INT n
)
2522 FIXME("iface %p, constant %p, n %d stub.\n", iface
, constant
, n
);
2527 static HRESULT WINAPI
d3dx9_texture_shader_SetIntArray(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const INT
*n
, UINT count
)
2529 FIXME("iface %p, constant %p, n %p, count %u stub.\n", iface
, constant
, n
, count
);
2534 static HRESULT WINAPI
d3dx9_texture_shader_SetFloat(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, FLOAT f
)
2536 FIXME("iface %p, constant %p, f %f stub.\n", iface
, constant
, f
);
2541 static HRESULT WINAPI
d3dx9_texture_shader_SetFloatArray(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const FLOAT
*f
, UINT count
)
2543 FIXME("iface %p, constant %p, f %p, count %u stub.\n", iface
, constant
, f
, count
);
2548 static HRESULT WINAPI
d3dx9_texture_shader_SetVector(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const D3DXVECTOR4
*vector
)
2550 FIXME("iface %p, constant %p, vector %p stub.\n", iface
, constant
, vector
);
2555 static HRESULT WINAPI
d3dx9_texture_shader_SetVectorArray(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const D3DXVECTOR4
*vector
, UINT count
)
2557 FIXME("iface %p, constant %p, vector %p, count %u stub.\n", iface
, constant
, vector
, count
);
2562 static HRESULT WINAPI
d3dx9_texture_shader_SetMatrix(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const D3DXMATRIX
*matrix
)
2564 FIXME("iface %p, constant %p, matrix %p stub.\n", iface
, constant
, matrix
);
2569 static HRESULT WINAPI
d3dx9_texture_shader_SetMatrixArray(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const D3DXMATRIX
*matrix
, UINT count
)
2571 FIXME("iface %p, constant %p, matrix %p, count %u stub.\n", iface
, constant
, matrix
, count
);
2576 static HRESULT WINAPI
d3dx9_texture_shader_SetMatrixPointerArray(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const D3DXMATRIX
**matrix
, UINT count
)
2578 FIXME("iface %p, constant %p, matrix %p, count %u stub.\n", iface
, constant
, matrix
, count
);
2583 static HRESULT WINAPI
d3dx9_texture_shader_SetMatrixTranspose(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const D3DXMATRIX
*matrix
)
2585 FIXME("iface %p, constant %p, matrix %p stub.\n", iface
, constant
, matrix
);
2590 static HRESULT WINAPI
d3dx9_texture_shader_SetMatrixTransposeArray(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const D3DXMATRIX
*matrix
, UINT count
)
2592 FIXME("iface %p, constant %p, matrix %p, count %u stub.\n", iface
, constant
, matrix
, count
);
2597 static HRESULT WINAPI
d3dx9_texture_shader_SetMatrixTransposePointerArray(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const D3DXMATRIX
**matrix
, UINT count
)
2599 FIXME("iface %p, constant %p, matrix %p, count %u stub.\n", iface
, constant
, matrix
, count
);
2604 static const struct ID3DXTextureShaderVtbl d3dx9_texture_shader_vtbl
=
2606 /*** IUnknown methods ***/
2607 d3dx9_texture_shader_QueryInterface
,
2608 d3dx9_texture_shader_AddRef
,
2609 d3dx9_texture_shader_Release
,
2610 /*** ID3DXTextureShader methods ***/
2611 d3dx9_texture_shader_GetFunction
,
2612 d3dx9_texture_shader_GetConstantBuffer
,
2613 d3dx9_texture_shader_GetDesc
,
2614 d3dx9_texture_shader_GetConstantDesc
,
2615 d3dx9_texture_shader_GetConstant
,
2616 d3dx9_texture_shader_GetConstantByName
,
2617 d3dx9_texture_shader_GetConstantElement
,
2618 d3dx9_texture_shader_SetDefaults
,
2619 d3dx9_texture_shader_SetValue
,
2620 d3dx9_texture_shader_SetBool
,
2621 d3dx9_texture_shader_SetBoolArray
,
2622 d3dx9_texture_shader_SetInt
,
2623 d3dx9_texture_shader_SetIntArray
,
2624 d3dx9_texture_shader_SetFloat
,
2625 d3dx9_texture_shader_SetFloatArray
,
2626 d3dx9_texture_shader_SetVector
,
2627 d3dx9_texture_shader_SetVectorArray
,
2628 d3dx9_texture_shader_SetMatrix
,
2629 d3dx9_texture_shader_SetMatrixArray
,
2630 d3dx9_texture_shader_SetMatrixPointerArray
,
2631 d3dx9_texture_shader_SetMatrixTranspose
,
2632 d3dx9_texture_shader_SetMatrixTransposeArray
,
2633 d3dx9_texture_shader_SetMatrixTransposePointerArray
2636 static inline struct d3dx9_texture_shader
*unsafe_impl_from_ID3DXTextureShader(ID3DXTextureShader
*iface
)
2641 assert(iface
->lpVtbl
== &d3dx9_texture_shader_vtbl
);
2642 return impl_from_ID3DXTextureShader(iface
);
2645 HRESULT WINAPI
D3DXCreateTextureShader(const DWORD
*function
, ID3DXTextureShader
**texture_shader
)
2647 struct d3dx9_texture_shader
*object
;
2651 TRACE("function %p, texture_shader %p.\n", function
, texture_shader
);
2653 if (!function
|| !texture_shader
)
2654 return D3DERR_INVALIDCALL
;
2656 if (!(size
= D3DXGetShaderSize(function
)))
2657 return D3DXERR_INVALIDDATA
;
2659 if (!(object
= heap_alloc_zero(sizeof(*object
))))
2660 return E_OUTOFMEMORY
;
2662 object
->ID3DXTextureShader_iface
.lpVtbl
= &d3dx9_texture_shader_vtbl
;
2665 if (FAILED(hr
= D3DXCreateBuffer(size
, &object
->byte_code
)))
2667 IUnknown_Release(&object
->ID3DXTextureShader_iface
);
2670 memcpy(ID3DXBuffer_GetBufferPointer(object
->byte_code
), function
, size
);
2672 if (FAILED(hr
= d3dx_init_parameters_store(&object
->parameters
, 0)))
2674 IUnknown_Release(&object
->ID3DXTextureShader_iface
);
2678 if (FAILED(hr
= d3dx_create_param_eval(&object
->parameters
, ID3DXBuffer_GetBufferPointer(object
->byte_code
),
2679 size
, D3DXPT_FLOAT
, &object
->eval
, &object
->version_counter
, NULL
, 0)))
2681 IUnknown_Release(&object
->ID3DXTextureShader_iface
);
2685 *texture_shader
= &object
->ID3DXTextureShader_iface
;
2690 void WINAPI
texture_shader_fill_2d(D3DXVECTOR4
*out
, const D3DXVECTOR2
*texcoord
,
2691 const D3DXVECTOR2
*texelsize
, void *data
)
2693 struct d3dx9_texture_shader
*shader
= data
;
2694 struct d3dx_parameter param
= { 0 };
2697 inputs
= (float *)shader
->eval
->pres
.regs
.tables
[PRES_REGTAB_INPUT
];
2699 *(inputs
++) = texcoord
->x
;
2700 *(inputs
++) = texcoord
->y
;
2704 *(inputs
++) = texelsize
->x
;
2705 *(inputs
++) = texelsize
->y
;
2709 param
.type
= D3DXPT_FLOAT
;
2710 param
.bytes
= 4 * sizeof(float);
2711 d3dx_evaluate_parameter(shader
->eval
, ¶m
, out
);
2714 void WINAPI
texture_shader_fill_3d(D3DXVECTOR4
*out
, const D3DXVECTOR3
*texcoord
,
2715 const D3DXVECTOR3
*texelsize
, void *data
)
2717 struct d3dx9_texture_shader
*shader
= data
;
2718 struct d3dx_parameter param
= { 0 };
2721 inputs
= (float *)shader
->eval
->pres
.regs
.tables
[PRES_REGTAB_INPUT
];
2723 *(inputs
++) = texcoord
->x
;
2724 *(inputs
++) = texcoord
->y
;
2725 *(inputs
++) = texcoord
->z
;
2728 *(inputs
++) = texelsize
->x
;
2729 *(inputs
++) = texelsize
->y
;
2730 *(inputs
++) = texelsize
->z
;
2733 param
.type
= D3DXPT_FLOAT
;
2734 param
.bytes
= 4 * sizeof(float);
2735 d3dx_evaluate_parameter(shader
->eval
, ¶m
, out
);
2738 HRESULT WINAPI
D3DXFillTextureTX(struct IDirect3DTexture9
*texture
, ID3DXTextureShader
*texture_shader
)
2740 struct d3dx9_texture_shader
*shader
= unsafe_impl_from_ID3DXTextureShader(texture_shader
);
2742 TRACE("texture %p, texture_shader %p.\n", texture
, texture_shader
);
2744 return D3DXFillTexture(texture
, texture_shader_fill_2d
, shader
);
2747 HRESULT WINAPI
D3DXFillCubeTextureTX(struct IDirect3DCubeTexture9
*cube
, ID3DXTextureShader
*texture_shader
)
2749 struct d3dx9_texture_shader
*shader
= unsafe_impl_from_ID3DXTextureShader(texture_shader
);
2751 TRACE("cube %p, texture_shader %p.\n", cube
, texture_shader
);
2753 return D3DXFillCubeTexture(cube
, texture_shader_fill_3d
, shader
);
2756 static unsigned int get_instr_length(const DWORD
*byte_code
, unsigned int major
, unsigned int minor
)
2758 DWORD opcode
= *byte_code
& 0xffff;
2759 unsigned int len
= 0;
2761 if (opcode
== D3DSIO_COMMENT
)
2762 return (*byte_code
& D3DSI_COMMENTSIZE_MASK
) >> D3DSI_COMMENTSIZE_SHIFT
;
2765 return (*byte_code
& D3DSI_INSTLENGTH_MASK
) >> D3DSI_INSTLENGTH_SHIFT
;
2770 ERR("Unexpected END token.\n");
2779 while (*byte_code
& 0x80000000)
2789 static HRESULT
get_shader_semantics(const DWORD
*byte_code
, D3DXSEMANTIC
*semantics
, UINT
*count
, BOOL output
)
2791 static const D3DDECLUSAGE regtype_usage
[] =
2796 D3DDECLUSAGE_TEXCOORD
,
2799 D3DDECLUSAGE_TEXCOORD
,
2804 static const D3DDECLUSAGE rast_usage
[] =
2806 D3DDECLUSAGE_POSITION
,
2810 uint32_t reg_type
, usage
, index
, version_token
= *byte_code
;
2811 BOOL is_ps
= version_token
>> 16 == 0xffff;
2812 unsigned int major
, minor
, i
= 0, j
;
2813 BYTE colors
= 0, rastout
= 0;
2814 BOOL has_dcl
, depth
= 0;
2817 if ((version_token
& 0xffff0000) != 0xfffe0000 && (version_token
& 0xffff0000) != 0xffff0000)
2818 return D3DXERR_INVALIDDATA
;
2820 major
= version_token
>> 8 & 0xff;
2821 minor
= version_token
& 0xff;
2823 TRACE("%s shader, version %u.%u.\n", is_ps
? "Pixel" : "Vertex", major
, minor
);
2826 has_dcl
= (!is_ps
&& (!output
|| major
== 3)) || (is_ps
&& !output
&& major
>= 2);
2828 while (*byte_code
!= D3DSIO_END
)
2830 if (has_dcl
&& (*byte_code
& 0xffff) == D3DSIO_DCL
)
2832 uint32_t usage_token
= byte_code
[1];
2833 uint32_t reg
= byte_code
[2];
2835 reg_type
= ((reg
& D3DSP_REGTYPE_MASK
) >> D3DSP_REGTYPE_SHIFT
)
2836 | ((reg
& D3DSP_REGTYPE_MASK2
) >> D3DSP_REGTYPE_SHIFT2
);
2838 if (is_ps
&& !output
&& major
== 2)
2840 /* dcl with no explicit usage, look at the register. */
2841 reg_type
= ((reg
& D3DSP_REGTYPE_MASK
) >> D3DSP_REGTYPE_SHIFT
)
2842 | ((reg
& D3DSP_REGTYPE_MASK2
) >> D3DSP_REGTYPE_SHIFT2
);
2843 index
= reg
& D3DSP_REGNUM_MASK
;
2844 if (reg_type
>= ARRAY_SIZE(regtype_usage
))
2846 WARN("Invalid register type %u.\n", reg_type
);
2849 usage
= regtype_usage
[reg_type
];
2852 semantics
[i
].Usage
= usage
;
2853 semantics
[i
].UsageIndex
= index
;
2857 else if ((!output
&& reg_type
== D3DSPR_INPUT
) || (output
&& reg_type
== D3DSPR_OUTPUT
))
2861 semantics
[i
].Usage
=
2862 (usage_token
& D3DSP_DCL_USAGE_MASK
) >> D3DSP_DCL_USAGE_SHIFT
;
2863 semantics
[i
].UsageIndex
=
2864 (usage_token
& D3DSP_DCL_USAGEINDEX_MASK
) >> D3DSP_DCL_USAGEINDEX_SHIFT
;
2872 unsigned int len
= get_instr_length(byte_code
, major
, minor
) + 1;
2874 switch (*byte_code
& 0xffff)
2876 case D3DSIO_COMMENT
:
2884 while (*byte_code
& 0x80000000)
2886 reg_type
= ((*byte_code
& D3DSP_REGTYPE_MASK
) >> D3DSP_REGTYPE_SHIFT
)
2887 | ((*byte_code
& D3DSP_REGTYPE_MASK2
) >> D3DSP_REGTYPE_SHIFT2
);
2888 index
= *byte_code
& D3DSP_REGNUM_MASK
;
2890 if ((reg_type
== D3DSPR_TEMP
&& is_ps
&& major
== 1)
2891 || (reg_type
== D3DSPR_INPUT
&& is_ps
)
2892 || (reg_type
== D3DSPR_TEXTURE
&& is_ps
&& !output
)
2893 || reg_type
== D3DSPR_RASTOUT
2894 || reg_type
== D3DSPR_ATTROUT
2895 || reg_type
== D3DSPR_OUTPUT
2896 || reg_type
== D3DSPR_DEPTHOUT
)
2898 if (reg_type
== D3DSPR_RASTOUT
)
2899 rastout
|= 1u << index
;
2900 else if (reg_type
== D3DSPR_DEPTHOUT
)
2902 else if (reg_type
== D3DSPR_TEXTURE
|| reg_type
== D3DSPR_OUTPUT
)
2903 texcoords
|= 1u << index
;
2905 colors
|= 1u << index
;
2913 byte_code
+= get_instr_length(byte_code
, major
, minor
) + 1;
2926 semantics
[i
].Usage
= D3DDECLUSAGE_TEXCOORD
;
2927 semantics
[i
].UsageIndex
= j
;
2941 semantics
[i
].Usage
= D3DDECLUSAGE_COLOR
;
2942 semantics
[i
].UsageIndex
= j
;
2954 if (j
>= ARRAY_SIZE(rast_usage
))
2956 WARN("Invalid RASTOUT register index.\n");
2961 usage
= rast_usage
[j
];
2965 semantics
[i
].Usage
= usage
;
2966 semantics
[i
].UsageIndex
= 0;
2977 semantics
[i
].Usage
= D3DDECLUSAGE_DEPTH
;
2978 semantics
[i
].UsageIndex
= 0;
2990 HRESULT WINAPI
D3DXGetShaderInputSemantics(const DWORD
*byte_code
, D3DXSEMANTIC
*semantics
, UINT
*count
)
2992 TRACE("byte_code %p, semantics %p, count %p.\n", byte_code
, semantics
, count
);
2994 return get_shader_semantics(byte_code
, semantics
, count
, FALSE
);
2997 HRESULT WINAPI
D3DXGetShaderOutputSemantics(const DWORD
*byte_code
, D3DXSEMANTIC
*semantics
, UINT
*count
)
2999 TRACE("byte_code %p, semantics %p, count %p.\n", byte_code
, semantics
, count
);
3001 return get_shader_semantics(byte_code
, semantics
, count
, TRUE
);