2 * Copyright 2008 Luis Busquets
3 * Copyright 2009 Matteo Bruni
4 * Copyright 2011 Travis Athougies
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include "wine/port.h"
24 #define NONAMELESSUNION
25 #define NONAMELESSSTRUCT
26 #include "wine/debug.h"
27 #include "wine/unicode.h"
31 #include "d3dcommon.h"
32 #include "d3dcompiler.h"
33 #include "d3dx9_36_private.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(d3dx
);
37 /* This function is not declared in the SDK headers yet */
38 HRESULT WINAPI
D3DAssemble(LPCVOID data
, SIZE_T datasize
, LPCSTR filename
,
39 const D3D_SHADER_MACRO
*defines
, ID3DInclude
*include
,
41 ID3DBlob
**shader
, ID3DBlob
**error_messages
);
43 LPCSTR WINAPI
D3DXGetPixelShaderProfile(LPDIRECT3DDEVICE9 device
)
47 TRACE("device %p\n", device
);
49 if (!device
) return NULL
;
51 IDirect3DDevice9_GetDeviceCaps(device
,&caps
);
53 switch (caps
.PixelShaderVersion
)
55 case D3DPS_VERSION(1, 1):
58 case D3DPS_VERSION(1, 2):
61 case D3DPS_VERSION(1, 3):
64 case D3DPS_VERSION(1, 4):
67 case D3DPS_VERSION(2, 0):
68 if ((caps
.PS20Caps
.NumTemps
>=22) &&
69 (caps
.PS20Caps
.Caps
&D3DPS20CAPS_ARBITRARYSWIZZLE
) &&
70 (caps
.PS20Caps
.Caps
&D3DPS20CAPS_GRADIENTINSTRUCTIONS
) &&
71 (caps
.PS20Caps
.Caps
&D3DPS20CAPS_PREDICATION
) &&
72 (caps
.PS20Caps
.Caps
&D3DPS20CAPS_NODEPENDENTREADLIMIT
) &&
73 (caps
.PS20Caps
.Caps
&D3DPS20CAPS_NOTEXINSTRUCTIONLIMIT
))
77 if ((caps
.PS20Caps
.NumTemps
>=32) &&
78 (caps
.PS20Caps
.Caps
&D3DPS20CAPS_NOTEXINSTRUCTIONLIMIT
))
84 case D3DPS_VERSION(3, 0):
91 UINT WINAPI
D3DXGetShaderSize(const DWORD
*byte_code
)
93 const DWORD
*ptr
= byte_code
;
95 TRACE("byte_code %p\n", byte_code
);
99 /* Look for the END token, skipping the VERSION token */
100 while (*++ptr
!= D3DSIO_END
)
103 if ((*ptr
& D3DSI_OPCODE_MASK
) == D3DSIO_COMMENT
)
105 ptr
+= ((*ptr
& D3DSI_COMMENTSIZE_MASK
) >> D3DSI_COMMENTSIZE_SHIFT
);
110 /* Return the shader size in bytes */
111 return (ptr
- byte_code
) * sizeof(*ptr
);
114 DWORD WINAPI
D3DXGetShaderVersion(const DWORD
*byte_code
)
116 TRACE("byte_code %p\n", byte_code
);
118 return byte_code
? *byte_code
: 0;
121 LPCSTR WINAPI
D3DXGetVertexShaderProfile(LPDIRECT3DDEVICE9 device
)
125 TRACE("device %p\n", device
);
127 if (!device
) return NULL
;
129 IDirect3DDevice9_GetDeviceCaps(device
,&caps
);
131 switch (caps
.VertexShaderVersion
)
133 case D3DVS_VERSION(1, 1):
135 case D3DVS_VERSION(2, 0):
136 if ((caps
.VS20Caps
.NumTemps
>=13) &&
137 (caps
.VS20Caps
.DynamicFlowControlDepth
==24) &&
138 (caps
.VS20Caps
.Caps
&D3DPS20CAPS_PREDICATION
))
143 case D3DVS_VERSION(3, 0):
150 HRESULT WINAPI
D3DXFindShaderComment(CONST DWORD
* byte_code
, DWORD fourcc
, LPCVOID
* data
, UINT
* size
)
152 CONST DWORD
*ptr
= byte_code
;
154 TRACE("(%p, %x, %p, %p)\n", byte_code
, fourcc
, data
, size
);
156 if (data
) *data
= NULL
;
160 return D3DERR_INVALIDCALL
;
162 while (*++ptr
!= D3DSIO_END
)
164 /* Check if it is a comment */
165 if ((*ptr
& D3DSI_OPCODE_MASK
) == D3DSIO_COMMENT
)
167 DWORD comment_size
= (*ptr
& D3DSI_COMMENTSIZE_MASK
) >> D3DSI_COMMENTSIZE_SHIFT
;
169 /* Check if this is the comment we are looking for */
170 if (*(ptr
+ 1) == fourcc
)
172 UINT ctab_size
= (comment_size
- 1) * sizeof(DWORD
);
173 LPCVOID ctab_data
= ptr
+ 2;
178 TRACE("Returning comment data at %p with size %d\n", ctab_data
, ctab_size
);
188 HRESULT WINAPI
D3DXAssembleShader(LPCSTR data
,
190 CONST D3DXMACRO
* defines
,
191 LPD3DXINCLUDE include
,
193 LPD3DXBUFFER
* shader
,
194 LPD3DXBUFFER
* error_messages
)
196 /* Forward to d3dcompiler: the parameter types aren't really different,
197 the actual data types are equivalent */
198 HRESULT hr
= D3DAssemble(data
, data_len
, NULL
, (D3D_SHADER_MACRO
*)defines
,
199 (ID3DInclude
*)include
, flags
, (ID3DBlob
**)shader
,
200 (ID3DBlob
**)error_messages
);
202 if(hr
== E_FAIL
) hr
= D3DXERR_INVALIDDATA
;
206 /* D3DXInclude private implementation, used to implement
207 D3DXAssembleShaderFromFile from D3DXAssembleShader */
208 /* To be able to correctly resolve include search paths we have to store
209 the pathname of each include file. We store the pathname pointer right
210 before the file data. */
211 static HRESULT WINAPI
d3dincludefromfile_open(ID3DXInclude
*iface
,
212 D3DXINCLUDE_TYPE include_type
,
213 LPCSTR filename
, LPCVOID parent_data
,
214 LPCVOID
*data
, UINT
*bytes
) {
215 const char *p
, *parent_name
= "";
216 char *pathname
= NULL
;
217 char **buffer
= NULL
;
221 if(parent_data
!= NULL
)
222 parent_name
= *((const char **)parent_data
- 1);
224 TRACE("Looking up for include file %s, parent %s\n", debugstr_a(filename
), debugstr_a(parent_name
));
226 if ((p
= strrchr(parent_name
, '\\')) || (p
= strrchr(parent_name
, '/'))) p
++;
227 else p
= parent_name
;
228 pathname
= HeapAlloc(GetProcessHeap(), 0, (p
- parent_name
) + strlen(filename
) + 1);
230 return HRESULT_FROM_WIN32(GetLastError());
232 memcpy(pathname
, parent_name
, p
- parent_name
);
233 strcpy(pathname
+ (p
- parent_name
), filename
);
235 file
= CreateFileA(pathname
, GENERIC_READ
, FILE_SHARE_READ
, 0, OPEN_EXISTING
, 0, 0);
236 if(file
== INVALID_HANDLE_VALUE
)
239 TRACE("Include file found at pathname = %s\n", debugstr_a(pathname
));
241 size
= GetFileSize(file
, NULL
);
242 if(size
== INVALID_FILE_SIZE
)
245 buffer
= HeapAlloc(GetProcessHeap(), 0, size
+ sizeof(char *));
249 if(!ReadFile(file
, buffer
+ 1, size
, bytes
, NULL
))
259 HeapFree(GetProcessHeap(), 0, pathname
);
260 HeapFree(GetProcessHeap(), 0, buffer
);
261 return HRESULT_FROM_WIN32(GetLastError());
264 static HRESULT WINAPI
d3dincludefromfile_close(ID3DXInclude
*iface
, LPCVOID data
) {
265 HeapFree(GetProcessHeap(), 0, *((char **)data
- 1));
266 HeapFree(GetProcessHeap(), 0, (char **)data
- 1);
270 static const struct ID3DXIncludeVtbl D3DXInclude_Vtbl
= {
271 d3dincludefromfile_open
,
272 d3dincludefromfile_close
275 struct D3DXIncludeImpl
{
276 ID3DXInclude ID3DXInclude_iface
;
279 HRESULT WINAPI
D3DXAssembleShaderFromFileA(LPCSTR filename
,
280 CONST D3DXMACRO
* defines
,
281 LPD3DXINCLUDE include
,
283 LPD3DXBUFFER
* shader
,
284 LPD3DXBUFFER
* error_messages
)
286 LPWSTR filename_w
= NULL
;
290 if (!filename
) return D3DXERR_INVALIDDATA
;
292 len
= MultiByteToWideChar(CP_ACP
, 0, filename
, -1, NULL
, 0);
293 filename_w
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
294 if (!filename_w
) return E_OUTOFMEMORY
;
295 MultiByteToWideChar(CP_ACP
, 0, filename
, -1, filename_w
, len
);
297 ret
= D3DXAssembleShaderFromFileW(filename_w
, defines
, include
, flags
, shader
, error_messages
);
299 HeapFree(GetProcessHeap(), 0, filename_w
);
303 HRESULT WINAPI
D3DXAssembleShaderFromFileW(LPCWSTR filename
,
304 CONST D3DXMACRO
* defines
,
305 LPD3DXINCLUDE include
,
307 LPD3DXBUFFER
* shader
,
308 LPD3DXBUFFER
* error_messages
)
313 struct D3DXIncludeImpl includefromfile
;
315 if(FAILED(map_view_of_file(filename
, &buffer
, &len
)))
316 return D3DXERR_INVALIDDATA
;
320 includefromfile
.ID3DXInclude_iface
.lpVtbl
= &D3DXInclude_Vtbl
;
321 include
= &includefromfile
.ID3DXInclude_iface
;
324 hr
= D3DXAssembleShader(buffer
, len
, defines
, include
, flags
,
325 shader
, error_messages
);
327 UnmapViewOfFile(buffer
);
331 HRESULT WINAPI
D3DXAssembleShaderFromResourceA(HMODULE module
,
333 CONST D3DXMACRO
* defines
,
334 LPD3DXINCLUDE include
,
336 LPD3DXBUFFER
* shader
,
337 LPD3DXBUFFER
* error_messages
)
343 if (!(res
= FindResourceA(module
, resource
, (LPCSTR
)RT_RCDATA
)))
344 return D3DXERR_INVALIDDATA
;
345 if (FAILED(load_resource_into_memory(module
, res
, (LPVOID
*)&buffer
, &len
)))
346 return D3DXERR_INVALIDDATA
;
347 return D3DXAssembleShader(buffer
, len
, defines
, include
, flags
,
348 shader
, error_messages
);
351 HRESULT WINAPI
D3DXAssembleShaderFromResourceW(HMODULE module
,
353 CONST D3DXMACRO
* defines
,
354 LPD3DXINCLUDE include
,
356 LPD3DXBUFFER
* shader
,
357 LPD3DXBUFFER
* error_messages
)
363 if (!(res
= FindResourceW(module
, resource
, (LPCWSTR
)RT_RCDATA
)))
364 return D3DXERR_INVALIDDATA
;
365 if (FAILED(load_resource_into_memory(module
, res
, (LPVOID
*)&buffer
, &len
)))
366 return D3DXERR_INVALIDDATA
;
367 return D3DXAssembleShader(buffer
, len
, defines
, include
, flags
,
368 shader
, error_messages
);
371 HRESULT WINAPI
D3DXCompileShader(LPCSTR pSrcData
,
373 CONST D3DXMACRO
* pDefines
,
374 LPD3DXINCLUDE pInclude
,
375 LPCSTR pFunctionName
,
378 LPD3DXBUFFER
* ppShader
,
379 LPD3DXBUFFER
* ppErrorMsgs
,
380 LPD3DXCONSTANTTABLE
* ppConstantTable
)
382 HRESULT hr
= D3DCompile(pSrcData
, srcDataLen
, NULL
,
383 (D3D_SHADER_MACRO
*)pDefines
, (ID3DInclude
*)pInclude
,
384 pFunctionName
, pProfile
, Flags
, 0,
385 (ID3DBlob
**)ppShader
, (ID3DBlob
**)ppErrorMsgs
);
387 if(SUCCEEDED(hr
) && ppConstantTable
)
388 return D3DXGetShaderConstantTable(ID3DXBuffer_GetBufferPointer(*ppShader
),
393 HRESULT WINAPI
D3DXCompileShaderFromFileA(LPCSTR filename
,
394 CONST D3DXMACRO
* defines
,
395 LPD3DXINCLUDE include
,
399 LPD3DXBUFFER
* shader
,
400 LPD3DXBUFFER
* error_messages
,
401 LPD3DXCONSTANTTABLE
* constant_table
)
403 LPWSTR filename_w
= NULL
;
407 if (!filename
) return D3DXERR_INVALIDDATA
;
409 len
= MultiByteToWideChar(CP_ACP
, 0, filename
, -1, NULL
, 0);
410 filename_w
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
411 if (!filename_w
) return E_OUTOFMEMORY
;
412 MultiByteToWideChar(CP_ACP
, 0, filename
, -1, filename_w
, len
);
414 ret
= D3DXCompileShaderFromFileW(filename_w
, defines
, include
,
415 entrypoint
, profile
, flags
,
416 shader
, error_messages
, constant_table
);
418 HeapFree(GetProcessHeap(), 0, filename_w
);
422 HRESULT WINAPI
D3DXCompileShaderFromFileW(LPCWSTR filename
,
423 CONST D3DXMACRO
* defines
,
424 LPD3DXINCLUDE include
,
428 LPD3DXBUFFER
* shader
,
429 LPD3DXBUFFER
* error_messages
,
430 LPD3DXCONSTANTTABLE
* constant_table
)
433 DWORD len
, filename_len
;
435 struct D3DXIncludeImpl includefromfile
;
438 if (FAILED(map_view_of_file(filename
, &buffer
, &len
)))
439 return D3DXERR_INVALIDDATA
;
443 includefromfile
.ID3DXInclude_iface
.lpVtbl
= &D3DXInclude_Vtbl
;
444 include
= &includefromfile
.ID3DXInclude_iface
;
447 filename_len
= WideCharToMultiByte(CP_ACP
, 0, filename
, -1, NULL
, 0, NULL
, NULL
);
448 filename_a
= HeapAlloc(GetProcessHeap(), 0, filename_len
* sizeof(char));
451 UnmapViewOfFile(buffer
);
452 return E_OUTOFMEMORY
;
454 WideCharToMultiByte(CP_ACP
, 0, filename
, -1, filename_a
, filename_len
, NULL
, NULL
);
456 hr
= D3DCompile(buffer
, len
, filename_a
, (const D3D_SHADER_MACRO
*)defines
,
457 (ID3DInclude
*)include
, entrypoint
, profile
, flags
, 0,
458 (ID3DBlob
**)shader
, (ID3DBlob
**)error_messages
);
460 if (SUCCEEDED(hr
) && constant_table
)
461 hr
= D3DXGetShaderConstantTable(ID3DXBuffer_GetBufferPointer(*shader
),
464 HeapFree(GetProcessHeap(), 0, filename_a
);
465 UnmapViewOfFile(buffer
);
469 HRESULT WINAPI
D3DXCompileShaderFromResourceA(HMODULE module
,
471 CONST D3DXMACRO
* defines
,
472 LPD3DXINCLUDE include
,
476 LPD3DXBUFFER
* shader
,
477 LPD3DXBUFFER
* error_messages
,
478 LPD3DXCONSTANTTABLE
* constant_table
)
484 if (!(res
= FindResourceA(module
, resource
, (LPCSTR
)RT_RCDATA
)))
485 return D3DXERR_INVALIDDATA
;
486 if (FAILED(load_resource_into_memory(module
, res
, (LPVOID
*)&buffer
, &len
)))
487 return D3DXERR_INVALIDDATA
;
488 return D3DXCompileShader(buffer
, len
, defines
, include
, entrypoint
, profile
,
489 flags
, shader
, error_messages
, constant_table
);
492 HRESULT WINAPI
D3DXCompileShaderFromResourceW(HMODULE module
,
494 CONST D3DXMACRO
* defines
,
495 LPD3DXINCLUDE include
,
499 LPD3DXBUFFER
* shader
,
500 LPD3DXBUFFER
* error_messages
,
501 LPD3DXCONSTANTTABLE
* constant_table
)
507 if (!(res
= FindResourceW(module
, resource
, (LPCWSTR
)RT_RCDATA
)))
508 return D3DXERR_INVALIDDATA
;
509 if (FAILED(load_resource_into_memory(module
, res
, (LPVOID
*)&buffer
, &len
)))
510 return D3DXERR_INVALIDDATA
;
511 return D3DXCompileShader(buffer
, len
, defines
, include
, entrypoint
, profile
,
512 flags
, shader
, error_messages
, constant_table
);
515 HRESULT WINAPI
D3DXPreprocessShader(LPCSTR data
,
517 CONST D3DXMACRO
* defines
,
518 LPD3DXINCLUDE include
,
519 LPD3DXBUFFER
* shader
,
520 LPD3DXBUFFER
* error_messages
)
522 TRACE("Forward to D3DPreprocess\n");
523 return D3DPreprocess(data
, data_len
, NULL
,
524 (const D3D_SHADER_MACRO
*)defines
, (ID3DInclude
*)include
,
525 (ID3DBlob
**)shader
, (ID3DBlob
**)error_messages
);
528 HRESULT WINAPI
D3DXPreprocessShaderFromFileA(LPCSTR filename
,
529 CONST D3DXMACRO
* defines
,
530 LPD3DXINCLUDE include
,
531 LPD3DXBUFFER
* shader
,
532 LPD3DXBUFFER
* error_messages
)
534 WCHAR
*filename_w
= NULL
;
538 if (!filename
) return D3DXERR_INVALIDDATA
;
540 len
= MultiByteToWideChar(CP_ACP
, 0, filename
, -1, NULL
, 0);
541 filename_w
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
542 if (!filename_w
) return E_OUTOFMEMORY
;
543 MultiByteToWideChar(CP_ACP
, 0, filename
, -1, filename_w
, len
);
545 ret
= D3DXPreprocessShaderFromFileW(filename_w
, defines
, include
, shader
, error_messages
);
547 HeapFree(GetProcessHeap(), 0, filename_w
);
551 HRESULT WINAPI
D3DXPreprocessShaderFromFileW(LPCWSTR filename
,
552 CONST D3DXMACRO
* defines
,
553 LPD3DXINCLUDE include
,
554 LPD3DXBUFFER
* shader
,
555 LPD3DXBUFFER
* error_messages
)
560 struct D3DXIncludeImpl includefromfile
;
562 if (FAILED(map_view_of_file(filename
, &buffer
, &len
)))
563 return D3DXERR_INVALIDDATA
;
567 includefromfile
.ID3DXInclude_iface
.lpVtbl
= &D3DXInclude_Vtbl
;
568 include
= &includefromfile
.ID3DXInclude_iface
;
571 hr
= D3DPreprocess(buffer
, len
, NULL
,
572 (const D3D_SHADER_MACRO
*)defines
,
573 (ID3DInclude
*) include
,
574 (ID3DBlob
**)shader
, (ID3DBlob
**)error_messages
);
576 UnmapViewOfFile(buffer
);
580 HRESULT WINAPI
D3DXPreprocessShaderFromResourceA(HMODULE module
,
582 CONST D3DXMACRO
* defines
,
583 LPD3DXINCLUDE include
,
584 LPD3DXBUFFER
* shader
,
585 LPD3DXBUFFER
* error_messages
)
591 if (!(res
= FindResourceA(module
, resource
, (LPCSTR
)RT_RCDATA
)))
592 return D3DXERR_INVALIDDATA
;
593 if (FAILED(load_resource_into_memory(module
, res
, (LPVOID
*)&buffer
, &len
)))
594 return D3DXERR_INVALIDDATA
;
595 return D3DXPreprocessShader(buffer
, len
, defines
, include
,
596 shader
, error_messages
);
599 HRESULT WINAPI
D3DXPreprocessShaderFromResourceW(HMODULE module
,
601 CONST D3DXMACRO
* defines
,
602 LPD3DXINCLUDE include
,
603 LPD3DXBUFFER
* shader
,
604 LPD3DXBUFFER
* error_messages
)
610 if (!(res
= FindResourceW(module
, resource
, (const WCHAR
*)RT_RCDATA
)))
611 return D3DXERR_INVALIDDATA
;
612 if (FAILED(load_resource_into_memory(module
, res
, (void **)&buffer
, &len
)))
613 return D3DXERR_INVALIDDATA
;
614 return D3DXPreprocessShader(buffer
, len
, defines
, include
,
615 shader
, error_messages
);
619 struct ctab_constant
{
620 D3DXCONSTANT_DESC desc
;
621 struct ctab_constant
*members
;
624 static const struct ID3DXConstantTableVtbl ID3DXConstantTable_Vtbl
;
626 struct ID3DXConstantTableImpl
{
627 ID3DXConstantTable ID3DXConstantTable_iface
;
631 D3DXCONSTANTTABLE_DESC desc
;
632 struct ctab_constant
*constants
;
635 static void free_constant_table(struct ID3DXConstantTableImpl
*table
)
637 HeapFree(GetProcessHeap(), 0, table
->constants
);
638 HeapFree(GetProcessHeap(), 0, table
->ctab
);
641 static inline struct ID3DXConstantTableImpl
*impl_from_ID3DXConstantTable(ID3DXConstantTable
*iface
)
643 return CONTAINING_RECORD(iface
, struct ID3DXConstantTableImpl
, ID3DXConstantTable_iface
);
646 static inline int is_vertex_shader(DWORD version
)
648 return (version
& 0xFFFF0000) == 0xFFFE0000;
651 static DWORD
calc_bytes(D3DXCONSTANT_DESC
*desc
)
653 if (desc
->RegisterSet
!= D3DXRS_FLOAT4
&& desc
->RegisterSet
!= D3DXRS_SAMPLER
)
654 FIXME("Don't know how to calculate Bytes for constants of type %d\n",
657 return 4 * desc
->Elements
* desc
->Rows
* desc
->Columns
;
660 static inline struct ctab_constant
*constant_from_handle(D3DXHANDLE handle
)
662 return (struct ctab_constant
*)handle
;
665 static inline D3DXHANDLE
handle_from_constant(struct ctab_constant
*constant
)
667 return (D3DXHANDLE
)constant
;
670 static inline struct ctab_constant
*is_valid_constant(struct ID3DXConstantTableImpl
*table
, D3DXHANDLE handle
)
672 struct ctab_constant
*c
= constant_from_handle(handle
);
677 for (i
= 0; i
< table
->desc
.Constants
; ++i
)
679 if (&table
->constants
[i
] == c
) return c
;
685 static inline void set_float_shader_constant(struct ID3DXConstantTableImpl
*table
, IDirect3DDevice9
*device
,
686 UINT register_index
, const FLOAT
*data
, UINT count
)
688 if (is_vertex_shader(table
->desc
.Version
))
689 IDirect3DDevice9_SetVertexShaderConstantF(device
, register_index
, data
, count
);
691 IDirect3DDevice9_SetPixelShaderConstantF(device
, register_index
, data
, count
);
694 /*** IUnknown methods ***/
695 static HRESULT WINAPI
ID3DXConstantTableImpl_QueryInterface(ID3DXConstantTable
*iface
, REFIID riid
, void **out
)
697 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
699 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
700 IsEqualGUID(riid
, &IID_ID3DXBuffer
) ||
701 IsEqualGUID(riid
, &IID_ID3DXConstantTable
))
703 ID3DXConstantTable_AddRef(iface
);
708 WARN("Interface %s not found.\n", debugstr_guid(riid
));
710 return E_NOINTERFACE
;
713 static ULONG WINAPI
ID3DXConstantTableImpl_AddRef(ID3DXConstantTable
*iface
)
715 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
717 TRACE("(%p)->(): AddRef from %d\n", This
, This
->ref
);
719 return InterlockedIncrement(&This
->ref
);
722 static ULONG WINAPI
ID3DXConstantTableImpl_Release(ID3DXConstantTable
*iface
)
724 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
725 ULONG ref
= InterlockedDecrement(&This
->ref
);
727 TRACE("(%p)->(): Release from %d\n", This
, ref
+ 1);
731 free_constant_table(This
);
732 HeapFree(GetProcessHeap(), 0, This
);
738 /*** ID3DXBuffer methods ***/
739 static LPVOID WINAPI
ID3DXConstantTableImpl_GetBufferPointer(ID3DXConstantTable
*iface
)
741 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
743 TRACE("(%p)->()\n", This
);
748 static DWORD WINAPI
ID3DXConstantTableImpl_GetBufferSize(ID3DXConstantTable
*iface
)
750 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
752 TRACE("(%p)->()\n", This
);
757 /*** ID3DXConstantTable methods ***/
758 static HRESULT WINAPI
ID3DXConstantTableImpl_GetDesc(ID3DXConstantTable
*iface
, D3DXCONSTANTTABLE_DESC
*desc
)
760 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
762 TRACE("(%p)->(%p)\n", This
, desc
);
765 return D3DERR_INVALIDCALL
;
767 memcpy(desc
, &This
->desc
, sizeof(This
->desc
));
772 static HRESULT WINAPI
ID3DXConstantTableImpl_GetConstantDesc(ID3DXConstantTable
*iface
, D3DXHANDLE constant
,
773 D3DXCONSTANT_DESC
*desc
, UINT
*count
)
775 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
776 struct ctab_constant
*constant_info
;
778 TRACE("(%p)->(%p, %p, %p)\n", This
, constant
, desc
, count
);
781 return D3DERR_INVALIDCALL
;
783 /* Applications can pass the name of the constant in place of the handle */
784 if (!is_valid_constant(This
, constant
))
786 constant
= ID3DXConstantTable_GetConstantByName(iface
, NULL
, constant
);
788 return D3DERR_INVALIDCALL
;
791 constant_info
= constant_from_handle(constant
);
794 *desc
= constant_info
->desc
;
801 static UINT WINAPI
ID3DXConstantTableImpl_GetSamplerIndex(ID3DXConstantTable
*iface
, D3DXHANDLE constant
)
803 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
804 D3DXCONSTANT_DESC desc
;
808 TRACE("(%p)->(%p)\n", This
, constant
);
810 res
= ID3DXConstantTable_GetConstantDesc(iface
, constant
, &desc
, &count
);
814 if (desc
.RegisterSet
!= D3DXRS_SAMPLER
)
817 return desc
.RegisterIndex
;
820 static D3DXHANDLE WINAPI
ID3DXConstantTableImpl_GetConstant(ID3DXConstantTable
*iface
, D3DXHANDLE constant
, UINT index
)
822 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
824 TRACE("(%p)->(%p, %d)\n", This
, constant
, index
);
828 FIXME("Only top level constants supported\n");
832 if (index
>= This
->desc
.Constants
)
835 return handle_from_constant(&This
->constants
[index
]);
838 static D3DXHANDLE WINAPI
ID3DXConstantTableImpl_GetConstantByName(ID3DXConstantTable
*iface
, D3DXHANDLE constant
, LPCSTR name
)
840 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
843 TRACE("(%p)->(%p, %s)\n", This
, constant
, name
);
850 FIXME("Only top level constants supported\n");
854 for (i
= 0; i
< This
->desc
.Constants
; i
++)
855 if (!strcmp(This
->constants
[i
].desc
.Name
, name
))
856 return handle_from_constant(&This
->constants
[i
]);
861 static D3DXHANDLE WINAPI
ID3DXConstantTableImpl_GetConstantElement(ID3DXConstantTable
*iface
, D3DXHANDLE constant
, UINT index
)
863 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
865 FIXME("(%p)->(%p, %d): stub\n", This
, constant
, index
);
870 static HRESULT
set_scalar_array(ID3DXConstantTable
*iface
, IDirect3DDevice9
*device
, D3DXHANDLE constant
, const void *data
,
871 UINT count
, D3DXPARAMETER_TYPE type
)
873 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
874 D3DXCONSTANT_DESC desc
;
876 UINT i
, desc_count
= 1;
877 float row
[4] = {0.0f
, 0.0f
, 0.0f
, 0.0f
};
879 hr
= ID3DXConstantTable_GetConstantDesc(iface
, constant
, &desc
, &desc_count
);
882 TRACE("ID3DXConstantTable_GetConstantDesc failed: %08x\n", hr
);
883 return D3DERR_INVALIDCALL
;
886 if (desc
.Class
!= D3DXPC_SCALAR
)
889 switch (desc
.RegisterSet
)
892 for (i
= 0; i
< min(count
, desc
.RegisterCount
); i
++)
894 /* We need the for loop since each IDirect3DDevice9_Set*ShaderConstantF expects a float4 */
898 row
[0] = ((float *)data
)[i
];
901 row
[0] = (float)((int *)data
)[i
];
904 row
[0] = ((BOOL
*)data
)[i
] ? 1.0f
: 0.0f
;
907 FIXME("Unhandled type %#x\n", type
);
908 return D3DERR_INVALIDCALL
;
910 set_float_shader_constant(This
, device
, desc
.RegisterIndex
+ i
, row
, 1);
914 FIXME("Handle other register sets\n");
921 static HRESULT
set_vector_array(ID3DXConstantTable
*iface
, IDirect3DDevice9
*device
, D3DXHANDLE constant
, const void *data
,
922 UINT count
, D3DXPARAMETER_TYPE type
)
924 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
925 D3DXCONSTANT_DESC desc
;
927 UINT i
, j
, desc_count
= 1;
928 float vec
[4] = {0.0f
, 0.0f
, 0.0f
, 0.0f
};
930 hr
= ID3DXConstantTable_GetConstantDesc(iface
, constant
, &desc
, &desc_count
);
933 TRACE("ID3DXConstantTable_GetConstantDesc failed: %08x\n", hr
);
934 return D3DERR_INVALIDCALL
;
937 if (desc
.Class
== D3DXPC_MATRIX_ROWS
|| desc
.Class
== D3DXPC_MATRIX_COLUMNS
)
940 switch (desc
.RegisterSet
)
943 for (i
= 0; i
< min(count
, desc
.RegisterCount
); i
++)
948 memcpy(vec
, ((float *)data
) + i
* desc
.Columns
, desc
.Columns
* sizeof(float));
951 for (j
= 0; j
< desc
.Columns
; j
++)
952 vec
[j
] = (float)((int *)data
)[i
* desc
.Columns
+ j
];
955 for (j
= 0; j
< desc
.Columns
; j
++)
956 vec
[j
] = ((BOOL
*)data
)[i
* desc
.Columns
+ j
] ? 1.0f
: 0.0f
;
959 FIXME("Unhandled type %#x\n", type
);
960 return D3DERR_INVALIDCALL
;
963 set_float_shader_constant(This
, device
, desc
.RegisterIndex
+ i
, vec
, 1);
967 FIXME("Unhandled register set %#x\n", desc
.RegisterSet
);
974 static HRESULT
set_float_matrix(FLOAT
*matrix
, const D3DXCONSTANT_DESC
*desc
,
975 UINT row_offset
, UINT column_offset
, UINT rows
, UINT columns
,
976 const void *data
, D3DXPARAMETER_TYPE type
, UINT src_columns
)
983 for (i
= 0; i
< rows
; i
++)
985 for (j
= 0; j
< columns
; j
++)
986 matrix
[i
* row_offset
+ j
* column_offset
] = ((FLOAT
*)data
)[i
* src_columns
+ j
];
990 for (i
= 0; i
< rows
; i
++)
992 for (j
= 0; j
< columns
; j
++)
993 matrix
[i
* row_offset
+ j
* column_offset
] = ((INT
*)data
)[i
* src_columns
+ j
];
997 FIXME("Unhandled type %#x\n", type
);
998 return D3DERR_INVALIDCALL
;
1004 static HRESULT
set_matrix_array(ID3DXConstantTable
*iface
, IDirect3DDevice9
*device
, D3DXHANDLE constant
, const void *data
,
1005 UINT count
, D3DXPARAMETER_CLASS
class, D3DXPARAMETER_TYPE type
, UINT rows
, UINT columns
)
1007 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1008 D3DXCONSTANT_DESC desc
;
1010 UINT registers_per_matrix
;
1011 UINT i
, desc_count
= 1;
1012 UINT num_rows
, num_columns
;
1013 UINT row_offset
, column_offset
;
1014 const DWORD
*data_ptr
;
1015 FLOAT matrix
[16] = {0.0f
, 0.0f
, 0.0f
, 0.0f
,
1016 0.0f
, 0.0f
, 0.0f
, 0.0f
,
1017 0.0f
, 0.0f
, 0.0f
, 0.0f
,
1018 0.0f
, 0.0f
, 0.0f
, 0.0f
};
1020 hr
= ID3DXConstantTable_GetConstantDesc(iface
, constant
, &desc
, &desc_count
);
1023 TRACE("ID3DXConstantTable_GetConstantDesc failed: %08x\n", hr
);
1024 return D3DERR_INVALIDCALL
;
1027 if (desc
.Class
== D3DXPC_MATRIX_ROWS
|| desc
.Class
== D3DXPC_MATRIX_COLUMNS
)
1029 if (desc
.Class
== class)
1040 if (class == D3DXPC_MATRIX_ROWS
)
1042 num_rows
= min(desc
.Rows
, rows
);
1043 num_columns
= min(desc
.Columns
, columns
);
1047 num_rows
= min(desc
.Columns
, columns
);
1048 num_columns
= min(desc
.Rows
, rows
);
1051 registers_per_matrix
= (desc
.Class
== D3DXPC_MATRIX_ROWS
) ? desc
.Rows
: desc
.Columns
;
1053 else if (desc
.Class
== D3DXPC_SCALAR
)
1057 num_rows
= min(desc
.Rows
, rows
);
1058 num_columns
= min(desc
.Columns
, columns
);
1059 registers_per_matrix
= 1;
1063 FIXME("Unhandled variable class %#x\n", desc
.Class
);
1067 switch (desc
.RegisterSet
)
1071 for (i
= 0; i
< count
; i
++)
1073 if (registers_per_matrix
* (i
+ 1) > desc
.RegisterCount
)
1076 hr
= set_float_matrix(matrix
, &desc
, row_offset
, column_offset
, num_rows
, num_columns
, data_ptr
, type
, columns
);
1077 if (FAILED(hr
)) return hr
;
1079 set_float_shader_constant(This
, device
, desc
.RegisterIndex
+ i
* registers_per_matrix
, matrix
, registers_per_matrix
);
1081 data_ptr
+= rows
* columns
;
1085 FIXME("Unhandled register set %#x\n", desc
.RegisterSet
);
1092 static HRESULT
set_matrix_pointer_array(ID3DXConstantTable
*iface
, IDirect3DDevice9
*device
, D3DXHANDLE constant
,
1093 const D3DXMATRIX
**data
, UINT count
, D3DXPARAMETER_CLASS
class)
1095 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1096 D3DXCONSTANT_DESC desc
;
1098 UINT registers_per_matrix
;
1099 UINT i
, desc_count
= 1;
1100 UINT num_rows
, num_columns
;
1101 UINT row_offset
, column_offset
;
1102 FLOAT matrix
[16] = {0.0f
, 0.0f
, 0.0f
, 0.0f
,
1103 0.0f
, 0.0f
, 0.0f
, 0.0f
,
1104 0.0f
, 0.0f
, 0.0f
, 0.0f
,
1105 0.0f
, 0.0f
, 0.0f
, 0.0f
};
1107 hr
= ID3DXConstantTable_GetConstantDesc(iface
, constant
, &desc
, &desc_count
);
1110 TRACE("ID3DXConstantTable_GetConstantDesc failed: %08x\n", hr
);
1111 return D3DERR_INVALIDCALL
;
1114 if (desc
.Class
== D3DXPC_MATRIX_ROWS
|| desc
.Class
== D3DXPC_MATRIX_COLUMNS
)
1116 if (desc
.Class
== class)
1127 if (class == D3DXPC_MATRIX_ROWS
)
1129 num_rows
= desc
.Rows
;
1130 num_columns
= desc
.Columns
;
1134 num_rows
= desc
.Columns
;
1135 num_columns
= desc
.Rows
;
1138 registers_per_matrix
= (desc
.Class
== D3DXPC_MATRIX_ROWS
) ? desc
.Rows
: desc
.Columns
;
1140 else if (desc
.Class
== D3DXPC_SCALAR
)
1142 registers_per_matrix
= 1;
1145 num_rows
= desc
.Rows
;
1146 num_columns
= desc
.Columns
;
1148 else if (desc
.Class
== D3DXPC_VECTOR
)
1150 registers_per_matrix
= 1;
1152 if (class == D3DXPC_MATRIX_ROWS
)
1156 num_rows
= desc
.Rows
;
1157 num_columns
= desc
.Columns
;
1163 num_rows
= desc
.Columns
;
1164 num_columns
= desc
.Rows
;
1169 FIXME("Unhandled variable class %#x\n", desc
.Class
);
1173 switch (desc
.RegisterSet
)
1176 for (i
= 0; i
< count
; i
++)
1178 if (registers_per_matrix
* (i
+ 1) > desc
.RegisterCount
)
1181 hr
= set_float_matrix(matrix
, &desc
, row_offset
, column_offset
, num_rows
, num_columns
, *data
, D3DXPT_FLOAT
, 4);
1182 if (FAILED(hr
)) return hr
;
1184 set_float_shader_constant(This
, device
, desc
.RegisterIndex
+ i
* registers_per_matrix
, matrix
, registers_per_matrix
);
1190 FIXME("Unhandled register set %#x\n", desc
.RegisterSet
);
1197 static HRESULT WINAPI
ID3DXConstantTableImpl_SetDefaults(ID3DXConstantTable
*iface
, LPDIRECT3DDEVICE9 device
)
1199 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1202 TRACE("(%p)->(%p)\n", This
, device
);
1205 return D3DERR_INVALIDCALL
;
1207 for (i
= 0; i
< This
->desc
.Constants
; i
++)
1209 D3DXCONSTANT_DESC
*desc
= &This
->constants
[i
].desc
;
1211 if (!desc
->DefaultValue
)
1214 set_float_shader_constant(This
, device
, desc
->RegisterIndex
, desc
->DefaultValue
, desc
->RegisterCount
);
1220 static HRESULT WINAPI
ID3DXConstantTableImpl_SetValue(ID3DXConstantTable
*iface
, LPDIRECT3DDEVICE9 device
,
1221 D3DXHANDLE constant
, LPCVOID data
, UINT bytes
)
1223 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1227 D3DXCONSTANT_DESC desc
;
1229 TRACE("(%p)->(%p, %p, %p, %d)\n", This
, device
, constant
, data
, bytes
);
1231 if (!device
|| !constant
|| !data
)
1232 return D3DERR_INVALIDCALL
;
1234 hr
= ID3DXConstantTable_GetConstantDesc(iface
, constant
, &desc
, &count
);
1238 elements
= bytes
/ (desc
.Bytes
/ desc
.Elements
);
1243 return set_scalar_array(iface
, device
, constant
, data
, elements
, desc
.Type
);
1245 return set_vector_array(iface
, device
, constant
, data
,elements
, desc
.Type
);
1246 case D3DXPC_MATRIX_ROWS
:
1247 case D3DXPC_MATRIX_COLUMNS
:
1248 return set_matrix_array(iface
, device
, constant
, data
, elements
,
1249 D3DXPC_MATRIX_ROWS
, desc
.Type
, desc
.Rows
, desc
.Columns
);
1251 FIXME("Unhandled parameter class %#x\n", desc
.Class
);
1252 return D3DERR_INVALIDCALL
;
1256 static HRESULT WINAPI
ID3DXConstantTableImpl_SetBool(ID3DXConstantTable
*iface
, LPDIRECT3DDEVICE9 device
,
1257 D3DXHANDLE constant
, BOOL b
)
1259 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1261 TRACE("(%p)->(%p, %p, %d)\n", This
, device
, constant
, b
);
1263 return set_scalar_array(iface
, device
, constant
, &b
, 1, D3DXPT_BOOL
);
1266 static HRESULT WINAPI
ID3DXConstantTableImpl_SetBoolArray(ID3DXConstantTable
*iface
, LPDIRECT3DDEVICE9 device
,
1267 D3DXHANDLE constant
, CONST BOOL
* b
, UINT count
)
1269 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1271 TRACE("(%p)->(%p, %p, %p, %d)\n", This
, device
, constant
, b
, count
);
1273 return set_scalar_array(iface
, device
, constant
, b
, count
, D3DXPT_BOOL
);
1276 static HRESULT WINAPI
ID3DXConstantTableImpl_SetInt(ID3DXConstantTable
*iface
, LPDIRECT3DDEVICE9 device
, D3DXHANDLE constant
, INT n
)
1278 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1280 TRACE("(%p)->(%p, %p, %d)\n", This
, device
, constant
, n
);
1282 return set_scalar_array(iface
, device
, constant
, &n
, 1, D3DXPT_INT
);
1285 static HRESULT WINAPI
ID3DXConstantTableImpl_SetIntArray(ID3DXConstantTable
*iface
, LPDIRECT3DDEVICE9 device
,
1286 D3DXHANDLE constant
, CONST INT
* n
, UINT count
)
1288 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1290 TRACE("(%p)->(%p, %p, %p, %d)\n", This
, device
, constant
, n
, count
);
1292 return set_scalar_array(iface
, device
, constant
, n
, count
, D3DXPT_INT
);
1295 static HRESULT WINAPI
ID3DXConstantTableImpl_SetFloat(ID3DXConstantTable
*iface
, LPDIRECT3DDEVICE9 device
,
1296 D3DXHANDLE constant
, FLOAT f
)
1298 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1300 TRACE("(%p)->(%p, %p, %f)\n", This
, device
, constant
, f
);
1302 return set_scalar_array(iface
, device
, constant
, &f
, 1, D3DXPT_FLOAT
);
1305 static HRESULT WINAPI
ID3DXConstantTableImpl_SetFloatArray(ID3DXConstantTable
*iface
, LPDIRECT3DDEVICE9 device
,
1306 D3DXHANDLE constant
, CONST FLOAT
*f
, UINT count
)
1308 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1310 TRACE("(%p)->(%p, %p, %p, %d)\n", This
, device
, constant
, f
, count
);
1312 return set_scalar_array(iface
, device
, constant
, f
, count
, D3DXPT_FLOAT
);
1315 static HRESULT WINAPI
ID3DXConstantTableImpl_SetVector(ID3DXConstantTable
*iface
, LPDIRECT3DDEVICE9 device
,
1316 D3DXHANDLE constant
, CONST D3DXVECTOR4
*vector
)
1318 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1320 TRACE("(%p)->(%p, %p, %p)\n", This
, device
, constant
, vector
);
1322 return set_vector_array(iface
, device
, constant
, vector
, 1, D3DXPT_FLOAT
);
1325 static HRESULT WINAPI
ID3DXConstantTableImpl_SetVectorArray(ID3DXConstantTable
*iface
, LPDIRECT3DDEVICE9 device
,
1326 D3DXHANDLE constant
, CONST D3DXVECTOR4
*vector
, UINT count
)
1328 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1330 TRACE("(%p)->(%p, %p, %p, %d)\n", This
, device
, constant
, vector
, count
);
1332 return set_vector_array(iface
, device
, constant
, vector
, count
, D3DXPT_FLOAT
);
1335 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrix(ID3DXConstantTable
*iface
, LPDIRECT3DDEVICE9 device
,
1336 D3DXHANDLE constant
, CONST D3DXMATRIX
*matrix
)
1338 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1340 TRACE("(%p)->(%p, %p, %p)\n", This
, device
, constant
, matrix
);
1342 return set_matrix_array(iface
, device
, constant
, matrix
, 1, D3DXPC_MATRIX_ROWS
, D3DXPT_FLOAT
, 4, 4);
1345 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrixArray(ID3DXConstantTable
*iface
, LPDIRECT3DDEVICE9 device
,
1346 D3DXHANDLE constant
, CONST D3DXMATRIX
*matrix
, UINT count
)
1348 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1350 TRACE("(%p)->(%p, %p, %p, %d)\n", This
, device
, constant
, matrix
, count
);
1352 return set_matrix_array(iface
, device
, constant
, matrix
, count
, D3DXPC_MATRIX_ROWS
, D3DXPT_FLOAT
, 4, 4);
1355 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrixPointerArray(ID3DXConstantTable
*iface
, LPDIRECT3DDEVICE9 device
,
1356 D3DXHANDLE constant
, CONST D3DXMATRIX
**matrix
, UINT count
)
1358 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1360 TRACE("(%p)->(%p, %p, %p, %d)\n", This
, device
, constant
, matrix
, count
);
1362 return set_matrix_pointer_array(iface
, device
, constant
, matrix
, count
, D3DXPC_MATRIX_ROWS
);
1365 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrixTranspose(ID3DXConstantTable
*iface
, LPDIRECT3DDEVICE9 device
,
1366 D3DXHANDLE constant
, CONST D3DXMATRIX
*matrix
)
1368 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1370 TRACE("(%p)->(%p, %p, %p)\n", This
, device
, constant
, matrix
);
1372 return set_matrix_array(iface
, device
, constant
, matrix
, 1, D3DXPC_MATRIX_COLUMNS
, D3DXPT_FLOAT
, 4, 4);
1375 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrixTransposeArray(ID3DXConstantTable
*iface
, LPDIRECT3DDEVICE9 device
,
1376 D3DXHANDLE constant
, CONST D3DXMATRIX
*matrix
, UINT count
)
1378 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1380 TRACE("(%p)->(%p, %p, %p, %d)\n", This
, device
, constant
, matrix
, count
);
1382 return set_matrix_array(iface
, device
, constant
, matrix
, count
, D3DXPC_MATRIX_COLUMNS
, D3DXPT_FLOAT
, 4, 4);
1385 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrixTransposePointerArray(ID3DXConstantTable
*iface
, LPDIRECT3DDEVICE9 device
,
1386 D3DXHANDLE constant
, CONST D3DXMATRIX
**matrix
, UINT count
)
1388 struct ID3DXConstantTableImpl
*This
= impl_from_ID3DXConstantTable(iface
);
1390 TRACE("(%p)->(%p, %p, %p, %d)\n", This
, device
, constant
, matrix
, count
);
1392 return set_matrix_pointer_array(iface
, device
, constant
, matrix
, count
, D3DXPC_MATRIX_COLUMNS
);
1395 static const struct ID3DXConstantTableVtbl ID3DXConstantTable_Vtbl
=
1397 /*** IUnknown methods ***/
1398 ID3DXConstantTableImpl_QueryInterface
,
1399 ID3DXConstantTableImpl_AddRef
,
1400 ID3DXConstantTableImpl_Release
,
1401 /*** ID3DXBuffer methods ***/
1402 ID3DXConstantTableImpl_GetBufferPointer
,
1403 ID3DXConstantTableImpl_GetBufferSize
,
1404 /*** ID3DXConstantTable methods ***/
1405 ID3DXConstantTableImpl_GetDesc
,
1406 ID3DXConstantTableImpl_GetConstantDesc
,
1407 ID3DXConstantTableImpl_GetSamplerIndex
,
1408 ID3DXConstantTableImpl_GetConstant
,
1409 ID3DXConstantTableImpl_GetConstantByName
,
1410 ID3DXConstantTableImpl_GetConstantElement
,
1411 ID3DXConstantTableImpl_SetDefaults
,
1412 ID3DXConstantTableImpl_SetValue
,
1413 ID3DXConstantTableImpl_SetBool
,
1414 ID3DXConstantTableImpl_SetBoolArray
,
1415 ID3DXConstantTableImpl_SetInt
,
1416 ID3DXConstantTableImpl_SetIntArray
,
1417 ID3DXConstantTableImpl_SetFloat
,
1418 ID3DXConstantTableImpl_SetFloatArray
,
1419 ID3DXConstantTableImpl_SetVector
,
1420 ID3DXConstantTableImpl_SetVectorArray
,
1421 ID3DXConstantTableImpl_SetMatrix
,
1422 ID3DXConstantTableImpl_SetMatrixArray
,
1423 ID3DXConstantTableImpl_SetMatrixPointerArray
,
1424 ID3DXConstantTableImpl_SetMatrixTranspose
,
1425 ID3DXConstantTableImpl_SetMatrixTransposeArray
,
1426 ID3DXConstantTableImpl_SetMatrixTransposePointerArray
1429 static HRESULT
parse_ctab_constant_type(const D3DXSHADER_TYPEINFO
*type
, struct ctab_constant
*constant
)
1431 constant
->desc
.Class
= type
->Class
;
1432 constant
->desc
.Type
= type
->Type
;
1433 constant
->desc
.Rows
= type
->Rows
;
1434 constant
->desc
.Columns
= type
->Columns
;
1435 constant
->desc
.Elements
= type
->Elements
;
1436 constant
->desc
.StructMembers
= type
->StructMembers
;
1437 constant
->desc
.Bytes
= calc_bytes(&constant
->desc
);
1439 TRACE("class = %d, type = %d, rows = %d, columns = %d, elements = %d, struct_members = %d\n",
1440 constant
->desc
.Class
, constant
->desc
.Type
, constant
->desc
.Rows
,
1441 constant
->desc
.Columns
, constant
->desc
.Elements
, constant
->desc
.StructMembers
);
1443 if ((constant
->desc
.Class
== D3DXPC_STRUCT
) && constant
->desc
.StructMembers
)
1445 FIXME("Struct not supported yet\n");
1452 HRESULT WINAPI
D3DXGetShaderConstantTableEx(CONST DWORD
*byte_code
,
1454 LPD3DXCONSTANTTABLE
*constant_table
)
1456 struct ID3DXConstantTableImpl
*object
= NULL
;
1460 const D3DXSHADER_CONSTANTTABLE
* ctab_header
;
1461 D3DXSHADER_CONSTANTINFO
* constant_info
;
1464 TRACE("(%p, %x, %p)\n", byte_code
, flags
, constant_table
);
1466 if (!byte_code
|| !constant_table
)
1468 WARN("Invalid argument specified.\n");
1469 return D3DERR_INVALIDCALL
;
1472 if (flags
) FIXME("Flags (%#x) are not handled, yet!\n", flags
);
1474 hr
= D3DXFindShaderComment(byte_code
, MAKEFOURCC('C','T','A','B'), &data
, &size
);
1477 WARN("CTAB not found.\n");
1478 return D3DXERR_INVALIDDATA
;
1481 if (size
< sizeof(D3DXSHADER_CONSTANTTABLE
))
1483 WARN("Invalid CTAB size.\n");
1484 return D3DXERR_INVALIDDATA
;
1487 ctab_header
= (const D3DXSHADER_CONSTANTTABLE
*)data
;
1488 if (ctab_header
->Size
!= sizeof(D3DXSHADER_CONSTANTTABLE
))
1490 WARN("Invalid D3DXSHADER_CONSTANTTABLE size.\n");
1491 return D3DXERR_INVALIDDATA
;
1494 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*object
));
1497 ERR("Out of memory\n");
1498 return E_OUTOFMEMORY
;
1501 object
->ID3DXConstantTable_iface
.lpVtbl
= &ID3DXConstantTable_Vtbl
;
1504 object
->ctab
= HeapAlloc(GetProcessHeap(), 0, size
);
1507 ERR("Out of memory\n");
1508 HeapFree(GetProcessHeap(), 0, object
);
1509 return E_OUTOFMEMORY
;
1511 object
->size
= size
;
1512 memcpy(object
->ctab
, data
, object
->size
);
1514 object
->desc
.Creator
= ctab_header
->Creator
? object
->ctab
+ ctab_header
->Creator
: NULL
;
1515 object
->desc
.Version
= ctab_header
->Version
;
1516 object
->desc
.Constants
= ctab_header
->Constants
;
1517 TRACE("Creator %s, Version %x, Constants %u, Target %s\n",
1518 debugstr_a(object
->desc
.Creator
), object
->desc
.Version
, object
->desc
.Constants
,
1519 debugstr_a(ctab_header
->Target
? object
->ctab
+ ctab_header
->Target
: NULL
));
1521 if (object
->desc
.Constants
> 65535)
1523 FIXME("Too many constants (%u)\n", object
->desc
.Constants
);
1528 object
->constants
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
1529 sizeof(*object
->constants
) * object
->desc
.Constants
);
1530 if (!object
->constants
)
1532 ERR("Out of memory\n");
1537 constant_info
= (LPD3DXSHADER_CONSTANTINFO
)(object
->ctab
+ ctab_header
->ConstantInfo
);
1538 for (i
= 0; i
< ctab_header
->Constants
; i
++)
1540 TRACE("name = %s\n", object
->ctab
+ constant_info
[i
].Name
);
1541 object
->constants
[i
].desc
.Name
= object
->ctab
+ constant_info
[i
].Name
;
1542 object
->constants
[i
].desc
.RegisterSet
= constant_info
[i
].RegisterSet
;
1543 object
->constants
[i
].desc
.RegisterIndex
= constant_info
[i
].RegisterIndex
;
1544 object
->constants
[i
].desc
.RegisterCount
= constant_info
[i
].RegisterCount
;
1545 object
->constants
[i
].desc
.DefaultValue
= constant_info
[i
].DefaultValue
1546 ? object
->ctab
+ constant_info
[i
].DefaultValue
: NULL
;
1548 hr
= parse_ctab_constant_type((LPD3DXSHADER_TYPEINFO
)(object
->ctab
+ constant_info
[i
].TypeInfo
),
1549 &object
->constants
[i
]);
1554 *constant_table
= &object
->ID3DXConstantTable_iface
;
1560 free_constant_table(object
);
1561 HeapFree(GetProcessHeap(), 0, object
);
1566 HRESULT WINAPI
D3DXGetShaderConstantTable(CONST DWORD
* byte_code
,
1567 LPD3DXCONSTANTTABLE
* constant_table
)
1569 TRACE("(%p, %p): Forwarded to D3DXGetShaderConstantTableEx\n", byte_code
, constant_table
);
1571 return D3DXGetShaderConstantTableEx(byte_code
, 0, constant_table
);
1574 HRESULT WINAPI
D3DXGetShaderSamplers(CONST DWORD
*byte_code
, LPCSTR
*samplers
, UINT
*count
)
1577 UINT i
, sampler_count
= 0;
1580 const D3DXSHADER_CONSTANTTABLE
*ctab_header
;
1581 const D3DXSHADER_CONSTANTINFO
*constant_info
;
1583 TRACE("byte_code %p, samplers %p, count %p\n", byte_code
, samplers
, count
);
1585 if (count
) *count
= 0;
1587 hr
= D3DXFindShaderComment(byte_code
, MAKEFOURCC('C','T','A','B'), (LPCVOID
*)&data
, &size
);
1588 if (hr
!= D3D_OK
) return D3D_OK
;
1590 if (size
< sizeof(D3DXSHADER_CONSTANTTABLE
)) return D3D_OK
;
1592 ctab_header
= (const D3DXSHADER_CONSTANTTABLE
*)data
;
1593 if (ctab_header
->Size
!= sizeof(*ctab_header
)) return D3D_OK
;
1595 constant_info
= (D3DXSHADER_CONSTANTINFO
*)(data
+ ctab_header
->ConstantInfo
);
1596 for (i
= 0; i
< ctab_header
->Constants
; i
++)
1598 const D3DXSHADER_TYPEINFO
*type
;
1600 TRACE("name = %s\n", data
+ constant_info
[i
].Name
);
1602 type
= (D3DXSHADER_TYPEINFO
*)(data
+ constant_info
[i
].TypeInfo
);
1604 if (type
->Type
== D3DXPT_SAMPLER
1605 || type
->Type
== D3DXPT_SAMPLER1D
1606 || type
->Type
== D3DXPT_SAMPLER2D
1607 || type
->Type
== D3DXPT_SAMPLER3D
1608 || type
->Type
== D3DXPT_SAMPLERCUBE
)
1610 if (samplers
) samplers
[sampler_count
] = data
+ constant_info
[i
].Name
;
1616 TRACE("Found %u samplers\n", sampler_count
);
1618 if (count
) *count
= sampler_count
;