{
                struct ac_ngg_prim prim = {};
 
-               prim.num_vertices = num_vertices;
-               prim.isnull = ctx->ac.i1false;
-               memcpy(prim.index, vtxindex, sizeof(vtxindex[0]) * 3);
-
-               for (unsigned i = 0; i < num_vertices; ++i) {
-                       tmp = LLVMBuildLShr(builder,
-                                           ac_get_arg(&ctx->ac, ctx->args->ac.gs_invocation_id),
-                                           LLVMConstInt(ctx->ac.i32, 8 + i, false), "");
-                       prim.edgeflag[i] = LLVMBuildTrunc(builder, tmp, ctx->ac.i1, "");
+               if (ctx->args->options->key.vs_common_out.as_ngg_passthrough) {
+                       prim.passthrough = ac_get_arg(&ctx->ac, ctx->args->gs_vtx_offset[0]);
+               } else {
+                       prim.num_vertices = num_vertices;
+                       prim.isnull = ctx->ac.i1false;
+                       memcpy(prim.index, vtxindex, sizeof(vtxindex[0]) * 3);
+
+                       for (unsigned i = 0; i < num_vertices; ++i) {
+                               tmp = LLVMBuildLShr(builder,
+                                                   ac_get_arg(&ctx->ac, ctx->args->ac.gs_invocation_id),
+                                                   LLVMConstInt(ctx->ac.i32, 8 + i, false), "");
+                               prim.edgeflag[i] = LLVMBuildTrunc(builder, tmp, ctx->ac.i1, "");
+                       }
                }
 
                ac_build_export_prim(&ctx->ac, &prim);
 
                stages |= S_028B54_PRIMGEN_EN(1);
                if (pipeline->streamout_shader)
                        stages |= S_028B54_NGG_WAVE_ID_EN(1);
+               if (radv_pipeline_has_ngg_passthrough(pipeline))
+                       stages |= S_028B54_PRIMGEN_PASSTHRU_EN(1);
        } else if (radv_pipeline_has_gs(pipeline)) {
                stages |= S_028B54_VS_EN(V_028B54_VS_STAGE_COPY_SHADER);
        }