+ struct nvfx_vertex_program* vp = nvfx->render_mode == HW ? nvfx->vertprog : nvfx->swtnl.vertprog;
+ if (fp->last_vp_id != vp->id) {
+ char* vp_sem_table = vp->generic_to_fp_input;
+ unsigned char* fp_semantics = fp->slot_to_generic;
+ unsigned diff = 0;
+ fp->last_vp_id = nvfx->vertprog->id;
+ unsigned char* cur_slots = fp->slot_to_fp_input;
+ for(unsigned i = 0; i < fp->num_slots; ++i) {
+ unsigned char slot_mask = vp_sem_table[fp_semantics[i]];
+ diff |= (slot_mask >> 4) & (slot_mask ^ cur_slots[i]);
+ }
+
+ if(diff)
+ {
+ for(unsigned i = 0; i < fp->num_slots; ++i) {
+ /* if 0xff, then this will write to the dummy value at fp->last_layout_mask[0] */
+ fp->slot_to_fp_input[i] = vp_sem_table[fp_semantics[i]] & 0xf;
+ //printf("fp: GENERIC[%i] from fpreg %i\n", fp_semantics[i], fp->slot_to_fp_input[i]);
+ }
+
+ fp->progs_left_with_obsolete_slot_assignments = fp->progs;
+ update = TRUE;
+ }
+ }
+
+ // last_sprite_coord_enable
+ unsigned sprite_coord_enable = nvfx->rasterizer->pipe.point_quad_rasterization * nvfx->rasterizer->pipe.sprite_coord_enable;
+ if(fp->last_sprite_coord_enable != sprite_coord_enable)
+ {
+ unsigned texcoord_mask = vp->texcoord_ouput_mask;
+ fp->last_sprite_coord_enable = sprite_coord_enable;
+ fp->point_sprite_control = 0;
+ for(unsigned i = 0; i < fp->num_slots; ++i) {
+ if((1 << fp->slot_to_generic[i]) & sprite_coord_enable)
+ {
+ unsigned fpin = fp->slot_to_fp_input[i];
+ //printf("sprite: slot %i generic %i had texcoord %i\n", i, fp->slot_to_generic[i], fpin - NVFX_FP_OP_INPUT_SRC_TC0);
+ if(fpin >= 0x0f)
+ {
+ unsigned tc = __builtin_ctz(~texcoord_mask);
+ texcoord_mask |= (1 << tc);
+ fp->slot_to_fp_input[i] = fpin = NVFX_FP_OP_INPUT_SRC_TC(tc);