2 * Direct3D shader assembler
4 * Copyright 2008 Stefan Dösinger
5 * Copyright 2009 Matteo Bruni
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #include "wine/port.h"
25 #include "wine/debug.h"
27 #include "d3dcompiler_private.h"
31 WINE_DEFAULT_DEBUG_CHANNEL
(asmshader
);
33 struct asm_parser asm_ctx
;
35 /* Error reporting function */
36 void asmparser_message
(struct asm_parser
*ctx
, const char *fmt
, ...
) {
41 if
(ctx
->messagecapacity
== 0) {
42 ctx
->messages
= asm_alloc
(MESSAGEBUFFER_INITIAL_SIZE
);
43 if
(ctx
->messages
== NULL
) {
44 ERR
("Error allocating memory for parser messages\n");
47 ctx
->messagecapacity
= MESSAGEBUFFER_INITIAL_SIZE
;
52 rc
= vsnprintf
(ctx
->messages
+ ctx
->messagesize
,
53 ctx
->messagecapacity
- ctx
->messagesize
, fmt
, args
);
56 if
(rc
< 0 ||
/* C89 */
57 rc
>= ctx
->messagecapacity
- ctx
->messagesize
) { /* C99 */
58 /* Resize the buffer */
59 newsize
= ctx
->messagecapacity
* 2;
60 newbuffer
= asm_realloc
(ctx
->messages
, newsize
);
61 if
(newbuffer
== NULL
){
62 ERR
("Error reallocating memory for parser messages\n");
65 ctx
->messages
= newbuffer
;
66 ctx
->messagecapacity
= newsize
;
68 ctx
->messagesize
+= rc
;
74 static void asmshader_error
(char const *s
) {
75 asmparser_message
(&asm_ctx
, "Line %u: Error \"%s\" from bison\n", asm_ctx.line_no
, s
);
76 set_parse_status
(&asm_ctx
, PARSE_ERR
);
79 static void set_rel_reg
(struct shader_reg
*reg
, struct rel_reg
*rel
) {
80 /* We can have an additional offset without true relative addressing
82 reg
->regnum
+= rel
->additional_offset
;
83 if
(!rel
->has_rel_reg
) {
86 reg
->rel_reg
= asm_alloc
(sizeof
(*reg
->rel_reg
));
90 reg
->rel_reg
->type
= rel
->type
;
91 reg
->rel_reg
->u.swizzle
= rel
->swizzle
;
92 reg
->rel_reg
->regnum
= rel
->rel_regnum
;
96 /* Needed lexer functions declarations */
97 int asmshader_lex
(void);
109 struct shader_reg reg
;
127 BWRITER_COMPARISON_TYPE comptype
;
132 BWRITERSAMPLER_TEXTURE_TYPE samplertype
;
133 struct rel_reg rel_reg
;
134 struct src_regs sregs
;
137 /* Common instructions between vertex and pixel shaders */
190 /* Vertex shader only instructions */
194 /* Pixel shader only instructions */
198 %token INSTR_TEXCOORD
205 %token INSTR_TEXREG2AR
206 %token INSTR_TEXREG2GB
207 %token INSTR_TEXREG2RGB
208 %token INSTR_TEXM3x2PAD
209 %token INSTR_TEXM3x2TEX
210 %token INSTR_TEXM3x3PAD
211 %token INSTR_TEXM3x3SPEC
212 %token INSTR_TEXM3x3VSPEC
213 %token INSTR_TEXM3x3TEX
214 %token INSTR_TEXDP3TEX
215 %token INSTR_TEXM3x2DEPTH
218 %token INSTR_TEXDEPTH
228 %token
<regnum
> REG_TEMP
229 %token
<regnum
> REG_OUTPUT
230 %token
<regnum
> REG_INPUT
231 %token
<regnum
> REG_CONSTFLOAT
232 %token
<regnum
> REG_CONSTINT
233 %token
<regnum
> REG_CONSTBOOL
234 %token
<regnum
> REG_TEXTURE
235 %token
<regnum
> REG_SAMPLER
236 %token
<regnum
> REG_TEXCRDOUT
240 %token
<regnum
> REG_VERTEXCOLOR
241 %token
<regnum
> REG_FRAGCOLOR
248 %token
<regnum
> REG_LABEL
266 /* Output modifiers */
285 /* Source register modifiers */
287 %token SMOD_SCALEBIAS
297 %token SAMPTYPE_VOLUME
299 /* Usage declaration tokens */
300 %token
<regnum
> USAGE_POSITION
301 %token
<regnum
> USAGE_BLENDWEIGHT
302 %token
<regnum
> USAGE_BLENDINDICES
303 %token
<regnum
> USAGE_NORMAL
304 %token
<regnum
> USAGE_PSIZE
305 %token
<regnum
> USAGE_TEXCOORD
306 %token
<regnum
> USAGE_TANGENT
307 %token
<regnum
> USAGE_BINORMAL
308 %token
<regnum
> USAGE_TESSFACTOR
309 %token
<regnum
> USAGE_POSITIONT
310 %token
<regnum
> USAGE_COLOR
311 %token
<regnum
> USAGE_FOG
312 %token
<regnum
> USAGE_DEPTH
313 %token
<regnum
> USAGE_SAMPLE
316 %token
<component
> COMPONENT
317 %token
<immval
> IMMVAL
318 %token
<immbool
> IMMBOOL
320 %type
<reg
> dreg_name
322 %type
<reg
> sreg_name
323 %type
<reg
> relreg_name
326 %type
<writemask
> writemask
327 %type
<wm_components
> wm_components
328 %type
<swizzle
> swizzle
329 %type
<sw_components
> sw_components
330 %type
<modshift
> omods
331 %type
<modshift
> omodifier
332 %type
<comptype
> comp
333 %type
<declaration
> dclusage
334 %type
<reg
> dcl_inputreg
335 %type
<samplertype
> sampdcl
336 %type
<rel_reg
> rel_reg
337 %type
<reg
> predicate
338 %type
<immval
> immsum
343 shader: version_marker instructions
345 asm_ctx.funcs
->end
(&asm_ctx
);
348 version_marker: VER_VS10
350 TRACE
("Vertex shader 1.0\n");
351 create_vs10_parser
(&asm_ctx
);
355 TRACE
("Vertex shader 1.1\n");
356 create_vs11_parser
(&asm_ctx
);
360 TRACE
("Vertex shader 2.0\n");
361 create_vs20_parser
(&asm_ctx
);
365 TRACE
("Vertex shader 2.x\n");
366 create_vs2x_parser
(&asm_ctx
);
370 TRACE
("Vertex shader 3.0\n");
371 create_vs30_parser
(&asm_ctx
);
375 TRACE
("Pixel shader 1.0\n");
376 create_ps10_parser
(&asm_ctx
);
380 TRACE
("Pixel shader 1.1\n");
381 create_ps11_parser
(&asm_ctx
);
385 TRACE
("Pixel shader 1.2\n");
386 create_ps12_parser
(&asm_ctx
);
390 TRACE
("Pixel shader 1.3\n");
391 create_ps13_parser
(&asm_ctx
);
395 TRACE
("Pixel shader 1.4\n");
396 create_ps14_parser
(&asm_ctx
);
400 TRACE
("Pixel shader 2.0\n");
401 create_ps20_parser
(&asm_ctx
);
405 TRACE
("Pixel shader 2.x\n");
406 create_ps2x_parser
(&asm_ctx
);
410 TRACE
("Pixel shader 3.0\n");
411 create_ps30_parser
(&asm_ctx
);
414 instructions: /* empty */
415 | instructions complexinstr
420 complexinstr: instruction
424 | predicate instruction
426 TRACE
("predicate\n");
427 asm_ctx.funcs
->predicate
(&asm_ctx
, &$1);
432 asm_ctx.funcs
->coissue
(&asm_ctx
);
435 instruction: INSTR_ADD omods dreg
',' sregs
438 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_ADD
, $2.mod
, $2.shift
, 0, &$3, &$5, 2);
443 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_NOP
, 0, 0, 0, 0, 0, 0);
445 | INSTR_MOV omods dreg
',' sregs
448 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_MOV
, $2.mod
, $2.shift
, 0, &$3, &$5, 1);
450 | INSTR_SUB omods dreg
',' sregs
453 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_SUB
, $2.mod
, $2.shift
, 0, &$3, &$5, 2);
455 | INSTR_MAD omods dreg
',' sregs
458 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_MAD
, $2.mod
, $2.shift
, 0, &$3, &$5, 3);
460 | INSTR_MUL omods dreg
',' sregs
463 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_MUL
, $2.mod
, $2.shift
, 0, &$3, &$5, 2);
465 | INSTR_RCP omods dreg
',' sregs
468 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_RCP
, $2.mod
, $2.shift
, 0, &$3, &$5, 1);
470 | INSTR_RSQ omods dreg
',' sregs
473 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_RSQ
, $2.mod
, $2.shift
, 0, &$3, &$5, 1);
475 | INSTR_DP3 omods dreg
',' sregs
478 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_DP3
, $2.mod
, $2.shift
, 0, &$3, &$5, 2);
480 | INSTR_DP4 omods dreg
',' sregs
483 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_DP4
, $2.mod
, $2.shift
, 0, &$3, &$5, 2);
485 | INSTR_MIN omods dreg
',' sregs
488 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_MIN
, $2.mod
, $2.shift
, 0, &$3, &$5, 2);
490 | INSTR_MAX omods dreg
',' sregs
493 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_MAX
, $2.mod
, $2.shift
, 0, &$3, &$5, 2);
495 | INSTR_SLT omods dreg
',' sregs
498 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_SLT
, $2.mod
, $2.shift
, 0, &$3, &$5, 2);
500 | INSTR_SGE omods dreg
',' sregs
503 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_SGE
, $2.mod
, $2.shift
, 0, &$3, &$5, 2);
505 | INSTR_ABS omods dreg
',' sregs
508 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_ABS
, $2.mod
, $2.shift
, 0, &$3, &$5, 1);
510 | INSTR_EXP omods dreg
',' sregs
513 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_EXP
, $2.mod
, $2.shift
, 0, &$3, &$5, 1);
515 | INSTR_LOG omods dreg
',' sregs
518 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_LOG
, $2.mod
, $2.shift
, 0, &$3, &$5, 1);
520 | INSTR_LOGP omods dreg
',' sregs
523 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_LOGP
, $2.mod
, $2.shift
, 0, &$3, &$5, 1);
525 | INSTR_EXPP omods dreg
',' sregs
528 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_EXPP
, $2.mod
, $2.shift
, 0, &$3, &$5, 1);
530 | INSTR_DST omods dreg
',' sregs
533 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_DST
, $2.mod
, $2.shift
, 0, &$3, &$5, 2);
535 | INSTR_LRP omods dreg
',' sregs
538 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_LRP
, $2.mod
, $2.shift
, 0, &$3, &$5, 3);
540 | INSTR_FRC omods dreg
',' sregs
543 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_FRC
, $2.mod
, $2.shift
, 0, &$3, &$5, 1);
545 | INSTR_POW omods dreg
',' sregs
548 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_POW
, $2.mod
, $2.shift
, 0, &$3, &$5, 2);
550 | INSTR_CRS omods dreg
',' sregs
553 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_CRS
, $2.mod
, $2.shift
, 0, &$3, &$5, 2);
555 | INSTR_SGN omods dreg
',' sregs
558 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_SGN
, $2.mod
, $2.shift
, 0, &$3, &$5, 3);
560 | INSTR_NRM omods dreg
',' sregs
563 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_NRM
, $2.mod
, $2.shift
, 0, &$3, &$5, 1);
565 | INSTR_SINCOS omods dreg
',' sregs
568 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_SINCOS
, $2.mod
, $2.shift
, 0, &$3, &$5, 1);
570 | INSTR_M4x4 omods dreg
',' sregs
573 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_M4x4
, $2.mod
, $2.shift
, 0, &$3, &$5, 2);
575 | INSTR_M4x3 omods dreg
',' sregs
578 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_M4x3
, $2.mod
, $2.shift
, 0, &$3, &$5, 2);
580 | INSTR_M3x4 omods dreg
',' sregs
583 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_M3x4
, $2.mod
, $2.shift
, 0, &$3, &$5, 2);
585 | INSTR_M3x3 omods dreg
',' sregs
588 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_M3x3
, $2.mod
, $2.shift
, 0, &$3, &$5, 2);
590 | INSTR_M3x2 omods dreg
',' sregs
593 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_M3x2
, $2.mod
, $2.shift
, 0, &$3, &$5, 2);
595 | INSTR_DCL dclusage REG_OUTPUT
597 struct shader_reg reg
;
598 TRACE
("Output reg declaration\n");
599 ZeroMemory
(®
, sizeof
(reg
));
600 reg.type
= BWRITERSPR_OUTPUT
;
604 reg.u.writemask
= BWRITERSP_WRITEMASK_ALL
;
605 asm_ctx.funcs
->dcl_output
(&asm_ctx
, $2.dclusage
, $2.regnum
, ®
);
607 | INSTR_DCL dclusage REG_OUTPUT writemask
609 struct shader_reg reg
;
610 TRACE
("Output reg declaration\n");
611 ZeroMemory
(®
, sizeof
(reg
));
612 reg.type
= BWRITERSPR_OUTPUT
;
616 reg.u.writemask
= $4;
617 asm_ctx.funcs
->dcl_output
(&asm_ctx
, $2.dclusage
, $2.regnum
, ®
);
619 | INSTR_DCL dclusage omods dcl_inputreg
621 struct shader_reg reg
;
622 TRACE
("Input reg declaration\n");
624 asmparser_message
(&asm_ctx
, "Line %u: Shift modifier not allowed here\n",
626 set_parse_status
(&asm_ctx
, PARSE_ERR
);
628 if
(asm_ctx.shader
->version
== BWRITERPS_VERSION
(2, 0) ||
629 asm_ctx.shader
->version
== BWRITERPS_VERSION
(2, 1)) {
630 asmparser_message
(&asm_ctx
, "Line %u: Declaration not supported in PS 2\n",
632 set_parse_status
(&asm_ctx
, PARSE_ERR
);
634 ZeroMemory
(®
, sizeof
(reg
));
636 reg.regnum
= $4.regnum
;
639 reg.u.writemask
= BWRITERSP_WRITEMASK_ALL
;
640 asm_ctx.funcs
->dcl_input
(&asm_ctx
, $2.dclusage
, $2.regnum
, $3.mod
, ®
);
642 | INSTR_DCL dclusage omods dcl_inputreg writemask
644 struct shader_reg reg
;
645 TRACE
("Input reg declaration\n");
647 asmparser_message
(&asm_ctx
, "Line %u: Shift modifier not allowed here\n",
649 set_parse_status
(&asm_ctx
, PARSE_ERR
);
651 if
(asm_ctx.shader
->version
== BWRITERPS_VERSION
(2, 0) ||
652 asm_ctx.shader
->version
== BWRITERPS_VERSION
(2, 1)) {
653 asmparser_message
(&asm_ctx
, "Line %u: Declaration not supported in PS 2\n",
655 set_parse_status
(&asm_ctx
, PARSE_ERR
);
657 ZeroMemory
(®
, sizeof
(reg
));
659 reg.regnum
= $4.regnum
;
662 reg.u.writemask
= $5;
663 asm_ctx.funcs
->dcl_input
(&asm_ctx
, $2.dclusage
, $2.regnum
, $3.mod
, ®
);
665 | INSTR_DCL omods dcl_inputreg
667 struct shader_reg reg
;
668 TRACE
("Input reg declaration\n");
670 asmparser_message
(&asm_ctx
, "Line %u: Shift modifier not allowed here\n",
672 set_parse_status
(&asm_ctx
, PARSE_ERR
);
674 if
(asm_ctx.shader
->type
!= ST_PIXEL
) {
675 asmparser_message
(&asm_ctx
, "Line %u: Declaration needs a semantic\n",
677 set_parse_status
(&asm_ctx
, PARSE_ERR
);
679 ZeroMemory
(®
, sizeof
(reg
));
681 reg.regnum
= $3.regnum
;
684 reg.u.writemask
= BWRITERSP_WRITEMASK_ALL
;
685 asm_ctx.funcs
->dcl_input
(&asm_ctx
, 0, 0, $2.mod
, ®
);
687 | INSTR_DCL omods dcl_inputreg writemask
689 struct shader_reg reg
;
690 TRACE
("Input reg declaration\n");
692 asmparser_message
(&asm_ctx
, "Line %u: Shift modifier not allowed here\n",
694 set_parse_status
(&asm_ctx
, PARSE_ERR
);
696 if
(asm_ctx.shader
->type
!= ST_PIXEL
) {
697 asmparser_message
(&asm_ctx
, "Line %u: Declaration needs a semantic\n",
699 set_parse_status
(&asm_ctx
, PARSE_ERR
);
701 ZeroMemory
(®
, sizeof
(reg
));
703 reg.regnum
= $3.regnum
;
706 reg.u.writemask
= $4;
707 asm_ctx.funcs
->dcl_input
(&asm_ctx
, 0, 0, $2.mod
, ®
);
709 | INSTR_DCL sampdcl omods REG_SAMPLER
711 TRACE
("Sampler declared\n");
713 asmparser_message
(&asm_ctx
, "Line %u: Shift modifier not allowed here\n",
715 set_parse_status
(&asm_ctx
, PARSE_ERR
);
717 asm_ctx.funcs
->dcl_sampler
(&asm_ctx
, $2, $3.mod
, $4, asm_ctx.line_no
);
719 | INSTR_DCL omods REG_SAMPLER
721 TRACE
("Sampler declared\n");
723 asmparser_message
(&asm_ctx
, "Line %u: Shift modifier not allowed here\n",
725 set_parse_status
(&asm_ctx
, PARSE_ERR
);
727 if
(asm_ctx.shader
->type
!= ST_PIXEL
) {
728 asmparser_message
(&asm_ctx
, "Line %u: Declaration needs a sampler type\n",
730 set_parse_status
(&asm_ctx
, PARSE_ERR
);
732 asm_ctx.funcs
->dcl_sampler
(&asm_ctx
, BWRITERSTT_UNKNOWN
, $2.mod
, $3, asm_ctx.line_no
);
734 | INSTR_DCL sampdcl omods dcl_inputreg
736 TRACE
("Error rule: sampler decl of input reg\n");
737 asmparser_message
(&asm_ctx
, "Line %u: Sampler declarations of input regs is not valid\n",
739 set_parse_status
(&asm_ctx
, PARSE_WARN
);
741 | INSTR_DCL sampdcl omods REG_OUTPUT
743 TRACE
("Error rule: sampler decl of output reg\n");
744 asmparser_message
(&asm_ctx
, "Line %u: Sampler declarations of output regs is not valid\n",
746 set_parse_status
(&asm_ctx
, PARSE_WARN
);
748 | INSTR_DEF REG_CONSTFLOAT
',' IMMVAL
',' IMMVAL
',' IMMVAL
',' IMMVAL
750 asm_ctx.funcs
->constF
(&asm_ctx
, $2, $4.val
, $6.val
, $8.val
, $10.val
);
752 | INSTR_DEFI REG_CONSTINT
',' IMMVAL
',' IMMVAL
',' IMMVAL
',' IMMVAL
754 asm_ctx.funcs
->constI
(&asm_ctx
, $2, $4.val
, $6.val
, $8.val
, $10.val
);
756 | INSTR_DEFB REG_CONSTBOOL
',' IMMBOOL
758 asm_ctx.funcs
->constB
(&asm_ctx
, $2, $4);
763 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_REP
, 0, 0, 0, 0, &$2, 1);
768 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_ENDREP
, 0, 0, 0, 0, 0, 0);
773 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_IF
, 0, 0, 0, 0, &$2, 1);
775 | INSTR_IF comp sregs
778 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_IFC
, 0, 0, $2, 0, &$3, 2);
783 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_ELSE
, 0, 0, 0, 0, 0, 0);
788 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_ENDIF
, 0, 0, 0, 0, 0, 0);
793 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_BREAK
, 0, 0, 0, 0, 0, 0);
795 | INSTR_BREAK comp sregs
798 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_BREAKC
, 0, 0, $2, 0, &$3, 2);
803 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_BREAKP
, 0, 0, 0, 0, &$2, 1);
808 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_CALL
, 0, 0, 0, 0, &$2, 1);
813 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_CALLNZ
, 0, 0, 0, 0, &$2, 2);
818 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_LOOP
, 0, 0, 0, 0, &$2, 2);
823 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_RET
, 0, 0, 0, 0, 0, 0);
828 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_ENDLOOP
, 0, 0, 0, 0, 0, 0);
833 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_LABEL
, 0, 0, 0, 0, &$2, 1);
835 | INSTR_SETP comp dreg
',' sregs
838 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_SETP
, 0, 0, $2, &$3, &$5, 2);
840 | INSTR_TEXLDL omods dreg
',' sregs
843 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_TEXLDL
, $2.mod
, $2.shift
, 0, &$3, &$5, 2);
845 | INSTR_LIT omods dreg
',' sregs
848 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_LIT
, $2.mod
, $2.shift
, 0, &$3, &$5, 1);
850 | INSTR_MOVA omods dreg
',' sregs
853 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_MOVA
, $2.mod
, $2.shift
, 0, &$3, &$5, 1);
855 | INSTR_CND omods dreg
',' sregs
858 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_CND
, $2.mod
, $2.shift
, 0, &$3, &$5, 3);
860 | INSTR_CMP omods dreg
',' sregs
863 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_CMP
, $2.mod
, $2.shift
, 0, &$3, &$5, 3);
865 | INSTR_DP2ADD omods dreg
',' sregs
868 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_DP2ADD
, $2.mod
, $2.shift
, 0, &$3, &$5, 3);
870 | INSTR_TEXCOORD omods dreg
873 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_TEXCOORD
, $2.mod
, $2.shift
, 0, &$3, 0, 0);
875 | INSTR_TEXCRD omods dreg
',' sregs
878 /* texcoord and texcrd share the same opcode */
879 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_TEXCOORD
, $2.mod
, $2.shift
, 0, &$3, &$5, 1);
884 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_TEXKILL
, 0, 0, 0, &$2, 0, 0);
886 | INSTR_TEX omods dreg
889 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_TEX
, $2.mod
, $2.shift
, 0, &$3, 0, 0);
891 | INSTR_TEXDEPTH omods dreg
894 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_TEXDEPTH
, $2.mod
, $2.shift
, 0, &$3, 0, 0);
896 | INSTR_TEXLD omods dreg
',' sregs
899 /* There is more than one acceptable syntax for texld:
900 with 1 sreg (PS 1.4) or
901 with 2 sregs (PS 2.0+)
902 Moreover, texld shares the same opcode as the tex instruction,
903 so there are a total of 3 valid syntaxes
904 These variations are handled in asmparser.c */
905 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_TEX
, $2.mod
, $2.shift
, 0, &$3, &$5, 2);
907 | INSTR_TEXLDP omods dreg
',' sregs
910 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_TEXLDP
, $2.mod
, $2.shift
, 0, &$3, &$5, 2);
912 | INSTR_TEXLDB omods dreg
',' sregs
915 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_TEXLDB
, $2.mod
, $2.shift
, 0, &$3, &$5, 2);
917 | INSTR_TEXBEM omods dreg
',' sregs
920 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_TEXBEM
, $2.mod
, $2.shift
, 0, &$3, &$5, 1);
922 | INSTR_TEXBEML omods dreg
',' sregs
925 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_TEXBEML
, $2.mod
, $2.shift
, 0, &$3, &$5, 1);
927 | INSTR_TEXREG2AR omods dreg
',' sregs
929 TRACE
("TEXREG2AR\n");
930 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_TEXREG2AR
, $2.mod
, $2.shift
, 0, &$3, &$5, 1);
932 | INSTR_TEXREG2GB omods dreg
',' sregs
934 TRACE
("TEXREG2GB\n");
935 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_TEXREG2GB
, $2.mod
, $2.shift
, 0, &$3, &$5, 1);
937 | INSTR_TEXREG2RGB omods dreg
',' sregs
939 TRACE
("TEXREG2RGB\n");
940 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_TEXREG2RGB
, $2.mod
, $2.shift
, 0, &$3, &$5, 1);
942 | INSTR_TEXM3x2PAD omods dreg
',' sregs
944 TRACE
("TEXM3x2PAD\n");
945 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_TEXM3x2PAD
, $2.mod
, $2.shift
, 0, &$3, &$5, 1);
947 | INSTR_TEXM3x3PAD omods dreg
',' sregs
949 TRACE
("INSTR_TEXM3x3PAD\n");
950 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_TEXM3x3PAD
, $2.mod
, $2.shift
, 0, &$3, &$5, 1);
952 | INSTR_TEXM3x3SPEC omods dreg
',' sregs
954 TRACE
("TEXM3x3SPEC\n");
955 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_TEXM3x3SPEC
, $2.mod
, $2.shift
, 0, &$3, &$5, 2);
957 | INSTR_TEXM3x3VSPEC omods dreg
',' sregs
959 TRACE
("TEXM3x3VSPEC\n");
960 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_TEXM3x3VSPEC
, $2.mod
, $2.shift
, 0, &$3, &$5, 1);
962 | INSTR_TEXM3x3TEX omods dreg
',' sregs
964 TRACE
("TEXM3x3TEX\n");
965 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_TEXM3x3TEX
, $2.mod
, $2.shift
, 0, &$3, &$5, 1);
967 | INSTR_TEXDP3TEX omods dreg
',' sregs
969 TRACE
("TEXDP3TEX\n");
970 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_TEXDP3TEX
, $2.mod
, $2.shift
, 0, &$3, &$5, 1);
972 | INSTR_TEXM3x2DEPTH omods dreg
',' sregs
974 TRACE
("TEXM3x2DEPTH\n");
975 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_TEXM3x2DEPTH
, $2.mod
, $2.shift
, 0, &$3, &$5, 1);
977 | INSTR_TEXM3x2TEX omods dreg
',' sregs
979 TRACE
("TEXM3x2TEX\n");
980 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_TEXM3x2TEX
, $2.mod
, $2.shift
, 0, &$3, &$5, 1);
982 | INSTR_TEXDP3 omods dreg
',' sregs
985 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_TEXDP3
, $2.mod
, $2.shift
, 0, &$3, &$5, 1);
987 | INSTR_TEXM3x3 omods dreg
',' sregs
990 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_TEXM3x3
, $2.mod
, $2.shift
, 0, &$3, &$5, 1);
992 | INSTR_BEM omods dreg
',' sregs
995 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_BEM
, $2.mod
, $2.shift
, 0, &$3, &$5, 2);
997 | INSTR_DSX omods dreg
',' sregs
1000 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_DSX
, $2.mod
, $2.shift
, 0, &$3, &$5, 1);
1002 | INSTR_DSY omods dreg
',' sregs
1005 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_DSY
, $2.mod
, $2.shift
, 0, &$3, &$5, 1);
1007 | INSTR_TEXLDD omods dreg
',' sregs
1010 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_TEXLDD
, $2.mod
, $2.shift
, 0, &$3, &$5, 4);
1015 asm_ctx.funcs
->instr
(&asm_ctx
, BWRITERSIO_PHASE
, 0, 0, 0, 0, 0, 0);
1019 dreg: dreg_name rel_reg
1021 $$.regnum
= $1.regnum
;
1023 $$.u.writemask
= BWRITERSP_WRITEMASK_ALL
;
1024 $$.srcmod
= BWRITERSPSM_NONE
;
1025 set_rel_reg
(&$$
, &$2);
1027 | dreg_name writemask
1029 $$.regnum
= $1.regnum
;
1031 $$.u.writemask
= $2;
1032 $$.srcmod
= BWRITERSPSM_NONE
;
1038 $$.regnum
= $1; $$.type
= BWRITERSPR_TEMP
;
1042 $$.regnum
= $1; $$.type
= BWRITERSPR_OUTPUT
;
1046 $$.regnum
= $1; $$.type
= BWRITERSPR_INPUT
;
1050 asmparser_message
(&asm_ctx
, "Line %u: Register c%u is not a valid destination register\n",
1051 asm_ctx.line_no
, $1);
1052 set_parse_status
(&asm_ctx
, PARSE_WARN
);
1056 asmparser_message
(&asm_ctx
, "Line %u: Register i%u is not a valid destination register\n",
1057 asm_ctx.line_no
, $1);
1058 set_parse_status
(&asm_ctx
, PARSE_WARN
);
1062 asmparser_message
(&asm_ctx
, "Line %u: Register b%u is not a valid destination register\n",
1063 asm_ctx.line_no
, $1);
1064 set_parse_status
(&asm_ctx
, PARSE_WARN
);
1068 $$.regnum
= $1; $$.type
= BWRITERSPR_TEXTURE
;
1072 $$.regnum
= $1; $$.type
= BWRITERSPR_TEXCRDOUT
;
1076 asmparser_message
(&asm_ctx
, "Line %u: Register s%u is not a valid destination register\n",
1077 asm_ctx.line_no
, $1);
1078 set_parse_status
(&asm_ctx
, PARSE_WARN
);
1082 $$.regnum
= BWRITERSRO_POSITION
; $$.type
= BWRITERSPR_RASTOUT
;
1086 $$.regnum
= BWRITERSRO_POINT_SIZE
; $$.type
= BWRITERSPR_RASTOUT
;
1090 $$.regnum
= BWRITERSRO_FOG
; $$.type
= BWRITERSPR_RASTOUT
;
1094 $$.regnum
= $1; $$.type
= BWRITERSPR_ATTROUT
;
1098 $$.regnum
= $1; $$.type
= BWRITERSPR_COLOROUT
;
1102 $$.regnum
= 0; $$.type
= BWRITERSPR_DEPTHOUT
;
1106 $$.regnum
= 0; $$.type
= BWRITERSPR_PREDICATE
;
1110 asmparser_message
(&asm_ctx
, "Line %u: Register vPos is not a valid destination register\n",
1112 set_parse_status
(&asm_ctx
, PARSE_WARN
);
1116 asmparser_message
(&asm_ctx
, "Line %u: Register vFace is not a valid destination register\n",
1118 set_parse_status
(&asm_ctx
, PARSE_WARN
);
1122 /* index 0 is hardcoded for the addr register */
1123 $$.regnum
= 0; $$.type
= BWRITERSPR_ADDR
;
1127 asmparser_message
(&asm_ctx
, "Line %u: Register aL is not a valid destination register\n",
1129 set_parse_status
(&asm_ctx
, PARSE_WARN
);
1132 writemask: '.' wm_components
1134 if
($2.writemask
== SWIZZLE_ERR
) {
1135 asmparser_message
(&asm_ctx
, "Line %u: Invalid writemask specified\n",
1137 set_parse_status
(&asm_ctx
, PARSE_ERR
);
1138 /* Provide a correct writemask to prevent following complaints */
1139 $$
= BWRITERSP_WRITEMASK_ALL
;
1143 TRACE
("Writemask: %x\n", $$
);
1147 wm_components: COMPONENT
1149 $$.writemask
= 1 << $1;
1153 | wm_components COMPONENT
1155 if
($1.writemask
== SWIZZLE_ERR ||
$1.idx
== 4)
1156 /* Wrong writemask */
1157 $$.writemask
= SWIZZLE_ERR
;
1160 $$.writemask
= SWIZZLE_ERR
;
1162 $$.writemask
= $1.writemask |
(1 << $2);
1163 $$.idx
= $1.idx
+ 1;
1168 swizzle: /* empty */
1170 $$
= BWRITERVS_NOSWIZZLE
;
1171 TRACE
("Default swizzle: %08x\n", $$
);
1175 if
($2.swizzle
== SWIZZLE_ERR
) {
1176 asmparser_message
(&asm_ctx
, "Line %u: Invalid swizzle\n",
1178 set_parse_status
(&asm_ctx
, PARSE_ERR
);
1179 /* Provide a correct swizzle to prevent following complaints */
1180 $$
= BWRITERVS_NOSWIZZLE
;
1185 $$
= $2.swizzle
<< BWRITERVS_SWIZZLE_SHIFT
;
1186 /* Fill the swizzle by extending the last component */
1187 last
= ($2.swizzle
>> 2 * ($2.idx
- 1)) & 0x03;
1188 for
(i
= $2.idx
; i
< 4; i
++){
1189 $$ |
= last
<< (BWRITERVS_SWIZZLE_SHIFT
+ 2 * i
);
1191 TRACE
("Got a swizzle: %08x\n", $$
);
1195 sw_components: COMPONENT
1200 | sw_components COMPONENT
1203 /* Too many sw_components */
1204 $$.swizzle
= SWIZZLE_ERR
;
1208 $$.swizzle
= $1.swizzle |
($2 << 2 * $1.idx
);
1209 $$.idx
= $1.idx
+ 1;
1220 $$.mod
= $1.mod |
$2.mod
;
1221 if
($1.shift
&& $2.shift
) {
1222 asmparser_message
(&asm_ctx
, "Line %u: More than one shift flag\n",
1224 set_parse_status
(&asm_ctx
, PARSE_ERR
);
1225 $$.shift
= $1.shift
;
1227 $$.shift
= $1.shift |
$2.shift
;
1263 $$.mod
= BWRITERSPDM_SATURATE
;
1268 $$.mod
= BWRITERSPDM_PARTIALPRECISION
;
1273 $$.mod
= BWRITERSPDM_MSAMPCENTROID
;
1284 if
($$.count
== MAX_SRC_REGS
){
1285 asmparser_message
(&asm_ctx
, "Line %u: Too many source registers in this instruction\n",
1287 set_parse_status
(&asm_ctx
, PARSE_ERR
);
1290 $$.reg
[$$.count
++] = $3;
1293 sreg: sreg_name rel_reg swizzle
1296 $$.regnum
= $1.regnum
;
1298 $$.srcmod
= BWRITERSPSM_NONE
;
1299 set_rel_reg
(&$$
, &$2);
1301 | sreg_name rel_reg smod swizzle
1304 $$.regnum
= $1.regnum
;
1305 set_rel_reg
(&$$
, &$2);
1309 |
'-' sreg_name rel_reg swizzle
1312 $$.regnum
= $2.regnum
;
1313 $$.srcmod
= BWRITERSPSM_NEG
;
1314 set_rel_reg
(&$$
, &$3);
1317 |
'-' sreg_name rel_reg smod swizzle
1320 $$.regnum
= $2.regnum
;
1321 set_rel_reg
(&$$
, &$3);
1323 case BWRITERSPSM_BIAS
: $$.srcmod
= BWRITERSPSM_BIASNEG
; break
;
1324 case BWRITERSPSM_X2
: $$.srcmod
= BWRITERSPSM_X2NEG
; break
;
1325 case BWRITERSPSM_SIGN
: $$.srcmod
= BWRITERSPSM_SIGNNEG
; break
;
1326 case BWRITERSPSM_ABS
: $$.srcmod
= BWRITERSPSM_ABSNEG
; break
;
1327 case BWRITERSPSM_DZ
:
1328 asmparser_message
(&asm_ctx
, "Line %u: Incompatible source modifiers: NEG and DZ\n",
1330 set_parse_status
(&asm_ctx
, PARSE_ERR
);
1332 case BWRITERSPSM_DW
:
1333 asmparser_message
(&asm_ctx
, "Line %u: Incompatible source modifiers: NEG and DW\n",
1335 set_parse_status
(&asm_ctx
, PARSE_ERR
);
1338 FIXME
("Unhandled combination of NEGATE and %u\n", $4);
1342 | IMMVAL
'-' sreg_name rel_reg swizzle
1344 if
($1.val
!= 1.0 ||
(!$1.integer
)) {
1345 asmparser_message
(&asm_ctx
, "Line %u: Only \"1 - reg\" is valid for D3DSPSM_COMP, "
1346 "%g - reg found\n", asm_ctx.line_no
, $1.val
);
1347 set_parse_status
(&asm_ctx
, PARSE_ERR
);
1349 /* Complement - not compatible with other source modifiers */
1351 $$.regnum
= $3.regnum
;
1352 $$.srcmod
= BWRITERSPSM_COMP
;
1353 set_rel_reg
(&$$
, &$4);
1356 | IMMVAL
'-' sreg_name rel_reg smod swizzle
1358 /* For nicer error reporting */
1359 if
($1.val
!= 1.0 ||
(!$1.integer
)) {
1360 asmparser_message
(&asm_ctx
, "Line %u: Only \"1 - reg\" is valid for D3DSPSM_COMP\n",
1362 set_parse_status
(&asm_ctx
, PARSE_ERR
);
1364 asmparser_message
(&asm_ctx
, "Line %u: Incompatible source modifiers: D3DSPSM_COMP and %s\n",
1366 debug_print_srcmod
($5));
1367 set_parse_status
(&asm_ctx
, PARSE_ERR
);
1370 | SMOD_NOT sreg_name swizzle
1373 $$.regnum
= $2.regnum
;
1375 $$.srcmod
= BWRITERSPSM_NOT
;
1379 rel_reg: /* empty */
1381 $$.has_rel_reg
= FALSE
;
1382 $$.additional_offset
= 0;
1386 $$.has_rel_reg
= FALSE
;
1387 $$.additional_offset
= $2.val
;
1389 |
'[' relreg_name swizzle
']'
1391 $$.has_rel_reg
= TRUE
;
1393 $$.additional_offset
= 0;
1394 $$.rel_regnum
= $2.regnum
;
1397 |
'[' immsum
'+' relreg_name swizzle
']'
1399 $$.has_rel_reg
= TRUE
;
1401 $$.additional_offset
= $2.val
;
1402 $$.rel_regnum
= $4.regnum
;
1405 |
'[' relreg_name swizzle
'+' immsum
']'
1407 $$.has_rel_reg
= TRUE
;
1409 $$.additional_offset
= $5.val
;
1410 $$.rel_regnum
= $2.regnum
;
1413 |
'[' immsum
'+' relreg_name swizzle
'+' immsum
']'
1415 $$.has_rel_reg
= TRUE
;
1417 $$.additional_offset
= $2.val
+ $7.val
;
1418 $$.rel_regnum
= $4.regnum
;
1425 asmparser_message
(&asm_ctx
, "Line %u: Unexpected float %f\n",
1426 asm_ctx.line_no
, $1.val
);
1427 set_parse_status
(&asm_ctx
, PARSE_ERR
);
1434 asmparser_message
(&asm_ctx
, "Line %u: Unexpected float %f\n",
1435 asm_ctx.line_no
, $3.val
);
1436 set_parse_status
(&asm_ctx
, PARSE_ERR
);
1438 $$.val
= $1.val
+ $3.val
;
1443 $$
= BWRITERSPSM_BIAS
;
1447 $$
= BWRITERSPSM_X2
;
1451 $$
= BWRITERSPSM_SIGN
;
1455 $$
= BWRITERSPSM_DZ
;
1459 $$
= BWRITERSPSM_DW
;
1463 $$
= BWRITERSPSM_ABS
;
1466 relreg_name: REG_ADDRESS
1468 $$.regnum
= 0; $$.type
= BWRITERSPR_ADDR
;
1472 $$.regnum
= 0; $$.type
= BWRITERSPR_LOOP
;
1477 $$.regnum
= $1; $$.type
= BWRITERSPR_TEMP
;
1481 asmparser_message
(&asm_ctx
, "Line %u: Register o%u is not a valid source register\n",
1482 asm_ctx.line_no
, $1);
1483 set_parse_status
(&asm_ctx
, PARSE_WARN
);
1487 $$.regnum
= $1; $$.type
= BWRITERSPR_INPUT
;
1491 $$.regnum
= $1; $$.type
= BWRITERSPR_CONST
;
1495 $$.regnum
= $1; $$.type
= BWRITERSPR_CONSTINT
;
1499 $$.regnum
= $1; $$.type
= BWRITERSPR_CONSTBOOL
;
1503 $$.regnum
= $1; $$.type
= BWRITERSPR_TEXTURE
;
1507 asmparser_message
(&asm_ctx
, "Line %u: Register oT%u is not a valid source register\n",
1508 asm_ctx.line_no
, $1);
1509 set_parse_status
(&asm_ctx
, PARSE_WARN
);
1513 $$.regnum
= $1; $$.type
= BWRITERSPR_SAMPLER
;
1517 asmparser_message
(&asm_ctx
, "Line %u: Register oPos is not a valid source register\n",
1519 set_parse_status
(&asm_ctx
, PARSE_WARN
);
1523 asmparser_message
(&asm_ctx
, "Line %u: Register oFog is not a valid source register\n",
1525 set_parse_status
(&asm_ctx
, PARSE_WARN
);
1529 asmparser_message
(&asm_ctx
, "Line %u: Register oD%u is not a valid source register\n",
1530 asm_ctx.line_no
, $1);
1531 set_parse_status
(&asm_ctx
, PARSE_WARN
);
1535 asmparser_message
(&asm_ctx
, "Line %u: Register oC%u is not a valid source register\n",
1536 asm_ctx.line_no
, $1);
1537 set_parse_status
(&asm_ctx
, PARSE_WARN
);
1541 asmparser_message
(&asm_ctx
, "Line %u: Register oDepth is not a valid source register\n",
1543 set_parse_status
(&asm_ctx
, PARSE_WARN
);
1547 $$.regnum
= 0; $$.type
= BWRITERSPR_PREDICATE
;
1551 $$.regnum
= 0; $$.type
= BWRITERSPR_MISCTYPE
;
1555 $$.regnum
= 1; $$.type
= BWRITERSPR_MISCTYPE
;
1559 $$.regnum
= 0; $$.type
= BWRITERSPR_ADDR
;
1563 $$.regnum
= 0; $$.type
= BWRITERSPR_LOOP
;
1567 $$.regnum
= $1; $$.type
= BWRITERSPR_LABEL
;
1570 comp: COMP_GT
{ $$
= BWRITER_COMPARISON_GT
; }
1571 | COMP_LT
{ $$
= BWRITER_COMPARISON_LT
; }
1572 | COMP_GE
{ $$
= BWRITER_COMPARISON_GE
; }
1573 | COMP_LE
{ $$
= BWRITER_COMPARISON_LE
; }
1574 | COMP_EQ
{ $$
= BWRITER_COMPARISON_EQ
; }
1575 | COMP_NE
{ $$
= BWRITER_COMPARISON_NE
; }
1577 dclusage: USAGE_POSITION
1579 TRACE
("dcl_position%u\n", $1);
1581 $$.dclusage
= BWRITERDECLUSAGE_POSITION
;
1585 TRACE
("dcl_blendweight%u\n", $1);
1587 $$.dclusage
= BWRITERDECLUSAGE_BLENDWEIGHT
;
1589 | USAGE_BLENDINDICES
1591 TRACE
("dcl_blendindices%u\n", $1);
1593 $$.dclusage
= BWRITERDECLUSAGE_BLENDINDICES
;
1597 TRACE
("dcl_normal%u\n", $1);
1599 $$.dclusage
= BWRITERDECLUSAGE_NORMAL
;
1603 TRACE
("dcl_psize%u\n", $1);
1605 $$.dclusage
= BWRITERDECLUSAGE_PSIZE
;
1609 TRACE
("dcl_texcoord%u\n", $1);
1611 $$.dclusage
= BWRITERDECLUSAGE_TEXCOORD
;
1615 TRACE
("dcl_tangent%u\n", $1);
1617 $$.dclusage
= BWRITERDECLUSAGE_TANGENT
;
1621 TRACE
("dcl_binormal%u\n", $1);
1623 $$.dclusage
= BWRITERDECLUSAGE_BINORMAL
;
1627 TRACE
("dcl_tessfactor%u\n", $1);
1629 $$.dclusage
= BWRITERDECLUSAGE_TESSFACTOR
;
1633 TRACE
("dcl_positiont%u\n", $1);
1635 $$.dclusage
= BWRITERDECLUSAGE_POSITIONT
;
1639 TRACE
("dcl_color%u\n", $1);
1641 $$.dclusage
= BWRITERDECLUSAGE_COLOR
;
1645 TRACE
("dcl_fog%u\n", $1);
1647 $$.dclusage
= BWRITERDECLUSAGE_FOG
;
1651 TRACE
("dcl_depth%u\n", $1);
1653 $$.dclusage
= BWRITERDECLUSAGE_DEPTH
;
1657 TRACE
("dcl_sample%u\n", $1);
1659 $$.dclusage
= BWRITERDECLUSAGE_SAMPLE
;
1662 dcl_inputreg: REG_INPUT
1664 $$.regnum
= $1; $$.type
= BWRITERSPR_INPUT
;
1668 $$.regnum
= $1; $$.type
= BWRITERSPR_TEXTURE
;
1671 sampdcl: SAMPTYPE_1D
1681 $$
= BWRITERSTT_CUBE
;
1685 $$
= BWRITERSTT_VOLUME
;
1688 predicate: '(' REG_PREDICATE swizzle
')'
1690 $$.type
= BWRITERSPR_PREDICATE
;
1693 $$.srcmod
= BWRITERSPSM_NONE
;
1696 |
'(' SMOD_NOT REG_PREDICATE swizzle
')'
1698 $$.type
= BWRITERSPR_PREDICATE
;
1701 $$.srcmod
= BWRITERSPSM_NOT
;
1707 /* New status is the worst between current status and parameter value */
1708 void set_parse_status
(struct asm_parser
*ctx
, enum parse_status status
) {
1709 if
(status
== PARSE_ERR
) ctx
->status
= PARSE_ERR
;
1710 else if
(status
== PARSE_WARN
&& ctx
->status
== PARSE_SUCCESS
) ctx
->status
= PARSE_WARN
;
1713 struct bwriter_shader
*parse_asm_shader
(char **messages
) {
1714 struct bwriter_shader
*ret
= NULL
;
1716 asm_ctx.shader
= NULL
;
1717 asm_ctx.status
= PARSE_SUCCESS
;
1718 asm_ctx.messagesize
= asm_ctx.messagecapacity
= 0;
1719 asm_ctx.line_no
= 1;
1723 if
(asm_ctx.status
!= PARSE_ERR
) ret
= asm_ctx.shader
;
1724 else if
(asm_ctx.shader
) SlDeleteShader
(asm_ctx.shader
);
1727 if
(asm_ctx.messagesize
) {
1728 /* Shrink the buffer to the used size */
1729 *messages
= asm_realloc
(asm_ctx.messages
, asm_ctx.messagesize
+ 1);
1731 ERR
("Out of memory, no messages reported\n");
1732 asm_free
(asm_ctx.messages
);
1738 if
(asm_ctx.messagecapacity
) asm_free
(asm_ctx.messages
);