I may be able to help you there.
First, ignoring layered rendering (and SAMPLE_SHADING, where the frag shader runs per sample), your frag shader runs per pixel, right? This explains why the GL spec says, regarding rendering to textures/rbuffers of different sizes via FBO:
Given this, it would seem that your render targets at least have to have the same resolution, in pixels, assuming you don’t just want some unused pixels off off on the sides. Your frag shader runs per pixel, outputting per-pixel values for each render target.
So let’s consider the lowest res you’d like any G-buffer channel to have to be the resolution in pixels that “all” of them have.
How’s that help? Consider this:
Suppose the res you want for your “higher-res” G-buffer channels is 2x2 greater than the “lower-res”. Ok, so allocate each and every G-buffer channel as 4x MSAA textures with a pixel res that’s the “lower-res” resolution. Now rasterize your scene into the N-channel 4xMSAA G-buffer.
And right now you’re thinkin’, "Whoah! dude! I told you I wanted to “save” bandwidth, not flush it down the toilet.
Well, I can tell you it’s surprisingly (and as some folks have said, “disturbingly”) cheap to rasterize a G-buffer with MSAA vs. with no AA. I don’t know half the special sauce the vendors use to make this so, but (to your bandwidth point) there’s this thing called MSAA bandwidth compression which from what I gather has become pretty standard in GPU tech for some time. If you’re rasterizing a pixel where all the subsamples get the same value (e.g. triangle interior – the typically case for most pixels with the frag shader running per-pixel), then only one sample’s worth of data needs to get shipped to GPU memory (even though there may be 4, 8, or 16 samples in that pixel). So you end up with roughly the same bandwidth cost for these pixels as for 1xAA. Except maybe for the depth buffer, which I’m not clear about. Anyway, it’s cheap.
So that addresses your rasterization bandwidth savings. What about readback bandwidth?
Well the nice thing is you have “total” control there. If you only want to read buffer A once per pixel, you can just grab one of the samples in each pixel via:
texelFetch( tex, texcoord, sample_num )
If you want to read buffer B once per sample, then grab all the samples (same method). If you want to read buffer C once for every 2x2 block of pixels, feel free. It’s totally up to you. If you want to prefilter a buffer down 2x2 res or 4x4 after rasterizing before readback, by all means, go for it!