[Fix, Test] (GLImpl, GLState): answer GL_ACTIVE_ATOMIC_COUNTER_BUFFERS and implement glGetActiveAtomicCounterBufferiv

This commit is contained in:
2026-08-20 11:23:33 -04:00
parent 6159166d38
commit a9fb7ef0af
7 changed files with 140 additions and 8 deletions
@@ -716,6 +716,68 @@ void main() {
EXPECT_EQ(TakeError(), GL_INVALID_ENUM);
}
// glGetProgramiv(GL_ACTIVE_ATOMIC_COUNTER_BUFFERS) and glGetActiveAtomicCounterBufferiv are
// the pre-4.3 spelling of the interface above, and the spec requires the two to agree.
// Neither did: the first counted glslang's atomic counter UNIFORMS - zero, because the
// relaxed parse folds every atomic_uint into a storage block before reflection runs - and
// the second was a stub that wrote nothing and raised nothing.
TEST_F(ProgramInterfaceTest, ActiveAtomicCounterBufferQueriesMatchTheInterface) {
const char* fs = R"(#version 430
out vec4 color;
layout (binding = 1, offset = 0) uniform atomic_uint a;
layout (binding = 2, offset = 0) uniform atomic_uint b;
layout (binding = 2, offset = 4) uniform atomic_uint c;
void main() {
color = vec4(float(atomicCounterIncrement(a) + atomicCounterIncrement(b) + atomicCounterIncrement(c)));
}
)";
const GLuint p = MakeProgram(kSimpleVs, fs);
LinkProgram(p);
ExpectLinked(p);
ClearErrors();
GLint bufferCount = -12345;
GetProgramiv(p, GL_ACTIVE_ATOMIC_COUNTER_BUFFERS, &bufferCount);
EXPECT_EQ(bufferCount, Interfaceiv(p, GL_ATOMIC_COUNTER_BUFFER, GL_ACTIVE_RESOURCES));
ASSERT_EQ(bufferCount, 2);
const auto activeBufferiv = [p](GLuint index, GLenum pname) {
GLint value = -12345;
GetActiveAtomicCounterBufferiv(p, index, pname, &value);
return value;
};
for (GLuint index = 0; index < static_cast<GLuint>(bufferCount); ++index) {
const std::vector<GLint> viaInterface =
Props(p, GL_ATOMIC_COUNTER_BUFFER, index,
{GL_BUFFER_BINDING, GL_BUFFER_DATA_SIZE, GL_NUM_ACTIVE_VARIABLES,
GL_REFERENCED_BY_VERTEX_SHADER, GL_REFERENCED_BY_FRAGMENT_SHADER});
ASSERT_EQ(viaInterface.size(), 5u);
EXPECT_EQ(activeBufferiv(index, GL_ATOMIC_COUNTER_BUFFER_BINDING), viaInterface[0]);
EXPECT_EQ(activeBufferiv(index, GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE), viaInterface[1]);
EXPECT_EQ(activeBufferiv(index, GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS), viaInterface[2]);
EXPECT_EQ(activeBufferiv(index, GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER), viaInterface[3]);
EXPECT_EQ(activeBufferiv(index, GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER), viaInterface[4]);
// The counter indices are the GL_UNIFORM indices, in the same order.
const std::vector<GLint> expectedIndices = Props(p, GL_ATOMIC_COUNTER_BUFFER, index, {GL_ACTIVE_VARIABLES});
ASSERT_FALSE(expectedIndices.empty());
std::vector<GLint> indices(expectedIndices.size(), -12345);
GetActiveAtomicCounterBufferiv(p, index, GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES,
indices.data());
EXPECT_EQ(indices, expectedIndices);
}
EXPECT_EQ(TakeError(), GL_NO_ERROR);
GLint sink = -12345;
GetActiveAtomicCounterBufferiv(p, static_cast<GLuint>(bufferCount), GL_ATOMIC_COUNTER_BUFFER_BINDING, &sink);
EXPECT_EQ(TakeError(), GL_INVALID_VALUE);
EXPECT_EQ(sink, -12345) << "a rejected query must not write the caller's output";
// The interface-query spelling of the same property is NOT accepted here.
GetActiveAtomicCounterBufferiv(p, 0, GL_BUFFER_BINDING, &sink);
EXPECT_EQ(TakeError(), GL_INVALID_ENUM);
EXPECT_EQ(sink, -12345);
}
// --------------------------------------------------------- transform-feedback ------
TEST_F(ProgramInterfaceTest, TransformFeedbackVaryingTypes) {
const char* vs = R"(#version 430