VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/shader_sm4.c@ 19678

Last change on this file since 19678 was 19678, checked in by vboxsync, 16 years ago

opengl: update wine to 1.1.21, add d3d9.dll to build list

  • Property svn:eol-style set to native
File size: 9.6 KB
Line 
1/*
2 * Copyright 2009 Henri Verbeet for CodeWeavers
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/*
20 * Sun LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
21 * other than GPL or LGPL is available it will apply instead, Sun elects to use only
22 * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
23 * a choice of LGPL license versions is made available with the language indicating
24 * that LGPLv2 or any later version may be used, or where a choice of which version
25 * of the LGPL is applied is otherwise unspecified.
26 */
27
28#include "config.h"
29#include "wine/port.h"
30
31#include "wined3d_private.h"
32
33WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
34
35#define WINED3D_SM4_INSTRUCTION_LENGTH_SHIFT 24
36#define WINED3D_SM4_INSTRUCTION_LENGTH_MASK (0xf << WINED3D_SM4_INSTRUCTION_LENGTH_SHIFT)
37
38#define WINED3D_SM4_OPCODE_MASK 0xff
39
40#define WINED3D_SM4_REGISTER_TYPE_SHIFT 12
41#define WINED3D_SM4_REGISTER_TYPE_MASK (0xf << WINED3D_SM4_REGISTER_TYPE_SHIFT)
42
43#define WINED3D_SM4_IMMCONST_TYPE_SHIFT 0
44#define WINED3D_SM4_IMMCONST_TYPE_MASK (0x3 << WINED3D_SM4_IMMCONST_TYPE_SHIFT)
45
46#define WINED3D_SM4_WRITEMASK_SHIFT 4
47#define WINED3D_SM4_WRITEMASK_MASK (0xf << WINED3D_SM4_WRITEMASK_SHIFT)
48
49#define WINED3D_SM4_SWIZZLE_SHIFT 4
50#define WINED3D_SM4_SWIZZLE_MASK (0xff << WINED3D_SM4_SWIZZLE_SHIFT)
51
52#define WINED3D_SM4_VERSION_MAJOR(version) (((version) >> 4) & 0xf)
53#define WINED3D_SM4_VERSION_MINOR(version) (((version) >> 0) & 0xf)
54
55enum wined3d_sm4_opcode
56{
57 WINED3D_SM4_OP_ADD = 0x00,
58 WINED3D_SM4_OP_EXP = 0x19,
59 WINED3D_SM4_OP_MOV = 0x36,
60 WINED3D_SM4_OP_MUL = 0x38,
61 WINED3D_SM4_OP_RET = 0x3e,
62 WINED3D_SM4_OP_SINCOS = 0x4d,
63};
64
65enum wined3d_sm4_register_type
66{
67 WINED3D_SM4_RT_TEMP = 0x0,
68 WINED3D_SM4_RT_INPUT = 0x1,
69 WINED3D_SM4_RT_OUTPUT = 0x2,
70 WINED3D_SM4_RT_IMMCONST = 0x4,
71};
72
73enum wined3d_sm4_immconst_type
74{
75 WINED3D_SM4_IMMCONST_FLOAT = 0x1,
76 WINED3D_SM4_IMMCONST_FLOAT4 = 0x2,
77};
78
79struct wined3d_sm4_data
80{
81 struct wined3d_shader_version shader_version;
82 const DWORD *end;
83};
84
85struct wined3d_sm4_opcode_info
86{
87 enum wined3d_sm4_opcode opcode;
88 enum WINED3D_SHADER_INSTRUCTION_HANDLER handler_idx;
89 UINT dst_count;
90 UINT src_count;
91};
92
93static const struct wined3d_sm4_opcode_info opcode_table[] =
94{
95 {WINED3D_SM4_OP_ADD, WINED3DSIH_ADD, 1, 2},
96 {WINED3D_SM4_OP_EXP, WINED3DSIH_EXP, 1, 1},
97 {WINED3D_SM4_OP_MOV, WINED3DSIH_MOV, 1, 1},
98 {WINED3D_SM4_OP_MUL, WINED3DSIH_MUL, 1, 2},
99 {WINED3D_SM4_OP_RET, WINED3DSIH_RET, 0, 0},
100 {WINED3D_SM4_OP_SINCOS, WINED3DSIH_SINCOS, 1, 2},
101};
102
103static const WINED3DSHADER_PARAM_REGISTER_TYPE register_type_table[] =
104{
105 /* WINED3D_SM4_RT_TEMP */ WINED3DSPR_TEMP,
106 /* WINED3D_SM4_RT_INPUT */ WINED3DSPR_INPUT,
107 /* WINED3D_SM4_RT_OUTPUT */ WINED3DSPR_OUTPUT,
108 /* UNKNOWN */ 0,
109 /* WINED3D_SM4_RT_IMMCONST */ WINED3DSPR_IMMCONST,
110};
111
112static const struct wined3d_sm4_opcode_info *get_opcode_info(enum wined3d_sm4_opcode opcode)
113{
114 unsigned int i;
115
116 for (i = 0; i < sizeof(opcode_table) / sizeof(*opcode_table); ++i)
117 {
118 if (opcode == opcode_table[i].opcode) return &opcode_table[i];
119 }
120
121 return NULL;
122}
123
124static void *shader_sm4_init(const DWORD *byte_code)
125{
126 struct wined3d_sm4_data *priv = HeapAlloc(GetProcessHeap(), 0, sizeof(*priv));
127 if (!priv)
128 {
129 ERR("Failed to allocate private data\n");
130 return NULL;
131 }
132
133 return priv;
134}
135
136static void shader_sm4_free(void *data)
137{
138 HeapFree(GetProcessHeap(), 0, data);
139}
140
141static void shader_sm4_read_header(void *data, const DWORD **ptr, struct wined3d_shader_version *shader_version)
142{
143 struct wined3d_sm4_data *priv = data;
144 DWORD version_token;
145
146 priv->end = *ptr;
147
148 version_token = *(*ptr)++;
149 TRACE("version: 0x%08x\n", version_token);
150
151 TRACE("token count: %u\n", **ptr);
152 priv->end += *(*ptr)++;
153
154 switch (version_token >> 16)
155 {
156 case WINED3D_SM4_PS:
157 priv->shader_version.type = WINED3D_SHADER_TYPE_PIXEL;
158 break;
159
160 case WINED3D_SM4_VS:
161 priv->shader_version.type = WINED3D_SHADER_TYPE_VERTEX;
162 break;
163
164 case WINED3D_SM4_GS:
165 priv->shader_version.type = WINED3D_SHADER_TYPE_GEOMETRY;
166 break;
167
168 default:
169 FIXME("Unrecognized shader type %#x\n", version_token >> 16);
170 }
171 priv->shader_version.major = WINED3D_SM4_VERSION_MAJOR(version_token);
172 priv->shader_version.minor = WINED3D_SM4_VERSION_MINOR(version_token);
173
174 *shader_version = priv->shader_version;
175}
176
177static void shader_sm4_read_opcode(void *data, const DWORD **ptr, struct wined3d_shader_instruction *ins,
178 UINT *param_size)
179{
180 const struct wined3d_sm4_opcode_info *opcode_info;
181 DWORD token = *(*ptr)++;
182 DWORD opcode = token & WINED3D_SM4_OPCODE_MASK;
183
184 *param_size = ((token & WINED3D_SM4_INSTRUCTION_LENGTH_MASK) >> WINED3D_SM4_INSTRUCTION_LENGTH_SHIFT) - 1;
185
186 opcode_info = get_opcode_info(opcode);
187 if (!opcode_info)
188 {
189 FIXME("Unrecognized opcode %#x, token 0x%08x\n", opcode, token);
190 ins->handler_idx = WINED3DSIH_TABLE_SIZE;
191 return;
192 }
193
194 ins->handler_idx = opcode_info->handler_idx;
195 ins->flags = 0;
196 ins->coissue = 0;
197 ins->predicate = 0;
198 ins->dst_count = opcode_info->dst_count;
199 ins->src_count = opcode_info->src_count;
200}
201
202static void shader_sm4_read_src_param(void *data, const DWORD **ptr, struct wined3d_shader_src_param *src_param,
203 struct wined3d_shader_src_param *src_rel_addr)
204{
205 DWORD token = *(*ptr)++;
206 enum wined3d_sm4_register_type register_type;
207
208 register_type = (token & WINED3D_SM4_REGISTER_TYPE_MASK) >> WINED3D_SM4_REGISTER_TYPE_SHIFT;
209 if (register_type >= sizeof(register_type_table) / sizeof(*register_type_table))
210 {
211 FIXME("Unhandled register type %#x\n", register_type);
212 src_param->reg.type = WINED3DSPR_TEMP;
213 }
214 else
215 {
216 src_param->reg.type = register_type_table[register_type];
217 }
218
219 if (register_type == WINED3D_SM4_RT_IMMCONST)
220 {
221 enum wined3d_sm4_immconst_type immconst_type =
222 (token & WINED3D_SM4_IMMCONST_TYPE_MASK) >> WINED3D_SM4_IMMCONST_TYPE_SHIFT;
223 src_param->swizzle = WINED3DSP_NOSWIZZLE;
224
225 switch(immconst_type)
226 {
227 case WINED3D_SM4_IMMCONST_FLOAT:
228 src_param->reg.immconst_type = WINED3D_IMMCONST_FLOAT;
229 memcpy(src_param->reg.immconst_data, *ptr, 1 * sizeof(DWORD));
230 *ptr += 1;
231 break;
232
233 case WINED3D_SM4_IMMCONST_FLOAT4:
234 src_param->reg.immconst_type = WINED3D_IMMCONST_FLOAT4;
235 memcpy(src_param->reg.immconst_data, *ptr, 4 * sizeof(DWORD));
236 *ptr += 4;
237 break;
238
239 default:
240 FIXME("Unhandled immediate constant type %#x\n", immconst_type);
241 break;
242 }
243 }
244 else
245 {
246 src_param->reg.idx = *(*ptr)++;
247 src_param->swizzle = (token & WINED3D_SM4_SWIZZLE_MASK) >> WINED3D_SM4_SWIZZLE_SHIFT;
248 }
249
250 src_param->modifiers = 0;
251 src_param->reg.rel_addr = NULL;
252}
253
254static void shader_sm4_read_dst_param(void *data, const DWORD **ptr, struct wined3d_shader_dst_param *dst_param,
255 struct wined3d_shader_src_param *dst_rel_addr)
256{
257 DWORD token = *(*ptr)++;
258 UINT register_idx = *(*ptr)++;
259 enum wined3d_sm4_register_type register_type;
260
261 register_type = (token & WINED3D_SM4_REGISTER_TYPE_MASK) >> WINED3D_SM4_REGISTER_TYPE_SHIFT;
262 if (register_type >= sizeof(register_type_table) / sizeof(*register_type_table))
263 {
264 FIXME("Unhandled register type %#x\n", register_type);
265 dst_param->reg.type = WINED3DSPR_TEMP;
266 }
267 else
268 {
269 dst_param->reg.type = register_type_table[register_type];
270 }
271
272 dst_param->reg.idx = register_idx;
273 dst_param->write_mask = (token & WINED3D_SM4_WRITEMASK_MASK) >> WINED3D_SM4_WRITEMASK_SHIFT;
274 dst_param->modifiers = 0;
275 dst_param->shift = 0;
276 dst_param->reg.rel_addr = NULL;
277}
278
279static void shader_sm4_read_semantic(const DWORD **ptr, struct wined3d_shader_semantic *semantic)
280{
281 FIXME("ptr %p, semantic %p stub!\n", ptr, semantic);
282}
283
284static void shader_sm4_read_comment(const DWORD **ptr, const char **comment)
285{
286 FIXME("ptr %p, comment %p stub!\n", ptr, comment);
287 *comment = NULL;
288}
289
290static BOOL shader_sm4_is_end(void *data, const DWORD **ptr)
291{
292 struct wined3d_sm4_data *priv = data;
293 return *ptr == priv->end;
294}
295
296const struct wined3d_shader_frontend sm4_shader_frontend =
297{
298 shader_sm4_init,
299 shader_sm4_free,
300 shader_sm4_read_header,
301 shader_sm4_read_opcode,
302 shader_sm4_read_src_param,
303 shader_sm4_read_dst_param,
304 shader_sm4_read_semantic,
305 shader_sm4_read_comment,
306 shader_sm4_is_end,
307};
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette