2 * Copyright 2008 Luis Busquets
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #include "wine/port.h"
21 #include "wine/debug.h"
22 #include "wine/unicode.h"
26 #include "d3dx9shader.h"
27 #include "d3dx9_36_private.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(d3dx
);
31 LPCSTR WINAPI
D3DXGetPixelShaderProfile(LPDIRECT3DDEVICE9 device
)
35 TRACE("device %p\n", device
);
37 if (!device
) return NULL
;
39 IDirect3DDevice9_GetDeviceCaps(device
,&caps
);
41 switch (caps
.PixelShaderVersion
)
43 case D3DPS_VERSION(1, 1):
46 case D3DPS_VERSION(1, 2):
49 case D3DPS_VERSION(1, 3):
52 case D3DPS_VERSION(1, 4):
55 case D3DPS_VERSION(2, 0):
56 if ((caps
.PS20Caps
.NumTemps
>=22) &&
57 (caps
.PS20Caps
.Caps
&D3DPS20CAPS_ARBITRARYSWIZZLE
) &&
58 (caps
.PS20Caps
.Caps
&D3DPS20CAPS_GRADIENTINSTRUCTIONS
) &&
59 (caps
.PS20Caps
.Caps
&D3DPS20CAPS_PREDICATION
) &&
60 (caps
.PS20Caps
.Caps
&D3DPS20CAPS_NODEPENDENTREADLIMIT
) &&
61 (caps
.PS20Caps
.Caps
&D3DPS20CAPS_NOTEXINSTRUCTIONLIMIT
))
65 if ((caps
.PS20Caps
.NumTemps
>=32) &&
66 (caps
.PS20Caps
.Caps
&D3DPS20CAPS_NOTEXINSTRUCTIONLIMIT
))
72 case D3DPS_VERSION(3, 0):
79 UINT WINAPI
D3DXGetShaderSize(const DWORD
*byte_code
)
81 const DWORD
*ptr
= byte_code
;
83 TRACE("byte_code %p\n", byte_code
);
87 /* Look for the END token, skipping the VERSION token */
88 while (*++ptr
!= D3DSIO_END
)
91 if ((*ptr
& D3DSI_OPCODE_MASK
) == D3DSIO_COMMENT
)
93 ptr
+= ((*ptr
& D3DSI_COMMENTSIZE_MASK
) >> D3DSI_COMMENTSIZE_SHIFT
);
98 /* Return the shader size in bytes */
99 return (ptr
- byte_code
) * sizeof(*ptr
);
102 DWORD WINAPI
D3DXGetShaderVersion(const DWORD
*byte_code
)
104 TRACE("byte_code %p\n", byte_code
);
106 return byte_code
? *byte_code
: 0;
109 LPCSTR WINAPI
D3DXGetVertexShaderProfile(LPDIRECT3DDEVICE9 device
)
113 TRACE("device %p\n", device
);
115 if (!device
) return NULL
;
117 IDirect3DDevice9_GetDeviceCaps(device
,&caps
);
119 switch (caps
.VertexShaderVersion
)
121 case D3DVS_VERSION(1, 1):
123 case D3DVS_VERSION(2, 0):
124 if ((caps
.VS20Caps
.NumTemps
>=13) &&
125 (caps
.VS20Caps
.DynamicFlowControlDepth
==24) &&
126 (caps
.VS20Caps
.Caps
&D3DPS20CAPS_PREDICATION
))
131 case D3DVS_VERSION(3, 0):
138 HRESULT WINAPI
D3DXFindShaderComment(CONST DWORD
* byte_code
, DWORD fourcc
, LPCVOID
* data
, UINT
* size
)
140 CONST DWORD
*ptr
= byte_code
;
142 TRACE("(%p, %x, %p, %p)", byte_code
, fourcc
, data
, size
);
145 return D3DERR_INVALIDCALL
;
147 while (*++ptr
!= D3DSIO_END
)
149 /* Check if it is a comment */
150 if ((*ptr
& D3DSI_OPCODE_MASK
) == D3DSIO_COMMENT
)
152 DWORD comment_size
= (*ptr
& D3DSI_COMMENTSIZE_MASK
) >> D3DSI_COMMENTSIZE_SHIFT
;
154 /* Check if this is the comment we are looking for */
155 if (*(ptr
+ 1) == fourcc
)
157 UINT ctab_size
= (comment_size
- 1) * sizeof(DWORD
);
158 LPCVOID ctab_data
= ptr
+ 2;
163 TRACE("Returning comment data at %p with size %d\n", ctab_data
, ctab_size
);
173 HRESULT WINAPI
D3DXAssembleShader(LPCSTR data
,
175 CONST D3DXMACRO
* defines
,
176 LPD3DXINCLUDE include
,
178 LPD3DXBUFFER
* shader
,
179 LPD3DXBUFFER
* error_messages
)
181 FIXME("(%p, %d, %p, %p, %x, %p, %p): stub\n", data
, data_len
, defines
, include
, flags
, shader
, error_messages
);
182 return D3DERR_INVALIDCALL
;
185 HRESULT WINAPI
D3DXAssembleShaderFromFileA(LPCSTR filename
,
186 CONST D3DXMACRO
* defines
,
187 LPD3DXINCLUDE include
,
189 LPD3DXBUFFER
* shader
,
190 LPD3DXBUFFER
* error_messages
)
192 LPWSTR filename_w
= NULL
;
196 if (!filename
) return D3DXERR_INVALIDDATA
;
198 len
= MultiByteToWideChar(CP_ACP
, 0, filename
, -1, NULL
, 0);
199 filename_w
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
200 if (!filename_w
) return E_OUTOFMEMORY
;
201 MultiByteToWideChar(CP_ACP
, 0, filename
, -1, filename_w
, len
);
203 ret
= D3DXAssembleShaderFromFileW(filename_w
, defines
, include
, flags
, shader
, error_messages
);
205 HeapFree(GetProcessHeap(), 0, filename_w
);
209 HRESULT WINAPI
D3DXAssembleShaderFromFileW(LPCWSTR filename
,
210 CONST D3DXMACRO
* defines
,
211 LPD3DXINCLUDE include
,
213 LPD3DXBUFFER
* shader
,
214 LPD3DXBUFFER
* error_messages
)
216 FIXME("(%s, %p, %p, %x, %p, %p): stub\n", debugstr_w(filename
), defines
, include
, flags
, shader
, error_messages
);
217 return D3DERR_INVALIDCALL
;
220 HRESULT WINAPI
D3DXAssembleShaderFromResourceA(HMODULE module
,
222 CONST D3DXMACRO
* defines
,
223 LPD3DXINCLUDE include
,
225 LPD3DXBUFFER
* shader
,
226 LPD3DXBUFFER
* error_messages
)
232 if (!(res
= FindResourceA(module
, resource
, (LPCSTR
)RT_RCDATA
)))
233 return D3DXERR_INVALIDDATA
;
234 if (FAILED(load_resource_into_memory(module
, res
, (LPVOID
*)&buffer
, &len
)))
235 return D3DXERR_INVALIDDATA
;
236 return D3DXAssembleShader(buffer
, len
, defines
, include
, flags
,
237 shader
, error_messages
);
240 HRESULT WINAPI
D3DXAssembleShaderFromResourceW(HMODULE module
,
242 CONST D3DXMACRO
* defines
,
243 LPD3DXINCLUDE include
,
245 LPD3DXBUFFER
* shader
,
246 LPD3DXBUFFER
* error_messages
)
252 if (!(res
= FindResourceW(module
, resource
, (LPCWSTR
)RT_RCDATA
)))
253 return D3DXERR_INVALIDDATA
;
254 if (FAILED(load_resource_into_memory(module
, res
, (LPVOID
*)&buffer
, &len
)))
255 return D3DXERR_INVALIDDATA
;
256 return D3DXAssembleShader(buffer
, len
, defines
, include
, flags
,
257 shader
, error_messages
);
260 HRESULT WINAPI
D3DXCompileShader(LPCSTR pSrcData
,
262 CONST D3DXMACRO
* pDefines
,
263 LPD3DXINCLUDE pInclude
,
264 LPCSTR pFunctionName
,
267 LPD3DXBUFFER
* ppShader
,
268 LPD3DXBUFFER
* ppErrorMsgs
,
269 LPD3DXCONSTANTTABLE
* ppConstantTable
)
271 FIXME("(%p, %d, %p, %p, %p, %p, %d, %p, %p, %p): stub\n",
272 pSrcData
, srcDataLen
, pDefines
, pInclude
, pFunctionName
,
273 pProfile
, Flags
, ppShader
, ppErrorMsgs
, ppConstantTable
);
274 return D3DERR_INVALIDCALL
;
277 static const struct ID3DXConstantTableVtbl ID3DXConstantTable_Vtbl
;
279 typedef struct ID3DXConstantTableImpl
{
280 const ID3DXConstantTableVtbl
*lpVtbl
;
284 } ID3DXConstantTableImpl
;
286 /*** IUnknown methods ***/
287 static HRESULT WINAPI
ID3DXConstantTableImpl_QueryInterface(ID3DXConstantTable
* iface
, REFIID riid
, void** ppvObject
)
289 ID3DXConstantTableImpl
*This
= (ID3DXConstantTableImpl
*)iface
;
291 TRACE("(%p)->(%s, %p)\n", This
, debugstr_guid(riid
), ppvObject
);
293 if (IsEqualGUID(riid
, &IID_IUnknown
) ||
294 IsEqualGUID(riid
, &IID_ID3DXConstantTable
))
296 ID3DXConstantTable_AddRef(iface
);
301 ERR("Interface %s not found\n", debugstr_guid(riid
));
303 return E_NOINTERFACE
;
306 static ULONG WINAPI
ID3DXConstantTableImpl_AddRef(ID3DXConstantTable
* iface
)
308 ID3DXConstantTableImpl
*This
= (ID3DXConstantTableImpl
*)iface
;
310 TRACE("(%p)->(): AddRef from %d\n", This
, This
->ref
);
312 return InterlockedIncrement(&This
->ref
);
315 static ULONG WINAPI
ID3DXConstantTableImpl_Release(ID3DXConstantTable
* iface
)
317 ID3DXConstantTableImpl
*This
= (ID3DXConstantTableImpl
*)iface
;
318 ULONG ref
= InterlockedDecrement(&This
->ref
);
320 TRACE("(%p)->(): Release from %d\n", This
, ref
+ 1);
324 HeapFree(GetProcessHeap(), 0, This
->ctab
);
325 HeapFree(GetProcessHeap(), 0, This
);
331 /*** ID3DXBuffer methods ***/
332 static LPVOID WINAPI
ID3DXConstantTableImpl_GetBufferPointer(ID3DXConstantTable
* iface
)
334 ID3DXConstantTableImpl
*This
= (ID3DXConstantTableImpl
*)iface
;
336 TRACE("(%p)->()\n", This
);
341 static DWORD WINAPI
ID3DXConstantTableImpl_GetBufferSize(ID3DXConstantTable
* iface
)
343 ID3DXConstantTableImpl
*This
= (ID3DXConstantTableImpl
*)iface
;
345 TRACE("(%p)->()\n", This
);
350 /*** ID3DXConstantTable methods ***/
351 static HRESULT WINAPI
ID3DXConstantTableImpl_GetDesc(ID3DXConstantTable
* iface
, D3DXCONSTANTTABLE_DESC
*desc
)
353 ID3DXConstantTableImpl
*This
= (ID3DXConstantTableImpl
*)iface
;
355 FIXME("(%p)->(%p): stub\n", This
, desc
);
360 static HRESULT WINAPI
ID3DXConstantTableImpl_GetConstantDesc(ID3DXConstantTable
* iface
, D3DXHANDLE constant
,
361 D3DXCONSTANT_DESC
*desc
, UINT
*count
)
363 ID3DXConstantTableImpl
*This
= (ID3DXConstantTableImpl
*)iface
;
365 FIXME("(%p)->(%p, %p, %p): stub\n", This
, constant
, desc
, count
);
370 static D3DXHANDLE WINAPI
ID3DXConstantTableImpl_GetConstant(ID3DXConstantTable
* iface
, D3DXHANDLE constant
, UINT index
)
372 ID3DXConstantTableImpl
*This
= (ID3DXConstantTableImpl
*)iface
;
374 FIXME("(%p)->(%p, %d): stub\n", This
, constant
, index
);
379 static D3DXHANDLE WINAPI
ID3DXConstantTableImpl_GetConstantByName(ID3DXConstantTable
* iface
, D3DXHANDLE constant
, LPCSTR name
)
381 ID3DXConstantTableImpl
*This
= (ID3DXConstantTableImpl
*)iface
;
383 FIXME("(%p)->(%p, %s): stub\n", This
, constant
, name
);
388 static D3DXHANDLE WINAPI
ID3DXConstantTableImpl_GetConstantByElement(ID3DXConstantTable
* iface
, D3DXHANDLE constant
, UINT index
)
390 ID3DXConstantTableImpl
*This
= (ID3DXConstantTableImpl
*)iface
;
392 FIXME("(%p)->(%p, %d): stub\n", This
, constant
, index
);
397 static HRESULT WINAPI
ID3DXConstantTableImpl_SetDefaults(ID3DXConstantTable
* iface
, LPDIRECT3DDEVICE9 device
)
399 ID3DXConstantTableImpl
*This
= (ID3DXConstantTableImpl
*)iface
;
401 FIXME("(%p)->(%p): stub\n", This
, device
);
406 static HRESULT WINAPI
ID3DXConstantTableImpl_SetValue(ID3DXConstantTable
* iface
, LPDIRECT3DDEVICE9 device
,
407 D3DXHANDLE constant
, LPCVOID data
, UINT bytes
)
409 ID3DXConstantTableImpl
*This
= (ID3DXConstantTableImpl
*)iface
;
411 FIXME("(%p)->(%p, %p, %p, %d): stub\n", This
, device
, constant
, data
, bytes
);
416 static HRESULT WINAPI
ID3DXConstantTableImpl_SetBool(ID3DXConstantTable
* iface
, LPDIRECT3DDEVICE9 device
,
417 D3DXHANDLE constant
, BOOL b
)
419 ID3DXConstantTableImpl
*This
= (ID3DXConstantTableImpl
*)iface
;
421 FIXME("(%p)->(%p, %p, %d): stub\n", This
, device
, constant
, b
);
426 static HRESULT WINAPI
ID3DXConstantTableImpl_SetBoolArray(ID3DXConstantTable
* iface
, LPDIRECT3DDEVICE9 device
,
427 D3DXHANDLE constant
, CONST BOOL
* b
, UINT count
)
429 ID3DXConstantTableImpl
*This
= (ID3DXConstantTableImpl
*)iface
;
431 FIXME("(%p)->(%p, %p, %p, %d): stub\n", This
, device
, constant
, b
, count
);
436 static HRESULT WINAPI
ID3DXConstantTableImpl_SetInt(ID3DXConstantTable
* iface
, LPDIRECT3DDEVICE9 device
, D3DXHANDLE constant
, INT n
)
438 ID3DXConstantTableImpl
*This
= (ID3DXConstantTableImpl
*)iface
;
440 FIXME("(%p)->(%p, %p, %d): stub\n", This
, device
, constant
, n
);
445 static HRESULT WINAPI
ID3DXConstantTableImpl_SetIntArray(ID3DXConstantTable
* iface
, LPDIRECT3DDEVICE9 device
,
446 D3DXHANDLE constant
, CONST INT
* n
, UINT count
)
448 ID3DXConstantTableImpl
*This
= (ID3DXConstantTableImpl
*)iface
;
450 FIXME("(%p)->(%p, %p, %p, %d): stub\n", This
, device
, constant
, n
, count
);
455 static HRESULT WINAPI
ID3DXConstantTableImpl_SetFloat(ID3DXConstantTable
* iface
, LPDIRECT3DDEVICE9 device
,
456 D3DXHANDLE constant
, FLOAT f
)
458 ID3DXConstantTableImpl
*This
= (ID3DXConstantTableImpl
*)iface
;
460 FIXME("(%p)->(%p, %p, %f): stub\n", This
, device
, constant
, f
);
465 static HRESULT WINAPI
ID3DXConstantTableImpl_SetFloatArray(ID3DXConstantTable
* iface
, LPDIRECT3DDEVICE9 device
,
466 D3DXHANDLE constant
, CONST FLOAT
* f
, UINT count
)
468 ID3DXConstantTableImpl
*This
= (ID3DXConstantTableImpl
*)iface
;
470 FIXME("(%p)->(%p, %p, %p, %d): stub\n", This
, device
, constant
, f
, count
);
475 static HRESULT WINAPI
ID3DXConstantTableImpl_SetVector(ID3DXConstantTable
* iface
, LPDIRECT3DDEVICE9 device
,
476 D3DXHANDLE constant
, CONST D3DXVECTOR4
* vector
)
478 ID3DXConstantTableImpl
*This
= (ID3DXConstantTableImpl
*)iface
;
480 FIXME("(%p)->(%p, %p, %p): stub\n", This
, device
, constant
, vector
);
485 static HRESULT WINAPI
ID3DXConstantTableImpl_SetVectorArray(ID3DXConstantTable
* iface
, LPDIRECT3DDEVICE9 device
,
486 D3DXHANDLE constant
, CONST D3DXVECTOR4
* vector
, UINT count
)
488 ID3DXConstantTableImpl
*This
= (ID3DXConstantTableImpl
*)iface
;
490 FIXME("(%p)->(%p, %p, %p, %d): stub\n", This
, device
, constant
, vector
, count
);
495 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrix(ID3DXConstantTable
* iface
, LPDIRECT3DDEVICE9 device
,
496 D3DXHANDLE constant
, CONST D3DXMATRIX
* matrix
)
498 ID3DXConstantTableImpl
*This
= (ID3DXConstantTableImpl
*)iface
;
500 FIXME("(%p)->(%p, %p, %p): stub\n", This
, device
, constant
, matrix
);
505 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrixArray(ID3DXConstantTable
* iface
, LPDIRECT3DDEVICE9 device
,
506 D3DXHANDLE constant
, CONST D3DXMATRIX
* matrix
, UINT count
)
508 ID3DXConstantTableImpl
*This
= (ID3DXConstantTableImpl
*)iface
;
510 FIXME("(%p)->(%p, %p, %p, %d): stub\n", This
, device
, constant
, matrix
, count
);
515 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrixPointerArray(ID3DXConstantTable
* iface
, LPDIRECT3DDEVICE9 device
,
516 D3DXHANDLE constant
, CONST D3DXMATRIX
** matrix
, UINT count
)
518 ID3DXConstantTableImpl
*This
= (ID3DXConstantTableImpl
*)iface
;
520 FIXME("(%p)->(%p, %p, %p, %d): stub\n", This
, device
, constant
, matrix
, count
);
525 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrixTranspose(ID3DXConstantTable
* iface
, LPDIRECT3DDEVICE9 device
,
526 D3DXHANDLE constant
, CONST D3DXMATRIX
* matrix
)
528 ID3DXConstantTableImpl
*This
= (ID3DXConstantTableImpl
*)iface
;
530 FIXME("(%p)->(%p, %p, %p): stub\n", This
, device
, constant
, matrix
);
535 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrixTransposeArray(ID3DXConstantTable
* iface
, LPDIRECT3DDEVICE9 device
,
536 D3DXHANDLE constant
, CONST D3DXMATRIX
* matrix
, UINT count
)
538 ID3DXConstantTableImpl
*This
= (ID3DXConstantTableImpl
*)iface
;
540 FIXME("(%p)->(%p, %p, %p, %d): stub\n", This
, device
, constant
, matrix
, count
);
545 static HRESULT WINAPI
ID3DXConstantTableImpl_SetMatrixTransposePointerArray(ID3DXConstantTable
* iface
, LPDIRECT3DDEVICE9 device
,
546 D3DXHANDLE constant
, CONST D3DXMATRIX
** matrix
, UINT count
)
548 ID3DXConstantTableImpl
*This
= (ID3DXConstantTableImpl
*)iface
;
550 FIXME("(%p)->(%p, %p, %p, %d): stub\n", This
, device
, constant
, matrix
, count
);
555 static const struct ID3DXConstantTableVtbl ID3DXConstantTable_Vtbl
=
557 /*** IUnknown methods ***/
558 ID3DXConstantTableImpl_QueryInterface
,
559 ID3DXConstantTableImpl_AddRef
,
560 ID3DXConstantTableImpl_Release
,
561 /*** ID3DXBuffer methods ***/
562 ID3DXConstantTableImpl_GetBufferPointer
,
563 ID3DXConstantTableImpl_GetBufferSize
,
564 /*** ID3DXConstantTable methods ***/
565 ID3DXConstantTableImpl_GetDesc
,
566 ID3DXConstantTableImpl_GetConstantDesc
,
567 ID3DXConstantTableImpl_GetConstant
,
568 ID3DXConstantTableImpl_GetConstantByName
,
569 ID3DXConstantTableImpl_GetConstantByElement
,
570 ID3DXConstantTableImpl_SetDefaults
,
571 ID3DXConstantTableImpl_SetValue
,
572 ID3DXConstantTableImpl_SetBool
,
573 ID3DXConstantTableImpl_SetBoolArray
,
574 ID3DXConstantTableImpl_SetInt
,
575 ID3DXConstantTableImpl_SetIntArray
,
576 ID3DXConstantTableImpl_SetFloat
,
577 ID3DXConstantTableImpl_SetFloatArray
,
578 ID3DXConstantTableImpl_SetVector
,
579 ID3DXConstantTableImpl_SetVectorArray
,
580 ID3DXConstantTableImpl_SetMatrix
,
581 ID3DXConstantTableImpl_SetMatrixArray
,
582 ID3DXConstantTableImpl_SetMatrixPointerArray
,
583 ID3DXConstantTableImpl_SetMatrixTranspose
,
584 ID3DXConstantTableImpl_SetMatrixTransposeArray
,
585 ID3DXConstantTableImpl_SetMatrixTransposePointerArray
588 HRESULT WINAPI
D3DXGetShaderConstantTableEx(CONST DWORD
* byte_code
,
590 LPD3DXCONSTANTTABLE
* constant_table
)
592 ID3DXConstantTableImpl
* object
;
597 FIXME("(%p, %x, %p): semi-stub\n", byte_code
, flags
, constant_table
);
599 if (!byte_code
|| !constant_table
)
600 return D3DERR_INVALIDCALL
;
602 hr
= D3DXFindShaderComment(byte_code
, MAKEFOURCC('C','T','A','B'), &data
, &size
);
604 return D3DXERR_INVALIDDATA
;
606 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(ID3DXConstantTableImpl
));
609 ERR("Out of memory\n");
610 return E_OUTOFMEMORY
;
613 object
->lpVtbl
= &ID3DXConstantTable_Vtbl
;
616 object
->ctab
= HeapAlloc(GetProcessHeap(), 0, size
);
619 HeapFree(GetProcessHeap(), 0, object
);
620 ERR("Out of memory\n");
621 return E_OUTOFMEMORY
;
624 memcpy(object
->ctab
, data
, object
->size
);
626 *constant_table
= (LPD3DXCONSTANTTABLE
)object
;
631 HRESULT WINAPI
D3DXGetShaderConstantTable(CONST DWORD
* byte_code
,
632 LPD3DXCONSTANTTABLE
* constant_table
)
634 TRACE("(%p, %p): Forwarded to D3DXGetShaderConstantTableEx\n", byte_code
, constant_table
);
636 return D3DXGetShaderConstantTableEx(byte_code
, 0, constant_table
);