+static void parse_shader(struct shader_translator *tx)
+{
+ struct nine_shader_info *info = tx->info;
+
+ while (!sm1_parse_eof(tx) && !tx->failure)
+ sm1_parse_instruction(tx);
+ tx->parse++; /* for byte_size */
+
+ if (tx->failure)
+ return;
+
+ if (IS_PS && tx->version.major < 3) {
+ if (tx->version.major < 2) {
+ assert(tx->num_temp); /* there must be color output */
+ info->rt_mask |= 0x1;
+ shader_add_ps_fog_stage(tx, ureg_src(tx->regs.r[0]));
+ } else {
+ shader_add_ps_fog_stage(tx, ureg_src(tx->regs.oCol[0]));
+ }
+ }
+
+ if (IS_VS && tx->version.major < 3 && ureg_dst_is_undef(tx->regs.oFog) && info->fog_enable) {
+ tx->regs.oFog = ureg_DECL_output(tx->ureg, TGSI_SEMANTIC_FOG, 0);
+ ureg_MOV(tx->ureg, ureg_writemask(tx->regs.oFog, TGSI_WRITEMASK_X), ureg_imm1f(tx->ureg, 0.0f));
+ }
+
+ if (info->position_t)
+ ureg_property(tx->ureg, TGSI_PROPERTY_VS_WINDOW_SPACE_POSITION, TRUE);
+
+ if (IS_VS && !ureg_dst_is_undef(tx->regs.oPts)) {
+ struct ureg_dst oPts = ureg_DECL_output(tx->ureg, TGSI_SEMANTIC_PSIZE, 0);
+ ureg_MAX(tx->ureg, tx->regs.oPts, ureg_src(tx->regs.oPts), ureg_imm1f(tx->ureg, info->point_size_min));
+ ureg_MIN(tx->ureg, oPts, ureg_src(tx->regs.oPts), ureg_imm1f(tx->ureg, info->point_size_max));
+ info->point_size = TRUE;
+ }
+
+ if (info->process_vertices)
+ shader_add_vs_viewport_transform(tx);
+
+ ureg_END(tx->ureg);
+}
+