fdopen: don't rewind the file after creating the FILE* handle. Added
[wine] / dlls / d3d8 / shader.c
1 /*
2  * shaders implementation
3  *
4  * Copyright 2002 Raphael Junqueira
5  *
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.
10  *
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.
15  *
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include "windef.h"
22 #include "winbase.h"
23 #include "winuser.h"
24 #include "wingdi.h"
25 #include "wine/debug.h"
26
27 #include <math.h>
28
29 #include "d3d8_private.h"
30
31 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
32
33 typedef void (*shader_fct0_t)(void);
34 typedef void (*shader_fct1_t)(SHADER8Vector*);
35 typedef void (*shader_fct2_t)(SHADER8Vector*,SHADER8Vector*);
36 typedef void (*shader_fct3_t)(SHADER8Vector*,SHADER8Vector*,SHADER8Vector*);
37 typedef void (*shader_fct4_t)(SHADER8Vector*,SHADER8Vector*,SHADER8Vector*,SHADER8Vector*);
38
39 /*
40 typedef union shader_fct {
41   shader_fct0_t fct0;
42   shader_fct1_t fct1;
43   shader_fct2_t fct2;
44   shader_fct3_t fct3;
45   shader_fct4_t fct4;
46 } shader_fct;
47 */
48 typedef void (*shader_fct)();
49
50 typedef struct shader_opcode {
51   CONST BYTE  opcode;
52   const char* name;
53   CONST UINT  num_params;
54   shader_fct  soft_fct;
55   /*
56   union {
57     shader_fct0_t fct0;
58     shader_fct1_t fct1;
59     shader_fct2_t fct2;
60     shader_fct3_t fct3;
61     shader_fct4_t fct4;
62   } shader_fct;
63   */
64 } shader_opcode;
65
66 typedef struct vshader_input_data {
67   /*SHADER8Vector V[16];//0-15 */
68   SHADER8Vector V0;
69   SHADER8Vector V1;
70   SHADER8Vector V2;
71   SHADER8Vector V3;
72   SHADER8Vector V4;
73   SHADER8Vector V5;
74   SHADER8Vector V6;
75   SHADER8Vector V7;
76   SHADER8Vector V8;
77   SHADER8Vector V9;
78   SHADER8Vector V10;
79   SHADER8Vector V11;
80   SHADER8Vector V12;
81   SHADER8Vector V13;
82   SHADER8Vector V14;
83   SHADER8Vector V15;
84 } vshader_input_data;
85
86 typedef struct vshader_output_data {
87   SHADER8Vector oPos;
88   /*SHADER8Vector oD[2];//0-1 */
89   SHADER8Vector oD0;
90   SHADER8Vector oD1;
91   /*SHADER8Vector oT[4];//0-3 */
92   SHADER8Vector oT0;
93   SHADER8Vector oT1;
94   SHADER8Vector oT2;
95   SHADER8Vector oT3;
96   SHADER8Scalar oFog;
97   SHADER8Scalar oPts;
98 } vshader_output_data;
99
100 /*********************
101  * vshader software VM
102  */
103
104 void vshader_add(SHADER8Vector* d, SHADER8Vector* s0, SHADER8Vector* s1) {
105   d->x = s0->x + s1->x;
106   d->y = s0->y + s1->y;
107   d->z = s0->z + s1->z;
108   d->w = s0->w + s1->w;
109 }
110
111 void vshader_dp3(SHADER8Vector* d, SHADER8Vector* s0, SHADER8Vector* s1) {
112   d->x = d->y = d->z = d->w = s0->x * s1->x + s0->y * s1->y + s0->z * s1->z;
113 }
114
115 void vshader_dp4(SHADER8Vector* d, SHADER8Vector* s0, SHADER8Vector* s1) {
116   d->x = d->y = d->z = d->w = s0->x * s1->x + s0->y * s1->y + s0->z * s1->z + s0->w * s1->w;
117 }
118
119 void vshader_dst(SHADER8Vector* d, SHADER8Vector* s0, SHADER8Vector* s1) {
120   d->x = 1;
121   d->y = s0->y * s1->y;
122   d->z = s0->z;
123   d->w = s1->w;
124 }
125
126 void vshader_expp(SHADER8Vector* d, SHADER8Vector* s0) {
127   float tmp_f = floorf(s0->w);
128   d->x = pow(2, tmp_f);
129   d->y = s0->w - tmp_f;
130   d->z = pow(2, s0->w);
131   d->w = 1;
132 }
133
134 void vshader_lit(SHADER8Vector* d, SHADER8Vector* s0) {
135   d->x = 1;
136   d->y = (0 < s0->x) ? s0->x : 0;
137   d->z = (0 < s0->x && 0 < s0->y) ? pow(s0->y, s0->w) : 0;
138   d->w = 1;
139 }
140
141 void vshader_logp(SHADER8Vector* d, SHADER8Vector* s0) {
142   d->x = d->y = d->z = d->w = (0 != s0->w) ? log(fabsf(s0->w))/log(2) : HUGE;
143 }
144
145 void vshader_mad(SHADER8Vector* d, SHADER8Vector* s0, SHADER8Vector* s1, SHADER8Vector* s2) {
146   d->x = s0->x * s1->x + s2->x;
147   d->y = s0->y * s1->y + s2->y;
148   d->z = s0->z * s1->z + s2->z;
149   d->w = s0->w * s1->w + s2->w;
150 }
151
152 void vshader_max(SHADER8Vector* d, SHADER8Vector* s0, SHADER8Vector* s1) {
153   d->x = (s0->x >= s1->x) ? s0->x : s1->x;
154   d->y = (s0->y >= s1->y) ? s0->y : s1->y;
155   d->z = (s0->z >= s1->z) ? s0->z : s1->z;
156   d->w = (s0->w >= s1->w) ? s0->w : s1->w;
157 }
158
159 void vshader_min(SHADER8Vector* d, SHADER8Vector* s0, SHADER8Vector* s1) {
160   d->x = (s0->x < s1->x) ? s0->x : s1->x;
161   d->y = (s0->y < s1->y) ? s0->y : s1->y;
162   d->z = (s0->z < s1->z) ? s0->z : s1->z;
163   d->w = (s0->w < s1->w) ? s0->w : s1->w;
164 }
165
166 void vshader_mov(SHADER8Vector* d, SHADER8Vector* s0) {
167   d->x = s0->x;
168   d->y = s0->y;
169   d->z = s0->z;
170   d->w = s0->w;
171 }
172
173 void vshader_mul(SHADER8Vector* d, SHADER8Vector* s0, SHADER8Vector* s1) {
174   d->x = s0->x * s1->x;
175   d->y = s0->y * s1->y;
176   d->z = s0->z * s1->z;
177   d->w = s0->w * s1->w;
178 }
179
180 void vshader_nop(void) {
181   /* NOPPPP ahhh too easy ;) */
182 }
183
184 void vshader_rcp(SHADER8Vector* d, SHADER8Vector* s0) {
185   d->x = d->y = d->z = d->w = (0 == s0->w) ? HUGE : 1 / s0->w;
186 }
187
188 void vshader_rsq(SHADER8Vector* d, SHADER8Vector* s0) {
189   d->x = d->y = d->z = d->w = (0 == s0->w) ? HUGE : 1 / sqrt(fabsf(s0->w));
190 }
191
192 void vshader_sge(SHADER8Vector* d, SHADER8Vector* s0, SHADER8Vector* s1) {
193   d->x = (s0->x >= s1->x) ? 1 : 0;
194   d->y = (s0->y >= s1->y) ? 1 : 0;
195   d->z = (s0->z >= s1->z) ? 1 : 0;
196   d->w = (s0->w >= s1->w) ? 1 : 0;
197 }
198
199 void vshader_slt(SHADER8Vector* d, SHADER8Vector* s0, SHADER8Vector* s1) {
200   d->x = (s0->x < s1->x) ? 1 : 0;
201   d->y = (s0->y < s1->y) ? 1 : 0;
202   d->z = (s0->z < s1->z) ? 1 : 0;
203   d->w = (s0->w < s1->w) ? 1 : 0;
204 }
205
206 void vshader_sub(SHADER8Vector* d, SHADER8Vector* s0, SHADER8Vector* s1) {
207   d->x = s0->x - s1->x;
208   d->y = s0->y - s1->y;
209   d->z = s0->z - s1->z;
210   d->w = s0->w - s1->w;
211 }
212
213 /**
214  * log, exp, frc, m*x* seems to be macros ins ... to see
215  *
216  * @TODO: find this fucking really opcodes values
217  */
218 static CONST shader_opcode vshader_ins [] =
219   {
220     {0, "mov",  2, vshader_mov},
221     {0, "max",  3, vshader_max},
222     {0, "min",  3, vshader_min},
223     {0, "sge",  3, vshader_sge},
224     {0, "slt",  3, vshader_slt},
225     {0, "add",  3, vshader_add},
226     {0, "sub",  3, vshader_sub},
227     {0, "mul",  3, vshader_mul},
228     {0, "rcp",  2, vshader_rcp},
229     {0, "mad",  4, vshader_mad},
230     {0, "dp3",  3, vshader_dp3},
231     {0, "dp4",  3, vshader_dp4},
232     {0, "rsq",  2, vshader_rsq},
233     {0, "dst",  3, vshader_dst},
234     {0, "lit",  2, vshader_lit},
235     {0, "expp", 2, vshader_expp},
236     {0, "logp", 2, vshader_logp},
237     {0, "nop",  0, vshader_nop},
238     {0, NULL, 0, NULL}
239   };
240
241
242 shader_opcode* vshader_get_opcode(const DWORD code) {
243   return NULL;
244 }
245
246 /**
247  * Function parser ...
248  */
249 BOOL vshader_parse_function(const DWORD* function) {
250   return TRUE;
251 }
252
253 BOOL vshader_hardware_execute_function(VERTEXSHADER8* vshader,
254                                        const vshader_input_data* input,
255                                        vshader_output_data* output) {
256   /** 
257    * TODO: use the GL_NV_vertex_program 
258    *  and specifics vendors variants for it 
259    */
260   return TRUE;
261 }
262
263 BOOL vshader_software_execute_function(VERTEXSHADER8* vshader,
264                                        const vshader_input_data* input,
265                                        vshader_output_data* output) {
266   /** Vertex Shader Temporary Registers */
267   /*SHADER8Vector R[12];*/
268   /*SHADER8Scalar A0;*/
269   /** temporary Vector for modifier management */
270   /*SHADER8Vector d;*/
271   /** parser datas */
272   const DWORD* pToken = vshader->function;
273   shader_opcode* curOpcode = NULL;
274   
275   /* the first dword is the version tag */
276   /* TODO: parse it */
277   
278   ++pToken;
279   while (0xFFFFFFFF != *pToken) {
280     curOpcode = vshader_get_opcode(*pToken);
281     ++pToken;
282     if (NULL == curOpcode) {
283       /* unkown current opcode ... */
284       return FALSE;
285     }
286     if (curOpcode->num_params > 0) {
287       /* TODO */
288     }
289   }
290   return TRUE;
291 }
292
293 /**
294  * Declaration Parser First draft ...
295  */
296
297 #if 0
298 static CONST char* vshader_decl [] =
299   {
300     "D3DVSDT_D3DCOLOR",
301     "D3DVSDT_FLOAT1",
302     "D3DVSDT_FLOAT2",
303     "D3DVSDT_FLOAT3",
304     "D3DVSDT_FLOAT4",
305     "D3DVSDT_UBYTE4",
306     NULL
307   };
308 #endif
309
310 /** Vertex Shader Declaration parser tokens */
311 enum D3DVSD_TOKENS {
312   D3DVSD_STREAM,
313   
314   D3DVSD_END
315 };
316
317 BOOL vshader_parse_declaration(VERTEXSHADER8* vshader) {
318   /** parser data */
319   const DWORD* pToken = vshader->decl;
320
321   ++pToken;
322   while (0xFFFFFFFF != *pToken) {
323     /** TODO */
324     ++pToken;
325   }
326   return TRUE;
327 }
328
329 HRESULT WINAPI ValidatePixelShader(void) {
330   FIXME("(void): stub\n");
331   return 0;
332 }
333
334 HRESULT WINAPI ValidateVertexShader(void) {
335   FIXME("(void): stub\n");
336   return 0;
337 }