VAO DSA format and divisor state after glVertexArrayVertexBuffer
Closed this issue · 4 comments
Description
- I have DSA VAO usage code that renders fine outside RenderDoc, but RenderDoc has trouble displaying it correctly.
- I believe that a call to
glVertexArrayVertexBuffer
incorrectly clears the state set byglVertexArrayAttribFormat
andglVertexArrayBindingDivisor
. - Neither the driver nor RenderDoc report incorrect API/buffer usage.
This is captured in bug_1.rdc
(frame 1), which shows that format and divisor state is reset compared to bug_0.rdc
(frame 0). Captures: vaodsabug.zip
I can workaround this by setting the state again after calling glVertexArrayVertexBuffer
. This is shown in workaround_[0,1].rdc
. From examples I've seen this should be unnecessary though.
Steps to reproduce
Command lists from the captures: vaodsabug.zip
Code for reference
// init
gl.createVertexArrays(1, &vao);
gl.enableVertexArrayAttrib(vao, 0);
gl.vertexArrayAttribFormat(vao, 0, 2, gl.FLOAT, gl.FALSE, 0);
gl.vertexArrayAttribBinding(vao, 0, 0);
gl.vertexArrayBindingDivisor(vao, 0, 1);
gl.enableVertexArrayAttrib(vao, 1);
gl.vertexArrayAttribFormat(vao, 1, 4, gl.FLOAT, gl.FALSE, 0);
gl.vertexArrayAttribBinding(vao, 1, 1);
gl.vertexArrayBindingDivisor(vao, 1, 1);
gl.enableVertexArrayAttrib(vao, 2);
gl.vertexArrayAttribFormat(vao, 2, 4, gl.UNSIGNED_BYTE, gl.TRUE, 0);
gl.vertexArrayAttribBinding(vao, 2, 2);
gl.vertexArrayBindingDivisor(vao, 2, 1);
gl.createBuffers(3, &vbo);
gl.vertexArrayVertexBuffer(vao, 0, vbo[0], 0, @sizeOf(Position));
gl.vertexArrayVertexBuffer(vao, 1, vbo[1], 0, @sizeOf([4]f32));
gl.vertexArrayVertexBuffer(vao, 2, vbo[2], 0, @sizeOf(Color));
// draw
gl.namedBufferData(vbo[0], count * @sizeOf(Position), positions.ptr, gl.STATIC_DRAW);
gl.namedBufferData(vbo[1], count * @sizeOf([4]f32), src_rect_buffer.ptr, gl.STATIC_DRAW);
gl.namedBufferData(vbo[2], count * @sizeOf(Color), tints.ptr, gl.STATIC_DRAW);
gl.bindVertexArray(vao);
gl.vertexArrayVertexBuffer(vao, 0, vbo[0], 0, @sizeOf(Position));
gl.vertexArrayVertexBuffer(vao, 1, vbo[1], 0, @sizeOf([4]f32));
gl.vertexArrayVertexBuffer(vao, 2, vbo[2], 0, @sizeOf(Color));
{
// RenderDoc workaround
gl.vertexArrayAttribFormat(vao, 0, 2, gl.FLOAT, gl.FALSE, 0);
gl.vertexArrayAttribFormat(vao, 1, 4, gl.FLOAT, gl.FALSE, 0);
gl.vertexArrayAttribFormat(vao, 2, 4, gl.UNSIGNED_BYTE, gl.TRUE, 0);
gl.vertexArrayBindingDivisor(vao, 0, 1);
gl.vertexArrayBindingDivisor(vao, 1, 1);
gl.vertexArrayBindingDivisor(vao, 2, 1);
}
gl.drawArraysInstanced(gl.TRIANGLE_STRIP, 0, 4, count);
Environment
- RenderDoc version: 1.3.0
- Operating System: Windows 10
- Graphics API: OpenGL 4.5 core
- GPU: AMD Radeon RX 570
- Driver version: 31.0.12027.9001
This looks to be a problem at capture time as the format
and divisor
data is not correct in the capture.
I have recreated the scenario in a test project, however that test project is working for me.
There must be something else or something different in your test project that is required to recreate the problem.
If possible can you supply a reproduction project (an executable or source code would be perfect)
I have it reproduced in your demos framework:
jbarthelmes@cb3a985 [edit: fixed a translation error]
The driver accepts this and renders frames 1+, but renderdoc replay doesn't without the workaround.
Thank you for the reproduction case using the RenderDoc test framework.
The test is working locally : tested on AMD, nVidia on Windows and nVidia on Linux.
Perhaps it is an AMD driver bug, your AMD driver looks to be about one year old.
I have included example local captures for comparison
GL_VAO_DSA_NVIDIA_FRAME_0.zip
GL_VAO_DSA_NVIDIA_FRAME_1.zip
As you said it seems to occur at capture time and with an old driver.