Merge from amd64-branch:
[reactos.git] / reactos / dll / directx / wine / d3dx9_36 / shader.c
1 /*
2 * Copyright 2008 Luis Busquets
3 *
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.
8 *
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.
13 *
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
17 */
18
19 #include "config.h"
20 #include "wine/port.h"
21 #include "wine/debug.h"
22 #include "wine/unicode.h"
23 #include "windef.h"
24 #include "wingdi.h"
25 #include "d3dx9.h"
26 #include "d3dx9_36_private.h"
27
28 WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
29
30 LPCSTR WINAPI D3DXGetPixelShaderProfile(LPDIRECT3DDEVICE9 device)
31 {
32 D3DCAPS9 caps;
33
34 TRACE("device %p\n", device);
35
36 if (!device) return NULL;
37
38 IDirect3DDevice9_GetDeviceCaps(device,&caps);
39
40 switch (caps.PixelShaderVersion)
41 {
42 case D3DPS_VERSION(1, 1):
43 return "ps_1_1";
44
45 case D3DPS_VERSION(1, 2):
46 return "ps_1_2";
47
48 case D3DPS_VERSION(1, 3):
49 return "ps_1_3";
50
51 case D3DPS_VERSION(1, 4):
52 return "ps_1_4";
53
54 case D3DPS_VERSION(2, 0):
55 if ((caps.PS20Caps.NumTemps>=22) &&
56 (caps.PS20Caps.Caps&D3DPS20CAPS_ARBITRARYSWIZZLE) &&
57 (caps.PS20Caps.Caps&D3DPS20CAPS_GRADIENTINSTRUCTIONS) &&
58 (caps.PS20Caps.Caps&D3DPS20CAPS_PREDICATION) &&
59 (caps.PS20Caps.Caps&D3DPS20CAPS_NODEPENDENTREADLIMIT) &&
60 (caps.PS20Caps.Caps&D3DPS20CAPS_NOTEXINSTRUCTIONLIMIT))
61 {
62 return "ps_2_a";
63 }
64 if ((caps.PS20Caps.NumTemps>=32) &&
65 (caps.PS20Caps.Caps&D3DPS20CAPS_NOTEXINSTRUCTIONLIMIT))
66 {
67 return "ps_2_b";
68 }
69 return "ps_2_0";
70
71 case D3DPS_VERSION(3, 0):
72 return "ps_3_0";
73 }
74
75 return NULL;
76 }
77
78 UINT WINAPI D3DXGetShaderSize(const DWORD *byte_code)
79 {
80 const DWORD *ptr = byte_code;
81
82 TRACE("byte_code %p\n", byte_code);
83
84 if (!ptr) return 0;
85
86 /* Look for the END token, skipping the VERSION token */
87 while (*++ptr != D3DSIO_END)
88 {
89 /* Skip comments */
90 if ((*ptr & D3DSI_OPCODE_MASK) == D3DSIO_COMMENT)
91 {
92 ptr += ((*ptr & D3DSI_COMMENTSIZE_MASK) >> D3DSI_COMMENTSIZE_SHIFT);
93 }
94 }
95 ++ptr;
96
97 /* Return the shader size in bytes */
98 return (ptr - byte_code) * sizeof(*ptr);
99 }
100
101 DWORD WINAPI D3DXGetShaderVersion(const DWORD *byte_code)
102 {
103 TRACE("byte_code %p\n", byte_code);
104
105 return byte_code ? *byte_code : 0;
106 }
107
108 LPCSTR WINAPI D3DXGetVertexShaderProfile(LPDIRECT3DDEVICE9 device)
109 {
110 D3DCAPS9 caps;
111
112 TRACE("device %p\n", device);
113
114 if (!device) return NULL;
115
116 IDirect3DDevice9_GetDeviceCaps(device,&caps);
117
118 switch (caps.VertexShaderVersion)
119 {
120 case D3DVS_VERSION(1, 1):
121 return "vs_1_1";
122 case D3DVS_VERSION(2, 0):
123 if ((caps.VS20Caps.NumTemps>=13) &&
124 (caps.VS20Caps.DynamicFlowControlDepth==24) &&
125 (caps.VS20Caps.Caps&D3DPS20CAPS_PREDICATION))
126 {
127 return "vs_2_a";
128 }
129 return "vs_2_0";
130 case D3DVS_VERSION(3, 0):
131 return "vs_3_0";
132 }
133
134 return NULL;
135 }
136
137 HRESULT WINAPI D3DXAssembleShader(LPCSTR data,
138 UINT data_len,
139 CONST D3DXMACRO* defines,
140 LPD3DXINCLUDE include,
141 DWORD flags,
142 LPD3DXBUFFER* shader,
143 LPD3DXBUFFER* error_messages)
144 {
145 FIXME("stub\n");
146 return D3DERR_INVALIDCALL;
147 }
148
149 HRESULT WINAPI D3DXAssembleShaderFromFileA(LPCSTR filename,
150 CONST D3DXMACRO* defines,
151 LPD3DXINCLUDE include,
152 DWORD flags,
153 LPD3DXBUFFER* shader,
154 LPD3DXBUFFER* error_messages)
155 {
156 LPWSTR filename_w = NULL;
157 DWORD len;
158 HRESULT ret;
159
160 if (!filename) return D3DXERR_INVALIDDATA;
161
162 len = MultiByteToWideChar(CP_ACP, 0, filename, -1, NULL, 0);
163 filename_w = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
164 if (!filename_w) return E_OUTOFMEMORY;
165 MultiByteToWideChar(CP_ACP, 0, filename, -1, filename_w, len);
166
167 ret = D3DXAssembleShaderFromFileW(filename_w, defines, include, flags, shader, error_messages);
168
169 HeapFree(GetProcessHeap(), 0, filename_w);
170 return ret;
171 }
172
173 HRESULT WINAPI D3DXAssembleShaderFromFileW(LPCWSTR filename,
174 CONST D3DXMACRO* defines,
175 LPD3DXINCLUDE include,
176 DWORD flags,
177 LPD3DXBUFFER* shader,
178 LPD3DXBUFFER* error_messages)
179 {
180 FIXME("stub\n");
181 return D3DERR_INVALIDCALL;
182 }
183
184 HRESULT WINAPI D3DXAssembleShaderFromResourceA(HMODULE module,
185 LPCSTR resource,
186 CONST D3DXMACRO* defines,
187 LPD3DXINCLUDE include,
188 DWORD flags,
189 LPD3DXBUFFER* shader,
190 LPD3DXBUFFER* error_messages)
191 {
192 HRSRC res;
193 LPCSTR buffer;
194 DWORD len;
195
196 if (!(res = FindResourceA(module, resource, (LPCSTR)RT_RCDATA)))
197 return D3DXERR_INVALIDDATA;
198 if (FAILED(load_resource_into_memory(module, res, (LPVOID *)&buffer, &len)))
199 return D3DXERR_INVALIDDATA;
200 return D3DXAssembleShader(buffer, len, defines, include, flags,
201 shader, error_messages);
202 }
203
204 HRESULT WINAPI D3DXAssembleShaderFromResourceW(HMODULE module,
205 LPCWSTR resource,
206 CONST D3DXMACRO* defines,
207 LPD3DXINCLUDE include,
208 DWORD flags,
209 LPD3DXBUFFER* shader,
210 LPD3DXBUFFER* error_messages)
211 {
212 HRSRC res;
213 LPCSTR buffer;
214 DWORD len;
215
216 if (!(res = FindResourceW(module, resource, (LPCWSTR)RT_RCDATA)))
217 return D3DXERR_INVALIDDATA;
218 if (FAILED(load_resource_into_memory(module, res, (LPVOID *)&buffer, &len)))
219 return D3DXERR_INVALIDDATA;
220 return D3DXAssembleShader(buffer, len, defines, include, flags,
221 shader, error_messages);
222 }