Diligent Engine API Reference
GLSLDefinitions.h
1 /* Copyright 2015-2018 Egor Yusov
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
10  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
11  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS.
12  *
13  * In no event and under no legal theory, whether in tort (including negligence),
14  * contract, or otherwise, unless required by applicable law (such as deliberate
15  * and grossly negligent acts) or agreed to in writing, shall any Contributor be
16  * liable for any damages, including any direct, indirect, special, incidental,
17  * or consequential damages of any character arising as a result of this License or
18  * out of the use or inability to use the software (including but not limited to damages
19  * for loss of goodwill, work stoppage, computer failure or malfunction, or any and
20  * all other commercial damages or losses), even if such Contributor has been advised
21  * of the possibility of such damages.
22  */
23 
24 #ifndef _GLSL_DEFINITIONS_
25 #define _GLSL_DEFINITIONS_
26 
27 #define GLSL
28 
29 #define float4 vec4
30 #define float3 vec3
31 #define float2 vec2
32 
33 #define int4 ivec4
34 #define int3 ivec3
35 #define int2 ivec2
36 
37 #define uint4 uvec4
38 #define uint3 uvec3
39 #define uint2 uvec2
40 
41 #define bool4 bvec4
42 #define bool3 bvec3
43 #define bool2 bvec2
44 
45 // OpenGL matrices in GLSL are always as column-major
46 // (this is not related to how they are stored)
47 #define float2x2 mat2x2
48 #define float2x3 mat3x2
49 #define float2x4 mat4x2
50 
51 #define float3x2 mat2x3
52 #define float3x3 mat3x3
53 #define float3x4 mat4x3
54 
55 #define float4x2 mat2x4
56 #define float4x3 mat3x4
57 #define float4x4 mat4x4
58 #define matrix mat4x4
59 
60 #define static
61 
62 #define SamplerState int
63 #define SamplerComparisonState int
64 
65 // https://www.opengl.org/wiki/Memory_Model#Incoherent_memory_access
66 // Shared variable access uses the rules for incoherent memory access.
67 // This means that the user must perform certain synchronization in
68 // order to ensure that shared variables are visible.
69 // At the same time, shared variables are all implicitly declared coherent,
70 // so one don't need to (and can't) use that qualifier.
71 #define groupshared shared
72 
73 #ifdef FRAGMENT_SHADER
74 # define ddx dFdx
75 # define ddy dFdy
76 #else
77 # define ddx(x) (x) // GLSL compiler fails when it sees derivatives
78 # define ddy(x) (x) // in any shader but fragment
79 #endif
80 
81 #define ddx_coarse ddx
82 #define ddy_coarse ddy
83 #define ddx_fine ddx
84 #define ddy_fine ddy
85 
86 #define mul(a, b) ((a)*(b))
87 #define frac fract
88 #define atan2 atan
89 #define rsqrt inversesqrt
90 #define fmod mod
91 #define lerp mix
92 #define dst distance
93 #define countbits bitCount
94 #define firstbithigh findMSB
95 #define firstbitlow findLSB
96 #define reversebits bitfieldReverse
97 
98 float rcp( float x ){ return 1.0 / x; }
99 vec2 rcp( vec2 x ){ return vec2(1.0,1.0) / x; }
100 vec3 rcp( vec3 x ){ return vec3(1.0,1.0,1.0) / x; }
101 vec4 rcp( vec4 x ){ return vec4(1.0,1.0,1.0,1.0) / x; }
102 
103 float saturate( float x ){ return clamp( x, 0.0, 1.0 ); }
104 vec2 saturate( vec2 x ){ return clamp( x, vec2(0.0, 0.0), vec2(1.0, 1.0) ); }
105 vec3 saturate( vec3 x ){ return clamp( x, vec3(0.0, 0.0, 0.0), vec3(1.0, 1.0, 1.0) ); }
106 vec4 saturate( vec4 x ){ return clamp( x, vec4(0.0, 0.0, 0.0, 0.0), vec4(1.0, 1.0, 1.0, 1.0) ); }
107 
108 void sincos( float x, out float s, out float c ){ s = sin( x ); c = cos( x ); }
109 void sincos( vec2 x, out vec2 s, out vec2 c ){ s = sin( x ); c = cos( x ); }
110 void sincos( vec3 x, out vec3 s, out vec3 c ){ s = sin( x ); c = cos( x ); }
111 void sincos( vec4 x, out vec4 s, out vec4 c ){ s = sin( x ); c = cos( x ); }
112 
113 
114 // Bit conversion operations
115 
116 float asfloat( float x ){ return x; }
117 vec2 asfloat( vec2 x ){ return x; }
118 vec3 asfloat( vec3 x ){ return x; }
119 vec4 asfloat( vec4 x ){ return x; }
120 
121 float asfloat( int x ){ return intBitsToFloat(x); }
122 vec2 asfloat( ivec2 x ){ return intBitsToFloat(x); }
123 vec3 asfloat( ivec3 x ){ return intBitsToFloat(x); }
124 vec4 asfloat( ivec4 x ){ return intBitsToFloat(x); }
125 
126 float asfloat( uint x ){ return uintBitsToFloat(x); }
127 vec2 asfloat( uvec2 x ){ return uintBitsToFloat(x); }
128 vec3 asfloat( uvec3 x ){ return uintBitsToFloat(x); }
129 vec4 asfloat( uvec4 x ){ return uintBitsToFloat(x); }
130 
131 
132 int asint( int x ){ return x; }
133 ivec2 asint( ivec2 x ){ return x; }
134 ivec3 asint( ivec3 x ){ return x; }
135 ivec4 asint( ivec4 x ){ return x; }
136 
137 int asint( uint x ){ return int(x); }
138 ivec2 asint( uvec2 x ){ return ivec2(x); }
139 ivec3 asint( uvec3 x ){ return ivec3(x); }
140 ivec4 asint( uvec4 x ){ return ivec4(x); }
141 
142 int asint( float x ){ return floatBitsToInt(x); }
143 ivec2 asint( vec2 x ){ return floatBitsToInt(x); }
144 ivec3 asint( vec3 x ){ return floatBitsToInt(x); }
145 ivec4 asint( vec4 x ){ return floatBitsToInt(x); }
146 
147 
148 uint asuint( uint x ){ return x; }
149 uvec2 asuint( uvec2 x ){ return x; }
150 uvec3 asuint( uvec3 x ){ return x; }
151 uvec4 asuint( uvec4 x ){ return x; }
152 
153 uint asuint( int x ){ return uint(x); }
154 uvec2 asuint( ivec2 x ){ return uvec2(x); }
155 uvec3 asuint( ivec3 x ){ return uvec3(x); }
156 uvec4 asuint( ivec4 x ){ return uvec4(x); }
157 
158 uint asuint( float x ){ return floatBitsToUint(x); }
159 uvec2 asuint( vec2 x ){ return floatBitsToUint(x); }
160 uvec3 asuint( vec3 x ){ return floatBitsToUint(x); }
161 uvec4 asuint( vec4 x ){ return floatBitsToUint(x); }
162 
163 
164 float f16tof32( uint u1 )
165 {
166  return unpackHalf2x16( u1 ).x;
167 }
168 vec2 f16tof32( uvec2 u2 )
169 {
170  uint u2PackedHalf = (u2.x & 0x0ffffu) | ((u2.y & 0x0ffffu) << 16u);
171  return unpackHalf2x16( u2PackedHalf );
172 }
173 vec3 f16tof32( uvec3 u3 )
174 {
175  return vec3( f16tof32( u3.xy ), f16tof32( u3.z ) );
176 }
177 vec4 f16tof32( uvec4 u4 )
178 {
179  return vec4( f16tof32( u4.xy ), f16tof32( u4.zw ) );
180 }
181 float f16tof32( int i1 ){ return f16tof32( uint ( i1 ) ); }
182 vec2 f16tof32( ivec2 i2 ){ return f16tof32( uvec2( i2 ) ); }
183 vec3 f16tof32( ivec3 i3 ){ return f16tof32( uvec3( i3 ) ); }
184 vec4 f16tof32( ivec4 i4 ){ return f16tof32( uvec4( i4 ) ); }
185 
186 uint f32tof16( float f )
187 {
188  return packHalf2x16( vec2( f, 0.0 ) ) & 0x0ffffu;
189 }
190 uvec2 f32tof16( vec2 f2 )
191 {
192  uint u2PackedHalf = packHalf2x16( f2 );
193  return uvec2( u2PackedHalf & 0x0ffffu, u2PackedHalf >> 16u );
194 }
195 uvec3 f32tof16( vec3 f3 )
196 {
197  return uvec3( f32tof16( f3.xy ), f32tof16( f3.z ) );
198 }
199 uvec4 f32tof16( vec4 f4 )
200 {
201  return uvec4( f32tof16( f4.xy ), f32tof16( f4.zw ) );
202 }
203 
204 #ifndef GL_ES // double is not supported on GLES
205 double asdouble(uint lowbits, uint highbits)
206 {
207  return packDouble2x32( uvec2( lowbits, highbits ) );
208 }
209 #endif
210 
211 
212 // Floating point functions
213 
214 bool isfinite( float x )
215 {
216  return !isinf( x ) && !isnan( x );
217 }
218 
219 bool2 isfinite( vec2 f2 )
220 {
221  return bool2( isfinite( f2.x ), isfinite( f2.y ) );
222 }
223 
224 bool3 isfinite( vec3 f3 )
225 {
226  return bool3( isfinite( f3.xy ), isfinite( f3.z ) );
227 }
228 
229 bool4 isfinite( vec4 f4 )
230 {
231  return bool4( isfinite( f4.xyz ), isfinite( f4.w ) );
232 }
233 
234 #ifndef GL_ES
235  float noise( float x ){ return noise1( x ); }
236  vec2 noise( vec2 x ){ return noise2( x ); }
237  vec3 noise( vec3 x ){ return noise3( x ); }
238  vec4 noise( vec4 x ){ return noise4( x ); }
239 #else
240  float noise( float x ){ return 0.0; }
241  vec2 noise( vec2 x ){ return vec2(0.0, 0.0); }
242  vec3 noise( vec3 x ){ return vec3(0.0, 0.0, 0.0); }
243  vec4 noise( vec4 x ){ return vec4(0.0, 0.0, 0.0, 0.0); }
244 #endif
245 
246 float log10( float x )
247 {
248  return log( x ) / log( 10.0 );
249 }
250 vec2 log10( vec2 x )
251 {
252  float _lg10 = log( 10.0 );
253  return log( x ) / vec2(_lg10, _lg10);
254 }
255 vec3 log10( vec3 x )
256 {
257  float _lg10 = log( 10.0 );
258  return log( x ) / vec3(_lg10, _lg10, _lg10);
259 }
260 vec4 log10( vec4 x )
261 {
262  float _lg10 = log( 10.0 );
263  return log( x ) / vec4(_lg10, _lg10, _lg10, _lg10);
264 }
265 
266 
267 #ifdef GL_ES
268 # define mad(a,b,c) ((a)*(b)+(c))
269 #else
270 # define mad fma
271 #endif
272 
273 
274 // Relational and logical operators
275 #define Less lessThan
276 #define LessEqual lessThanEqual
277 #define Greater greaterThan
278 #define GreaterEqual greaterThanEqual
279 #define Equal equal
280 #define NotEqual notEqual
281 #define Not not
282 bool4 And(bool4 L, bool4 R)
283 {
284  return bool4(L.x && R.x,
285  L.y && R.y,
286  L.z && R.z,
287  L.w && R.w);
288 }
289 bool3 And(bool3 L, bool3 R)
290 {
291  return bool3(L.x && R.x,
292  L.y && R.y,
293  L.z && R.z);
294 }
295 bool2 And(bool2 L, bool2 R)
296 {
297  return bool2(L.x && R.x,
298  L.y && R.y);
299 }
300 bool And(bool L, bool R)
301 {
302  return (L && R);
303 }
304 
305 
306 bool4 Or(bool4 L, bool4 R)
307 {
308  return bool4(L.x || R.x,
309  L.y || R.y,
310  L.z || R.z,
311  L.w || R.w);
312 }
313 bool3 Or(bool3 L, bool3 R)
314 {
315  return bool3(L.x || R.x,
316  L.y || R.y,
317  L.z || R.z);
318 }
319 bool2 Or(bool2 L, bool2 R)
320 {
321  return bool2(L.x || R.x,
322  L.y || R.y);
323 }
324 bool Or(bool L, bool R)
325 {
326  return (L || R);
327 }
328 
329 float4 BoolToFloat( bool4 b4 )
330 {
331  return float4(b4.x ? 1.0 : 0.0,
332  b4.y ? 1.0 : 0.0,
333  b4.z ? 1.0 : 0.0,
334  b4.w ? 1.0 : 0.0);
335 }
336 float3 BoolToFloat( bool3 b3 )
337 {
338  return float3(b3.x ? 1.0 : 0.0,
339  b3.y ? 1.0 : 0.0,
340  b3.z ? 1.0 : 0.0);
341 }
342 float2 BoolToFloat( bool2 b2 )
343 {
344  return float2(b2.x ? 1.0 : 0.0,
345  b2.y ? 1.0 : 0.0);
346 }
347 float BoolToFloat( bool b )
348 {
349  return b ? 1.0 : 0.0;
350 }
351 
352 
353 // Synchronization functions
354 
355 #ifdef COMPUTE_SHADER
356 
357 // https://www.opengl.org/wiki/Memory_Model#Incoherent_memory_access
358 
359 // MSDN: GroupMemoryBarrier() blocks execution of all threads
360 // in a group until all group SHARED accesses have been completed.
361 void GroupMemoryBarrier()
362 {
363  // OpenGL.org: groupMemoryBarrier() waits on the completion of all memory accesses
364  // performed by an invocation of a compute shader relative to the same access performed
365  // by other invocations in the same work group and then returns with no other effect.
366 
367  // groupMemoryBarrier() acts like memoryBarrier(), ordering memory writes for all kinds
368  // of variables, but it only orders read/writes for the current work group.
369  groupMemoryBarrier();
370 
371  // OpenGL.org: memoryBarrierShared() waits on the completion of
372  // all memory accesses resulting from the use of SHARED variables
373  // and then returns with no other effect.
374  memoryBarrierShared();
375 }
376 
377 // MSDN: GroupMemoryBarrierWithGroupSync() blocks execution of all
378 // threads in a group until all memory accesses have been completed
379 // and all threads in the group have reached this call.
380 void GroupMemoryBarrierWithGroupSync()
381 {
382  // Issue memory barrier first!
383  GroupMemoryBarrier();
384  barrier();
385 }
386 
387 // MSDN: DeviceMemoryBarrier() blocks execution of all threads
388 // in a group until all device memory accesses have been completed.
389 void DeviceMemoryBarrier()
390 {
391  // Call all memory barriers except for shared memory
392 
393  // Do we need to call groupMemoryBarrier() ?????
394 
395  // OpenGL.org: memoryBarrierBuffer() waits on the completion of
396  // all memory accesses resulting from the use of BUFFER variables
397  // and then returns with no other effect
398  memoryBarrierBuffer();
399 
400  // OpenGL.org: memoryBarrierImage() waits on the completion of all
401  // memory accesses resulting from the use of IMAGE variables and then
402  // returns with no other effect.
403  memoryBarrierImage();
404 
405  // OpenGL.org: memoryBarrierAtomicCounter() waits on the completion of
406  // all accesses resulting from the use of ATOMIC COUNTERS and then returns
407  // with no other effect.
408  memoryBarrierAtomicCounter();
409 }
410 
411 // MSDN: DeviceMemoryBarrierWithGroupSync() blocks execution of
412 // all threads in a group until all device memory accesses have
413 // been completed and all threads in the group have reached this call.
414 void DeviceMemoryBarrierWithGroupSync()
415 {
416  DeviceMemoryBarrier();
417  barrier();
418 }
419 
420 // MSDN: AllMemoryBarrier() blocks execution of all threads in a
421 // group until all memory accesses have been completed.
422 void AllMemoryBarrier()
423 {
424  // OpenGL.org: memoryBarrier() waits on the completion of ALL
425  // memory accesses resulting from the use of IMAGE variables or
426  // ATOMIC COUNTERS and then returns with no other effect.
427  memoryBarrier();
428  // NOTE: nothing is said about buffer memory and shared memory,
429  // so call memoryBarrierBuffer() and memoryBarrierShared() for safety
430 
431  // OpenGL.org: memoryBarrierBuffer() waits on the completion of
432  // all memory accesses resulting from the use of BUFFER variables
433  // and then returns with no other effect
434  memoryBarrierBuffer();
435 
436  // OpenGL.org: memoryBarrierShared() waits on the completion of
437  // all memory accesses resulting from the use of SHARED variables
438  // and then returns with no other effect.
439  memoryBarrierShared();
440 
441  // Call all memory barrier functions. They should have no effect
442  // if everything is synchronized.
443 
444  // OpenGL.org: memoryBarrierImage() waits on the completion of all
445  // memory accesses resulting from the use of IMAGE variables and then
446  // returns with no other effect.
447  memoryBarrierImage();
448 
449  // OpenGL.org: memoryBarrierAtomicCounter() waits on the completion of
450  // all accesses resulting from the use of ATOMIC COUNTERS and then returns
451  // with no other effect.
452  memoryBarrierAtomicCounter();
453 
454  // groupMemoryBarrier waits on the completion of all memory accesses performed
455  // by an invocation of a compute shader relative to the same access performed by
456  // other invocations in the same work group and then returns with no other effect.
457  groupMemoryBarrier();
458 }
459 
460 // MSDN: AllMemoryBarrierWithGroupSync() blocks execution of all
461 // threads in a group until all memory accesses have been completed
462 // and all threads in the group have reached this call.
463 void AllMemoryBarrierWithGroupSync()
464 {
465  AllMemoryBarrier();
466  barrier();
467 }
468 
469 #else
470 
471 void AllMemoryBarrier(){}
472 void AllMemoryBarrierWithGroupSync(){}
473 void DeviceMemoryBarrier(){}
474 void DeviceMemoryBarrierWithGroupSync(){}
475 void GroupMemoryBarrier(){}
476 void GroupMemoryBarrierWithGroupSync(){}
477 
478 #endif
479 
480 
481 // Type conversion functions
482 
483 vec4 _ExpandVector( float x ){ return vec4( x, x, x, x ); }
484 vec4 _ExpandVector( vec2 f2 ){ return vec4( f2.x, f2.y, 0.0, 0.0 ); }
485 vec4 _ExpandVector( vec3 f3 ){ return vec4( f3.x, f3.y, f3.z, 0.0 ); }
486 vec4 _ExpandVector( vec4 f4 ){ return vec4( f4.x, f4.y, f4.z, f4.w ); }
487 
488 ivec4 _ExpandVector( int x ){ return ivec4( x, x, x, x ); }
489 ivec4 _ExpandVector( ivec2 i2 ){ return ivec4( i2.x, i2.y, 0, 0 ); }
490 ivec4 _ExpandVector( ivec3 i3 ){ return ivec4( i3.x, i3.y, i3.z, 0 ); }
491 ivec4 _ExpandVector( ivec4 i4 ){ return ivec4( i4.x, i4.y, i4.z, i4.w ); }
492 
493 uvec4 _ExpandVector( uint x ){ return uvec4( x, x, x, x ); }
494 uvec4 _ExpandVector( uvec2 u2 ){ return uvec4( u2.x, u2.y, 0u, 0u ); }
495 uvec4 _ExpandVector( uvec3 u3 ){ return uvec4( u3.x, u3.y, u3.z, 0u ); }
496 uvec4 _ExpandVector( uvec4 u4 ){ return uvec4( u4.x, u4.y, u4.z, u4.w ); }
497 
498 bvec4 _ExpandVector( bool x ){ return bvec4( x, x, x, x ); }
499 bvec4 _ExpandVector( bvec2 b2 ){ return bvec4( b2.x, b2.y, false, false ); }
500 bvec4 _ExpandVector( bvec3 b3 ){ return bvec4( b3.x, b3.y, b3.z, false ); }
501 bvec4 _ExpandVector( bvec4 b4 ){ return bvec4( b4.x, b4.y, b4.z, b4.w ); }
502 
503 void _ResizeVector(out vec4 outVec4, in vec4 inVec4){outVec4 = inVec4;}
504 void _ResizeVector(out vec3 outVec3, in vec4 inVec4){outVec3 = inVec4.xyz;}
505 void _ResizeVector(out vec2 outVec2, in vec4 inVec4){outVec2 = inVec4.xy;}
506 void _ResizeVector(out float outFlt, in vec4 inVec4){outFlt = inVec4.x;}
507 
508 void _ResizeVector(out vec4 outVec4, in vec3 inVec3){outVec4 = vec4(inVec3, 0.0);}
509 void _ResizeVector(out vec3 outVec3, in vec3 inVec3){outVec3 = inVec3;}
510 void _ResizeVector(out vec2 outVec2, in vec3 inVec3){outVec2 = inVec3.xy;}
511 void _ResizeVector(out float outFlt, in vec3 inVec3){outFlt = inVec3.x;}
512 
513 void _ResizeVector(out vec4 outVec4, in vec2 inVec2){outVec4 = vec4(inVec2, 0.0, 0.0);}
514 void _ResizeVector(out vec3 outVec3, in vec2 inVec2){outVec3 = vec3(inVec2, 0.0);}
515 void _ResizeVector(out vec2 outVec2, in vec2 inVec2){outVec2 = inVec2;}
516 void _ResizeVector(out float outFlt, in vec2 inVec2){outFlt = inVec2.x;}
517 
518 void _ResizeVector(out vec4 outVec4, in float v){outVec4 = vec4(v, 0.0, 0.0, 0.0);}
519 void _ResizeVector(out vec3 outVec3, in float v){outVec3 = vec3(v, 0.0, 0.0);}
520 void _ResizeVector(out vec2 outVec2, in float v){outVec2 = vec2(v, 0.0);}
521 void _ResizeVector(out float outFlt, in float v){outFlt = v;}
522 
523 
524 void _TypeConvertStore( out float Dst, in int Src ){ Dst = float( Src ); }
525 void _TypeConvertStore( out float Dst, in uint Src ){ Dst = float( Src ); }
526 void _TypeConvertStore( out float Dst, in float Src ){ Dst = float( Src ); }
527 void _TypeConvertStore( out uint Dst, in int Src ){ Dst = uint( Src ); }
528 void _TypeConvertStore( out uint Dst, in uint Src ){ Dst = uint( Src ); }
529 void _TypeConvertStore( out uint Dst, in float Src ){ Dst = uint( Src ); }
530 void _TypeConvertStore( out int Dst, in int Src ){ Dst = int( Src ); }
531 void _TypeConvertStore( out int Dst, in uint Src ){ Dst = int( Src ); }
532 void _TypeConvertStore( out int Dst, in float Src ){ Dst = int( Src ); }
533 
534 int _ToInt( int x ) { return int(x); }
535 int _ToInt( uint x ) { return int(x); }
536 int _ToInt( float x ){ return int(x); }
537 int _ToInt( bool x ) { return x ? 1 : 0; }
538 
539 float _ToFloat( int x ) { return float(x); }
540 float _ToFloat( uint x ) { return float(x); }
541 float _ToFloat( float x ){ return float(x); }
542 float _ToFloat( bool x ) { return x ? 1.0 : 0.0;}
543 
544 uint _ToUint( int x ) { return uint(x); }
545 uint _ToUint( uint x ) { return uint(x); }
546 uint _ToUint( float x ){ return uint(x); }
547 uint _ToUint( bool x ) { return x ? 1u : 0u; }
548 
549 bool _ToBool( int x ) { return x != 0 ? true : false; }
550 bool _ToBool( uint x ) { return x != 0u ? true : false; }
551 bool _ToBool( float x ){ return x != 0.0 ? true : false; }
552 bool _ToBool( bool x ) { return x; }
553 
554 #define _ToVec2(x,y) vec2(_ToFloat(x), _ToFloat(y))
555 #define _ToVec3(x,y,z) vec3(_ToFloat(x), _ToFloat(y), _ToFloat(z))
556 #define _ToVec4(x,y,z,w) vec4(_ToFloat(x), _ToFloat(y), _ToFloat(z), _ToFloat(w))
557 
558 #define _ToIvec2(x,y) ivec2(_ToInt(x), _ToInt(y))
559 #define _ToIvec3(x,y,z) ivec3(_ToInt(x), _ToInt(y), _ToInt(z))
560 #define _ToIvec4(x,y,z,w) ivec4(_ToInt(x), _ToInt(y), _ToInt(z), _ToInt(w))
561 
562 #define _ToUvec2(x,y) uvec2(_ToUint(x), _ToUint(y))
563 #define _ToUvec3(x,y,z) uvec3(_ToUint(x), _ToUint(y), _ToUint(z))
564 #define _ToUvec4(x,y,z,w) uvec4(_ToUint(x), _ToUint(y), _ToUint(z), _ToUint(w))
565 
566 #define _ToBvec2(x,y) bvec2(_ToBool(x), _ToBool(y))
567 #define _ToBvec3(x,y,z) bvec3(_ToBool(x), _ToBool(y), _ToBool(z))
568 #define _ToBvec4(x,y,z,w) bvec4(_ToBool(x), _ToBool(y), _ToBool(z), _ToBool(w))
569 
570 
571 int _ToIvec( uint u1 ){ return _ToInt( u1 ); }
572 ivec2 _ToIvec( uvec2 u2 ){ return _ToIvec2( u2.x, u2.y ); }
573 ivec3 _ToIvec( uvec3 u3 ){ return _ToIvec3( u3.x, u3.y, u3.z ); }
574 ivec4 _ToIvec( uvec4 u4 ){ return _ToIvec4( u4.x, u4.y, u4.z, u4.w ); }
575 
576 int _ToIvec( int i1 ){ return i1; }
577 ivec2 _ToIvec( ivec2 i2 ){ return i2; }
578 ivec3 _ToIvec( ivec3 i3 ){ return i3; }
579 ivec4 _ToIvec( ivec4 i4 ){ return i4; }
580 
581 int _ToIvec( float f1 ){ return _ToInt( f1 ); }
582 ivec2 _ToIvec( vec2 f2 ){ return _ToIvec2( f2.x, f2.y ); }
583 ivec3 _ToIvec( vec3 f3 ){ return _ToIvec3( f3.x, f3.y, f3.z ); }
584 ivec4 _ToIvec( vec4 f4 ){ return _ToIvec4( f4.x, f4.y, f4.z, f4.w ); }
585 
586 
587 float _ToVec( uint u1 ){ return _ToFloat(u1); }
588 vec2 _ToVec( uvec2 u2 ){ return _ToVec2( u2.x, u2.y ); }
589 vec3 _ToVec( uvec3 u3 ){ return _ToVec3( u3.x, u3.y, u3.z ); }
590 vec4 _ToVec( uvec4 u4 ){ return _ToVec4( u4.x, u4.y, u4.z, u4.w ); }
591 
592 float _ToVec( int i1 ){ return _ToFloat(i1); }
593 vec2 _ToVec( ivec2 i2 ){ return _ToVec2( i2.x, i2.y ); }
594 vec3 _ToVec( ivec3 i3 ){ return _ToVec3( i3.x, i3.y, i3.z ); }
595 vec4 _ToVec( ivec4 i4 ){ return _ToVec4( i4.x, i4.y, i4.z, i4.w ); }
596 
597 float _ToVec( float f1 ){ return f1; }
598 vec2 _ToVec( vec2 f2 ){ return f2; }
599 vec3 _ToVec( vec3 f3 ){ return f3; }
600 vec4 _ToVec( vec4 f4 ){ return f4; }
601 
602 
603 uint _ToUvec( uint u1 ){ return u1; }
604 uvec2 _ToUvec( uvec2 u2 ){ return u2; }
605 uvec3 _ToUvec( uvec3 u3 ){ return u3; }
606 uvec4 _ToUvec( uvec4 u4 ){ return u4; }
607 
608 uint _ToUvec( int i1 ){ return _ToUint( i1 ); }
609 uvec2 _ToUvec( ivec2 i2 ){ return _ToUvec2( i2.x, i2.y ); }
610 uvec3 _ToUvec( ivec3 i3 ){ return _ToUvec3( i3.x, i3.y, i3.z ); }
611 uvec4 _ToUvec( ivec4 i4 ){ return _ToUvec4( i4.x, i4.y, i4.z, i4.w ); }
612 
613 uint _ToUvec( float f1 ){ return _ToUint( f1 ); }
614 uvec2 _ToUvec( vec2 f2 ){ return _ToUvec2( f2.x, f2.y ); }
615 uvec3 _ToUvec( vec3 f3 ){ return _ToUvec3( f3.x, f3.y, f3.z ); }
616 uvec4 _ToUvec( vec4 f4 ){ return _ToUvec4( f4.x, f4.y, f4.z, f4.w ); }
617 
618 
619 // TEXTURE FUNCTION STUB MACROS
620 // https://www.opengl.org/wiki/Sampler_(GLSL)
621 
622 
623 // Texture size queries
624 // https://www.opengl.org/sdk/docs/man/html/textureSize.xhtml
625 // textureSize returns the dimensions of level lod (if present) of the texture bound to sampler.
626 // The components in the return value are filled in, in order, with the width, height and depth
627 // of the texture. For the array forms, the last component of the return value is the number of
628 // layers in the texture array.
629 
630 //#if !(defined(DESKTOP_GL) && __VERSION__ >= 430)
631 # define textureQueryLevels(x) 0 // Only supported on 4.3+
632 //#endif
633 
634 #define GetTex1DDimensions_1(Sampler, Width)\
635 { \
636  _TypeConvertStore( Width, textureSize(Sampler, 0) );\
637 }
638 
639 #define GetTex1DDimensions_3(Sampler, MipLevel, Width, NumberOfMipLevels)\
640 { \
641  _TypeConvertStore( Width, textureSize(Sampler, _ToInt(MipLevel)) ); \
642  _TypeConvertStore( NumberOfMipLevels, textureQueryLevels(Sampler) ); \
643 }
644 
645 #define GetTex1DArrDimensions_2(Sampler, Width, Elements)\
646 { \
647  ivec2 i2Size = textureSize(Sampler, 0); \
648  _TypeConvertStore( Width, i2Size.x );\
649  _TypeConvertStore( Elements, i2Size.y );\
650 }
651 
652 #define GetTex1DArrDimensions_4(Sampler, MipLevel, Width, Elements, NumberOfMipLevels)\
653 { \
654  ivec2 i2Size = textureSize(Sampler, _ToInt(MipLevel)); \
655  _TypeConvertStore( Width, i2Size.x ); \
656  _TypeConvertStore( Elements, i2Size.y ); \
657  _TypeConvertStore( NumberOfMipLevels, textureQueryLevels(Sampler) );\
658 }
659 
660 #define GetTex2DDimensions_2(Sampler, Width, Height)\
661 { \
662  ivec2 i2Size = textureSize(Sampler, 0); \
663  _TypeConvertStore( Width, i2Size.x ); \
664  _TypeConvertStore( Height, i2Size.y ); \
665 }
666 
667 #define GetTex2DDimensions_4(Sampler, MipLevel, Width, Height, NumberOfMipLevels)\
668 { \
669  ivec2 i2Size = textureSize(Sampler, _ToInt(MipLevel) ); \
670  _TypeConvertStore( Width, i2Size.x ); \
671  _TypeConvertStore( Height, i2Size.y ); \
672  _TypeConvertStore( NumberOfMipLevels, textureQueryLevels(Sampler) );\
673 }
674 
675 #define GetTex2DArrDimensions_3(Sampler, Width, Height, Elements)\
676 { \
677  ivec3 i3Size = textureSize(Sampler, 0); \
678  _TypeConvertStore( Width, i3Size.x ); \
679  _TypeConvertStore( Height, i3Size.y ); \
680  _TypeConvertStore( Elements,i3Size.z ); \
681 }
682 
683 #define GetTex2DArrDimensions_5(Sampler, MipLevel, Width, Height, Elements, NumberOfMipLevels)\
684 { \
685  ivec3 i3Size = textureSize(Sampler, _ToInt(MipLevel)); \
686  _TypeConvertStore( Width, i3Size.x ); \
687  _TypeConvertStore( Height, i3Size.y ); \
688  _TypeConvertStore( Elements, i3Size.z ); \
689  _TypeConvertStore( NumberOfMipLevels, textureQueryLevels(Sampler) );\
690 }
691 
692 #define GetTex3DDimensions_3(Sampler, Width, Height, Depth)\
693 { \
694  ivec3 i3Size = textureSize(Sampler, 0); \
695  _TypeConvertStore( Width, i3Size.x ); \
696  _TypeConvertStore( Height, i3Size.y ); \
697  _TypeConvertStore( Depth, i3Size.z ); \
698 }
699 
700 #define GetTex3DDimensions_5(Sampler, MipLevel, Width, Height, Depth, NumberOfMipLevels)\
701 { \
702  ivec3 i3Size = textureSize(Sampler, _ToInt(MipLevel)); \
703  _TypeConvertStore( Width, i3Size.x ); \
704  _TypeConvertStore( Height, i3Size.y ); \
705  _TypeConvertStore( Depth, i3Size.z ); \
706  _TypeConvertStore( NumberOfMipLevels, textureQueryLevels(Sampler) );\
707 }
708 
709 #define GetTex2DMSDimensions_3(Sampler, Width, Height, NumberOfSamples)\
710 { \
711  ivec2 i2Size = textureSize(Sampler); \
712  _TypeConvertStore( Width, i2Size.x ); \
713  _TypeConvertStore( Height, i2Size.y ); \
714  _TypeConvertStore( NumberOfSamples, 0 );\
715 }
716 
717 #define GetTex2DMSArrDimensions_4(Sampler, Width, Height, Elements, NumberOfSamples)\
718 { \
719  ivec3 i3Size = textureSize(Sampler); \
720  _TypeConvertStore( Width, i3Size.x );\
721  _TypeConvertStore( Height, i3Size.y );\
722  _TypeConvertStore( Elements, i3Size.z );\
723  _TypeConvertStore( NumberOfSamples, 0 );\
724 }
725 
726 
727 // https://www.opengl.org/sdk/docs/man/html/imageSize.xhtml
728 // imageSize returns the dimensions of the image bound to image. The components in the
729 // return value are filled in, in order, with the width, height and depth of the image.
730 // For the array forms, the last component of the return value is the number of layers
731 // in the texture array.
732 
733 #define GetRWTex1DDimensions_1(Tex, Width)\
734 { \
735  _TypeConvertStore( Width, imageSize(Tex) ); \
736 }
737 
738 #define GetRWTex1DArrDimensions_2(Tex, Width, Elements)\
739 { \
740  ivec2 i2Size = imageSize(Tex); \
741  _TypeConvertStore( Width, i2Size.x ); \
742  _TypeConvertStore( Elements, i2Size.y ); \
743 }
744 
745 #define GetRWTex2DDimensions_2(Tex, Width, Height)\
746 { \
747  ivec2 i2Size = imageSize(Tex); \
748  _TypeConvertStore( Width, i2Size.x ); \
749  _TypeConvertStore( Height, i2Size.y ); \
750 }
751 
752 #define GetRWTex2DArrDimensions_3(Tex, Width, Height, Elements)\
753 { \
754  ivec3 i3Size = imageSize(Tex); \
755  _TypeConvertStore( Width, i3Size.x );\
756  _TypeConvertStore( Height, i3Size.y );\
757  _TypeConvertStore( Elements, i3Size.z );\
758 }
759 
760 #define GetRWTex3DDimensions_3(Tex, Width, Height, Depth)\
761 { \
762  ivec3 i3Size = imageSize(Tex); \
763  _TypeConvertStore( Width, i3Size.x ); \
764  _TypeConvertStore( Height, i3Size.y ); \
765  _TypeConvertStore( Depth, i3Size.z ); \
766 }
767 
768 
769 
770 // Texture sampling operations
771 
772 
773 // IMPORTANT NOTE ABOUT OFFSET
774 // Offset parameter to all texture sampling functions must be a constant expression.
775 // If it is not, the shader will be successfully compiled, HOWEVER the value of Offset
776 // will silently be zero.
777 //
778 // A constant expression in GLSL is defined as follows:
779 // * A literal value.
780 // * A const-qualified variable with an explicit initializer (so not a function parameter).
781 // * The result of the length() function of an array, but only if the array has an explicit size.
782 // * The result of most operators, so long as all the operands are themselves constant expressions.
783 // The operators not on this list are any assignment operators (+= and so forth), and the comma operator.
784 // * The result of a constructor for a type, but only if all of the arguments to the constructor are
785 // themselves constant expressions.
786 // * The return value of any built-in function, but only if all of the arguments to the function are
787 // themselves constant expressions. Opaque Types are never constant expressions. Note that the
788 // functions dFdx, dFdy, and fwidth will return 0, when used in a context that requires a constant
789 // expression (such as a const variable initializer).
790 //
791 // The list above does not include return value of a function, even when the value is compile-time expression.
792 // As a result, we cannot use type conversion functions for Offset parameter.
793 
794 // In all texture sampling functions, the last component of Coords is used as Dsub and the array layer is specified
795 // in the second to last component of Coords. (The second component of Coords is unused for 1D shadow lookups.)
796 // For cube array textures, Dsub is specified as a separate parameter
797 // mip
798 #define SampleCmpLevel0Tex1D_3(Tex, Sampler, Coords, CompareValue) textureLod(Tex, _ToVec3((Coords).x, 0.0, CompareValue), 0.0)
799 #define SampleCmpLevel0Tex1DArr_3(Tex, Sampler, Coords, CompareValue) textureLod(Tex, _ToVec3((Coords).x, (Coords).y, CompareValue), 0.0)
800 #define SampleCmpLevel0Tex2D_3(Tex, Sampler, Coords, CompareValue) textureLod(Tex, _ToVec3((Coords).x, (Coords).y, CompareValue), 0.0)
801 #define SampleCmpLevel0Tex2DArr_3(Tex, Sampler, Coords, CompareValue) 0.0 // No textureLod for sampler2DArrayShadow
802 #define SampleCmpLevel0TexCube_3(Tex, Sampler, Coords, CompareValue) 0.0 // No textureLod for samplerCubeShadow
803 #define SampleCmpLevel0TexCubeArr_3(Tex, Sampler, Coords, CompareValue) 0.0 // No textureLod for samplerCubeArrayShadow
804 
805 // mip
806 #define SampleCmpLevel0Tex1D_4(Tex, Sampler, Coords, CompareValue, Offset) textureLodOffset(Tex, _ToVec3((Coords).x, 0.0, CompareValue), 0.0, int(Offset))
807 #define SampleCmpLevel0Tex1DArr_4(Tex, Sampler, Coords, CompareValue, Offset) textureLodOffset(Tex, _ToVec3((Coords).x, (Coords).y, CompareValue), 0.0, int(Offset))
808 #define SampleCmpLevel0Tex2D_4(Tex, Sampler, Coords, CompareValue, Offset) textureLodOffset(Tex, _ToVec3((Coords).x, (Coords).y, CompareValue), 0.0, ivec2((Offset).xy))
809 #define SampleCmpLevel0Tex2DArr_4(Tex, Sampler, Coords, CompareValue, Offset) 0.0 // No textureLodOffset for sampler2DArrayShadow
810 
811 
812 // https://www.opengl.org/sdk/docs/man/html/texture.xhtml - note: there are many mistakes on the page
813 #ifdef FRAGMENT_SHADER
814 
815 # define Sample_2(Tex, Sampler, Coords) texture (Tex, _ToVec(Coords))
816 # define Sample_3(Tex, Sampler, Coords, Offset) textureOffset(Tex, _ToVec(Coords), Offset)
817 # define SampleBias_3(Tex, Sampler, Coords, Bias) texture (Tex, _ToVec(Coords), _ToFloat(Bias))
818 # define SampleBias_4(Tex, Sampler, Coords, Bias, Offset) textureOffset(Tex, _ToVec(Coords), Offset, _ToFloat(Bias))
819 
820 # define SampleCmpTex1D_3(Tex, Sampler, Coords, CompareValue) texture(Tex, _ToVec3((Coords).x, 0.0, CompareValue))
821 # define SampleCmpTex1DArr_3(Tex, Sampler, Coords, CompareValue) texture(Tex, _ToVec3((Coords).x, (Coords).y, CompareValue))
822 # define SampleCmpTex2D_3(Tex, Sampler, Coords, CompareValue) texture(Tex, _ToVec3((Coords).x, (Coords).y, CompareValue))
823 # define SampleCmpTex2DArr_3(Tex, Sampler, Coords, CompareValue) texture(Tex, _ToVec4((Coords).x, (Coords).y, (Coords).z, CompareValue))
824 # define SampleCmpTexCube_3(Tex, Sampler, Coords, CompareValue) texture(Tex, _ToVec4((Coords).x, (Coords).y, (Coords).z, CompareValue))
825 # define SampleCmpTexCubeArr_3(Tex, Sampler, Coords, CompareValue) texture(Tex, _ToVec4((Coords).x, (Coords).y, (Coords).z, (Coords).w), _ToFloat(CompareValue))
826 
827 # define SampleCmpTex1D_4(Tex, Sampler, Coords, CompareValue, Offset) textureOffset(Tex, _ToVec3((Coords).x, 0.0, CompareValue), int(Offset))
828 # define SampleCmpTex1DArr_4(Tex, Sampler, Coords, CompareValue, Offset) textureOffset(Tex, _ToVec3((Coords).x, (Coords).y, CompareValue), int(Offset))
829 # define SampleCmpTex2D_4(Tex, Sampler, Coords, CompareValue, Offset) textureOffset(Tex, _ToVec3((Coords).x, (Coords).y, CompareValue), ivec2((Offset).xy))
830 # define SampleCmpTex2DArr_4(Tex, Sampler, Coords, CompareValue, Offset) textureOffset(Tex, _ToVec4((Coords).x, (Coords).y, (Coords).z, CompareValue), ivec2((Offset).xy))
831 
832 #else
833 
834 // Derivatives are only available in fragment shader. GLSL compiler fails when it
835 // encounters texture() or textureOffset() instructions in other types of shaders. So
836 // to let the shader be compiled and to have something meaningful, replace such operations
837 // with textureLod() and textureLodOffset()
838 
839 # define Sample_2(Tex, Sampler, Coords) textureLod (Tex, _ToVec(Coords), 0.0)
840 # define Sample_3(Tex, Sampler, Coords, Offset) textureLodOffset(Tex, _ToVec(Coords), 0.0, Offset)
841 # define SampleBias_3(Tex, Sampler, Coords, Bias) textureLod (Tex, _ToVec(Coords), 0.0 + _ToFloat(Bias))
842 # define SampleBias_4(Tex, Sampler, Coords, Bias, Offset) textureLodOffset(Tex, _ToVec(Coords), 0.0 + _ToFloat(Bias), Offset)
843 
844 # define SampleCmpTex1D_3 SampleCmpLevel0Tex1D_3
845 # define SampleCmpTex1DArr_3 SampleCmpLevel0Tex1DArr_3
846 # define SampleCmpTex2D_3 SampleCmpLevel0Tex2D_3
847 # define SampleCmpTex2DArr_3 SampleCmpLevel0Tex2DArr_3
848 # define SampleCmpTexCube_3 SampleCmpLevel0TexCube_3
849 # define SampleCmpTexCubeArr_3 SampleCmpLevel0TexCubeArr_3
850 
851 # define SampleCmpTex1D_4 SampleCmpLevel0Tex1D_4
852 # define SampleCmpTex1DArr_4 SampleCmpLevel0Tex1DArr_4
853 # define SampleCmpTex2D_4 SampleCmpLevel0Tex2D_4
854 # define SampleCmpTex2DArr_4 SampleCmpLevel0Tex2DArr_4
855 
856 #endif
857 
858 // https://www.opengl.org/sdk/docs/man/html/textureLod.xhtml
859 #define SampleLevel_3(Tex, Sampler, Coords, Level) textureLod (Tex, _ToVec(Coords), _ToFloat(Level))
860 #define SampleLevel_4(Tex, Sampler, Coords, Level, Offset) textureLodOffset(Tex, _ToVec(Coords), _ToFloat(Level), Offset)
861 
862 // https://www.opengl.org/sdk/docs/man/html/textureGrad.xhtml
863 #define SampleGrad_4(Tex, Sampler, Coords, DDX, DDY) textureGrad (Tex, _ToVec(Coords), _ToVec(DDX), _ToVec(DDY))
864 #define SampleGrad_5(Tex, Sampler, Coords, DDX, DDY, Offset) textureGradOffset(Tex, _ToVec(Coords), _ToVec(DDX), _ToVec(DDY), Offset)
865 
866 
867 // texelFetch performs a lookup of a single texel from texture coordinate P in the texture
868 // bound to sampler. The array layer is specified in the last component of P for array forms.
869 // The lod parameter (if present) specifies the level-of-detail from which the texel will be fetched.
870 // The sample specifies which sample within the texel will be returned when reading from a multi-sample texure.
871 
872 #define LoadTex1D_1(Tex, Location) texelFetch (Tex, _ToInt((Location).x), _ToInt((Location).y))
873 #define LoadTex1D_2(Tex, Location, Offset)texelFetchOffset(Tex, _ToInt((Location).x), _ToInt((Location).y), int(Offset))
874 #define LoadTex1DArr_1(Tex, Location) texelFetch (Tex, _ToIvec( (Location).xy), _ToInt((Location).z) )
875 #define LoadTex1DArr_2(Tex, Location, Offset)texelFetchOffset(Tex, _ToIvec( (Location).xy), _ToInt((Location).z), int(Offset))
876 #define LoadTex2D_1(Tex, Location) texelFetch (Tex, _ToIvec( (Location).xy), _ToInt((Location).z))
877 #define LoadTex2D_2(Tex, Location, Offset)texelFetchOffset(Tex, _ToIvec( (Location).xy), _ToInt((Location).z), ivec2( (Offset).xy) )
878 #define LoadTex2DArr_1(Tex, Location) texelFetch (Tex, _ToIvec( (Location).xyz), _ToInt((Location).w) )
879 #define LoadTex2DArr_2(Tex, Location, Offset)texelFetchOffset(Tex, _ToIvec( (Location).xyz), _ToInt((Location).w), ivec2( (Offset).xy))
880 #define LoadTex3D_1(Tex, Location) texelFetch (Tex, _ToIvec( (Location).xyz), _ToInt((Location).w))
881 #define LoadTex3D_2(Tex, Location, Offset)texelFetchOffset(Tex, _ToIvec( (Location).xyz), _ToInt((Location).w), ivec3( (Offset).xyz))
882 #define LoadTex2DMS_2(Tex, Location, Sample) texelFetch(Tex, _ToIvec( (Location).xy), _ToInt(Sample))
883 #define LoadTex2DMS_3(Tex, Location, Sample, Offset)texelFetch(Tex, _ToIvec2( (Location).x + (Offset).x, (Location).y + (Offset).y), int(Sample) ) // No texelFetchOffset for texture2DMS
884 #define LoadTex2DMSArr_2(Tex, Location, Sample) texelFetch(Tex, _ToIvec( (Location).xyz), _ToInt(Sample))
885 #define LoadTex2DMSArr_3(Tex, Location, Sample, Offset)texelFetch(Tex, _ToIvec3( (Location).x + (Offset).x, (Location).y + (Offset).y, (Location).z), int(Sample)) // No texelFetchOffset for texture2DMSArray
886 
887 //https://www.opengl.org/sdk/docs/man/html/imageLoad.xhtml
888 #define LoadRWTex1D_1(Tex, Location) imageLoad(Tex, _ToIvec((Location).x) )
889 #define LoadRWTex1DArr_1(Tex, Location) imageLoad(Tex, _ToIvec((Location).xy) )
890 #define LoadRWTex2D_1(Tex, Location) imageLoad(Tex, _ToIvec((Location).xy) )
891 #define LoadRWTex2DArr_1(Tex, Location) imageLoad(Tex, _ToIvec((Location).xyz) )
892 #define LoadRWTex3D_1(Tex, Location) imageLoad(Tex, _ToIvec((Location).xyz) )
893 
894 
895 #define Gather_2(Tex, Sampler, Location) textureGather (Tex, _ToVec(Location))
896 #define Gather_3(Tex, Sampler, Location, Offset)textureGatherOffset(Tex, _ToVec(Location), Offset)
897 
898 #define GatherCmp_3(Tex, Sampler, Location, CompareVal) textureGather (Tex, _ToVec(Location), _ToFloat(CompareVal))
899 #define GatherCmp_4(Tex, Sampler, Location, CompareVal, Offset)textureGatherOffset(Tex, _ToVec(Location), _ToFloat(CompareVal), Offset)
900 
901 // Atomic operations
902 #define InterlockedAddSharedVar_2(dest, value) atomicAdd(dest, value)
903 #define InterlockedAddSharedVar_3(dest, value, orig_val) orig_val = atomicAdd(dest, value)
904 #define InterlockedAddImage_2(img, coords, value) imageAtomicAdd(img, _ToIvec(coords), value)
905 #define InterlockedAddImage_3(img, coords, value, orig_val)orig_val = imageAtomicAdd(img, _ToIvec(coords), value)
906 
907 #define InterlockedAndSharedVar_2(dest, value) atomicAnd(dest, value)
908 #define InterlockedAndSharedVar_3(dest, value, orig_val) orig_val = atomicAnd(dest, value)
909 #define InterlockedAndImage_2(img, coords, value) imageAtomicAnd(img, _ToIvec(coords), value)
910 #define InterlockedAndImage_3(img, coords, value, orig_val)orig_val = imageAtomicAnd(img, _ToIvec(coords), value)
911 
912 #define InterlockedMaxSharedVar_2(dest, value) atomicMax(dest, value)
913 #define InterlockedMaxSharedVar_3(dest, value, orig_val) orig_val = atomicMax(dest, value)
914 #define InterlockedMaxImage_2(img, coords, value) imageAtomicMax(img, _ToIvec(coords), value)
915 #define InterlockedMaxImage_3(img, coords, value, orig_val)orig_val = imageAtomicMax(img, _ToIvec(coords), value)
916 
917 #define InterlockedMinSharedVar_2(dest, value) atomicMin(dest, value)
918 #define InterlockedMinSharedVar_3(dest, value, orig_val) orig_val = atomicMin(dest, value)
919 #define InterlockedMinImage_2(img, coords, value) imageAtomicMin(img, _ToIvec(coords), value)
920 #define InterlockedMinImage_3(img, coords, value, orig_val)orig_val = imageAtomicMin(img, _ToIvec(coords), value)
921 
922 #define InterlockedOrSharedVar_2(dest, value) atomicOr(dest, value)
923 #define InterlockedOrSharedVar_3(dest, value, orig_val) orig_val = atomicOr(dest, value)
924 #define InterlockedOrImage_2(img, coords, value) imageAtomicOr(img, _ToIvec(coords), value)
925 #define InterlockedOrImage_3(img, coords, value, orig_val)orig_val = imageAtomicOr(img, _ToIvec(coords), value)
926 
927 #define InterlockedXorSharedVar_2(dest, value) atomicXor(dest, value)
928 #define InterlockedXorSharedVar_3(dest, value, orig_val) orig_val = atomicXor(dest, value)
929 #define InterlockedXorImage_2(img, coords, value) imageAtomicXor(img, _ToIvec(coords), value)
930 #define InterlockedXorImage_3(img, coords, value, orig_val)orig_val = imageAtomicXor(img, _ToIvec(coords), value)
931 
932 // There is actually no InterlockedExchange() with 2 arguments
933 #define InterlockedExchangeSharedVar_2(dest, value) atomicExchange(dest, value)
934 #define InterlockedExchangeSharedVar_3(dest, value, orig_val) orig_val = atomicExchange(dest, value)
935 #define InterlockedExchangeImage_2(img, coords, value) imageAtomicExchange(img, _ToIvec(coords), value)
936 #define InterlockedExchangeImage_3(img, coords, value, orig_val)orig_val = imageAtomicExchange(img, _ToIvec(coords), value)
937 
938 //uint imageAtomicCompSwap( image img, IVec P, nint compare, nint data);
939 //void InterlockedCompareExchange( in R dest, in T compare_value, in T value, out T original_value);
940 #define InterlockedCompareExchangeSharedVar_4(dest, cmp_val, value, orig_val) orig_val = atomicCompSwap(dest, cmp_val, value)
941 #define InterlockedCompareExchangeImage_4(img, coords, cmp_val, value, orig_val) orig_val = imageAtomicCompSwap(img, _ToIvec(coords), cmp_val, value)
942 
943 #define InterlockedCompareStoreSharedVar_3(dest, cmp_val, value) atomicCompSwap(dest, cmp_val, value)
944 #define InterlockedCompareStoreImage_3(img, coords, cmp_val, value)imageAtomicCompSwap(img, _ToIvec(coords), cmp_val, value)
945 
946 
947 // Swizzling macros
948 #define _SWIZZLE0
949 #define _SWIZZLE1 .x
950 #define _SWIZZLE2 .xy
951 #define _SWIZZLE3 .xyz
952 #define _SWIZZLE4 .xyzw
953 
954 // Helper functions
955 
956 float2 NormalizedDeviceXYToTexUV( float2 f2ProjSpaceXY )
957 {
958  return float2(0.5,0.5) + float2(0.5,0.5) * f2ProjSpaceXY.xy;
959 }
960 
961 float NormalizedDeviceZToDepth(float fNDC_Z)
962 {
963  return fNDC_Z * 0.5 + 0.5; // [-1, +1] -> [0, 1]
964 }
965 
966 float DepthToNormalizedDeviceZ(float fDepth)
967 {
968  return fDepth * 2.0 - 1.0; // [0, 1] -> [-1, +1]
969 }
970 
971 #define F3NDC_XYZ_TO_UVD_SCALE float3(0.5, 0.5, 0.5)
972 
973 #define NDC_MIN_Z -1.0 // Minimal z in the normalized device space
974 
975 #define MATRIX_ELEMENT(mat, row, col) mat[col][row]
976 
977 // ---------------------------------- Vertex shader ----------------------------------
978 #ifdef VERTEX_SHADER
979 
980 #ifndef GL_ES
981 out gl_PerVertex
982 {
983  vec4 gl_Position;
984 };
985 #endif
986 
987 #define _GET_GL_VERTEX_ID(VertexId)_TypeConvertStore(VertexId, gl_VertexID)
988 #define _GET_GL_INSTANCE_ID(InstId)_TypeConvertStore(InstId, gl_InstanceID)
989 #define _SET_GL_POSITION(Pos)gl_Position=_ExpandVector(Pos)
990 
991 #endif
992 
993 
994 // --------------------------------- Fragment shader ---------------------------------
995 #ifdef FRAGMENT_SHADER
996 
997 #define _GET_GL_FRAG_COORD(FragCoord)_ResizeVector(FragCoord, gl_FragCoord)
998 #define _SET_GL_FRAG_DEPTH(Depth)_TypeConvertStore(gl_FragDepth, Depth)
999 
1000 #endif
1001 
1002 
1003 // --------------------------------- Geometry shader ---------------------------------
1004 #ifdef GEOMETRY_SHADER
1005 
1006 // ARB_separate_shader_objects requires built-in block gl_PerVertex to be redeclared before accessing its members
1007 // declaring gl_PointSize and gl_ClipDistance causes compilation error on Android
1008 in gl_PerVertex
1009 {
1010  vec4 gl_Position;
1011  //float gl_PointSize;
1012  //float gl_ClipDistance[];
1013 } gl_in[];
1014 
1015 out gl_PerVertex
1016 {
1017  vec4 gl_Position;
1018  //float gl_PointSize;
1019  //float gl_ClipDistance[];
1020 };
1021 
1022 #define _GET_GL_POSITION(Pos)_ResizeVector(Pos, gl_in[i].gl_Position)
1023 #define _GET_GL_PRIMITIVE_ID(PrimId)_TypeConvertStore(PrimId, gl_in[i].gl_PrimitiveIDIn)
1024 
1025 #define _SET_GL_POSITION(Pos)gl_Position=_ExpandVector(Pos)
1026 #define _SET_GL_LAYER(Layer)_TypeConvertStore(gl_Layer,Layer)
1027 
1028 #endif
1029 
1030 
1031 // --------------------------- Tessellation control shader ---------------------------
1032 #ifdef TESS_CONTROL_SHADER
1033 
1034 in gl_PerVertex
1035 {
1036  vec4 gl_Position;
1037  //float gl_PointSize;
1038  //float gl_ClipDistance[];
1039 } gl_in[gl_MaxPatchVertices];
1040 
1041 out gl_PerVertex
1042 {
1043  vec4 gl_Position;
1044  //float gl_PointSize;
1045  //float gl_ClipDistance[];
1046 } gl_out[];
1047 
1048 #define _GET_GL_INVOCATION_ID(InvocId)_TypeConvertStore(InvocId, gl_InvocationID)
1049 #define _GET_GL_PRIMITIVE_ID(PrimId)_TypeConvertStore(PrimId, gl_PrimitiveID)
1050 #define _GET_GL_POSITION(Pos)_ResizeVector(Pos, gl_in[i].gl_Position)
1051 
1052 #define _SET_GL_POSITION(Pos)gl_out[gl_InvocationID].gl_Position=_ExpandVector(Pos)
1053 #define _SET_GL_TESS_LEVEL_OUTER(OuterLevel)for(int i=0; i < OuterLevel.length(); ++i)gl_TessLevelOuter[i] = OuterLevel[i]
1054 
1055 void _SetGLTessLevelInner(float InnerLevel[2])
1056 {
1057  gl_TessLevelInner[0] = InnerLevel[0];
1058  gl_TessLevelInner[1] = InnerLevel[1];
1059 }
1060 void _SetGLTessLevelInner(float InnerLevel)
1061 {
1062  gl_TessLevelInner[0] = InnerLevel;
1063 }
1064 
1065 #endif
1066 
1067 
1068 // --------------------------- Tessellation evaluation shader ---------------------------
1069 #ifdef TESS_EVALUATION_SHADER
1070 
1071 in gl_PerVertex
1072 {
1073  vec4 gl_Position;
1074  //float gl_PointSize;
1075  //float gl_ClipDistance[];
1076 } gl_in[gl_MaxPatchVertices];
1077 
1078 out gl_PerVertex
1079 {
1080  vec4 gl_Position;
1081  //float gl_PointSize;
1082  //float gl_ClipDistance[];
1083 };
1084 
1085 #define _GET_GL_POSITION(Pos)_ResizeVector(Pos, gl_in[i].gl_Position)
1086 #define _GET_GL_TESS_LEVEL_OUTER(OuterLevel)for(int i=0; i < OuterLevel.length(); ++i)OuterLevel[i] = gl_TessLevelOuter[i]
1087 void _GetGLTessLevelInner(out float InnerLevel[2])
1088 {
1089  InnerLevel[0] = gl_TessLevelInner[0];
1090  InnerLevel[1] = gl_TessLevelInner[1];
1091 }
1092 void _GetGLTessLevelInner(out float InnerLevel)
1093 {
1094  InnerLevel = gl_TessLevelInner[0];
1095 }
1096 
1097 #define _GET_GL_TESS_COORD(TessCoord)_ResizeVector(TessCoord, gl_TessCoord)
1098 #define _GET_GL_PRIMITIVE_ID(PrimId)_TypeConvertStore(PrimId, gl_PrimitiveID)
1099 
1100 #define _SET_GL_POSITION(Pos)gl_Position=_ExpandVector(Pos)
1101 
1102 #endif
1103 
1104 
1105 // ---------------------------------- Compute shader ----------------------------------
1106 #ifdef COMPUTE_SHADER
1107 
1108 #define _GET_GL_GLOBAL_INVOCATION_ID(Type, InvocId)InvocId=Type(gl_GlobalInvocationID)
1109 #define _GET_GL_WORK_GROUP_ID(Type, GroupId)GroupId=Type(gl_WorkGroupID)
1110 #define _GET_GL_LOCAL_INVOCATION_ID(Type, InvocId)InvocId=Type(gl_LocalInvocationID)
1111 #define _GET_GL_LOCAL_INVOCATION_INDEX(Type, InvocInd)InvocInd=Type(gl_LocalInvocationIndex)
1112 
1113 #endif
1114 
1115 #endif // _GLSL_DEFINITIONS_