static void fog_blend( struct brw_wm_compile *c, struct prog_src_register fog_factor ) { struct prog_dst_register outcolor = dst_reg(PROGRAM_OUTPUT, FRAG_RESULT_COLR); struct prog_src_register fogcolor = search_or_add_param5( c, STATE_FOG_COLOR, 0,0,0,0 ); /* color.xyz = LRP fog_factor.xxxx, output_color, fog_color */ emit_op(c, OPCODE_LRP, dst_mask(outcolor, WRITEMASK_XYZ), 0, 0, 0, fog_factor, src_reg_from_dst(outcolor), fogcolor); }
/** * Some TEX instructions require extra code, cube map coordinate * normalization, or coordinate scaling for RECT textures, etc. * This function emits those extra instructions and the TEX * instruction itself. */ static void precalc_tex( struct brw_wm_compile *c, const struct prog_instruction *inst ) { struct prog_src_register coord; struct prog_dst_register tmpcoord; const GLuint unit = c->fp->program.Base.SamplerUnits[inst->TexSrcUnit]; assert(unit < BRW_MAX_TEX_UNIT); if (inst->TexSrcTarget == TEXTURE_CUBE_INDEX) { struct prog_instruction *out; struct prog_dst_register tmp0 = get_temp(c); struct prog_src_register tmp0src = src_reg_from_dst(tmp0); struct prog_dst_register tmp1 = get_temp(c); struct prog_src_register tmp1src = src_reg_from_dst(tmp1); struct prog_src_register src0 = inst->SrcReg[0]; /* find longest component of coord vector and normalize it */ tmpcoord = get_temp(c); coord = src_reg_from_dst(tmpcoord); /* tmpcoord = src0 (i.e.: coord = src0) */ out = emit_op(c, OPCODE_MOV, tmpcoord, 0, src0, src_undef(), src_undef()); out->SrcReg[0].Negate = NEGATE_NONE; out->SrcReg[0].Abs = 1; /* tmp0 = MAX(coord.X, coord.Y) */ emit_op(c, OPCODE_MAX, tmp0, 0, src_swizzle1(coord, X), src_swizzle1(coord, Y), src_undef()); /* tmp1 = MAX(tmp0, coord.Z) */ emit_op(c, OPCODE_MAX, tmp1, 0, tmp0src, src_swizzle1(coord, Z), src_undef()); /* tmp0 = 1 / tmp1 */ emit_op(c, OPCODE_RCP, dst_mask(tmp0, WRITEMASK_X), 0, tmp1src, src_undef(), src_undef()); /* tmpCoord = src0 * tmp0 */ emit_op(c, OPCODE_MUL, tmpcoord, 0, src0, src_swizzle1(tmp0src, SWIZZLE_X), src_undef()); release_temp(c, tmp0); release_temp(c, tmp1); } else if (inst->TexSrcTarget == TEXTURE_RECT_INDEX) { struct prog_src_register scale = search_or_add_param5( c, STATE_INTERNAL, STATE_TEXRECT_SCALE, unit, 0,0 ); tmpcoord = get_temp(c); /* coord.xy = MUL inst->SrcReg[0], { 1/width, 1/height } */ emit_op(c, OPCODE_MUL, tmpcoord, 0, inst->SrcReg[0], src_swizzle(scale, SWIZZLE_X, SWIZZLE_Y, SWIZZLE_ONE, SWIZZLE_ONE), src_undef()); coord = src_reg_from_dst(tmpcoord); } else { coord = inst->SrcReg[0]; } /* Need to emit YUV texture conversions by hand. Probably need to * do this here - the alternative is in brw_wm_emit.c, but the * conversion requires allocating a temporary variable which we * don't have the facility to do that late in the compilation. */ if (c->key.yuvtex_mask & (1 << unit)) { /* convert ycbcr to RGBA */ GLboolean swap_uv = c->key.yuvtex_swap_mask & (1<<unit); /* CONST C0 = { -.5, -.0625, -.5, 1.164 } CONST C1 = { 1.596, -0.813, 2.018, -.391 } UYV = TEX ... UYV.xyz = ADD UYV, C0 UYV.y = MUL UYV.y, C0.w if (UV swaped) RGB.xyz = MAD UYV.zzx, C1, UYV.y else RGB.xyz = MAD UYV.xxz, C1, UYV.y RGB.y = MAD UYV.z, C1.w, RGB.y */ struct prog_dst_register dst = inst->DstReg; struct prog_dst_register tmp = get_temp(c); struct prog_src_register tmpsrc = src_reg_from_dst(tmp); struct prog_src_register C0 = search_or_add_const4f( c, -.5, -.0625, -.5, 1.164 ); struct prog_src_register C1 = search_or_add_const4f( c, 1.596, -0.813, 2.018, -.391 ); /* tmp = TEX ... */ emit_tex_op(c, OPCODE_TEX, tmp, inst->SaturateMode, unit, inst->TexSrcTarget, inst->TexShadow, coord, src_undef(), src_undef()); /* tmp.xyz = ADD TMP, C0 */ emit_op(c, OPCODE_ADD, dst_mask(tmp, WRITEMASK_XYZ), 0, tmpsrc, C0, src_undef()); /* YUV.y = MUL YUV.y, C0.w */ emit_op(c, OPCODE_MUL, dst_mask(tmp, WRITEMASK_Y), 0, tmpsrc, src_swizzle1(C0, W), src_undef()); /* * if (UV swaped) * RGB.xyz = MAD YUV.zzx, C1, YUV.y * else * RGB.xyz = MAD YUV.xxz, C1, YUV.y */ emit_op(c, OPCODE_MAD, dst_mask(dst, WRITEMASK_XYZ), 0, swap_uv?src_swizzle(tmpsrc, Z,Z,X,X):src_swizzle(tmpsrc, X,X,Z,Z), C1, src_swizzle1(tmpsrc, Y)); /* RGB.y = MAD YUV.z, C1.w, RGB.y */ emit_op(c, OPCODE_MAD, dst_mask(dst, WRITEMASK_Y), 0, src_swizzle1(tmpsrc, Z), src_swizzle1(C1, W), src_swizzle1(src_reg_from_dst(dst), Y)); release_temp(c, tmp); } else { /* ordinary RGBA tex instruction */ emit_tex_op(c, OPCODE_TEX, inst->DstReg, inst->SaturateMode, unit, inst->TexSrcTarget, inst->TexShadow, coord, src_undef(), src_undef()); } /* For GL_EXT_texture_swizzle: */ if (c->key.tex_swizzles[unit] != SWIZZLE_NOOP) { /* swizzle the result of the TEX instruction */ struct prog_src_register tmpsrc = src_reg_from_dst(inst->DstReg); emit_op(c, OPCODE_SWZ, inst->DstReg, SATURATE_OFF, /* saturate already done above */ src_swizzle4(tmpsrc, c->key.tex_swizzles[unit]), src_undef(), src_undef()); } if ((inst->TexSrcTarget == TEXTURE_RECT_INDEX) || (inst->TexSrcTarget == TEXTURE_CUBE_INDEX)) release_temp(c, tmpcoord); }
static void precalc_tex( struct brw_wm_compile *c, const struct prog_instruction *inst ) { struct prog_src_register coord; struct prog_dst_register tmpcoord; if (inst->TexSrcTarget == TEXTURE_RECT_INDEX) { struct prog_src_register scale = search_or_add_param5( c, STATE_INTERNAL, STATE_TEXRECT_SCALE, inst->TexSrcUnit, 0,0 ); tmpcoord = get_temp(c); /* coord.xy = MUL inst->SrcReg[0], { 1/width, 1/height } */ emit_op(c, OPCODE_MUL, tmpcoord, 0, 0, 0, inst->SrcReg[0], scale, src_undef()); coord = src_reg_from_dst(tmpcoord); } else { coord = inst->SrcReg[0]; } /* Need to emit YUV texture conversions by hand. Probably need to * do this here - the alternative is in brw_wm_emit.c, but the * conversion requires allocating a temporary variable which we * don't have the facility to do that late in the compilation. */ if (!(c->key.yuvtex_mask & (1<<inst->TexSrcUnit))) { emit_op(c, OPCODE_TEX, inst->DstReg, inst->SaturateMode, inst->TexSrcUnit, inst->TexSrcTarget, coord, src_undef(), src_undef()); } else { /* CONST C0 = { -.5, -.0625, -.5, 1.164 } CONST C1 = { 1.596, -0.813, 2.018, -.391 } UYV = TEX ... UYV.xyz = ADD UYV, C0 UYV.y = MUL UYV.y, C0.w RGB.xyz = MAD UYV.xxz, C1, UYV.y RGB.y = MAD UYV.z, C1.w, RGB.y */ struct prog_dst_register dst = inst->DstReg; struct prog_src_register src0 = inst->SrcReg[0]; struct prog_dst_register tmp = get_temp(c); struct prog_src_register tmpsrc = src_reg_from_dst(tmp); struct prog_src_register C0 = search_or_add_const4f( c, -.5, -.0625, -.5, 1.164 ); struct prog_src_register C1 = search_or_add_const4f( c, 1.596, -0.813, 2.018, -.391 ); /* tmp = TEX ... */ emit_op(c, OPCODE_TEX, tmp, inst->SaturateMode, inst->TexSrcUnit, inst->TexSrcTarget, src0, src_undef(), src_undef()); /* tmp.xyz = ADD TMP, C0 */ emit_op(c, OPCODE_ADD, dst_mask(tmp, WRITEMASK_XYZ), 0, 0, 0, tmpsrc, C0, src_undef()); /* YUV.y = MUL YUV.y, C0.w */ emit_op(c, OPCODE_MUL, dst_mask(tmp, WRITEMASK_Y), 0, 0, 0, tmpsrc, src_swizzle1(C0, W), src_undef()); /* RGB.xyz = MAD YUV.xxz, C1, YUV.y */ emit_op(c, OPCODE_MAD, dst_mask(dst, WRITEMASK_XYZ), 0, 0, 0, src_swizzle(tmpsrc, X,X,Z,Z), C1, src_swizzle1(tmpsrc, Y)); /* RGB.y = MAD YUV.z, C1.w, RGB.y */ emit_op(c, OPCODE_MAD, dst_mask(dst, WRITEMASK_Y), 0, 0, 0, src_swizzle1(tmpsrc, Z), src_swizzle1(C1, W), src_swizzle1(src_reg_from_dst(dst), Y)); release_temp(c, tmp); } if (inst->TexSrcTarget == GL_TEXTURE_RECTANGLE_NV) release_temp(c, tmpcoord); }