/** * Return total number of the shader outputs. This function is similar to * draw_current_shader_outputs() but this function also counts any extra * vertex/geometry output attributes that may be filled in by some draw * stages (such as AA point, AA line). * * If geometry shader is present, its output will be returned, * if not vertex shader is used. */ uint draw_num_shader_outputs(const struct draw_context *draw) { const struct tgsi_shader_info *info = draw_get_shader_info(draw); uint count; count = info->num_outputs; count += draw->extra_shader_outputs.num; return count; }
/** * Ask the draw module for the location/slot of the given vertex attribute in * a post-transformed vertex. * * With this function, drivers that use the draw module should have no reason * to track the current vertex/geometry shader. * * Note that the draw module may sometimes generate vertices with extra * attributes (such as texcoords for AA lines). The driver can call this * function to find those attributes. * * Zero is returned if the attribute is not found since this is * a don't care / undefined situtation. Returning -1 would be a bit more * work for the drivers. */ int draw_find_shader_output(const struct draw_context *draw, uint semantic_name, uint semantic_index) { const struct tgsi_shader_info *info = draw_get_shader_info(draw); uint i; for (i = 0; i < info->num_outputs; i++) { if (info->output_semantic_name[i] == semantic_name && info->output_semantic_index[i] == semantic_index) return i; } /* Search the extra vertex attributes */ for (i = 0; i < draw->extra_shader_outputs.num; i++) { if (draw->extra_shader_outputs.semantic_name[i] == semantic_name && draw->extra_shader_outputs.semantic_index[i] == semantic_index) { return draw->extra_shader_outputs.slot[i]; } } return 0; }
/* Update state. Could further delay this until we hit the first * primitive that really requires clipping. */ static void clip_init_state( struct draw_stage *stage ) { struct clip_stage *clipper = clip_stage( stage ); const struct draw_context *draw = stage->draw; const struct draw_fragment_shader *fs = draw->fs.fragment_shader; const struct tgsi_shader_info *info = draw_get_shader_info(draw); uint i, j; /* We need to know for each attribute what kind of interpolation is * done on it (flat, smooth or noperspective). But the information * is not directly accessible for outputs, only for inputs. So we * have to match semantic name and index between the VS (or GS/ES) * outputs and the FS inputs to get to the interpolation mode. * * The only hitch is with gl_FrontColor/gl_BackColor which map to * gl_Color, and their Secondary versions. First there are (up to) * two outputs for one input, so we tuck the information in a * specific array. Second if they don't have qualifiers, the * default value has to be picked from the global shade mode. * * Of course, if we don't have a fragment shader in the first * place, defaults should be used. */ /* First pick up the interpolation mode for * gl_Color/gl_SecondaryColor, with the correct default. */ int indexed_interp[2]; indexed_interp[0] = indexed_interp[1] = draw->rasterizer->flatshade ? TGSI_INTERPOLATE_CONSTANT : TGSI_INTERPOLATE_PERSPECTIVE; if (fs) { for (i = 0; i < fs->info.num_inputs; i++) { if (fs->info.input_semantic_name[i] == TGSI_SEMANTIC_COLOR) { if (fs->info.input_interpolate[i] != TGSI_INTERPOLATE_COLOR) indexed_interp[fs->info.input_semantic_index[i]] = fs->info.input_interpolate[i]; } } } /* Then resolve the interpolation mode for every output attribute. * * Given how the rest of the code, the most efficient way is to * have a vector of flat-mode attributes, and a mask for * noperspective attributes. */ clipper->num_flat_attribs = 0; memset(clipper->noperspective_attribs, 0, sizeof(clipper->noperspective_attribs)); for (i = 0; i < info->num_outputs; i++) { /* Find the interpolation mode for a specific attribute */ int interp = find_interp(fs, indexed_interp, info->output_semantic_name[i], info->output_semantic_index[i]); /* If it's flat, add it to the flat vector. Otherwise update * the noperspective mask. */ if (interp == TGSI_INTERPOLATE_CONSTANT) { clipper->flat_attribs[clipper->num_flat_attribs] = i; clipper->num_flat_attribs++; } else clipper->noperspective_attribs[i] = interp == TGSI_INTERPOLATE_LINEAR; } /* Search the extra vertex attributes */ for (j = 0; j < draw->extra_shader_outputs.num; j++) { /* Find the interpolation mode for a specific attribute */ int interp = find_interp(fs, indexed_interp, draw->extra_shader_outputs.semantic_name[j], draw->extra_shader_outputs.semantic_index[j]); /* If it's flat, add it to the flat vector. Otherwise update * the noperspective mask. */ if (interp == TGSI_INTERPOLATE_CONSTANT) { clipper->flat_attribs[clipper->num_flat_attribs] = i + j; clipper->num_flat_attribs++; } else clipper->noperspective_attribs[i + j] = interp == TGSI_INTERPOLATE_LINEAR; } stage->tri = clip_tri; stage->line = clip_line; }