Collision filtering confusion

I’m confused trying to set up a 2.8.x style collision group system.

It says in the manual that collision groups are gone, and provides an example where you simply have to put the group int in filterData.word0.
I also noticed PxDefaultSimulationFilterShader.h theres a system already setup, not mentioned in the manual, with handy looking functions like PxSetGroup(PxActor& actor, const PxU16 collisionGroup);

However, all the scene queries and raycasts use the internal fixed-function applyFilterEquation() to filter the results, which just does:
const PxU32 keep = (queryFd.word0 & objFd.word0) | (queryFd.word1 & objFd.word1) | (queryFd.word2 & objFd.word2) | (queryFd.word3 & objFd.word3);

But that’s obviously assuming that the .word0 is a bitmask of the collision group, not a straight int.
So it seems that scene queries and collision filtering are both using the FilterData in different, incompatible ways?

There are separate filter data for both the simulation (what you need to replicate the 2.8 groups) and the scene queries.

See PxShape:

virtual void setSimulationFilterData(const PxFilterData& data) = 0;
virtual void setQueryFilterData(const PxFilterData& data) = 0;