© Copyright Khronos Group, 2011 - Page 1
OpenGL Shading LanguageHints/Kinks
Bill Licea-KaneAMD
© Copyright Khronos Group, 2011 - Page 2
OpenGL Shading Language Hints/KinksMade in the Shade• A brief WABAC Machine moment
• Our world is no longer side effect free
- (GL_ARB_conservative_depth)
- GL_ARB_shader_image_load_store
- GL_ARB_shader_atomic_counters
• Some examples
- Don't try this at home
- Something old school
- Something new school
© Copyright Khronos Group, 2011 - Page 3
Brief WABAC Machine momentA decade in the shade
OpenGL Birds of a Feather
Wednesday, 15 August, 6:30 pm - 8:30 pm
Wilshire Grand, Wilshire Room
© Copyright Khronos Group, 2011 - Page 4
Shader-centric viewThe way things were – side effect free
Shader
Uniforms Textures
Temporaries
in out
© Copyright Khronos Group, 2011 - Page 5
Shader-centric viewThe way things are – side effects!
Shader
Uniforms Textures Images
Temporaries
in out
© Copyright Khronos Group, 2011 - Page 6
Shader-centric view…but still embarrassingly parallel
© Copyright Khronos Group, 2011 - Page 7
memory qualifiersmemory functions// memory qualifiers
coherent
volatile
restrict
writeonly
readonly
// memory functions
void memoryBarrier();
© Copyright Khronos Group, 2011 - Page 8
built-in functions
gvec4 imageLoad(readonly IMAGE_PARAMS)
void imageStore(writeonly IMAGE_PARAMS, gvec4 data)
© Copyright Khronos Group, 2011 - Page 9
built-in functionscontinuedint imageAtomicAdd(IMAGE_PARAMS, int data)
int imageAtomicMin(IMAGE_PARAMS, int data)
int imageAtomicMax(IMAGE_PARAMS, int data)
int imageAtomicAnd(IMAGE_PARAMS, int data)
int imageAtomicOr(IMAGE_PARAMS, int data)
int imageAtomicXor(IMAGE_PARAMS, int data)
int imageAtomicExchange(IMAGE_PARAMS, int data)
int imageAtomicCompSwap(IMAGE_PARAMS, int compare, int data)
© Copyright Khronos Group, 2011 - Page 10
built-in functionscontinueduint imageAtomicAdd(IMAGE_PARAMS, uint data)
uint imageAtomicMin(IMAGE_PARAMS, uint data)
uint imageAtomicMax(IMAGE_PARAMS, uint data)
uint imageAtomicAnd(IMAGE_PARAMS, uint data)
uint imageAtomicOr(IMAGE_PARAMS, uint data)
uint imageAtomicXor(IMAGE_PARAMS, uint data)
uint imageAtomicExchange(IMAGE_PARAMS, uint data)
uint imageAtomicCompSwap(IMAGE_PARAMS, uint compare, uint data)
© Copyright Khronos Group, 2011 - Page 11
built-in functionscontinueduint atomicCounterIncrement (atomic_uint c)
uint atomicCounterDecrement (atomic_uint c)
uint atomicCounter (atomic_uint c)
© Copyright Khronos Group, 2011 - Page 12
We would rather not shade if possibleSome controls to helplayout (depth_any) out float gl_FragDepth; // [unhappy face]
// hints
// may allow depth test early, gl_FragDepth will be written
layout (depth_unchanged) out float gl_FragDepth; // [happy face]
layout (depth_greater) out float gl_FragDepth; // [half-happy face]
layout (depth_less) out float gl_FragDepth; // [half-happy face]
// early depth test, period. gl_FragDepth ignored
layout (early_fragment_tests) in; // [woot-woot face]
© Copyright Khronos Group, 2011 - Page 13
Examples - Don’t try this at homeWe are what you call "experts"// "Experts" wouldn’t do this either.
// For thought-experimentation ONLY!!!
// Seriously.
layout (early_fragment_tests) in;
layout (binding=0, offset=0) uniform atomic_uint counter;
void main()
{
atomicCounterIncrement(counter);
}
© Copyright Khronos Group, 2011 - Page 14
Examples - Don’t try this at homeOcclusion querry-ish// "Experts" wouldn’t do this either.
// For thought-experimentation ONLY!!!
// Seriously.
layout (early_fragment_tests) in;
layout (binding=0, offset=0) uniform atomic_uint counter;
void main()
{
atomicCounterIncrement(counter);
}
© Copyright Khronos Group, 2011 - Page 15
Examples – Something old school
layout (triangles) in;
layout (points , max_vertices=1) out;
// ...
bool classifyTriangle();
void emitHit();
void main()
{
if classifyTriangle()
emitHit();
}
© Copyright Khronos Group, 2011 - Page 16
Examples – Something old schoolSelection Modelayout (triangles) in;
layout (points , max_vertices=1) out;
// ...
bool classifyTriangle();
void emitHit();
void main()
{
if classifyTriangle()
emitHit();
}
© Copyright Khronos Group, 2011 - Page 17
Examples – something new schoolPer fragment (even per sample) selection• Based on example from GDC 2010
- OIT and Indirect Illumination using DX11 Linked Lists
Holger Gruen, Nicolas Thibieroz, AMD ISV Relations
• Create a selection-sized offset image (4x4)
• Bind headOffset and dataStore images
• Bind counter buffer
• Initialize headOffset and counter
• Setup scissor
• DISABLE depth testing (we want EVERYTHING in the list)
• No framebuffer output
• Render
© Copyright Khronos Group, 2011 - Page 18
Examples – something new schoolImages – headOffset and dataStore
-1 -1 -1 -1
-1 -1 -1 -1
-1 -1 -1 -1
-1 -1 -1 -1
link id depthoffset
© Copyright Khronos Group, 2011 - Page 19
Examples – something new schoolImages – 1st triangle
-1 -1 -1 -1
-1 0 -1 -1
-1 -1 -1 -1
-1 -1 -1 -1
-1 id-red depth-red
link id depthoffset
© Copyright Khronos Group, 2011 - Page 20
Examples – something new schoolImages – 2nd triangle
-1 -1 -1 3
-1 0 4 2
-1 -1 -1 -1
-1 -1 1 -1
-1 id-red depth-red
-1 id-green depth-green
link id depthoffset
© Copyright Khronos Group, 2011 - Page 21
Examples – something new schoolImages – 3rd triangle
-1 -1 -1 3
-1 0 4 2
-1 -1 -1 -1
-1 -1 1 -1
-1 id-red depth-red
-1 id-green depth-green
-1 id-cyan depth-cyan
-1 id-cyan depth-cyan
-1 id-cyan depth-cyan
link id depthoffset
© Copyright Khronos Group, 2011 - Page 22
Examples – something new schoolImages – nth triangle
-1 id-red depth-red
-1 id-green depth-green
-1 id-cyan depth-cyan
-1 id-cyan depth-cyan
0 id-blue depth-blue
-1 id-cyan depth-cyan
link id depthoffset
-1 -1 -1 3
-1 4 2
-1 -1 -1 -1
-1 -1 1 -1
f-1
© Copyright Khronos Group, 2011 - Page 23
Examples – Something new school
layout (binding=0, offset=0) uniform atomic_uint fragmentCounter;
layout (r32ui) coherent uniform image2D restrict headOffset;
layout (rgba32ui) writeonly uimageBuffer restrict dataStore;
int2 coord(); // transform to coordinate system of headOffset buffer
uvec3 data(); // id, depth, whatever (color?)
void main()
{
uint NewOffset, PrevOffset;
NewOffset = atomicCounterIncrement(fragmentCounter);
PrevOffset = imageAtomicExchange(headOffset, coord(), NewOffset);
imageStore(dataStore, NewOffset, uvec4(PrevOffset, data()));
}
© Copyright Khronos Group, 2011 - Page 24
OpenGL Shading Language Hints/Kinks
Thank you!
http://blogs.amd.com/developer/