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 */