/** * Create a TGSI ureg_dst register from a Mesa dest register. */ static struct ureg_dst translate_dst( struct st_translate *t, const struct prog_dst_register *DstReg, boolean saturate, boolean clamp_color) { struct ureg_dst dst = dst_register( t, DstReg->File, DstReg->Index ); dst = ureg_writemask( dst, DstReg->WriteMask ); if (saturate) dst = ureg_saturate( dst ); else if (clamp_color && DstReg->File == PROGRAM_OUTPUT) { /* Clamp colors for ARB_color_buffer_float. */ switch (t->procType) { case TGSI_PROCESSOR_VERTEX: /* This can only occur with a compatibility profile, which doesn't * support geometry shaders. */ if (DstReg->Index == VARYING_SLOT_COL0 || DstReg->Index == VARYING_SLOT_COL1 || DstReg->Index == VARYING_SLOT_BFC0 || DstReg->Index == VARYING_SLOT_BFC1) { dst = ureg_saturate(dst); } break; case TGSI_PROCESSOR_FRAGMENT: if (DstReg->Index >= FRAG_RESULT_COLOR) { dst = ureg_saturate(dst); } break; } } if (DstReg->RelAddr) dst = ureg_dst_indirect( dst, ureg_src(t->address[0]) ); return dst; }
/** * Create a TGSI ureg_dst register from a Mesa dest register. */ static struct ureg_dst translate_dst( struct st_translate *t, const struct prog_dst_register *DstReg, boolean saturate, boolean clamp_color) { struct ureg_dst dst = dst_register( t, DstReg->File, DstReg->Index ); dst = ureg_writemask( dst, DstReg->WriteMask ); if (saturate) dst = ureg_saturate( dst ); else if (clamp_color && DstReg->File == PROGRAM_OUTPUT) { /* Clamp colors for ARB_color_buffer_float. */ switch (t->procType) { case TGSI_PROCESSOR_VERTEX: /* XXX if the geometry shader is present, this must be done there * instead of here. */ if (DstReg->Index == VARYING_SLOT_COL0 || DstReg->Index == VARYING_SLOT_COL1 || DstReg->Index == VARYING_SLOT_BFC0 || DstReg->Index == VARYING_SLOT_BFC1) { dst = ureg_saturate(dst); } break; case TGSI_PROCESSOR_FRAGMENT: if (DstReg->Index >= FRAG_RESULT_COLOR) { dst = ureg_saturate(dst); } break; } } if (DstReg->RelAddr) dst = ureg_dst_indirect( dst, ureg_src(t->address[0]) ); return dst; }
/** * OpenGL's fragment gl_FrontFace input is 1 for front-facing, 0 for back. * TGSI uses +1 for front, -1 for back. * This function converts the TGSI value to the GL value. Simply clamping/ * saturating the value to [0,1] does the job. */ static void emit_face_var( struct st_translate *t, const struct gl_program *program ) { struct ureg_program *ureg = t->ureg; struct ureg_dst face_temp = ureg_DECL_temporary( ureg ); struct ureg_src face_input = t->inputs[t->inputMapping[VARYING_SLOT_FACE]]; /* MOV_SAT face_temp, input[face] */ face_temp = ureg_saturate( face_temp ); ureg_MOV( ureg, face_temp, face_input ); /* Use face_temp as face input from here on: */ t->inputs[t->inputMapping[VARYING_SLOT_FACE]] = ureg_src(face_temp); }
static void emit_dstmod(struct st_translate *t, struct ureg_dst dst, GLuint dstMod) { float imm; struct ureg_src src[3]; GLuint scale = dstMod & ~GL_SATURATE_BIT_ATI; if (dstMod == GL_NONE) { return; } switch (scale) { case GL_2X_BIT_ATI: imm = 2.0f; break; case GL_4X_BIT_ATI: imm = 4.0f; break; case GL_8X_BIT_ATI: imm = 8.0f; break; case GL_HALF_BIT_ATI: imm = 0.5f; break; case GL_QUARTER_BIT_ATI: imm = 0.25f; break; case GL_EIGHTH_BIT_ATI: imm = 0.125f; break; default: imm = 1.0f; } src[0] = ureg_src(dst); src[1] = ureg_imm1f(t->ureg, imm); if (dstMod & GL_SATURATE_BIT_ATI) { dst = ureg_saturate(dst); } ureg_insn(t->ureg, TGSI_OPCODE_MUL, &dst, 1, src, 2); }
/** * Create a TGSI ureg_dst register from a Mesa dest register. */ static struct ureg_dst translate_dst( struct st_translate *t, const struct prog_dst_register *DstReg, boolean saturate) { struct ureg_dst dst = dst_register( t, DstReg->File, DstReg->Index ); dst = ureg_writemask( dst, DstReg->WriteMask ); if (saturate) dst = ureg_saturate( dst ); if (DstReg->RelAddr) dst = ureg_dst_indirect( dst, ureg_src(t->address[0]) ); return dst; }
static void * create_deint_frag_shader(struct vl_deint_filter *filter, unsigned field, struct vertex2f *sizes, bool spatial_filter) { struct ureg_program *shader; struct ureg_src i_vtex; struct ureg_src sampler_cur; struct ureg_src sampler_prevprev; struct ureg_src sampler_prev; struct ureg_src sampler_next; struct ureg_dst o_fragment; struct ureg_dst t_tex; struct ureg_dst t_comp_top, t_comp_bot; struct ureg_dst t_diff; struct ureg_dst t_a, t_b; struct ureg_dst t_weave, t_linear; shader = ureg_create(PIPE_SHADER_FRAGMENT); if (!shader) { return NULL; } t_tex = ureg_DECL_temporary(shader); t_comp_top = ureg_DECL_temporary(shader); t_comp_bot = ureg_DECL_temporary(shader); t_diff = ureg_DECL_temporary(shader); t_a = ureg_DECL_temporary(shader); t_b = ureg_DECL_temporary(shader); t_weave = ureg_DECL_temporary(shader); t_linear = ureg_DECL_temporary(shader); i_vtex = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTEX, TGSI_INTERPOLATE_LINEAR); sampler_prevprev = ureg_DECL_sampler(shader, 0); sampler_prev = ureg_DECL_sampler(shader, 1); sampler_cur = ureg_DECL_sampler(shader, 2); sampler_next = ureg_DECL_sampler(shader, 3); o_fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0); // we don't care about ZW interpolation (allows better optimization) ureg_MOV(shader, t_tex, i_vtex); ureg_MOV(shader, ureg_writemask(t_tex, TGSI_WRITEMASK_ZW), ureg_imm1f(shader, 0)); // sample between texels for cheap lowpass ureg_ADD(shader, t_comp_top, ureg_src(t_tex), ureg_imm4f(shader, sizes->x * 0.5f, sizes->y * -0.5f, 0, 0)); ureg_ADD(shader, t_comp_bot, ureg_src(t_tex), ureg_imm4f(shader, sizes->x * -0.5f, sizes->y * 0.5f, 1.0f, 0)); if (field == 0) { /* interpolating top field -> current field is a bottom field */ // cur vs prev2 ureg_TEX(shader, t_a, TGSI_TEXTURE_2D_ARRAY, ureg_src(t_comp_bot), sampler_cur); ureg_TEX(shader, t_b, TGSI_TEXTURE_2D_ARRAY, ureg_src(t_comp_bot), sampler_prevprev); ureg_ADD(shader, ureg_writemask(t_diff, TGSI_WRITEMASK_X), ureg_src(t_a), ureg_negate(ureg_src(t_b))); // prev vs next ureg_TEX(shader, t_a, TGSI_TEXTURE_2D_ARRAY, ureg_src(t_comp_top), sampler_prev); ureg_TEX(shader, t_b, TGSI_TEXTURE_2D_ARRAY, ureg_src(t_comp_top), sampler_next); ureg_ADD(shader, ureg_writemask(t_diff, TGSI_WRITEMASK_Y), ureg_src(t_a), ureg_negate(ureg_src(t_b))); } else { /* interpolating bottom field -> current field is a top field */ // cur vs prev2 ureg_TEX(shader, t_a, TGSI_TEXTURE_2D_ARRAY, ureg_src(t_comp_top), sampler_cur); ureg_TEX(shader, t_b, TGSI_TEXTURE_2D_ARRAY, ureg_src(t_comp_top), sampler_prevprev); ureg_ADD(shader, ureg_writemask(t_diff, TGSI_WRITEMASK_X), ureg_src(t_a), ureg_negate(ureg_src(t_b))); // prev vs next ureg_TEX(shader, t_a, TGSI_TEXTURE_2D_ARRAY, ureg_src(t_comp_bot), sampler_prev); ureg_TEX(shader, t_b, TGSI_TEXTURE_2D_ARRAY, ureg_src(t_comp_bot), sampler_next); ureg_ADD(shader, ureg_writemask(t_diff, TGSI_WRITEMASK_Y), ureg_src(t_a), ureg_negate(ureg_src(t_b))); } // absolute maximum of differences ureg_MAX(shader, ureg_writemask(t_diff, TGSI_WRITEMASK_X), ureg_abs(ureg_src(t_diff)), ureg_scalar(ureg_abs(ureg_src(t_diff)), TGSI_SWIZZLE_Y)); if (field == 0) { /* weave with prev top field */ ureg_TEX(shader, t_weave, TGSI_TEXTURE_2D_ARRAY, ureg_src(t_tex), sampler_prev); /* get linear interpolation from current bottom field */ ureg_ADD(shader, t_comp_top, ureg_src(t_tex), ureg_imm4f(shader, 0, sizes->y * -1.0f, 1.0f, 0)); ureg_TEX(shader, t_linear, TGSI_TEXTURE_2D_ARRAY, ureg_src(t_comp_top), sampler_cur); } else { /* weave with prev bottom field */ ureg_ADD(shader, t_comp_bot, ureg_src(t_tex), ureg_imm4f(shader, 0, 0, 1.0f, 0)); ureg_TEX(shader, t_weave, TGSI_TEXTURE_2D_ARRAY, ureg_src(t_comp_bot), sampler_prev); /* get linear interpolation from current top field */ ureg_ADD(shader, t_comp_bot, ureg_src(t_tex), ureg_imm4f(shader, 0, sizes->y * 1.0f, 0, 0)); ureg_TEX(shader, t_linear, TGSI_TEXTURE_2D_ARRAY, ureg_src(t_comp_bot), sampler_cur); } // mix between weave and linear // fully weave if diff < 6 (0.02353), fully interpolate if diff > 14 (0.05490) ureg_ADD(shader, ureg_writemask(t_diff, TGSI_WRITEMASK_X), ureg_src(t_diff), ureg_imm4f(shader, -0.02353f, 0, 0, 0)); ureg_MUL(shader, ureg_saturate(ureg_writemask(t_diff, TGSI_WRITEMASK_X)), ureg_src(t_diff), ureg_imm4f(shader, 31.8750f, 0, 0, 0)); ureg_LRP(shader, ureg_writemask(t_tex, TGSI_WRITEMASK_X), ureg_src(t_diff), ureg_src(t_linear), ureg_src(t_weave)); ureg_MOV(shader, o_fragment, ureg_scalar(ureg_src(t_tex), TGSI_SWIZZLE_X)); ureg_release_temporary(shader, t_tex); ureg_release_temporary(shader, t_comp_top); ureg_release_temporary(shader, t_comp_bot); ureg_release_temporary(shader, t_diff); ureg_release_temporary(shader, t_a); ureg_release_temporary(shader, t_b); ureg_release_temporary(shader, t_weave); ureg_release_temporary(shader, t_linear); ureg_END(shader); return ureg_create_shader_and_destroy(shader, filter->pipe); }