[Solved] glMultiDrawElementsIndirect fails, only on one GPU

On one of my Nvidia machines, using glMultiDrawElementsIndirect is producing an INVALID_OPERATION error. I do not believe any of the conditions listed in the documentation that would cause this error are present, as both cards are running the same code.

Here is a test application:
removed

This configuration causes an INVALID_OPERATION error:

  • GPU: GEForce 1660 ti (Dell G7 laptop)
  • Driver: 551.61 (from nvidia.com)
  • OS: Windows 11 64-bit
  • OpenGL version: 4.6

This configuration does not produce any error:

  • GPU: GEForce 1080 GTX ti
  • Driver: 551.61
  • OS: Windows 10 64-bit
  • OpenGL version: 4.6

The Windows 10 machine also works fine with an AMD 6600.

The error occurs after the draw call:

Assert(glGetInteger(GL_DRAW_INDIRECT_BUFFER_BINDING) != 0);
Assert(glGetInteger(GL_ELEMENT_ARRAY_BUFFER_BINDING) != 0);
glMultiDrawElementsIndirect(pmode, GL_UNSIGNED_INT, (void*)(shaderbatch.drawOffset * stride), shaderbatch.drawCount, stride);

stride is equal to 20, the size of the indirect draw structure:

struct DrawElementsIndirectCommand 
{
	uint32_t  count;
	uint32_t  instanceCount;
	uint32_t  firstIndex;
	int32_t  baseVertex;
	uint32_t  baseInstance;
};

Note that we make use of the indirect function argument, as an offset into the DRAW_INDIRECT buffer. It’s probably more common to just supply NULL to this argument, so perhaps something got overlooked there in the driver implementation.

Result

  • The application will display some “Failed to load…” messages, which you can ignore.
  • On the 1660, invalid operation errors will be continuously printed to the console, and the box will not be rendered.
  • On the 1080, a spinning blue box will appear and no OpenGL errors will be printed.

According to the OpenGL 4.6 spec, INVALID_OPERATION errors can occur when:

  • An INVALID_OPERATION error is generated if no element array buffer is
    bound.
  • An INVALID_OPERATION error is generated if the command would
    source data beyond the end of the buffer object.
  • An INVALID_VALUE error is generated if indirect is not a multiple of the
    size, in basic machine units, of uint.

This should be sufficient to demonstrate those cases are not occuring:

#ifdef _DEBUG
Assert(glGetInteger(GL_DRAW_INDIRECT_BUFFER_BINDING) != 0);
Assert(glGetInteger(GL_ELEMENT_ARRAY_BUFFER_BINDING) != 0);
int bufsz;
glGetBufferParameteriv(GL_DRAW_INDIRECT_BUFFER, GL_BUFFER_SIZE, &bufsz);
Assert((shaderbatch.drawOffset + shaderbatch.drawCount) * stride <= bufsz);
Assert((shaderbatch.drawOffset* stride) % 4 == 0);
#endif

Hi user50703, welcome back to the developer forums.

I suppose the Dell laptop is Intel based, correct?

Can you make 100% sure that the laptop is not using the Windows/intel based OpenGL implementation instead of the NVIDIA driver based? Sometimes this has caused issues.

I will pass your report on to the driver team, hopefully they can clear this up.

Thanks!

Wow, it was actually using the integrated Intel graphics. I switched it to prefer the discrete NVidia GPU and now it’s fine.

Sorry about that, I am coming from Vulkan and forgot some of the specifics of OpenGL development.

1 Like

No worries! Great that you could solve this!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.