Advertisement

Weird symptoms when drawing a simple array of points

Started by March 22, 2023 11:34 PM
0 comments, last by irreversible 1 year, 7 months ago

I've been staring this for quite some time now and I'm seriously beginning to think that I'm going insane. I'm sure I'm missing something trivial somewhere, but I'm running out of ideas where to look:

  • I have a vertex shader, which takes a stream of integers (32-bit, I've checked the data and shader inputs a billion times now), which it uses to read from a TBO, which then drives a geometry shader, which in turn can emit a wide gamut of triangle strip configurations.
  • The input integers are not indexed and my test case uses very few (just 4) elements. No stride or offsets are given alongside the attribute pointer. Culling and depth testing are disabled, all output is 2D on the XY plane. OpenGL reports no errors at any point.
  • I'm not seeing the below behavior anywhere else in my code, but neither have I had a chance to test the code on anything other than my AMD 6900XT (drivers up to date)
  • Basically, on the surface of it what happens is that only half of the input primitives are processed (I'm using GL_POINTS) with every second vertex seemingly not appearing in the vertex stage. So, if I draw 4 elements starting at 0, then 0 and 2 are drawn properly; if I start from base 1, then 1 and 3 are drawn.

    I know that for those “missing” vertices something goes through the pipeline because querying GL_PRIMITIVES_GENERATED tells me all expected primitives are actually emitted (e.g. the geometry stage is invoked for all 4 of the input indexes). However, when I try to intercept the missing input points in the vertex shader, then I can verify that the odd indexes do not appear to ever reach it. I'm using a pretty simple test: during a given run check gl_VertexID for a specific value and manually set the read index to a value that I know to be correct. The output is as expected, but only for either even or odd IDs (depending on the base index).
  • A hack that does solve the issue is padding/duplicating the input integer values, calling glDrawArrays with numElements * 2 and dividing gl_VertexID by 2 in the vertex shader. With this twice as many primitives than are supposed to be emitted are reported by the query, but all 4 shapes do appear as expected.

I've gone through the code with a fine tooth comb and at this point the closest thing I can think of is some sort of alignment issue in the input data (which is nevertheless supposed to be tightly packed), but even then this doesn't explain why oddly indexed vertex IDs simply don't seem to show up in the vertex stage or why/how GL still reports that primitives have been processed for the apparently skipped indexes.

I know this is probably something incredibly basic and inane, but I can't seem to find anything on these symptoms online and my brain is slowly shutting down.

My code is spread out across a large codebase, but here are some of the most relevant snippets, in logical order (just in case I'm certifiably blind):

	// Setting up the attrib buffer

	CHECK_GL_ERROR(glBindBuffer(GL_ARRAY_BUFFER, bufHandle));
	// Binding is 1
	CHECK_GL_ERROR(glEnableVertexAttribArray(buf.binding));
	// Resolves to: 1, 1, GL_INT; No stride or offset.	
	CHECK_GL_ERROR(glVertexAttribIPointer(
					buf.binding, buf.buffer->numComponents,
					gl_TranslateDataType(dataType),
					0, 0));



	// Drawing & checking
	
	GLuint query;
	glGenQueries(1, &query);
	glBeginQuery(GL_PRIMITIVES_GENERATED, query);

	// resolves to: GL_POINTS, 0, 4
	auto glPrimType								= gl_TranslatePrimitiveType(primType);
	CHECK_GL_ERROR(glDrawArrays(glPrimType, GLint(baseElement), GLint(numElements)));

	glEndQuery(GL_PRIMITIVES_GENERATED);

	GLuint num_primitives;
	glGetQueryObjectuiv(query, GL_QUERY_RESULT, &num_primitives);

	glDeleteQueries(1, &query);
	
	
	// Vertex shader: just to show that a single input at binding 1 is indeed expected 
	
	layout(location = 1) in int							in_tboVec4Offset;

This topic is closed to new replies.

Advertisement