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 /* This function is not declared in the SDK headers yet. */
30 HRESULT WINAPI
D3DAssemble(const void *data
, SIZE_T datasize
, const char *filename
,
31 const D3D_SHADER_MACRO
*defines
, ID3DInclude
*include
, UINT flags
,
32 ID3DBlob
**shader
, ID3DBlob
**error_messages
);
34 static inline BOOL
is_valid_bytecode(DWORD token
)
36 return (token
& 0xfffe0000) == 0xfffe0000;
39 const char * WINAPI
D3DXGetPixelShaderProfile(struct IDirect3DDevice9
*device
)
43 TRACE("device %p\n", device
);
45 if (!device
) return NULL
;
47 IDirect3DDevice9_GetDeviceCaps(device
,&caps
);
49 switch (caps
.PixelShaderVersion
)
51 case D3DPS_VERSION(1, 1):
54 case D3DPS_VERSION(1, 2):
57 case D3DPS_VERSION(1, 3):
60 case D3DPS_VERSION(1, 4):
63 case D3DPS_VERSION(2, 0):
64 if ((caps
.PS20Caps
.NumTemps
>=22) &&
65 (caps
.PS20Caps
.Caps
&D3DPS20CAPS_ARBITRARYSWIZZLE
) &&
66 (caps
.PS20Caps
.Caps
&D3DPS20CAPS_GRADIENTINSTRUCTIONS
) &&
67 (caps
.PS20Caps
.Caps
&D3DPS20CAPS_PREDICATION
) &&
68 (caps
.PS20Caps
.Caps
&D3DPS20CAPS_NODEPENDENTREADLIMIT
) &&
69 (caps
.PS20Caps
.Caps
&D3DPS20CAPS_NOTEXINSTRUCTIONLIMIT
))
73 if ((caps
.PS20Caps
.NumTemps
>=32) &&
74 (caps
.PS20Caps
.Caps
&D3DPS20CAPS_NOTEXINSTRUCTIONLIMIT
))
80 case D3DPS_VERSION(3, 0):
87 UINT WINAPI
D3DXGetShaderSize(const DWORD
*byte_code
)
89 const DWORD
*ptr
= byte_code
;
91 TRACE("byte_code %p\n", byte_code
);
95 /* Look for the END token, skipping the VERSION token */
96 while (*++ptr
!= D3DSIO_END
)
99 if ((*ptr
& D3DSI_OPCODE_MASK
) == D3DSIO_COMMENT
)
101 ptr
+= ((*ptr
& D3DSI_COMMENTSIZE_MASK
) >> D3DSI_COMMENTSIZE_SHIFT
);
106 /* Return the shader size in bytes */
107 return (ptr
- byte_code
) * sizeof(*ptr
);
110 DWORD WINAPI
D3DXGetShaderVersion(const DWORD
*byte_code
)
112 TRACE("byte_code %p\n", byte_code
);
114 return byte_code
? *byte_code
: 0;
117 const char * WINAPI
D3DXGetVertexShaderProfile(struct IDirect3DDevice9
*device
)
121 TRACE("device %p\n", device
);
123 if (!device
) return NULL
;
125 IDirect3DDevice9_GetDeviceCaps(device
,&caps
);
127 switch (caps
.VertexShaderVersion
)
129 case D3DVS_VERSION(1, 1):
131 case D3DVS_VERSION(2, 0):
132 if ((caps
.VS20Caps
.NumTemps
>=13) &&
133 (caps
.VS20Caps
.DynamicFlowControlDepth
==24) &&
134 (caps
.VS20Caps
.Caps
&D3DPS20CAPS_PREDICATION
))
139 case D3DVS_VERSION(3, 0):
146 HRESULT WINAPI
D3DXFindShaderComment(const DWORD
*byte_code
, DWORD fourcc
, const void **data
, UINT
*size
)
148 const DWORD
*ptr
= byte_code
;
151 TRACE("byte_code %p, fourcc %#lx, data %p, size %p.\n", byte_code
, fourcc
, data
, size
);
153 if (data
) *data
= NULL
;
156 if (!byte_code
) return D3DERR_INVALIDCALL
;
158 version
= *ptr
>> 16;
159 if (version
!= 0x4658 /* FX */
160 && version
!= 0x5458 /* TX */
163 && version
!= 0xfffe /* VS */
164 && version
!= 0xffff) /* PS */
166 WARN("Invalid data supplied\n");
167 return D3DXERR_INVALIDDATA
;
170 while (*++ptr
!= D3DSIO_END
)
172 /* Check if it is a comment */
173 if ((*ptr
& D3DSI_OPCODE_MASK
) == D3DSIO_COMMENT
)
175 DWORD comment_size
= (*ptr
& D3DSI_COMMENTSIZE_MASK
) >> D3DSI_COMMENTSIZE_SHIFT
;
177 /* Check if this is the comment we are looking for */
178 if (*(ptr
+ 1) == fourcc
)
180 UINT ctab_size
= (comment_size
- 1) * sizeof(DWORD
);
181 const void *ctab_data
= ptr
+ 2;
186 TRACE("Returning comment data at %p with size %d\n", ctab_data
, ctab_size
);
196 HRESULT WINAPI
D3DXAssembleShader(const char *data
, UINT data_len
, const D3DXMACRO
*defines
,
197 ID3DXInclude
*include
, DWORD flags
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
201 TRACE("data %p, data_len %u, defines %p, include %p, flags %#lx, shader %p, error_messages %p.\n",
202 data
, data_len
, defines
, include
, flags
, shader
, error_messages
);
204 /* Forward to d3dcompiler: the parameter types aren't really different,
205 the actual data types are equivalent */
206 hr
= D3DAssemble(data
, data_len
, NULL
, (D3D_SHADER_MACRO
*)defines
,
207 (ID3DInclude
*)include
, flags
, (ID3DBlob
**)shader
,
208 (ID3DBlob
**)error_messages
);
210 if(hr
== E_FAIL
) hr
= D3DXERR_INVALIDDATA
;
214 static const void *main_file_data
;
216 static CRITICAL_SECTION_DEBUG from_file_mutex_debug
=
218 0, 0, &from_file_mutex
,
220 &from_file_mutex_debug
.ProcessLocksList
,
221 &from_file_mutex_debug
.ProcessLocksList
223 0, 0, {(DWORD_PTR
)(__FILE__
": from_file_mutex")}
225 CRITICAL_SECTION from_file_mutex
= {&from_file_mutex_debug
, -1, 0, 0, 0, 0};
227 /* D3DXInclude private implementation, used to implement
228 * D3DXAssembleShaderFromFile() from D3DXAssembleShader(). */
229 /* To be able to correctly resolve include search paths we have to store the
230 * pathname of each include file. We store the pathname pointer right before
232 static HRESULT WINAPI
d3dx_include_from_file_open(ID3DXInclude
*iface
, D3DXINCLUDE_TYPE include_type
,
233 const char *filename
, const void *parent_data
, const void **data
, UINT
*bytes
)
235 const char *p
, *parent_name
= "";
236 char *pathname
= NULL
, *ptr
;
237 char **buffer
= NULL
;
243 parent_name
= *((const char **)parent_data
- 1);
248 parent_name
= *((const char **)main_file_data
- 1);
251 TRACE("Looking up include file %s, parent %s.\n", debugstr_a(filename
), debugstr_a(parent_name
));
253 if ((p
= strrchr(parent_name
, '\\')))
257 pathname
= HeapAlloc(GetProcessHeap(), 0, (p
- parent_name
) + strlen(filename
) + 1);
259 return HRESULT_FROM_WIN32(GetLastError());
261 memcpy(pathname
, parent_name
, p
- parent_name
);
262 strcpy(pathname
+ (p
- parent_name
), filename
);
263 ptr
= pathname
+ (p
- parent_name
);
271 file
= CreateFileA(pathname
, GENERIC_READ
, FILE_SHARE_READ
, 0, OPEN_EXISTING
, 0, 0);
272 if(file
== INVALID_HANDLE_VALUE
)
275 TRACE("Include file found at pathname = %s\n", debugstr_a(pathname
));
277 size
= GetFileSize(file
, NULL
);
278 if(size
== INVALID_FILE_SIZE
)
281 buffer
= HeapAlloc(GetProcessHeap(), 0, size
+ sizeof(char *));
285 if (!ReadFile(file
, buffer
+ 1, size
, (DWORD
*)bytes
, NULL
))
290 main_file_data
= *data
;
297 HeapFree(GetProcessHeap(), 0, pathname
);
298 HeapFree(GetProcessHeap(), 0, buffer
);
299 return HRESULT_FROM_WIN32(GetLastError());
302 static HRESULT WINAPI
d3dx_include_from_file_close(ID3DXInclude
*iface
, const void *data
)
304 HeapFree(GetProcessHeap(), 0, *((char **)data
- 1));
305 HeapFree(GetProcessHeap(), 0, (char **)data
- 1);
306 if (main_file_data
== data
)
307 main_file_data
= NULL
;
311 const struct ID3DXIncludeVtbl d3dx_include_from_file_vtbl
=
313 d3dx_include_from_file_open
,
314 d3dx_include_from_file_close
317 HRESULT WINAPI
D3DXAssembleShaderFromFileA(const char *filename
, const D3DXMACRO
*defines
,
318 ID3DXInclude
*include
, DWORD flags
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
324 TRACE("filename %s, defines %p, include %p, flags %#lx, shader %p, error_messages %p.\n",
325 debugstr_a(filename
), defines
, include
, flags
, shader
, error_messages
);
327 if (!filename
) return D3DXERR_INVALIDDATA
;
329 len
= MultiByteToWideChar(CP_ACP
, 0, filename
, -1, NULL
, 0);
330 filename_w
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
331 if (!filename_w
) return E_OUTOFMEMORY
;
332 MultiByteToWideChar(CP_ACP
, 0, filename
, -1, filename_w
, len
);
334 ret
= D3DXAssembleShaderFromFileW(filename_w
, defines
, include
, flags
, shader
, error_messages
);
336 HeapFree(GetProcessHeap(), 0, filename_w
);
340 HRESULT WINAPI
D3DXAssembleShaderFromFileW(const WCHAR
*filename
, const D3DXMACRO
*defines
,
341 ID3DXInclude
*include
, DWORD flags
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
343 struct d3dx_include_from_file include_from_file
;
349 TRACE("filename %s, defines %p, include %p, flags %#lx, shader %p, error_messages %p.\n",
350 debugstr_w(filename
), defines
, include
, flags
, shader
, error_messages
);
354 include_from_file
.ID3DXInclude_iface
.lpVtbl
= &d3dx_include_from_file_vtbl
;
355 include
= &include_from_file
.ID3DXInclude_iface
;
358 len
= WideCharToMultiByte(CP_ACP
, 0, filename
, -1, NULL
, 0, NULL
, NULL
);
359 filename_a
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(char));
361 return E_OUTOFMEMORY
;
362 WideCharToMultiByte(CP_ACP
, 0, filename
, -1, filename_a
, len
, NULL
, NULL
);
364 EnterCriticalSection(&from_file_mutex
);
365 hr
= ID3DXInclude_Open(include
, D3DXINC_LOCAL
, filename_a
, NULL
, &buffer
, &len
);
368 LeaveCriticalSection(&from_file_mutex
);
369 HeapFree(GetProcessHeap(), 0, filename_a
);
370 return D3DXERR_INVALIDDATA
;
373 hr
= D3DXAssembleShader(buffer
, len
, defines
, include
, flags
, shader
, error_messages
);
375 ID3DXInclude_Close(include
, buffer
);
376 LeaveCriticalSection(&from_file_mutex
);
377 HeapFree(GetProcessHeap(), 0, filename_a
);
381 HRESULT WINAPI
D3DXAssembleShaderFromResourceA(HMODULE module
, const char *resource
, const D3DXMACRO
*defines
,
382 ID3DXInclude
*include
, DWORD flags
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
388 TRACE("module %p, resource %s, defines %p, include %p, flags %#lx, shader %p, error_messages %p.\n",
389 module
, debugstr_a(resource
), defines
, include
, flags
, shader
, error_messages
);
391 if (!(res
= FindResourceA(module
, resource
, (const char *)RT_RCDATA
)))
392 return D3DXERR_INVALIDDATA
;
393 if (FAILED(load_resource_into_memory(module
, res
, &buffer
, &len
)))
394 return D3DXERR_INVALIDDATA
;
395 return D3DXAssembleShader(buffer
, len
, defines
, include
, flags
,
396 shader
, error_messages
);
399 HRESULT WINAPI
D3DXAssembleShaderFromResourceW(HMODULE module
, const WCHAR
*resource
, const D3DXMACRO
*defines
,
400 ID3DXInclude
*include
, DWORD flags
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
406 TRACE("module %p, resource %s, defines %p, include %p, flags %#lx, shader %p, error_messages %p.\n",
407 module
, debugstr_w(resource
), defines
, include
, flags
, shader
, error_messages
);
409 if (!(res
= FindResourceW(module
, resource
, (const WCHAR
*)RT_RCDATA
)))
410 return D3DXERR_INVALIDDATA
;
411 if (FAILED(load_resource_into_memory(module
, res
, &buffer
, &len
)))
412 return D3DXERR_INVALIDDATA
;
413 return D3DXAssembleShader(buffer
, len
, defines
, include
, flags
,
414 shader
, error_messages
);
417 HRESULT WINAPI
D3DXCompileShader(const char *data
, UINT length
, const D3DXMACRO
*defines
,
418 ID3DXInclude
*include
, const char *function
, const char *profile
, DWORD flags
,
419 ID3DXBuffer
**shader
, ID3DXBuffer
**error_msgs
, ID3DXConstantTable
**constant_table
)
423 TRACE("data %s, length %u, defines %p, include %p, function %s, profile %s, "
424 "flags %#lx, shader %p, error_msgs %p, constant_table %p.\n",
425 debugstr_a(data
), length
, defines
, include
, debugstr_a(function
), debugstr_a(profile
),
426 flags
, shader
, error_msgs
, constant_table
);
428 if (D3DX_SDK_VERSION
<= 36)
429 flags
|= D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY
;
431 hr
= D3DCompile(data
, length
, NULL
, (D3D_SHADER_MACRO
*)defines
, (ID3DInclude
*)include
,
432 function
, profile
, flags
, 0, (ID3DBlob
**)shader
, (ID3DBlob
**)error_msgs
);
434 if (SUCCEEDED(hr
) && constant_table
)
436 hr
= D3DXGetShaderConstantTable(ID3DXBuffer_GetBufferPointer(*shader
), constant_table
);
439 ID3DXBuffer_Release(*shader
);
447 HRESULT WINAPI
D3DXCompileShaderFromFileA(const char *filename
, const D3DXMACRO
*defines
,
448 ID3DXInclude
*include
, const char *entrypoint
, const char *profile
, DWORD flags
,
449 ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
, ID3DXConstantTable
**constant_table
)
455 TRACE("filename %s, defines %p, include %p, entrypoint %s, profile %s, "
456 "flags %#lx, shader %p, error_messages %p, constant_table %p.\n",
457 debugstr_a(filename
), defines
, include
, debugstr_a(entrypoint
),
458 debugstr_a(profile
), flags
, shader
, error_messages
, constant_table
);
460 if (!filename
) return D3DXERR_INVALIDDATA
;
462 len
= MultiByteToWideChar(CP_ACP
, 0, filename
, -1, NULL
, 0);
463 filename_w
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
464 if (!filename_w
) return E_OUTOFMEMORY
;
465 MultiByteToWideChar(CP_ACP
, 0, filename
, -1, filename_w
, len
);
467 ret
= D3DXCompileShaderFromFileW(filename_w
, defines
, include
,
468 entrypoint
, profile
, flags
,
469 shader
, error_messages
, constant_table
);
471 HeapFree(GetProcessHeap(), 0, filename_w
);
475 HRESULT WINAPI
D3DXCompileShaderFromFileW(const WCHAR
*filename
, const D3DXMACRO
*defines
,
476 ID3DXInclude
*include
, const char *entrypoint
, const char *profile
, DWORD flags
,
477 ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
, ID3DXConstantTable
**constant_table
)
479 struct d3dx_include_from_file include_from_file
;
480 unsigned int filename_len
;
486 TRACE("filename %s, defines %p, include %p, entrypoint %s, profile %s, "
487 "flags %#lx, shader %p, error_messages %p, constant_table %p.\n",
488 debugstr_w(filename
), defines
, include
, debugstr_a(entrypoint
), debugstr_a(profile
),
489 flags
, shader
, error_messages
, constant_table
);
493 include_from_file
.ID3DXInclude_iface
.lpVtbl
= &d3dx_include_from_file_vtbl
;
494 include
= &include_from_file
.ID3DXInclude_iface
;
497 filename_len
= WideCharToMultiByte(CP_ACP
, 0, filename
, -1, NULL
, 0, NULL
, NULL
);
498 filename_a
= HeapAlloc(GetProcessHeap(), 0, filename_len
* sizeof(char));
500 return E_OUTOFMEMORY
;
501 WideCharToMultiByte(CP_ACP
, 0, filename
, -1, filename_a
, filename_len
, NULL
, NULL
);
503 EnterCriticalSection(&from_file_mutex
);
504 hr
= ID3DXInclude_Open(include
, D3DXINC_LOCAL
, filename_a
, NULL
, &buffer
, &len
);
507 LeaveCriticalSection(&from_file_mutex
);
508 HeapFree(GetProcessHeap(), 0, filename_a
);
509 return D3DXERR_INVALIDDATA
;
512 if (D3DX_SDK_VERSION
<= 36)
513 flags
|= D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY
;
515 hr
= D3DCompile(buffer
, len
, filename_a
, (const D3D_SHADER_MACRO
*)defines
,
516 (ID3DInclude
*)include
, entrypoint
, profile
, flags
, 0,
517 (ID3DBlob
**)shader
, (ID3DBlob
**)error_messages
);
519 if (SUCCEEDED(hr
) && constant_table
)
520 hr
= D3DXGetShaderConstantTable(ID3DXBuffer_GetBufferPointer(*shader
),
523 ID3DXInclude_Close(include
, buffer
);
524 LeaveCriticalSection(&from_file_mutex
);
525 HeapFree(GetProcessHeap(), 0, filename_a
);
529 HRESULT WINAPI
D3DXCompileShaderFromResourceA(HMODULE module
, const char *resource
, const D3DXMACRO
*defines
,
530 ID3DXInclude
*include
, const char *entrypoint
, const char *profile
, DWORD flags
,
531 ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
, ID3DXConstantTable
**constant_table
)
537 TRACE("module %p, resource %s, defines %p, include %p, entrypoint %s, profile %s, "
538 "flags %#lx, shader %p, error_messages %p, constant_table %p.\n",
539 module
, debugstr_a(resource
), defines
, include
, debugstr_a(entrypoint
), debugstr_a(profile
),
540 flags
, shader
, error_messages
, constant_table
);
542 if (!(res
= FindResourceA(module
, resource
, (const char *)RT_RCDATA
)))
543 return D3DXERR_INVALIDDATA
;
544 if (FAILED(load_resource_into_memory(module
, res
, &buffer
, &len
)))
545 return D3DXERR_INVALIDDATA
;
546 return D3DXCompileShader(buffer
, len
, defines
, include
, entrypoint
, profile
,
547 flags
, shader
, error_messages
, constant_table
);
550 HRESULT WINAPI
D3DXCompileShaderFromResourceW(HMODULE module
, const WCHAR
*resource
, const D3DXMACRO
*defines
,
551 ID3DXInclude
*include
, const char *entrypoint
, const char *profile
, DWORD flags
,
552 ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
, ID3DXConstantTable
**constant_table
)
558 TRACE("module %p, resource %s, defines %p, include %p, entrypoint %s, profile %s, "
559 "flags %#lx, shader %p, error_messages %p, constant_table %p.\n",
560 module
, debugstr_w(resource
), defines
, include
, debugstr_a(entrypoint
), debugstr_a(profile
),
561 flags
, shader
, error_messages
, constant_table
);
563 if (!(res
= FindResourceW(module
, resource
, (const WCHAR
*)RT_RCDATA
)))
564 return D3DXERR_INVALIDDATA
;
565 if (FAILED(load_resource_into_memory(module
, res
, &buffer
, &len
)))
566 return D3DXERR_INVALIDDATA
;
567 return D3DXCompileShader(buffer
, len
, defines
, include
, entrypoint
, profile
,
568 flags
, shader
, error_messages
, constant_table
);
571 HRESULT WINAPI
D3DXPreprocessShader(const char *data
, UINT data_len
, const D3DXMACRO
*defines
,
572 ID3DXInclude
*include
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
574 TRACE("data %s, data_len %u, defines %p, include %p, shader %p, error_messages %p.\n",
575 debugstr_a(data
), data_len
, defines
, include
, shader
, error_messages
);
577 return D3DPreprocess(data
, data_len
, NULL
,
578 (const D3D_SHADER_MACRO
*)defines
, (ID3DInclude
*)include
,
579 (ID3DBlob
**)shader
, (ID3DBlob
**)error_messages
);
582 HRESULT WINAPI
D3DXPreprocessShaderFromFileA(const char *filename
, const D3DXMACRO
*defines
,
583 ID3DXInclude
*include
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
585 WCHAR
*filename_w
= NULL
;
589 TRACE("filename %s, defines %p, include %p, shader %p, error_messages %p.\n",
590 debugstr_a(filename
), defines
, include
, shader
, error_messages
);
592 if (!filename
) return D3DXERR_INVALIDDATA
;
594 len
= MultiByteToWideChar(CP_ACP
, 0, filename
, -1, NULL
, 0);
595 filename_w
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
596 if (!filename_w
) return E_OUTOFMEMORY
;
597 MultiByteToWideChar(CP_ACP
, 0, filename
, -1, filename_w
, len
);
599 ret
= D3DXPreprocessShaderFromFileW(filename_w
, defines
, include
, shader
, error_messages
);
601 HeapFree(GetProcessHeap(), 0, filename_w
);
605 HRESULT WINAPI
D3DXPreprocessShaderFromFileW(const WCHAR
*filename
, const D3DXMACRO
*defines
,
606 ID3DXInclude
*include
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
608 struct d3dx_include_from_file include_from_file
;
614 TRACE("filename %s, defines %p, include %p, shader %p, error_messages %p.\n",
615 debugstr_w(filename
), defines
, include
, shader
, error_messages
);
619 include_from_file
.ID3DXInclude_iface
.lpVtbl
= &d3dx_include_from_file_vtbl
;
620 include
= &include_from_file
.ID3DXInclude_iface
;
623 len
= WideCharToMultiByte(CP_ACP
, 0, filename
, -1, NULL
, 0, NULL
, NULL
);
624 filename_a
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(char));
626 return E_OUTOFMEMORY
;
627 WideCharToMultiByte(CP_ACP
, 0, filename
, -1, filename_a
, len
, NULL
, NULL
);
629 EnterCriticalSection(&from_file_mutex
);
630 hr
= ID3DXInclude_Open(include
, D3DXINC_LOCAL
, filename_a
, NULL
, &buffer
, &len
);
633 LeaveCriticalSection(&from_file_mutex
);
634 HeapFree(GetProcessHeap(), 0, filename_a
);
635 return D3DXERR_INVALIDDATA
;
638 hr
= D3DPreprocess(buffer
, len
, NULL
,
639 (const D3D_SHADER_MACRO
*)defines
,
640 (ID3DInclude
*) include
,
641 (ID3DBlob
**)shader
, (ID3DBlob
**)error_messages
);
643 ID3DXInclude_Close(include
, buffer
);
644 LeaveCriticalSection(&from_file_mutex
);
645 HeapFree(GetProcessHeap(), 0, filename_a
);
649 HRESULT WINAPI
D3DXPreprocessShaderFromResourceA(HMODULE module
, const char *resource
, const D3DXMACRO
*defines
,
650 ID3DXInclude
*include
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
656 TRACE("module %p, resource %s, defines %p, include %p, shader %p, error_messages %p.\n",
657 module
, debugstr_a(resource
), defines
, include
, shader
, error_messages
);
659 if (!(res
= FindResourceA(module
, resource
, (const char *)RT_RCDATA
)))
660 return D3DXERR_INVALIDDATA
;
661 if (FAILED(load_resource_into_memory(module
, res
, &buffer
, &len
)))
662 return D3DXERR_INVALIDDATA
;
663 return D3DXPreprocessShader(buffer
, len
, defines
, include
,
664 shader
, error_messages
);
667 HRESULT WINAPI
D3DXPreprocessShaderFromResourceW(HMODULE module
, const WCHAR
*resource
, const D3DXMACRO
*defines
,
668 ID3DXInclude
*include
, ID3DXBuffer
**shader
, ID3DXBuffer
**error_messages
)
674 TRACE("module %p, resource %s, defines %p, include %p, shader %p, error_messages %p.\n",
675 module
, debugstr_w(resource
), defines
, include
, shader
, error_messages
);
677 if (!(res
= FindResourceW(module
, resource
, (const WCHAR
*)RT_RCDATA
)))
678 return D3DXERR_INVALIDDATA
;
679 if (FAILED(load_resource_into_memory(module
, res
, &buffer
, &len
)))
680 return D3DXERR_INVALIDDATA
;
681 return D3DXPreprocessShader(buffer
, len
, defines
, include
,
682 shader
, error_messages
);
686 struct ID3DXConstantTableImpl
688 ID3DXConstantTable ID3DXConstantTable_iface
;
693 D3DXCONSTANTTABLE_DESC desc
;
694 struct ctab_constant
*constants
;
697 static void free_constant(struct ctab_constant
*constant
)
699 if (constant
->constants
)
701 UINT i
, count
= constant
->desc
.Elements
> 1 ? constant
->desc
.Elements
: constant
->desc
.StructMembers
;
703 for (i
= 0; i
< count
; ++i
)
705 free_constant(&constant
->constants
[i
]);
707 HeapFree(GetProcessHeap(), 0, constant
->constants
);
711 static void free_constant_table(struct ID3DXConstantTableImpl
*table
)
713 if (table
->constants
)
717 for (i
= 0; i
< table
->desc
.Constants
; ++i
)
719 free_constant(&table
->constants
[i
]);
721 HeapFree(GetProcessHeap(), 0, table
->constants
);
723 HeapFree(GetProcessHeap(), 0, table
->ctab
);
726 static inline struct ID3DXConstantTableImpl
*impl_from_ID3DXConstantTable(ID3DXConstantTable
*iface
)
728 return CONTAINING_RECORD(iface
, struct ID3DXConstantTableImpl
, ID3DXConstantTable_iface
);
731 static inline BOOL
is_vertex_shader(DWORD version
)
733 return (version
& 0xffff0000) == 0xfffe0000;
736 static inline D3DXHANDLE
handle_from_constant(struct ctab_constant
*constant
)
738 return (D3DXHANDLE
)constant
;
741 static struct ctab_constant
*get_constant_by_name(struct ID3DXConstantTableImpl
*table
,
742 struct ctab_constant
*constant
, const char *name
);
744 static struct ctab_constant
*get_constant_element_by_name(struct ctab_constant
*constant
, const char *name
)
749 TRACE("constant %p, name %s\n", constant
, debugstr_a(name
));
751 if (!name
|| !*name
) return NULL
;
753 element
= atoi(name
);
754 part
= strchr(name
, ']') + 1;
756 if (constant
->desc
.Elements
> element
)
758 struct ctab_constant
*c
= constant
->constants
? &constant
->constants
[element
] : constant
;
763 return get_constant_by_name(NULL
, c
, part
);
766 return get_constant_element_by_name(c
, part
);
769 TRACE("Returning parameter %p\n", c
);
773 FIXME("Unhandled case \"%c\"\n", *--part
);
778 TRACE("Constant not found\n");
782 static struct ctab_constant
*get_constant_by_name(struct ID3DXConstantTableImpl
*table
,
783 struct ctab_constant
*constant
, const char *name
)
785 UINT i
, count
, length
;
786 struct ctab_constant
*handles
;
789 TRACE("table %p, constant %p, name %s\n", table
, constant
, debugstr_a(name
));
791 if (!name
|| !*name
) return NULL
;
795 count
= table
->desc
.Constants
;
796 handles
= table
->constants
;
800 count
= constant
->desc
.StructMembers
;
801 handles
= constant
->constants
;
804 length
= strcspn(name
, "[.");
805 part
= name
+ length
;
807 for (i
= 0; i
< count
; i
++)
809 if (strlen(handles
[i
].desc
.Name
) == length
&& !strncmp(handles
[i
].desc
.Name
, name
, length
))
814 return get_constant_by_name(NULL
, &handles
[i
], part
);
817 return get_constant_element_by_name(&handles
[i
], part
);
820 TRACE("Returning parameter %p\n", &handles
[i
]);
826 TRACE("Constant not found\n");
830 static struct ctab_constant
*is_valid_sub_constant(struct ctab_constant
*parent
, D3DXHANDLE handle
)
832 struct ctab_constant
*c
;
835 /* all variable have at least elements = 1, but not always elements */
836 if (!parent
->constants
) return NULL
;
838 count
= parent
->desc
.Elements
> 1 ? parent
->desc
.Elements
: parent
->desc
.StructMembers
;
839 for (i
= 0; i
< count
; ++i
)
841 if (handle_from_constant(&parent
->constants
[i
]) == handle
)
842 return &parent
->constants
[i
];
844 c
= is_valid_sub_constant(&parent
->constants
[i
], handle
);
851 static inline struct ctab_constant
*get_valid_constant(struct ID3DXConstantTableImpl
*table
, D3DXHANDLE handle
)
853 struct ctab_constant
*c
;
856 if (!handle
) return NULL
;
858 for (i
= 0; i
< table
->desc
.Constants
; ++i
)
860 if (handle_from_constant(&table
->constants
[i
]) == handle
)
861 return &table
->constants
[i
];
863 c
= is_valid_sub_constant(&table
->constants
[i
], handle
);
867 if (table
->flags
& D3DXCONSTTABLE_LARGEADDRESSAWARE
)
870 return get_constant_by_name(table
, NULL
, handle
);
873 /*** IUnknown methods ***/
874 static HRESULT WINAPI
ID3DXConstantTableImpl_QueryInterface(ID3DXConstantTable
*iface
, REFIID riid
, void **out
)
876 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
878 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
879 IsEqualGUID(riid
, &IID_ID3DXBuffer
) ||
880 IsEqualGUID(riid
, &IID_ID3DXConstantTable
))
882 ID3DXConstantTable_AddRef(iface
);
887 WARN("Interface %s not found.\n", debugstr_guid(riid
));
889 return E_NOINTERFACE
;
892 static ULONG WINAPI
ID3DXConstantTableImpl_AddRef(ID3DXConstantTable
*iface
)
894 struct ID3DXConstantTableImpl
*table
= impl_from_ID3DXConstantTable(iface
);
895 ULONG refcount
= InterlockedIncrement(&table
->ref
);
897 TRACE("%p increasing refcount to %lu.\n", table
, refcount
);
902 static ULONG WINAPI
ID3DXConstantTableImpl_Release(ID3DXConstantTable
*iface
)
904 struct ID3DXConstantTableImpl
*table
= impl_from_ID3DXConstantTable(iface
);
905 ULONG refcount
= InterlockedDecrement(&table
->ref
);
907 TRACE("%p decreasing refcount to %lu.\n", table
, refcount
);
911 free_constant_table(table
);
912 HeapFree(GetProcessHeap(), 0, table
);
918 /*** ID3DXBuffer methods ***/
919 static void * WINAPI
ID3DXConstantTableImpl_GetBufferPointer(ID3DXConstantTable
*iface
)
921 struct ID3DXConstantTableImpl
*table
= impl_from_ID3DXConstantTable(iface
);
923 TRACE("iface %p.\n", iface
);
928 static DWORD WINAPI
ID3DXConstantTableImpl_GetBufferSize(ID3DXConstantTable
*iface
)
930 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
932 TRACE("(%p)->()\n", This
);
937 /*** ID3DXConstantTable methods ***/
938 static HRESULT WINAPI
ID3DXConstantTableImpl_GetDesc(ID3DXConstantTable
*iface
, D3DXCONSTANTTABLE_DESC
*desc
)
940 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
942 TRACE("(%p)->(%p)\n", This
, desc
);
945 return D3DERR_INVALIDCALL
;
952 const struct ctab_constant
*d3dx_shader_get_ctab_constant(ID3DXConstantTable
*iface
, D3DXHANDLE constant
)
954 struct ID3DXConstantTableImpl
*ctab
= impl_from_ID3DXConstantTable(iface
);
956 return get_valid_constant(ctab
, constant
);
959 static HRESULT WINAPI
ID3DXConstantTableImpl_GetConstantDesc(ID3DXConstantTable
*iface
, D3DXHANDLE constant
,
960 D3DXCONSTANT_DESC
*desc
, UINT
*count
)
962 struct ID3DXConstantTableImpl
*ctab
= impl_from_ID3DXConstantTable(iface
);
963 struct ctab_constant
*c
= get_valid_constant(ctab
, constant
);
965 TRACE("(%p)->(%p, %p, %p)\n", ctab
, constant
, desc
, count
);
969 WARN("Invalid argument specified\n");
970 return D3DERR_INVALIDCALL
;
973 if (desc
) *desc
= c
->desc
;
974 if (count
) *count
= 1;
979 static UINT WINAPI
ID3DXConstantTableImpl_GetSamplerIndex(ID3DXConstantTable
*iface
, D3DXHANDLE constant
)
981 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
982 struct ctab_constant
*c
= get_valid_constant(This
, constant
);
984 TRACE("(%p)->(%p)\n", This
, constant
);
986 if (!c
|| c
->desc
.RegisterSet
!= D3DXRS_SAMPLER
)
988 WARN("Invalid argument specified\n");
992 TRACE("Returning RegisterIndex %u\n", c
->desc
.RegisterIndex
);
993 return c
->desc
.RegisterIndex
;
996 static D3DXHANDLE WINAPI
ID3DXConstantTableImpl_GetConstant(ID3DXConstantTable
*iface
, D3DXHANDLE constant
, UINT index
)
998 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
999 struct ctab_constant
*c
;
1001 TRACE("(%p)->(%p, %d)\n", This
, constant
, index
);
1005 c
= get_valid_constant(This
, constant
);
1006 if (c
&& index
< c
->desc
.StructMembers
)
1008 c
= &c
->constants
[index
];
1009 TRACE("Returning constant %p\n", c
);
1010 return handle_from_constant(c
);
1015 if (index
< This
->desc
.Constants
)
1017 c
= &This
->constants
[index
];
1018 TRACE("Returning constant %p\n", c
);
1019 return handle_from_constant(c
);
1023 WARN("Index out of range\n");
1027 static D3DXHANDLE WINAPI
ID3DXConstantTableImpl_GetConstantByName(ID3DXConstantTable
*iface
,
1028 D3DXHANDLE constant
, const char *name
)
1030 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1031 struct ctab_constant
*c
= get_valid_constant(This
, constant
);
1033 TRACE("iface %p, constant %p, name %s.\n", iface
, constant
, debugstr_a(name
));
1035 c
= get_constant_by_name(This
, c
, name
);
1036 TRACE("Returning constant %p\n", c
);
1038 return handle_from_constant(c
);
1041 static D3DXHANDLE WINAPI
ID3DXConstantTableImpl_GetConstantElement(ID3DXConstantTable
*iface
, D3DXHANDLE constant
, UINT index
)
1043 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1044 struct ctab_constant
*c
= get_valid_constant(This
, constant
);
1046 TRACE("(%p)->(%p, %d)\n", This
, constant
, index
);
1048 if (c
&& index
< c
->desc
.Elements
)
1050 if (c
->desc
.Elements
> 1) c
= &c
->constants
[index
];
1051 TRACE("Returning constant %p\n", c
);
1052 return handle_from_constant(c
);
1055 WARN("Invalid argument specified\n");
1059 static inline DWORD
get_index(const void **indata
, UINT index
, BOOL is_pointer
)
1065 return ((DWORD
**)indata
)[index
/ 16][index
% 16];
1067 return (*((DWORD
**)indata
))[index
];
1070 static UINT
set(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
, struct ctab_constant
*constant
,
1071 const void **indata
, D3DXPARAMETER_TYPE intype
, UINT
*size
, UINT incol
, D3DXPARAMETER_CLASS inclass
, UINT index
,
1074 D3DXCONSTANT_DESC
*desc
= &constant
->desc
;
1075 UINT l
, i
, regcount
= 1, regsize
= 1, cin
= 1, rin
= 1, ret
, last
= 0;
1078 /* size too small to set anything */
1079 if (*size
< desc
->Rows
* desc
->Columns
)
1085 /* D3DXPC_STRUCT is somewhat special */
1086 if (desc
->Class
== D3DXPC_STRUCT
)
1089 * Struct array sets the last complete input to the first struct element, all other
1090 * elements are not set.
1091 * E.g.: struct {int i;} s1[2];
1092 * SetValue(device, "s1", [1, 2], 8) => s1 = {2, x};
1094 * struct {int i; int n} s2[2];
1095 * SetValue(device, "s2", [1, 2, 3, 4, 5], 20) => s1 = {{3, 4}, {x, x}};
1097 if (desc
->Elements
> 1)
1099 UINT offset
= *size
/ (desc
->Rows
* desc
->Columns
) - 1;
1101 offset
= min(desc
->Elements
- 1, offset
);
1102 last
= offset
* desc
->Rows
* desc
->Columns
;
1104 if ((is_pointer
|| inclass
== D3DXPC_MATRIX_ROWS
) && desc
->RegisterSet
!= D3DXRS_BOOL
)
1106 set(table
, device
, &constant
->constants
[0], NULL
, intype
, size
, incol
, inclass
, 0, is_pointer
);
1110 last
+= set(table
, device
, &constant
->constants
[0], indata
, intype
, size
, incol
, inclass
,
1111 index
+ last
, is_pointer
);
1117 * D3DXRS_BOOL is always set. As there are only 16 bools and there are
1118 * exactly 16 input values, use matrix transpose.
1120 if (inclass
== D3DXPC_MATRIX_ROWS
&& desc
->RegisterSet
== D3DXRS_BOOL
)
1122 D3DXMATRIX mat
, *m
, min
;
1125 min
= *(D3DXMATRIX
*)(indata
[index
/ 16]);
1127 min
= **(D3DXMATRIX
**)indata
;
1129 D3DXMatrixTranspose(&mat
, &min
);
1131 for (i
= 0; i
< desc
->StructMembers
; ++i
)
1133 last
+= set(table
, device
, &constant
->constants
[i
], (const void **)&m
, intype
, size
, incol
,
1134 D3DXPC_SCALAR
, index
+ last
, is_pointer
);
1138 * For pointers or for matrix rows, only the first member is set.
1139 * All other members are set to 0. This is not true for D3DXRS_BOOL.
1140 * E.g.: struct {int i; int n} s;
1141 * SetValue(device, "s", [1, 2], 8) => s = {1, 0};
1143 else if ((is_pointer
|| inclass
== D3DXPC_MATRIX_ROWS
) && desc
->RegisterSet
!= D3DXRS_BOOL
)
1145 last
= set(table
, device
, &constant
->constants
[0], indata
, intype
, size
, incol
, inclass
,
1146 index
+ last
, is_pointer
);
1148 for (i
= 1; i
< desc
->StructMembers
; ++i
)
1150 set(table
, device
, &constant
->constants
[i
], NULL
, intype
, size
, incol
, inclass
, 0, is_pointer
);
1155 for (i
= 0; i
< desc
->StructMembers
; ++i
)
1157 last
+= set(table
, device
, &constant
->constants
[i
], indata
, intype
, size
, incol
, D3DXPC_SCALAR
,
1158 index
+ last
, is_pointer
);
1167 if (desc
->Elements
> 1)
1169 for (i
= 0; i
< desc
->Elements
&& *size
> 0; ++i
)
1171 last
+= set(table
, device
, &constant
->constants
[i
], indata
, intype
, size
, incol
, inclass
,
1172 index
+ last
, is_pointer
);
1174 /* adjust the vector size for matrix rows */
1175 if (inclass
== D3DXPC_MATRIX_ROWS
&& desc
->Class
== D3DXPC_VECTOR
&& (i
% 4) == 3)
1178 *size
= *size
< 12 ? 0 : *size
- 12;
1185 switch (desc
->Class
)
1189 case D3DXPC_MATRIX_ROWS
:
1190 regcount
= min(desc
->RegisterCount
, desc
->Rows
);
1191 if (inclass
== D3DXPC_MATRIX_ROWS
) cin
= incol
;
1193 regsize
= desc
->Columns
;
1196 case D3DXPC_MATRIX_COLUMNS
:
1197 regcount
= min(desc
->RegisterCount
, desc
->Columns
);
1198 if (inclass
== D3DXPC_MATRIX_ROWS
) rin
= incol
;
1200 regsize
= desc
->Rows
;
1204 FIXME("Unhandled variable class %s\n", debug_d3dxparameter_class(desc
->Class
));
1208 /* specific stuff for different in types */
1212 ret
= desc
->Columns
* desc
->Rows
;
1213 *size
-= desc
->Columns
* desc
->Rows
;
1217 switch (desc
->Class
)
1219 case D3DXPC_MATRIX_ROWS
:
1220 if (*size
< regcount
* 4)
1226 *size
-= 4 * regcount
;
1229 case D3DXPC_MATRIX_COLUMNS
:
1231 *size
-= 4 * regcount
;
1245 FIXME("Unhandled variable class %s\n", debug_d3dxparameter_class(desc
->Class
));
1250 case D3DXPC_MATRIX_ROWS
:
1251 switch (desc
->Class
)
1253 case D3DXPC_MATRIX_ROWS
:
1254 case D3DXPC_MATRIX_COLUMNS
:
1272 FIXME("Unhandled variable class %s\n", debug_d3dxparameter_class(desc
->Class
));
1278 case D3DXPC_MATRIX_COLUMNS
:
1279 switch (desc
->Class
)
1281 case D3DXPC_MATRIX_ROWS
:
1282 case D3DXPC_MATRIX_COLUMNS
:
1300 FIXME("Unhandled variable class %s\n", debug_d3dxparameter_class(desc
->Class
));
1307 FIXME("Unhandled variable class %s\n", debug_d3dxparameter_class(inclass
));
1311 /* set the registers */
1312 switch (desc
->RegisterSet
)
1315 regcount
= min(desc
->RegisterCount
, desc
->Columns
* desc
->Rows
);
1317 for (i
= 0; i
< regcount
; ++i
)
1320 DWORD t
= get_index(indata
, index
+ i
/ regsize
* rin
+ l
* cin
, is_pointer
);
1322 set_number(&tmp
, desc
->Type
, &t
, intype
);
1323 set_number(&out
, D3DXPT_BOOL
, &tmp
, desc
->Type
);
1324 if (is_vertex_shader(table
->desc
.Version
))
1325 IDirect3DDevice9_SetVertexShaderConstantB(device
, desc
->RegisterIndex
+ i
, &out
, 1);
1327 IDirect3DDevice9_SetPixelShaderConstantB(device
, desc
->RegisterIndex
+ i
, &out
, 1);
1329 if (++l
>= regsize
) l
= 0;
1334 for (i
= 0; i
< regcount
; ++i
)
1336 INT vec
[4] = {0, 0, 1, 0};
1338 for (l
= 0; l
< regsize
; ++l
)
1340 DWORD t
= get_index(indata
, index
+ i
* rin
+ l
* cin
, is_pointer
);
1342 set_number(&tmp
, desc
->Type
, &t
, intype
);
1343 set_number(&vec
[l
], D3DXPT_INT
, &tmp
, desc
->Type
);
1345 if (is_vertex_shader(table
->desc
.Version
))
1346 IDirect3DDevice9_SetVertexShaderConstantI(device
, desc
->RegisterIndex
+ i
, vec
, 1);
1348 IDirect3DDevice9_SetPixelShaderConstantI(device
, desc
->RegisterIndex
+ i
, vec
, 1);
1353 for (i
= 0; i
< regcount
; ++i
)
1357 for (l
= 0; l
< regsize
; ++l
)
1359 DWORD t
= get_index(indata
, index
+ i
* rin
+ l
* cin
, is_pointer
);
1361 set_number(&tmp
, desc
->Type
, &t
, intype
);
1362 set_number(&vec
[l
], D3DXPT_FLOAT
, &tmp
, desc
->Type
);
1364 if (is_vertex_shader(table
->desc
.Version
))
1365 IDirect3DDevice9_SetVertexShaderConstantF(device
, desc
->RegisterIndex
+ i
, vec
, 1);
1367 IDirect3DDevice9_SetPixelShaderConstantF(device
, desc
->RegisterIndex
+ i
, vec
, 1);
1372 FIXME("Unhandled register set %s\n", debug_d3dxparameter_registerset(desc
->RegisterSet
));
1377 static HRESULT
set_scalar(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
, D3DXHANDLE constant
,
1378 const void *indata
, D3DXPARAMETER_TYPE intype
)
1380 struct ctab_constant
*c
= get_valid_constant(table
, constant
);
1385 WARN("Invalid argument specified\n");
1386 return D3DERR_INVALIDCALL
;
1389 switch (c
->desc
.Class
)
1392 set(table
, device
, c
, &indata
, intype
, &count
, c
->desc
.Columns
, D3DXPC_SCALAR
, 0, FALSE
);
1396 case D3DXPC_MATRIX_ROWS
:
1397 case D3DXPC_MATRIX_COLUMNS
:
1402 FIXME("Unhandled parameter class %s\n", debug_d3dxparameter_class(c
->desc
.Class
));
1403 return D3DERR_INVALIDCALL
;
1407 static HRESULT
set_scalar_array(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
, D3DXHANDLE constant
,
1408 const void *indata
, UINT count
, D3DXPARAMETER_TYPE intype
)
1410 struct ctab_constant
*c
= get_valid_constant(table
, constant
);
1414 WARN("Invalid argument specified\n");
1415 return D3DERR_INVALIDCALL
;
1418 switch (c
->desc
.Class
)
1422 case D3DXPC_MATRIX_ROWS
:
1423 case D3DXPC_MATRIX_COLUMNS
:
1425 set(table
, device
, c
, &indata
, intype
, &count
, c
->desc
.Columns
, D3DXPC_SCALAR
, 0, FALSE
);
1429 FIXME("Unhandled parameter class %s\n", debug_d3dxparameter_class(c
->desc
.Class
));
1430 return D3DERR_INVALIDCALL
;
1434 static HRESULT
set_vector(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
, D3DXHANDLE constant
,
1435 const void *indata
, D3DXPARAMETER_TYPE intype
)
1437 struct ctab_constant
*c
= get_valid_constant(table
, constant
);
1442 WARN("Invalid argument specified\n");
1443 return D3DERR_INVALIDCALL
;
1446 switch (c
->desc
.Class
)
1451 set(table
, device
, c
, &indata
, intype
, &count
, 4, D3DXPC_VECTOR
, 0, FALSE
);
1454 case D3DXPC_MATRIX_ROWS
:
1455 case D3DXPC_MATRIX_COLUMNS
:
1459 FIXME("Unhandled parameter class %s\n", debug_d3dxparameter_class(c
->desc
.Class
));
1460 return D3DERR_INVALIDCALL
;
1464 static HRESULT
set_vector_array(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
, D3DXHANDLE constant
,
1465 const void *indata
, UINT count
, D3DXPARAMETER_TYPE intype
)
1467 struct ctab_constant
*c
= get_valid_constant(table
, constant
);
1471 WARN("Invalid argument specified\n");
1472 return D3DERR_INVALIDCALL
;
1475 switch (c
->desc
.Class
)
1479 case D3DXPC_MATRIX_ROWS
:
1480 case D3DXPC_MATRIX_COLUMNS
:
1483 set(table
, device
, c
, &indata
, intype
, &count
, 4, D3DXPC_VECTOR
, 0, FALSE
);
1487 FIXME("Unhandled parameter class %s\n", debug_d3dxparameter_class(c
->desc
.Class
));
1488 return D3DERR_INVALIDCALL
;
1492 static HRESULT
set_matrix_array(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
, D3DXHANDLE constant
,
1493 const void *indata
, UINT count
, BOOL transpose
)
1495 struct ctab_constant
*c
= get_valid_constant(table
, constant
);
1499 WARN("Invalid argument specified\n");
1500 return D3DERR_INVALIDCALL
;
1503 switch (c
->desc
.Class
)
1507 case D3DXPC_MATRIX_ROWS
:
1508 case D3DXPC_MATRIX_COLUMNS
:
1511 set(table
, device
, c
, &indata
, D3DXPT_FLOAT
, &count
, 4,
1512 transpose
? D3DXPC_MATRIX_ROWS
: D3DXPC_MATRIX_COLUMNS
, 0, FALSE
);
1516 FIXME("Unhandled parameter class %s\n", debug_d3dxparameter_class(c
->desc
.Class
));
1517 return D3DERR_INVALIDCALL
;
1521 static HRESULT
set_matrix_pointer_array(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
,
1522 D3DXHANDLE constant
, const void **indata
, UINT count
, BOOL transpose
)
1524 struct ctab_constant
*c
= get_valid_constant(table
, constant
);
1528 WARN("Invalid argument specified\n");
1529 return D3DERR_INVALIDCALL
;
1532 switch (c
->desc
.Class
)
1536 case D3DXPC_MATRIX_ROWS
:
1537 case D3DXPC_MATRIX_COLUMNS
:
1540 set(table
, device
, c
, indata
, D3DXPT_FLOAT
, &count
, 4,
1541 transpose
? D3DXPC_MATRIX_ROWS
: D3DXPC_MATRIX_COLUMNS
, 0, TRUE
);
1545 FIXME("Unhandled parameter class %s\n", debug_d3dxparameter_class(c
->desc
.Class
));
1546 return D3DERR_INVALIDCALL
;
1550 static HRESULT WINAPI
ID3DXConstantTableImpl_SetDefaults(struct ID3DXConstantTable
*iface
,
1551 struct IDirect3DDevice9
*device
)
1553 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1556 TRACE("iface %p, device %p\n", iface
, device
);
1560 WARN("Invalid argument specified\n");
1561 return D3DERR_INVALIDCALL
;
1564 for (i
= 0; i
< This
->desc
.Constants
; i
++)
1566 D3DXCONSTANT_DESC
*desc
= &This
->constants
[i
].desc
;
1569 if (!desc
->DefaultValue
)
1572 switch (desc
->RegisterSet
)
1575 if (is_vertex_shader(This
->desc
.Version
))
1576 hr
= IDirect3DDevice9_SetVertexShaderConstantB(device
, desc
->RegisterIndex
, desc
->DefaultValue
,
1577 desc
->RegisterCount
);
1579 hr
= IDirect3DDevice9_SetPixelShaderConstantB(device
, desc
->RegisterIndex
, desc
->DefaultValue
,
1580 desc
->RegisterCount
);
1584 if (is_vertex_shader(This
->desc
.Version
))
1585 hr
= IDirect3DDevice9_SetVertexShaderConstantI(device
, desc
->RegisterIndex
, desc
->DefaultValue
,
1586 desc
->RegisterCount
);
1588 hr
= IDirect3DDevice9_SetPixelShaderConstantI(device
, desc
->RegisterIndex
, desc
->DefaultValue
,
1589 desc
->RegisterCount
);
1593 if (is_vertex_shader(This
->desc
.Version
))
1594 hr
= IDirect3DDevice9_SetVertexShaderConstantF(device
, desc
->RegisterIndex
, desc
->DefaultValue
,
1595 desc
->RegisterCount
);
1597 hr
= IDirect3DDevice9_SetPixelShaderConstantF(device
, desc
->RegisterIndex
, desc
->DefaultValue
,
1598 desc
->RegisterCount
);
1602 FIXME("Unhandled register set %s\n", debug_d3dxparameter_registerset(desc
->RegisterSet
));
1614 static HRESULT WINAPI
ID3DXConstantTableImpl_SetValue(struct ID3DXConstantTable
*iface
,
1615 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const void *data
, unsigned int bytes
)
1617 struct ID3DXConstantTableImpl
*table
= impl_from_ID3DXConstantTable(iface
);
1618 struct ctab_constant
*c
= get_valid_constant(table
, constant
);
1619 D3DXCONSTANT_DESC
*desc
;
1621 TRACE("iface %p, device %p, constant %p, data %p, bytes %u\n", iface
, device
, constant
, data
, bytes
);
1623 if (!device
|| !c
|| !data
)
1625 WARN("Invalid argument specified\n");
1626 return D3DERR_INVALIDCALL
;
1631 switch (desc
->Class
)
1635 case D3DXPC_MATRIX_ROWS
:
1636 case D3DXPC_MATRIX_COLUMNS
:
1639 set(table
, device
, c
, &data
, desc
->Type
, &bytes
, desc
->Columns
, D3DXPC_SCALAR
, 0, FALSE
);
1643 FIXME("Unhandled parameter class %s\n", debug_d3dxparameter_class(desc
->Class
));
1644 return D3DERR_INVALIDCALL
;
1648 static HRESULT WINAPI
ID3DXConstantTableImpl_SetBool(struct ID3DXConstantTable
*iface
,
1649 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, BOOL b
)
1651 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1653 TRACE("iface %p, device %p, constant %p, b %d\n", iface
, device
, constant
, b
);
1655 return set_scalar(This
, device
, constant
, &b
, D3DXPT_BOOL
);
1658 static HRESULT WINAPI
ID3DXConstantTableImpl_SetBoolArray(struct ID3DXConstantTable
*iface
,
1659 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const BOOL
*b
, UINT count
)
1661 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1663 TRACE("iface %p, device %p, constant %p, b %p, count %d\n", iface
, device
, constant
, b
, count
);
1665 return set_scalar_array(This
, device
, constant
, b
, count
, D3DXPT_BOOL
);
1668 static HRESULT WINAPI
ID3DXConstantTableImpl_SetInt(struct ID3DXConstantTable
*iface
,
1669 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, INT n
)
1671 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1673 TRACE("iface %p, device %p, constant %p, n %d\n", iface
, device
, constant
, n
);
1675 return set_scalar(This
, device
, constant
, &n
, D3DXPT_INT
);
1678 static HRESULT WINAPI
ID3DXConstantTableImpl_SetIntArray(struct ID3DXConstantTable
*iface
,
1679 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const INT
*n
, UINT count
)
1681 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1683 TRACE("iface %p, device %p, constant %p, n %p, count %d\n", iface
, device
, constant
, n
, count
);
1685 return set_scalar_array(This
, device
, constant
, n
, count
, D3DXPT_INT
);
1688 static HRESULT WINAPI
ID3DXConstantTableImpl_SetFloat(struct ID3DXConstantTable
*iface
,
1689 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, float f
)
1691 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1693 TRACE("iface %p, device %p, constant %p, f %f\n", iface
, device
, constant
, f
);
1695 return set_scalar(This
, device
, constant
, &f
, D3DXPT_FLOAT
);
1698 static HRESULT WINAPI
ID3DXConstantTableImpl_SetFloatArray(struct ID3DXConstantTable
*iface
,
1699 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const float *f
, UINT count
)
1701 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1703 TRACE("iface %p, device %p, constant %p, f %p, count %d\n", iface
, device
, constant
, f
, count
);
1705 return set_scalar_array(This
, device
, constant
, f
, count
, D3DXPT_FLOAT
);
1708 static HRESULT WINAPI
ID3DXConstantTableImpl_SetVector(struct ID3DXConstantTable
*iface
,
1709 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXVECTOR4
*vector
)
1711 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1713 TRACE("iface %p, device %p, constant %p, vector %p\n", iface
, device
, constant
, vector
);
1715 return set_vector(This
, device
, constant
, vector
, D3DXPT_FLOAT
);
1718 static HRESULT WINAPI
ID3DXConstantTableImpl_SetVectorArray(struct ID3DXConstantTable
*iface
,
1719 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXVECTOR4
*vector
, UINT count
)
1721 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1723 TRACE("iface %p, device %p, constant %p, vector %p, count %u\n", iface
, device
, constant
, vector
, count
);
1725 return set_vector_array(This
, device
, constant
, vector
, count
, D3DXPT_FLOAT
);
1728 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrix(struct ID3DXConstantTable
*iface
,
1729 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXMATRIX
*matrix
)
1731 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1733 TRACE("iface %p, device %p, constant %p, matrix %p\n", iface
, device
, constant
, matrix
);
1735 return set_matrix_array(This
, device
, constant
, matrix
, 1, FALSE
);
1738 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrixArray(struct ID3DXConstantTable
*iface
,
1739 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXMATRIX
*matrix
, UINT count
)
1741 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1743 TRACE("iface %p, device %p, constant %p, matrix %p, count %u\n", iface
, device
, constant
, matrix
, count
);
1745 return set_matrix_array(This
, device
, constant
, matrix
, count
, FALSE
);
1748 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrixPointerArray(struct ID3DXConstantTable
*iface
,
1749 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXMATRIX
**matrix
, UINT count
)
1751 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1753 TRACE("iface %p, device %p, constant %p, matrix %p, count %u)\n", iface
, device
, constant
, matrix
, count
);
1755 return set_matrix_pointer_array(This
, device
, constant
, (const void **)matrix
, count
, FALSE
);
1758 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrixTranspose(struct ID3DXConstantTable
*iface
,
1759 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXMATRIX
*matrix
)
1761 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1763 TRACE("iface %p, device %p, constant %p, matrix %p\n", iface
, device
, constant
, matrix
);
1765 return set_matrix_array(This
, device
, constant
, matrix
, 1, TRUE
);
1768 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrixTransposeArray(struct ID3DXConstantTable
*iface
,
1769 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXMATRIX
*matrix
, UINT count
)
1771 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1773 TRACE("iface %p, device %p, constant %p, matrix %p, count %u\n", iface
, device
, constant
, matrix
, count
);
1775 return set_matrix_array(This
, device
, constant
, matrix
, count
, TRUE
);
1778 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrixTransposePointerArray(struct ID3DXConstantTable
*iface
,
1779 struct IDirect3DDevice9
*device
, D3DXHANDLE constant
, const D3DXMATRIX
**matrix
, UINT count
)
1781 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1783 TRACE("iface %p, device %p, constant %p, matrix %p, count %u)\n", iface
, device
, constant
, matrix
, count
);
1785 return set_matrix_pointer_array(This
, device
, constant
, (const void **)matrix
, count
, TRUE
);
1788 static const struct ID3DXConstantTableVtbl ID3DXConstantTable_Vtbl
=
1790 /*** IUnknown methods ***/
1791 ID3DXConstantTableImpl_QueryInterface
,
1792 ID3DXConstantTableImpl_AddRef
,
1793 ID3DXConstantTableImpl_Release
,
1794 /*** ID3DXBuffer methods ***/
1795 ID3DXConstantTableImpl_GetBufferPointer
,
1796 ID3DXConstantTableImpl_GetBufferSize
,
1797 /*** ID3DXConstantTable methods ***/
1798 ID3DXConstantTableImpl_GetDesc
,
1799 ID3DXConstantTableImpl_GetConstantDesc
,
1800 ID3DXConstantTableImpl_GetSamplerIndex
,
1801 ID3DXConstantTableImpl_GetConstant
,
1802 ID3DXConstantTableImpl_GetConstantByName
,
1803 ID3DXConstantTableImpl_GetConstantElement
,
1804 ID3DXConstantTableImpl_SetDefaults
,
1805 ID3DXConstantTableImpl_SetValue
,
1806 ID3DXConstantTableImpl_SetBool
,
1807 ID3DXConstantTableImpl_SetBoolArray
,
1808 ID3DXConstantTableImpl_SetInt
,
1809 ID3DXConstantTableImpl_SetIntArray
,
1810 ID3DXConstantTableImpl_SetFloat
,
1811 ID3DXConstantTableImpl_SetFloatArray
,
1812 ID3DXConstantTableImpl_SetVector
,
1813 ID3DXConstantTableImpl_SetVectorArray
,
1814 ID3DXConstantTableImpl_SetMatrix
,
1815 ID3DXConstantTableImpl_SetMatrixArray
,
1816 ID3DXConstantTableImpl_SetMatrixPointerArray
,
1817 ID3DXConstantTableImpl_SetMatrixTranspose
,
1818 ID3DXConstantTableImpl_SetMatrixTransposeArray
,
1819 ID3DXConstantTableImpl_SetMatrixTransposePointerArray
1822 static HRESULT
parse_ctab_constant_type(const char *ctab
, DWORD typeoffset
, struct ctab_constant
*constant
,
1823 BOOL is_element
, WORD index
, WORD max_index
, DWORD
*offset
, DWORD nameoffset
, UINT regset
)
1825 const D3DXSHADER_TYPEINFO
*type
= (LPD3DXSHADER_TYPEINFO
)(ctab
+ typeoffset
);
1826 const D3DXSHADER_STRUCTMEMBERINFO
*memberinfo
= NULL
;
1827 HRESULT hr
= D3D_OK
;
1831 constant
->desc
.DefaultValue
= offset
? ctab
+ *offset
: NULL
;
1832 constant
->desc
.Class
= type
->Class
;
1833 constant
->desc
.Type
= type
->Type
;
1834 constant
->desc
.Rows
= type
->Rows
;
1835 constant
->desc
.Columns
= type
->Columns
;
1836 constant
->desc
.Elements
= is_element
? 1 : type
->Elements
;
1837 constant
->desc
.StructMembers
= type
->StructMembers
;
1838 constant
->desc
.Name
= ctab
+ nameoffset
;
1839 constant
->desc
.RegisterSet
= regset
;
1840 constant
->desc
.RegisterIndex
= index
;
1842 TRACE("name %s, elements %u, index %u, defaultvalue %p, regset %s\n", constant
->desc
.Name
,
1843 constant
->desc
.Elements
, index
, constant
->desc
.DefaultValue
,
1844 debug_d3dxparameter_registerset(regset
));
1845 TRACE("class %s, type %s, rows %d, columns %d, elements %d, struct_members %d\n",
1846 debug_d3dxparameter_class(type
->Class
), debug_d3dxparameter_type(type
->Type
),
1847 type
->Rows
, type
->Columns
, type
->Elements
, type
->StructMembers
);
1849 if (type
->Elements
> 1 && !is_element
)
1851 count
= type
->Elements
;
1853 else if ((type
->Class
== D3DXPC_STRUCT
) && type
->StructMembers
)
1855 memberinfo
= (D3DXSHADER_STRUCTMEMBERINFO
*)(ctab
+ type
->StructMemberInfo
);
1856 count
= type
->StructMembers
;
1861 constant
->constants
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*constant
->constants
) * count
);
1862 if (!constant
->constants
)
1864 ERR("Out of memory\n");
1869 for (i
= 0; i
< count
; ++i
)
1871 hr
= parse_ctab_constant_type(ctab
, memberinfo
? memberinfo
[i
].TypeInfo
: typeoffset
,
1872 &constant
->constants
[i
], memberinfo
== NULL
, index
+ size
, max_index
, offset
,
1873 memberinfo
? memberinfo
[i
].Name
: nameoffset
, regset
);
1877 size
+= constant
->constants
[i
].desc
.RegisterCount
;
1882 WORD offsetdiff
= type
->Columns
* type
->Rows
;
1885 size
= type
->Columns
* type
->Rows
;
1890 fail
= type
->Class
!= D3DXPC_SCALAR
&& type
->Class
!= D3DXPC_VECTOR
1891 && type
->Class
!= D3DXPC_MATRIX_ROWS
&& type
->Class
!= D3DXPC_MATRIX_COLUMNS
;
1896 switch (type
->Class
)
1902 offsetdiff
= type
->Rows
* 4;
1905 case D3DXPC_MATRIX_ROWS
:
1906 offsetdiff
= type
->Rows
* 4;
1910 case D3DXPC_MATRIX_COLUMNS
:
1911 offsetdiff
= type
->Columns
* 4;
1912 size
= type
->Columns
;
1921 case D3DXRS_SAMPLER
:
1923 fail
= type
->Class
!= D3DXPC_OBJECT
;
1933 FIXME("Unhandled register set %s, type class %s\n", debug_d3dxparameter_registerset(regset
),
1934 debug_d3dxparameter_class(type
->Class
));
1937 /* offset in bytes => offsetdiff * sizeof(DWORD) */
1938 if (offset
) *offset
+= offsetdiff
* 4;
1941 constant
->desc
.RegisterCount
= max(0, min(max_index
- index
, size
));
1942 constant
->desc
.Bytes
= 4 * constant
->desc
.Elements
* type
->Rows
* type
->Columns
;
1947 if (constant
->constants
)
1949 for (i
= 0; i
< count
; ++i
)
1951 free_constant(&constant
->constants
[i
]);
1953 HeapFree(GetProcessHeap(), 0, constant
->constants
);
1954 constant
->constants
= NULL
;
1960 HRESULT WINAPI
D3DXGetShaderConstantTableEx(const DWORD
*byte_code
, DWORD flags
, ID3DXConstantTable
**constant_table
)
1962 struct ID3DXConstantTableImpl
*object
= NULL
;
1966 const D3DXSHADER_CONSTANTTABLE
*ctab_header
;
1967 const D3DXSHADER_CONSTANTINFO
*constant_info
;
1970 TRACE("byte_code %p, flags %#lx, constant_table %p.\n", byte_code
, flags
, constant_table
);
1973 *constant_table
= NULL
;
1975 if (!byte_code
|| !constant_table
)
1977 WARN("Invalid argument specified.\n");
1978 return D3DERR_INVALIDCALL
;
1981 if (!is_valid_bytecode(*byte_code
))
1983 WARN("Invalid byte_code specified.\n");
1987 if (flags
& ~D3DXCONSTTABLE_LARGEADDRESSAWARE
)
1988 FIXME("Flags %#lx not handled.\n", flags
);
1990 hr
= D3DXFindShaderComment(byte_code
, MAKEFOURCC('C','T','A','B'), &data
, &size
);
1993 WARN("CTAB not found.\n");
1994 return D3DXERR_INVALIDDATA
;
1997 if (size
< sizeof(*ctab_header
))
1999 WARN("Invalid CTAB size.\n");
2000 return D3DXERR_INVALIDDATA
;
2003 ctab_header
= (const D3DXSHADER_CONSTANTTABLE
*)data
;
2004 if (ctab_header
->Size
!= sizeof(*ctab_header
))
2006 WARN("Invalid D3DXSHADER_CONSTANTTABLE size.\n");
2007 return D3DXERR_INVALIDDATA
;
2010 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*object
));
2012 return E_OUTOFMEMORY
;
2014 object
->ID3DXConstantTable_iface
.lpVtbl
= &ID3DXConstantTable_Vtbl
;
2017 object
->ctab
= HeapAlloc(GetProcessHeap(), 0, size
);
2020 ERR("Out of memory\n");
2021 HeapFree(GetProcessHeap(), 0, object
);
2022 return E_OUTOFMEMORY
;
2024 object
->size
= size
;
2025 memcpy(object
->ctab
, data
, object
->size
);
2027 object
->flags
= flags
;
2028 object
->desc
.Creator
= ctab_header
->Creator
? object
->ctab
+ ctab_header
->Creator
: NULL
;
2029 object
->desc
.Version
= ctab_header
->Version
;
2030 object
->desc
.Constants
= ctab_header
->Constants
;
2031 TRACE("Creator %s, Version %#lx, Constants %u, Target %s.\n",
2032 debugstr_a(object
->desc
.Creator
), object
->desc
.Version
, object
->desc
.Constants
,
2033 debugstr_a(ctab_header
->Target
? object
->ctab
+ ctab_header
->Target
: NULL
));
2035 object
->constants
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
2036 sizeof(*object
->constants
) * object
->desc
.Constants
);
2037 if (!object
->constants
)
2039 ERR("Out of memory\n");
2044 constant_info
= (const D3DXSHADER_CONSTANTINFO
*)(object
->ctab
+ ctab_header
->ConstantInfo
);
2045 for (i
= 0; i
< ctab_header
->Constants
; i
++)
2047 DWORD offset
= constant_info
[i
].DefaultValue
;
2049 hr
= parse_ctab_constant_type(object
->ctab
, constant_info
[i
].TypeInfo
,
2050 &object
->constants
[i
], FALSE
, constant_info
[i
].RegisterIndex
,
2051 constant_info
[i
].RegisterIndex
+ constant_info
[i
].RegisterCount
,
2052 offset
? &offset
: NULL
, constant_info
[i
].Name
, constant_info
[i
].RegisterSet
);
2057 * Set the register count, it may differ for D3DXRS_INT4, because somehow
2058 * it makes the assumption that the register size is 1 instead of 4, so the
2059 * count is 4 times bigger. This holds true only for toplevel shader
2060 * constants. The count of elements and members is always based on a
2061 * register size of 4.
2063 if (object
->constants
[i
].desc
.RegisterSet
== D3DXRS_INT4
)
2065 object
->constants
[i
].desc
.RegisterCount
= constant_info
[i
].RegisterCount
;
2067 object
->constants
[i
].constantinfo_reserved
= constant_info
[i
].Reserved
;
2070 *constant_table
= &object
->ID3DXConstantTable_iface
;
2075 free_constant_table(object
);
2076 HeapFree(GetProcessHeap(), 0, object
);
2081 HRESULT WINAPI
D3DXGetShaderConstantTable(const DWORD
*byte_code
, ID3DXConstantTable
**constant_table
)
2083 TRACE("(%p, %p): Forwarded to D3DXGetShaderConstantTableEx\n", byte_code
, constant_table
);
2085 return D3DXGetShaderConstantTableEx(byte_code
, 0, constant_table
);
2088 struct d3dx9_fragment_linker
2090 ID3DXFragmentLinker ID3DXFragmentLinker_iface
;
2093 struct IDirect3DDevice9
*device
;
2097 static inline struct d3dx9_fragment_linker
*impl_from_ID3DXFragmentLinker(ID3DXFragmentLinker
*iface
)
2099 return CONTAINING_RECORD(iface
, struct d3dx9_fragment_linker
, ID3DXFragmentLinker_iface
);
2102 static HRESULT WINAPI
d3dx9_fragment_linker_QueryInterface(ID3DXFragmentLinker
*iface
, REFIID riid
, void **out
)
2104 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
2106 if (IsEqualGUID(riid
, &IID_IUnknown
)
2107 || IsEqualGUID(riid
, &IID_ID3DXFragmentLinker
))
2109 iface
->lpVtbl
->AddRef(iface
);
2114 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
2116 return E_NOINTERFACE
;
2119 static ULONG WINAPI
d3dx9_fragment_linker_AddRef(ID3DXFragmentLinker
*iface
)
2121 struct d3dx9_fragment_linker
*linker
= impl_from_ID3DXFragmentLinker(iface
);
2122 ULONG refcount
= InterlockedIncrement(&linker
->ref
);
2124 TRACE("%p increasing refcount to %lu.\n", linker
, refcount
);
2129 static ULONG WINAPI
d3dx9_fragment_linker_Release(ID3DXFragmentLinker
*iface
)
2131 struct d3dx9_fragment_linker
*linker
= impl_from_ID3DXFragmentLinker(iface
);
2132 ULONG refcount
= InterlockedDecrement(&linker
->ref
);
2134 TRACE("%p decreasing refcount to %lu.\n", linker
, refcount
);
2138 IDirect3DDevice9_Release(linker
->device
);
2145 static HRESULT WINAPI
d3dx9_fragment_linker_GetDevice(ID3DXFragmentLinker
*iface
, struct IDirect3DDevice9
**device
)
2147 struct d3dx9_fragment_linker
*linker
= impl_from_ID3DXFragmentLinker(iface
);
2149 TRACE("iface %p, device %p.\n", linker
, device
);
2153 WARN("Invalid argument supplied.\n");
2154 return D3DERR_INVALIDCALL
;
2157 IDirect3DDevice9_AddRef(linker
->device
);
2158 *device
= linker
->device
;
2159 TRACE("Returning device %p.\n", *device
);
2164 static UINT WINAPI
d3dx9_fragment_linker_GetNumberOfFragments(ID3DXFragmentLinker
*iface
)
2166 FIXME("iface %p: stub.\n", iface
);
2171 static D3DXHANDLE WINAPI
d3dx9_fragment_linker_GetFragmentHandleByIndex(ID3DXFragmentLinker
*iface
, UINT index
)
2173 FIXME("iface %p, index %u: stub.\n", iface
, index
);
2178 static D3DXHANDLE WINAPI
d3dx9_fragment_linker_GetFragmentHandleByName(ID3DXFragmentLinker
*iface
,
2181 FIXME("iface %p, name %s: stub.\n", iface
, debugstr_a(name
));
2186 static HRESULT WINAPI
d3dx9_fragment_linker_GetFragmentDesc(ID3DXFragmentLinker
*iface
, D3DXHANDLE name
,
2187 D3DXFRAGMENT_DESC
*desc
)
2189 FIXME("iface %p, name %p, desc %p: stub.\n", iface
, name
, desc
);
2194 static HRESULT WINAPI
d3dx9_fragment_linker_AddFragments(ID3DXFragmentLinker
*iface
, const DWORD
*fragments
)
2196 FIXME("iface %p, fragments %p: stub.\n", iface
, fragments
);
2201 static HRESULT WINAPI
d3dx9_fragment_linker_GetAllFragments(ID3DXFragmentLinker
*iface
, ID3DXBuffer
**buffer
)
2203 FIXME("iface %p, buffer %p: stub.\n", iface
, buffer
);
2208 static HRESULT WINAPI
d3dx9_fragment_linker_GetFragment(ID3DXFragmentLinker
*iface
, D3DXHANDLE name
,
2209 ID3DXBuffer
**buffer
)
2211 FIXME("iface %p, name %p, buffer %p: stub.\n", iface
, name
, buffer
);
2216 static HRESULT WINAPI
d3dx9_fragment_linker_LinkShader(ID3DXFragmentLinker
*iface
, const char *profile
,
2217 DWORD flags
, const D3DXHANDLE
*handles
, UINT fragment_count
, ID3DXBuffer
**buffer
,
2218 ID3DXBuffer
**errors
)
2220 FIXME("iface %p, profile %s, flags %#lx, handles %p, fragment_count %u, buffer %p, errors %p: stub.\n",
2221 iface
, debugstr_a(profile
), flags
, handles
, fragment_count
, buffer
, errors
);
2226 static HRESULT WINAPI
d3dx9_fragment_linker_LinkVertexShader(ID3DXFragmentLinker
*iface
, const char *profile
,
2227 DWORD flags
, const D3DXHANDLE
*handles
, UINT fragment_count
, IDirect3DVertexShader9
**shader
,
2228 ID3DXBuffer
**errors
)
2230 FIXME("iface %p, profile %s, flags %#lx, handles %p, fragment_count %u, shader %p, errors %p: stub.\n",
2231 iface
, debugstr_a(profile
), flags
, handles
, fragment_count
, shader
, errors
);
2236 static HRESULT WINAPI
d3dx9_fragment_linker_LinkPixelShader(ID3DXFragmentLinker
*iface
, const char *profile
,
2237 DWORD flags
, const D3DXHANDLE
*handles
, UINT fragment_count
, IDirect3DPixelShader9
**shader
,
2238 ID3DXBuffer
**errors
)
2240 FIXME("iface %p, profile %s, flags %#lx, handles %p, fragment_count %u, shader %p, errors %p: stub.\n",
2241 iface
, debugstr_a(profile
), flags
, handles
, fragment_count
, shader
, errors
);
2246 static HRESULT WINAPI
d3dx9_fragment_linker_ClearCache(ID3DXFragmentLinker
*iface
)
2248 FIXME("iface %p: stub.\n", iface
);
2253 static const struct ID3DXFragmentLinkerVtbl d3dx9_fragment_linker_vtbl
=
2255 d3dx9_fragment_linker_QueryInterface
,
2256 d3dx9_fragment_linker_AddRef
,
2257 d3dx9_fragment_linker_Release
,
2258 d3dx9_fragment_linker_GetDevice
,
2259 d3dx9_fragment_linker_GetNumberOfFragments
,
2260 d3dx9_fragment_linker_GetFragmentHandleByIndex
,
2261 d3dx9_fragment_linker_GetFragmentHandleByName
,
2262 d3dx9_fragment_linker_GetFragmentDesc
,
2263 d3dx9_fragment_linker_AddFragments
,
2264 d3dx9_fragment_linker_GetAllFragments
,
2265 d3dx9_fragment_linker_GetFragment
,
2266 d3dx9_fragment_linker_LinkShader
,
2267 d3dx9_fragment_linker_LinkVertexShader
,
2268 d3dx9_fragment_linker_LinkPixelShader
,
2269 d3dx9_fragment_linker_ClearCache
2272 HRESULT WINAPI
D3DXCreateFragmentLinkerEx(IDirect3DDevice9
*device
, UINT size
, DWORD flags
,
2273 ID3DXFragmentLinker
**linker
)
2275 struct d3dx9_fragment_linker
*object
;
2277 TRACE("device %p, size %u, flags %#lx, linker %p.\n", device
, size
, flags
, linker
);
2279 object
= heap_alloc(sizeof(*object
));
2281 return E_OUTOFMEMORY
;
2283 object
->ID3DXFragmentLinker_iface
.lpVtbl
= &d3dx9_fragment_linker_vtbl
;
2286 IDirect3DDevice9_AddRef(device
);
2287 object
->device
= device
;
2288 object
->flags
= flags
;
2290 *linker
= &object
->ID3DXFragmentLinker_iface
;
2295 HRESULT WINAPI
D3DXCreateFragmentLinker(IDirect3DDevice9
*device
, UINT size
, ID3DXFragmentLinker
**linker
)
2297 TRACE("device %p, size %u, linker %p.\n", device
, size
, linker
);
2299 return D3DXCreateFragmentLinkerEx(device
, size
, 0, linker
);
2302 HRESULT WINAPI
D3DXGetShaderSamplers(const DWORD
*byte_code
, const char **samplers
, UINT
*count
)
2304 UINT i
, sampler_count
= 0;
2307 const D3DXSHADER_CONSTANTTABLE
*ctab_header
;
2308 const D3DXSHADER_CONSTANTINFO
*constant_info
;
2310 TRACE("byte_code %p, samplers %p, count %p\n", byte_code
, samplers
, count
);
2312 if (count
) *count
= 0;
2314 if (D3DXFindShaderComment(byte_code
, MAKEFOURCC('C','T','A','B'), (const void **)&data
, &size
) != D3D_OK
)
2317 if (size
< sizeof(*ctab_header
)) return D3D_OK
;
2319 ctab_header
= (const D3DXSHADER_CONSTANTTABLE
*)data
;
2320 if (ctab_header
->Size
!= sizeof(*ctab_header
)) return D3D_OK
;
2322 constant_info
= (const D3DXSHADER_CONSTANTINFO
*)(data
+ ctab_header
->ConstantInfo
);
2323 for (i
= 0; i
< ctab_header
->Constants
; i
++)
2325 const D3DXSHADER_TYPEINFO
*type
;
2327 TRACE("name = %s\n", data
+ constant_info
[i
].Name
);
2329 type
= (const D3DXSHADER_TYPEINFO
*)(data
+ constant_info
[i
].TypeInfo
);
2331 if (type
->Type
== D3DXPT_SAMPLER
2332 || type
->Type
== D3DXPT_SAMPLER1D
2333 || type
->Type
== D3DXPT_SAMPLER2D
2334 || type
->Type
== D3DXPT_SAMPLER3D
2335 || type
->Type
== D3DXPT_SAMPLERCUBE
)
2337 if (samplers
) samplers
[sampler_count
] = data
+ constant_info
[i
].Name
;
2343 TRACE("Found %u samplers\n", sampler_count
);
2345 if (count
) *count
= sampler_count
;
2350 HRESULT WINAPI
D3DXDisassembleShader(const DWORD
*shader
, BOOL colorcode
, const char *comments
,
2351 ID3DXBuffer
**buffer
)
2353 TRACE("shader %p, colorcode %d, comments %s, buffer %p.\n", shader
, colorcode
, debugstr_a(comments
), buffer
);
2355 return D3DDisassemble(shader
, D3DXGetShaderSize(shader
), colorcode
? D3D_DISASM_ENABLE_COLOR_CODE
: 0,
2356 comments
, (ID3DBlob
**)buffer
);
2359 struct d3dx9_texture_shader
2361 ID3DXTextureShader ID3DXTextureShader_iface
;
2364 ID3DXBuffer
*byte_code
;
2365 ULONG64 version_counter
;
2366 struct d3dx_parameters_store parameters
;
2367 struct d3dx_param_eval
*eval
;
2370 static inline struct d3dx9_texture_shader
*impl_from_ID3DXTextureShader(ID3DXTextureShader
*iface
)
2372 return CONTAINING_RECORD(iface
, struct d3dx9_texture_shader
, ID3DXTextureShader_iface
);
2375 static HRESULT WINAPI
d3dx9_texture_shader_QueryInterface(ID3DXTextureShader
*iface
, REFIID riid
, void **out
)
2377 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
2379 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
2380 IsEqualGUID(riid
, &IID_ID3DXTextureShader
))
2382 iface
->lpVtbl
->AddRef(iface
);
2387 WARN("Interface %s not found.\n", debugstr_guid(riid
));
2389 return E_NOINTERFACE
;
2392 static ULONG WINAPI
d3dx9_texture_shader_AddRef(ID3DXTextureShader
*iface
)
2394 struct d3dx9_texture_shader
*texture_shader
= impl_from_ID3DXTextureShader(iface
);
2395 ULONG refcount
= InterlockedIncrement(&texture_shader
->ref
);
2397 TRACE("%p increasing refcount to %lu.\n", texture_shader
, refcount
);
2402 static ULONG WINAPI
d3dx9_texture_shader_Release(ID3DXTextureShader
*iface
)
2404 struct d3dx9_texture_shader
*texture_shader
= impl_from_ID3DXTextureShader(iface
);
2405 ULONG refcount
= InterlockedDecrement(&texture_shader
->ref
);
2407 TRACE("%p decreasing refcount to %lu.\n", texture_shader
, refcount
);
2411 if (texture_shader
->byte_code
)
2412 ID3DXBuffer_Release(texture_shader
->byte_code
);
2413 d3dx_free_param_eval(texture_shader
->eval
);
2414 d3dx_parameters_store_cleanup(&texture_shader
->parameters
);
2415 HeapFree(GetProcessHeap(), 0, texture_shader
);
2421 static HRESULT WINAPI
d3dx9_texture_shader_GetFunction(ID3DXTextureShader
*iface
, struct ID3DXBuffer
**function
)
2423 struct d3dx9_texture_shader
*texture_shader
= impl_from_ID3DXTextureShader(iface
);
2425 TRACE("iface %p, function %p.\n", iface
, function
);
2427 *function
= texture_shader
->byte_code
;
2428 ID3DXBuffer_AddRef(*function
);
2433 static HRESULT WINAPI
d3dx9_texture_shader_GetConstantBuffer(ID3DXTextureShader
*iface
, struct ID3DXBuffer
**constant_buffer
)
2435 FIXME("iface %p, constant_buffer %p stub.\n", iface
, constant_buffer
);
2440 static HRESULT WINAPI
d3dx9_texture_shader_GetDesc(ID3DXTextureShader
*iface
, D3DXCONSTANTTABLE_DESC
*desc
)
2442 FIXME("iface %p, desc %p stub.\n", iface
, desc
);
2447 static HRESULT WINAPI
d3dx9_texture_shader_GetConstantDesc(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, D3DXCONSTANT_DESC
*constant_desc
, UINT
*count
)
2449 FIXME("iface %p, constant %p, constant_desc %p, count %p stub.\n", iface
, constant
, constant_desc
, count
);
2454 static D3DXHANDLE WINAPI
d3dx9_texture_shader_GetConstant(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, UINT index
)
2456 FIXME("iface %p, constant %p, index %u stub.\n", iface
, constant
, index
);
2461 static D3DXHANDLE WINAPI
d3dx9_texture_shader_GetConstantByName(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const char *name
)
2463 FIXME("iface %p, constant %p, name %s stub.\n", iface
, constant
, debugstr_a(name
));
2468 static D3DXHANDLE WINAPI
d3dx9_texture_shader_GetConstantElement(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, UINT index
)
2470 FIXME("iface %p, constant %p, index %u stub.\n", iface
, constant
, index
);
2475 static HRESULT WINAPI
d3dx9_texture_shader_SetDefaults(ID3DXTextureShader
*iface
)
2477 FIXME("iface %p stub.\n", iface
);
2482 static HRESULT WINAPI
d3dx9_texture_shader_SetValue(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const void *data
, UINT bytes
)
2484 FIXME("iface %p, constant %p, data %p, bytes %u stub.\n", iface
, constant
, data
, bytes
);
2489 static HRESULT WINAPI
d3dx9_texture_shader_SetBool(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, BOOL b
)
2491 FIXME("iface %p, constant %p, b %u stub.\n", iface
, constant
, b
);
2496 static HRESULT WINAPI
d3dx9_texture_shader_SetBoolArray(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const BOOL
*b
, UINT count
)
2498 FIXME("iface %p, constant %p, b %p, count %u stub.\n", iface
, constant
, b
, count
);
2503 static HRESULT WINAPI
d3dx9_texture_shader_SetInt(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, INT n
)
2505 FIXME("iface %p, constant %p, n %d stub.\n", iface
, constant
, n
);
2510 static HRESULT WINAPI
d3dx9_texture_shader_SetIntArray(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const INT
*n
, UINT count
)
2512 FIXME("iface %p, constant %p, n %p, count %u stub.\n", iface
, constant
, n
, count
);
2517 static HRESULT WINAPI
d3dx9_texture_shader_SetFloat(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, FLOAT f
)
2519 FIXME("iface %p, constant %p, f %f stub.\n", iface
, constant
, f
);
2524 static HRESULT WINAPI
d3dx9_texture_shader_SetFloatArray(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const FLOAT
*f
, UINT count
)
2526 FIXME("iface %p, constant %p, f %p, count %u stub.\n", iface
, constant
, f
, count
);
2531 static HRESULT WINAPI
d3dx9_texture_shader_SetVector(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const D3DXVECTOR4
*vector
)
2533 FIXME("iface %p, constant %p, vector %p stub.\n", iface
, constant
, vector
);
2538 static HRESULT WINAPI
d3dx9_texture_shader_SetVectorArray(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const D3DXVECTOR4
*vector
, UINT count
)
2540 FIXME("iface %p, constant %p, vector %p, count %u stub.\n", iface
, constant
, vector
, count
);
2545 static HRESULT WINAPI
d3dx9_texture_shader_SetMatrix(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const D3DXMATRIX
*matrix
)
2547 FIXME("iface %p, constant %p, matrix %p stub.\n", iface
, constant
, matrix
);
2552 static HRESULT WINAPI
d3dx9_texture_shader_SetMatrixArray(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const D3DXMATRIX
*matrix
, UINT count
)
2554 FIXME("iface %p, constant %p, matrix %p, count %u stub.\n", iface
, constant
, matrix
, count
);
2559 static HRESULT WINAPI
d3dx9_texture_shader_SetMatrixPointerArray(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const D3DXMATRIX
**matrix
, UINT count
)
2561 FIXME("iface %p, constant %p, matrix %p, count %u stub.\n", iface
, constant
, matrix
, count
);
2566 static HRESULT WINAPI
d3dx9_texture_shader_SetMatrixTranspose(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const D3DXMATRIX
*matrix
)
2568 FIXME("iface %p, constant %p, matrix %p stub.\n", iface
, constant
, matrix
);
2573 static HRESULT WINAPI
d3dx9_texture_shader_SetMatrixTransposeArray(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const D3DXMATRIX
*matrix
, UINT count
)
2575 FIXME("iface %p, constant %p, matrix %p, count %u stub.\n", iface
, constant
, matrix
, count
);
2580 static HRESULT WINAPI
d3dx9_texture_shader_SetMatrixTransposePointerArray(ID3DXTextureShader
*iface
, D3DXHANDLE constant
, const D3DXMATRIX
**matrix
, UINT count
)
2582 FIXME("iface %p, constant %p, matrix %p, count %u stub.\n", iface
, constant
, matrix
, count
);
2587 static const struct ID3DXTextureShaderVtbl d3dx9_texture_shader_vtbl
=
2589 /*** IUnknown methods ***/
2590 d3dx9_texture_shader_QueryInterface
,
2591 d3dx9_texture_shader_AddRef
,
2592 d3dx9_texture_shader_Release
,
2593 /*** ID3DXTextureShader methods ***/
2594 d3dx9_texture_shader_GetFunction
,
2595 d3dx9_texture_shader_GetConstantBuffer
,
2596 d3dx9_texture_shader_GetDesc
,
2597 d3dx9_texture_shader_GetConstantDesc
,
2598 d3dx9_texture_shader_GetConstant
,
2599 d3dx9_texture_shader_GetConstantByName
,
2600 d3dx9_texture_shader_GetConstantElement
,
2601 d3dx9_texture_shader_SetDefaults
,
2602 d3dx9_texture_shader_SetValue
,
2603 d3dx9_texture_shader_SetBool
,
2604 d3dx9_texture_shader_SetBoolArray
,
2605 d3dx9_texture_shader_SetInt
,
2606 d3dx9_texture_shader_SetIntArray
,
2607 d3dx9_texture_shader_SetFloat
,
2608 d3dx9_texture_shader_SetFloatArray
,
2609 d3dx9_texture_shader_SetVector
,
2610 d3dx9_texture_shader_SetVectorArray
,
2611 d3dx9_texture_shader_SetMatrix
,
2612 d3dx9_texture_shader_SetMatrixArray
,
2613 d3dx9_texture_shader_SetMatrixPointerArray
,
2614 d3dx9_texture_shader_SetMatrixTranspose
,
2615 d3dx9_texture_shader_SetMatrixTransposeArray
,
2616 d3dx9_texture_shader_SetMatrixTransposePointerArray
2619 static inline struct d3dx9_texture_shader
*unsafe_impl_from_ID3DXTextureShader(ID3DXTextureShader
*iface
)
2624 assert(iface
->lpVtbl
== &d3dx9_texture_shader_vtbl
);
2625 return impl_from_ID3DXTextureShader(iface
);
2628 HRESULT WINAPI
D3DXCreateTextureShader(const DWORD
*function
, ID3DXTextureShader
**texture_shader
)
2630 struct d3dx9_texture_shader
*object
;
2634 TRACE("function %p, texture_shader %p.\n", function
, texture_shader
);
2636 if (!function
|| !texture_shader
)
2637 return D3DERR_INVALIDCALL
;
2639 if (!(size
= D3DXGetShaderSize(function
)))
2640 return D3DXERR_INVALIDDATA
;
2642 if (!(object
= heap_alloc_zero(sizeof(*object
))))
2643 return E_OUTOFMEMORY
;
2645 object
->ID3DXTextureShader_iface
.lpVtbl
= &d3dx9_texture_shader_vtbl
;
2648 if (FAILED(hr
= D3DXCreateBuffer(size
, &object
->byte_code
)))
2650 IUnknown_Release(&object
->ID3DXTextureShader_iface
);
2653 memcpy(ID3DXBuffer_GetBufferPointer(object
->byte_code
), function
, size
);
2655 if (FAILED(hr
= d3dx_init_parameters_store(&object
->parameters
, 0)))
2657 IUnknown_Release(&object
->ID3DXTextureShader_iface
);
2661 if (FAILED(hr
= d3dx_create_param_eval(&object
->parameters
, ID3DXBuffer_GetBufferPointer(object
->byte_code
),
2662 size
, D3DXPT_FLOAT
, &object
->eval
, &object
->version_counter
, NULL
, 0)))
2664 IUnknown_Release(&object
->ID3DXTextureShader_iface
);
2668 *texture_shader
= &object
->ID3DXTextureShader_iface
;
2673 void WINAPI
texture_shader_fill_2d(D3DXVECTOR4
*out
, const D3DXVECTOR2
*texcoord
,
2674 const D3DXVECTOR2
*texelsize
, void *data
)
2676 struct d3dx9_texture_shader
*shader
= data
;
2677 struct d3dx_parameter param
= { 0 };
2680 inputs
= (float *)shader
->eval
->pres
.regs
.tables
[PRES_REGTAB_INPUT
];
2682 *(inputs
++) = texcoord
->x
;
2683 *(inputs
++) = texcoord
->y
;
2687 *(inputs
++) = texelsize
->x
;
2688 *(inputs
++) = texelsize
->y
;
2692 param
.type
= D3DXPT_FLOAT
;
2693 param
.bytes
= 4 * sizeof(float);
2694 d3dx_evaluate_parameter(shader
->eval
, ¶m
, out
);
2697 void WINAPI
texture_shader_fill_3d(D3DXVECTOR4
*out
, const D3DXVECTOR3
*texcoord
,
2698 const D3DXVECTOR3
*texelsize
, void *data
)
2700 struct d3dx9_texture_shader
*shader
= data
;
2701 struct d3dx_parameter param
= { 0 };
2704 inputs
= (float *)shader
->eval
->pres
.regs
.tables
[PRES_REGTAB_INPUT
];
2706 *(inputs
++) = texcoord
->x
;
2707 *(inputs
++) = texcoord
->y
;
2708 *(inputs
++) = texcoord
->z
;
2711 *(inputs
++) = texelsize
->x
;
2712 *(inputs
++) = texelsize
->y
;
2713 *(inputs
++) = texelsize
->z
;
2716 param
.type
= D3DXPT_FLOAT
;
2717 param
.bytes
= 4 * sizeof(float);
2718 d3dx_evaluate_parameter(shader
->eval
, ¶m
, out
);
2721 HRESULT WINAPI
D3DXFillTextureTX(struct IDirect3DTexture9
*texture
, ID3DXTextureShader
*texture_shader
)
2723 struct d3dx9_texture_shader
*shader
= unsafe_impl_from_ID3DXTextureShader(texture_shader
);
2725 TRACE("texture %p, texture_shader %p.\n", texture
, texture_shader
);
2727 return D3DXFillTexture(texture
, texture_shader_fill_2d
, shader
);
2730 HRESULT WINAPI
D3DXFillCubeTextureTX(struct IDirect3DCubeTexture9
*cube
, ID3DXTextureShader
*texture_shader
)
2732 struct d3dx9_texture_shader
*shader
= unsafe_impl_from_ID3DXTextureShader(texture_shader
);
2734 TRACE("cube %p, texture_shader %p.\n", cube
, texture_shader
);
2736 return D3DXFillCubeTexture(cube
, texture_shader_fill_3d
, shader
);
2739 static unsigned int get_instr_length(const DWORD
*byte_code
, unsigned int major
, unsigned int minor
)
2741 DWORD opcode
= *byte_code
& 0xffff;
2742 unsigned int len
= 0;
2744 if (opcode
== D3DSIO_COMMENT
)
2745 return (*byte_code
& D3DSI_COMMENTSIZE_MASK
) >> D3DSI_COMMENTSIZE_SHIFT
;
2748 return (*byte_code
& D3DSI_INSTLENGTH_MASK
) >> D3DSI_INSTLENGTH_SHIFT
;
2753 ERR("Unexpected END token.\n");
2762 while (*byte_code
& 0x80000000)
2772 static HRESULT
get_shader_semantics(const DWORD
*byte_code
, D3DXSEMANTIC
*semantics
, UINT
*count
, BOOL output
)
2774 static const D3DDECLUSAGE regtype_usage
[] =
2779 D3DDECLUSAGE_TEXCOORD
,
2782 D3DDECLUSAGE_TEXCOORD
,
2787 static const D3DDECLUSAGE rast_usage
[] =
2789 D3DDECLUSAGE_POSITION
,
2793 uint32_t reg_type
, usage
, index
, version_token
= *byte_code
;
2794 BOOL is_ps
= version_token
>> 16 == 0xffff;
2795 unsigned int major
, minor
, i
= 0, j
;
2796 BYTE colors
= 0, rastout
= 0;
2797 BOOL has_dcl
, depth
= 0;
2800 if ((version_token
& 0xffff0000) != 0xfffe0000 && (version_token
& 0xffff0000) != 0xffff0000)
2801 return D3DXERR_INVALIDDATA
;
2803 major
= version_token
>> 8 & 0xff;
2804 minor
= version_token
& 0xff;
2806 TRACE("%s shader, version %u.%u.\n", is_ps
? "Pixel" : "Vertex", major
, minor
);
2809 has_dcl
= (!is_ps
&& (!output
|| major
== 3)) || (is_ps
&& !output
&& major
>= 2);
2811 while (*byte_code
!= D3DSIO_END
)
2813 if (has_dcl
&& (*byte_code
& 0xffff) == D3DSIO_DCL
)
2815 uint32_t usage_token
= byte_code
[1];
2816 uint32_t reg
= byte_code
[2];
2818 reg_type
= ((reg
& D3DSP_REGTYPE_MASK
) >> D3DSP_REGTYPE_SHIFT
)
2819 | ((reg
& D3DSP_REGTYPE_MASK2
) >> D3DSP_REGTYPE_SHIFT2
);
2821 if (is_ps
&& !output
&& major
== 2)
2823 /* dcl with no explicit usage, look at the register. */
2824 reg_type
= ((reg
& D3DSP_REGTYPE_MASK
) >> D3DSP_REGTYPE_SHIFT
)
2825 | ((reg
& D3DSP_REGTYPE_MASK2
) >> D3DSP_REGTYPE_SHIFT2
);
2826 index
= reg
& D3DSP_REGNUM_MASK
;
2827 if (reg_type
>= ARRAY_SIZE(regtype_usage
))
2829 WARN("Invalid register type %u.\n", reg_type
);
2832 usage
= regtype_usage
[reg_type
];
2835 semantics
[i
].Usage
= usage
;
2836 semantics
[i
].UsageIndex
= index
;
2840 else if ((!output
&& reg_type
== D3DSPR_INPUT
) || (output
&& reg_type
== D3DSPR_OUTPUT
))
2844 semantics
[i
].Usage
=
2845 (usage_token
& D3DSP_DCL_USAGE_MASK
) >> D3DSP_DCL_USAGE_SHIFT
;
2846 semantics
[i
].UsageIndex
=
2847 (usage_token
& D3DSP_DCL_USAGEINDEX_MASK
) >> D3DSP_DCL_USAGEINDEX_SHIFT
;
2855 unsigned int len
= get_instr_length(byte_code
, major
, minor
) + 1;
2857 switch (*byte_code
& 0xffff)
2859 case D3DSIO_COMMENT
:
2867 while (*byte_code
& 0x80000000)
2869 reg_type
= ((*byte_code
& D3DSP_REGTYPE_MASK
) >> D3DSP_REGTYPE_SHIFT
)
2870 | ((*byte_code
& D3DSP_REGTYPE_MASK2
) >> D3DSP_REGTYPE_SHIFT2
);
2871 index
= *byte_code
& D3DSP_REGNUM_MASK
;
2873 if ((reg_type
== D3DSPR_TEMP
&& is_ps
&& major
== 1)
2874 || (reg_type
== D3DSPR_INPUT
&& is_ps
)
2875 || (reg_type
== D3DSPR_TEXTURE
&& is_ps
&& !output
)
2876 || reg_type
== D3DSPR_RASTOUT
2877 || reg_type
== D3DSPR_ATTROUT
2878 || reg_type
== D3DSPR_OUTPUT
2879 || reg_type
== D3DSPR_DEPTHOUT
)
2881 if (reg_type
== D3DSPR_RASTOUT
)
2882 rastout
|= 1u << index
;
2883 else if (reg_type
== D3DSPR_DEPTHOUT
)
2885 else if (reg_type
== D3DSPR_TEXTURE
|| reg_type
== D3DSPR_OUTPUT
)
2886 texcoords
|= 1u << index
;
2888 colors
|= 1u << index
;
2896 byte_code
+= get_instr_length(byte_code
, major
, minor
) + 1;
2909 semantics
[i
].Usage
= D3DDECLUSAGE_TEXCOORD
;
2910 semantics
[i
].UsageIndex
= j
;
2924 semantics
[i
].Usage
= D3DDECLUSAGE_COLOR
;
2925 semantics
[i
].UsageIndex
= j
;
2937 if (j
>= ARRAY_SIZE(rast_usage
))
2939 WARN("Invalid RASTOUT register index.\n");
2944 usage
= rast_usage
[j
];
2948 semantics
[i
].Usage
= usage
;
2949 semantics
[i
].UsageIndex
= 0;
2960 semantics
[i
].Usage
= D3DDECLUSAGE_DEPTH
;
2961 semantics
[i
].UsageIndex
= 0;
2973 HRESULT WINAPI
D3DXGetShaderInputSemantics(const DWORD
*byte_code
, D3DXSEMANTIC
*semantics
, UINT
*count
)
2975 TRACE("byte_code %p, semantics %p, count %p.\n", byte_code
, semantics
, count
);
2977 return get_shader_semantics(byte_code
, semantics
, count
, FALSE
);
2980 HRESULT WINAPI
D3DXGetShaderOutputSemantics(const DWORD
*byte_code
, D3DXSEMANTIC
*semantics
, UINT
*count
)
2982 TRACE("byte_code %p, semantics %p, count %p.\n", byte_code
, semantics
, count
);
2984 return get_shader_semantics(byte_code
, semantics
, count
, TRUE
);