wined3d: Move program_dump_decl_usage into baseshader.
[wine.git] / dlls / wined3d / baseshader.c
blobb06533611438f8a63caff2bab80ee9e222c074d7
1 /*
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
23 #include "config.h"
24 #include <string.h>
25 #include <stdio.h>
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);
39 int shader_addline(
40 SHADER_BUFFER* buffer,
41 const char *format, ...) {
43 char* base = buffer->buffer + buffer->bsize;
44 int rc;
46 va_list args;
47 va_start(args, format);
48 rc = vsnprintf(base, SHADER_PGMSIZE - 1 - buffer->bsize, format, args);
49 va_end(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;
57 return -1;
60 buffer->bsize += rc;
61 buffer->lineNo++;
62 TRACE("GL HW (%u, %u) : %s", buffer->lineNo, buffer->bsize, base);
63 return 0;
66 const SHADER_OPCODE* shader_get_opcode(
67 IWineD3DBaseShader *iface, const DWORD code) {
69 IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl*) iface;
71 DWORD i = 0;
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];
83 ++i;
85 FIXME("Unsupported opcode %lx(%ld) masked %lx version %ld\n",
86 code, code, code & D3DSI_OPCODE_MASK, version);
87 return NULL;
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,
99 CONST DWORD* pToken,
100 DWORD* tempsUsed,
101 DWORD* texUsed) {
103 if (pToken == NULL)
104 return;
106 *tempsUsed = 0;
107 *texUsed = 0;
109 while (D3DVS_END() != *pToken) {
110 CONST SHADER_OPCODE* curOpcode;
112 /* Skip version */
113 if (shader_is_version_token(*pToken)) {
114 ++pToken;
115 continue;
117 /* Skip comments */
118 } else if (shader_is_comment_token(*pToken)) {
119 DWORD comment_len = (*pToken & D3DSI_COMMENTSIZE_MASK) >> D3DSI_COMMENTSIZE_SHIFT;
120 ++pToken;
121 pToken += comment_len;
122 continue;
125 /* Fetch opcode */
126 curOpcode = shader_get_opcode(iface, *pToken);
127 ++pToken;
129 /* Unhandled opcode, and its parameters */
130 if (NULL == curOpcode) {
131 while (*pToken & 0x80000000)
132 ++pToken;
133 continue;
135 /* Skip declarations (for now) */
136 } else if (D3DSIO_DCL == curOpcode->opcode) {
137 pToken += curOpcode->num_params;
138 continue;
140 /* Skip definitions (for now) */
141 } else if (D3DSIO_DEF == curOpcode->opcode) {
142 pToken += curOpcode->num_params;
143 continue;
145 /* Set texture registers, and temporary registers */
146 } else {
147 int i;
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);
156 ++pToken;
162 void shader_program_dump_decl_usage(
163 DWORD decl,
164 DWORD param) {
166 DWORD regtype = shader_get_regtype(param);
167 TRACE("dcl_");
169 if (regtype == D3DSPR_SAMPLER) {
170 DWORD ttype = decl & D3DSP_TEXTURETYPE_MASK;
172 switch (ttype) {
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);
179 } else {
181 DWORD usage = decl & D3DSP_DCL_USAGE_MASK;
182 DWORD idx = (decl & D3DSP_DCL_USAGEINDEX_MASK) >> D3DSP_DCL_USAGEINDEX_SHIFT;
184 switch(usage) {
185 case D3DDECLUSAGE_POSITION:
186 TRACE("%s%ld", "position", idx);
187 break;
188 case D3DDECLUSAGE_BLENDINDICES:
189 TRACE("%s", "blend");
190 break;
191 case D3DDECLUSAGE_BLENDWEIGHT:
192 TRACE("%s", "weight");
193 break;
194 case D3DDECLUSAGE_NORMAL:
195 TRACE("%s%ld", "normal", idx);
196 break;
197 case D3DDECLUSAGE_PSIZE:
198 TRACE("%s", "psize");
199 break;
200 case D3DDECLUSAGE_COLOR:
201 if(idx == 0) {
202 TRACE("%s", "color");
203 } else {
204 TRACE("%s%ld", "specular", (idx - 1));
206 break;
207 case D3DDECLUSAGE_TEXCOORD:
208 TRACE("%s%ld", "texture", idx);
209 break;
210 case D3DDECLUSAGE_TANGENT:
211 TRACE("%s", "tangent");
212 break;
213 case D3DDECLUSAGE_BINORMAL:
214 TRACE("%s", "binormal");
215 break;
216 case D3DDECLUSAGE_TESSFACTOR:
217 TRACE("%s", "tessfactor");
218 break;
219 case D3DDECLUSAGE_POSITIONT:
220 TRACE("%s%ld", "positionT", idx);
221 break;
222 case D3DDECLUSAGE_FOG:
223 TRACE("%s", "fog");
224 break;
225 case D3DDECLUSAGE_DEPTH:
226 TRACE("%s", "depth");
227 break;
228 case D3DDECLUSAGE_SAMPLE:
229 TRACE("%s", "sample");
230 break;
231 default:
232 FIXME("unknown_semantics(%08lx)", usage);
237 /* TODO: Move other shared code here */