Ok - I'll answer my own question.
The answer is that QGL in Qt 4.8 does not support profiles above compatibility 2.1.
To do so requires hacking the file qgl_mac.mm and adding NSOpenGLPFAOpenGLProfile and NSOpenGLProfileVersion3_2Core to the NSOpenGLPixelFormatAttributes structures used.
Don't treat the following diff as a complete solution - it will break any old style OpenGL on mac:
diff --git a/build/packages/qt-everywhere-opensource-src-4.8.6/src/opengl/qgl_mac.mm b/build/packages/qt-everywhere-opensource-src-4.8.6/src/opengl/qgl_mac.mm
index 4ecf888..52b24ed 100644
--- a/build/packages/qt-everywhere-opensource-src-4.8.6/src/opengl/qgl_mac.mm
+++ b/build/packages/qt-everywhere-opensource-src-4.8.6/src/opengl/qgl_mac.mm
@@ -148,7 +148,11 @@ QGLTemporaryContext::QGLTemporaryContext(bool, QWidget *)
aglDestroyPixelFormat(fmt);
#else
QMacCocoaAutoReleasePool pool;
NSOpenGLPixelFormatAttribute attribs[] = { 0 };
NSOpenGLPixelFormatAttribute attribs[] = {
NSOpenGLPFAOpenGLProfile,
NSOpenGLProfileVersion3_2Core,
0
};
NSOpenGLPixelFormat *fmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];
if (!fmt) {
qWarning("QGLTemporaryContext: Cannot find any visuals");
@@ -350,7 +354,7 @@ bool QGLContext::chooseContext(const QGLContext *shareContext)
void *QGLContextPrivate::tryFormat(const QGLFormat &format)
{
static const int Max = 40;
static const int Max = 42;
#ifndef QT_MAC_USE_COCOA
GLint attribs[Max], cnt = 0;
bool device_is_pixmap = (paintDevice->devType() == QInternal::Pixmap);
@@ -464,6 +468,10 @@ void *QGLContextPrivate::tryFormat(const QGLFormat &format)
if (devType == QInternal::Pbuffer)
attribs[cnt++] = NSOpenGLPFAPixelBuffer;
attribs[cnt++] = NSOpenGLPFAOpenGLProfile;
attribs[cnt++] = NSOpenGLProfileVersion3_2Core;
attribs[cnt] = 0;
Q_ASSERT(cnt < Max);
return [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];