Need help with geometry shader

This is why we write documentation, particularly for naming things


Expecting people to search through large, multi-file codebases to even understand the nature of what the code is even trying to achieve (let alone what the problem is and how OpenGL is involved with it) is not reasonable.

In general language usage, those words may mean what you’re talking about. But within the specific context of rendering APIs and their functionality, those words have very specific definitions.

As previously stated, it would be very helpful for your understanding of things if you stop trying to impose your meanings and expectations on things. Spend less time telling experienced people they’re wrong and spend more time trying to understand what things actually mean to these APIs.

You can choose to rage against those definitions all you like, but all it will be is screaming into a tornado. Nobody will understand you, everyone will think you’re crazy, and you’ll eventually be whisked off to the Land of Oz.

Then go write a graphics driver. Because that’s the only place where you’re are going to get that kind of freedom.

No graphics API has ever promised to let you try anything, to expose the exact, precise details of the underlying hardware. All of them abstract away these differences into specific patterns and impose limitations on those patterns in accord with that abstraction. That is the nature of the beast.

If you direct, unfiltered access to the GPU, then you need to bypass these APIs and write specific drivers for specific GPUs. Good luck with that.

And good luck getting OS’s to let you. And good luck getting NVIDIA to give you the detailed specs to their GPUs that you’d need to do it.

As previously stated, your expectations are simply unreasonable.

But there are compiler limitations. Compilers are based on abstractions of hardware. Hardware can have more features than compilers expose.

For example in assembly, you can do tricks like changing the stack address for the return pointer, thus allowing a single conceptual “return” instruction to return several layers in the stack.

C and C++ do not let you do this. The hardware can do it, but you cannot. And yes, at the advent of C and languages of similar abstractions, some people did create an “uproar”.

But in the end, C won out over the uproar. Because the cross-platform compatibility and structured programming model of C was far easier to use than writing code for specific pieces of hardware. And also because C compilers could get smart enough to make use of such functionality automatically (see tail recursion). So you didn’t even have to give up the performance benefits in quite a few cases.

What gets to be a “RUNTIME/HARDWARE issue” is a matter for the abstraction to decide. You can either use the abstraction or go write your own compiler.

There was no way I was going to find that with ease, besides who in their right mind would expect to need to look for the explanation of a structure rather than the symbols using said structure? Theres’s no reason I would even think to look for documentation on finding uniforms because I thought it was a syntax issue like any normal developer would think when they’re new to glsl, had it not been for the example I found at stack overflow I would not have ever thought to look for the name of the structure instead of the symbol using the structure, it’s counter-intuitive because the symbol holds the data, the structure just describes the interface for said data, I would obviously look for the symbol so I could set the data it points to, not the structure describing it, there’s no reason I would ever have suspected I couldn’t find the location simply opengl expected me to look for the description hence why I didn’t look for documentation for that and instead looked for documentation on the syntax, basically I was lead on a wild goose chase because of an api that wasn’t designed around human nature but around idealistic nature.

Edit: Forgot to add thx for the links

Not really, there’s a search box on both github & gitlab, it only took typing in a few letters and then looking for the result that describes the object to tell you SRC had nothing to do with the usage of opengl specifically, at that point you would likely have started ignoring it as a detail of the general APIs I was using, there’s also the factor I was clearly passing pointers to pointers in the function you mentioned (I think it was MakeVfxVar() which was even named appropriately enough that you coulda put 2 & 2 together and realised it had probably something to do with allocations (which it does) since the function didn’t except any other details that would be needed for opengl interactions.

a point & vertex are just descriptions of positions, in shaders that happen to take on a bit more than just the position in their descriptions but they are still just descriptions of those positions, they are NOT particles, particles have substance, they have size, points & vertices never have sizes, they are used with sizes to create particles & objects, but never do they actually have a size of their own, this is why I say you’re confusing the two.

I’ll certainly try later if I find time since all I need is to know what instructions the driver takes, if it happens to be an old one that only accepts code then it’s just a matter of querying the abilities of said code then spitting errors when valid syntax is unsupported by the target driver, but again that’s a runtime issue, it’s never the place of the shader language to decide that for the developer.

The only reason it’s not yet part of C is because there’s neither any syntax for it, nor enough demand, possibly not even a use case scenario (I’m curious on that one but not enough to go looking for it), GLSL on the other hand can easily add syntax for triangle_fan etc, whether the hardware supports it is always going to be a runtime issue, opengl should still support it at the glsl level, once it’s compiled into instructions it can be passed onto the gpu driver to verify if the hardware supports the desired actions, a language can do anything, a shader compiler has no place deciding what the hardware can or can’t do, it can & should query the limits sure, but that’s different from saying “I don’t care what the hardware in use might be able to to do, I’m gonna refuse this just because old hardware was not able to do it”, not even the C committee restrain syntax & APIs just because some old cpu doesn’t support the instructions, they leave that issue to compilers to sort out, if the hardware being compiled for doesn’t support it then sure the compiler would stop at that point if happens to know, in the case of shader compilers they just need to query what instruction set the driver takes to find what syntax is supported, but again that is a runtime issue, not a syntax issue, limiting the syntax for the sake of old or current hardware is putting the cart before the horse, why would gpu manufacturers be inclined to support something that current syntax does not allow anyways? The syntax should valid, always, if the hardware doesn’t support what the code supports then it will be identified at runtime, assuming it doesn’t is like saying all white people are racist, it’s prejudice and has no place in shader language.

after finally working up the motivation to continue programming and fixing a few bugs here and there I’ve now run into a strange situation where the program supposedly links fine but doesn’t link simultaneously, I’ll edit this post with a link to the uploaded shaders in a moment (gotta actually upload them after all) but for now here’s the log:

make debug=1 run
...
cd bin && ./d-check_extra.elf
Attempting to open 'libd-extraglfw.so' & 'libd-extragl.so'
Creating program '[vfxapp.flat]'
Bound shader 'shaders/null.glsl' as point shader
Bound shader 'shaders/flat.glsl' as basic shader
Bound shader 'shaders/frag.glsl' as color shader
Linking program...
source = GL_DEBUG_SOURCE_SHADER_COMPILER, fromid = 1 (GL_ID_UNKOWN), report = Shader Stats: SGPRS: 16 VGPRS: 4 Code Size: 4 LDS: 0 Scratch: 0 Max Waves: 8 Spilled SGPRs: 0 Spilled VGPRs: 0 PrivMem VGPRs: 0
Testing program...
test/extra/create.c:113: 'uints' not found
test/extra/create.c:113: 'dnums' not found
source = GL_DEBUG_SOURCE_API, defect = GL_DEBUG_TYPE_ERROR, weight = GL_DEBUG_SEVERITY_HIGH, fromid = 2 (GL_ID_UNKOWN)
report = GL_INVALID_OPERATION in glUniform(program not linked)
source = GL_DEBUG_SOURCE_API, defect = GL_DEBUG_TYPE_ERROR, weight = GL_DEBUG_SEVERITY_HIGH, fromid = 2 (GL_ID_UNKOWN)
report = GL_INVALID_OPERATION in glUniform(program not linked)
source = GL_DEBUG_SOURCE_API, defect = GL_DEBUG_TYPE_ERROR, weight = GL_DEBUG_SEVERITY_HIGH, fromid = 2 (GL_ID_UNKOWN)
report = GL_INVALID_OPERATION in glUniform(program not linked)
source = GL_DEBUG_SOURCE_API, defect = GL_DEBUG_TYPE_ERROR, weight = GL_DEBUG_SEVERITY_HIGH, fromid = 2 (GL_ID_UNKOWN)
report = GL_INVALID_OPERATION in glUniform(program not linked)
source = GL_DEBUG_SOURCE_SHADER_COMPILER, fromid = 1 (GL_ID_UNKOWN), report = Shader Stats: SGPRS: 16 VGPRS: 24 Code Size: 136 LDS: 0 Scratch: 0 Max Waves: 8 Spilled SGPRs: 0 Spilled VGPRs: 0 PrivMem VGPRs: 0
source = GL_DEBUG_SOURCE_SHADER_COMPILER, fromid = 1 (GL_ID_UNKOWN), report = Shader Stats: SGPRS: 64 VGPRS: 12 Code Size: 2408 LDS: 0 Scratch: 0 Max Waves: 8 Spilled SGPRs: 0 Spilled VGPRs: 0 PrivMem VGPRs: 0
source = GL_DEBUG_SOURCE_SHADER_COMPILER, fromid = 1 (GL_ID_UNKOWN), report = Shader Stats: SGPRS: 24 VGPRS: 8 Code Size: 152 LDS: 0 Scratch: 0 Max Waves: 8 Spilled SGPRs: 0 Spilled VGPRs: 0 PrivMem VGPRs: 0
source = GL_DEBUG_SOURCE_API, defect = GL_DEBUG_TYPE_ERROR, weight = GL_DEBUG_SEVERITY_HIGH, fromid = 2 (GL_ID_UNKOWN)
report = GL_INVALID_OPERATION in glUniform(count = 14 for non-array "DINTS.WinPoint"@1)
source = GL_DEBUG_SOURCE_API, defect = GL_DEBUG_TYPE_ERROR, weight = GL_DEBUG_SEVERITY_HIGH, fromid = 2 (GL_ID_UNKOWN)
report = GL_INVALID_OPERATION in glDrawArrays
...
source = GL_DEBUG_SOURCE_API, defect = GL_DEBUG_TYPE_ERROR, weight = GL_DEBUG_SEVERITY_HIGH, fromid = 2 (GL_ID_UNKOWN)
report = GL_INVALID_OPERATION in glUniform(count = 15 for non-array "DINTS.WinSpace"@0)
source = GL_DEBUG_SOURCE_API, defect = GL_DEBUG_TYPE_ERROR, weight = GL_DEBUG_SEVERITY_HIGH, fromid = 2 (GL_ID_UNKOWN)
report = GL_INVALID_OPERATION in glDrawArrays
Compilation finished successfully.

Edit: Alright, here’s the link:

Edit 2: I should also mention the set of shaders loaded is defined in vfxapps.ini, just look for the matching group to the one mentioned in the log

Edit 3: Although you can easily find this information in src/extra/viewfx/opengl the structures I’m using in code basically serve these purposes in code for opengl:

VFXWIN > glfw
VFXAPP > gl*Program
SHADER > gl*Shader
VFXCFG > gl*VertexArray
VFXBUF > gl*Buffer
VFXVAR > glUniform*/glVertexAttribPointer/etc

Essentially since opengl apparantly has more “concepts” built into it’s api I’m wrapping around it first and the others should be easier to plug in than if I did it the other way around, wrapping vulkan etc first

Finally occurred to me that I might need to call glUseProgram() earlier than the uniform calls, did that and the “program not linked” messages went away, still having the other errors though:

make debug=1 run
...
cd bin && ./d-check_extraelf
Attempting to open 'libd-vfxglfw.so' & 'libd-vfxgl.so'
Creating program '[vfxapp.flat]'
Bound shader 'shaders/null.glsl' as point shader
Bound shader 'shaders/flat.glsl' as basic shader
Bound shader 'shaders/frag.glsl' as color shader
Linking program...
Testing program...
test/extra/create.c:113: 'UINTS' not found
test/extra/create.c:113: 'DNUMS' not found
source = GL_DEBUG_SOURCE_API, defect = GL_DEBUG_TYPE_ERROR, weight = GL_DEBUG_SEVERITY_HIGH, fromid = 1 (GL_ID_UNKOWN)
report = GL_INVALID_OPERATION in glUniform(count = 14 for non-array "DINTS.WinPoint"@1)
source = GL_DEBUG_SOURCE_API, defect = GL_DEBUG_TYPE_ERROR, weight = GL_DEBUG_SEVERITY_HIGH, fromid = 1 (GL_ID_UNKOWN)
report = GL_INVALID_OPERATION in glUniform(count = 15 for non-array "DINTS.WinSpace"@0)
source = GL_DEBUG_SOURCE_SHADER_COMPILER, fromid = 2 (GL_ID_UNKOWN), report = Shader Stats: SGPRS: 16 VGPRS: 4 Code Size: 4 LDS: 0 Scratch: 0 Max Waves: 8 Spilled SGPRs: 0 Spilled VGPRs: 0 PrivMem VGPRs: 0
source = GL_DEBUG_SOURCE_SHADER_COMPILER, fromid = 2 (GL_ID_UNKOWN), report = Shader Stats: SGPRS: 16 VGPRS: 24 Code Size: 136 LDS: 0 Scratch: 0 Max Waves: 8 Spilled SGPRs: 0 Spilled VGPRs: 0 PrivMem VGPRs: 0
source = GL_DEBUG_SOURCE_SHADER_COMPILER, fromid = 2 (GL_ID_UNKOWN), report = Shader Stats: SGPRS: 64 VGPRS: 12 Code Size: 2408 LDS: 0 Scratch: 0 Max Waves: 8 Spilled SGPRs: 0 Spilled VGPRs: 0 PrivMem VGPRs: 0
source = GL_DEBUG_SOURCE_SHADER_COMPILER, fromid = 2 (GL_ID_UNKOWN), report = Shader Stats: SGPRS: 24 VGPRS: 8 Code Size: 152 LDS: 0 Scratch: 0 Max Waves: 8 Spilled SGPRs: 0 Spilled VGPRs: 0 PrivMem VGPRs: 0
source = GL_DEBUG_SOURCE_API, defect = GL_DEBUG_TYPE_ERROR, weight = GL_DEBUG_SEVERITY_HIGH, fromid = 1 (GL_ID_UNKOWN)
report = GL_INVALID_OPERATION in glUniform(count = 14 for non-array "DINTS.WinPoint"@1)
source = GL_DEBUG_SOURCE_API, defect = GL_DEBUG_TYPE_ERROR, weight = GL_DEBUG_SEVERITY_HIGH, fromid = 1 (GL_ID_UNKOWN)
report = GL_INVALID_OPERATION in glDrawArrays
source = GL_DEBUG_SOURCE_API, defect = GL_DEBUG_TYPE_ERROR, weight = GL_DEBUG_SEVERITY_HIGH, fromid = 1 (GL_ID_UNKOWN)
report = GL_INVALID_OPERATION in glUniform(count = 15 for non-array "DINTS.WinSpace"@0)
source = GL_DEBUG_SOURCE_API, defect = GL_DEBUG_TYPE_ERROR, weight = GL_DEBUG_SEVERITY_HIGH, fromid = 1 (GL_ID_UNKOWN)
report = GL_INVALID_OPERATION in glDrawArrays
...
source = GL_DEBUG_SOURCE_API, defect = GL_DEBUG_TYPE_ERROR, weight = GL_DEBUG_SEVERITY_HIGH, fromid = 1 (GL_ID_UNKOWN)
report = GL_INVALID_OPERATION in glUniform(count = 14 for non-array "DINTS.WinPoint"@1)
source = GL_DEBUG_SOURCE_API, defect = GL_DEBUG_TYPE_ERROR, weight = GL_DEBUG_SEVERITY_HIGH, fromid = 1 (GL_ID_UNKOWN)
report = GL_INVALID_OPERATION in glDrawArrays
source = GL_DEBUG_SOURCE_API, defect = GL_DEBUG_TYPE_ERROR, weight = GL_DEBUG_SEVERITY_HIGH, fromid = 1 (GL_ID_UNKOWN)
report = GL_INVALID_OPERATION in glUniform(count = 15 for non-array "DINTS.WinSpace"@0)
source = GL_DEBUG_SOURCE_API, defect = GL_DEBUG_TYPE_ERROR, weight = GL_DEBUG_SEVERITY_HIGH, fromid = 1 (GL_ID_UNKOWN)
report = GL_INVALID_OPERATION in glDrawArrays
Compilation finished successfully.

Managed to silence the DINTS related warnings after:

  1. Finally noticing I had accidentally made my C version of the struct a struct instead a union causing the int raw[sizeof(DINTS_STRUCT)/sizeof(int)]; to be recognised as extra ints which was not intended
  2. Moving the single valued members up to the top, didn’t realise opengl was extra picky about the top members being the same size “vectors” as what was sent, seems stupid to me since as long as the total amount of integers is the same and packed together the same then there should be no issues just shoving into the uniform since the uniform amounted to just an array of integers, am I misunderstanding something? or am I misunderstanding the usage of glUniform1iv etc?

Edit: Forgot to ask if there’s any common single valued floats that I can add to the top of my FNUMS structures for silencing the other warnings

glUniform1iv is for uploading to an array of integers (or to a single integer if you pass a count of 1). However much you may feel that “the uniform amounted to just an array of integers,” it is not actually an array of integers. The way you spell “array of integers” like this: int array_of_integers[count];. Unless that’s what the uniform variable looks like, it’s not an “array of integers”.

GLSL is not C. You cannot just pretend that a construct is something you feel is isomorphic with it, then use it as your version of the thing, and expect everything to “work” (you shouldn’t do that in C either, but whatever). When you say that you’re uploading to a variable of some type, OpenGL expects that variable to actually be of the type you say it is. If you say that it is an array of ints, OpenGL will expect the variable to be an actually array that contains actual ints.

Yes, code behaving the way the code actually says it behaves (ie: a struct of integers is not an array of integers) may seem “extra picky” to a C programmer, but that’s standard operating procedure for most other languages.

Also, uniform variables have no memory layout. Uniform blocks do (within the buffer object), but the individual members of a non-block uniform struct variable have no relationship to one another. Even the uniform locations of members of such a struct need not be sequential (unless you explicitly used layout(location = #) to assign a location to the uniform variable).

There are legitimate reasons for doing so in either GLSL or C, here’s an example from C:

typedef union _SHARED_DINTS
{
	dint raw[sizeof(SHARED_DINT_STRUCT)/sizeof(dint)];
	SHARED_DINT_STRUCT mem;
} SHARED_DINTS;
...
for ( i = 0; i < (sizeof(SHARED_DINT_STRUCT)/sizeof(dint)); )
{
	achs name = dint_names[i];
	dint count = dint_counts[i];
	for ( j = 0; j < count; ++j, ++i )
		printf( "%s[%i] = %d", name, j, dints.raw[i] );
}

Not something I’m using at the moment but I plan to use something similar when I start building a gui for managing all this stuff after I’m satisfied I’ve got a decent enough understanding of opengl and have wrapped the api appropriately enough that newbs like myself can develop a slightly more intuitive understanding via the wrapper and looking “under the hood”.

If I can make a union based uniform that can circumvent looking for individual members when passing the data then I’m all ears (or rather eyes since we’re not using voip or whatever).

A structure full of only floats & an array full of only floats, when the same size amount to the same thing as far as bytes are concerned, hence why it should be fine to treat it as such, anything else is being deliberately slow over what amounts to semantics that a machine will never care about (excluding an ai developed to do so), therefore this particular point of yours falls on deaf ears.

Even those languages you speak of always have a means to re-interpret them, it just happens that some require extra steps to do so due the nature of the language (such as being interpreted like in the case of lua or javascript)

Well of course they have a layout, can’t place data in any old place, but your point about “need not be sequential” does explain why I can’t just do it the fastest way, annoying but at least understandable now.

Edit: Quick question, is there any means to locate the offsets of members or am I just gonna have to manually match until I setup something slightly more convenient (in terms of looping, not so much value setting like how I can currently just do dints.mem.WinLimit.x = w; then send of the buffer as is)

That’s called “uniform blocks” (or uniform buffers or UBOs); you upload bytes directly into a buffer object and the shader reads whatever you wrote there in accords with the uniform block definition.

But you decided to stop using them for some reason.

No they don’t. Java, C#, Go, Swift, they don’t let you just pretend one thing is another thing. Even Rust doesn’t let you do it by default.

When I said non-block uniforms have no layout, I meant it: there is no layout. Implementations are permitted the freedom to store uniform variables however it wants. For example, NVIDIA implementations have been known to not have storage for non-block uniforms at all (except for opaque types, which are a separate matter). Instead, when you make a glUniform call, it directly patches the compiled shader binary with the uniform value you provided. That is, “uniforms” are just literals in the binary, and doing glUniform changes the binary appropriately.

Implementations are able to do this because the API does not expose a layout for non-block uniforms.

Every attempt I made to declare the uniform a union ended in failure so that’s why I gave up trying to declare it so, however I’m still using UBOs, that’s what I’m trying to fill the entirety of the structures with, I welcome an example.

There’s always a way, you just gotta dig deep enough to find it.

That’s still a “layout”, it’s just in the binary instead of somewhere in GDDR, anyways I got gospel to go to so I’ll be a while before my next response if you happen to give one prior to me coming back. Also for now I’ve been tweaking my api a bit to sorta recognise uniform structures, at least until I understand where I’m going wrong with the UBOs (can create the buffers fine but declaration & filling of the uniforms themselves that’s issue)