[CLOSED] Issue with buffer length in glGet*() functions

Started by Hotshot5000, June 21, 2013, 16:07:49

Previous topic - Next topic

Hotshot5000

public static void glGetInteger(int pname, IntBuffer params) {
      ContextCapabilities caps = GLContext.getCapabilities();
      long function_pointer = caps.glGetIntegerv;
      BufferChecks.checkFunctionAddress(function_pointer);
      BufferChecks.checkBuffer(params, 16);
      nglGetIntegerv(pname, MemoryUtil.getAddress(params), function_pointer);
   }

This line:
BufferChecks.checkBuffer(params, 16);

Why does it require the length of the buffer to be 16?

Sometimes the return value needed is only of 4 bytes like here:

Gdx.gl20.glGetIntegerv(GL20.GL_MAX_TEXTURE_IMAGE_UNITS, buffer);

Why should the buffer be of allocateDirect(16)??

I don't know what they did it in android but if it only required 4 bytes in didn't ask for more.

quew8

The error message is pretty definitive "... because at most 16 elements can be returned ...". ( That is from memory - shows how often this has screwed me over )

This is a check LWJGL does and it assumes the maximum size required for any value of pname since otherwise you would have to switch through each and every possible parameter to find the correct size. That would not be efficient, bearing in mind this is a function you could be calling many times each frame.

Hotshot5000

So all the buffers have to be 16 sized? This is horrid design. Yes the switch solution is much better and probably used by Android.

Why would you call it every frame? Keep the state in your program and use get() in Java. No need to call glGet*() and pass through JNI.

spasi

Hello Hotshot5000,

First of all, the buffer is required to have 16 elements for historical reasons. It's been like that since the first LWJGL version and there hasn't been any serious reason/complain to change it. The new LWJGL 3.0 that is currently under development has reduced the requirement to a single element. With that said:

a) There is a alternative GetInteger that returns a simple int and doesn't even require you to pass a buffer. It covers 99% of the use-cases.
b) It's very simple to allocate a single buffer and reuse it for all your GetX calls.
c) 16 x 4 = 64 bytes = a single cache-line, which is the unit of basically every memory operation on modern CPUs. The fact that GetX can even cause a pipeline flush makes the 16 element "overhead" laughable in comparison.

Hotshot5000

glGetInteger would work only that I am using lwjgl through libgdx which doesn't expose that method. Oh well.... It's good that it has been fixed for the next version.