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 return src_reg(PROGRAM_STATE_VAR
, idx
);
433 static struct prog_src_register
search_or_add_const4f( struct brw_wm_compile
*c
,
439 struct gl_program_parameter_list
*paramList
= c
->fp
->program
.Base
.Parameters
;
449 /* Have to search, otherwise multiple compilations will each grow
450 * the parameter list.
452 for (idx
= 0; idx
< paramList
->NumParameters
; idx
++) {
453 if (paramList
->Parameters
[idx
].Type
== PROGRAM_CONSTANT
&&
454 memcmp(paramList
->ParameterValues
[idx
], values
, sizeof(values
)) == 0)
456 /* XXX: this mimics the mesa bug which puts all constants and
457 * parameters into the "PROGRAM_STATE_VAR" category:
459 return src_reg(PROGRAM_STATE_VAR
, idx
);
462 idx
= _mesa_add_unnamed_constant( paramList
, values
, 4, &swizzle
);
463 assert(swizzle
== SWIZZLE_NOOP
); /* Need to handle swizzle in reg setup */
464 return src_reg(PROGRAM_STATE_VAR
, idx
);
469 /***********************************************************************
470 * Expand various instructions here to simpler forms.
472 static void precalc_dst( struct brw_wm_compile
*c
,
473 const struct prog_instruction
*inst
)
475 struct prog_src_register src0
= inst
->SrcReg
[0];
476 struct prog_src_register src1
= inst
->SrcReg
[1];
477 struct prog_dst_register dst
= inst
->DstReg
;
479 if (dst
.WriteMask
& WRITEMASK_Y
) {
480 /* dst.y = mul src0.y, src1.y
484 dst_mask(dst
, WRITEMASK_Y
),
485 inst
->SaturateMode
, 0, 0,
492 if (dst
.WriteMask
& WRITEMASK_XZ
) {
493 struct prog_instruction
*swz
;
494 GLuint z
= GET_SWZ(src0
.Swizzle
, Z
);
496 /* dst.xz = swz src0.1zzz
500 dst_mask(dst
, WRITEMASK_XZ
),
501 inst
->SaturateMode
, 0, 0,
502 src_swizzle(src0
, SWIZZLE_ONE
, z
, z
, z
),
505 /* Avoid letting negation flag of src0 affect our 1 constant. */
506 swz
->SrcReg
[0].NegateBase
&= ~NEGATE_X
;
508 if (dst
.WriteMask
& WRITEMASK_W
) {
509 /* dst.w = mov src1.w
513 dst_mask(dst
, WRITEMASK_W
),
514 inst
->SaturateMode
, 0, 0,
522 static void precalc_lit( struct brw_wm_compile
*c
,
523 const struct prog_instruction
*inst
)
525 struct prog_src_register src0
= inst
->SrcReg
[0];
526 struct prog_dst_register dst
= inst
->DstReg
;
528 if (dst
.WriteMask
& WRITEMASK_XW
) {
529 struct prog_instruction
*swz
;
531 /* dst.xw = swz src0.1111
535 dst_mask(dst
, WRITEMASK_XW
),
537 src_swizzle1(src0
, SWIZZLE_ONE
),
540 /* Avoid letting the negation flag of src0 affect our 1 constant. */
541 swz
->SrcReg
[0].NegateBase
= 0;
545 if (dst
.WriteMask
& WRITEMASK_YZ
) {
548 dst_mask(dst
, WRITEMASK_YZ
),
549 inst
->SaturateMode
, 0, 0,
556 static void precalc_tex( struct brw_wm_compile
*c
,
557 const struct prog_instruction
*inst
)
559 struct prog_src_register coord
;
560 struct prog_dst_register tmpcoord
;
561 GLuint unit
= c
->fp
->program
.Base
.SamplerUnits
[inst
->TexSrcUnit
];
563 if (inst
->TexSrcTarget
== TEXTURE_CUBE_INDEX
) {
564 struct prog_instruction
*out
;
565 struct prog_dst_register tmp0
= get_temp(c
);
566 struct prog_src_register tmp0src
= src_reg_from_dst(tmp0
);
567 struct prog_dst_register tmp1
= get_temp(c
);
568 struct prog_src_register tmp1src
= src_reg_from_dst(tmp1
);
569 struct prog_src_register src0
= inst
->SrcReg
[0];
571 tmpcoord
= get_temp(c
);
572 coord
= src_reg_from_dst(tmpcoord
);
574 out
= emit_op(c
, OPCODE_MOV
,
580 out
->SrcReg
[0].NegateBase
= 0;
581 out
->SrcReg
[0].Abs
= 1;
583 emit_op(c
, OPCODE_MAX
,
586 src_swizzle1(coord
, X
),
587 src_swizzle1(coord
, Y
),
590 emit_op(c
, OPCODE_MAX
,
594 src_swizzle1(coord
, Z
),
597 emit_op(c
, OPCODE_RCP
,
604 emit_op(c
, OPCODE_MUL
,
611 release_temp(c
, tmp0
);
612 release_temp(c
, tmp1
);
613 } else if (inst
->TexSrcTarget
== TEXTURE_RECT_INDEX
) {
614 struct prog_src_register scale
=
615 search_or_add_param5( c
,
621 tmpcoord
= get_temp(c
);
623 /* coord.xy = MUL inst->SrcReg[0], { 1/width, 1/height }
633 coord
= src_reg_from_dst(tmpcoord
);
636 coord
= inst
->SrcReg
[0];
639 /* Need to emit YUV texture conversions by hand. Probably need to
640 * do this here - the alternative is in brw_wm_emit.c, but the
641 * conversion requires allocating a temporary variable which we
642 * don't have the facility to do that late in the compilation.
644 if (!(c
->key
.yuvtex_mask
& (1<<unit
))) {
656 GLboolean swap_uv
= c
->key
.yuvtex_swap_mask
& (1<<unit
);
659 CONST C0 = { -.5, -.0625, -.5, 1.164 }
660 CONST C1 = { 1.596, -0.813, 2.018, -.391 }
662 UYV.xyz = ADD UYV, C0
663 UYV.y = MUL UYV.y, C0.w
665 RGB.xyz = MAD UYV.zzx, C1, UYV.y
667 RGB.xyz = MAD UYV.xxz, C1, UYV.y
668 RGB.y = MAD UYV.z, C1.w, RGB.y
670 struct prog_dst_register dst
= inst
->DstReg
;
671 struct prog_dst_register tmp
= get_temp(c
);
672 struct prog_src_register tmpsrc
= src_reg_from_dst(tmp
);
673 struct prog_src_register C0
= search_or_add_const4f( c
, -.5, -.0625, -.5, 1.164 );
674 struct prog_src_register C1
= search_or_add_const4f( c
, 1.596, -0.813, 2.018, -.391 );
688 /* tmp.xyz = ADD TMP, C0
692 dst_mask(tmp
, WRITEMASK_XYZ
),
698 /* YUV.y = MUL YUV.y, C0.w
703 dst_mask(tmp
, WRITEMASK_Y
),
711 * RGB.xyz = MAD YUV.zzx, C1, YUV.y
713 * RGB.xyz = MAD YUV.xxz, C1, YUV.y
718 dst_mask(dst
, WRITEMASK_XYZ
),
720 swap_uv
?src_swizzle(tmpsrc
, Z
,Z
,X
,X
):src_swizzle(tmpsrc
, X
,X
,Z
,Z
),
722 src_swizzle1(tmpsrc
, Y
));
724 /* RGB.y = MAD YUV.z, C1.w, RGB.y
728 dst_mask(dst
, WRITEMASK_Y
),
730 src_swizzle1(tmpsrc
, Z
),
732 src_swizzle1(src_reg_from_dst(dst
), Y
));
734 release_temp(c
, tmp
);
737 if ((inst
->TexSrcTarget
== TEXTURE_RECT_INDEX
) ||
738 (inst
->TexSrcTarget
== TEXTURE_CUBE_INDEX
))
739 release_temp(c
, tmpcoord
);
743 static GLboolean
projtex( struct brw_wm_compile
*c
,
744 const struct prog_instruction
*inst
)
746 struct prog_src_register src
= inst
->SrcReg
[0];
748 /* Only try to detect the simplest cases. Could detect (later)
749 * cases where we are trying to emit code like RCP {1.0}, MUL x,
752 * More complex cases than this typically only arise from
753 * user-provided fragment programs anyway:
755 if (inst
->TexSrcTarget
== TEXTURE_CUBE_INDEX
)
756 return 0; /* ut2004 gun rendering !?! */
757 else if (src
.File
== PROGRAM_INPUT
&&
758 GET_SWZ(src
.Swizzle
, W
) == W
&&
759 (c
->key
.projtex_mask
& (1<<(src
.Index
+ FRAG_ATTRIB_WPOS
- FRAG_ATTRIB_TEX0
))) == 0)
766 static void precalc_txp( struct brw_wm_compile
*c
,
767 const struct prog_instruction
*inst
)
769 struct prog_src_register src0
= inst
->SrcReg
[0];
771 if (projtex(c
, inst
)) {
772 struct prog_dst_register tmp
= get_temp(c
);
773 struct prog_instruction tmp_inst
;
775 /* tmp0.w = RCP inst.arg[0][3]
779 dst_mask(tmp
, WRITEMASK_W
),
781 src_swizzle1(src0
, GET_SWZ(src0
.Swizzle
, W
)),
785 /* tmp0.xyz = MUL inst.arg[0], tmp0.wwww
789 dst_mask(tmp
, WRITEMASK_XYZ
),
792 src_swizzle1(src_reg_from_dst(tmp
), W
),
795 /* dst = precalc(TEX tmp0)
798 tmp_inst
.SrcReg
[0] = src_reg_from_dst(tmp
);
799 precalc_tex(c
, &tmp_inst
);
801 release_temp(c
, tmp
);
805 /* dst = precalc(TEX src0)
807 precalc_tex(c
, inst
);
815 /***********************************************************************
816 * Add instructions to perform fog blending
819 static void fog_blend( struct brw_wm_compile
*c
,
820 struct prog_src_register fog_factor
)
822 struct prog_dst_register outcolor
= dst_reg(PROGRAM_OUTPUT
, FRAG_RESULT_COLR
);
823 struct prog_src_register fogcolor
= search_or_add_param5( c
, STATE_FOG_COLOR
, 0,0,0,0 );
825 /* color.xyz = LRP fog_factor.xxxx, output_color, fog_color */
829 dst_mask(outcolor
, WRITEMASK_XYZ
),
832 src_reg_from_dst(outcolor
),
838 /* This one is simple - just take the interpolated fog coordinate and
839 * use it as the fog blend factor.
841 static void fog_interpolated( struct brw_wm_compile
*c
)
843 struct prog_src_register fogc
= src_reg(PROGRAM_INPUT
, FRAG_ATTRIB_FOGC
);
845 if (!(c
->fp_interp_emitted
& (1<<FRAG_ATTRIB_FOGC
)))
846 emit_interp(c
, FRAG_ATTRIB_FOGC
);
848 fog_blend( c
, src_swizzle1(fogc
, GET_SWZ(fogc
.Swizzle
,X
)));
851 static void emit_fog( struct brw_wm_compile
*c
)
853 if (!c
->fp
->program
.FogOption
)
857 fog_interpolated( c
);
859 /* TODO: per-pixel fog */
864 static void emit_fb_write( struct brw_wm_compile
*c
)
866 struct prog_src_register outcolor
= src_reg(PROGRAM_OUTPUT
, FRAG_RESULT_COLR
);
867 struct prog_src_register payload_r0_depth
= src_reg(PROGRAM_PAYLOAD
, PAYLOAD_DEPTH
);
868 struct prog_src_register outdepth
= src_reg(PROGRAM_OUTPUT
, FRAG_RESULT_DEPR
);
871 struct prog_instruction
*inst
, *last_inst
;
872 struct brw_context
*brw
= c
->func
.brw
;
874 /* inst->Sampler is not used by backend,
875 use it for fb write target and eot */
877 if (brw
->state
.nr_draw_regions
> 1) {
878 for (i
= 0 ; i
< brw
->state
.nr_draw_regions
; i
++) {
879 outcolor
= src_reg(PROGRAM_OUTPUT
, FRAG_RESULT_DATA0
+ i
);
880 last_inst
= inst
= emit_op(c
,
881 WM_FB_WRITE
, dst_mask(dst_undef(),0), 0, 0, 0,
882 outcolor
, payload_r0_depth
, outdepth
);
883 inst
->Sampler
= (i
<<1);
884 if (c
->fp_fragcolor_emitted
) {
885 outcolor
= src_reg(PROGRAM_OUTPUT
, FRAG_RESULT_COLR
);
886 last_inst
= inst
= emit_op(c
, WM_FB_WRITE
, dst_mask(dst_undef(),0),
887 0, 0, 0, outcolor
, payload_r0_depth
, outdepth
);
888 inst
->Sampler
= (i
<<1);
891 last_inst
->Sampler
|= 1; //eot
893 inst
= emit_op(c
, WM_FB_WRITE
, dst_mask(dst_undef(),0),
894 0, 0, 0, outcolor
, payload_r0_depth
, outdepth
);
895 inst
->Sampler
= 1|(0<<1);
902 /***********************************************************************
903 * Emit INTERP instructions ahead of first use of each attrib.
906 static void validate_src_regs( struct brw_wm_compile
*c
,
907 const struct prog_instruction
*inst
)
909 GLuint nr_args
= brw_wm_nr_args( inst
->Opcode
);
912 for (i
= 0; i
< nr_args
; i
++) {
913 if (inst
->SrcReg
[i
].File
== PROGRAM_INPUT
) {
914 GLuint idx
= inst
->SrcReg
[i
].Index
;
915 if (!(c
->fp_interp_emitted
& (1<<idx
))) {
922 static void validate_dst_regs( struct brw_wm_compile
*c
,
923 const struct prog_instruction
*inst
)
925 if (inst
->DstReg
.File
== PROGRAM_OUTPUT
) {
926 GLuint idx
= inst
->DstReg
.Index
;
927 if (idx
== FRAG_RESULT_COLR
)
928 c
->fp_fragcolor_emitted
= 1;
932 static void print_insns( const struct prog_instruction
*insn
,
936 for (i
= 0; i
< nr
; i
++, insn
++) {
937 _mesa_printf("%3d: ", i
);
938 if (insn
->Opcode
< MAX_OPCODE
)
939 _mesa_print_instruction(insn
);
940 else if (insn
->Opcode
< MAX_WM_OPCODE
) {
941 GLuint idx
= insn
->Opcode
- MAX_OPCODE
;
943 _mesa_print_alu_instruction(insn
,
944 wm_opcode_strings
[idx
],
948 _mesa_printf("UNKNOWN\n");
953 void brw_wm_pass_fp( struct brw_wm_compile
*c
)
955 struct brw_fragment_program
*fp
= c
->fp
;
958 if (INTEL_DEBUG
& DEBUG_WM
) {
959 _mesa_printf("\n\n\npre-fp:\n");
960 _mesa_print_program(&fp
->program
.Base
);
964 c
->pixel_xy
= src_undef();
965 c
->delta_xy
= src_undef();
966 c
->pixel_w
= src_undef();
969 /* Emit preamble instructions:
973 for (insn
= 0; insn
< fp
->program
.Base
.NumInstructions
; insn
++) {
974 const struct prog_instruction
*inst
= &fp
->program
.Base
.Instructions
[insn
];
975 validate_src_regs(c
, inst
);
976 validate_dst_regs(c
, inst
);
978 for (insn
= 0; insn
< fp
->program
.Base
.NumInstructions
; insn
++) {
979 const struct prog_instruction
*inst
= &fp
->program
.Base
.Instructions
[insn
];
980 struct prog_instruction
*out
;
982 /* Check for INPUT values, emit INTERP instructions where
987 switch (inst
->Opcode
) {
989 out
= emit_insn(c
, inst
);
990 out
->Opcode
= OPCODE_MOV
;
994 out
= emit_insn(c
, inst
);
995 out
->Opcode
= OPCODE_MOV
;
996 out
->SrcReg
[0].NegateBase
= 0;
997 out
->SrcReg
[0].Abs
= 1;
1001 out
= emit_insn(c
, inst
);
1002 out
->Opcode
= OPCODE_ADD
;
1003 out
->SrcReg
[1].NegateBase
^= 0xf;
1007 out
= emit_insn(c
, inst
);
1008 /* This should probably be done in the parser.
1010 out
->DstReg
.WriteMask
&= WRITEMASK_XY
;
1014 precalc_dst(c
, inst
);
1018 precalc_lit(c
, inst
);
1022 precalc_tex(c
, inst
);
1026 precalc_txp(c
, inst
);
1030 out
= emit_insn(c
, inst
);
1031 out
->TexSrcUnit
= fp
->program
.Base
.SamplerUnits
[inst
->TexSrcUnit
];
1035 out
= emit_insn(c
, inst
);
1036 /* This should probably be done in the parser.
1038 out
->DstReg
.WriteMask
&= WRITEMASK_XYZ
;
1042 out
= emit_insn(c
, inst
);
1043 /* This should probably be done in the parser.
1045 out
->DstReg
.WriteMask
= 0;
1066 if (INTEL_DEBUG
& DEBUG_WM
) {
1067 _mesa_printf("\n\n\npass_fp:\n");
1068 print_insns( c
->prog_instructions
, c
->nr_fp_insns
);