/** * 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] = -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; } 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); } 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] = (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; 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); }
enum pipe_error svga_swtnl_update_vdecl( struct svga_context *svga ) { struct svga_vbuf_render *svga_render = svga_vbuf_render(svga->swtnl.backend); struct draw_context *draw = svga->swtnl.draw; struct vertex_info *vinfo = &svga_render->vertex_info; SVGA3dVertexDecl vdecl[PIPE_MAX_ATTRIBS]; const enum interp_mode colorInterp = svga->curr.rast->templ.flatshade ? INTERP_CONSTANT : INTERP_LINEAR; struct svga_fragment_shader *fs = svga->curr.fs; int offset = 0; int nr_decls = 0; int src; unsigned i; memset(vinfo, 0, sizeof(*vinfo)); memset(vdecl, 0, sizeof(vdecl)); draw_prepare_shader_outputs(draw); /* always add position */ src = draw_find_shader_output(draw, TGSI_SEMANTIC_POSITION, 0); draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_LINEAR, src); vinfo->attrib[0].emit = EMIT_4F; vdecl[0].array.offset = offset; vdecl[0].identity.type = SVGA3D_DECLTYPE_FLOAT4; vdecl[0].identity.usage = SVGA3D_DECLUSAGE_POSITIONT; vdecl[0].identity.usageIndex = 0; offset += 16; nr_decls++; for (i = 0; i < fs->base.info.num_inputs; i++) { const unsigned sem_name = fs->base.info.input_semantic_name[i]; const unsigned sem_index = fs->base.info.input_semantic_index[i]; src = draw_find_shader_output(draw, sem_name, sem_index); vdecl[nr_decls].array.offset = offset; vdecl[nr_decls].identity.usageIndex = sem_index; switch (sem_name) { case TGSI_SEMANTIC_COLOR: draw_emit_vertex_attr(vinfo, EMIT_4F, colorInterp, src); vdecl[nr_decls].identity.usage = SVGA3D_DECLUSAGE_COLOR; vdecl[nr_decls].identity.type = SVGA3D_DECLTYPE_FLOAT4; offset += 16; nr_decls++; break; case TGSI_SEMANTIC_GENERIC: draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src); vdecl[nr_decls].identity.usage = SVGA3D_DECLUSAGE_TEXCOORD; vdecl[nr_decls].identity.type = SVGA3D_DECLTYPE_FLOAT4; vdecl[nr_decls].identity.usageIndex = svga_remap_generic_index(fs->generic_remap_table, sem_index); offset += 16; nr_decls++; break; case TGSI_SEMANTIC_FOG: draw_emit_vertex_attr(vinfo, EMIT_1F, INTERP_PERSPECTIVE, src); vdecl[nr_decls].identity.usage = SVGA3D_DECLUSAGE_TEXCOORD; vdecl[nr_decls].identity.type = SVGA3D_DECLTYPE_FLOAT1; assert(vdecl[nr_decls].identity.usageIndex == 0); offset += 4; nr_decls++; break; case TGSI_SEMANTIC_POSITION: /* generated internally, not a vertex shader output */ break; default: assert(0); } } draw_compute_vertex_size(vinfo); svga_render->vdecl_count = nr_decls; for (i = 0; i < svga_render->vdecl_count; i++) vdecl[i].array.stride = offset; if (memcmp(svga_render->vdecl, vdecl, sizeof(vdecl)) == 0) return PIPE_OK; memcpy(svga_render->vdecl, vdecl, sizeof(vdecl)); svga->swtnl.new_vdecl = TRUE; return PIPE_OK; }