/** * The vertex info describes how to convert the post-transformed vertices * (simple float[][4]) used by the 'draw' module into vertices for * rasterization. * * This function validates the vertex layout. */ static void compute_vertex_info(struct llvmpipe_context *llvmpipe) { const struct tgsi_shader_info *fsInfo = &llvmpipe->fs->info.base; struct vertex_info *vinfo = &llvmpipe->vertex_info; int vs_index; uint i; draw_prepare_shader_outputs(llvmpipe->draw); /* * Those can't actually be 0 (because pos is always at 0). * But use ints anyway to avoid confusion (in vs outputs, they * can very well be at pos 0). */ llvmpipe->color_slot[0] = -1; llvmpipe->color_slot[1] = -1; llvmpipe->bcolor_slot[0] = -1; llvmpipe->bcolor_slot[1] = -1; llvmpipe->viewport_index_slot = -1; llvmpipe->layer_slot = -1; llvmpipe->face_slot = -1; llvmpipe->psize_slot = -1; /* * Match FS inputs against VS outputs, emitting the necessary * attributes. Could cache these structs and look them up with a * combination of fragment shader, vertex shader ids. */ vinfo->num_attribs = 0; vs_index = draw_find_shader_output(llvmpipe->draw, TGSI_SEMANTIC_POSITION, 0); draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index); for (i = 0; i < fsInfo->num_inputs; i++) { /* * Search for each input in current vs output: */ vs_index = draw_find_shader_output(llvmpipe->draw, fsInfo->input_semantic_name[i], fsInfo->input_semantic_index[i]); if (fsInfo->input_semantic_name[i] == TGSI_SEMANTIC_COLOR && fsInfo->input_semantic_index[i] < 2) { int idx = fsInfo->input_semantic_index[i]; llvmpipe->color_slot[idx] = (int)vinfo->num_attribs; } if (fsInfo->input_semantic_name[i] == TGSI_SEMANTIC_FACE) { llvmpipe->face_slot = (int)vinfo->num_attribs; draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index); /* * For vp index and layer, if the fs requires them but the vs doesn't * provide them, draw (vbuf) will give us the required 0 (slot -1). * (This means in this case we'll also use those slots in setup, which * isn't necessary but they'll contain the correct (0) value.) */ } else if (fsInfo->input_semantic_name[i] == TGSI_SEMANTIC_VIEWPORT_INDEX) { llvmpipe->viewport_index_slot = (int)vinfo->num_attribs; draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index); } else if (fsInfo->input_semantic_name[i] == TGSI_SEMANTIC_LAYER) { llvmpipe->layer_slot = (int)vinfo->num_attribs; draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index); } else { /* * Note that we'd actually want to skip position (as we won't use * the attribute in the fs) but can't. The reason is that we don't * actually have a input/output map for setup (even though it looks * like we do...). Could adjust for this though even without a map * (in llvmpipe_create_fs_state()). */ draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index); } } /* Figure out if we need bcolor as well. */ for (i = 0; i < 2; i++) { vs_index = draw_find_shader_output(llvmpipe->draw, TGSI_SEMANTIC_BCOLOR, i); if (vs_index >= 0) { llvmpipe->bcolor_slot[i] = (int)vinfo->num_attribs; draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index); } } /* Figure out if we need pointsize as well. */ vs_index = draw_find_shader_output(llvmpipe->draw, TGSI_SEMANTIC_PSIZE, 0); if (vs_index >= 0) { llvmpipe->psize_slot = (int)vinfo->num_attribs; draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index); } /* Figure out if we need viewport index (if it wasn't already in fs input) */ if (llvmpipe->viewport_index_slot < 0) { vs_index = draw_find_shader_output(llvmpipe->draw, TGSI_SEMANTIC_VIEWPORT_INDEX, 0); if (vs_index >= 0) { llvmpipe->viewport_index_slot =(int)vinfo->num_attribs; draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index); } } /* Figure out if we need layer (if it wasn't already in fs input) */ if (llvmpipe->layer_slot < 0) { vs_index = draw_find_shader_output(llvmpipe->draw, TGSI_SEMANTIC_LAYER, 0); if (vs_index >= 0) { llvmpipe->layer_slot = (int)vinfo->num_attribs; draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index); } } draw_compute_vertex_size(vinfo); lp_setup_set_vertex_info(llvmpipe->setup, vinfo); }
/** * The vertex info describes how to convert the post-transformed vertices * (simple float[][4]) used by the 'draw' module into vertices for * rasterization. * * This function validates the vertex layout. */ static void compute_vertex_info(struct llvmpipe_context *llvmpipe) { const struct lp_fragment_shader *lpfs = llvmpipe->fs; struct vertex_info *vinfo = &llvmpipe->vertex_info; int vs_index; uint i; draw_prepare_shader_outputs(llvmpipe->draw); llvmpipe->color_slot[0] = 0; llvmpipe->color_slot[1] = 0; llvmpipe->bcolor_slot[0] = 0; llvmpipe->bcolor_slot[1] = 0; llvmpipe->viewport_index_slot = 0; llvmpipe->layer_slot = 0; llvmpipe->face_slot = 0; llvmpipe->psize_slot = 0; /* * Match FS inputs against VS outputs, emitting the necessary * attributes. Could cache these structs and look them up with a * combination of fragment shader, vertex shader ids. */ vinfo->num_attribs = 0; vs_index = draw_find_shader_output(llvmpipe->draw, TGSI_SEMANTIC_POSITION, 0); draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, vs_index); for (i = 0; i < lpfs->info.base.num_inputs; i++) { /* * Search for each input in current vs output: */ vs_index = draw_find_shader_output(llvmpipe->draw, lpfs->info.base.input_semantic_name[i], lpfs->info.base.input_semantic_index[i]); if (lpfs->info.base.input_semantic_name[i] == TGSI_SEMANTIC_COLOR && lpfs->info.base.input_semantic_index[i] < 2) { int idx = lpfs->info.base.input_semantic_index[i]; llvmpipe->color_slot[idx] = vinfo->num_attribs; } if (lpfs->info.base.input_semantic_name[i] == TGSI_SEMANTIC_FACE) { llvmpipe->face_slot = vinfo->num_attribs; draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, vs_index); } else if (lpfs->info.base.input_semantic_name[i] == TGSI_SEMANTIC_PRIMID) { draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, vs_index); /* * For vp index and layer, if the fs requires them but the vs doesn't * provide them, store the slot - we'll later replace the data directly * with zero (as required by ARB_fragment_layer_viewport). This is * because draw itself just redirects them to whatever was at output 0. * We'll also store the real vpindex/layer slot for setup use. */ } else if (lpfs->info.base.input_semantic_name[i] == TGSI_SEMANTIC_VIEWPORT_INDEX) { if (vs_index >= 0) { llvmpipe->viewport_index_slot = vinfo->num_attribs; } else { llvmpipe->fake_vpindex_slot = vinfo->num_attribs; } draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, vs_index); } else if (lpfs->info.base.input_semantic_name[i] == TGSI_SEMANTIC_LAYER) { if (vs_index >= 0) { llvmpipe->layer_slot = vinfo->num_attribs; } else { llvmpipe->fake_layer_slot = vinfo->num_attribs; } draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, vs_index); } else { /* * Emit the requested fs attribute for all but position. */ draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, vs_index); } } /* Figure out if we need bcolor as well. */ for (i = 0; i < 2; i++) { vs_index = draw_find_shader_output(llvmpipe->draw, TGSI_SEMANTIC_BCOLOR, i); if (vs_index >= 0) { llvmpipe->bcolor_slot[i] = vinfo->num_attribs; draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, vs_index); } } /* Figure out if we need pointsize as well. */ vs_index = draw_find_shader_output(llvmpipe->draw, TGSI_SEMANTIC_PSIZE, 0); if (vs_index >= 0) { llvmpipe->psize_slot = vinfo->num_attribs; draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, vs_index); } /* Figure out if we need viewport index (if it wasn't already in fs input) */ if (llvmpipe->viewport_index_slot == 0) { vs_index = draw_find_shader_output(llvmpipe->draw, TGSI_SEMANTIC_VIEWPORT_INDEX, 0); if (vs_index >= 0) { llvmpipe->viewport_index_slot = vinfo->num_attribs; draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, vs_index); } } /* Figure out if we need layer (if it wasn't already in fs input) */ if (llvmpipe->layer_slot == 0) { vs_index = draw_find_shader_output(llvmpipe->draw, TGSI_SEMANTIC_LAYER, 0); if (vs_index >= 0) { llvmpipe->layer_slot = vinfo->num_attribs; draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, vs_index); } } draw_compute_vertex_size(vinfo); lp_setup_set_vertex_info(llvmpipe->setup, vinfo); }
/** * The vertex info describes how to convert the post-transformed vertices * (simple float[][4]) used by the 'draw' module into vertices for * rasterization. * * This function validates the vertex layout. */ static void compute_vertex_info(struct llvmpipe_context *llvmpipe) { const struct lp_fragment_shader *lpfs = llvmpipe->fs; struct vertex_info *vinfo = &llvmpipe->vertex_info; int vs_index; uint i; llvmpipe->color_slot[0] = -1; llvmpipe->color_slot[1] = -1; llvmpipe->bcolor_slot[0] = -1; llvmpipe->bcolor_slot[1] = -1; /* * Match FS inputs against VS outputs, emitting the necessary * attributes. Could cache these structs and look them up with a * combination of fragment shader, vertex shader ids. */ vinfo->num_attribs = 0; vs_index = draw_find_shader_output(llvmpipe->draw, TGSI_SEMANTIC_POSITION, 0); draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, vs_index); for (i = 0; i < lpfs->info.base.num_inputs; i++) { /* * Search for each input in current vs output: */ vs_index = draw_find_shader_output(llvmpipe->draw, lpfs->info.base.input_semantic_name[i], lpfs->info.base.input_semantic_index[i]); if (lpfs->info.base.input_semantic_name[i] == TGSI_SEMANTIC_COLOR && lpfs->info.base.input_semantic_index[i] < 2) { int idx = lpfs->info.base.input_semantic_index[i]; llvmpipe->color_slot[idx] = (int)vinfo->num_attribs; } /* * Emit the requested fs attribute for all but position. */ draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, vs_index); } /* Figure out if we need bcolor as well. */ for (i = 0; i < 2; i++) { vs_index = draw_find_shader_output(llvmpipe->draw, TGSI_SEMANTIC_BCOLOR, i); if (vs_index >= 0) { llvmpipe->bcolor_slot[i] = (int)vinfo->num_attribs; draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, vs_index); } } /* Figure out if we need pointsize as well. */ vs_index = draw_find_shader_output(llvmpipe->draw, TGSI_SEMANTIC_PSIZE, 0); if (vs_index >= 0) { llvmpipe->psize_slot = vinfo->num_attribs; draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, vs_index); } /* Figure out if we need viewport index */ vs_index = draw_find_shader_output(llvmpipe->draw, TGSI_SEMANTIC_VIEWPORT_INDEX, 0); if (vs_index >= 0) { llvmpipe->viewport_index_slot = vinfo->num_attribs; draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, vs_index); } else { llvmpipe->viewport_index_slot = 0; } /* Figure out if we need layer */ vs_index = draw_find_shader_output(llvmpipe->draw, TGSI_SEMANTIC_LAYER, 0); if (vs_index >= 0) { llvmpipe->layer_slot = vinfo->num_attribs; draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, vs_index); } else { llvmpipe->layer_slot = 0; } draw_compute_vertex_size(vinfo); lp_setup_set_vertex_info(llvmpipe->setup, vinfo); }
/** * The vertex info describes how to convert the post-transformed vertices * (simple float[][4]) used by the 'draw' module into vertices for * rasterization. * * This function validates the vertex layout. */ static void compute_vertex_info(struct llvmpipe_context *llvmpipe) { const struct lp_fragment_shader *lpfs = llvmpipe->fs; struct vertex_info *vinfo = &llvmpipe->vertex_info; struct lp_shader_input *inputs = llvmpipe->inputs; unsigned vs_index; uint i; /* * Match FS inputs against VS outputs, emitting the necessary attributes. */ vinfo->num_attribs = 0; vs_index = draw_find_shader_output(llvmpipe->draw, TGSI_SEMANTIC_POSITION, 0); draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, vs_index); for (i = 0; i < lpfs->info.num_inputs; i++) { /* * Search for each input in current vs output: */ vs_index = draw_find_shader_output(llvmpipe->draw, lpfs->info.input_semantic_name[i], lpfs->info.input_semantic_index[i]); if (vs_index < 0) { /* * This can happen with sprite coordinates - the vertex * shader doesn't need to provide an output as we generate * them internally. However, lets keep pretending that there * is something there to not confuse other code. */ vs_index = 0; } /* This can be pre-computed, except for flatshade: */ inputs[i].usage_mask = lpfs->info.input_usage_mask[i]; switch (lpfs->info.input_interpolate[i]) { case TGSI_INTERPOLATE_CONSTANT: inputs[i].interp = LP_INTERP_CONSTANT; break; case TGSI_INTERPOLATE_LINEAR: inputs[i].interp = LP_INTERP_LINEAR; break; case TGSI_INTERPOLATE_PERSPECTIVE: inputs[i].interp = LP_INTERP_PERSPECTIVE; break; default: assert(0); break; } switch (lpfs->info.input_semantic_name[i]) { case TGSI_SEMANTIC_FACE: inputs[i].interp = LP_INTERP_FACING; break; case TGSI_SEMANTIC_POSITION: /* Position was already emitted above */ inputs[i].interp = LP_INTERP_POSITION; inputs[i].src_index = 0; continue; case TGSI_SEMANTIC_COLOR: /* Colors are linearly inputs[i].interpolated in the fragment shader * even when flatshading is active. This just tells the * setup module to use coefficients with ddx==0 and * ddy==0. */ if (llvmpipe->rasterizer->flatshade) inputs[i].interp = LP_INTERP_CONSTANT; break; default: break; } /* * Emit the requested fs attribute for all but position. */ inputs[i].src_index = vinfo->num_attribs; draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, vs_index); } /* Figure out if we need pointsize as well. */ vs_index = draw_find_shader_output(llvmpipe->draw, TGSI_SEMANTIC_PSIZE, 0); if (vs_index > 0) { llvmpipe->psize_slot = vinfo->num_attribs; draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, vs_index); } llvmpipe->num_inputs = lpfs->info.num_inputs; draw_compute_vertex_size(vinfo); lp_setup_set_vertex_info(llvmpipe->setup, vinfo); lp_setup_set_fs_inputs(llvmpipe->setup, inputs, lpfs->info.num_inputs); }