I’m doing depth-stencil clearing using glClearNamedFramebufferfi :
// f is depth ClearValue - 1.0 , s is stencilClearValue - 0x00, fbo is valid, completness-checked framebuffer
if( depthBufferFormat == GpuApi::ETF_Depth24Stencil8 )
{
glClearNamedFramebufferfi( fbo, GL_DEPTH_STENCIL, f, s );
}
What’im getting is : GL_INVALID_VALUE error generated. Invalid draw buffer.
Documentation glClearBuffer - OpenGL 4 Reference Pages desn’t have any drawbuffer argument passed to the function What make thing more interesting is the signature of the function:
Suddenly clearing starts working perfectly fine w/o any error or warning messages. It seems that somehow documentation is wrong and all the WGL stuff follows that wrong doc or I’m missing something.
// Clearing depth and stencil using separate functions works fine.
void ClearNamedFramebufferfi( uint framebuffer, enum buffer, int drawbuffer, float depth, int stencil );
IOW, the “fi” versions have one more parameter than the others; they retain the drawbuffer parameter while having two parameters for the depth and stencil values rather than a single parameter for the value.
/**
* The ClearBuffer framework is so complicated and so riddled with the
* assumption that the framebuffer is bound that, for now, we will just fake
* direct state access clearing for the user.
*/
void GLAPIENTRY
_mesa_ClearNamedFramebufferfi(GLuint framebuffer, GLenum buffer,
GLfloat depth, GLint stencil)
{
GLint oldfb;
_mesa_GetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &oldfb);
_mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
_mesa_ClearBufferfi(buffer, 0, depth, stencil);
_mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, (GLuint) oldfb);
}
Actually does the job. So the signature is wrong, but function hiding under that exact adress expects 5 arguments.
Why is that weird? That’s how function pointers work. The pointer is just an address. And the number of parameters is not encoded in that address. The number of parameters is used by the compiler only to figure out how to communicate with the code at that address. How to encode parameters in registers/on the stack, how to receive parameters, etc.
That’s why it’s so important when dealing with DLLs to always cast pointers to the exact correct function type. Because there’s no safety net if you get it wrong; nobody can know what was actually intended.
I’m not talking about how function works, but that the driver side code expects 5 arguments on the stack after the call happens.
But that’s not weird; that’s what the specification says. So that’s what ought to happen.
Then again, I guess it is weird that AMD actually got it right
What’s much weirder is that… this bug in the XML files (the source of which is probably the ARB_direct_state_access extension specification) has been around for over a year, since the release of ARB_DSA and OpenGL 4.5. This was long enough for it to propagate into MESA. Literally every OpenGL loading library incorporates this mistake.
Yet you’re the first person who actually noticed it.