2

So, here's the problem. I have got an FBO with 8 render buffers which I use in my deferred rendering pipeline. Then I added another render buffer and now I get a GLError.

GLError(
err = 1282,
description = b'invalid operation',
baseOperation = glFramebufferTexture2D,
cArguments = (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT8, GL_TEXTURE_2D, 12, 0,)

The code should be fine, since I have just copied it from the previously used render buffer.

glMyRenderBuffer = glGenTextures(1)
glBindTexture(GL_TEXTURE_2D, glMyRenderBuffer)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, self.width, self.height, 0, GL_RGB, GL_FLOAT, None)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST)
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT8, GL_TEXTURE_2D, glMyRenderBuffer, 0)
glGenerateMipmap(GL_TEXTURE_2D)

And I get the error at this line

glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT8, GL_TEXTURE_2D, glMyRenderBuffer, 0)

It looks more like some kind of OpenGL limitation that I don't know about.

And I also have got a weird stack - Linux + GLFW + PyOpenGL which may also cause this problem.

I would be glad to any advice at this point.

Denis
  • 719
  • 2
  • 8
  • 23

1 Answers1

4

It looks more like some kind of OpenGL limitation that I don't know about.

The relevant limit is GL_MAX_COLOR_ATTACHMENTS and the spec guarantees that this value is at least 8.

Now needing more than 8 render targets in a single pass seems insane anyway.

Consider the following things:

  • try to reduce the number of render targets as much as possible, do not store redundant information (such as vertex position) which can easily be calculated on the fly (you only need depth alone, and you usually have a depth attachment anyway)
  • use clever encodings appropriate for the data, i.e. 3xfloat for a normal vector is a huge waste. See for example Survey of Efficient Representations for Independent Unit Vectors
  • coalesce different render targets. i.e if you need one vec3 and 2 vec2 outputs, better use 2 vec4 targets and asiign the 8 values to the 8 channels
  • maybe even use a higher bitdepth formats like RGBA32UI and manually encode different values into a single channel

If you still need more data, you either can do several render passes (basically with n/8 targets for each pass). Another alternative would be to use image load/store or SSBOs in your fragment shader to write the additional data. In your Scenario, using image load/store seems to make most sense, soince you probaly need the resulting data as texture. You also get a relatively good access pattern, since you can basically use gl_FragCoord.xy for adressing the image. However, care must be taken if you have overlapping geometry in one draw call, so that you write to each pixel more than once (that issue is also addressed by the GL_ARB_fragment_shader_interlock extension, but that one is not yet a core feature of OpenGL). However, you might be able to eliminate that scenario completely by using a pre-depth-pass.

derhass
  • 43,833
  • 2
  • 57
  • 78
  • >Now needing more than 8 render targets in a single pass seems insane anyway. It's not really insane. I am doing some scientific visualization with lots of additional data like segmentation and stuff and I am afraid I can't really avoid it. But thanks anyway, I just wanted to be sure that this limitation cannot be avoided. I'll start looking into this kind of optimizations and probably a small rearranging of my pipeline. – Denis Feb 11 '19 at 13:54
  • Well, within the guarantees the GL makes (and the actual HW limits of most GPUs), you can get 8 render targets with 4x32Bit channels at most. If you can't fit your data into those, you need to do several render passes. Building a dynamic system witch would fit `n` render targets into `n/8` passes would not be too hard, the question is more like what performance level is still tolerable for your scenario... – derhass Feb 11 '19 at 16:19
  • I've updated my answer to also mention the alternative of using image load/store. – derhass Feb 11 '19 at 16:27