io.spi_sid = 0;
       break;
    case TGSI_SEMANTIC_GENERIC:
+   case TGSI_SEMANTIC_TEXCOORD:
+   case TGSI_SEMANTIC_PCOORD:
       io.spi_sid = io.sid + 1;
       break;
    default:
 
            << " interpolation:" << input->data.interpolation
            << "\n";
 
-   unsigned name, sid;
-
    if (input->data.location == VARYING_SLOT_FACE) {
       m_sv_values.set(es_face);
       return true;
    }
 
-   tgsi_get_gl_varying_semantic(static_cast<gl_varying_slot>(input->data.location),
-                                true, &name, &sid);
-
-   /* Work around the mixed tgsi/nir semantic problems, this fixes
-    * dEQP-GLES2.functional.shaders.builtin_variable.pointcoord */
-   if (input->data.location == VARYING_SLOT_PNTC) {
-      name = TGSI_SEMANTIC_GENERIC;
-      sid = 8;
-   }
+   unsigned name, sid;
+   auto semantic = r600_get_varying_semantic(input->data.location);
+   name = semantic.first;
+   sid = semantic.second;
 
    tgsi_semantic sname = static_cast<tgsi_semantic>(name);
 
 
  * USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
 
-#include "tgsi/tgsi_from_mesa.h"
 #include "sfn_shader_geometry.h"
 #include "sfn_instruction_misc.h"
 #include "sfn_instruction_fetch.h"
+#include "sfn_shaderio.h"
 
 namespace r600 {
 
        input->data.location <= VARYING_SLOT_TEX7)) {
 
       r600_shader_io& io = sh_info().input[input->data.driver_location];
-      tgsi_get_gl_varying_semantic(static_cast<gl_varying_slot>( input->data.location),
-                                   true, &io.name, &io.sid);
+      auto semantic = r600_get_varying_semantic(input->data.location);
+      io.name = semantic.first;
+      io.sid = semantic.second;
+
       io.ring_offset = 16 * input->data.driver_location;
       ++sh_info().ninput;
       m_next_input_ring_offset += 16;
        output->data.location == VARYING_SLOT_FOGC) {
       r600_shader_io& io = sh_info().output[output->data.driver_location];
 
-      tgsi_get_gl_varying_semantic(static_cast<gl_varying_slot>( output->data.location),
-                                   true, &io.name, &io.sid);
+      auto semantic = r600_get_varying_semantic(output->data.location);
+      io.name = semantic.first;
+      io.sid = semantic.second;
+
       evaluate_spi_sid(io);
       ++sh_info().noutput;
 
 
       assert(0 && "System value used as varying");
       break;
    case TGSI_SEMANTIC_GENERIC:
+   case TGSI_SEMANTIC_TEXCOORD:
+   case TGSI_SEMANTIC_PCOORD:
       m_spi_sid = m_sid + 1;
       break;
    default:
    m_two_sided = true;
 }
 
+std::pair<unsigned, unsigned>
+r600_get_varying_semantic(unsigned varying_location)
+{
+   std::pair<unsigned, unsigned> result;
+   tgsi_get_gl_varying_semantic(static_cast<gl_varying_slot>(varying_location),
+                                true, &result.first, &result.second);
+
+   if (result.first == TGSI_SEMANTIC_GENERIC) {
+      result.second += 9;
+   } else if (result.first == TGSI_SEMANTIC_PCOORD) {
+      result.second = 8;
+   }
+   return result;
+}
+
+
+
 }
 
 
 
 };
 
+std::pair<unsigned, unsigned>
+r600_get_varying_semantic(unsigned varying_location);
+
+
 }
 
-#endif // SFN_SHADERIO_H
\ No newline at end of file
+#endif // SFN_SHADERIO_H
 
 #include "sfn_vertexstageexport.h"
 
-#include "tgsi/tgsi_from_mesa.h"
+#include "sfn_shaderio.h"
 
 namespace r600 {
 
        ) {
 
       r600_shader_io& io = m_proc.sh_info().output[output->data.driver_location];
-      tgsi_get_gl_varying_semantic(static_cast<gl_varying_slot>( output->data.location),
-                                   true, &io.name, &io.sid);
+      auto semantic = r600_get_varying_semantic(output->data.location);
+      io.name = semantic.first;
+      io.sid = semantic.second;
 
       m_proc.evaluate_spi_sid(io);
       io.write_mask = ((1 << glsl_get_components(output->type)) - 1)