/** * Compute the setup->coef[] array dadx, dady, a0 values. * Must be called after setup->vmin,vmax are initialized. */ static boolean setup_line_coefficients(struct setup_context *setup, const float (*v0)[4], const float (*v1)[4]) { struct softpipe_context *softpipe = setup->softpipe; const struct tgsi_shader_info *fsInfo = &setup->softpipe->fs_variant->info; const struct sp_setup_info *sinfo = &softpipe->setup_info; uint fragSlot; float area; float v[2]; assert(sinfo->valid); /* use setup->vmin, vmax to point to vertices */ if (softpipe->rasterizer->flatshade_first) setup->vprovoke = v0; else setup->vprovoke = v1; setup->vmin = v0; setup->vmax = v1; setup->emaj.dx = setup->vmax[0][0] - setup->vmin[0][0]; setup->emaj.dy = setup->vmax[0][1] - setup->vmin[0][1]; /* NOTE: this is not really area but something proportional to it */ area = setup->emaj.dx * setup->emaj.dx + setup->emaj.dy * setup->emaj.dy; if (area == 0.0f || util_is_inf_or_nan(area)) return FALSE; setup->oneoverarea = 1.0f / area; /* z and w are done by linear interpolation: */ v[0] = setup->vmin[0][2]; v[1] = setup->vmax[0][2]; line_linear_coeff(setup, &setup->posCoef, 2, v); v[0] = setup->vmin[0][3]; v[1] = setup->vmax[0][3]; line_linear_coeff(setup, &setup->posCoef, 3, v); /* setup interpolation for all the remaining attributes: */ for (fragSlot = 0; fragSlot < fsInfo->num_inputs; fragSlot++) { const uint vertSlot = sinfo->attrib[fragSlot].src_index; uint j; switch (sinfo->attrib[fragSlot].interp) { case SP_INTERP_CONSTANT: for (j = 0; j < TGSI_NUM_CHANNELS; j++) const_coeff(setup, &setup->coef[fragSlot], vertSlot, j); break; case SP_INTERP_LINEAR: for (j = 0; j < TGSI_NUM_CHANNELS; j++) { line_apply_cylindrical_wrap(setup->vmin[vertSlot][j], setup->vmax[vertSlot][j], fsInfo->input_cylindrical_wrap[fragSlot] & (1 << j), v); line_linear_coeff(setup, &setup->coef[fragSlot], j, v); } break; case SP_INTERP_PERSPECTIVE: for (j = 0; j < TGSI_NUM_CHANNELS; j++) { line_apply_cylindrical_wrap(setup->vmin[vertSlot][j], setup->vmax[vertSlot][j], fsInfo->input_cylindrical_wrap[fragSlot] & (1 << j), v); line_persp_coeff(setup, &setup->coef[fragSlot], j, v); } break; case SP_INTERP_POS: setup_fragcoord_coeff(setup, fragSlot); break; default: assert(0); } if (fsInfo->input_semantic_name[fragSlot] == TGSI_SEMANTIC_FACE) { /* convert 0 to 1.0 and 1 to -1.0 */ setup->coef[fragSlot].a0[0] = setup->facing * -2.0f + 1.0f; setup->coef[fragSlot].dadx[0] = 0.0; setup->coef[fragSlot].dady[0] = 0.0; } } return TRUE; }
/** * Compute the setup->coef[] array dadx, dady, a0 values. * Must be called after setup->vmin,vmax are initialized. */ static INLINE boolean setup_line_coefficients(struct setup_context *setup, const float (*v0)[4], const float (*v1)[4]) { struct softpipe_context *softpipe = setup->softpipe; const struct sp_fragment_shader *spfs = softpipe->fs; const struct vertex_info *vinfo = softpipe_get_vertex_info(softpipe); uint fragSlot; float area; /* use setup->vmin, vmax to point to vertices */ if (softpipe->rasterizer->flatshade_first) setup->vprovoke = v0; else setup->vprovoke = v1; setup->vmin = v0; setup->vmax = v1; setup->emaj.dx = setup->vmax[0][0] - setup->vmin[0][0]; setup->emaj.dy = setup->vmax[0][1] - setup->vmin[0][1]; /* NOTE: this is not really area but something proportional to it */ area = setup->emaj.dx * setup->emaj.dx + setup->emaj.dy * setup->emaj.dy; if (area == 0.0f || util_is_inf_or_nan(area)) return FALSE; setup->oneoverarea = 1.0f / area; /* z and w are done by linear interpolation: */ line_linear_coeff(setup, &setup->posCoef, 0, 2); line_linear_coeff(setup, &setup->posCoef, 0, 3); /* setup interpolation for all the remaining attributes: */ for (fragSlot = 0; fragSlot < spfs->info.num_inputs; fragSlot++) { const uint vertSlot = vinfo->attrib[fragSlot].src_index; uint j; switch (vinfo->attrib[fragSlot].interp_mode) { case INTERP_CONSTANT: for (j = 0; j < NUM_CHANNELS; j++) const_coeff(setup, &setup->coef[fragSlot], vertSlot, j); break; case INTERP_LINEAR: for (j = 0; j < NUM_CHANNELS; j++) line_linear_coeff(setup, &setup->coef[fragSlot], vertSlot, j); break; case INTERP_PERSPECTIVE: for (j = 0; j < NUM_CHANNELS; j++) line_persp_coeff(setup, &setup->coef[fragSlot], vertSlot, j); break; case INTERP_POS: setup_fragcoord_coeff(setup, fragSlot); break; default: assert(0); } if (spfs->info.input_semantic_name[fragSlot] == TGSI_SEMANTIC_FACE) { setup->coef[fragSlot].a0[0] = 1.0f - setup->facing; setup->coef[fragSlot].dadx[0] = 0.0; setup->coef[fragSlot].dady[0] = 0.0; } } return TRUE; }