2 Copyright (C) Intel Corp. 2006. All Rights Reserved.
3 Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
4 develop this 3D driver.
6 Permission is hereby granted, free of charge, to any person obtaining
7 a copy of this software and associated documentation files (the
8 "Software"), to deal in the Software without restriction, including
9 without limitation the rights to use, copy, modify, merge, publish,
10 distribute, sublicense, and/or sell copies of the Software, and to
11 permit persons to whom the Software is furnished to do so, subject to
12 the following conditions:
14 The above copyright notice and this permission notice (including the
15 next paragraph) shall be included in all copies or substantial
16 portions of the Software.
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
22 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 **********************************************************************/
29 * Keith Whitwell <keith@tungstengraphics.com>
33 #include "main/glheader.h"
34 #include "main/macros.h"
35 #include "main/enums.h"
36 #include "brw_context.h"
40 #include "shader/prog_parameter.h"
41 #include "shader/prog_print.h"
42 #include "shader/prog_statevars.h"
45 #define FIRST_INTERNAL_TEMP MAX_NV_FRAGMENT_PROGRAM_TEMPS
53 static const char *wm_opcode_strings
[] = {
65 static const char *wm_file_strings
[] = {
71 /***********************************************************************
75 static struct prog_src_register
src_reg(GLuint file
, GLuint idx
)
77 struct prog_src_register reg
;
80 reg
.Swizzle
= SWIZZLE_NOOP
;
88 static struct prog_src_register
src_reg_from_dst(struct prog_dst_register dst
)
90 return src_reg(dst
.File
, dst
.Index
);
93 static struct prog_src_register
src_undef( void )
95 return src_reg(PROGRAM_UNDEFINED
, 0);
98 static GLboolean
src_is_undef(struct prog_src_register src
)
100 return src
.File
== PROGRAM_UNDEFINED
;
103 static struct prog_src_register
src_swizzle( struct prog_src_register reg
, int x
, int y
, int z
, int w
)
105 reg
.Swizzle
= MAKE_SWIZZLE4(x
,y
,z
,w
);
109 static struct prog_src_register
src_swizzle1( struct prog_src_register reg
, int x
)
111 return src_swizzle(reg
, x
, x
, x
, x
);
115 /***********************************************************************
119 static struct prog_dst_register
dst_reg(GLuint file
, GLuint idx
)
121 struct prog_dst_register reg
;
124 reg
.WriteMask
= WRITEMASK_XYZW
;
132 static struct prog_dst_register
dst_mask( struct prog_dst_register reg
, int mask
)
134 reg
.WriteMask
&= mask
;
138 static struct prog_dst_register
dst_undef( void )
140 return dst_reg(PROGRAM_UNDEFINED
, 0);
145 static struct prog_dst_register
get_temp( struct brw_wm_compile
*c
)
147 int bit
= _mesa_ffs( ~c
->fp_temp
);
150 _mesa_printf("%s: out of temporaries\n", __FILE__
);
154 c
->fp_temp
|= 1<<(bit
-1);
155 return dst_reg(PROGRAM_TEMPORARY
, FIRST_INTERNAL_TEMP
+(bit
-1));
159 static void release_temp( struct brw_wm_compile
*c
, struct prog_dst_register temp
)
161 c
->fp_temp
&= ~(1 << (temp
.Index
- FIRST_INTERNAL_TEMP
));
165 /***********************************************************************
169 static struct prog_instruction
*get_fp_inst(struct brw_wm_compile
*c
)
171 return &c
->prog_instructions
[c
->nr_fp_insns
++];
174 static struct prog_instruction
*emit_insn(struct brw_wm_compile
*c
,
175 const struct prog_instruction
*inst0
)
177 struct prog_instruction
*inst
= get_fp_inst(c
);
179 inst
->Data
= (void *)inst0
;
183 static struct prog_instruction
* emit_op(struct brw_wm_compile
*c
,
185 struct prog_dst_register dest
,
188 GLuint tex_src_target
,
189 struct prog_src_register src0
,
190 struct prog_src_register src1
,
191 struct prog_src_register src2
)
193 struct prog_instruction
*inst
= get_fp_inst(c
);
195 memset(inst
, 0, sizeof(*inst
));
199 inst
->SaturateMode
= saturate
;
200 inst
->TexSrcUnit
= tex_src_unit
;
201 inst
->TexSrcTarget
= tex_src_target
;
202 inst
->SrcReg
[0] = src0
;
203 inst
->SrcReg
[1] = src1
;
204 inst
->SrcReg
[2] = src2
;
211 /***********************************************************************
212 * Special instructions for interpolation and other tasks
215 static struct prog_src_register
get_pixel_xy( struct brw_wm_compile
*c
)
217 if (src_is_undef(c
->pixel_xy
)) {
218 struct prog_dst_register pixel_xy
= get_temp(c
);
219 struct prog_src_register payload_r0_depth
= src_reg(PROGRAM_PAYLOAD
, PAYLOAD_DEPTH
);
222 /* Emit the out calculations, and hold onto the results. Use
223 * two instructions as a temporary is required.
225 /* pixel_xy.xy = PIXELXY payload[0];
229 dst_mask(pixel_xy
, WRITEMASK_XY
),
235 c
->pixel_xy
= src_reg_from_dst(pixel_xy
);
241 static struct prog_src_register
get_delta_xy( struct brw_wm_compile
*c
)
243 if (src_is_undef(c
->delta_xy
)) {
244 struct prog_dst_register delta_xy
= get_temp(c
);
245 struct prog_src_register pixel_xy
= get_pixel_xy(c
);
246 struct prog_src_register payload_r0_depth
= src_reg(PROGRAM_PAYLOAD
, PAYLOAD_DEPTH
);
248 /* deltas.xy = DELTAXY pixel_xy, payload[0]
252 dst_mask(delta_xy
, WRITEMASK_XY
),
258 c
->delta_xy
= src_reg_from_dst(delta_xy
);
264 static struct prog_src_register
get_pixel_w( struct brw_wm_compile
*c
)
266 if (src_is_undef(c
->pixel_w
)) {
267 struct prog_dst_register pixel_w
= get_temp(c
);
268 struct prog_src_register deltas
= get_delta_xy(c
);
269 struct prog_src_register interp_wpos
= src_reg(PROGRAM_PAYLOAD
, FRAG_ATTRIB_WPOS
);
272 /* deltas.xyw = DELTAS2 deltas.xy, payload.interp_wpos.x
276 dst_mask(pixel_w
, WRITEMASK_W
),
283 c
->pixel_w
= src_reg_from_dst(pixel_w
);
289 static void emit_interp( struct brw_wm_compile
*c
,
292 struct prog_dst_register dst
= dst_reg(PROGRAM_INPUT
, idx
);
293 struct prog_src_register interp
= src_reg(PROGRAM_PAYLOAD
, idx
);
294 struct prog_src_register deltas
= get_delta_xy(c
);
295 struct prog_src_register arg2
;
298 /* Need to use PINTERP on attributes which have been
299 * multiplied by 1/W in the SF program, and LINTERP on those
303 case FRAG_ATTRIB_WPOS
:
307 /* Have to treat wpos.xy specially:
311 dst_mask(dst
, WRITEMASK_XY
),
317 dst
= dst_mask(dst
, WRITEMASK_ZW
);
319 /* PROGRAM_INPUT.attr.xyzw = INTERP payload.interp[attr].x, deltas.xyw
329 case FRAG_ATTRIB_COL0
:
330 case FRAG_ATTRIB_COL1
:
331 if (c
->key
.flat_shade
) {
361 c
->fp_interp_emitted
|= 1<<idx
;
364 static void emit_ddx( struct brw_wm_compile
*c
,
365 const struct prog_instruction
*inst
)
367 GLuint idx
= inst
->SrcReg
[0].Index
;
368 struct prog_src_register interp
= src_reg(PROGRAM_PAYLOAD
, idx
);
370 c
->fp_deriv_emitted
|= 1<<idx
;
380 static void emit_ddy( struct brw_wm_compile
*c
,
381 const struct prog_instruction
*inst
)
383 GLuint idx
= inst
->SrcReg
[0].Index
;
384 struct prog_src_register interp
= src_reg(PROGRAM_PAYLOAD
, idx
);
386 c
->fp_deriv_emitted
|= 1<<idx
;
396 /***********************************************************************
397 * Hacks to extend the program parameter and constant lists.
400 /* Add the fog parameters to the parameter list of the original
401 * program, rather than creating a new list. Doesn't really do any
402 * harm and it's not as if the parameter handling isn't a big hack
405 static struct prog_src_register
search_or_add_param5(struct brw_wm_compile
*c
,
412 struct gl_program_parameter_list
*paramList
= c
->fp
->program
.Base
.Parameters
;
413 gl_state_index tokens
[STATE_LENGTH
];
421 for (idx
= 0; idx
< paramList
->NumParameters
; idx
++) {
422 if (paramList
->Parameters
[idx
].Type
== PROGRAM_STATE_VAR
&&
423 memcmp(paramList
->Parameters
[idx
].StateIndexes
, tokens
, sizeof(tokens
)) == 0)
424 return src_reg(PROGRAM_STATE_VAR
, idx
);
427 idx
= _mesa_add_state_reference( paramList
, tokens
);
429 /* Recalculate state dependency:
431 c
->fp
->param_state
= paramList
->StateFlags
;
433 return src_reg(PROGRAM_STATE_VAR
, idx
);
437 static struct prog_src_register
search_or_add_const4f( struct brw_wm_compile
*c
,
443 struct gl_program_parameter_list
*paramList
= c
->fp
->program
.Base
.Parameters
;
453 /* Have to search, otherwise multiple compilations will each grow
454 * the parameter list.
456 for (idx
= 0; idx
< paramList
->NumParameters
; idx
++) {
457 if (paramList
->Parameters
[idx
].Type
== PROGRAM_CONSTANT
&&
458 memcmp(paramList
->ParameterValues
[idx
], values
, sizeof(values
)) == 0)
460 /* XXX: this mimics the mesa bug which puts all constants and
461 * parameters into the "PROGRAM_STATE_VAR" category:
463 return src_reg(PROGRAM_STATE_VAR
, idx
);
466 idx
= _mesa_add_unnamed_constant( paramList
, values
, 4, &swizzle
);
467 assert(swizzle
== SWIZZLE_NOOP
); /* Need to handle swizzle in reg setup */
468 return src_reg(PROGRAM_STATE_VAR
, idx
);
473 /***********************************************************************
474 * Expand various instructions here to simpler forms.
476 static void precalc_dst( struct brw_wm_compile
*c
,
477 const struct prog_instruction
*inst
)
479 struct prog_src_register src0
= inst
->SrcReg
[0];
480 struct prog_src_register src1
= inst
->SrcReg
[1];
481 struct prog_dst_register dst
= inst
->DstReg
;
483 if (dst
.WriteMask
& WRITEMASK_Y
) {
484 /* dst.y = mul src0.y, src1.y
488 dst_mask(dst
, WRITEMASK_Y
),
489 inst
->SaturateMode
, 0, 0,
496 if (dst
.WriteMask
& WRITEMASK_XZ
) {
497 struct prog_instruction
*swz
;
498 GLuint z
= GET_SWZ(src0
.Swizzle
, Z
);
500 /* dst.xz = swz src0.1zzz
504 dst_mask(dst
, WRITEMASK_XZ
),
505 inst
->SaturateMode
, 0, 0,
506 src_swizzle(src0
, SWIZZLE_ONE
, z
, z
, z
),
509 /* Avoid letting negation flag of src0 affect our 1 constant. */
510 swz
->SrcReg
[0].NegateBase
&= ~NEGATE_X
;
512 if (dst
.WriteMask
& WRITEMASK_W
) {
513 /* dst.w = mov src1.w
517 dst_mask(dst
, WRITEMASK_W
),
518 inst
->SaturateMode
, 0, 0,
526 static void precalc_lit( struct brw_wm_compile
*c
,
527 const struct prog_instruction
*inst
)
529 struct prog_src_register src0
= inst
->SrcReg
[0];
530 struct prog_dst_register dst
= inst
->DstReg
;
532 if (dst
.WriteMask
& WRITEMASK_XW
) {
533 struct prog_instruction
*swz
;
535 /* dst.xw = swz src0.1111
539 dst_mask(dst
, WRITEMASK_XW
),
541 src_swizzle1(src0
, SWIZZLE_ONE
),
544 /* Avoid letting the negation flag of src0 affect our 1 constant. */
545 swz
->SrcReg
[0].NegateBase
= 0;
549 if (dst
.WriteMask
& WRITEMASK_YZ
) {
552 dst_mask(dst
, WRITEMASK_YZ
),
553 inst
->SaturateMode
, 0, 0,
560 static void precalc_tex( struct brw_wm_compile
*c
,
561 const struct prog_instruction
*inst
)
563 struct prog_src_register coord
;
564 struct prog_dst_register tmpcoord
;
565 GLuint unit
= c
->fp
->program
.Base
.SamplerUnits
[inst
->TexSrcUnit
];
567 if (inst
->TexSrcTarget
== TEXTURE_CUBE_INDEX
) {
568 struct prog_instruction
*out
;
569 struct prog_dst_register tmp0
= get_temp(c
);
570 struct prog_src_register tmp0src
= src_reg_from_dst(tmp0
);
571 struct prog_dst_register tmp1
= get_temp(c
);
572 struct prog_src_register tmp1src
= src_reg_from_dst(tmp1
);
573 struct prog_src_register src0
= inst
->SrcReg
[0];
575 tmpcoord
= get_temp(c
);
576 coord
= src_reg_from_dst(tmpcoord
);
578 out
= emit_op(c
, OPCODE_MOV
,
584 out
->SrcReg
[0].NegateBase
= 0;
585 out
->SrcReg
[0].Abs
= 1;
587 emit_op(c
, OPCODE_MAX
,
590 src_swizzle1(coord
, X
),
591 src_swizzle1(coord
, Y
),
594 emit_op(c
, OPCODE_MAX
,
598 src_swizzle1(coord
, Z
),
601 emit_op(c
, OPCODE_RCP
,
608 emit_op(c
, OPCODE_MUL
,
615 release_temp(c
, tmp0
);
616 release_temp(c
, tmp1
);
617 } else if (inst
->TexSrcTarget
== TEXTURE_RECT_INDEX
) {
618 struct prog_src_register scale
=
619 search_or_add_param5( c
,
625 tmpcoord
= get_temp(c
);
627 /* coord.xy = MUL inst->SrcReg[0], { 1/width, 1/height }
637 coord
= src_reg_from_dst(tmpcoord
);
640 coord
= inst
->SrcReg
[0];
643 /* Need to emit YUV texture conversions by hand. Probably need to
644 * do this here - the alternative is in brw_wm_emit.c, but the
645 * conversion requires allocating a temporary variable which we
646 * don't have the facility to do that late in the compilation.
648 if (!(c
->key
.yuvtex_mask
& (1<<unit
))) {
660 GLboolean swap_uv
= c
->key
.yuvtex_swap_mask
& (1<<unit
);
663 CONST C0 = { -.5, -.0625, -.5, 1.164 }
664 CONST C1 = { 1.596, -0.813, 2.018, -.391 }
666 UYV.xyz = ADD UYV, C0
667 UYV.y = MUL UYV.y, C0.w
669 RGB.xyz = MAD UYV.zzx, C1, UYV.y
671 RGB.xyz = MAD UYV.xxz, C1, UYV.y
672 RGB.y = MAD UYV.z, C1.w, RGB.y
674 struct prog_dst_register dst
= inst
->DstReg
;
675 struct prog_dst_register tmp
= get_temp(c
);
676 struct prog_src_register tmpsrc
= src_reg_from_dst(tmp
);
677 struct prog_src_register C0
= search_or_add_const4f( c
, -.5, -.0625, -.5, 1.164 );
678 struct prog_src_register C1
= search_or_add_const4f( c
, 1.596, -0.813, 2.018, -.391 );
692 /* tmp.xyz = ADD TMP, C0
696 dst_mask(tmp
, WRITEMASK_XYZ
),
702 /* YUV.y = MUL YUV.y, C0.w
707 dst_mask(tmp
, WRITEMASK_Y
),
715 * RGB.xyz = MAD YUV.zzx, C1, YUV.y
717 * RGB.xyz = MAD YUV.xxz, C1, YUV.y
722 dst_mask(dst
, WRITEMASK_XYZ
),
724 swap_uv
?src_swizzle(tmpsrc
, Z
,Z
,X
,X
):src_swizzle(tmpsrc
, X
,X
,Z
,Z
),
726 src_swizzle1(tmpsrc
, Y
));
728 /* RGB.y = MAD YUV.z, C1.w, RGB.y
732 dst_mask(dst
, WRITEMASK_Y
),
734 src_swizzle1(tmpsrc
, Z
),
736 src_swizzle1(src_reg_from_dst(dst
), Y
));
738 release_temp(c
, tmp
);
741 if ((inst
->TexSrcTarget
== TEXTURE_RECT_INDEX
) ||
742 (inst
->TexSrcTarget
== TEXTURE_CUBE_INDEX
))
743 release_temp(c
, tmpcoord
);
747 static GLboolean
projtex( struct brw_wm_compile
*c
,
748 const struct prog_instruction
*inst
)
750 struct prog_src_register src
= inst
->SrcReg
[0];
752 /* Only try to detect the simplest cases. Could detect (later)
753 * cases where we are trying to emit code like RCP {1.0}, MUL x,
756 * More complex cases than this typically only arise from
757 * user-provided fragment programs anyway:
759 if (inst
->TexSrcTarget
== TEXTURE_CUBE_INDEX
)
760 return 0; /* ut2004 gun rendering !?! */
761 else if (src
.File
== PROGRAM_INPUT
&&
762 GET_SWZ(src
.Swizzle
, W
) == W
&&
763 (c
->key
.projtex_mask
& (1<<(src
.Index
+ FRAG_ATTRIB_WPOS
- FRAG_ATTRIB_TEX0
))) == 0)
770 static void precalc_txp( struct brw_wm_compile
*c
,
771 const struct prog_instruction
*inst
)
773 struct prog_src_register src0
= inst
->SrcReg
[0];
775 if (projtex(c
, inst
)) {
776 struct prog_dst_register tmp
= get_temp(c
);
777 struct prog_instruction tmp_inst
;
779 /* tmp0.w = RCP inst.arg[0][3]
783 dst_mask(tmp
, WRITEMASK_W
),
785 src_swizzle1(src0
, GET_SWZ(src0
.Swizzle
, W
)),
789 /* tmp0.xyz = MUL inst.arg[0], tmp0.wwww
793 dst_mask(tmp
, WRITEMASK_XYZ
),
796 src_swizzle1(src_reg_from_dst(tmp
), W
),
799 /* dst = precalc(TEX tmp0)
802 tmp_inst
.SrcReg
[0] = src_reg_from_dst(tmp
);
803 precalc_tex(c
, &tmp_inst
);
805 release_temp(c
, tmp
);
809 /* dst = precalc(TEX src0)
811 precalc_tex(c
, inst
);
819 /***********************************************************************
820 * Add instructions to perform fog blending
823 static void fog_blend( struct brw_wm_compile
*c
,
824 struct prog_src_register fog_factor
)
826 struct prog_dst_register outcolor
= dst_reg(PROGRAM_OUTPUT
, FRAG_RESULT_COLR
);
827 struct prog_src_register fogcolor
= search_or_add_param5( c
, STATE_FOG_COLOR
, 0,0,0,0 );
829 /* color.xyz = LRP fog_factor.xxxx, output_color, fog_color */
833 dst_mask(outcolor
, WRITEMASK_XYZ
),
836 src_reg_from_dst(outcolor
),
842 /* This one is simple - just take the interpolated fog coordinate and
843 * use it as the fog blend factor.
845 static void fog_interpolated( struct brw_wm_compile
*c
)
847 struct prog_src_register fogc
= src_reg(PROGRAM_INPUT
, FRAG_ATTRIB_FOGC
);
849 if (!(c
->fp_interp_emitted
& (1<<FRAG_ATTRIB_FOGC
)))
850 emit_interp(c
, FRAG_ATTRIB_FOGC
);
852 fog_blend( c
, src_swizzle1(fogc
, GET_SWZ(fogc
.Swizzle
,X
)));
855 static void emit_fog( struct brw_wm_compile
*c
)
857 if (!c
->fp
->program
.FogOption
)
861 fog_interpolated( c
);
863 /* TODO: per-pixel fog */
868 static void emit_fb_write( struct brw_wm_compile
*c
)
870 struct prog_src_register outcolor
= src_reg(PROGRAM_OUTPUT
, FRAG_RESULT_COLR
);
871 struct prog_src_register payload_r0_depth
= src_reg(PROGRAM_PAYLOAD
, PAYLOAD_DEPTH
);
872 struct prog_src_register outdepth
= src_reg(PROGRAM_OUTPUT
, FRAG_RESULT_DEPR
);
875 struct prog_instruction
*inst
, *last_inst
;
876 struct brw_context
*brw
= c
->func
.brw
;
878 /* inst->Sampler is not used by backend,
879 use it for fb write target and eot */
881 if (brw
->state
.nr_draw_regions
> 1) {
882 for (i
= 0 ; i
< brw
->state
.nr_draw_regions
; i
++) {
883 outcolor
= src_reg(PROGRAM_OUTPUT
, FRAG_RESULT_DATA0
+ i
);
884 last_inst
= inst
= emit_op(c
,
885 WM_FB_WRITE
, dst_mask(dst_undef(),0), 0, 0, 0,
886 outcolor
, payload_r0_depth
, outdepth
);
887 inst
->Sampler
= (i
<<1);
888 if (c
->fp_fragcolor_emitted
) {
889 outcolor
= src_reg(PROGRAM_OUTPUT
, FRAG_RESULT_COLR
);
890 last_inst
= inst
= emit_op(c
, WM_FB_WRITE
, dst_mask(dst_undef(),0),
891 0, 0, 0, outcolor
, payload_r0_depth
, outdepth
);
892 inst
->Sampler
= (i
<<1);
895 last_inst
->Sampler
|= 1; //eot
897 inst
= emit_op(c
, WM_FB_WRITE
, dst_mask(dst_undef(),0),
898 0, 0, 0, outcolor
, payload_r0_depth
, outdepth
);
899 inst
->Sampler
= 1|(0<<1);
906 /***********************************************************************
907 * Emit INTERP instructions ahead of first use of each attrib.
910 static void validate_src_regs( struct brw_wm_compile
*c
,
911 const struct prog_instruction
*inst
)
913 GLuint nr_args
= brw_wm_nr_args( inst
->Opcode
);
916 for (i
= 0; i
< nr_args
; i
++) {
917 if (inst
->SrcReg
[i
].File
== PROGRAM_INPUT
) {
918 GLuint idx
= inst
->SrcReg
[i
].Index
;
919 if (!(c
->fp_interp_emitted
& (1<<idx
))) {
926 static void validate_dst_regs( struct brw_wm_compile
*c
,
927 const struct prog_instruction
*inst
)
929 if (inst
->DstReg
.File
== PROGRAM_OUTPUT
) {
930 GLuint idx
= inst
->DstReg
.Index
;
931 if (idx
== FRAG_RESULT_COLR
)
932 c
->fp_fragcolor_emitted
= 1;
936 static void print_insns( const struct prog_instruction
*insn
,
940 for (i
= 0; i
< nr
; i
++, insn
++) {
941 _mesa_printf("%3d: ", i
);
942 if (insn
->Opcode
< MAX_OPCODE
)
943 _mesa_print_instruction(insn
);
944 else if (insn
->Opcode
< MAX_WM_OPCODE
) {
945 GLuint idx
= insn
->Opcode
- MAX_OPCODE
;
947 _mesa_print_alu_instruction(insn
,
948 wm_opcode_strings
[idx
],
952 _mesa_printf("UNKNOWN\n");
957 void brw_wm_pass_fp( struct brw_wm_compile
*c
)
959 struct brw_fragment_program
*fp
= c
->fp
;
962 if (INTEL_DEBUG
& DEBUG_WM
) {
963 _mesa_printf("\n\n\npre-fp:\n");
964 _mesa_print_program(&fp
->program
.Base
);
968 c
->pixel_xy
= src_undef();
969 c
->delta_xy
= src_undef();
970 c
->pixel_w
= src_undef();
973 /* Emit preamble instructions:
977 for (insn
= 0; insn
< fp
->program
.Base
.NumInstructions
; insn
++) {
978 const struct prog_instruction
*inst
= &fp
->program
.Base
.Instructions
[insn
];
979 validate_src_regs(c
, inst
);
980 validate_dst_regs(c
, inst
);
982 for (insn
= 0; insn
< fp
->program
.Base
.NumInstructions
; insn
++) {
983 const struct prog_instruction
*inst
= &fp
->program
.Base
.Instructions
[insn
];
984 struct prog_instruction
*out
;
986 /* Check for INPUT values, emit INTERP instructions where
991 switch (inst
->Opcode
) {
993 out
= emit_insn(c
, inst
);
994 out
->Opcode
= OPCODE_MOV
;
998 out
= emit_insn(c
, inst
);
999 out
->Opcode
= OPCODE_MOV
;
1000 out
->SrcReg
[0].NegateBase
= 0;
1001 out
->SrcReg
[0].Abs
= 1;
1005 out
= emit_insn(c
, inst
);
1006 out
->Opcode
= OPCODE_ADD
;
1007 out
->SrcReg
[1].NegateBase
^= 0xf;
1011 out
= emit_insn(c
, inst
);
1012 /* This should probably be done in the parser.
1014 out
->DstReg
.WriteMask
&= WRITEMASK_XY
;
1018 precalc_dst(c
, inst
);
1022 precalc_lit(c
, inst
);
1026 precalc_tex(c
, inst
);
1030 precalc_txp(c
, inst
);
1034 out
= emit_insn(c
, inst
);
1035 out
->TexSrcUnit
= fp
->program
.Base
.SamplerUnits
[inst
->TexSrcUnit
];
1039 out
= emit_insn(c
, inst
);
1040 /* This should probably be done in the parser.
1042 out
->DstReg
.WriteMask
&= WRITEMASK_XYZ
;
1046 out
= emit_insn(c
, inst
);
1047 /* This should probably be done in the parser.
1049 out
->DstReg
.WriteMask
= 0;
1070 if (INTEL_DEBUG
& DEBUG_WM
) {
1071 _mesa_printf("\n\n\npass_fp:\n");
1072 print_insns( c
->prog_instructions
, c
->nr_fp_insns
);