Enable extension and fwidth in glsl - glsl

I'm using webGL and I want to use fwidth as I did it in Three.js.
in .glsl file I've added an extension like this:
#ifndef GL_ES
// Non OpenGL ES devices doesnt support precision qualifiers, so we do
// nothing instead
#define lowp
#define mediump
#define highp
#else
// to have functions like fwidth for OpenGL ES or WebGL, the extension should
// be explicitly enabled.
#extension GL_OES_standard_derivatives : enable
#endif
But I'm keep getting this errors:
Error compiling FRAGMENT_SHADER: WARNING: 0:14: '
' : extension directive should occur before any non-preprocessor tokens
WARNING: 0:14: 'GL_OES_standard_derivatives' : extension is not supported
ERROR: 0:47: 'fwidth' : no matching overloaded function found
If anyone knows how to fix this - would be great to get a hint.

Related

Validation failure tex2D HLSL Shader Model 6.0

So apparently tex2D is still supported in HLSL shaderModel 6.0 so why does doing something like the following produce validation errors:
float myFloat = tex2D(MySampler, In.texCoord).w;
It does not like tex2D, if I make a Texture2D MyTex variable 1st then do
MyFloat = MyTex.Sample(MySampler, In.texCoord).w; validation is fine.
Of course I have disables validation with /Vd and dxc spits out a compiled file but no .asm when specified, dxc also tends to jam up with tex2D usage....
I have tried compilation with multiple versions of dxc.exe
Any ideas?
Thanks

"invalid operation" on shader loading and compiling

Problem
Having a shader program in a.vs as:
#version 330
in vec2 vPosition;
void main() {
gl_Position = vec4(vPosition, 0.0, 1.0);
}
and given:
import qualified Graphics.GLUtil as GLU
import qualified Graphics.Rendering.OpenGL as GL
this line:
vs <- GLU.loadShader GL.VertexShader $ shaderPath </> "a.vs"
causes:
GL: Error InvalidOperation "invalid operation"
at runtime.
Details
I'm running on Mac OS X 10.10.2. The OpenGL context is set via GLFW with:
GLFW.windowHint $ GLFW.WindowHint'OpenGLDebugContext True
GLFW.windowHint $ GLFW.WindowHint'ContextVersionMajor 3
GLFW.windowHint $ GLFW.WindowHint'ContextVersionMinor 3
GLFW.windowHint $ GLFW.WindowHint'OpenGLForwardCompat True
GLFW.windowHint $ GLFW.WindowHint'OpenGLProfile GLFW.OpenGLProfile'Core
giving an OpenGL 3.3 context.
The context of the code can be found at this repository (link to the specific commit), and specifically in Main.hs.
Question
What can I do to fix this issue or get more debugging informations?
I ran your code under gDebugger, and it made it plain:
GL.matrixMode $= GL.Projection
GL.loadIdentity
GL.ortho2D 0 (realToFrac w) (realToFrac h) 0
This leftover piece of code was triggering an error state:
Error-Code: GL_INVALID_OPERATION
Error-Description:
The specified operation is not allowed in the current state. The offending function is ignored, having no side effect other than to set the error flag.
As a side note, shader compilation can never trigger an INVALID_OPERATION (except when you try to render with a broken pipeline); the compilation errors can be obtained by checking the compilation status directly.

Is there a way to check what OpenGL / GLSL extensions are used by a program?

I'm wondering if is there some tool that can check what extensions are you using in a program or in a shader (or what minimun GL version you must to check).
Something like: 'checkGL directory' to get the list of extensions used by a program in a directory.
The output would be something like:
GL_MIRRORED_REPEAT - GL_VERSION_1_4 - GL_OES_texture_mirrored_repeat
glUseProgram - GL_VERSION_2_0 - GL_ES_VERSION_2_0
glEnableVertexAttribArray - GL_VERSION_2_0 - GL_ES_VERSION_2_0
I have never done this programatically, but it should be straight forward to do if you rely on compiler errors and have experience parsing XML files. In lieu of an actual existing tool (which I am unaware of), this is how you can implement it yourself.
Build your program as you would normally, but comment out all includes related to GL (e.g. #include <GL/gl.h> or #include <GL/glew.h>) and then save the compiler error log to a file. Given this error log, you can track down which GL extension and/or core version of GL is required for the missing functions and constants by parsing the OpenGL XML registry.
I suggest parsing the compiler error log for GL constants, types and functions rather than the source code because the compiler will run it through the pre-processor and this will eliminate a lot of false positives. You can just as easily parse every .c, .cpp, .h, etc. file in a project directory yourself and look for anything that begins with gl* or GL_*, but that will naively include inactive code branches, comments and so forth.
The XML registry is what Khronos uses to generate the headers on their site and it has very detailed information for every API function, enumerant, typedef and extension if you know how to parse it.
As-per your example, you will find:
<feature api="gl" name="GL_VERSION_1_4" number="1.4">
<require>
...
<enum name="GL_MIRRORED_REPEAT"/>
...
</require>
</feature>
...
<feature api="gles2" name="GL_ES_VERSION_2_0" number="2.0">
<require>
...
<enum name="GL_MIRRORED_REPEAT"/>
...
</require>
</feature>
This means that in "gl" (desktop GL), GL_MIRRORED_REPEAT is core in version 1.4 and in "gles2" (OpenGL ES 2.0+) it is core in version 2.0.
Be careful not to read too much into the label "gles2" (this is a fork of OpenGL ES that includes anything ES 2.0 or newer, parse the actual name and number to find out version requirements).
If you know the enum value of the core constant GL_MIRRORED_REPEAT, then you can lookup all other enums that have that same value and track them back to the respective extensions that were promoted to core.
Cross reference all extensions that provide GL_MIRRORED_REPEAT (0x8370):
<enums namespace="GL" start="0x8370" end="0x837F" vendor="HP">
<!-- NOTE: IBM is using values in this range, because of a
bobble when an employee left DEC for IBM at the same
time as they were assigned the range. their registry
became inconsistent. It's unknown whether HP has any
conflicts. They have never reported using any values in
this range. Lesson: assigned ranges belong to vendors,
not engineers! -->
<enum value="0x8370" name="GL_MIRRORED_REPEAT"/>
<enum value="0x8370" name="GL_MIRRORED_REPEAT_ARB"/>
<enum value="0x8370" name="GL_MIRRORED_REPEAT_IBM"/>
<enum value="0x8370" name="GL_MIRRORED_REPEAT_OES"/>
<unused start="0x8371" end="0x837F" vendor="HP"/>
</enums>
...
<extension name="GL_ARB_texture_mirrored_repeat" supported="gl">
<require>
<enum name="GL_MIRRORED_REPEAT_ARB"/>
</require>
</extension>
<extension name="GL_IBM_texture_mirrored_repeat" supported="gl">
<require>
<enum name="GL_MIRRORED_REPEAT_IBM"/>
</require>
</extension>
<extension name="GL_OES_texture_mirrored_repeat" supported="gles1">
<require>
<enum name="GL_MIRRORED_REPEAT_OES"/>
</require>
</extension>
In this case, GL_MIRRORED_REPEAT is provided by GL_ARB_texture_mirrored_repeat and GL_IBM_texture_mirrored_repeat in GL and by GL_OES_texture_mirrored_repeat in GLES 1.x (it is core in ES 2.0).
Regarding determining minimum version numbers for GLSL shaders, there is no XML file you can parse there. The only real saving grace is that if you set the #version ... directive too low, most GLSL compilers include the required version and/or extension in an error/warning in the shader info log.
Your best bet is going to be using GLslang (OpenGL Reference Compiler) to validate your shaders with a forced version of 110 (Desktop GL) and 100 (OpenGL ES). It is not as complete as the vendor GLSL compilers, but its output is always consistent regardless what GPU you are using and you should be able to write a parser for it.
UPDATE:
I threw together a project in a couple of hours that does roughly what you want, this is some sample output:
Enter OpenGL name to search for: GL_MIRRORED_REPEAT
--------------------------------
>> Enum: GL_MIRRORED_REPEAT is 0x8370
* Core in GL_VERSION_1_4 ( gl 1.4)
* Core in GL_ES_VERSION_2_0 (gles2 2.0)
>> Enum Alias: GL_MIRRORED_REPEAT_ARB <<
* Provided by GL_ARB_texture_mirrored_repeat (gl)
>> Enum Alias: GL_MIRRORED_REPEAT_IBM <<
* Provided by GL_IBM_texture_mirrored_repeat (gl)
>> Enum Alias: GL_MIRRORED_REPEAT_OES <<
* Provided by GL_OES_texture_mirrored_repeat (gles1)
Enter OpenGL name to search for: glEnableVertexAttribArray
--------------------------------
>> Command: void glEnableVertexAttribArray (GLuint index)
* Core in GL_VERSION_2_0 ( gl 2.0)
* Core in GL_ES_VERSION_2_0 (gles2 2.0)
>> Command Alias: glEnableVertexAttribArrayARB <<
* Provided by GL_ARB_vertex_program (gl)
Source code for this project is available on GitHub here.

GLSL 4.2 - Syntax error: "layout" parse error

So, I recently found an interesting shader and tried to compile it.
But, the GLSL compiler threw the following error:
ERROR: 0:50: error(#132) Syntax error: "layout" parse error
# (Fragment shader)
#version 420
...
uint ImageAtomic_Average_RGBA8(layout (r32ui) volatile uimage3D Img, ivec3 Coords, vec4 NewVal)
{ ... }
Details:
Card: AMD Radeon HD 7870 (It supports OpenGL 4.20)
I tried both the 4.2 driver and the 4.3 beta driver.
A layout qualifier cannot be part of the function's signature. Section 6.1.1 of the GLSL 4.40 Specification defines the following grammar for a function prototype:
function-prototype :
precision-qualifier type function-name(*parameter-qualifiers* precision-qualifier type name array-specifier, ... )
Now, a parameter-qualifier can be one of
const
in
out
inout
precise
memory qualifier (volatile, ...)
precision qualifier(lowp, ...)
Consistently, section 4.10 explicitly states:
Layout qualifiers cannot be used on formal function parameters [..]
If you drop the layout qualifier, you should be fine. If not, it's a driver bug.

How can I compile a CUDA program for sm_1X AND sm_2X when I have a surface declaration

I am writing a library that uses a surface (to re-sample and write to a texture) for a performance gain:
...
surface<void, 2> my_surf2D; //allows writing to a texture
...
The target platform GPU has compute capability 2.0 and I can compile my code with:
nvcc -arch=sm_20 ...
and it works just fine.
The problem is when I am trying to develop and debug the library on my laptop which has an NVIDIA ION GPU with compute capability 1.1 (I would also like my library to be backwards compatible). I know this architecture does not support surfaces so I used the nvcc macros in my device code to define an alternate code path for this older architecture:
#if (__CUDA_ARCH__ < 200)
#warning using kernel for CUDA ARCH < 2.0
...
temp_array[...] = tex3D(my_tex,X,Y,Z+0.5f);
#else
...
surf2Dwrite( tex3D(my_tex,X,Y,Z+0.5f), my_surf2D, ix*4, iy,cudaBoundaryModeTrap);
#endif
The problem is that when I do:
nvcc -gencode arch=compute_11,code=sm_11
I get this error:
ptxas PTX/myLibrary.ptx, line 1784; fatal : Parsing error near '.surf': syntax error
When I look at the PTX file is see what appears to be the surface declaration:
.surf .u32 _ZN16LIB_15my_surf2DE;
If I try to put a similar macro around the surface declaration in my source code:
#ifdef __CUDACC__
#if __CUDA_ARCH__ < 200
#warning skipping surface declaration for nvcc trajectory
#else
surface ...
#endif
#else
#warning keeping surface declaration by default
surface ...
#endif
I get an error saying the surface variable is undefined in the host code call to to bind cuda surface to array. Should I add the macro around the bind function as well?
I'm not sure if it is possible, or if I goofed somewhere, please help.
Figured this thread should show up as answered...
I got it to work (quite simple actually). You must put a macro around all three possible places where the surface reference is used, and be careful to use the macros properly (it turns out, __CUDACC__ is not necessary).
The following only changes the code when compiling for compute capability < 2.0
The surface declaration:
//enable backwards compatability:
#if defined(__CUDA_ARCH__) & (__CUDA_ARCH__ < 200)
#warning skipping surface declarations for compute capability < 2.0
#else
surface<void, 2> my_surf2D; //allows writing to a texture
#endif
Surface binding:
#if defined(__CUDA_ARCH__) & (__CUDA_ARCH__ < 200)
#warning skipping cudaBindSurfaceToArray for compute capability < 2.0
...
#else
errorCode = cudaBindSurfaceToArray(my_surf2D, my_cudaArray2D);
#endif
And Surface writing:
#if defined(__CUDA_ARCH__) & (__CUDA_ARCH__ < 200)
#warning using kernel for compute capability < 2.0
...
temp_array[...] = tex3D(my_tex,X,Y,Z+0.5f);
#else
...
surf2Dwrite( tex3D(my_tex,X,Y,Z+0.5f), my_surf2D, ix*4, iy,cudaBoundaryModeTrap);
#endif
This works for both virtual and real targets (-arch=compute_XX and -arch=sm_XX respectively).
Thanks to talonmies and Roger Dahl for pointing me in the right direction, as well as this answer from talonmies which has a great explanation of nvcc/CUDA macros as well.