2 * shaders implementation
4 * Copyright 2002-2003 Jason Edmeades
5 * Copyright 2002-2003 Raphael Junqueira
6 * Copyright 2005 Oliver Stieber
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #include "wined3d_private.h"
28 WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
30 inline static BOOL shader_is_version_token(DWORD token) {
31 return 0xFFFF0000 == (token & 0xFFFF0000) ||
32 0xFFFE0000 == (token & 0xFFFF0000);
35 inline static BOOL shader_is_comment_token(DWORD token) {
36 return D3DSIO_COMMENT == (token & D3DSI_OPCODE_MASK);
40 SHADER_BUFFER* buffer,
41 const char *format, ...) {
43 char* base = buffer->buffer + buffer->bsize;
47 va_start(args, format);
48 rc = vsnprintf(base, SHADER_PGMSIZE - 1 - buffer->bsize, format, args);
51 if (rc < 0 || /* C89 */
52 rc > SHADER_PGMSIZE - 1 - buffer->bsize) { /* C99 */
54 ERR("The buffer allocated for the shader program string "
55 "is too small at %d bytes.\n", SHADER_PGMSIZE);
56 buffer->bsize = SHADER_PGMSIZE - 1;
62 TRACE("GL HW (%u, %u) : %s", buffer->lineNo, buffer->bsize, base);
66 const SHADER_OPCODE* shader_get_opcode(
67 IWineD3DBaseShader *iface, const DWORD code) {
69 IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl*) iface;
72 DWORD version = This->baseShader.version;
73 DWORD hex_version = This->baseShader.hex_version;
74 const SHADER_OPCODE *shader_ins = This->baseShader.shader_ins;
76 /** TODO: use dichotomic search */
77 while (NULL != shader_ins[i].name) {
78 if (((code & D3DSI_OPCODE_MASK) == shader_ins[i].opcode) &&
79 (((hex_version >= shader_ins[i].min_version) && (hex_version <= shader_ins[i].max_version)) ||
80 ((shader_ins[i].min_version == 0) && (shader_ins[i].max_version == 0)))) {
81 return &shader_ins[i];
85 FIXME("Unsupported opcode %lx(%ld) masked %lx version %ld\n",
86 code, code, code & D3DSI_OPCODE_MASK, version);
90 /* Note: For vertex shaders,
91 * texUsed = addrUsed, and
92 * D3DSPR_TEXTURE = D3DSPR_ADDR.
94 * Also note that this does not count the loop register
95 * as an address register. */
97 void shader_get_registers_used(
98 IWineD3DBaseShader *iface,
109 while (D3DVS_END() != *pToken) {
110 CONST SHADER_OPCODE* curOpcode;
113 if (shader_is_version_token(*pToken)) {
118 } else if (shader_is_comment_token(*pToken)) {
119 DWORD comment_len = (*pToken & D3DSI_COMMENTSIZE_MASK) >> D3DSI_COMMENTSIZE_SHIFT;
121 pToken += comment_len;
126 curOpcode = shader_get_opcode(iface, *pToken);
129 /* Unhandled opcode, and its parameters */
130 if (NULL == curOpcode) {
131 while (*pToken & 0x80000000)
135 /* Skip declarations (for now) */
136 } else if (D3DSIO_DCL == curOpcode->opcode) {
137 pToken += curOpcode->num_params;
140 /* Skip definitions (for now) */
141 } else if (D3DSIO_DEF == curOpcode->opcode) {
142 pToken += curOpcode->num_params;
145 /* Set texture registers, and temporary registers */
149 for (i = 0; i < curOpcode->num_params; ++i) {
150 DWORD regtype = (((*pToken) & D3DSP_REGTYPE_MASK) >> D3DSP_REGTYPE_SHIFT);
151 DWORD reg = (*pToken) & D3DSP_REGNUM_MASK;
152 if (D3DSPR_TEXTURE == regtype)
153 *texUsed |= (1 << reg);
154 if (D3DSPR_TEMP == regtype)
155 *tempsUsed |= (1 << reg);
162 void shader_program_dump_decl_usage(
166 DWORD regtype = shader_get_regtype(param);
169 if (regtype == D3DSPR_SAMPLER) {
170 DWORD ttype = decl & D3DSP_TEXTURETYPE_MASK;
173 case D3DSTT_2D: TRACE("2d"); break;
174 case D3DSTT_CUBE: TRACE("cube"); break;
175 case D3DSTT_VOLUME: TRACE("volume"); break;
176 default: TRACE("unknown_ttype(%08lx)", ttype);
181 DWORD usage = decl & D3DSP_DCL_USAGE_MASK;
182 DWORD idx = (decl & D3DSP_DCL_USAGEINDEX_MASK) >> D3DSP_DCL_USAGEINDEX_SHIFT;
185 case D3DDECLUSAGE_POSITION:
186 TRACE("%s%ld", "position", idx);
188 case D3DDECLUSAGE_BLENDINDICES:
189 TRACE("%s", "blend");
191 case D3DDECLUSAGE_BLENDWEIGHT:
192 TRACE("%s", "weight");
194 case D3DDECLUSAGE_NORMAL:
195 TRACE("%s%ld", "normal", idx);
197 case D3DDECLUSAGE_PSIZE:
198 TRACE("%s", "psize");
200 case D3DDECLUSAGE_COLOR:
202 TRACE("%s", "color");
204 TRACE("%s%ld", "specular", (idx - 1));
207 case D3DDECLUSAGE_TEXCOORD:
208 TRACE("%s%ld", "texture", idx);
210 case D3DDECLUSAGE_TANGENT:
211 TRACE("%s", "tangent");
213 case D3DDECLUSAGE_BINORMAL:
214 TRACE("%s", "binormal");
216 case D3DDECLUSAGE_TESSFACTOR:
217 TRACE("%s", "tessfactor");
219 case D3DDECLUSAGE_POSITIONT:
220 TRACE("%s%ld", "positionT", idx);
222 case D3DDECLUSAGE_FOG:
225 case D3DDECLUSAGE_DEPTH:
226 TRACE("%s", "depth");
228 case D3DDECLUSAGE_SAMPLE:
229 TRACE("%s", "sample");
232 FIXME("unknown_semantics(%08lx)", usage);
237 /* TODO: Move other shared code here */