Skip to content

Do explicit uint casting in GLSL operations #1613

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions src/engine/renderer/gl_shader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -529,8 +529,19 @@ static std::string GenCompatHeader() {
str += "float smoothstep(float edge0, float edge1, float x) { float t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0); return t * t * (3.0 - 2.0 * t); }\n";
}

if ( !glConfig2.gpuShader5Available ) {
str += "#define unpackUnorm4x8( value ) ( ( vec4( value, value >> 8, value >> 16, value >> 24 ) & 0xFF ) / 255.0f )\n";
if ( !glConfig2.gpuShader5Available && glConfig2.gpuShader4Available )
{
str +=
R"(vec4 unpackUnorm4x8( uint value )
{
uint x = value & 0xFFu;
uint y = ( value >> 8u ) & 0xFFu;
uint z = ( value >> 16u ) & 0xFFu;
uint w = ( value >> 24u ) & 0xFFu;

return vec4( x, y, z, w ) / 255.0f;
}
)";
}

/* Driver bug: Adrenaline/OGLP drivers fail to recognise the ARB function versions when they return a 4.6 context
Expand Down
14 changes: 7 additions & 7 deletions src/engine/renderer/glsl_source/computeLight_fp.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ void computeDynamicLight( uint idx, vec3 P, vec3 normal, vec3 viewDir, vec4 diff
diffuse, material, color );
}

const int lightsPerLayer = 16;
const uint lightsPerLayer = 16u;

#define idxs_t uvec4

Expand All @@ -213,7 +213,7 @@ idxs_t fetchIdxs( in vec3 coords, in usampler3D u_LightTiles ) {

// 8 bits per light ID
uint nextIdx( in uint count, in idxs_t idxs ) {
return ( idxs[count / 4] >> ( 8 * ( count % 4 ) ) ) & 0xFFu;
return ( idxs[count / 4u] >> ( 8u * ( count % 4u ) ) ) & 0xFFu;
}

void computeDynamicLights( vec3 P, vec3 normal, vec3 viewDir, vec4 diffuse, vec4 material,
Expand All @@ -225,20 +225,20 @@ void computeDynamicLights( vec3 P, vec3 normal, vec3 viewDir, vec4 diffuse, vec4

vec2 tile = floor( gl_FragCoord.xy * ( 1.0 / float( TILE_SIZE ) ) ) + 0.5;

for( uint layer = 0; layer < NUM_LIGHT_LAYERS; layer++ ) {
uint lightCount = 0;
for( uint layer = 0u; layer < uint( NUM_LIGHT_LAYERS ); layer++ ) {
uint lightCount = 0u;
idxs_t idxs = fetchIdxs( tileScale * vec3( tile, float( layer ) + 0.5 ), u_LightTiles );

for( uint i = 0; i < lightsPerLayer; i++ ) {
for( uint i = 0u; i < lightsPerLayer; i++ ) {
uint idx = nextIdx( lightCount, idxs );

if( idx == 0 ) {
if( idx == 0u ) {
break;
}

/* Light IDs are stored relative to the layer
Subtract 1 because 0 means there's no light */
idx = ( idx - 1 ) * NUM_LIGHT_LAYERS + layer;
idx = ( idx - 1u ) * uint( NUM_LIGHT_LAYERS ) + layer;

computeDynamicLight( idx, P, normal, viewDir, diffuse, material, color );
lightCount++;
Expand Down
12 changes: 6 additions & 6 deletions src/engine/renderer/glsl_source/lighttile_fp.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -59,16 +59,16 @@ uniform sampler2D u_DepthMap;
uniform int u_lightLayer;
uniform vec3 u_zFar;

const int lightsPerLayer = 16;
const uint lightsPerLayer = 16u;

#define idxs_t uvec4

DECLARE_OUTPUT(uvec4)

// 8 bits per light ID
void pushIdxs( in uint idx, in uint count, inout uvec4 idxs ) {
idxs[count / 4] <<= 8;
idxs[count / 4] |= idx & 0xFFu;
idxs[count / 4u] <<= 8u;
idxs[count / 4u] |= idx & 0xFFu;
}

#define exportIdxs( x ) outputColor = ( x )
Expand Down Expand Up @@ -114,13 +114,13 @@ void main() {

idxs_t idxs = uvec4( 0, 0, 0, 0 );

uint lightCount = 0;
uint lightCount = 0u;

/* Dynamic lights are put into 4 layers of a 3D texture. Since checking if we already added some light is infeasible,
only process 1 / 4 of different lights for each layer, extra lights going into the last layer. This can fail to add some lights
if 1 / 4 of all lights is more than the amount of lights that each layer can hold (16). To fix this, we'd need to either do this on CPU
or use compute shaders with atomics so we can have a variable amount of lights for each tile. */
for( uint i = u_lightLayer; i < u_numLights; i += NUM_LIGHT_LAYERS ) {
for( uint i = uint( u_lightLayer ); i < uint( u_numLights ); i += uint( NUM_LIGHT_LAYERS ) ) {
Light l = GetLight( i );
vec3 center = ( u_ModelMatrix * vec4( l.center, 1.0 ) ).xyz;
float radius = max( 2.0 * l.radius, 2.0 * 32.0 ); // Avoid artifacts with weak light sources
Expand All @@ -136,7 +136,7 @@ void main() {
if( radius > 0.0 ) {
/* Light IDs are stored relative to the layer
Add 1 because 0 means there's no light */
pushIdxs( ( i / NUM_LIGHT_LAYERS ) + 1, lightCount, idxs );
pushIdxs( ( i / uint( NUM_LIGHT_LAYERS ) ) + 1u, lightCount, idxs );
lightCount++;

if( lightCount == lightsPerLayer ) {
Expand Down