Permalink
Browse files

Workaround for the tiled renderer on systems without UBO support.

  • Loading branch information...
1 parent f12493a commit 03d882660dd800257e170f5da94971a524116da3 @gimhael gimhael committed Mar 10, 2016
@@ -457,6 +457,12 @@ std::string GLShaderManager::BuildGPUShaderText( Str::StringRef mainShaderNa
if ( glConfig2.textureRGAvailable )
AddDefine( env, "TEXTURE_RG", 1 );
+ if ( glConfig2.uniformBufferObjectAvailable )
+ AddDefine( env, "UNIFORM_BUFFER_OBJECT", 1 );
+
+ if ( glConfig2.textureIntegerAvailable )
+ AddDefine( env, "TEXTURE_INTEGER", 1 );
+
AddDefine( env, "r_AmbientScale", r_ambientScale->value );
AddDefine( env, "r_SpecularScale", r_specularScale->value );
AddDefine( env, "r_NormalScale", r_normalScale->value );
@@ -1302,6 +1308,9 @@ void GLShader_generic::SetShaderProgramUniforms( shaderProgram_t *shaderProgram
{
glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ColorMap" ), 0 );
glUniform1i( glGetUniformLocation( shaderProgram->program, "u_DepthMap" ), 1 );
+ if( !glConfig2.uniformBufferObjectAvailable ) {
+ glUniform1i( glGetUniformLocation( shaderProgram->program, "u_Lights" ), 9 );
+ }
}
GLShader_lightMapping::GLShader_lightMapping( GLShaderManager *manager ) :
@@ -1352,6 +1361,9 @@ void GLShader_lightMapping::SetShaderProgramUniforms( shaderProgram_t *shaderPro
glUniform1i( glGetUniformLocation( shaderProgram->program, "u_DeluxeMap" ), 4 );
glUniform1i( glGetUniformLocation( shaderProgram->program, "u_GlowMap" ), 5 );
glUniform1i( glGetUniformLocation( shaderProgram->program, "u_LightTiles" ), 8 );
+ if( !glConfig2.uniformBufferObjectAvailable ) {
+ glUniform1i( glGetUniformLocation( shaderProgram->program, "u_Lights" ), 9 );
+ }
}
GLShader_vertexLighting_DBS_entity::GLShader_vertexLighting_DBS_entity( GLShaderManager *manager ) :
@@ -1410,6 +1422,9 @@ void GLShader_vertexLighting_DBS_entity::SetShaderProgramUniforms( shaderProgram
glUniform1i( glGetUniformLocation( shaderProgram->program, "u_LightGrid1" ), 6 );
glUniform1i( glGetUniformLocation( shaderProgram->program, "u_LightGrid2" ), 7 );
glUniform1i( glGetUniformLocation( shaderProgram->program, "u_LightTiles" ), 8 );
+ if( !glConfig2.uniformBufferObjectAvailable ) {
+ glUniform1i( glGetUniformLocation( shaderProgram->program, "u_Lights" ), 9 );
+ }
}
GLShader_vertexLighting_DBS_world::GLShader_vertexLighting_DBS_world( GLShaderManager *manager ) :
@@ -1465,6 +1480,9 @@ void GLShader_vertexLighting_DBS_world::SetShaderProgramUniforms( shaderProgram_
glUniform1i( glGetUniformLocation( shaderProgram->program, "u_LightGrid1" ), 6 );
glUniform1i( glGetUniformLocation( shaderProgram->program, "u_LightGrid2" ), 7 );
glUniform1i( glGetUniformLocation( shaderProgram->program, "u_LightTiles" ), 8 );
+ if( !glConfig2.uniformBufferObjectAvailable ) {
+ glUniform1i( glGetUniformLocation( shaderProgram->program, "u_Lights" ), 9 );
+ }
}
GLShader_forwardLighting_omniXYZ::GLShader_forwardLighting_omniXYZ( GLShaderManager *manager ):
@@ -2034,6 +2052,7 @@ GLShader_lighttile::GLShader_lighttile( GLShaderManager *manager ) :
void GLShader_lighttile::SetShaderProgramUniforms( shaderProgram_t *shaderProgram )
{
glUniform1i( glGetUniformLocation( shaderProgram->program, "u_DepthMap" ), 0 );
+ glUniform1i( glGetUniformLocation( shaderProgram->program, "u_Lights" ), 1 );
}
GLShader_fxaa::GLShader_fxaa( GLShaderManager *manager ) :
Oops, something went wrong.
@@ -2812,7 +2812,11 @@ void RB_RenderPostDepth()
gl_lighttileShader->BindProgram( 0 );
gl_lighttileShader->SetUniform_ModelMatrix( backEnd.viewParms.world.modelViewMatrix );
gl_lighttileShader->SetUniform_numLights( backEnd.refdef.numLights );
- gl_lighttileShader->SetUniformBlock_Lights( tr.dlightUBO );
+ if( glConfig2.uniformBufferObjectAvailable ) {
+ gl_lighttileShader->SetUniformBlock_Lights( tr.dlightUBO );
+ } else {
+ GL_BindToTMU( 1, tr.dlightImage );
+ }
GL_BindToTMU( 0, tr.depthtile2RenderImage );
@@ -5412,17 +5416,17 @@ static const void *RB_SetupLights( const void *data )
{
const setupLightsCommand_t *cmd;
int numLights;
+ GLenum bufferTarget = glConfig2.uniformBufferObjectAvailable ? GL_UNIFORM_BUFFER : GL_PIXEL_UNPACK_BUFFER;
GLimp_LogComment( "--- RB_SetupLights ---\n" );
cmd = ( const setupLightsCommand_t * ) data;
- if( ( glConfig2.uniformBufferObjectAvailable ) &&
- (numLights = cmd->refdef.numLights) > 0 ) {
+ if( (numLights = cmd->refdef.numLights) > 0 ) {
shaderLight_t *buffer;
- glBindBuffer( GL_UNIFORM_BUFFER, tr.dlightUBO );
- buffer = (shaderLight_t *)glMapBufferRange( GL_UNIFORM_BUFFER,
+ glBindBuffer( bufferTarget, tr.dlightUBO );
+ buffer = (shaderLight_t *)glMapBufferRange( bufferTarget,
0, numLights * sizeof( shaderLight_t ),
GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT );
@@ -5452,8 +5456,12 @@ static const void *RB_SetupLights( const void *data )
}
}
- glUnmapBuffer( GL_UNIFORM_BUFFER );
- glBindBuffer( GL_UNIFORM_BUFFER, 0 );
+ glUnmapBuffer( bufferTarget );
+ if( !glConfig2.uniformBufferObjectAvailable ) {
+ GL_BindToTMU( 0, tr.dlightImage );
+ glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, tr.dlightImage->width, tr.dlightImage->height, GL_RGBA, GL_FLOAT, NULL );
+ }
+ glBindBuffer( bufferTarget, 0 );
}
return ( const void * )( cmd + 1 );
@@ -2643,6 +2643,11 @@ static void R_CreateDepthRenderImage()
} else {
tr.lighttileRenderImage = R_Create3DImage( "_lighttileRender", nullptr, w, h, 4, IF_NOPICMIP, filterType_t::FT_NEAREST, wrapTypeEnum_t::WT_CLAMP );
}
+
+ if( !glConfig2.uniformBufferObjectAvailable ) {
+ w = 64; h = 3 * MAX_REF_LIGHTS / w;
+ tr.dlightImage = R_CreateImage("_dlightImage", nullptr, w, h, 4, IF_NOPICMIP | IF_RGBA32F, filterType_t::FT_NEAREST, wrapTypeEnum_t::WT_CLAMP );
+ }
}
static void R_CreatePortalRenderImage()
@@ -103,6 +103,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
cvar_t *r_arb_buffer_storage;
cvar_t *r_arb_map_buffer_range;
cvar_t *r_arb_sync;
+ cvar_t *r_arb_uniform_buffer_object;
cvar_t *r_ignoreGLErrors;
cvar_t *r_logFile;
@@ -1082,6 +1083,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
r_arb_buffer_storage = ri.Cvar_Get( "r_arb_buffer_storage", "1", CVAR_CHEAT | CVAR_LATCH );
r_arb_map_buffer_range = ri.Cvar_Get( "r_arb_map_buffer_range", "1", CVAR_CHEAT | CVAR_LATCH );
r_arb_sync = ri.Cvar_Get( "r_arb_sync", "1", CVAR_CHEAT | CVAR_LATCH );
+ r_arb_uniform_buffer_object = ri.Cvar_Get( "r_arb_uniform_buffer_object", "1", CVAR_CHEAT | CVAR_LATCH );
r_collapseStages = ri.Cvar_Get( "r_collapseStages", "1", CVAR_LATCH | CVAR_CHEAT );
r_picmip = ri.Cvar_Get( "r_picmip", "0", CVAR_LATCH | CVAR_ARCHIVE );
@@ -2741,6 +2741,7 @@ static inline void halfToFloat( const f16vec4_t in, vec4_t out )
FBO_t *fbos[ MAX_FBOS ];
GLuint dlightUBO;
+ image_t *dlightImage; // if the UBO is not available
growList_t vbos;
growList_t ibos;
@@ -2881,6 +2882,7 @@ static inline void halfToFloat( const f16vec4_t in, vec4_t out )
extern cvar_t *r_arb_buffer_storage;
extern cvar_t *r_arb_map_buffer_range;
extern cvar_t *r_arb_sync;
+ extern cvar_t *r_arb_uniform_buffer_object;
extern cvar_t *r_nobind; // turns off binding to appropriate textures
extern cvar_t *r_collapseStages;
@@ -635,7 +635,11 @@ static void Render_generic( int stage )
if( backEnd.refdef.numShaderLights > 0 ) {
gl_genericShader->SetUniform_numLights( backEnd.refdef.numLights );
- gl_genericShader->SetUniformBlock_Lights( tr.dlightUBO );
+ if( glConfig2.uniformBufferObjectAvailable ) {
+ gl_genericShader->SetUniformBlock_Lights( tr.dlightUBO );
+ } else {
+ GL_BindToTMU( 9, tr.dlightImage );
+ }
}
// u_AlphaTest
@@ -773,7 +777,11 @@ static void Render_vertexLighting_DBS_entity( int stage )
if( backEnd.refdef.numShaderLights > 0 ) {
gl_vertexLightingShader_DBS_entity->SetUniform_numLights( backEnd.refdef.numLights );
- gl_vertexLightingShader_DBS_entity->SetUniformBlock_Lights( tr.dlightUBO );
+ if( glConfig2.uniformBufferObjectAvailable ) {
+ gl_vertexLightingShader_DBS_entity->SetUniformBlock_Lights( tr.dlightUBO );
+ } else {
+ GL_BindToTMU( 9, tr.dlightImage );
+ }
}
// u_AlphaTest
@@ -985,7 +993,11 @@ static void Render_vertexLighting_DBS_world( int stage )
if( backEnd.refdef.numShaderLights > 0 ) {
gl_vertexLightingShader_DBS_world->SetUniform_numLights( backEnd.refdef.numLights );
- gl_vertexLightingShader_DBS_world->SetUniformBlock_Lights( tr.dlightUBO );
+ if( glConfig2.uniformBufferObjectAvailable ) {
+ gl_vertexLightingShader_DBS_world->SetUniformBlock_Lights( tr.dlightUBO );
+ } else {
+ GL_BindToTMU( 9, tr.dlightImage );
+ }
}
GL_CheckErrors();
@@ -1181,7 +1193,11 @@ static void Render_lightMapping( int stage, bool asColorMap, bool normalMapping
if( backEnd.refdef.numShaderLights > 0 ) {
gl_lightMappingShader->SetUniform_numLights( backEnd.refdef.numLights );
- gl_lightMappingShader->SetUniformBlock_Lights( tr.dlightUBO );
+ if( glConfig2.uniformBufferObjectAvailable ) {
+ gl_lightMappingShader->SetUniformBlock_Lights( tr.dlightUBO );
+ } else {
+ GL_BindToTMU( 9, tr.dlightImage );
+ }
}
// u_DeformGen
@@ -1028,6 +1028,11 @@ void R_InitVBOs()
glBindBuffer( GL_UNIFORM_BUFFER, tr.dlightUBO );
glBufferData( GL_UNIFORM_BUFFER, MAX_REF_LIGHTS * sizeof( shaderLight_t ), nullptr, GL_DYNAMIC_DRAW );
glBindBuffer( GL_UNIFORM_BUFFER, 0 );
+ } else {
+ glGenBuffers( 1, &tr.dlightUBO );
+ glBindBuffer( GL_PIXEL_UNPACK_BUFFER, tr.dlightUBO );
+ glBufferData( GL_PIXEL_UNPACK_BUFFER, MAX_REF_LIGHTS * sizeof( shaderLight_t ), nullptr, GL_DYNAMIC_DRAW );
+ glBindBuffer( GL_PIXEL_UNPACK_BUFFER, 0 );
}
GL_CheckErrors();
@@ -1152,7 +1152,7 @@ static void GLimp_InitExtensions()
}
// made required since OpenGL 3.1
- glConfig2.uniformBufferObjectAvailable = GLEW_ARB_uniform_buffer_object || glConfig2.glCoreProfile;
+ glConfig2.uniformBufferObjectAvailable = LOAD_CORE_EXTENSION_WITH_CVAR( ARB_uniform_buffer_object, r_arb_uniform_buffer_object );
// made required in OpenGL 3.0
glConfig2.mapBufferRangeAvailable = LOAD_CORE_EXTENSION_WITH_CVAR( ARB_map_buffer_range, r_arb_map_buffer_range );
@@ -21,17 +21,13 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* lighttile_fp.glsl */
-#if __VERSION__ < 150
-#extension GL_ARB_uniform_buffer_object : require
+#if __VERSION__ < 150 && defined( UNIFORM_BUFFER_OBJECT )
+#extension GL_ARB_uniform_buffer_object : enable
#endif
-#if __VERSION__ < 130
+
+#if __VERSION__ < 130 && defined( TEXTURE_INTEGER )
#extension GL_EXT_texture_integer : enable
#extension GL_EXT_gpu_shader4 : enable
-#if defined( GL_EXT_texture_integer ) && defined( GL_EXT_gpu_shader4 )
-#define HAVE_INTTEX 1
-#endif
-#else
-#define HAVE_INTTEX 1
#endif
varying vec2 vPosition;
@@ -43,17 +39,29 @@ struct light {
vec4 direction_angle;
};
+#ifdef UNIFORM_BUFFER_OBJECT
layout(std140) uniform u_Lights {
light lights[ MAX_REF_LIGHTS ];
};
+#define GetLight(idx, component) lights[idx].component
+#else
+uniform sampler2D u_Lights;
+#define center_radius_offset 0
+#define color_type_offset 1
+#define direction_angle_offset 2
+#define idxToTC( idx, w, h ) vec2( floor( ( idx * ( 1.0 / w ) + 0.5 ) * ( 1.0 / h ) ), \
+ fract( ( idx + 0.5 ) * (1.0 / w ) ) )
+#define GetLight(idx, component) texture2D( u_Lights, idxToTC(3 * idx + component##_offset, 64.0, float( 3 * MAX_REF_LIGHTS / 64 ) ) )
+#endif
+
uniform int u_numLights;
uniform mat4 u_ModelMatrix;
uniform sampler2D u_DepthMap;
uniform int u_lightLayer;
const int numLayers = MAX_REF_LIGHTS / 256;
-#if defined( HAVE_INTTEX )
+#ifdef TEXTURE_INTEGER
#define idxs_t uvec4
#define idx_initializer uvec4(3)
#if __VERSION__ < 130
@@ -104,8 +112,9 @@ void main() {
idxs_t idxs = idx_initializer;
for( int i = u_lightLayer; i < u_numLights; i += numLayers ) {
- vec3 center = ( u_ModelMatrix * vec4( lights[ i ].center_radius.xyz, 1.0 ) ).xyz;
- float radius = 2.0 * lights[ i ].center_radius.w;
+ vec4 center_radius = GetLight( i, center_radius );
+ vec3 center = ( u_ModelMatrix * vec4( center_radius.xyz, 1.0 ) ).xyz;
+ float radius = 2.0 * center_radius.w;
// todo: better checks for spotlights
lightOutsidePlane( plane1, center, radius );
@@ -22,17 +22,13 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
// reliefMapping_vp.glsl - Relief mapping helper functions
#if defined( USE_SHADER_LIGHTS )
-#if __VERSION__ < 150
-#extension GL_ARB_uniform_buffer_object : require
+#if __VERSION__ < 150 && defined( UNIFORM_BUFFER_OBJECT )
+#extension GL_ARB_uniform_buffer_object : enable
#endif
-#if __VERSION__ < 130
+
+#if __VERSION__ < 130 && defined( TEXTURE_INTEGER )
#extension GL_EXT_texture_integer : enable
#extension GL_EXT_gpu_shader4 : enable
-#if defined( GL_EXT_texture_integer ) && defined( GL_EXT_gpu_shader4 )
-#define HAVE_INTTEX 1
-#endif
-#else
-#define HAVE_INTTEX 1
#endif
struct light {
@@ -41,9 +37,20 @@ struct light {
vec4 direction_angle;
};
+#ifdef UNIFORM_BUFFER_OBJECT
layout(std140) uniform u_Lights {
light lights[ MAX_REF_LIGHTS ];
};
+#define GetLight(idx, component) lights[idx].component
+#else
+uniform sampler2D u_Lights;
+#define center_radius_offset 0
+#define color_type_offset 1
+#define direction_angle_offset 2
+#define idxToTC( idx, w, h ) vec2( floor( ( idx * ( 1.0 / w ) ) + 0.5 ) * ( 1.0 / h ), \
+ fract( ( idx + 0.5 ) * (1.0 / w ) ) )
+#define GetLight(idx, component) texture2D( u_Lights, idxToTC(3 * idx + component##_offset, 64.0, float( 3 * MAX_REF_LIGHTS / 64 ) ) )
+#endif
uniform int u_numLights;
#endif
@@ -101,7 +108,7 @@ void computeLight( vec3 lightDir, vec3 normal, vec3 eyeDir, vec3 lightColor,
#if defined( USE_SHADER_LIGHTS )
-#if defined( HAVE_INTTEX )
+#ifdef TEXTURE_INTEGER
const int lightsPerLayer = 16;
uniform usampler3D u_LightTiles;
#define idxs_t uvec4
@@ -132,10 +139,12 @@ const int numLayers = MAX_REF_LIGHTS / 256;
void computeDLight( int idx, vec3 P, vec3 N, vec3 I, vec4 diffuse,
vec4 specular, inout vec4 color ) {
- vec3 L = lights[idx].center_radius.xyz - P;
- float attenuation = 1.0 / (1.0 + 8.0 * length(L) / lights[idx].center_radius.w);
+ vec4 center_radius = GetLight( idx, center_radius );
+ vec4 color_type = GetLight( idx, color_type );
+ vec3 L = center_radius.xyz - P;
+ float attenuation = 1.0 / (1.0 + 8.0 * length(L) / center_radius.w);
computeLight( normalize( L ), N, I,
- attenuation * attenuation * lights[idx].color_type.xyz,
+ attenuation * attenuation * color_type.xyz,
diffuse, specular, color );
}

0 comments on commit 03d8826

Please sign in to comment.