#include "lp_setup.h"
#include "lp_state.h"
-
+#include "tgsi/tgsi_from_mesa.h"
/**
* The vertex info describes how to convert the post-transformed vertices
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;
draw_prepare_shader_outputs(llvmpipe->draw);
draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index);
- for (unsigned 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 an 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);
+ struct nir_shader *nir = llvmpipe->fs->base.ir.nir;
+ uint64_t slot_emitted = 0;
+ nir_foreach_shader_in_variable(var, nir) {
+ unsigned tgsi_semantic_name, tgsi_semantic_index;
+ unsigned slots = nir_variable_count_slots(var, var->type);
+ tgsi_get_gl_varying_semantic(var->data.location,
+ true,
+ &tgsi_semantic_name,
+ &tgsi_semantic_index);
+
+ for (unsigned i = 0; i < slots; i++) {
+ vs_index = draw_find_shader_output(llvmpipe->draw,
+ tgsi_semantic_name,
+ tgsi_semantic_index);
+ if (slot_emitted & BITFIELD64_BIT(vs_index)) {
+ tgsi_semantic_index++;
+ continue;
+ }
+
+ if (tgsi_semantic_name == TGSI_SEMANTIC_COLOR &&
+ tgsi_semantic_index < 2) {
+ int idx = tgsi_semantic_index;
+ llvmpipe->color_slot[idx] = (int)vinfo->num_attribs;
+ }
+ if (tgsi_semantic_name == 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 (tgsi_semantic_name == TGSI_SEMANTIC_VIEWPORT_INDEX) {
+ llvmpipe->viewport_index_slot = (int)vinfo->num_attribs;
+ draw_emit_vertex_attr(vinfo, EMIT_4F, vs_index);
+ } else if (tgsi_semantic_name == 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 an 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);
+ }
+ slot_emitted |= BITFIELD64_BIT(vs_index);
+ tgsi_semantic_index++;
}
}
* ordinary fs register above. But we still need to assign a vs output
* location so draw can inject face info for unfilled tris.
*/
- if (llvmpipe->face_slot < 0 && fsInfo->uses_frontface) {
+ if (llvmpipe->face_slot < 0 &&
+ BITSET_TEST(nir->info.system_values_read, SYSTEM_VALUE_FRONT_FACE)) {
vs_index = draw_find_shader_output(llvmpipe->draw,
TGSI_SEMANTIC_FACE, 0);
llvmpipe->face_slot = (int)vinfo->num_attribs;
llvmpipe->dirty = 0;
}
-