dual monitor gamma issues

Discuss programming topics for the various GPL'd game engine sources.
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Re: dual monitor gamma issues

Post by Spike »

or in other words, you mean tl;dr ?

#define GL_FRAMEBUFFER_SRGB 0x8DB9
glEnable(GL_FRAMEBUFFER_SRGB);
The output of your fragment program will be scaled up by about 2.2 gamma (remember that quake's gamma cvar is backwards, about .45 iiuc).
(basically, this works around the issue that ericw pointed out).



When uploading textures, if you specify GL_SRGB_EXT for your internalformat argument, then your image is treated as though its already gamma corrected, and will be 'linearised' as part of sampling, such that it won't get brightened.

Using both at the same time can reduce banding in low-light areas, supposedly.

Edit:
Regarding documentation, the microsoft docs are outdated to the point of pointlessness. They don't document *ANYTHING* beyond gl 1.1. its all fixed function stuff - stuff that has been deprectated for quite some time now.
On the plus side, when it doesn't support anything, there's not much that is needed to be documented - which makes it muuuch more readable I guess.
Either way, if you're depending upon microsoft for documentation then you're basically handicapping yourself to whatever the latest thing microsoft thinks it can get away with pushing.
Its ironic really, their rediculously-outdated documentation for opengl is far more readable than thier documentation for d3d... Or would be, if searches for gl stuff on msdn didn't get drowned out by people talking about comparisons between gl+d3d... by citing microsoft.
Also, http://www.gamedev.net/topic/198541-glv ... ion-error/
The nice thing about official documentation of opengl is that its both complete and definitive. Other sites simply don't offer that (unless they're just copy+paste, making them a bit pointless except as mirrors).
But yes, you do have to actually know what you're looking for first.
Last edited by Spike on Sun Feb 22, 2015 9:14 pm, edited 1 time in total.
Baker
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Re: dual monitor gamma issues

Post by Baker »

Spike wrote:or in other words, you mean tl;dr ?

#define GL_FRAMEBUFFER_SRGB 0x8DB9
glEnable(GL_FRAMEBUFFER_SRGB);
Thank you for the information.

However, that isn't in either of those 2 OpenGL extension specs pages. So tl;dr? = No. Too long and wasn't there = yes.

For a brief moment while rechecking I briefly had to ponder if for once the OpenGL pages contained the actual information that someone would be looking for.

And for a moment, I was disturbed because the presence of actual information on an OpenGL page would turn my world upside down.

Finding actual information on OpenGL documentation is a similar experience to finding actual information in Apple documentation. :D

Well, at least in theory. I haven't had either experience even once so I can't claim to speak firsthand to what that would feel like, only imagine what it might feel like. :D
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Re: dual monitor gamma issues

Post by Spike »

Baker wrote: However, that isn't in either of those 2 OpenGL extension specs pages.
what the hell are you talking about?
overview wrote: When blending is disabled but the new sRGB
updated mode is enabled (assume the framebuffer supports the
capability), high-precision linear color component values for red,
green, and blue generated by fragment coloring are encoded for sRGB
prior to being written into the framebuffer
the bit about when blending is enabled is more wordy and might distract the fickle, so I won't paste it here.
Overview wrote: The sRGB color space roughly corresponds to 2.2 gamma correction.
Oh, so *that's* what sRGB is all about then.
New Tokens wrote: Accepted by the <cap> parameter of Enable, Disable, and IsEnabled,
and by the <pname> parameter of GetBooleanv, GetIntegerv, GetFloatv,
and GetDoublev:

FRAMEBUFFER_SRGB 0x8DB9
Ah, so that's how to enable it. glEnable enables all...

Its all there, even the exact srgb->rgb->srgb mappings.
But yes, its written for software engineers, rather than copy pasters.


Examples like this is why I cba writing documentation. Even if you put it all there, people ignore it completely, but its nice to know other people have the same problem with their documentation. :)
Baker
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Re: dual monitor gamma issues

Post by Baker »

Spike wrote:...
Its all there, even the exact srgb->rgb->srgb mappings.
But yes, its written for software engineers, rather than copy pasters.
...
Sure it was a bit of a rant, although I don't know why you would take my displeasure of OpenGL's docs personally. More than a few times in the past, I've needless wasted quite a bit of time fighting an extension or similar.

I don't expect the documentation to write the code, but OpenGL has a client-server model and that means it has a command stream and it would be nice for it to say --- oh, I don't know --- the command. ... In just one of the 604 lines (doc 1) or 834 lines (doc 2).

One opinion, and I'm often wrong.
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Re: dual monitor gamma issues

Post by Spike »

yeah, its annoying that it doesn't have nice simple examples, but then I guess 'nice simple examples' involve 1000 lines to set up textures+glsl+etc... still, something cut down would be nice, but blurgh.

microsoft and opengl just annoys me.
did you know that the SwapBuffers call makes _two_ separate LoadLibrary+GetProcAddress calls each and every time you call it? They didn't even bother to use delay-loaded dlls for it, but just did it in the most inefficient way possible.
You can use wglSwapLayerBuffers instead and that'll give you a 10% boost if you're just spamming SwapBuffers, at least if you're doing it on my pc. When you're cpu-bound, that's actually noticable.
wglSwapLayerBuffers still calls gdi's GetPixelFormat, which calls opengl32's wglGetPixelFormat, which is where the other LoadLibrary inefficiency comes from.
All this helps explains how come linux gets higher framerates in games like quake.

It used to be that FTE's d3d9 renderer would get the highest (simple scene) framerates on windows on my machine (no microsoft anti-portability tax with d3d, about equal with gl in linux, with win gl 1000 fps lower), but since getting a new gpu that's simply no longer the case - it actually lost about 1000 fps in my test case (while wingl gained about that amount). I assume this is due to fte's d3d9 renderer basically only using fixed-function stuff with no hlsl or (long-term) vbos, though as these are only simple scenes that latter omission shouldn't hinder much more than the extra overhead of fte's more feature-packed gl renderer.
(if I recall correctly, the d3d11 renderer gained, but not so much. tbh, I didn't benchmark this reliably enough to compare. my experience of d3d11 has not been particuarly favourable, other than for the removal of needing to check for capabilities quite so much, in much the same way that an engine written for gl3 contexts would be able to assume that everything is supported)
either way, it kinda goes to show that quake is all cpu limited without some seriously large batches (read: something like this).
even old builds exhibit this behaviour too.

so really, what I'm trying to say is that by depending on microsoft's documentation, you're learning outdated practises that are built around trying to make d3d seem better.
By slamming into you so hard about it, I hope to change your ways so you do start using other resources, so that you are more open to using gl2 extensions freely (glquake without glsl is just glitchy!).
Fine, use msdn for gl1.1 docs if you really need that, but the point is that you shouldn't need that. The thought that you're basically handycapping yourself to 20-year-old capabilities is what really annoys me here.

I'd give you the code to create a GLES2 context in windows to force you to learn (slightly) more current practises... meh, here goes:

Code: Select all

#define WGL_CONTEXT_MAJOR_VERSION_ARB		0x2091
#define WGL_CONTEXT_MINOR_VERSION_ARB		0x2092
#define WGL_CONTEXT_PROFILE_MASK_ARB		0x9126/*WGL_ARB_create_context_profile*/
#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB	0x00000001 /*just in case you want this*/
#define WGL_CONTEXT_ES_PROFILE_BIT_EXT		0x00000004 /*requests a gles context*/
wglMakeCurrent(windowhdc, glcontext);//should exist in your code already, at just after gl context creation.
pwglCreateContextAttribsARB = wglGetProcAddress("wglCreateContextAttribsARB");
int attribarray[] = {WGL_CONTEXT_MAJOR_VERSION_ARB, 2, WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_ES_PROFILE_BIT_EXT, 0};
if (pwglCreateContextAttribsARB && (newglcontext = pwglCreateContextAttribsARB(windowhdc, NULL, attribarray)))
{
wglMakeCurrent(windowhdc, newglcontext);
wglDeleteContext(glcontext);
glcontext = newglcontext;
}
fix it up a little and you should now have a gles 2(or 3) context instead of a desktop gl4 or whatever one.
you know you got a gles context if glGetString(GL_VERSION) returns something starting with "OpenGL ES". In which case you need to avoid glBegin, fix up some texture formats (format+internal format must be the same, annoyingly), and of course migrate everything to use glsl instead of texenv or whatever.
a gl3.1 core context will require the use of VBOs (recommended for static stuff, but can be slower if you're only using it once, due to driver's automatic buffering being a little more efficient).
a gl3.3 core context will require a vao set up, which is a bit annoying, but whatever.
if you get a lot of gl errors, you can add WGL_CONTEXT_FLAGS_ARB,WGL_CONTEXT_DEBUG_BIT_ARB to your attrib list, and then utilise GL_ARB_debug_output to help track the calls that trigger gl errors.

Of course, this is all VERY offtopic now.
Baker
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Re: dual monitor gamma issues

Post by Baker »

Spike wrote:did you know that the SwapBuffers call makes _two_ separate LoadLibrary+GetProcAddress calls each and every time you call it? They didn't even bother to use delay-loaded dlls for it, but just did it in the most inefficient way possible.
You can use wglSwapLayerBuffers instead and that'll give you a 10% boost if you're just spamming SwapBuffers, at least if you're doing it on my pc. When you're cpu-bound, that's actually noticable.
wglSwapLayerBuffers still calls gdi's GetPixelFormat, which calls opengl32's wglGetPixelFormat, which is where the other LoadLibrary inefficiency comes from.
All this helps explains how come linux gets higher framerates in games like quake.
That's very interesting and a bit strange.
Of course, this is all VERY offtopic now.
Let's go more offtopic! memmove is one extra instruction over memcpy. memcpy should be deprecated and never used (except really low-level code).

And something I didn't take into account: OpenGL to some extent is only a specification for hardware manufacturers.
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
r00k
Posts: 1111
Joined: Sat Nov 13, 2004 10:39 pm

Re: dual monitor gamma issues

Post by r00k »

ok more off topic but steering back to RTT/GLSL

from what ericw mentioned, using RMQe as a guide to setting up RTT and GLSL i added the r_waterwarp. I'm hoping that i can use the same code for blur and gamma too

but once all is said and done im getting this...
Image

now, the grey areas are using gl_clear 1, otherwise i get 'hall of mirrors' effect in those areas.
without posting all relative code, am i forgetting something? The ACTUAL render/warp code is 100% from RMQe, maybe im not clearing a buffer or something?


EDIT: NEVERMIND!! I WAS CALLING R_DrawUnderwaterWarp FROM THE WRONG PLACE! doh!
dimman
Posts: 7
Joined: Wed Jan 29, 2014 1:58 pm

Re: dual monitor gamma issues

Post by dimman »

I did a quick hack to port the code to ezQuake and I'm seeing about 50-70% performance drop when gamma != 1.

Is this reasonable by using the shader/implementation ericw presented?? (I haven't managed to get quakespasm running here yet otherwise it seems like a fairly easy test to do by toggling it on/off on cmdline)
ericw
Posts: 92
Joined: Sat Jan 18, 2014 2:11 am

Re: dual monitor gamma issues

Post by ericw »

I didn't realize it was that much of a perf hit, at least on id1 maps, but in e1m1 I go from 770fps with gamma 1 to 290fps with gamma != 1.
I tried that at 2880x1800 to maximize the performance hit, w/ geforce 650gt 1024mb, OS X.

On the other hand if I try one of the heaviest quake maps I know of, jam3_tronyn.bsp, I get about 130fps regardless of gamma.

(Btw, we did some cleanup last week to the quakespasm build system for VisualStudio, CodeBlocks, and XCode; with any luck it will build out of the box if you checkout the latest svn.)
dimman
Posts: 7
Joined: Wed Jan 29, 2014 1:58 pm

Re: dual monitor gamma issues

Post by dimman »

ericw wrote:I didn't realize it was that much of a perf hit, at least on id1 maps, but in e1m1 I go from 770fps with gamma 1 to 290fps with gamma != 1.
I tried that at 2880x1800 to maximize the performance hit, w/ geforce 650gt 1024mb, OS X.

On the other hand if I try one of the heaviest quake maps I know of, jam3_tronyn.bsp, I get about 130fps regardless of gamma.

(Btw, we did some cleanup last week to the quakespasm build system for VisualStudio, CodeBlocks, and XCode; with any luck it will build out of the box if you checkout the latest svn.)
Ok thanks for confirming that it's just not me :) I tried using the cross compilation for win32 with SDL2 (building on linux) and after copying all the .dll's it just refused to start. No complaints at all it just seemed like a NOP to double click the .exe.
Tried running it from cmd too but no output.

I've started trying to clean up the extremely messy and outdated ezquake code. It's currently also running on SDL2 only, but had to adapt some OpenGL initialization code from quakespasm (which is rather clean and nice) and thought I might have made some mistake in that part, or since the other ezQuake opengl code is ancient it might affect too. I'm a real noob at specifically gfx/OpenGL, although I'm trying to convince myself that I'm interested enough to learn it.. :)

EDIT: After doing some investigation with Spike's help it seems like its all calls to glCopyTexSubImage2D that kills performance, and Spikes answer: Use FBO's. Atm that's pure greek for me but might be useful for someone with enough knowledge about it :)
mh
Posts: 2292
Joined: Sat Jan 12, 2008 1:38 am

Re: dual monitor gamma issues

Post by mh »

If you're getting that kind of drop with shader-based gamma via glCopyTexSubImage, then you're either doing something else wrong or your driver has a very poor implementation of glCopyTexSubImage.

I'd be surprised if it was the latter; Doom 3 extensively uses glCopyTex(Sub)Image for it's post-processing effects, and FQ/QS itself uses glCopyTex(Sub)Image for it's r_oldwater 0. Perhaps you could try a comparative benchmark with r_oldwater 0?

It's possible that while glCopyTexSubImage may be sub-optimal on some drivers, glCopyTexImage is not. One possible reason for that might be that glCopyTexImage will respecify the texture, so it may be better able to handle cases where a previous frame's drawing using the same texture is still queued up. A 50% to 70% perf drop certainly does suggest some kind of synchronization is going on.

So I also suggest trying a switch to glCopyTexImage instead and see if that improves things.

You should specify GL_NEAREST for the filtering modes when applying gamma this way, by the way, otherwise you will drop some image quality.
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
ericw
Posts: 92
Joined: Sat Jan 18, 2014 2:11 am

Re: dual monitor gamma issues

Post by ericw »

Booting into Windows, I tried dipping under water in e1m1 with RMQEngine and DirectQ, and both of those also show a ~50% fps drop when the render-to-texture screen warp kicks in. But again, 2880x1800 resolution, and the drop was ~700 to ~300fps. This is a laptop, too, and the gfx card isn't that great, so maybe it just doesn't have the horsepower to copy that large of a framebuffer at 700fps?

r_oldwater: I tried Quakespasm, gamma 1, in the water in e1m1, and got 448fps with r_oldwater 0, 487fps with r_oldwater 1, so a bit of a boost from disabling RTT. But the warp image is only 512x512, and the 2880x1800 framebuffer is almost 20 times bigger.

Taking out the redundant glClear in my RTT code Spike pointed out, and change to GL_NEAREST, I'm up to 330fps with the RTT gamma which is a bit better.
I tried a switch to glCopyTexImage but it didn't make any difference.

Thanks for the tips!
mh
Posts: 2292
Joined: Sat Jan 12, 2008 1:38 am

Re: dual monitor gamma issues

Post by mh »

I missed the 2880x1800 part. :oops:

Yeah, that's gonna be a performance drag whatever way you slice it. DirectQ, by the way, should do a "real" render to texture (i.e using D3D's equivalent of FBOs: SetRenderTarget) so that should establish that switching to FBOs in GL isn't going to help much. At this stage I'd be willing to bet that you get a similar performance drop when the polyblend is on (do an impulse 255 and test it; it won't be as large but it should be in the same kinda ballpark), so it seems that it's just drawing over such a large resolution viewport that's primarily to blame.
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
ericw
Posts: 92
Joined: Sat Jan 18, 2014 2:11 am

Re: dual monitor gamma issues

Post by ericw »

Ah :) Yup, the framerate hit from impulse 255 at that resolution is about 40% (770->440fps).

Anyhow, I'm pretty happy with this gamma implementation. From what I've seen I doubt it will ever get in the way of hitting 60fps (or even 120fps) on Quake maps. Running id1 content at very high resolutions and uncapped FPS is sort of a crazy border case, I think.
dimman
Posts: 7
Joined: Wed Jan 29, 2014 1:58 pm

Re: dual monitor gamma issues

Post by dimman »

Hehe, yeah if 60-120fps were good enough for the old an dirty ezQuake engine and its users :) I come from the QW community and the requirements there are a bit higher I assume. People play with framerates of atleast ~500fps and a drop from say 2000fps to 1000fps wouldn't be accepted.

Anyway, thanks a lot guys for looking into it, I'll see if I can do anything about it on my side :) (Btw, I was testing @ 1680x1050 and could see some drops from 2900fps to 1200fps or so. The engine is a big hack and currently uses OpenGL 1.x.. Hopefully I'll be able to fix and clean things up around it at first and then look into the renderer. Oh and yeah I did test commenting out the gl_clear calls and changed LINEAR to NEAREST, and also changed to glCopyTexImage2D but no big changes really.)
Post Reply