From d923881f82328609ada177f1f70708d3d168e698 Mon Sep 17 00:00:00 2001 From: VReaperV Date: Fri, 23 Aug 2024 00:09:44 +0300 Subject: [PATCH 01/27] Allocate material memory for stages rather than surfaces Allocate memory for each stage of used shaders rather than for each stage in all used shaders for each surface that uses them. Change some of the material system functions to use `shaderStage_t*` instead of `drawSurf_t*` etc as input. Textures are put into a different storage buffer, following the structure of `textureBundle_t`. This allows decreasing the total amount of memory used, and changing the material buffer to be a UBO instead. The lightmap and deluxemap handles are put into another UBO, because they're per-surface, rather than per-shader-stage. Also moved some duplicate code into a function. --- src/engine/renderer/Material.cpp | 775 ++++++++++-------- src/engine/renderer/Material.h | 121 ++- src/engine/renderer/ShadeCommon.h | 4 +- src/engine/renderer/gl_shader.cpp | 72 +- src/engine/renderer/gl_shader.h | 14 +- .../renderer/glsl_source/generic_vp.glsl | 5 +- .../renderer/glsl_source/heatHaze_vp.glsl | 5 +- .../renderer/glsl_source/lightMapping_vp.glsl | 4 +- .../renderer/glsl_source/liquid_vp.glsl | 5 +- .../renderer/glsl_source/material_fp.glsl | 8 +- .../glsl_source/reflection_CB_vp.glsl | 5 +- .../renderer/glsl_source/skybox_fp.glsl | 4 +- src/engine/renderer/tr_backend.cpp | 2 +- src/engine/renderer/tr_local.h | 81 +- src/engine/renderer/tr_shade.cpp | 6 +- src/engine/renderer/tr_shader.cpp | 6 +- src/engine/renderer/tr_vbo.cpp | 4 + 17 files changed, 689 insertions(+), 432 deletions(-) diff --git a/src/engine/renderer/Material.cpp b/src/engine/renderer/Material.cpp index 1070522b60..8589144de3 100644 --- a/src/engine/renderer/Material.cpp +++ b/src/engine/renderer/Material.cpp @@ -38,6 +38,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "ShadeCommon.h" GLSSBO materialsSSBO( "materials", 0, GL_MAP_WRITE_BIT, GL_MAP_INVALIDATE_RANGE_BIT ); +GLSSBO texDataSSBO( "texData", 6, GL_MAP_WRITE_BIT, GL_MAP_FLUSH_EXPLICIT_BIT ); +GLUBO lightmapDataUBO( "texData", 7, GL_MAP_WRITE_BIT, GL_MAP_FLUSH_EXPLICIT_BIT ); GLSSBO surfaceDescriptorsSSBO( "surfaceDescriptors", 1, GL_MAP_WRITE_BIT, GL_MAP_INVALIDATE_RANGE_BIT ); GLSSBO surfaceCommandsSSBO( "surfaceCommands", 2, GL_MAP_WRITE_BIT, GL_MAP_FLUSH_EXPLICIT_BIT ); @@ -114,69 +116,6 @@ static void ComputeDynamics( shaderStage_t* pStage ) { } } - for ( textureBundle_t& bundle : pStage->bundle ) { - for ( size_t i = 0; i < bundle.numTexMods; i++ ) { - switch ( bundle.texMods[i].type ) { - case texMod_t::TMOD_NONE: - case texMod_t::TMOD_SCALE: - case texMod_t::TMOD_TRANSFORM: - break; - - case texMod_t::TMOD_TURBULENT: - case texMod_t::TMOD_ENTITY_TRANSLATE: - case texMod_t::TMOD_SCROLL: - { - pStage->texMatricesDynamic = true; - break; - } - - case texMod_t::TMOD_STRETCH: - { - if( bundle.texMods->wave.func != genFunc_t::GF_NONE ) { - pStage->texMatricesDynamic = true; - } - break; - } - - case texMod_t::TMOD_ROTATE: - { - pStage->texMatricesDynamic = true; - break; - } - - case texMod_t::TMOD_SCROLL2: - case texMod_t::TMOD_SCALE2: - case texMod_t::TMOD_CENTERSCALE: - case texMod_t::TMOD_SHEAR: - { - if ( bundle.texMods[i].sExp.numOps || bundle.texMods[i].tExp.numOps ) { - pStage->texMatricesDynamic = true; - } - break; - } - - case texMod_t::TMOD_ROTATE2: - { - if( bundle.texMods[i].rExp.numOps ) { - pStage->texMatricesDynamic = true; - } - break; - } - - default: - break; - } - } - } - - // TODO: Move this to a different buffer? - for ( const textureBundle_t& bundle : pStage->bundle ) { - if ( bundle.isVideoMap || bundle.numImages > 1 ) { - pStage->texturesDynamic = true; - break; - } - } - // Can we move this to a compute shader too? // Doesn't seem to be used much if at all, so probably not worth the effort to do that pStage->dynamic = pStage->dynamic || pStage->ifExp.numOps; @@ -187,31 +126,30 @@ static void ComputeDynamics( shaderStage_t* pStage ) { || pStage->fogDensityExp.numOps || pStage->fresnelBiasExp.numOps || pStage->fresnelPowerExp.numOps || pStage->fresnelScaleExp.numOps || pStage->normalIntensityExp.numOps || pStage->refractionIndexExp.numOps; - pStage->dynamic = pStage->dynamic || pStage->colorDynamic || pStage->texMatricesDynamic || pStage->texturesDynamic; + pStage->dynamic = pStage->dynamic || pStage->colorDynamic; } // UpdateSurface*() functions will actually write the uniform values to the SSBO // Mirrors parts of the Render_*() functions in tr_shade.cpp -void UpdateSurfaceDataNONE( uint32_t*, Material&, drawSurf_t*, const uint32_t ) { +void UpdateSurfaceDataNONE( uint32_t*, Material&, shaderStage_t* ) { ASSERT_UNREACHABLE(); } -void UpdateSurfaceDataNOP( uint32_t*, Material&, drawSurf_t*, const uint32_t ) { +void UpdateSurfaceDataNOP( uint32_t*, Material&, shaderStage_t* ) { } -void UpdateSurfaceDataGeneric3D( uint32_t* materials, Material& material, drawSurf_t* drawSurf, const uint32_t stage ) { - shader_t* shader = drawSurf->shader; - shaderStage_t* pStage = &shader->stages[stage]; +void UpdateSurfaceDataGeneric3D( uint32_t* materials, Material& material, shaderStage_t* pStage ) { + shader_t* shader = pStage->shader; - const uint32_t paddedOffset = drawSurf->materialsSSBOOffset[stage] * material.shader->GetPaddedSize(); + const uint32_t paddedOffset = ( pStage->materialsSSBOOffset + pStage->currentOffset ) * material.shader->GetPaddedSize(); materials += paddedOffset; - bool updated = !drawSurf->initialized[stage] || pStage->colorDynamic || pStage->texMatricesDynamic || pStage->dynamic; + bool updated = !pStage->bufferInitialized || pStage->colorDynamic || pStage->dynamic; if ( !updated ) { return; } - drawSurf->initialized[stage] = true; + pStage->bufferInitialized = true; gl_genericShaderMaterial->BindProgram( material.deformIndex ); @@ -229,18 +167,6 @@ void UpdateSurfaceDataGeneric3D( uint32_t* materials, Material& material, drawSu Tess_ComputeColor( pStage ); gl_genericShaderMaterial->SetUniform_Color( tess.svars.color ); - Tess_ComputeTexMatrices( pStage ); - gl_genericShaderMaterial->SetUniform_TextureMatrix( tess.svars.texMatrices[TB_COLORMAP] ); - - // bind u_ColorMap - if ( pStage->type == stageType_t::ST_STYLELIGHTMAP ) { - gl_genericShaderMaterial->SetUniform_ColorMapBindless( - GL_BindToTMU( 0, GetLightMap( drawSurf ) ) - ); - } else { - gl_genericShaderMaterial->SetUniform_ColorMapBindless( BindAnimatedImage( 0, &pStage->bundle[TB_COLORMAP] ) ); - } - bool hasDepthFade = pStage->hasDepthFade; if ( hasDepthFade ) { gl_genericShaderMaterial->SetUniform_DepthScale( pStage->depthFadeValue ); @@ -249,44 +175,35 @@ void UpdateSurfaceDataGeneric3D( uint32_t* materials, Material& material, drawSu gl_genericShaderMaterial->WriteUniformsToBuffer( materials ); } -void UpdateSurfaceDataLightMapping( uint32_t* materials, Material& material, drawSurf_t* drawSurf, const uint32_t stage ) { - shader_t* shader = drawSurf->shader; - shaderStage_t* pStage = &shader->stages[stage]; +void UpdateSurfaceDataLightMapping( uint32_t* materials, Material& material, shaderStage_t* pStage ) { + shader_t* shader = pStage->shader; - const uint32_t paddedOffset = drawSurf->materialsSSBOOffset[stage] * material.shader->GetPaddedSize(); + const uint32_t paddedOffset = ( pStage->materialsSSBOOffset + pStage->currentOffset ) * material.shader->GetPaddedSize(); materials += paddedOffset; - bool updated = !drawSurf->initialized[stage] || pStage->colorDynamic || pStage->texMatricesDynamic || pStage->dynamic; + bool updated = !pStage->bufferInitialized || pStage->colorDynamic || pStage->dynamic; if ( !updated ) { return; } - drawSurf->initialized[stage] = true; + pStage->bufferInitialized = true; gl_lightMappingShaderMaterial->BindProgram( material.deformIndex ); gl_lightMappingShaderMaterial->SetUniform_ModelMatrix( backEnd.orientation.transformMatrix ); - lightMode_t lightMode; - deluxeMode_t deluxeMode; - SetLightDeluxeMode( drawSurf, pStage->type, lightMode, deluxeMode ); - - // u_Map, u_DeluxeMap - image_t* lightmap = SetLightMap( drawSurf, lightMode ); - image_t* deluxemap = SetDeluxeMap( drawSurf, deluxeMode ); - // u_ColorModulate colorGen_t rgbGen = SetRgbGen( pStage ); alphaGen_t alphaGen = SetAlphaGen( pStage ); Tess_ComputeColor( pStage ); - SetVertexLightingSettings( lightMode, rgbGen ); - - bool enableGridLighting = ( lightMode == lightMode_t::GRID ); - bool enableGridDeluxeMapping = ( deluxeMode == deluxeMode_t::GRID ); + // HACK: This only has effect on vertex-lit surfaces + if ( pStage->vertexLit ) { + SetVertexLightingSettings( lightMode_t::VERTEX, rgbGen ); + } // u_ColorModulate - gl_lightMappingShaderMaterial->SetUniform_ColorModulateColorGen( rgbGen, alphaGen, false, lightMode != lightMode_t::FULLBRIGHT ); + gl_lightMappingShaderMaterial->SetUniform_ColorModulateColorGen( rgbGen, alphaGen, false, !pStage->fullbright ); // u_Color gl_lightMappingShaderMaterial->SetUniform_Color( tess.svars.color ); @@ -294,37 +211,13 @@ void UpdateSurfaceDataLightMapping( uint32_t* materials, Material& material, dra // u_AlphaThreshold gl_lightMappingShaderMaterial->SetUniform_AlphaTest( pStage->stateBits ); - // bind u_HeightMap + // HeightMap if ( pStage->enableReliefMapping ) { float depthScale = RB_EvalExpression( &pStage->depthScaleExp, r_reliefDepthScale->value ); depthScale *= shader->reliefDepthScale; gl_lightMappingShaderMaterial->SetUniform_ReliefDepthScale( depthScale ); gl_lightMappingShaderMaterial->SetUniform_ReliefOffsetBias( shader->reliefOffsetBias ); - - // FIXME: if there is both, embedded heightmap in normalmap is used instead of standalone heightmap - if ( !pStage->hasHeightMapInNormalMap ) { - gl_lightMappingShaderMaterial->SetUniform_HeightMapBindless( - GL_BindToTMU( BIND_HEIGHTMAP, pStage->bundle[TB_HEIGHTMAP].image[0] ) - ); - } - } - - // bind u_DiffuseMap - gl_lightMappingShaderMaterial->SetUniform_DiffuseMapBindless( - GL_BindToTMU( BIND_DIFFUSEMAP, pStage->bundle[TB_DIFFUSEMAP].image[0] ) - ); - - if ( pStage->type != stageType_t::ST_LIGHTMAP ) { - Tess_ComputeTexMatrices( pStage ); - gl_lightMappingShaderMaterial->SetUniform_TextureMatrix( tess.svars.texMatrices[TB_DIFFUSEMAP] ); - } - - // bind u_NormalMap - if ( !!r_normalMapping->integer || pStage->hasHeightMapInNormalMap ) { - gl_lightMappingShaderMaterial->SetUniform_NormalMapBindless( - GL_BindToTMU( BIND_NORMALMAP, pStage->bundle[TB_NORMALMAP].image[0] ) - ); } // bind u_NormalScale @@ -335,13 +228,6 @@ void UpdateSurfaceDataLightMapping( uint32_t* materials, Material& material, dra gl_lightMappingShaderMaterial->SetUniform_NormalScale( normalScale ); } - // bind u_MaterialMap - if ( pStage->enableSpecularMapping || pStage->enablePhysicalMapping ) { - gl_lightMappingShaderMaterial->SetUniform_MaterialMapBindless( - GL_BindToTMU( BIND_MATERIALMAP, pStage->bundle[TB_MATERIALMAP].image[0] ) - ); - } - if ( pStage->enableSpecularMapping ) { float specExpMin = RB_EvalExpression( &pStage->specularExponentMin, r_specularExponentMin->value ); float specExpMax = RB_EvalExpression( &pStage->specularExponentMax, r_specularExponentMax->value ); @@ -349,47 +235,20 @@ void UpdateSurfaceDataLightMapping( uint32_t* materials, Material& material, dra gl_lightMappingShaderMaterial->SetUniform_SpecularExponent( specExpMin, specExpMax ); } - // bind u_LightMap - if ( !enableGridLighting ) { - gl_lightMappingShaderMaterial->SetUniform_LightMapBindless( - GL_BindToTMU( BIND_LIGHTMAP, lightmap ) - ); - } - - // bind u_DeluxeMap - if ( !enableGridDeluxeMapping ) { - gl_lightMappingShaderMaterial->SetUniform_DeluxeMapBindless( - GL_BindToTMU( BIND_DELUXEMAP, deluxemap ) - ); - } - - // bind u_GlowMap - if ( !!r_glowMapping->integer ) { - gl_lightMappingShaderMaterial->SetUniform_GlowMapBindless( - GL_BindToTMU( BIND_GLOWMAP, pStage->bundle[TB_GLOWMAP].image[0] ) - ); - } - gl_lightMappingShaderMaterial->WriteUniformsToBuffer( materials ); } -void UpdateSurfaceDataReflection( uint32_t* materials, Material& material, drawSurf_t* drawSurf, const uint32_t stage ) { - shader_t* shader = drawSurf->shader; - shaderStage_t* pStage = &shader->stages[stage]; +void UpdateSurfaceDataReflection( uint32_t* materials, Material& material, shaderStage_t* pStage ) { + shader_t* shader = pStage->shader; - const uint32_t paddedOffset = drawSurf->materialsSSBOOffset[stage] * material.shader->GetPaddedSize(); + const uint32_t paddedOffset = ( pStage->materialsSSBOOffset + pStage->currentOffset ) * material.shader->GetPaddedSize(); materials += paddedOffset; - bool updated = !drawSurf->initialized[stage] || pStage->colorDynamic || pStage->texMatricesDynamic || pStage->dynamic; + bool updated = !pStage->bufferInitialized || pStage->colorDynamic || pStage->dynamic; if ( !updated ) { return; } - drawSurf->initialized[stage] = true; - - // bind u_NormalMap - gl_reflectionShaderMaterial->SetUniform_NormalMapBindless( - GL_BindToTMU( 1, pStage->bundle[TB_NORMALMAP].image[0] ) - ); + pStage->bufferInitialized = true; // bind u_ColorMap vec3_t position; @@ -415,98 +274,76 @@ void UpdateSurfaceDataReflection( uint32_t* materials, Material& material, drawS gl_reflectionShaderMaterial->SetUniform_NormalScale( normalScale ); } - // bind u_HeightMap u_depthScale u_reliefOffsetBias + // u_depthScale u_reliefOffsetBias if ( pStage->enableReliefMapping ) { float depthScale = RB_EvalExpression( &pStage->depthScaleExp, r_reliefDepthScale->value ); float reliefDepthScale = shader->reliefDepthScale; depthScale *= reliefDepthScale == 0 ? 1 : reliefDepthScale; gl_reflectionShaderMaterial->SetUniform_ReliefDepthScale( depthScale ); gl_reflectionShaderMaterial->SetUniform_ReliefOffsetBias( shader->reliefOffsetBias ); - - // FIXME: if there is both, embedded heightmap in normalmap is used instead of standalone heightmap - if ( !pStage->hasHeightMapInNormalMap ) { - gl_reflectionShaderMaterial->SetUniform_HeightMapBindless( - GL_BindToTMU( 15, pStage->bundle[TB_HEIGHTMAP].image[0] ) - ); - } } gl_reflectionShaderMaterial->WriteUniformsToBuffer( materials ); } -void UpdateSurfaceDataSkybox( uint32_t* materials, Material& material, drawSurf_t* drawSurf, const uint32_t stage ) { - shader_t* shader = drawSurf->shader; - shaderStage_t* pStage = &shader->stages[stage]; +void UpdateSurfaceDataSkybox( uint32_t* materials, Material& material, shaderStage_t* pStage ) { + shader_t* shader = pStage->shader; - const uint32_t paddedOffset = drawSurf->materialsSSBOOffset[stage] * material.shader->GetPaddedSize(); + const uint32_t paddedOffset = ( pStage->materialsSSBOOffset + pStage->currentOffset ) * material.shader->GetPaddedSize(); materials += paddedOffset; - bool updated = !drawSurf->initialized[stage] || pStage->colorDynamic || pStage->texMatricesDynamic || pStage->dynamic; + bool updated = !pStage->bufferInitialized || pStage->colorDynamic || pStage->dynamic; if ( !updated ) { return; } - drawSurf->initialized[stage] = true; + pStage->bufferInitialized = true; gl_skyboxShaderMaterial->BindProgram( material.deformIndex ); - // bind u_ColorMap - gl_skyboxShaderMaterial->SetUniform_ColorMapCubeBindless( - GL_BindToTMU( 0, pStage->bundle[TB_COLORMAP].image[0] ) - ); - // u_AlphaThreshold gl_skyboxShaderMaterial->SetUniform_AlphaTest( GLS_ATEST_NONE ); gl_skyboxShaderMaterial->WriteUniformsToBuffer( materials ); } -void UpdateSurfaceDataScreen( uint32_t* materials, Material& material, drawSurf_t* drawSurf, const uint32_t stage ) { - shader_t* shader = drawSurf->shader; - shaderStage_t* pStage = &shader->stages[stage]; +void UpdateSurfaceDataScreen( uint32_t* materials, Material& material, shaderStage_t* pStage ) { + shader_t* shader = pStage->shader; - const uint32_t paddedOffset = drawSurf->materialsSSBOOffset[stage] * material.shader->GetPaddedSize(); + const uint32_t paddedOffset = ( pStage->materialsSSBOOffset + pStage->currentOffset ) * material.shader->GetPaddedSize(); materials += paddedOffset; - bool updated = !drawSurf->initialized[stage] || pStage->colorDynamic || pStage->texMatricesDynamic || pStage->dynamic; + bool updated = !pStage->bufferInitialized || pStage->colorDynamic || pStage->dynamic; if ( !updated ) { return; } - drawSurf->initialized[stage] = true; + pStage->bufferInitialized = true; gl_screenShaderMaterial->BindProgram( pStage->deformIndex ); // bind u_CurrentMap /* FIXME: This is currently unused, but u_CurrentMap was made global for other shaders, this seems to be the only material system shader that might need it to not be global */ - gl_screenShaderMaterial->SetUniform_CurrentMapBindless( BindAnimatedImage( 0, &drawSurf->shader->stages[stage].bundle[TB_COLORMAP] ) ); + gl_screenShaderMaterial->SetUniform_CurrentMapBindless( BindAnimatedImage( 0, &pStage->bundle[TB_COLORMAP] ) ); gl_screenShaderMaterial->WriteUniformsToBuffer( materials ); } -void UpdateSurfaceDataHeatHaze( uint32_t* materials, Material& material, drawSurf_t* drawSurf, const uint32_t stage ) { - shader_t* shader = drawSurf->shader; - shaderStage_t* pStage = &shader->stages[stage]; +void UpdateSurfaceDataHeatHaze( uint32_t* materials, Material& material, shaderStage_t* pStage ) { + shader_t* shader = pStage->shader; - const uint32_t paddedOffset = drawSurf->materialsSSBOOffset[stage] * material.shader->GetPaddedSize(); + const uint32_t paddedOffset = ( pStage->materialsSSBOOffset + pStage->currentOffset ) * material.shader->GetPaddedSize(); materials += paddedOffset; - bool updated = !drawSurf->initialized[stage] || pStage->colorDynamic || pStage->texMatricesDynamic || pStage->dynamic; + bool updated = !pStage->bufferInitialized || pStage->colorDynamic || pStage->dynamic; if ( !updated ) { return; } - drawSurf->initialized[stage] = true; + pStage->bufferInitialized = true; float deformMagnitude = RB_EvalExpression( &pStage->deformMagnitudeExp, 1.0 ); gl_heatHazeShaderMaterial->SetUniform_DeformMagnitude( deformMagnitude ); - // bind u_NormalMap - gl_heatHazeShaderMaterial->SetUniform_NormalMapBindless( - GL_BindToTMU( 0, pStage->bundle[TB_NORMALMAP].image[0] ) - ); - if ( pStage->enableNormalMapping ) { - gl_heatHazeShaderMaterial->SetUniform_TextureMatrix( tess.svars.texMatrices[TB_NORMALMAP] ); - vec3_t normalScale; SetNormalScale( pStage, normalScale ); @@ -517,18 +354,17 @@ void UpdateSurfaceDataHeatHaze( uint32_t* materials, Material& material, drawSur gl_heatHazeShaderMaterial->WriteUniformsToBuffer( materials ); } -void UpdateSurfaceDataLiquid( uint32_t* materials, Material& material, drawSurf_t* drawSurf, const uint32_t stage ) { - shader_t* shader = drawSurf->shader; - shaderStage_t* pStage = &shader->stages[stage]; +void UpdateSurfaceDataLiquid( uint32_t* materials, Material& material, shaderStage_t* pStage ) { + shader_t* shader = pStage->shader; - const uint32_t paddedOffset = drawSurf->materialsSSBOOffset[stage] * material.shader->GetPaddedSize(); + const uint32_t paddedOffset = ( pStage->materialsSSBOOffset + pStage->currentOffset ) * material.shader->GetPaddedSize(); materials += paddedOffset; - bool updated = !drawSurf->initialized[stage] || pStage->colorDynamic || pStage->texMatricesDynamic || pStage->dynamic; + bool updated = !pStage->bufferInitialized || pStage->colorDynamic || pStage->dynamic; if ( !updated ) { return; } - drawSurf->initialized[stage] = true; + pStage->bufferInitialized = true; float fogDensity = RB_EvalExpression( &pStage->fogDensityExp, 0.001 ); vec4_t fogColor; @@ -563,16 +399,8 @@ void UpdateSurfaceDataLiquid( uint32_t* materials, Material& material, drawSurf_ depthScale *= reliefDepthScale == 0 ? 1 : reliefDepthScale; gl_liquidShaderMaterial->SetUniform_ReliefDepthScale( depthScale ); gl_liquidShaderMaterial->SetUniform_ReliefOffsetBias( tess.surfaceShader->reliefOffsetBias ); - - // FIXME: if there is both, embedded heightmap in normalmap is used instead of standalone heightmap - if ( !pStage->hasHeightMapInNormalMap ) { - gl_liquidShaderMaterial->SetUniform_HeightMapBindless( GL_BindToTMU( 15, pStage->bundle[TB_HEIGHTMAP].image[0] ) ); - } } - // bind u_NormalMap - gl_liquidShaderMaterial->SetUniform_NormalMapBindless( GL_BindToTMU( 3, pStage->bundle[TB_NORMALMAP].image[0] ) ); - // bind u_NormalScale if ( pStage->enableNormalMapping ) { vec3_t normalScale; @@ -585,18 +413,17 @@ void UpdateSurfaceDataLiquid( uint32_t* materials, Material& material, drawSurf_ gl_liquidShaderMaterial->WriteUniformsToBuffer( materials ); } -void UpdateSurfaceDataFog( uint32_t* materials, Material& material, drawSurf_t* drawSurf, const uint32_t stage ) { - shader_t* shader = drawSurf->shader; - shaderStage_t* pStage = &shader->stages[stage]; +void UpdateSurfaceDataFog( uint32_t* materials, Material& material, shaderStage_t* pStage ) { + shader_t* shader = pStage->shader; - const uint32_t paddedOffset = drawSurf->materialsSSBOOffset[stage] * material.shader->GetPaddedSize(); + const uint32_t paddedOffset = ( pStage->materialsSSBOOffset + pStage->currentOffset ) * material.shader->GetPaddedSize(); materials += paddedOffset; - bool updated = !drawSurf->initialized[stage] || pStage->colorDynamic || pStage->texMatricesDynamic || pStage->dynamic; + bool updated = !pStage->bufferInitialized || pStage->dynamic; if ( !updated ) { return; } - drawSurf->initialized[stage] = true; + pStage->bufferInitialized = true; const fog_t* fog = material.fog; @@ -609,30 +436,20 @@ void UpdateSurfaceDataFog( uint32_t* materials, Material& material, drawSurf_t* /* * Buffer layout: * // Static surfaces data: -* // Material0 -* // Surface/stage0_0: +* // Stage0: * uniform0_0 * uniform0_1 * .. * uniform0_x * optional_struct_padding -* // Surface/stage0_1: +* // Stage1: * .. -* // Surface/stage0_y: +* // Stage_y: * uniform0_0 * uniform0_1 * .. * uniform0_x * optional_struct_padding -* optional_material1_padding -* // Material1 -* // Surface/stage1_0: -* .. -* // Surface/stage1_y: -* .. -* .. -* // Materialz: -* .. * .. * // Dynamic surfaces data: * // Same as the static layout @@ -642,125 +459,151 @@ void UpdateSurfaceDataFog( uint32_t* materials, Material& material, drawSurf_t* void MaterialSystem::GenerateWorldMaterialsBuffer() { Log::Debug( "Generating materials buffer" ); - uint32_t offset = 0; - materialsSSBO.BindBuffer(); - // Compute data size for static surfaces - for ( MaterialPack& pack : materialPacks ) { - for ( Material& material : pack.materials ) { - // Any new material in the buffer must start on an offset that is an integer multiple of - // the padded size of the material struct - const uint32_t paddedSize = material.shader->GetPaddedSize(); - const uint32_t padding = ( offset % paddedSize == 0 ) ? 0 : paddedSize - ( offset % paddedSize ); + // Sort by padded size to avoid extra padding + std::sort( materialStages.begin(), materialStages.end(), + [&]( const shaderStage_t* lhs, const shaderStage_t* rhs ) { + if ( !lhs->dynamic && rhs->dynamic ) { + return true; + } - offset += padding; - material.staticMaterialsSSBOOffset = offset; - offset += paddedSize * material.totalStaticDrawSurfCount; - } - } + if ( !rhs->dynamic && lhs->dynamic ) { + return false; + } + + return materialPacks[lhs->materialPackID].materials[lhs->materialID].shader->GetPaddedSize() + < materialPacks[rhs->materialPackID].materials[rhs->materialID].shader->GetPaddedSize(); + } ); + uint32_t offset = 0; + uint32_t dynamicOffset = 0; + dynamicStagesOffset = 0; bool dynamicDrawSurfOffsetSet = false; - // Compute data size for dynamic surfaces - for ( MaterialPack& pack : materialPacks ) { - for ( Material& material : pack.materials ) { - // Any new material in the buffer must start on an offset that is an integer multiple of - // the padded size of the material struct - const uint32_t paddedSize = material.shader->GetPaddedSize(); - const uint32_t padding = ( offset % paddedSize == 0 ) ? 0 : paddedSize - ( offset % paddedSize ); - - offset += padding; - - // Make sure padding is taken into account for dynamicDrawSurfsOffset + // Compute data size for stages + for ( shaderStage_t* pStage : materialStages ) { + const uint32_t paddedSize = materialPacks[pStage->materialPackID].materials[pStage->materialID].shader->GetPaddedSize(); + const uint32_t padding = ( offset % paddedSize == 0 ) ? 0 : paddedSize - ( offset % paddedSize ); + + offset += padding; + + // Make sure padding is taken into account for dynamicStagesOffset + if ( pStage->dynamic ) { if ( !dynamicDrawSurfOffsetSet ) { - dynamicDrawSurfsOffset = offset; + dynamicStagesOffset = offset; dynamicDrawSurfOffsetSet = true; } - material.dynamicMaterialsSSBOOffset = offset; - offset += paddedSize * material.totalDynamicDrawSurfCount; + const uint32_t dynamicPadding = ( dynamicOffset % paddedSize == 0 ) ? 0 : paddedSize - ( dynamicOffset % paddedSize ); + dynamicOffset += dynamicPadding; + pStage->dynamicMaterialsOffset = dynamicOffset / paddedSize; + dynamicOffset += paddedSize * pStage->variantOffset; } + + pStage->materialsSSBOOffset = offset / paddedSize; + offset += paddedSize * pStage->variantOffset; } - dynamicDrawSurfsSize = offset - dynamicDrawSurfsOffset; + dynamicStagesSize = dynamicDrawSurfOffsetSet ? offset - dynamicStagesOffset : 0; + totalStageSize = offset; // 4 bytes per component glBufferData( GL_SHADER_STORAGE_BUFFER, offset * sizeof( uint32_t ), nullptr, GL_DYNAMIC_DRAW ); uint32_t* materialsData = materialsSSBO.MapBufferRange( offset ); - memset( materialsData, 0, offset * sizeof( uint32_t ) ); + + GenerateMaterialsBuffer( materialStages, offset, materialsData ); for ( uint32_t materialPackID = 0; materialPackID < 3; materialPackID++ ) { for ( Material& material : materialPacks[materialPackID].materials ) { - for ( drawSurf_t* drawSurf : material.drawSurfs ) { - bool hasDynamicStages = false; - uint32_t stage = 0; for ( shaderStage_t* pStage = drawSurf->shader->stages; pStage < drawSurf->shader->lastStage; pStage++ ) { - if ( drawSurf->materialIDs[stage] != material.id || drawSurf->materialPackIDs[stage] != materialPackID ) { + if ( pStage->materialID != material.id || pStage->materialPackID != materialPackID ) { stage++; continue; } - - uint32_t SSBOOffset = 0; - uint32_t drawSurfCount = 0; - if ( pStage->dynamic ) { - SSBOOffset = material.dynamicMaterialsSSBOOffset; - drawSurfCount = material.currentDynamicDrawSurfCount; - material.currentDynamicDrawSurfCount++; - } else { - SSBOOffset = material.staticMaterialsSSBOOffset; - drawSurfCount = material.currentStaticDrawSurfCount; - material.currentStaticDrawSurfCount++; - } - - drawSurf->materialsSSBOOffset[stage] = ( SSBOOffset + drawSurfCount * material.shader->GetPaddedSize() ) / - material.shader->GetPaddedSize(); - - if ( pStage->dynamic ) { - hasDynamicStages = true; - } - AddStageTextures( drawSurf, pStage, &material ); - - pStage->surfaceDataUpdater( materialsData, material, drawSurf, stage ); + // We need some of the values from the remapped stage, but material/materialPack ID has to come from pStage + shaderStage_t* remappedStage = pStage->materialRemappedStage ? pStage->materialRemappedStage : pStage; + const uint32_t SSBOOffset = + remappedStage->materialsSSBOOffset + remappedStage->variantOffsets[drawSurf->shaderVariant[stage]]; tess.currentDrawSurf = drawSurf; - tess.currentSSBOOffset = tess.currentDrawSurf->materialsSSBOOffset[stage]; - tess.materialID = tess.currentDrawSurf->materialIDs[stage]; - tess.materialPackID = tess.currentDrawSurf->materialPackIDs[stage]; + tess.currentSSBOOffset = SSBOOffset; + tess.materialID = pStage->materialID; + tess.materialPackID = pStage->materialPackID; Tess_Begin( Tess_StageIteratorDummy, nullptr, nullptr, false, -1, 0 ); rb_surfaceTable[Util::ordinal( *drawSurf->surface )]( drawSurf->surface ); - pStage->colorRenderer( pStage ); + remappedStage->colorRenderer( remappedStage ); Tess_Clear(); drawSurf->drawCommandIDs[stage] = lastCommandID; - if ( pStage->dynamic ) { - drawSurf->materialsSSBOOffset[stage] = ( SSBOOffset - dynamicDrawSurfsOffset + drawSurfCount * - material.shader->GetPaddedSize() ) / material.shader->GetPaddedSize(); - } - stage++; } - - if ( hasDynamicStages ) { - // We need a copy here because the memory pointed to by drawSurf will change later - // We'll probably need a separate buffer for entities other than world entity + ensure we don't store a drawSurf with - // invalid pointers - dynamicDrawSurfs.emplace_back( *drawSurf ); - } } } } + for ( shaderStage_t* pStage : materialStages ) { + if ( pStage->dynamic ) { + pStage->materialsSSBOOffset = pStage->dynamicMaterialsOffset; + } + } + materialsSSBO.UnmapBuffer(); } -// This generates the buffer GLIndirect commands +void MaterialSystem::GenerateMaterialsBuffer( std::vector& stages, const uint32_t size, uint32_t* materialsData ) { + // Shader uniforms are set to 0 if they're not specified, so make sure we do that here too + memset( materialsData, 0, size * sizeof( uint32_t ) ); + for ( shaderStage_t* pStage : stages ) { + Material& material = materialPacks[pStage->materialPackID].materials[pStage->materialID]; + + /* Stage variants are essentially copies of the same stage with slightly different values that + normally come from a drawSurf_t */ + uint32_t variants = 0; + for ( int i = 0; i < Util::ordinal( ShaderStageVariant::ALL ) && variants < pStage->variantOffset; i++ ) { + if ( pStage->variantOffsets[i] != -1 ) { + pStage->mayUseVertexOverbright = i & Util::ordinal( ShaderStageVariant::VERTEX_OVERBRIGHT ); + pStage->vertexLit = i & Util::ordinal( ShaderStageVariant::VERTEX_LIT ); + pStage->fullbright = i & Util::ordinal( ShaderStageVariant::FULLBRIGHT ); + pStage->currentOffset = pStage->variantOffsets[i]; + pStage->surfaceDataUpdater( materialsData, material, pStage ); + variants++; + } + } + } +} + +void MaterialSystem::GenerateTexturesBuffer( std::vector& textures, TexBundle* textureBundles ) { + for ( TextureData& textureData : textures ) { + for ( int i = 0; i < MAX_TEXTURE_BUNDLES; i++ ) { + if ( textureData.texBundlesOverride[i] ) { + textureBundles->textures[i] = textureData.texBundlesOverride[i]->texture->bindlessTextureHandle; + continue; + } + + const textureBundle_t* bundle = textureData.texBundles[i]; + if ( bundle && bundle->image[0] ) { + if ( generatingWorldCommandBuffer ) { + textureBundles->textures[i] = bundle->image[0]->texture->bindlessTextureHandle; + } else { + textureBundles->textures[i] = BindAnimatedImage( 0, bundle ); + } + } + } + + // While reflection, liquid and heatHaze shaders use the matrix from TB_NORMALMAP bundle, it's never actually parsed + RB_CalcTexMatrix( textureData.texBundles[0], textureBundles->textureMatrix ); + textureBundles++; + } +} + +// This generates the buffers with indirect rendering commands etc. void MaterialSystem::GenerateWorldCommandBuffer() { Log::Debug( "Generating world command buffer" ); @@ -789,8 +632,6 @@ void MaterialSystem::GenerateWorldCommandBuffer() { Log::Debug( "Total batch count: %u", totalBatchCount ); - drawSurf_t* drawSurf; - surfaceDescriptorsSSBO.BindBuffer(); surfaceDescriptorsCount = totalDrawSurfs; descriptorSize = BOUNDING_SPHERE_SIZE + maxStages; @@ -798,6 +639,67 @@ void MaterialSystem::GenerateWorldCommandBuffer() { nullptr, GL_STATIC_DRAW ); uint32_t* surfaceDescriptors = surfaceDescriptorsSSBO.MapBufferRange( surfaceDescriptorsCount * descriptorSize ); + texDataSSBO.BindBuffer(); + texDataSSBO.BufferStorage( ( texData.size() + dynamicTexData.size() ) * TEX_BUNDLE_SIZE, 1, nullptr ); + texDataSSBO.MapAll(); + TexBundle* textureBundles = ( TexBundle* ) texDataSSBO.GetData(); + memset( textureBundles, 0, ( texData.size() + dynamicTexData.size() ) * TEX_BUNDLE_SIZE * sizeof( uint32_t ) ); + + GenerateTexturesBuffer( texData, textureBundles ); + + textureBundles += texData.size(); + + GenerateTexturesBuffer( dynamicTexData, textureBundles ); + + dynamicTexDataOffset = texData.size() * TEX_BUNDLE_SIZE; + dynamicTexDataSize = dynamicTexData.size() * TEX_BUNDLE_SIZE; + + texDataSSBO.FlushAll(); + texDataSSBO.UnmapBuffer(); + texDataSSBO.UnBindBuffer(); + + lightmapDataUBO.BindBuffer(); + lightmapDataUBO.BufferStorage( MAX_LIGHTMAPS * LIGHTMAP_SIZE, 1, nullptr ); + lightmapDataUBO.MapAll(); + uint64_t* lightmapData = ( uint64_t* ) lightmapDataUBO.GetData(); + memset( lightmapData, 0, MAX_LIGHTMAPS * LIGHTMAP_SIZE * sizeof( uint32_t ) ); + + for ( uint32_t i = 0; i < tr.lightmaps.size(); i++ ) { + if ( !tr.lightmaps[i]->texture->hasBindlessHandle ) { + tr.lightmaps[i]->texture->GenBindlessHandle(); + } + lightmapData[i * 2] = tr.lightmaps[i]->texture->bindlessTextureHandle; + } + for ( uint32_t i = 0; i < tr.deluxemaps.size(); i++ ) { + if ( !tr.deluxemaps[i]->texture->hasBindlessHandle ) { + tr.deluxemaps[i]->texture->GenBindlessHandle(); + } + lightmapData[i * 2 + 1] = tr.deluxemaps[i]->texture->bindlessTextureHandle; + } + + ASSERT_LE( tr.lightmaps.size(), 256 ); // Engine supports up to 256 lightmaps currently, so we use 8 bits to address them + + if ( tr.lightmaps.size() == 256 ) { + /* It's very unlikely that this would actually happen, but put the warn here just in case + If needed, another bit can be added to the lightmap address in rendering commands, but that would mean + that its hex representation would no longer be easily "parsable" by just looking at it in a frame debugger */ + Log::Warn( "Material system only supports up to 255 lightmaps, got 256" ); + } else { + if ( !tr.whiteImage->texture->hasBindlessHandle ) { + tr.whiteImage->texture->GenBindlessHandle(); + } + if ( !tr.blackImage->texture->hasBindlessHandle ) { + tr.blackImage->texture->GenBindlessHandle(); + } + // Use lightmap 255 for drawSurfs that use a full white image for their lightmap + lightmapData[255 * 2] = tr.whiteImage->texture->bindlessTextureHandle; + lightmapData[255 * 2 + 1] = tr.blackImage->texture->bindlessTextureHandle; + } + + lightmapDataUBO.FlushAll(); + lightmapDataUBO.UnmapBuffer(); + lightmapDataUBO.UnBindBuffer(); + surfaceCommandsCount = totalBatchCount * SURFACE_COMMANDS_PER_BATCH; surfaceCommandsSSBO.BindBuffer(); @@ -858,7 +760,8 @@ void MaterialSystem::GenerateWorldCommandBuffer() { } for ( int i = 0; i < tr.refdef.numDrawSurfs; i++ ) { - drawSurf = &tr.refdef.drawSurfs[i]; + const drawSurf_t* drawSurf = &tr.refdef.drawSurfs[i]; + if ( drawSurf->entity != &tr.worldEntity ) { continue; } @@ -891,7 +794,8 @@ void MaterialSystem::GenerateWorldCommandBuffer() { if ( depthPrePass ) { const drawSurf_t* depthDrawSurf = drawSurf->depthSurface; - const Material* material = &materialPacks[depthDrawSurf->materialPackIDs[0]].materials[depthDrawSurf->materialIDs[0]]; + const Material* material = &materialPacks[depthDrawSurf->shader->stages[0].materialPackID] + .materials[depthDrawSurf->shader->stages[0].materialID]; uint cmdID = material->surfaceCommandBatchOffset * SURFACE_COMMANDS_PER_BATCH + depthDrawSurf->drawCommandIDs[0]; // Add 1 because cmd 0 == no-command surface.surfaceCommandIDs[0] = cmdID + 1; @@ -899,12 +803,16 @@ void MaterialSystem::GenerateWorldCommandBuffer() { SurfaceCommand surfaceCommand; surfaceCommand.enabled = 0; surfaceCommand.drawCommand = material->drawCommands[depthDrawSurf->drawCommandIDs[0]].cmd; + // We still need the textures for alpha-tested depth pre-pass surface commands + surfaceCommand.drawCommand.baseInstance |= depthDrawSurf->texDataDynamic[0] + ? ( depthDrawSurf->texDataIDs[0] + texData.size() ) << TEX_BUNDLE_BITS + : depthDrawSurf->texDataIDs[0] << TEX_BUNDLE_BITS; surfaceCommands[cmdID] = surfaceCommand; } uint32_t stage = 0; for ( shaderStage_t* pStage = drawSurf->shader->stages; pStage < drawSurf->shader->lastStage; pStage++ ) { - const Material* material = &materialPacks[drawSurf->materialPackIDs[stage]].materials[drawSurf->materialIDs[stage]]; + const Material* material = &materialPacks[pStage->materialPackID].materials[pStage->materialID]; uint32_t cmdID = material->surfaceCommandBatchOffset * SURFACE_COMMANDS_PER_BATCH + drawSurf->drawCommandIDs[stage]; // Add 1 because cmd 0 == no-command surface.surfaceCommandIDs[stage + ( depthPrePass ? 1 : 0 )] = cmdID + 1; @@ -912,6 +820,10 @@ void MaterialSystem::GenerateWorldCommandBuffer() { SurfaceCommand surfaceCommand; surfaceCommand.enabled = 0; surfaceCommand.drawCommand = material->drawCommands[drawSurf->drawCommandIDs[stage]].cmd; + surfaceCommand.drawCommand.baseInstance |= drawSurf->texDataDynamic[stage] + ? ( drawSurf->texDataIDs[stage] + texData.size() ) << TEX_BUNDLE_BITS + : drawSurf->texDataIDs[stage] << TEX_BUNDLE_BITS; + surfaceCommand.drawCommand.baseInstance |= ( HasLightMap( drawSurf ) ? GetLightMapNum( drawSurf ) : 255 ) << LIGHTMAP_BITS; surfaceCommands[cmdID] = surfaceCommand; stage++; @@ -919,7 +831,8 @@ void MaterialSystem::GenerateWorldCommandBuffer() { if ( drawSurf->fogSurface ) { const drawSurf_t* fogDrawSurf = drawSurf->fogSurface; - const Material* material = &materialPacks[fogDrawSurf->materialPackIDs[0]].materials[fogDrawSurf->materialIDs[0]]; + const Material* material = &materialPacks[fogDrawSurf->shader->stages[0].materialPackID] + .materials[fogDrawSurf->shader->stages[0].materialID]; uint cmdID = material->surfaceCommandBatchOffset * SURFACE_COMMANDS_PER_BATCH + fogDrawSurf->drawCommandIDs[0]; // Add 1 because cmd 0 == no-command surface.surfaceCommandIDs[stage + ( depthPrePass ? 1 : 0 )] = cmdID + 1; @@ -1392,8 +1305,131 @@ void ProcessMaterialFog( Material* material, shaderStage_t* pStage, drawSurf_t* material->program = gl_fogQuake3ShaderMaterial->GetProgram( pStage->deformIndex ); } +void MaterialSystem::AddStage( drawSurf_t* drawSurf, shaderStage_t* pStage, uint32_t stage ) { + const int variant = ( pStage->mayUseVertexOverbright ? Util::ordinal( ShaderStageVariant::VERTEX_OVERBRIGHT ) : 0 ) + | ( pStage->vertexLit ? Util::ordinal( ShaderStageVariant::VERTEX_LIT ) : 0 ) + | ( pStage->fullbright ? Util::ordinal( ShaderStageVariant::FULLBRIGHT ) : 0 ); + + if ( pStage->variantOffsets[variant] == -1 ) { + pStage->variantOffsets[variant] = pStage->variantOffset; + pStage->variantOffset++; + } + + drawSurf->shaderVariant[stage] = variant; + + // Look for a stage that will have the same data layout and data + data changes themselves + for ( shaderStage_t* pStage2 : materialStages ) { + if ( pStage == pStage2 ) { + return; + } + + if ( pStage->shaderBinder != pStage2->shaderBinder ) { + continue; + } + + if ( pStage->dynamic != pStage2->dynamic ) { + continue; + } + + if ( pStage->ifExp != pStage2->ifExp ) { + continue; + } + + if ( pStage->rgbGen != pStage2->rgbGen ) { + continue; + } + + if ( pStage->rgbGen == colorGen_t::CGEN_WAVEFORM && pStage->rgbWave != pStage2->rgbWave ) { + continue; + } + + if ( pStage->rgbGen == colorGen_t::CGEN_CUSTOM_RGB && pStage->rgbExp != pStage2->rgbExp ) { + continue; + } + + if ( pStage->rgbGen == colorGen_t::CGEN_CUSTOM_RGBs && + !( pStage->redExp == pStage2->redExp && pStage->greenExp == pStage2->greenExp && pStage->blueExp == pStage2->blueExp ) ) { + continue; + } + + if ( ( pStage->type == stageType_t::ST_STYLELIGHTMAP || pStage->type == stageType_t::ST_STYLECOLORMAP + || pStage2->type == stageType_t::ST_STYLELIGHTMAP || pStage2->type == stageType_t::ST_STYLECOLORMAP ) && pStage->type != pStage2->type ) { + continue; + } + + if ( pStage->alphaGen != pStage2->alphaGen ) { + continue; + } + + if ( pStage->alphaGen == alphaGen_t::AGEN_WAVEFORM && pStage->alphaWave != pStage2->alphaWave ) { + continue; + } + + if ( pStage->alphaGen == alphaGen_t::AGEN_CUSTOM && pStage->alphaExp != pStage2->alphaExp ) { + continue; + } + + if ( pStage->constantColor.Red() != pStage2->constantColor.Red() || pStage->constantColor.Green() != pStage2->constantColor.Green() + || pStage->constantColor.Blue() != pStage2->constantColor.Blue() || pStage->constantColor.Alpha() != pStage2->constantColor.Alpha() ) { + continue; + } + + if ( pStage->depthFadeValue != pStage2->depthFadeValue ) { + continue; + } + + // Only GLS_ATEST_BITS affect stage data, the other bits go into the material + if ( ( pStage->stateBits & GLS_ATEST_BITS ) != ( pStage2->stateBits & GLS_ATEST_BITS ) ) { + continue; + } + + if ( pStage->refractionIndexExp != pStage2->refractionIndexExp || pStage->specularExponentMin != pStage2->specularExponentMin + || pStage->specularExponentMax != pStage2->specularExponentMax || pStage->fresnelPowerExp != pStage2->fresnelPowerExp + || pStage->fresnelScaleExp != pStage2->fresnelScaleExp || pStage->fresnelBiasExp != pStage2->fresnelBiasExp + || !VectorCompare( pStage->normalScale, pStage2->normalScale ) || pStage->normalIntensityExp != pStage2->normalIntensityExp + || pStage->fogDensityExp != pStage2->fogDensityExp || pStage->depthScaleExp != pStage2->depthScaleExp ) { + continue; + } + + pStage->materialRemappedStage = pStage2; + + return; + } + + // Add at the back if we haven't found any matching ones + materialStages.emplace_back( pStage ); + + if ( pStage->dynamic ) { + dynamicStages.emplace_back( pStage ); + } +} + void MaterialSystem::ProcessStage( drawSurf_t* drawSurf, shaderStage_t* pStage, shader_t* shader, uint32_t* packIDs, uint32_t& stage, uint32_t& previousMaterialID ) { + lightMode_t lightMode; + deluxeMode_t deluxeMode; + SetLightDeluxeMode( drawSurf, pStage->type, lightMode, deluxeMode ); + pStage->mayUseVertexOverbright = pStage->type == stageType_t::ST_COLORMAP && drawSurf->bspSurface && pStage->shaderBinder == BindShaderGeneric3D; + pStage->vertexLit = lightMode == lightMode_t::VERTEX && pStage->shaderBinder == BindShaderLightMapping; + pStage->fullbright = lightMode == lightMode_t::FULLBRIGHT && pStage->shaderBinder == BindShaderLightMapping; + + ComputeDynamics( pStage ); + + AddStage( drawSurf, pStage, stage ); + + if ( pStage->initialized ) { + Material* material = &materialPacks[pStage->materialPackID].materials[pStage->materialID]; + if ( std::find( material->drawSurfs.begin(), material->drawSurfs.end(), drawSurf ) + == material->drawSurfs.end() ) { + material->drawSurfs.emplace_back( drawSurf ); + } + + AddStageTextures( drawSurf, stage, material ); + + stage++; + return; + } + Material material; uint32_t materialPack = 0; @@ -1426,12 +1462,6 @@ void MaterialSystem::ProcessStage( drawSurf_t* drawSurf, shaderStage_t* pStage, material.vbo = glState.currentVBO; material.ibo = glState.currentIBO; - ComputeDynamics( pStage ); - - if ( pStage->texturesDynamic ) { - drawSurf->texturesDynamic[stage] = true; - } - material.bspSurface = drawSurf->bspSurface; pStage->materialProcessor( &material, pStage, drawSurf ); @@ -1462,20 +1492,17 @@ void MaterialSystem::ProcessStage( drawSurf_t* drawSurf, shaderStage_t* pStage, } pStage->useMaterialSystem = true; - materials[previousMaterialID].totalDrawSurfCount++; - if ( pStage->dynamic ) { - materials[previousMaterialID].totalDynamicDrawSurfCount++; - } else { - materials[previousMaterialID].totalStaticDrawSurfCount++; - } + pStage->initialized = true; + + AddStageTextures( drawSurf, stage, &materials[previousMaterialID] ); if ( std::find( materials[previousMaterialID].drawSurfs.begin(), materials[previousMaterialID].drawSurfs.end(), drawSurf ) == materials[previousMaterialID].drawSurfs.end() ) { materials[previousMaterialID].drawSurfs.emplace_back( drawSurf ); } - drawSurf->materialIDs[stage] = previousMaterialID; - drawSurf->materialPackIDs[stage] = materialPack; + pStage->materialID = previousMaterialID; + pStage->materialPackID = materialPack; packIDs[materialPack] = id; @@ -1537,7 +1564,7 @@ void MaterialSystem::GenerateWorldMaterials() { rb_surfaceTable[Util::ordinal( *( drawSurf->surface ) )]( drawSurf->surface ); Tess_Clear(); - // Only add the main surface for surfaces with depth pre-pass to the total count + // Only add the main surface for surfaces with depth pre-pass or fog to the total count if ( !drawSurf->materialSystemSkip ) { totalDrawSurfs++; } @@ -1556,14 +1583,17 @@ void MaterialSystem::GenerateWorldMaterials() { totalCount += pack.materials.size(); } Log::Notice( "Generated %u materials from %u surfaces", totalCount, tr.refdef.numDrawSurfs ); + Log::Notice( "Materials UBO: total: %.2f kb, dynamic: %.2f kb, texData: %.2f kb", + totalStageSize * 4 / 1024.0f, dynamicStagesSize * 4 / 1024.0f, + ( texData.size() + dynamicTexData.size() ) * TEX_BUNDLE_SIZE * 4 / 1024.0f ); + /* for ( const MaterialPack& materialPack : materialPacks ) { Log::Notice( "materialPack sort: %i %i", Util::ordinal( materialPack.fromSort ), Util::ordinal( materialPack.toSort ) ); for ( const Material& material : materialPack.materials ) { - Log::Notice( "id: %u, useSync: %b, sync: %u, program: %i, stateBits: %u, totalDrawSurfCount: %u, shader: %s, vbo: %s, ibo: %s" - ", staticDrawSurfs: %u, dynamicDrawSurfs: %u, culling: %i", - material.id, material.useSync, material.syncMaterial, material.program, material.stateBits, material.totalDrawSurfCount, - material.shader->GetName(), material.vbo->name, material.ibo->name, material.currentStaticDrawSurfCount, - material.currentDynamicDrawSurfCount, material.cullType ); + Log::Notice( "id: %u, useSync: %b, sync: %u, program: %i, stateBits: %u, total drawSurfs: %u, shader: %s, vbo: %s, ibo: %s" + ", culling: %i", + material.id, material.useSync, material.syncMaterial, material.program, material.stateBits, material.drawSurfs.size(), + material.shader->GetName(), material.vbo->name, material.ibo->name, material.cullType ); } } */ @@ -1582,7 +1612,12 @@ void MaterialSystem::AddAllWorldSurfaces() { generatingWorldCommandBuffer = false; } -void MaterialSystem::AddStageTextures( drawSurf_t* drawSurf, shaderStage_t* pStage, Material* material ) { +void MaterialSystem::AddStageTextures( drawSurf_t* drawSurf, const uint32_t stage, Material* material ) { + TextureData textureData; + const shaderStage_t* pStage = &drawSurf->shader->stages[stage]; + + int bundleNum = 0; + bool dynamic = false; for ( const textureBundle_t& bundle : pStage->bundle ) { if ( bundle.isVideoMap ) { material->AddTexture( tr.cinematicImage[bundle.videoMapHandle]->texture ); @@ -1594,10 +1629,16 @@ void MaterialSystem::AddStageTextures( drawSurf_t* drawSurf, shaderStage_t* pSta material->AddTexture( image->texture ); } } + + if ( bundle.numImages > 1 || bundle.numTexMods > 0 ) { + dynamic = true; + } + + textureData.texBundles[bundleNum] = &bundle; + bundleNum++; } // Add lightmap and deluxemap for this surface to the material as well - lightMode_t lightMode; deluxeMode_t deluxeMode; SetLightDeluxeMode( drawSurf, pStage->type, lightMode, deluxeMode ); @@ -1609,6 +1650,21 @@ void MaterialSystem::AddStageTextures( drawSurf_t* drawSurf, shaderStage_t* pSta material->AddTexture( lightmap->texture ); material->AddTexture( deluxemap->texture ); + if ( pStage->type == stageType_t::ST_STYLELIGHTMAP ) { + textureData.texBundlesOverride[TB_COLORMAP] = lightmap; + } + + std::vector& textures = dynamic ? dynamicTexData : texData; + + std::vector::iterator it = std::find( textures.begin(), textures.end(), textureData ); + if ( it == textures.end() ) { + drawSurf->texDataIDs[stage] = textures.size(); + textures.emplace_back( textureData ); + } else { + drawSurf->texDataIDs[stage] = it - textures.begin(); + } + drawSurf->texDataDynamic[stage] = dynamic; + if ( glConfig2.realtimeLighting ) { if ( r_realtimeLightingRenderer.Get() == Util::ordinal( realtimeLightingRenderer_t::TILED ) ) { material->AddTexture( tr.lighttileRenderImage->texture ); @@ -1618,25 +1674,23 @@ void MaterialSystem::AddStageTextures( drawSurf_t* drawSurf, shaderStage_t* pSta // Dynamic surfaces are those whose values in the SSBO can be updated void MaterialSystem::UpdateDynamicSurfaces() { - if ( dynamicDrawSurfsSize == 0 ) { - return; + if ( dynamicStagesSize > 0 ) { + materialsSSBO.BindBuffer(); + uint32_t* materialsData = materialsSSBO.MapBufferRange( dynamicStagesOffset, dynamicStagesSize ); + + GenerateMaterialsBuffer( dynamicStages, dynamicStagesSize, materialsData ); + + materialsSSBO.UnmapBuffer(); } - materialsSSBO.BindBuffer(); - uint32_t* materialsData = materialsSSBO.MapBufferRange( dynamicDrawSurfsOffset, dynamicDrawSurfsSize ); - // Shader uniforms are set to 0 if they're not specified, so make sure we do that here too - memset( materialsData, 0, 4 * dynamicDrawSurfsSize ); - for ( drawSurf_t& drawSurf : dynamicDrawSurfs ) { - uint32_t stage = 0; - for ( shaderStage_t* pStage = drawSurf.shader->stages; pStage < drawSurf.shader->lastStage; pStage++ ) { - Material& material = materialPacks[drawSurf.materialPackIDs[stage]].materials[drawSurf.materialIDs[stage]]; + if ( dynamicTexDataSize > 0 ) { + texDataSSBO.BindBuffer(); + TexBundle* textureBundles = ( TexBundle* ) texDataSSBO.MapBufferRange( dynamicTexDataOffset, dynamicTexDataSize ); - pStage->surfaceDataUpdater( materialsData, material, &drawSurf, stage ); + GenerateTexturesBuffer( dynamicTexData, textureBundles ); - stage++; - } + texDataSSBO.UnmapBuffer(); } - materialsSSBO.UnmapBuffer(); } void MaterialSystem::UpdateFrameData() { @@ -1890,19 +1944,24 @@ void MaterialSystem::GeneratePortalBoundingSpheres() { void MaterialSystem::Free() { generatedWorldCommandBuffer = false; - dynamicDrawSurfs.clear(); + materialStages.clear(); + dynamicStages.clear(); autospriteSurfaces.clear(); portalSurfaces.clear(); portalSurfacesTmp.clear(); portalBounds.clear(); skyShaders.clear(); renderedMaterials.clear(); + texData.clear(); + dynamicTexData.clear(); R_SyncRenderThread(); surfaceCommandsSSBO.UnmapBuffer(); culledCommandsBuffer.UnmapBuffer(); atomicCommandCountersBuffer.UnmapBuffer(); + texDataSSBO.UnmapBuffer(); + lightmapDataUBO.UnmapBuffer(); if ( totalPortals > 0 ) { portalSurfacesSSBO.UnmapBuffer(); @@ -2206,6 +2265,9 @@ void MaterialSystem::RenderMaterial( Material& material, const uint32_t viewID ) atomicCommandCountersBuffer.BindBuffer( GL_PARAMETER_BUFFER_ARB ); + texDataSSBO.BindBufferBase(); + lightmapDataUBO.BindBufferBase(); + if ( r_showGlobalMaterials.Get() && material.sort != 0 && ( material.shaderBinder == BindShaderLightMapping || material.shaderBinder == BindShaderGeneric3D ) ) { vec3_t color; @@ -2320,6 +2382,9 @@ void MaterialSystem::RenderMaterial( Material& material, const uint32_t viewID ) atomicCommandCountersBuffer.UnBindBuffer( GL_PARAMETER_BUFFER_ARB ); + texDataSSBO.UnBindBufferBase(); + lightmapDataUBO.UnBindBufferBase(); + if ( material.usePolygonOffset ) { glDisable( GL_POLYGON_OFFSET_FILL ); } diff --git a/src/engine/renderer/Material.h b/src/engine/renderer/Material.h index 9a41d0093c..16a22eabf9 100644 --- a/src/engine/renderer/Material.h +++ b/src/engine/renderer/Material.h @@ -70,14 +70,6 @@ struct DrawCommand { struct Material { uint32_t materialsSSBOOffset = 0; - uint32_t staticMaterialsSSBOOffset = 0; - uint32_t dynamicMaterialsSSBOOffset = 0; - uint32_t totalDrawSurfCount = 0; - uint32_t totalStaticDrawSurfCount = 0; - uint32_t totalDynamicDrawSurfCount = 0; - uint32_t currentDrawSurfCount = 0; - uint32_t currentStaticDrawSurfCount = 0; - uint32_t currentDynamicDrawSurfCount = 0; uint32_t globalID = 0; uint32_t surfaceCommandBatchOffset = 0; @@ -143,6 +135,69 @@ struct Material { } }; +struct TexBundle { + matrix_t textureMatrix; + GLuint64 textures[MAX_TEXTURE_BUNDLES]; + GLuint64 padding; +}; + +struct TextureData { + const textureBundle_t* texBundles[MAX_TEXTURE_BUNDLES] = { nullptr, nullptr, nullptr, nullptr, nullptr }; + // For ST_STYLELIGHTMAP stages + image_t* texBundlesOverride[MAX_TEXTURE_BUNDLES] = { nullptr, nullptr, nullptr, nullptr, nullptr }; + + bool operator==( const TextureData& other ) const { + for ( int i = 0; i < MAX_TEXTURE_BUNDLES; i++ ) { + if ( texBundlesOverride[i] != other.texBundlesOverride[i] ) { + return false; + } + + // Skip texBundles check for ST_STYLELIGHTMAP + if ( texBundlesOverride[i] ) { + continue; + } + + const textureBundle_t* bundle = texBundles[i]; + const textureBundle_t* otherBundle = other.texBundles[i]; + + if ( bundle->numImages != otherBundle->numImages ) { + return false; + } + + if ( ( bundle->numImages > 1 ) && ( bundle->imageAnimationSpeed != otherBundle->imageAnimationSpeed ) ) { + return false; + } + + const uint8_t numImages = bundle->numImages > 0 ? bundle->numImages : 1; + for ( int j = 0; j < numImages; j++ ) { + if ( bundle->image[j] != otherBundle->image[j] ) { + return false; + } + } + + if ( bundle->numTexMods != otherBundle->numTexMods ) { + return false; + } + + for ( size_t j = 0; j < bundle->numTexMods; j++ ) { + if ( bundle->texMods[j] != otherBundle->texMods[j] ) { + return false; + } + } + } + + return true; + } + + TextureData() { + } + + TextureData( const TextureData& other ) { + memcpy( texBundles, other.texBundles, MAX_TEXTURE_BUNDLES * sizeof( textureBundle_t* ) ); + memcpy( texBundlesOverride, other.texBundlesOverride, MAX_TEXTURE_BUNDLES * sizeof( image_t* ) ); + } +}; + enum class MaterialDebugMode { NONE, DEPTH, @@ -178,6 +233,10 @@ extern PortalView portalStack[MAX_VIEWS]; #define INDIRECT_COMMAND_SIZE 5 #define SURFACE_COMMAND_SIZE 4 #define SURFACE_COMMAND_BATCH_SIZE 2 +#define TEX_BUNDLE_SIZE 28 +#define TEX_BUNDLE_BITS 12 +#define LIGHTMAP_SIZE 4 +#define LIGHTMAP_BITS 24 #define PORTAL_SURFACE_SIZE 8 #define MAX_FRAMES 2 @@ -276,7 +335,8 @@ class MaterialSystem { void GenerateDepthImages( const int width, const int height, imageParams_t imageParms ); - void AddStageTextures( drawSurf_t* drawSurf, shaderStage_t* pStage, Material* material ); + void AddStageTextures( drawSurf_t* drawSurf, const uint32_t stage, Material* material ); + void AddStage( drawSurf_t* drawSurf, shaderStage_t* pStage, uint32_t stage ); void ProcessStage( drawSurf_t* drawSurf, shaderStage_t* pStage, shader_t* shader, uint32_t* packIDs, uint32_t& stage, uint32_t& previousMaterialID ); void GenerateWorldMaterials(); @@ -284,6 +344,9 @@ class MaterialSystem { void GenerateWorldCommandBuffer(); void GeneratePortalBoundingSpheres(); + void GenerateMaterialsBuffer( std::vector& stages, const uint32_t size, uint32_t* materialsData ); + void GenerateTexturesBuffer( std::vector& textures, TexBundle* textureBundles ); + void AddAllWorldSurfaces(); void Free(); @@ -308,9 +371,17 @@ class MaterialSystem { uint32_t surfaceCommandsCount = 0; uint32_t surfaceDescriptorsCount = 0; - std::vector dynamicDrawSurfs; - uint32_t dynamicDrawSurfsOffset = 0; - uint32_t dynamicDrawSurfsSize = 0; + std::vector materialStages; + std::vector dynamicStages; + + std::vector texData; + std::vector dynamicTexData; + + uint32_t totalStageSize; + uint32_t dynamicStagesOffset = 0; + uint32_t dynamicStagesSize = 0; + uint32_t dynamicTexDataOffset = 0; + uint32_t dynamicTexDataSize = 0; Frame frames[MAX_FRAMES]; uint32_t currentFrame = 0; @@ -324,6 +395,8 @@ class MaterialSystem { }; extern GLSSBO materialsSSBO; // Global +extern GLSSBO texDataSSBO; // Global +extern GLUBO lightmapDataUBO; // Global extern GLSSBO surfaceDescriptorsSSBO; // Global extern GLSSBO surfaceCommandsSSBO; // Per viewframe, GPU updated @@ -336,16 +409,18 @@ extern GLSSBO debugSSBO; // Global extern MaterialSystem materialSystem; -void UpdateSurfaceDataNONE( uint32_t*, Material&, drawSurf_t*, const uint32_t ); -void UpdateSurfaceDataNOP( uint32_t*, Material&, drawSurf_t*, const uint32_t ); -void UpdateSurfaceDataGeneric3D( uint32_t* materials, Material& material, drawSurf_t* drawSurf, const uint32_t stage ); -void UpdateSurfaceDataLightMapping( uint32_t* materials, Material& material, drawSurf_t* drawSurf, const uint32_t stage ); -void UpdateSurfaceDataReflection( uint32_t* materials, Material& material, drawSurf_t* drawSurf, const uint32_t stage ); -void UpdateSurfaceDataSkybox( uint32_t* materials, Material& material, drawSurf_t* drawSurf, const uint32_t stage ); -void UpdateSurfaceDataScreen( uint32_t* materials, Material& material, drawSurf_t* drawSurf, const uint32_t stage ); -void UpdateSurfaceDataHeatHaze( uint32_t* materials, Material& material, drawSurf_t* drawSurf, const uint32_t stage ); -void UpdateSurfaceDataLiquid( uint32_t* materials, Material& material, drawSurf_t* drawSurf, const uint32_t stage ); -void UpdateSurfaceDataFog( uint32_t* materials, Material& material, drawSurf_t* drawSurf, const uint32_t stage ); +void UpdateSurfaceDataNONE( uint32_t*, Material&, shaderStage_t* ); +void UpdateSurfaceDataNOP( uint32_t*, Material&, shaderStage_t* ); +void UpdateSurfaceDataGeneric3D( uint32_t* materials, Material& material, shaderStage_t* pStage ); +void UpdateSurfaceDataLightMapping( uint32_t* materials, Material& material, shaderStage_t* pStage ); +void UpdateSurfaceDataReflection( uint32_t* materials, Material& material, shaderStage_t* pStage ); +void UpdateSurfaceDataSkybox( uint32_t* materials, Material& material, shaderStage_t* pStage ); +void UpdateSurfaceDataScreen( uint32_t* materials, Material& material, shaderStage_t* pStage ); +void UpdateSurfaceDataHeatHaze( uint32_t* materials, Material& material, shaderStage_t* pStage ); +void UpdateSurfaceDataLiquid( uint32_t* materials, Material& material, shaderStage_t* pStage ); +void UpdateSurfaceDataFog( uint32_t* materials, Material& material, shaderStage_t* pStage ); + +// void UpdateSurf( uint32) void BindShaderNONE( Material* ); void BindShaderNOP( Material* ); @@ -360,7 +435,7 @@ void BindShaderFog( Material* material ); void ProcessMaterialNONE( Material*, shaderStage_t*, drawSurf_t* ); void ProcessMaterialNOP( Material*, shaderStage_t*, drawSurf_t* ); -void ProcessMaterialGeneric3D( Material* material, shaderStage_t* pStage, drawSurf_t* drawSurf ); +void ProcessMaterialGeneric3D( Material* material, shaderStage_t* pStage, drawSurf_t* /* drawSurf */ ); void ProcessMaterialLightMapping( Material* material, shaderStage_t* pStage, drawSurf_t* drawSurf ); void ProcessMaterialReflection( Material* material, shaderStage_t* pStage, drawSurf_t* /* drawSurf */ ); void ProcessMaterialSkybox( Material* material, shaderStage_t* pStage, drawSurf_t* /* drawSurf */ ); diff --git a/src/engine/renderer/ShadeCommon.h b/src/engine/renderer/ShadeCommon.h index 79fc32abff..f83f6ecf92 100644 --- a/src/engine/renderer/ShadeCommon.h +++ b/src/engine/renderer/ShadeCommon.h @@ -32,12 +32,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================== */ -inline size_t GetLightMapNum( shaderCommands_t* tess ) +inline size_t GetLightMapNum( const shaderCommands_t* tess ) { return tess->lightmapNum; } -inline size_t GetLightMapNum( drawSurf_t* drawSurf ) +inline size_t GetLightMapNum( const drawSurf_t* drawSurf ) { return drawSurf->lightmapNum(); } diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index d37926ffdb..5ef5fc7910 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -1360,8 +1360,35 @@ std::string GLShaderManager::ShaderPostProcess( GLShader *shader, const std::str std::string newShaderText; std::string materialStruct = "\nstruct Material {\n"; std::string materialBlock = "layout(std430, binding = 0) readonly buffer materialsSSBO {\n" - " Material materials[];\n" - "};\n\n"; + " Material materials[];\n" + "};\n\n"; + std::string texDataBlock = "struct TexData {\n" + " mat4 u_TextureMatrix;\n" + " uvec2 u_DiffuseMap;\n" + " uvec2 u_NormalMap;\n" + " uvec2 u_HeightMap;\n" + " uvec2 u_MaterialMap;\n" + " uvec2 u_GlowMap;\n" + " uvec2 padding;\n" + "};\n\n" + "layout(std430, binding = 6) readonly buffer texDataSSBO {\n" + " TexData texData[];\n" + "};\n\n" + "#define u_TextureMatrix texData[( baseInstance >> 12 ) & 0xFFF].u_TextureMatrix\n" + "#define u_DiffuseMap_initial uvec2( texData[( baseInstance >> 12 ) & 0xFFF].u_DiffuseMap )\n" + "#define u_NormalMap_initial uvec2( texData[( baseInstance >> 12 ) & 0xFFF].u_NormalMap )\n" + "#define u_HeightMap_initial uvec2( texData[( baseInstance >> 12 ) & 0xFFF].u_HeightMap )\n" + "#define u_MaterialMap_initial uvec2( texData[( baseInstance >> 12 ) & 0xFFF].u_MaterialMap )\n" + "#define u_GlowMap_initial uvec2( texData[( baseInstance >> 12 ) & 0xFFF].u_GlowMap )\n\n" + "struct LightMapData {\n" + " uvec2 u_LightMap;\n" + " uvec2 u_DeluxeMap;\n" + "};\n\n" + "layout(std140, binding = 7) uniform lightmapDataUBO {\n" + " LightMapData lightmapData[256];\n" + "};\n\n" + "#define u_LightMap_initial lightmapData[( baseInstance >> 24 ) & 0xFF].u_LightMap\n" + "#define u_DeluxeMap_initial lightmapData[( baseInstance >> 24 ) & 0xFF].u_DeluxeMap\n\n"; std::string materialDefines; /* Generate the struct and defines in the form of: @@ -1380,24 +1407,25 @@ std::string GLShaderManager::ShaderPostProcess( GLShader *shader, const std::str continue; } - if ( uniform->IsTexture() ) { - materialStruct += " uvec2 "; - materialStruct += uniform->GetName(); - } else { - materialStruct += " " + uniform->GetType() + " " + uniform->GetName(); - } + if ( !uniform->IsTexture() ) { + materialStruct += " " + uniform->GetType() + " " + uniform->GetName(); - if ( uniform->GetComponentSize() ) { - materialStruct += "[ " + std::to_string( uniform->GetComponentSize() ) + " ]"; + if ( uniform->GetComponentSize() ) { + materialStruct += "[ " + std::to_string( uniform->GetComponentSize() ) + " ]"; + } + materialStruct += ";\n"; + + // vec3 is aligned to 4 components, so just pad it with int + // TODO: Try to move 1 component uniforms here to avoid wasting memory + if ( uniform->GetSTD430Size() == 3 ) { + materialStruct += " int "; + materialStruct += uniform->GetName(); + materialStruct += "_padding;\n"; + } } - materialStruct += ";\n"; - // vec3 is aligned to 4 components, so just pad it with int - // TODO: Try to move 1 component uniforms here to avoid wasting memory - if ( uniform->GetSTD430Size() == 3 ) { - materialStruct += " int "; - materialStruct += uniform->GetName(); - materialStruct += "_padding;\n"; + if ( uniform->IsTexture() ) { + continue; } materialDefines += "#define "; @@ -1407,7 +1435,7 @@ std::string GLShaderManager::ShaderPostProcess( GLShader *shader, const std::str materialDefines += "_initial uvec2("; // We'll need this to create sampler objects later } - materialDefines += " materials[baseInstance]."; + materialDefines += " materials[baseInstance & 0xFFF]."; materialDefines += uniform->GetName(); if ( uniform->IsTexture() ) { @@ -1419,7 +1447,7 @@ std::string GLShaderManager::ShaderPostProcess( GLShader *shader, const std::str // Array of structs is aligned to the largest member of the struct for ( uint i = 0; i < shader->padding; i++ ) { - materialStruct += " int material_padding" + std::to_string( i ); + materialStruct += " int material_padding" + std::to_string( i ); materialStruct += ";\n"; } @@ -1457,7 +1485,7 @@ std::string GLShaderManager::ShaderPostProcess( GLShader *shader, const std::str materialDefines += "\n"; - newShaderText = "#define USE_MATERIAL_SYSTEM\n" + materialStruct + materialBlock + materialDefines + shaderMain; + newShaderText = "#define USE_MATERIAL_SYSTEM\n" + materialStruct + materialBlock + texDataBlock + materialDefines + shaderMain; return newShaderText; } @@ -1978,7 +2006,7 @@ void GLShader::PostProcessUniforms() { std::vector globalUniforms; for ( GLUniform* uniform : _uniforms ) { - if ( uniform->IsGlobal() ) { + if ( uniform->IsGlobal() || uniform->IsTexture() ) { globalUniforms.emplace_back( uniform ); } } @@ -2178,7 +2206,7 @@ void GLShader::SetRequiredVertexPointers() void GLShader::WriteUniformsToBuffer( uint32_t* buffer ) { uint32_t* bufPtr = buffer; for ( GLUniform* uniform : _uniforms ) { - if ( !uniform->IsGlobal() ) { + if ( !uniform->IsGlobal() && !uniform->IsTexture() ) { bufPtr = uniform->WriteToBuffer( bufPtr ); } } diff --git a/src/engine/renderer/gl_shader.h b/src/engine/renderer/gl_shader.h index 7c49f7b9d8..8020bd1bf9 100644 --- a/src/engine/renderer/gl_shader.h +++ b/src/engine/renderer/gl_shader.h @@ -429,7 +429,8 @@ class GLUniform size_t _locationIndex; GLUniform( GLShader *shader, const char *name, const char* type, const GLuint std430Size, const GLuint std430Alignment, - const bool global, const int components = 0, const bool isTexture = false ) : + const bool global, const int components = 0, + const bool isTexture = false ) : _shader( shader ), _name( name ), _type( type ), @@ -1531,6 +1532,10 @@ class GLUBO : public GLBuffer { GLBuffer::BindBuffer( GL_UNIFORM_BUFFER ); } + void UnBindBuffer() { + GLBuffer::UnBindBuffer( GL_UNIFORM_BUFFER ); + } + void BufferStorage( const GLsizeiptr areaSize, const GLsizeiptr areaCount, const void* data ) { GLBuffer::BufferStorage( GL_UNIFORM_BUFFER, areaSize, areaCount, data ); } @@ -2140,6 +2145,7 @@ class u_ColorMap : GLUniformSampler2D { public: u_ColorMap( GLShader* shader ) : + // While u_ColorMap is used for some screen-space shaders, it's never global in material system shaders GLUniformSampler2D( shader, "u_ColorMap" ) { } @@ -2268,7 +2274,7 @@ class u_LightMap : GLUniformSampler { public: u_LightMap( GLShader* shader ) : - GLUniformSampler( shader, "u_LightMap", "sampler2D", 1 ) { + GLUniformSampler( shader, "u_LightMap", "sampler2D", 1, true ) { } void SetUniform_LightMapBindless( GLuint64 bindlessHandle ) { @@ -2284,7 +2290,7 @@ class u_DeluxeMap : GLUniformSampler { public: u_DeluxeMap( GLShader* shader ) : - GLUniformSampler( shader, "u_DeluxeMap", "sampler2D", 1 ) { + GLUniformSampler( shader, "u_DeluxeMap", "sampler2D", 1, true ) { } void SetUniform_DeluxeMapBindless( GLuint64 bindlessHandle ) { @@ -2701,7 +2707,7 @@ class u_TextureMatrix : { public: u_TextureMatrix( GLShader *shader ) : - GLUniformMatrix4f( shader, "u_TextureMatrix" ) + GLUniformMatrix4f( shader, "u_TextureMatrix", true ) { } diff --git a/src/engine/renderer/glsl_source/generic_vp.glsl b/src/engine/renderer/glsl_source/generic_vp.glsl index 6ea263733f..8553433d39 100644 --- a/src/engine/renderer/glsl_source/generic_vp.glsl +++ b/src/engine/renderer/glsl_source/generic_vp.glsl @@ -28,7 +28,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #insert vertexAnimation_vp #insert shaderProfiler_vp -uniform mat4 u_TextureMatrix; +#if !defined(USE_MATERIAL_SYSTEM) + uniform mat4 u_TextureMatrix; +#endif + uniform vec3 u_ViewOrigin; uniform float u_Time; diff --git a/src/engine/renderer/glsl_source/heatHaze_vp.glsl b/src/engine/renderer/glsl_source/heatHaze_vp.glsl index 29fd607409..05656d4836 100644 --- a/src/engine/renderer/glsl_source/heatHaze_vp.glsl +++ b/src/engine/renderer/glsl_source/heatHaze_vp.glsl @@ -28,7 +28,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA uniform float u_Time; -uniform mat4 u_TextureMatrix; +#if !defined(USE_MATERIAL_SYSTEM) + uniform mat4 u_TextureMatrix; +#endif + uniform mat4 u_ProjectionMatrixTranspose; uniform mat4 u_ModelViewMatrixTranspose; uniform mat4 u_ModelViewProjectionMatrix; diff --git a/src/engine/renderer/glsl_source/lightMapping_vp.glsl b/src/engine/renderer/glsl_source/lightMapping_vp.glsl index 6cdae695ed..e884649a6e 100644 --- a/src/engine/renderer/glsl_source/lightMapping_vp.glsl +++ b/src/engine/renderer/glsl_source/lightMapping_vp.glsl @@ -36,7 +36,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #define USE_LIGHT_MAPPING #endif -uniform mat4 u_TextureMatrix; +#if !defined(USE_MATERIAL_SYSTEM) + uniform mat4 u_TextureMatrix; +#endif #if defined(USE_MODEL_SURFACE) uniform mat4 u_ModelMatrix; diff --git a/src/engine/renderer/glsl_source/liquid_vp.glsl b/src/engine/renderer/glsl_source/liquid_vp.glsl index b65e2f44e9..290e8c86c6 100644 --- a/src/engine/renderer/glsl_source/liquid_vp.glsl +++ b/src/engine/renderer/glsl_source/liquid_vp.glsl @@ -28,7 +28,10 @@ IN vec3 attr_Tangent; IN vec3 attr_Binormal; IN vec3 attr_Normal; -uniform mat4 u_TextureMatrix; +#if !defined(USE_MATERIAL_SYSTEM) + uniform mat4 u_TextureMatrix; +#endif + uniform mat4 u_ModelMatrix; uniform mat4 u_ModelViewProjectionMatrix; diff --git a/src/engine/renderer/glsl_source/material_fp.glsl b/src/engine/renderer/glsl_source/material_fp.glsl index 5584f24fdb..9bf8caf54e 100644 --- a/src/engine/renderer/glsl_source/material_fp.glsl +++ b/src/engine/renderer/glsl_source/material_fp.glsl @@ -59,7 +59,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #endif // !COMPUTELIGHT_GLSL #if defined(GENERIC_GLSL) - sampler2D u_ColorMap = sampler2D( u_ColorMap_initial ); + sampler2D u_ColorMap = sampler2D( u_DiffuseMap_initial ); #endif // !GENERIC_GLSL #if defined(LIGHTMAPPING_GLSL) @@ -71,7 +71,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #endif // !LIGHTMAPPING_GLSL #if defined(REFLECTION_CB_GLSL) - samplerCube u_ColorMapCube = samplerCube( u_ColorMapCube_initial ); + samplerCube u_ColorMapCube = samplerCube( u_DiffuseMap_initial ); #endif // !REFLECTION_CB_GLSL #if defined(RELIEFMAPPING_GLSL) @@ -89,8 +89,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #endif // !RELIEFMAPPING_GLSL #if defined(SKYBOX_GLSL) - samplerCube u_ColorMapCube = samplerCube( u_ColorMapCube_initial ); - sampler2D u_CloudMap = sampler2D( u_CloudMap_initial ); + samplerCube u_ColorMapCube = samplerCube( u_DiffuseMap_initial ); + sampler2D u_CloudMap = sampler2D( u_NormalMap_initial ); #endif // !SKYBOX_GLSL #else // !HAVE_ARB_bindless_texture diff --git a/src/engine/renderer/glsl_source/reflection_CB_vp.glsl b/src/engine/renderer/glsl_source/reflection_CB_vp.glsl index 240f02093d..8380de171e 100644 --- a/src/engine/renderer/glsl_source/reflection_CB_vp.glsl +++ b/src/engine/renderer/glsl_source/reflection_CB_vp.glsl @@ -26,7 +26,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #insert vertexSkinning_vp #insert vertexAnimation_vp -uniform mat4 u_TextureMatrix; +#if !defined(USE_MATERIAL_SYSTEM) + uniform mat4 u_TextureMatrix; +#endif + uniform mat4 u_ModelMatrix; uniform mat4 u_ModelViewProjectionMatrix; diff --git a/src/engine/renderer/glsl_source/skybox_fp.glsl b/src/engine/renderer/glsl_source/skybox_fp.glsl index 13f0fa2477..a89f1a6b89 100644 --- a/src/engine/renderer/glsl_source/skybox_fp.glsl +++ b/src/engine/renderer/glsl_source/skybox_fp.glsl @@ -33,7 +33,9 @@ uniform sampler2D u_CloudMap; uniform bool u_UseCloudMap; uniform float u_CloudHeight; -uniform mat4 u_TextureMatrix; +#if !defined(USE_MATERIAL_SYSTEM) + uniform mat4 u_TextureMatrix; +#endif uniform float u_AlphaThreshold; diff --git a/src/engine/renderer/tr_backend.cpp b/src/engine/renderer/tr_backend.cpp index 70352f37ec..72c040ab27 100644 --- a/src/engine/renderer/tr_backend.cpp +++ b/src/engine/renderer/tr_backend.cpp @@ -82,7 +82,7 @@ void GL_Unbind( image_t *image ) glBindTexture( image->type, 0 ); } -GLuint64 BindAnimatedImage( int unit, textureBundle_t *bundle ) +GLuint64 BindAnimatedImage( int unit, const textureBundle_t *bundle ) { int index; diff --git a/src/engine/renderer/tr_local.h b/src/engine/renderer/tr_local.h index 3bf09cf9e7..1289710ea3 100644 --- a/src/engine/renderer/tr_local.h +++ b/src/engine/renderer/tr_local.h @@ -911,6 +911,24 @@ enum class shaderProfilerRenderSubGroupsMode { { expOperation_t ops[ MAX_EXPRESSION_OPS ]; size_t numOps; + + bool operator==( const expression_t& other ) { + if ( numOps != other.numOps ) { + return false; + } + + for ( size_t i = 0; i < numOps; i++ ) { + if ( ops[i].type != other.ops[i].type || ops[i].value != other.ops[i].value ) { + return false; + } + } + + return true; + } + + bool operator!=( const expression_t& other ) { + return !( *this == other ); + } }; struct waveForm_t @@ -921,6 +939,15 @@ enum class shaderProfilerRenderSubGroupsMode { float amplitude; float phase; float frequency; + + bool operator==( const waveForm_t& other ) { + return func == other.func && base == other.base && amplitude == other.amplitude && phase == other.phase + && frequency == other.frequency; + } + + bool operator!=( const waveForm_t& other ) { + return !( *this == other ); + } }; #define TR_MAX_TEXMODS 4 @@ -988,6 +1015,17 @@ enum class shaderProfilerRenderSubGroupsMode { expression_t sExp; expression_t tExp; expression_t rExp; + + bool operator==( const texModInfo_t& other ) { + return type == other.type && wave == other.wave && MatrixCompare( matrix, other.matrix ) + && scale[0] == other.scale[0] && scale[1] == other.scale[1] && scroll[0] == other.scroll[0] && scroll[1] == other.scroll[1] + && rotateSpeed == other.rotateSpeed + && sExp == other.sExp && tExp == other.tExp && rExp == other.rExp; + } + + bool operator!=( const texModInfo_t& other ) { + return !( *this == other ); + } }; #define MAX_IMAGE_ANIMATIONS 32 @@ -1064,10 +1102,17 @@ enum class shaderProfilerRenderSubGroupsMode { struct drawSurf_t; using stageRenderer_t = void(*)(shaderStage_t *); - using stageSurfaceDataUpdater_t = void(*)(uint32_t*, Material&, drawSurf_t*, const uint32_t); + using surfaceDataUpdater_t = void(*)(uint32_t*, Material&, shaderStage_t*); using stageShaderBinder_t = void(*)(Material*); using stageMaterialProcessor_t = void(*)(Material*, shaderStage_t*, drawSurf_t*); + enum class ShaderStageVariant { + VERTEX_OVERBRIGHT = 1, + VERTEX_LIT = BIT( 1 ), + FULLBRIGHT = BIT( 2 ), + ALL = BIT( 3 ) + }; + struct shaderStage_t { stageType_t type; @@ -1082,7 +1127,7 @@ enum class shaderProfilerRenderSubGroupsMode { stageRenderer_t colorRenderer; // Material renderer (code path for advanced OpenGL techniques like bindless textures). - stageSurfaceDataUpdater_t surfaceDataUpdater; + surfaceDataUpdater_t surfaceDataUpdater; stageShaderBinder_t shaderBinder; stageMaterialProcessor_t materialProcessor; @@ -1164,12 +1209,28 @@ enum class shaderProfilerRenderSubGroupsMode { bool noFog; // used only for shaders that have fog disabled, so we can enable it for individual stages bool useMaterialSystem = false; + shader_t* shader; + shaderStage_t* materialRemappedStage = nullptr; + + uint32_t materialsSSBOOffset = 0; + uint32_t dynamicMaterialsOffset = 0; + + bool initialized = false; + bool bufferInitialized = false; + uint materialPackID = 0; uint materialID = 0; + bool dynamic = false; bool colorDynamic = false; - bool texMatricesDynamic = false; - bool texturesDynamic = false; + + int variantOffsets[Util::ordinal( ShaderStageVariant::ALL )]; + uint32_t variantOffset = 0; + uint32_t currentOffset = 0; + + bool mayUseVertexOverbright = false; + bool vertexLit = false; + bool fullbright = false; }; enum cullType_t : int @@ -1606,12 +1667,10 @@ enum class shaderProfilerRenderSubGroupsMode { int fog; int portalNum = -1; - uint materialsSSBOOffset[ MAX_SHADER_STAGES ]; - bool initialized[ MAX_SHADER_STAGES ]; - uint materialIDs[ MAX_SHADER_STAGES ]; - uint materialPackIDs[ MAX_SHADER_STAGES ]; - bool texturesDynamic[ MAX_SHADER_STAGES ]; - uint drawCommandIDs[ MAX_SHADER_STAGES ]; + uint32_t drawCommandIDs[MAX_SHADER_STAGES]; + uint32_t texDataIDs[MAX_SHADER_STAGES]; + bool texDataDynamic[MAX_SHADER_STAGES]; + uint32_t shaderVariant[MAX_SHADER_STAGES]; drawSurf_t* depthSurface; drawSurf_t* fogSurface; @@ -3192,7 +3251,7 @@ inline bool checkGLErrors() void GL_Bind( image_t *image ); void GL_BindNearestCubeMap( int unit, const vec3_t xyz ); void GL_Unbind( image_t *image ); - GLuint64 BindAnimatedImage( int unit, textureBundle_t *bundle ); + GLuint64 BindAnimatedImage( int unit, const textureBundle_t *bundle ); void GL_TextureFilter( image_t *image, filterType_t filterType ); void GL_BindProgram( shaderProgram_t *program ); GLuint64 GL_BindToTMU( int unit, image_t *image ); diff --git a/src/engine/renderer/tr_shade.cpp b/src/engine/renderer/tr_shade.cpp index 235743706a..ee8297ad59 100644 --- a/src/engine/renderer/tr_shade.cpp +++ b/src/engine/renderer/tr_shade.cpp @@ -2698,9 +2698,9 @@ void Tess_StageIteratorColor() Tess_ComputeTexMatrices( pStage ); if ( materialSystem.generatingWorldCommandBuffer && pStage->useMaterialSystem ) { - tess.currentSSBOOffset = tess.currentDrawSurf->materialsSSBOOffset[stage]; - tess.materialID = tess.currentDrawSurf->materialIDs[stage]; - tess.materialPackID = tess.currentDrawSurf->materialPackIDs[stage]; + tess.currentSSBOOffset = pStage->materialsSSBOOffset; + tess.materialID = pStage->materialID; + tess.materialPackID = pStage->materialPackID; } pStage->colorRenderer( pStage ); diff --git a/src/engine/renderer/tr_shader.cpp b/src/engine/renderer/tr_shader.cpp index 77b52a80ce..81a45342c6 100644 --- a/src/engine/renderer/tr_shader.cpp +++ b/src/engine/renderer/tr_shader.cpp @@ -5239,6 +5239,8 @@ static void FinishStages() default: break; } + + memset( stage->variantOffsets, -1, Util::ordinal( ShaderStageVariant::ALL ) * sizeof( int ) ); } GroupActiveStages(); @@ -5372,7 +5374,7 @@ static void SetStagesRenderers() stageRenderer_t colorRenderer; // Material renderer (code path for advanced OpenGL techniques like bindless textures). - stageSurfaceDataUpdater_t surfaceDataUpdater; + surfaceDataUpdater_t surfaceDataUpdater; stageShaderBinder_t shaderBinder; stageMaterialProcessor_t materialProcessor; @@ -5591,6 +5593,8 @@ static shader_t *MakeShaderPermanent() std::copy_n( stages[ s ].bundle[ b ].texMods, newShader->stages[ s ].bundle[ b ].numTexMods, newShader->stages[ s ].bundle[ b ].texMods ); } + + newShader->stages[ s ].shader = newShader; } newShader->lastStage = newShader->stages + numStages; diff --git a/src/engine/renderer/tr_vbo.cpp b/src/engine/renderer/tr_vbo.cpp index 37c95d6285..5e6ab9b246 100644 --- a/src/engine/renderer/tr_vbo.cpp +++ b/src/engine/renderer/tr_vbo.cpp @@ -730,6 +730,8 @@ static void R_InitLightUBO() static void R_InitMaterialBuffers() { if( glConfig2.usingMaterialSystem ) { materialsSSBO.GenBuffer(); + texDataSSBO.GenBuffer(); + lightmapDataUBO.GenBuffer(); surfaceDescriptorsSSBO.GenBuffer(); surfaceCommandsSSBO.GenBuffer(); @@ -860,6 +862,8 @@ void R_ShutdownVBOs() if ( glConfig2.usingMaterialSystem ) { materialsSSBO.DelBuffer(); + texDataSSBO.DelBuffer(); + lightmapDataUBO.DelBuffer(); surfaceDescriptorsSSBO.DelBuffer(); surfaceCommandsSSBO.DelBuffer(); From 8fa176bf1964dcf81043846e0cdba27625d46e02 Mon Sep 17 00:00:00 2001 From: VReaperV Date: Wed, 25 Dec 2024 11:37:11 +0300 Subject: [PATCH 02/27] Change u_TextureMatrix to mat3x2 Only these 6 components (0, 1, 4, 5, 12, 13) actually have an effect. This largely reduces the amount of data being transferred for texture matrices, as well as some useless computations. . --- src/engine/renderer/Material.cpp | 10 +++- src/engine/renderer/Material.h | 33 +++++------ src/engine/renderer/gl_shader.cpp | 3 +- src/engine/renderer/gl_shader.h | 57 ++++++++++++++++++- .../glsl_source/forwardLighting_vp.glsl | 4 +- .../renderer/glsl_source/generic_vp.glsl | 6 +- .../renderer/glsl_source/heatHaze_vp.glsl | 4 +- .../renderer/glsl_source/lightMapping_vp.glsl | 4 +- .../renderer/glsl_source/liquid_vp.glsl | 4 +- .../glsl_source/reflection_CB_vp.glsl | 4 +- .../renderer/glsl_source/shadowFill_vp.glsl | 4 +- .../renderer/glsl_source/skybox_fp.glsl | 4 +- 12 files changed, 96 insertions(+), 41 deletions(-) diff --git a/src/engine/renderer/Material.cpp b/src/engine/renderer/Material.cpp index 8589144de3..ef4dc220d3 100644 --- a/src/engine/renderer/Material.cpp +++ b/src/engine/renderer/Material.cpp @@ -598,7 +598,15 @@ void MaterialSystem::GenerateTexturesBuffer( std::vector& textures, } // While reflection, liquid and heatHaze shaders use the matrix from TB_NORMALMAP bundle, it's never actually parsed - RB_CalcTexMatrix( textureData.texBundles[0], textureBundles->textureMatrix ); + RB_CalcTexMatrix( textureData.texBundles[0], tess.svars.texMatrices[TB_COLORMAP] ); + /* We only actually need these 6 components to get the correct texture transformation, + the other ones are unused */ + textureBundles->textureMatrix[0] = tess.svars.texMatrices[TB_COLORMAP][0]; + textureBundles->textureMatrix[1] = tess.svars.texMatrices[TB_COLORMAP][1]; + textureBundles->textureMatrix[2] = tess.svars.texMatrices[TB_COLORMAP][4]; + textureBundles->textureMatrix[3] = tess.svars.texMatrices[TB_COLORMAP][5]; + textureBundles->textureMatrix[4] = tess.svars.texMatrices[TB_COLORMAP][12]; + textureBundles->textureMatrix[5] = tess.svars.texMatrices[TB_COLORMAP][13]; textureBundles++; } } diff --git a/src/engine/renderer/Material.h b/src/engine/renderer/Material.h index 16a22eabf9..05fa55aa02 100644 --- a/src/engine/renderer/Material.h +++ b/src/engine/renderer/Material.h @@ -136,9 +136,8 @@ struct Material { }; struct TexBundle { - matrix_t textureMatrix; + vec_t textureMatrix[6]; GLuint64 textures[MAX_TEXTURE_BUNDLES]; - GLuint64 padding; }; struct TextureData { @@ -152,27 +151,25 @@ struct TextureData { return false; } - // Skip texBundles check for ST_STYLELIGHTMAP - if ( texBundlesOverride[i] ) { - continue; - } - const textureBundle_t* bundle = texBundles[i]; const textureBundle_t* otherBundle = other.texBundles[i]; - if ( bundle->numImages != otherBundle->numImages ) { - return false; - } - - if ( ( bundle->numImages > 1 ) && ( bundle->imageAnimationSpeed != otherBundle->imageAnimationSpeed ) ) { - return false; - } + // Skip texBundles image check for ST_STYLELIGHTMAP + if ( !texBundlesOverride[i] ) { + if ( bundle->numImages != otherBundle->numImages ) { + return false; + } - const uint8_t numImages = bundle->numImages > 0 ? bundle->numImages : 1; - for ( int j = 0; j < numImages; j++ ) { - if ( bundle->image[j] != otherBundle->image[j] ) { + if ( ( bundle->numImages > 1 ) && ( bundle->imageAnimationSpeed != otherBundle->imageAnimationSpeed ) ) { return false; } + + const uint8_t numImages = bundle->numImages > 0 ? bundle->numImages : 1; + for ( int j = 0; j < numImages; j++ ) { + if ( bundle->image[j] != otherBundle->image[j] ) { + return false; + } + } } if ( bundle->numTexMods != otherBundle->numTexMods ) { @@ -233,7 +230,7 @@ extern PortalView portalStack[MAX_VIEWS]; #define INDIRECT_COMMAND_SIZE 5 #define SURFACE_COMMAND_SIZE 4 #define SURFACE_COMMAND_BATCH_SIZE 2 -#define TEX_BUNDLE_SIZE 28 +#define TEX_BUNDLE_SIZE 16 #define TEX_BUNDLE_BITS 12 #define LIGHTMAP_SIZE 4 #define LIGHTMAP_BITS 24 diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index 5ef5fc7910..1d0e9b6954 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -1363,13 +1363,12 @@ std::string GLShaderManager::ShaderPostProcess( GLShader *shader, const std::str " Material materials[];\n" "};\n\n"; std::string texDataBlock = "struct TexData {\n" - " mat4 u_TextureMatrix;\n" + " mat3x2 u_TextureMatrix;\n" " uvec2 u_DiffuseMap;\n" " uvec2 u_NormalMap;\n" " uvec2 u_HeightMap;\n" " uvec2 u_MaterialMap;\n" " uvec2 u_GlowMap;\n" - " uvec2 padding;\n" "};\n\n" "layout(std430, binding = 6) readonly buffer texDataSSBO {\n" " TexData texData[];\n" diff --git a/src/engine/renderer/gl_shader.h b/src/engine/renderer/gl_shader.h index 8020bd1bf9..41177b198e 100644 --- a/src/engine/renderer/gl_shader.h +++ b/src/engine/renderer/gl_shader.h @@ -1198,6 +1198,48 @@ class GLUniformMatrix4f : protected GLUniform matrix_t currentValue; }; +class GLUniformMatrix32f : protected GLUniform { + protected: + GLUniformMatrix32f( GLShader* shader, const char* name, const bool global = false ) : + GLUniform( shader, name, "mat3x2", 6, 2, global ) { + } + + inline void SetValue( GLboolean transpose, const vec_t* m ) { + shaderProgram_t* p = _shader->GetProgram(); + + if ( _global || !_shader->UseMaterialSystem() ) { + ASSERT_EQ( p, glState.currentProgram ); + } + +#if defined( LOG_GLSL_UNIFORMS ) + if ( r_logFile->integer ) { + GLimp_LogComment( va( "GLSL_SetUniformMatrix32f( %s, shader: %s, transpose: %d, [ %f, %f, %f, %f, %f, %f ] ) ---\n", + this->GetName(), _shader->GetName().c_str(), transpose, + m[0], m[1], m[2], m[3], m[4], m[5] ) ); + } +#endif + + if ( _shader->UseMaterialSystem() && !_global ) { + memcpy( currentValue, m, 6 * sizeof( float ) ); + return; + } + + glUniformMatrix3x2fv( p->uniformLocations[_locationIndex], 1, transpose, m ); + } + public: + size_t GetSize() override { + return 6 * sizeof( float ); + } + + uint32_t* WriteToBuffer( uint32_t* buffer ) override { + memcpy( buffer, currentValue, 6 * sizeof( float ) ); + return buffer + 6 * _components; + } + + private: + vec_t currentValue[6] {}; +}; + class GLUniformMatrix4fv : protected GLUniform { protected: @@ -2703,17 +2745,26 @@ class u_ShadowClipMap4 : }; class u_TextureMatrix : - GLUniformMatrix4f + GLUniformMatrix32f { public: u_TextureMatrix( GLShader *shader ) : - GLUniformMatrix4f( shader, "u_TextureMatrix", true ) + GLUniformMatrix32f( shader, "u_TextureMatrix", true ) { } void SetUniform_TextureMatrix( const matrix_t m ) { - this->SetValue( GL_FALSE, m ); + /* We only actually need these 6 components to get the correct texture transformation, + the other ones are unused */ + static vec_t m2[6]; + m2[0] = m[0]; + m2[1] = m[1]; + m2[2] = m[4]; + m2[3] = m[5]; + m2[4] = m[12]; + m2[5] = m[13]; + this->SetValue( GL_FALSE, m2 ); } }; diff --git a/src/engine/renderer/glsl_source/forwardLighting_vp.glsl b/src/engine/renderer/glsl_source/forwardLighting_vp.glsl index 2263d926f3..06f9039df2 100644 --- a/src/engine/renderer/glsl_source/forwardLighting_vp.glsl +++ b/src/engine/renderer/glsl_source/forwardLighting_vp.glsl @@ -27,7 +27,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #insert vertexSkinning_vp #insert vertexAnimation_vp -uniform mat4 u_TextureMatrix; +uniform mat3x2 u_TextureMatrix; uniform mat4 u_LightAttenuationMatrix; uniform mat4 u_ModelMatrix; uniform mat4 u_ModelViewProjectionMatrix; @@ -86,7 +86,7 @@ void main() var_TexAttenuation = u_LightAttenuationMatrix * position; // transform diffusemap texcoords - var_TexCoords = (u_TextureMatrix * vec4(texCoord, 0.0, 1.0)).st; + var_TexCoords = (u_TextureMatrix * vec3(texCoord, 1.0)).st; var_Color = color; } diff --git a/src/engine/renderer/glsl_source/generic_vp.glsl b/src/engine/renderer/glsl_source/generic_vp.glsl index 8553433d39..09042277f4 100644 --- a/src/engine/renderer/glsl_source/generic_vp.glsl +++ b/src/engine/renderer/glsl_source/generic_vp.glsl @@ -29,7 +29,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #insert shaderProfiler_vp #if !defined(USE_MATERIAL_SYSTEM) - uniform mat4 u_TextureMatrix; + uniform mat3x2 u_TextureMatrix; #endif uniform vec3 u_ViewOrigin; @@ -95,9 +95,9 @@ void main() var_TexCoords = 0.5 + vec2(0.5, -0.5) * reflected.yz; } #elif defined(USE_TCGEN_LIGHTMAP) - var_TexCoords = (u_TextureMatrix * vec4(lmCoord, 0.0, 1.0)).xy; + var_TexCoords = (u_TextureMatrix * vec3(lmCoord, 1.0)).xy; #else - var_TexCoords = (u_TextureMatrix * vec4(texCoord, 0.0, 1.0)).xy; + var_TexCoords = (u_TextureMatrix * vec3(texCoord, 1.0)).xy; #endif #if defined(USE_DEPTH_FADE) diff --git a/src/engine/renderer/glsl_source/heatHaze_vp.glsl b/src/engine/renderer/glsl_source/heatHaze_vp.glsl index 05656d4836..54b7b97206 100644 --- a/src/engine/renderer/glsl_source/heatHaze_vp.glsl +++ b/src/engine/renderer/glsl_source/heatHaze_vp.glsl @@ -29,7 +29,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA uniform float u_Time; #if !defined(USE_MATERIAL_SYSTEM) - uniform mat4 u_TextureMatrix; + uniform mat3x2 u_TextureMatrix; #endif uniform mat4 u_ProjectionMatrixTranspose; @@ -75,7 +75,7 @@ void main() deformVec.z = dot(u_ModelViewMatrixTranspose[2], position); // transform normalmap texcoords - var_TexCoords = (u_TextureMatrix * vec4(texCoord, 0.0, 1.0)).st; + var_TexCoords = (u_TextureMatrix * vec3(texCoord, 1.0)).st; d1 = dot(u_ProjectionMatrixTranspose[0], deformVec); d2 = dot(u_ProjectionMatrixTranspose[3], deformVec); diff --git a/src/engine/renderer/glsl_source/lightMapping_vp.glsl b/src/engine/renderer/glsl_source/lightMapping_vp.glsl index e884649a6e..49bee16a28 100644 --- a/src/engine/renderer/glsl_source/lightMapping_vp.glsl +++ b/src/engine/renderer/glsl_source/lightMapping_vp.glsl @@ -37,7 +37,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #endif #if !defined(USE_MATERIAL_SYSTEM) - uniform mat4 u_TextureMatrix; + uniform mat3x2 u_TextureMatrix; #endif #if defined(USE_MODEL_SURFACE) @@ -106,7 +106,7 @@ void main() SHADER_PROFILER_SET // transform diffusemap texcoords - var_TexCoords = (u_TextureMatrix * vec4(texCoord, 0.0, 1.0)).st; + var_TexCoords = (u_TextureMatrix * vec3(texCoord, 1.0)).st; // assign color var_Color = color; diff --git a/src/engine/renderer/glsl_source/liquid_vp.glsl b/src/engine/renderer/glsl_source/liquid_vp.glsl index 290e8c86c6..08f3ee2626 100644 --- a/src/engine/renderer/glsl_source/liquid_vp.glsl +++ b/src/engine/renderer/glsl_source/liquid_vp.glsl @@ -29,7 +29,7 @@ IN vec3 attr_Binormal; IN vec3 attr_Normal; #if !defined(USE_MATERIAL_SYSTEM) - uniform mat4 u_TextureMatrix; + uniform mat3x2 u_TextureMatrix; #endif uniform mat4 u_ModelMatrix; @@ -52,7 +52,7 @@ void main() var_Position = (u_ModelMatrix * vec4(attr_Position, 1.0)).xyz; // transform normalmap texcoords - var_TexCoords = (u_TextureMatrix * vec4(attr_TexCoord0, 0.0, 1.0)).st; + var_TexCoords = (u_TextureMatrix * vec3(attr_TexCoord0, 1.0)).st; var_Tangent.xyz = (u_ModelMatrix * vec4(attr_Tangent, 0.0)).xyz; var_Binormal.xyz = (u_ModelMatrix * vec4(attr_Binormal, 0.0)).xyz; diff --git a/src/engine/renderer/glsl_source/reflection_CB_vp.glsl b/src/engine/renderer/glsl_source/reflection_CB_vp.glsl index 8380de171e..b87dc20fe5 100644 --- a/src/engine/renderer/glsl_source/reflection_CB_vp.glsl +++ b/src/engine/renderer/glsl_source/reflection_CB_vp.glsl @@ -27,7 +27,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #insert vertexAnimation_vp #if !defined(USE_MATERIAL_SYSTEM) - uniform mat4 u_TextureMatrix; + uniform mat3x2 u_TextureMatrix; #endif uniform mat4 u_ModelMatrix; @@ -85,6 +85,6 @@ void main() var_Normal.xyz = (u_ModelMatrix * vec4(LB.normal, 0.0)).xyz; // transform normalmap texcoords - var_TexCoords = (u_TextureMatrix * vec4(texCoord, 0.0, 1.0)).st; + var_TexCoords = (u_TextureMatrix * vec3(texCoord, 1.0)).st; } diff --git a/src/engine/renderer/glsl_source/shadowFill_vp.glsl b/src/engine/renderer/glsl_source/shadowFill_vp.glsl index 5becd198ff..3ac13c691e 100644 --- a/src/engine/renderer/glsl_source/shadowFill_vp.glsl +++ b/src/engine/renderer/glsl_source/shadowFill_vp.glsl @@ -28,7 +28,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA uniform uint u_Color; -uniform mat4 u_TextureMatrix; +uniform mat3x2 u_TextureMatrix; uniform mat4 u_ModelMatrix; uniform mat4 u_ModelViewProjectionMatrix; @@ -70,7 +70,7 @@ void main() #endif // transform texcoords - var_TexCoords = (u_TextureMatrix * vec4(texCoord, 0.0, 1.0)).st; + var_TexCoords = (u_TextureMatrix * vec3(texCoord, 1.0)).st; // assign color var_Color = unpackUnorm4x8( u_Color ); diff --git a/src/engine/renderer/glsl_source/skybox_fp.glsl b/src/engine/renderer/glsl_source/skybox_fp.glsl index a89f1a6b89..4a4bd38250 100644 --- a/src/engine/renderer/glsl_source/skybox_fp.glsl +++ b/src/engine/renderer/glsl_source/skybox_fp.glsl @@ -34,7 +34,7 @@ uniform bool u_UseCloudMap; uniform float u_CloudHeight; #if !defined(USE_MATERIAL_SYSTEM) - uniform mat4 u_TextureMatrix; + uniform mat3x2 u_TextureMatrix; #endif uniform float u_AlphaThreshold; @@ -68,7 +68,7 @@ void main() incidentRay.z += radiusWorld; incidentRay = normalize( incidentRay ); vec2 st = vec2( acos(incidentRay.x), acos(incidentRay.y) ); - st = (u_TextureMatrix * vec4(st, 0.0, 1.0)).xy; + st = (u_TextureMatrix * vec3(st, 1.0)).xy; color = texture2D( u_CloudMap, st ).rgba; } From c7cfecb1b499e67a13cf3a88eb89e1fcdd21e6a3 Mon Sep 17 00:00:00 2001 From: VReaperV Date: Wed, 25 Dec 2024 19:34:01 +0300 Subject: [PATCH 03/27] Fix material system dynamic stages --- src/engine/renderer/Material.cpp | 37 +++++++++++++------------------ src/engine/renderer/gl_shader.cpp | 4 ++-- src/engine/renderer/tr_local.h | 5 +++-- src/engine/renderer/tr_shade.cpp | 2 +- 4 files changed, 22 insertions(+), 26 deletions(-) diff --git a/src/engine/renderer/Material.cpp b/src/engine/renderer/Material.cpp index ef4dc220d3..573b2c0151 100644 --- a/src/engine/renderer/Material.cpp +++ b/src/engine/renderer/Material.cpp @@ -142,7 +142,7 @@ void UpdateSurfaceDataNOP( uint32_t*, Material&, shaderStage_t* ) { void UpdateSurfaceDataGeneric3D( uint32_t* materials, Material& material, shaderStage_t* pStage ) { shader_t* shader = pStage->shader; - const uint32_t paddedOffset = ( pStage->materialsSSBOOffset + pStage->currentOffset ) * material.shader->GetPaddedSize(); + const uint32_t paddedOffset = pStage->bufferOffset; materials += paddedOffset; bool updated = !pStage->bufferInitialized || pStage->colorDynamic || pStage->dynamic; @@ -178,7 +178,7 @@ void UpdateSurfaceDataGeneric3D( uint32_t* materials, Material& material, shader void UpdateSurfaceDataLightMapping( uint32_t* materials, Material& material, shaderStage_t* pStage ) { shader_t* shader = pStage->shader; - const uint32_t paddedOffset = ( pStage->materialsSSBOOffset + pStage->currentOffset ) * material.shader->GetPaddedSize(); + const uint32_t paddedOffset = pStage->bufferOffset; materials += paddedOffset; bool updated = !pStage->bufferInitialized || pStage->colorDynamic || pStage->dynamic; @@ -241,7 +241,7 @@ void UpdateSurfaceDataLightMapping( uint32_t* materials, Material& material, sha void UpdateSurfaceDataReflection( uint32_t* materials, Material& material, shaderStage_t* pStage ) { shader_t* shader = pStage->shader; - const uint32_t paddedOffset = ( pStage->materialsSSBOOffset + pStage->currentOffset ) * material.shader->GetPaddedSize(); + const uint32_t paddedOffset = pStage->bufferOffset; materials += paddedOffset; bool updated = !pStage->bufferInitialized || pStage->colorDynamic || pStage->dynamic; @@ -289,7 +289,7 @@ void UpdateSurfaceDataReflection( uint32_t* materials, Material& material, shade void UpdateSurfaceDataSkybox( uint32_t* materials, Material& material, shaderStage_t* pStage ) { shader_t* shader = pStage->shader; - const uint32_t paddedOffset = ( pStage->materialsSSBOOffset + pStage->currentOffset ) * material.shader->GetPaddedSize(); + const uint32_t paddedOffset = pStage->bufferOffset; materials += paddedOffset; bool updated = !pStage->bufferInitialized || pStage->colorDynamic || pStage->dynamic; @@ -309,7 +309,7 @@ void UpdateSurfaceDataSkybox( uint32_t* materials, Material& material, shaderSta void UpdateSurfaceDataScreen( uint32_t* materials, Material& material, shaderStage_t* pStage ) { shader_t* shader = pStage->shader; - const uint32_t paddedOffset = ( pStage->materialsSSBOOffset + pStage->currentOffset ) * material.shader->GetPaddedSize(); + const uint32_t paddedOffset = pStage->bufferOffset; materials += paddedOffset; bool updated = !pStage->bufferInitialized || pStage->colorDynamic || pStage->dynamic; @@ -331,7 +331,7 @@ void UpdateSurfaceDataScreen( uint32_t* materials, Material& material, shaderSta void UpdateSurfaceDataHeatHaze( uint32_t* materials, Material& material, shaderStage_t* pStage ) { shader_t* shader = pStage->shader; - const uint32_t paddedOffset = ( pStage->materialsSSBOOffset + pStage->currentOffset ) * material.shader->GetPaddedSize(); + const uint32_t paddedOffset = pStage->bufferOffset; materials += paddedOffset; bool updated = !pStage->bufferInitialized || pStage->colorDynamic || pStage->dynamic; @@ -357,7 +357,7 @@ void UpdateSurfaceDataHeatHaze( uint32_t* materials, Material& material, shaderS void UpdateSurfaceDataLiquid( uint32_t* materials, Material& material, shaderStage_t* pStage ) { shader_t* shader = pStage->shader; - const uint32_t paddedOffset = ( pStage->materialsSSBOOffset + pStage->currentOffset ) * material.shader->GetPaddedSize(); + const uint32_t paddedOffset = pStage->bufferOffset; materials += paddedOffset; bool updated = !pStage->bufferInitialized || pStage->colorDynamic || pStage->dynamic; @@ -416,7 +416,7 @@ void UpdateSurfaceDataLiquid( uint32_t* materials, Material& material, shaderSta void UpdateSurfaceDataFog( uint32_t* materials, Material& material, shaderStage_t* pStage ) { shader_t* shader = pStage->shader; - const uint32_t paddedOffset = ( pStage->materialsSSBOOffset + pStage->currentOffset ) * material.shader->GetPaddedSize(); + const uint32_t paddedOffset = pStage->bufferOffset; materials += paddedOffset; bool updated = !pStage->bufferInitialized || pStage->dynamic; @@ -477,9 +477,8 @@ void MaterialSystem::GenerateWorldMaterialsBuffer() { } ); uint32_t offset = 0; - uint32_t dynamicOffset = 0; dynamicStagesOffset = 0; - bool dynamicDrawSurfOffsetSet = false; + bool dynamicStagesOffsetSet = false; // Compute data size for stages for ( shaderStage_t* pStage : materialStages ) { @@ -490,22 +489,18 @@ void MaterialSystem::GenerateWorldMaterialsBuffer() { // Make sure padding is taken into account for dynamicStagesOffset if ( pStage->dynamic ) { - if ( !dynamicDrawSurfOffsetSet ) { + if ( !dynamicStagesOffsetSet ) { dynamicStagesOffset = offset; - dynamicDrawSurfOffsetSet = true; + dynamicStagesOffsetSet = true; } - - const uint32_t dynamicPadding = ( dynamicOffset % paddedSize == 0 ) ? 0 : paddedSize - ( dynamicOffset % paddedSize ); - dynamicOffset += dynamicPadding; - pStage->dynamicMaterialsOffset = dynamicOffset / paddedSize; - dynamicOffset += paddedSize * pStage->variantOffset; } - pStage->materialsSSBOOffset = offset / paddedSize; + pStage->materialOffset = offset / paddedSize; + pStage->bufferOffset = offset; offset += paddedSize * pStage->variantOffset; } - dynamicStagesSize = dynamicDrawSurfOffsetSet ? offset - dynamicStagesOffset : 0; + dynamicStagesSize = dynamicStagesOffsetSet ? offset - dynamicStagesOffset : 0; totalStageSize = offset; // 4 bytes per component @@ -527,7 +522,7 @@ void MaterialSystem::GenerateWorldMaterialsBuffer() { // We need some of the values from the remapped stage, but material/materialPack ID has to come from pStage shaderStage_t* remappedStage = pStage->materialRemappedStage ? pStage->materialRemappedStage : pStage; const uint32_t SSBOOffset = - remappedStage->materialsSSBOOffset + remappedStage->variantOffsets[drawSurf->shaderVariant[stage]]; + remappedStage->materialOffset + remappedStage->variantOffsets[drawSurf->shaderVariant[stage]]; tess.currentDrawSurf = drawSurf; @@ -550,7 +545,7 @@ void MaterialSystem::GenerateWorldMaterialsBuffer() { for ( shaderStage_t* pStage : materialStages ) { if ( pStage->dynamic ) { - pStage->materialsSSBOOffset = pStage->dynamicMaterialsOffset; + pStage->bufferOffset -= dynamicStagesOffset; } } diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index 1d0e9b6954..8dd02dc66c 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -1359,7 +1359,7 @@ std::string GLShaderManager::ShaderPostProcess( GLShader *shader, const std::str std::string newShaderText; std::string materialStruct = "\nstruct Material {\n"; - std::string materialBlock = "layout(std430, binding = 0) readonly buffer materialsSSBO {\n" + std::string materialBlock = "layout(std430, binding = 0) restrict readonly buffer materialsSSBO {\n" " Material materials[];\n" "};\n\n"; std::string texDataBlock = "struct TexData {\n" @@ -1370,7 +1370,7 @@ std::string GLShaderManager::ShaderPostProcess( GLShader *shader, const std::str " uvec2 u_MaterialMap;\n" " uvec2 u_GlowMap;\n" "};\n\n" - "layout(std430, binding = 6) readonly buffer texDataSSBO {\n" + "layout(std430, binding = 6) restrict readonly buffer texDataSSBO {\n" " TexData texData[];\n" "};\n\n" "#define u_TextureMatrix texData[( baseInstance >> 12 ) & 0xFFF].u_TextureMatrix\n" diff --git a/src/engine/renderer/tr_local.h b/src/engine/renderer/tr_local.h index 1289710ea3..a2688c6d97 100644 --- a/src/engine/renderer/tr_local.h +++ b/src/engine/renderer/tr_local.h @@ -1212,8 +1212,9 @@ enum class shaderProfilerRenderSubGroupsMode { shader_t* shader; shaderStage_t* materialRemappedStage = nullptr; - uint32_t materialsSSBOOffset = 0; - uint32_t dynamicMaterialsOffset = 0; + uint32_t materialOffset = 0; + uint32_t bufferOffset = 0; + uint32_t dynamicBufferOffset = 0; bool initialized = false; bool bufferInitialized = false; diff --git a/src/engine/renderer/tr_shade.cpp b/src/engine/renderer/tr_shade.cpp index ee8297ad59..ebc618b1d6 100644 --- a/src/engine/renderer/tr_shade.cpp +++ b/src/engine/renderer/tr_shade.cpp @@ -2698,7 +2698,7 @@ void Tess_StageIteratorColor() Tess_ComputeTexMatrices( pStage ); if ( materialSystem.generatingWorldCommandBuffer && pStage->useMaterialSystem ) { - tess.currentSSBOOffset = pStage->materialsSSBOOffset; + tess.currentSSBOOffset = pStage->materialOffset; tess.materialID = pStage->materialID; tess.materialPackID = pStage->materialPackID; } From 7a4d524854cb08d33731aab6b3ce8f31d4bc7e71 Mon Sep 17 00:00:00 2001 From: VReaperV Date: Wed, 25 Dec 2024 21:31:17 +0300 Subject: [PATCH 04/27] Use UBOs for texData when possible --- src/engine/renderer/Material.cpp | 30 ++++++++++++++++----------- src/engine/renderer/Material.h | 13 ++++++++++-- src/engine/renderer/gl_shader.cpp | 34 +++++++++++++++++-------------- src/engine/renderer/tr_public.h | 1 + src/engine/sys/sdl_glimp.cpp | 1 + 5 files changed, 50 insertions(+), 29 deletions(-) diff --git a/src/engine/renderer/Material.cpp b/src/engine/renderer/Material.cpp index 573b2c0151..265694f872 100644 --- a/src/engine/renderer/Material.cpp +++ b/src/engine/renderer/Material.cpp @@ -38,7 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "ShadeCommon.h" GLSSBO materialsSSBO( "materials", 0, GL_MAP_WRITE_BIT, GL_MAP_INVALIDATE_RANGE_BIT ); -GLSSBO texDataSSBO( "texData", 6, GL_MAP_WRITE_BIT, GL_MAP_FLUSH_EXPLICIT_BIT ); +GLBuffer texDataSSBO( "texData", 6, GL_MAP_WRITE_BIT, GL_MAP_FLUSH_EXPLICIT_BIT ); GLUBO lightmapDataUBO( "texData", 7, GL_MAP_WRITE_BIT, GL_MAP_FLUSH_EXPLICIT_BIT ); GLSSBO surfaceDescriptorsSSBO( "surfaceDescriptors", 1, GL_MAP_WRITE_BIT, GL_MAP_INVALIDATE_RANGE_BIT ); @@ -600,8 +600,9 @@ void MaterialSystem::GenerateTexturesBuffer( std::vector& textures, textureBundles->textureMatrix[1] = tess.svars.texMatrices[TB_COLORMAP][1]; textureBundles->textureMatrix[2] = tess.svars.texMatrices[TB_COLORMAP][4]; textureBundles->textureMatrix[3] = tess.svars.texMatrices[TB_COLORMAP][5]; - textureBundles->textureMatrix[4] = tess.svars.texMatrices[TB_COLORMAP][12]; - textureBundles->textureMatrix[5] = tess.svars.texMatrices[TB_COLORMAP][13]; + // These are stored as part of a vec4 in a UBO, so we need to convert them here as well + textureBundles->textureMatrix2[0] = tess.svars.texMatrices[TB_COLORMAP][12] * 32768.0f; + textureBundles->textureMatrix2[1] = tess.svars.texMatrices[TB_COLORMAP][13] * 32768.0f; textureBundles++; } } @@ -642,9 +643,11 @@ void MaterialSystem::GenerateWorldCommandBuffer() { nullptr, GL_STATIC_DRAW ); uint32_t* surfaceDescriptors = surfaceDescriptorsSSBO.MapBufferRange( surfaceDescriptorsCount * descriptorSize ); - texDataSSBO.BindBuffer(); - texDataSSBO.BufferStorage( ( texData.size() + dynamicTexData.size() ) * TEX_BUNDLE_SIZE, 1, nullptr ); - texDataSSBO.MapAll(); + texDataBufferType = glConfig2.maxUniformBlockSize >= MIN_MATERIAL_UBO_SIZE ? GL_UNIFORM_BUFFER : GL_SHADER_STORAGE_BUFFER; + + texDataSSBO.BindBuffer( texDataBufferType ); + texDataSSBO.BufferStorage( texDataBufferType, ( texData.size() + dynamicTexData.size() ) * TEX_BUNDLE_SIZE, 1, nullptr ); + texDataSSBO.MapAll( texDataBufferType ); TexBundle* textureBundles = ( TexBundle* ) texDataSSBO.GetData(); memset( textureBundles, 0, ( texData.size() + dynamicTexData.size() ) * TEX_BUNDLE_SIZE * sizeof( uint32_t ) ); @@ -657,9 +660,9 @@ void MaterialSystem::GenerateWorldCommandBuffer() { dynamicTexDataOffset = texData.size() * TEX_BUNDLE_SIZE; dynamicTexDataSize = dynamicTexData.size() * TEX_BUNDLE_SIZE; - texDataSSBO.FlushAll(); + texDataSSBO.FlushAll( texDataBufferType ); texDataSSBO.UnmapBuffer(); - texDataSSBO.UnBindBuffer(); + texDataSSBO.UnBindBuffer( texDataBufferType ); lightmapDataUBO.BindBuffer(); lightmapDataUBO.BufferStorage( MAX_LIGHTMAPS * LIGHTMAP_SIZE, 1, nullptr ); @@ -1687,8 +1690,11 @@ void MaterialSystem::UpdateDynamicSurfaces() { } if ( dynamicTexDataSize > 0 ) { - texDataSSBO.BindBuffer(); - TexBundle* textureBundles = ( TexBundle* ) texDataSSBO.MapBufferRange( dynamicTexDataOffset, dynamicTexDataSize ); + texDataSSBO.BindBuffer( texDataBufferType ); + GL_CheckErrors(); + TexBundle* textureBundles = + ( TexBundle* ) texDataSSBO.MapBufferRange( texDataBufferType, dynamicTexDataOffset, dynamicTexDataSize ); + GL_CheckErrors(); GenerateTexturesBuffer( dynamicTexData, textureBundles ); @@ -2268,7 +2274,7 @@ void MaterialSystem::RenderMaterial( Material& material, const uint32_t viewID ) atomicCommandCountersBuffer.BindBuffer( GL_PARAMETER_BUFFER_ARB ); - texDataSSBO.BindBufferBase(); + texDataSSBO.BindBufferBase( texDataBufferType ); lightmapDataUBO.BindBufferBase(); if ( r_showGlobalMaterials.Get() && material.sort != 0 @@ -2385,7 +2391,7 @@ void MaterialSystem::RenderMaterial( Material& material, const uint32_t viewID ) atomicCommandCountersBuffer.UnBindBuffer( GL_PARAMETER_BUFFER_ARB ); - texDataSSBO.UnBindBufferBase(); + texDataSSBO.UnBindBufferBase( texDataBufferType ); lightmapDataUBO.UnBindBufferBase(); if ( material.usePolygonOffset ) { diff --git a/src/engine/renderer/Material.h b/src/engine/renderer/Material.h index 05fa55aa02..9cba489951 100644 --- a/src/engine/renderer/Material.h +++ b/src/engine/renderer/Material.h @@ -136,7 +136,8 @@ struct Material { }; struct TexBundle { - vec_t textureMatrix[6]; + vec_t textureMatrix[4]; + uint32_t textureMatrix2[2]; GLuint64 textures[MAX_TEXTURE_BUNDLES]; }; @@ -236,6 +237,13 @@ extern PortalView portalStack[MAX_VIEWS]; #define LIGHTMAP_BITS 24 #define PORTAL_SURFACE_SIZE 8 +// 64kb min +#define MIN_MATERIAL_UBO_SIZE BIT( 16 ) + +/* 64kb UBO : 54kb texBundles, 4kb lightmaps, 2kb map shader stages, 4kb entity shader stages +Current mapss use up to ~38kb at max, without models */ +#define MAX_TEX_BUNDLES 54 * 1024 / 64 + #define MAX_FRAMES 2 #define MAX_VIEWFRAMES MAX_VIEWS * MAX_FRAMES // Buffer 2 frames for each view @@ -371,6 +379,7 @@ class MaterialSystem { std::vector materialStages; std::vector dynamicStages; + GLenum texDataBufferType; std::vector texData; std::vector dynamicTexData; @@ -392,7 +401,7 @@ class MaterialSystem { }; extern GLSSBO materialsSSBO; // Global -extern GLSSBO texDataSSBO; // Global +extern GLBuffer texDataSSBO; // Global extern GLUBO lightmapDataUBO; // Global extern GLSSBO surfaceDescriptorsSSBO; // Global diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index 8dd02dc66c..63e635564b 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -1362,23 +1362,27 @@ std::string GLShaderManager::ShaderPostProcess( GLShader *shader, const std::str std::string materialBlock = "layout(std430, binding = 0) restrict readonly buffer materialsSSBO {\n" " Material materials[];\n" "};\n\n"; + std::string texBuf = glConfig2.maxUniformBlockSize >= MIN_MATERIAL_UBO_SIZE ? + "layout(std140, binding = 6) uniform texDataUBO {\n" + " TexData texData[" + std::to_string( MAX_TEX_BUNDLES ) + "]; \n" + "};\n\n" + : "layout(std430, binding = 6) restrict readonly buffer texDataSSBO {\n" + " TexData texData[];\n" + "};\n\n"; + // We have to store these as a bunch of vec4/uvec4 because std140 pads everything to a vec4 std::string texDataBlock = "struct TexData {\n" - " mat3x2 u_TextureMatrix;\n" - " uvec2 u_DiffuseMap;\n" - " uvec2 u_NormalMap;\n" - " uvec2 u_HeightMap;\n" - " uvec2 u_MaterialMap;\n" - " uvec2 u_GlowMap;\n" + " vec4 u_TextureMatrix;\n" + " uvec4 u_TextureDiffuseMap;\n" + " uvec4 u_NormalHeightMap;\n" + " uvec4 u_MaterialGlowMap;\n" "};\n\n" - "layout(std430, binding = 6) restrict readonly buffer texDataSSBO {\n" - " TexData texData[];\n" - "};\n\n" - "#define u_TextureMatrix texData[( baseInstance >> 12 ) & 0xFFF].u_TextureMatrix\n" - "#define u_DiffuseMap_initial uvec2( texData[( baseInstance >> 12 ) & 0xFFF].u_DiffuseMap )\n" - "#define u_NormalMap_initial uvec2( texData[( baseInstance >> 12 ) & 0xFFF].u_NormalMap )\n" - "#define u_HeightMap_initial uvec2( texData[( baseInstance >> 12 ) & 0xFFF].u_HeightMap )\n" - "#define u_MaterialMap_initial uvec2( texData[( baseInstance >> 12 ) & 0xFFF].u_MaterialMap )\n" - "#define u_GlowMap_initial uvec2( texData[( baseInstance >> 12 ) & 0xFFF].u_GlowMap )\n\n" + + texBuf + + "#define u_TextureMatrix mat3x2( texData[( baseInstance >> 12 ) & 0xFFF].u_TextureMatrix, vec2( texData[( baseInstance >> 12 ) & 0xFFF].u_TextureDiffuseMap.xy ) * vec2( 1.0f / 32768.0f ) )\n" + "#define u_DiffuseMap_initial uvec2( texData[( baseInstance >> 12 ) & 0xFFF].u_TextureDiffuseMap.zw )\n" + "#define u_NormalMap_initial uvec2( texData[( baseInstance >> 12 ) & 0xFFF].u_NormalHeightMap.xy )\n" + "#define u_HeightMap_initial uvec2( texData[( baseInstance >> 12 ) & 0xFFF].u_NormalHeightMap.zw )\n" + "#define u_MaterialMap_initial uvec2( texData[( baseInstance >> 12 ) & 0xFFF].u_MaterialGlowMap.xy )\n" + "#define u_GlowMap_initial uvec2( texData[( baseInstance >> 12 ) & 0xFFF].u_MaterialGlowMap.zw )\n\n" "struct LightMapData {\n" " uvec2 u_LightMap;\n" " uvec2 u_DeluxeMap;\n" diff --git a/src/engine/renderer/tr_public.h b/src/engine/renderer/tr_public.h index 038c069489..b5b320a3d9 100644 --- a/src/engine/renderer/tr_public.h +++ b/src/engine/renderer/tr_public.h @@ -77,6 +77,7 @@ struct glconfig2_t char shadingLanguageVersionString[ MAX_STRING_CHARS ]; int shadingLanguageVersion; + int maxUniformBlockSize; int maxVertexUniforms; // int maxVaryingFloats; int maxVertexAttribs; diff --git a/src/engine/sys/sdl_glimp.cpp b/src/engine/sys/sdl_glimp.cpp index 36519fccd3..a6cf29903a 100644 --- a/src/engine/sys/sdl_glimp.cpp +++ b/src/engine/sys/sdl_glimp.cpp @@ -2013,6 +2013,7 @@ static void GLimp_InitExtensions() } // Shader limits + glGetIntegerv( GL_MAX_UNIFORM_BLOCK_SIZE, &glConfig2.maxUniformBlockSize ); glGetIntegerv( GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB, &glConfig2.maxVertexUniforms ); glGetIntegerv( GL_MAX_VERTEX_ATTRIBS_ARB, &glConfig2.maxVertexAttribs ); From d3a123f6efce650be7771770686a2f456bdf1bb5 Mon Sep 17 00:00:00 2001 From: VReaperV Date: Thu, 26 Dec 2024 01:13:17 +0300 Subject: [PATCH 05/27] Comment out some unused args --- src/engine/renderer/Material.cpp | 20 ++++++++++---------- src/engine/renderer/Material.h | 8 ++++---- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/engine/renderer/Material.cpp b/src/engine/renderer/Material.cpp index 265694f872..6dd1a4542f 100644 --- a/src/engine/renderer/Material.cpp +++ b/src/engine/renderer/Material.cpp @@ -140,7 +140,7 @@ void UpdateSurfaceDataNOP( uint32_t*, Material&, shaderStage_t* ) { } void UpdateSurfaceDataGeneric3D( uint32_t* materials, Material& material, shaderStage_t* pStage ) { - shader_t* shader = pStage->shader; + // shader_t* shader = pStage->shader; const uint32_t paddedOffset = pStage->bufferOffset; materials += paddedOffset; @@ -238,7 +238,7 @@ void UpdateSurfaceDataLightMapping( uint32_t* materials, Material& material, sha gl_lightMappingShaderMaterial->WriteUniformsToBuffer( materials ); } -void UpdateSurfaceDataReflection( uint32_t* materials, Material& material, shaderStage_t* pStage ) { +void UpdateSurfaceDataReflection( uint32_t* materials, Material& /* material */, shaderStage_t* pStage) { shader_t* shader = pStage->shader; const uint32_t paddedOffset = pStage->bufferOffset; @@ -287,7 +287,7 @@ void UpdateSurfaceDataReflection( uint32_t* materials, Material& material, shade } void UpdateSurfaceDataSkybox( uint32_t* materials, Material& material, shaderStage_t* pStage ) { - shader_t* shader = pStage->shader; + // shader_t* shader = pStage->shader; const uint32_t paddedOffset = pStage->bufferOffset; materials += paddedOffset; @@ -306,8 +306,8 @@ void UpdateSurfaceDataSkybox( uint32_t* materials, Material& material, shaderSta gl_skyboxShaderMaterial->WriteUniformsToBuffer( materials ); } -void UpdateSurfaceDataScreen( uint32_t* materials, Material& material, shaderStage_t* pStage ) { - shader_t* shader = pStage->shader; +void UpdateSurfaceDataScreen( uint32_t* materials, Material& /* material */, shaderStage_t* pStage) { + // shader_t* shader = pStage->shader; const uint32_t paddedOffset = pStage->bufferOffset; materials += paddedOffset; @@ -328,8 +328,8 @@ void UpdateSurfaceDataScreen( uint32_t* materials, Material& material, shaderSta gl_screenShaderMaterial->WriteUniformsToBuffer( materials ); } -void UpdateSurfaceDataHeatHaze( uint32_t* materials, Material& material, shaderStage_t* pStage ) { - shader_t* shader = pStage->shader; +void UpdateSurfaceDataHeatHaze( uint32_t* materials, Material& /* material */, shaderStage_t* pStage) { + // shader_t* shader = pStage->shader; const uint32_t paddedOffset = pStage->bufferOffset; materials += paddedOffset; @@ -354,8 +354,8 @@ void UpdateSurfaceDataHeatHaze( uint32_t* materials, Material& material, shaderS gl_heatHazeShaderMaterial->WriteUniformsToBuffer( materials ); } -void UpdateSurfaceDataLiquid( uint32_t* materials, Material& material, shaderStage_t* pStage ) { - shader_t* shader = pStage->shader; +void UpdateSurfaceDataLiquid( uint32_t* materials, Material& /* material */, shaderStage_t* pStage) { + // shader_t* shader = pStage->shader; const uint32_t paddedOffset = pStage->bufferOffset; materials += paddedOffset; @@ -414,7 +414,7 @@ void UpdateSurfaceDataLiquid( uint32_t* materials, Material& material, shaderSta } void UpdateSurfaceDataFog( uint32_t* materials, Material& material, shaderStage_t* pStage ) { - shader_t* shader = pStage->shader; + // shader_t* shader = pStage->shader; const uint32_t paddedOffset = pStage->bufferOffset; materials += paddedOffset; diff --git a/src/engine/renderer/Material.h b/src/engine/renderer/Material.h index 9cba489951..fe682bc41c 100644 --- a/src/engine/renderer/Material.h +++ b/src/engine/renderer/Material.h @@ -419,11 +419,11 @@ void UpdateSurfaceDataNONE( uint32_t*, Material&, shaderStage_t* ); void UpdateSurfaceDataNOP( uint32_t*, Material&, shaderStage_t* ); void UpdateSurfaceDataGeneric3D( uint32_t* materials, Material& material, shaderStage_t* pStage ); void UpdateSurfaceDataLightMapping( uint32_t* materials, Material& material, shaderStage_t* pStage ); -void UpdateSurfaceDataReflection( uint32_t* materials, Material& material, shaderStage_t* pStage ); +void UpdateSurfaceDataReflection( uint32_t* materials, Material& /* material */, shaderStage_t* pStage); void UpdateSurfaceDataSkybox( uint32_t* materials, Material& material, shaderStage_t* pStage ); -void UpdateSurfaceDataScreen( uint32_t* materials, Material& material, shaderStage_t* pStage ); -void UpdateSurfaceDataHeatHaze( uint32_t* materials, Material& material, shaderStage_t* pStage ); -void UpdateSurfaceDataLiquid( uint32_t* materials, Material& material, shaderStage_t* pStage ); +void UpdateSurfaceDataScreen( uint32_t* materials, Material& /* material */, shaderStage_t* pStage); +void UpdateSurfaceDataHeatHaze( uint32_t* materials, Material& /* material */, shaderStage_t* pStage); +void UpdateSurfaceDataLiquid( uint32_t* materials, Material& /* material */, shaderStage_t* pStage); void UpdateSurfaceDataFog( uint32_t* materials, Material& material, shaderStage_t* pStage ); // void UpdateSurf( uint32) From c6cecec9a25b96451d05e3525ed6711da719a529 Mon Sep 17 00:00:00 2001 From: VReaperV Date: Thu, 26 Dec 2024 11:04:08 +0300 Subject: [PATCH 06/27] Fix stage variants upload Also removed some now useless code. --- src/engine/renderer/Material.cpp | 57 +++++--------------------------- src/engine/renderer/tr_local.h | 1 - 2 files changed, 9 insertions(+), 49 deletions(-) diff --git a/src/engine/renderer/Material.cpp b/src/engine/renderer/Material.cpp index 6dd1a4542f..c5bfbaf282 100644 --- a/src/engine/renderer/Material.cpp +++ b/src/engine/renderer/Material.cpp @@ -145,12 +145,6 @@ void UpdateSurfaceDataGeneric3D( uint32_t* materials, Material& material, shader const uint32_t paddedOffset = pStage->bufferOffset; materials += paddedOffset; - bool updated = !pStage->bufferInitialized || pStage->colorDynamic || pStage->dynamic; - if ( !updated ) { - return; - } - pStage->bufferInitialized = true; - gl_genericShaderMaterial->BindProgram( material.deformIndex ); // u_AlphaThreshold @@ -181,12 +175,6 @@ void UpdateSurfaceDataLightMapping( uint32_t* materials, Material& material, sha const uint32_t paddedOffset = pStage->bufferOffset; materials += paddedOffset; - bool updated = !pStage->bufferInitialized || pStage->colorDynamic || pStage->dynamic; - if ( !updated ) { - return; - } - pStage->bufferInitialized = true; - gl_lightMappingShaderMaterial->BindProgram( material.deformIndex ); gl_lightMappingShaderMaterial->SetUniform_ModelMatrix( backEnd.orientation.transformMatrix ); @@ -244,12 +232,6 @@ void UpdateSurfaceDataReflection( uint32_t* materials, Material& /* material */, const uint32_t paddedOffset = pStage->bufferOffset; materials += paddedOffset; - bool updated = !pStage->bufferInitialized || pStage->colorDynamic || pStage->dynamic; - if ( !updated ) { - return; - } - pStage->bufferInitialized = true; - // bind u_ColorMap vec3_t position; if ( backEnd.currentEntity && ( backEnd.currentEntity != &tr.worldEntity ) ) { @@ -292,12 +274,6 @@ void UpdateSurfaceDataSkybox( uint32_t* materials, Material& material, shaderSta const uint32_t paddedOffset = pStage->bufferOffset; materials += paddedOffset; - bool updated = !pStage->bufferInitialized || pStage->colorDynamic || pStage->dynamic; - if ( !updated ) { - return; - } - pStage->bufferInitialized = true; - gl_skyboxShaderMaterial->BindProgram( material.deformIndex ); // u_AlphaThreshold @@ -312,12 +288,6 @@ void UpdateSurfaceDataScreen( uint32_t* materials, Material& /* material */, sha const uint32_t paddedOffset = pStage->bufferOffset; materials += paddedOffset; - bool updated = !pStage->bufferInitialized || pStage->colorDynamic || pStage->dynamic; - if ( !updated ) { - return; - } - pStage->bufferInitialized = true; - gl_screenShaderMaterial->BindProgram( pStage->deformIndex ); // bind u_CurrentMap @@ -334,12 +304,6 @@ void UpdateSurfaceDataHeatHaze( uint32_t* materials, Material& /* material */, s const uint32_t paddedOffset = pStage->bufferOffset; materials += paddedOffset; - bool updated = !pStage->bufferInitialized || pStage->colorDynamic || pStage->dynamic; - if ( !updated ) { - return; - } - pStage->bufferInitialized = true; - float deformMagnitude = RB_EvalExpression( &pStage->deformMagnitudeExp, 1.0 ); gl_heatHazeShaderMaterial->SetUniform_DeformMagnitude( deformMagnitude ); @@ -360,12 +324,6 @@ void UpdateSurfaceDataLiquid( uint32_t* materials, Material& /* material */, sha const uint32_t paddedOffset = pStage->bufferOffset; materials += paddedOffset; - bool updated = !pStage->bufferInitialized || pStage->colorDynamic || pStage->dynamic; - if ( !updated ) { - return; - } - pStage->bufferInitialized = true; - float fogDensity = RB_EvalExpression( &pStage->fogDensityExp, 0.001 ); vec4_t fogColor; Tess_ComputeColor( pStage ); @@ -419,12 +377,6 @@ void UpdateSurfaceDataFog( uint32_t* materials, Material& material, shaderStage_ const uint32_t paddedOffset = pStage->bufferOffset; materials += paddedOffset; - bool updated = !pStage->bufferInitialized || pStage->dynamic; - if ( !updated ) { - return; - } - pStage->bufferInitialized = true; - const fog_t* fog = material.fog; // u_Color @@ -567,7 +519,11 @@ void MaterialSystem::GenerateMaterialsBuffer( std::vector& stage pStage->vertexLit = i & Util::ordinal( ShaderStageVariant::VERTEX_LIT ); pStage->fullbright = i & Util::ordinal( ShaderStageVariant::FULLBRIGHT ); pStage->currentOffset = pStage->variantOffsets[i]; + + const uint32_t variantOffset = pStage->variantOffsets[i] * material.shader->GetPaddedSize(); + pStage->bufferOffset += variantOffset; pStage->surfaceDataUpdater( materialsData, material, pStage ); + pStage->bufferOffset -= variantOffset; variants++; } } @@ -1399,6 +1355,11 @@ void MaterialSystem::AddStage( drawSurf_t* drawSurf, shaderStage_t* pStage, uint pStage->materialRemappedStage = pStage2; + if ( pStage2->variantOffsets[variant] == -1 ) { + pStage2->variantOffsets[variant] = pStage2->variantOffset; + pStage2->variantOffset++; + } + return; } diff --git a/src/engine/renderer/tr_local.h b/src/engine/renderer/tr_local.h index a2688c6d97..9a3f32a756 100644 --- a/src/engine/renderer/tr_local.h +++ b/src/engine/renderer/tr_local.h @@ -1217,7 +1217,6 @@ enum class shaderProfilerRenderSubGroupsMode { uint32_t dynamicBufferOffset = 0; bool initialized = false; - bool bufferInitialized = false; uint materialPackID = 0; uint materialID = 0; From 21c0079289ecc59a175f472eb44526c5d4331229 Mon Sep 17 00:00:00 2001 From: VReaperV Date: Thu, 2 Jan 2025 14:25:37 +0300 Subject: [PATCH 07/27] Fix drawSurf-specific data with material system --- src/engine/renderer/Material.cpp | 83 ++++++++----------- src/engine/renderer/Material.h | 20 ++--- src/engine/renderer/gl_shader.cpp | 4 +- src/engine/renderer/gl_shader.h | 16 +++- .../renderer/glsl_source/fogQuake3_vp.glsl | 6 +- src/engine/renderer/tr_local.h | 11 ++- src/engine/renderer/tr_shade.cpp | 6 +- 7 files changed, 74 insertions(+), 72 deletions(-) diff --git a/src/engine/renderer/Material.cpp b/src/engine/renderer/Material.cpp index c5bfbaf282..cb291bf141 100644 --- a/src/engine/renderer/Material.cpp +++ b/src/engine/renderer/Material.cpp @@ -132,21 +132,19 @@ static void ComputeDynamics( shaderStage_t* pStage ) { // UpdateSurface*() functions will actually write the uniform values to the SSBO // Mirrors parts of the Render_*() functions in tr_shade.cpp -void UpdateSurfaceDataNONE( uint32_t*, Material&, shaderStage_t* ) { +void UpdateSurfaceDataNONE( uint32_t*, shaderStage_t* ) { ASSERT_UNREACHABLE(); } -void UpdateSurfaceDataNOP( uint32_t*, Material&, shaderStage_t* ) { +void UpdateSurfaceDataNOP( uint32_t*, shaderStage_t* ) { } -void UpdateSurfaceDataGeneric3D( uint32_t* materials, Material& material, shaderStage_t* pStage ) { +void UpdateSurfaceDataGeneric3D( uint32_t* materials, shaderStage_t* pStage ) { // shader_t* shader = pStage->shader; const uint32_t paddedOffset = pStage->bufferOffset; materials += paddedOffset; - gl_genericShaderMaterial->BindProgram( material.deformIndex ); - // u_AlphaThreshold gl_genericShaderMaterial->SetUniform_AlphaTest( pStage->stateBits ); @@ -154,7 +152,7 @@ void UpdateSurfaceDataGeneric3D( uint32_t* materials, Material& material, shader colorGen_t rgbGen = SetRgbGen( pStage ); alphaGen_t alphaGen = SetAlphaGen( pStage ); - bool mayUseVertexOverbright = pStage->type == stageType_t::ST_COLORMAP && drawSurf->bspSurface; + bool mayUseVertexOverbright = pStage->mayUseVertexOverbright; const bool styleLightMap = pStage->type == stageType_t::ST_STYLELIGHTMAP || pStage->type == stageType_t::ST_STYLECOLORMAP; gl_genericShaderMaterial->SetUniform_ColorModulateColorGen( rgbGen, alphaGen, mayUseVertexOverbright, styleLightMap ); @@ -169,16 +167,12 @@ void UpdateSurfaceDataGeneric3D( uint32_t* materials, Material& material, shader gl_genericShaderMaterial->WriteUniformsToBuffer( materials ); } -void UpdateSurfaceDataLightMapping( uint32_t* materials, Material& material, shaderStage_t* pStage ) { +void UpdateSurfaceDataLightMapping( uint32_t* materials, shaderStage_t* pStage ) { shader_t* shader = pStage->shader; const uint32_t paddedOffset = pStage->bufferOffset; materials += paddedOffset; - gl_lightMappingShaderMaterial->BindProgram( material.deformIndex ); - - gl_lightMappingShaderMaterial->SetUniform_ModelMatrix( backEnd.orientation.transformMatrix ); - // u_ColorModulate colorGen_t rgbGen = SetRgbGen( pStage ); alphaGen_t alphaGen = SetAlphaGen( pStage ); @@ -226,7 +220,7 @@ void UpdateSurfaceDataLightMapping( uint32_t* materials, Material& material, sha gl_lightMappingShaderMaterial->WriteUniformsToBuffer( materials ); } -void UpdateSurfaceDataReflection( uint32_t* materials, Material& /* material */, shaderStage_t* pStage) { +void UpdateSurfaceDataReflection( uint32_t* materials, shaderStage_t* pStage) { shader_t* shader = pStage->shader; const uint32_t paddedOffset = pStage->bufferOffset; @@ -268,28 +262,24 @@ void UpdateSurfaceDataReflection( uint32_t* materials, Material& /* material */, gl_reflectionShaderMaterial->WriteUniformsToBuffer( materials ); } -void UpdateSurfaceDataSkybox( uint32_t* materials, Material& material, shaderStage_t* pStage ) { +void UpdateSurfaceDataSkybox( uint32_t* materials, shaderStage_t* pStage ) { // shader_t* shader = pStage->shader; const uint32_t paddedOffset = pStage->bufferOffset; materials += paddedOffset; - gl_skyboxShaderMaterial->BindProgram( material.deformIndex ); - // u_AlphaThreshold gl_skyboxShaderMaterial->SetUniform_AlphaTest( GLS_ATEST_NONE ); gl_skyboxShaderMaterial->WriteUniformsToBuffer( materials ); } -void UpdateSurfaceDataScreen( uint32_t* materials, Material& /* material */, shaderStage_t* pStage) { +void UpdateSurfaceDataScreen( uint32_t* materials, shaderStage_t* pStage) { // shader_t* shader = pStage->shader; const uint32_t paddedOffset = pStage->bufferOffset; materials += paddedOffset; - gl_screenShaderMaterial->BindProgram( pStage->deformIndex ); - // bind u_CurrentMap /* FIXME: This is currently unused, but u_CurrentMap was made global for other shaders, this seems to be the only material system shader that might need it to not be global */ @@ -298,7 +288,7 @@ void UpdateSurfaceDataScreen( uint32_t* materials, Material& /* material */, sha gl_screenShaderMaterial->WriteUniformsToBuffer( materials ); } -void UpdateSurfaceDataHeatHaze( uint32_t* materials, Material& /* material */, shaderStage_t* pStage) { +void UpdateSurfaceDataHeatHaze( uint32_t* materials, shaderStage_t* pStage) { // shader_t* shader = pStage->shader; const uint32_t paddedOffset = pStage->bufferOffset; @@ -318,7 +308,7 @@ void UpdateSurfaceDataHeatHaze( uint32_t* materials, Material& /* material */, s gl_heatHazeShaderMaterial->WriteUniformsToBuffer( materials ); } -void UpdateSurfaceDataLiquid( uint32_t* materials, Material& /* material */, shaderStage_t* pStage) { +void UpdateSurfaceDataLiquid( uint32_t* materials, shaderStage_t* pStage) { // shader_t* shader = pStage->shader; const uint32_t paddedOffset = pStage->bufferOffset; @@ -371,17 +361,12 @@ void UpdateSurfaceDataLiquid( uint32_t* materials, Material& /* material */, sha gl_liquidShaderMaterial->WriteUniformsToBuffer( materials ); } -void UpdateSurfaceDataFog( uint32_t* materials, Material& material, shaderStage_t* pStage ) { +void UpdateSurfaceDataFog( uint32_t* materials, shaderStage_t* pStage ) { // shader_t* shader = pStage->shader; const uint32_t paddedOffset = pStage->bufferOffset; materials += paddedOffset; - const fog_t* fog = material.fog; - - // u_Color - gl_fogQuake3ShaderMaterial->SetUniform_Color( fog->color ); - gl_fogQuake3ShaderMaterial->WriteUniformsToBuffer( materials ); } @@ -424,8 +409,7 @@ void MaterialSystem::GenerateWorldMaterialsBuffer() { return false; } - return materialPacks[lhs->materialPackID].materials[lhs->materialID].shader->GetPaddedSize() - < materialPacks[rhs->materialPackID].materials[rhs->materialID].shader->GetPaddedSize(); + return lhs->paddedSize < rhs->paddedSize; } ); uint32_t offset = 0; @@ -434,8 +418,8 @@ void MaterialSystem::GenerateWorldMaterialsBuffer() { // Compute data size for stages for ( shaderStage_t* pStage : materialStages ) { - const uint32_t paddedSize = materialPacks[pStage->materialPackID].materials[pStage->materialID].shader->GetPaddedSize(); - const uint32_t padding = ( offset % paddedSize == 0 ) ? 0 : paddedSize - ( offset % paddedSize ); + const uint32_t paddedSize = pStage->paddedSize; + const uint32_t padding = !paddedSize || offset % paddedSize == 0 ? 0 : paddedSize - ( offset % paddedSize ); offset += padding; @@ -447,7 +431,7 @@ void MaterialSystem::GenerateWorldMaterialsBuffer() { } } - pStage->materialOffset = offset / paddedSize; + pStage->materialOffset = paddedSize ? offset / paddedSize : 0; pStage->bufferOffset = offset; offset += paddedSize * pStage->variantOffset; } @@ -466,7 +450,7 @@ void MaterialSystem::GenerateWorldMaterialsBuffer() { for ( drawSurf_t* drawSurf : material.drawSurfs ) { uint32_t stage = 0; for ( shaderStage_t* pStage = drawSurf->shader->stages; pStage < drawSurf->shader->lastStage; pStage++ ) { - if ( pStage->materialID != material.id || pStage->materialPackID != materialPackID ) { + if ( drawSurf->materialIDs[stage] != material.id || drawSurf->materialPackIDs[stage] != materialPackID ) { stage++; continue; } @@ -479,8 +463,8 @@ void MaterialSystem::GenerateWorldMaterialsBuffer() { tess.currentDrawSurf = drawSurf; tess.currentSSBOOffset = SSBOOffset; - tess.materialID = pStage->materialID; - tess.materialPackID = pStage->materialPackID; + tess.materialID = drawSurf->materialIDs[stage]; + tess.materialPackID = drawSurf->materialPackIDs[stage]; Tess_Begin( Tess_StageIteratorDummy, nullptr, nullptr, false, -1, 0 ); rb_surfaceTable[Util::ordinal( *drawSurf->surface )]( drawSurf->surface ); @@ -508,8 +492,6 @@ void MaterialSystem::GenerateMaterialsBuffer( std::vector& stage // Shader uniforms are set to 0 if they're not specified, so make sure we do that here too memset( materialsData, 0, size * sizeof( uint32_t ) ); for ( shaderStage_t* pStage : stages ) { - Material& material = materialPacks[pStage->materialPackID].materials[pStage->materialID]; - /* Stage variants are essentially copies of the same stage with slightly different values that normally come from a drawSurf_t */ uint32_t variants = 0; @@ -520,9 +502,11 @@ void MaterialSystem::GenerateMaterialsBuffer( std::vector& stage pStage->fullbright = i & Util::ordinal( ShaderStageVariant::FULLBRIGHT ); pStage->currentOffset = pStage->variantOffsets[i]; - const uint32_t variantOffset = pStage->variantOffsets[i] * material.shader->GetPaddedSize(); + const uint32_t variantOffset = pStage->variantOffsets[i] * pStage->paddedSize; pStage->bufferOffset += variantOffset; - pStage->surfaceDataUpdater( materialsData, material, pStage ); + + pStage->surfaceDataUpdater( materialsData, pStage ); + pStage->bufferOffset -= variantOffset; variants++; } @@ -756,8 +740,8 @@ void MaterialSystem::GenerateWorldCommandBuffer() { if ( depthPrePass ) { const drawSurf_t* depthDrawSurf = drawSurf->depthSurface; - const Material* material = &materialPacks[depthDrawSurf->shader->stages[0].materialPackID] - .materials[depthDrawSurf->shader->stages[0].materialID]; + const Material* material = &materialPacks[depthDrawSurf->materialPackIDs[0]] + .materials[depthDrawSurf->materialIDs[0]]; uint cmdID = material->surfaceCommandBatchOffset * SURFACE_COMMANDS_PER_BATCH + depthDrawSurf->drawCommandIDs[0]; // Add 1 because cmd 0 == no-command surface.surfaceCommandIDs[0] = cmdID + 1; @@ -774,7 +758,7 @@ void MaterialSystem::GenerateWorldCommandBuffer() { uint32_t stage = 0; for ( shaderStage_t* pStage = drawSurf->shader->stages; pStage < drawSurf->shader->lastStage; pStage++ ) { - const Material* material = &materialPacks[pStage->materialPackID].materials[pStage->materialID]; + const Material* material = &materialPacks[drawSurf->materialPackIDs[stage]].materials[drawSurf->materialIDs[stage]]; uint32_t cmdID = material->surfaceCommandBatchOffset * SURFACE_COMMANDS_PER_BATCH + drawSurf->drawCommandIDs[stage]; // Add 1 because cmd 0 == no-command surface.surfaceCommandIDs[stage + ( depthPrePass ? 1 : 0 )] = cmdID + 1; @@ -793,8 +777,8 @@ void MaterialSystem::GenerateWorldCommandBuffer() { if ( drawSurf->fogSurface ) { const drawSurf_t* fogDrawSurf = drawSurf->fogSurface; - const Material* material = &materialPacks[fogDrawSurf->shader->stages[0].materialPackID] - .materials[fogDrawSurf->shader->stages[0].materialID]; + const Material* material = &materialPacks[fogDrawSurf->materialPackIDs[0]] + .materials[fogDrawSurf->materialIDs[0]]; uint cmdID = material->surfaceCommandBatchOffset * SURFACE_COMMANDS_PER_BATCH + fogDrawSurf->drawCommandIDs[0]; // Add 1 because cmd 0 == no-command surface.surfaceCommandIDs[stage + ( depthPrePass ? 1 : 0 )] = cmdID + 1; @@ -1105,6 +1089,8 @@ void BindShaderFog( Material* material ) { gl_fogQuake3ShaderMaterial->SetUniform_FogDepthVector( fogDepthVector ); gl_fogQuake3ShaderMaterial->SetUniform_FogEyeT( eyeT ); + gl_fogQuake3ShaderMaterial->SetUniform_ColorGlobal( fog->color ); + gl_fogQuake3ShaderMaterial->SetUniform_ModelMatrix( backEnd.orientation.transformMatrix ); gl_fogQuake3ShaderMaterial->SetUniform_ModelViewProjectionMatrix( glState.modelViewProjectionMatrix[glState.stackIndex] ); @@ -1384,8 +1370,8 @@ void MaterialSystem::ProcessStage( drawSurf_t* drawSurf, shaderStage_t* pStage, AddStage( drawSurf, pStage, stage ); - if ( pStage->initialized ) { - Material* material = &materialPacks[pStage->materialPackID].materials[pStage->materialID]; + /* if ( pStage->initialized ) { + Material* material = &materialPacks[drawSurf->materialPackIDs[stage]].materials[drawSurf->materialIDs[stage]]; if ( std::find( material->drawSurfs.begin(), material->drawSurfs.end(), drawSurf ) == material->drawSurfs.end() ) { material->drawSurfs.emplace_back( drawSurf ); @@ -1395,7 +1381,7 @@ void MaterialSystem::ProcessStage( drawSurf_t* drawSurf, shaderStage_t* pStage, stage++; return; - } + } */ Material material; @@ -1431,6 +1417,7 @@ void MaterialSystem::ProcessStage( drawSurf_t* drawSurf, shaderStage_t* pStage, material.bspSurface = drawSurf->bspSurface; pStage->materialProcessor( &material, pStage, drawSurf ); + pStage->paddedSize = material.shader->GetPaddedSize(); std::vector& materials = materialPacks[materialPack].materials; std::vector::iterator currentSearchIt = materials.begin(); @@ -1468,8 +1455,8 @@ void MaterialSystem::ProcessStage( drawSurf_t* drawSurf, shaderStage_t* pStage, materials[previousMaterialID].drawSurfs.emplace_back( drawSurf ); } - pStage->materialID = previousMaterialID; - pStage->materialPackID = materialPack; + drawSurf->materialIDs[stage] = previousMaterialID; + drawSurf->materialPackIDs[stage] = materialPack; packIDs[materialPack] = id; diff --git a/src/engine/renderer/Material.h b/src/engine/renderer/Material.h index fe682bc41c..ec7cf9771c 100644 --- a/src/engine/renderer/Material.h +++ b/src/engine/renderer/Material.h @@ -415,16 +415,16 @@ extern GLSSBO debugSSBO; // Global extern MaterialSystem materialSystem; -void UpdateSurfaceDataNONE( uint32_t*, Material&, shaderStage_t* ); -void UpdateSurfaceDataNOP( uint32_t*, Material&, shaderStage_t* ); -void UpdateSurfaceDataGeneric3D( uint32_t* materials, Material& material, shaderStage_t* pStage ); -void UpdateSurfaceDataLightMapping( uint32_t* materials, Material& material, shaderStage_t* pStage ); -void UpdateSurfaceDataReflection( uint32_t* materials, Material& /* material */, shaderStage_t* pStage); -void UpdateSurfaceDataSkybox( uint32_t* materials, Material& material, shaderStage_t* pStage ); -void UpdateSurfaceDataScreen( uint32_t* materials, Material& /* material */, shaderStage_t* pStage); -void UpdateSurfaceDataHeatHaze( uint32_t* materials, Material& /* material */, shaderStage_t* pStage); -void UpdateSurfaceDataLiquid( uint32_t* materials, Material& /* material */, shaderStage_t* pStage); -void UpdateSurfaceDataFog( uint32_t* materials, Material& material, shaderStage_t* pStage ); +void UpdateSurfaceDataNONE( uint32_t*, shaderStage_t* ); +void UpdateSurfaceDataNOP( uint32_t*, shaderStage_t* ); +void UpdateSurfaceDataGeneric3D( uint32_t* materials, shaderStage_t* pStage ); +void UpdateSurfaceDataLightMapping( uint32_t* materials, shaderStage_t* pStage ); +void UpdateSurfaceDataReflection( uint32_t* materials, shaderStage_t* pStage); +void UpdateSurfaceDataSkybox( uint32_t* materials, shaderStage_t* pStage ); +void UpdateSurfaceDataScreen( uint32_t* materials, shaderStage_t* pStage); +void UpdateSurfaceDataHeatHaze( uint32_t* materials, shaderStage_t* pStage); +void UpdateSurfaceDataLiquid( uint32_t* materials, shaderStage_t* pStage); +void UpdateSurfaceDataFog( uint32_t* materials, shaderStage_t* pStage ); // void UpdateSurf( uint32) diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index 63e635564b..c9770f95e3 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -2707,7 +2707,7 @@ GLShader_fogQuake3::GLShader_fogQuake3( GLShaderManager *manager ) : u_FogMap( this ), u_ModelMatrix( this ), u_ModelViewProjectionMatrix( this ), - u_Color( this ), + u_ColorGlobal( this ), u_Bones( this ), u_VertexInterpolation( this ), u_FogDistanceVector( this ), @@ -2729,7 +2729,7 @@ GLShader_fogQuake3Material::GLShader_fogQuake3Material( GLShaderManager* manager u_FogMap( this ), u_ModelMatrix( this ), u_ModelViewProjectionMatrix( this ), - u_Color( this ), + u_ColorGlobal( this ), u_FogDistanceVector( this ), u_FogDepthVector( this ), u_FogEyeT( this ), diff --git a/src/engine/renderer/gl_shader.h b/src/engine/renderer/gl_shader.h index 41177b198e..72bd4b993c 100644 --- a/src/engine/renderer/gl_shader.h +++ b/src/engine/renderer/gl_shader.h @@ -3155,6 +3155,18 @@ class u_Color : } }; +class u_ColorGlobal : + GLUniform1ui { + public: + u_ColorGlobal( GLShader* shader ) : + GLUniform1ui( shader, "u_ColorGlobal", true ) { + } + + void SetUniform_ColorGlobal( const Color::Color& color ) { + this->SetValue( packUnorm4x8( color.ToArray() ) ); + } +}; + class u_Frame : GLUniform1ui { public: @@ -4376,7 +4388,7 @@ class GLShader_fogQuake3 : public u_FogMap, public u_ModelMatrix, public u_ModelViewProjectionMatrix, - public u_Color, + public u_ColorGlobal, public u_Bones, public u_VertexInterpolation, public u_FogDistanceVector, @@ -4396,7 +4408,7 @@ class GLShader_fogQuake3Material : public u_FogMap, public u_ModelMatrix, public u_ModelViewProjectionMatrix, - public u_Color, + public u_ColorGlobal, public u_FogDistanceVector, public u_FogDepthVector, public u_FogEyeT, diff --git a/src/engine/renderer/glsl_source/fogQuake3_vp.glsl b/src/engine/renderer/glsl_source/fogQuake3_vp.glsl index 77eba51fe1..33b216b485 100644 --- a/src/engine/renderer/glsl_source/fogQuake3_vp.glsl +++ b/src/engine/renderer/glsl_source/fogQuake3_vp.glsl @@ -28,8 +28,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA uniform float u_Time; -uniform vec4 u_ColorModulate; -uniform uint u_Color; +uniform vec4 u_ColorModulate; +uniform uint u_ColorGlobal; uniform mat4 u_ModelMatrix; uniform mat4 u_ModelViewProjectionMatrix; @@ -58,7 +58,7 @@ void main() VertexFetch( position, LB, color, texCoord, lmCoord ); - color = /* color * u_ColorModulate + */ unpackUnorm4x8( u_Color ); + color = /* color * u_ColorModulate + */ unpackUnorm4x8( u_ColorGlobal ); DeformVertex( position, LB.normal, diff --git a/src/engine/renderer/tr_local.h b/src/engine/renderer/tr_local.h index 9a3f32a756..c55836ed32 100644 --- a/src/engine/renderer/tr_local.h +++ b/src/engine/renderer/tr_local.h @@ -1102,7 +1102,7 @@ enum class shaderProfilerRenderSubGroupsMode { struct drawSurf_t; using stageRenderer_t = void(*)(shaderStage_t *); - using surfaceDataUpdater_t = void(*)(uint32_t*, Material&, shaderStage_t*); + using surfaceDataUpdater_t = void(*)(uint32_t*, shaderStage_t*); using stageShaderBinder_t = void(*)(Material*); using stageMaterialProcessor_t = void(*)(Material*, shaderStage_t*, drawSurf_t*); @@ -1212,15 +1212,14 @@ enum class shaderProfilerRenderSubGroupsMode { shader_t* shader; shaderStage_t* materialRemappedStage = nullptr; + uint32_t paddedSize = 0; + uint32_t materialOffset = 0; uint32_t bufferOffset = 0; uint32_t dynamicBufferOffset = 0; bool initialized = false; - uint materialPackID = 0; - uint materialID = 0; - bool dynamic = false; bool colorDynamic = false; @@ -1667,6 +1666,10 @@ enum class shaderProfilerRenderSubGroupsMode { int fog; int portalNum = -1; + + uint32_t materialPackIDs[MAX_SHADER_STAGES]; + uint32_t materialIDs[MAX_SHADER_STAGES]; + uint32_t drawCommandIDs[MAX_SHADER_STAGES]; uint32_t texDataIDs[MAX_SHADER_STAGES]; bool texDataDynamic[MAX_SHADER_STAGES]; diff --git a/src/engine/renderer/tr_shade.cpp b/src/engine/renderer/tr_shade.cpp index ebc618b1d6..8eb915f689 100644 --- a/src/engine/renderer/tr_shade.cpp +++ b/src/engine/renderer/tr_shade.cpp @@ -2317,7 +2317,7 @@ void Render_fog( shaderStage_t* pStage ) gl_fogQuake3Shader->SetUniform_FogEyeT( eyeT ); // u_Color - gl_fogQuake3Shader->SetUniform_Color( fog->color ); + gl_fogQuake3Shader->SetUniform_ColorGlobal( fog->color ); gl_fogQuake3Shader->SetUniform_ModelMatrix( backEnd.orientation.transformMatrix ); gl_fogQuake3Shader->SetUniform_ModelViewProjectionMatrix( glState.modelViewProjectionMatrix[ glState.stackIndex ] ); @@ -2699,8 +2699,8 @@ void Tess_StageIteratorColor() if ( materialSystem.generatingWorldCommandBuffer && pStage->useMaterialSystem ) { tess.currentSSBOOffset = pStage->materialOffset; - tess.materialID = pStage->materialID; - tess.materialPackID = pStage->materialPackID; + tess.materialID = tess.currentDrawSurf->materialIDs[stage]; + tess.materialPackID = tess.currentDrawSurf->materialPackIDs[stage]; } pStage->colorRenderer( pStage ); From 53679523369cb29f4be01f714ffe9315f67cf681 Mon Sep 17 00:00:00 2001 From: VReaperV Date: Thu, 2 Jan 2025 14:42:59 +0300 Subject: [PATCH 08/27] Some material system cleanup --- src/engine/renderer/Material.cpp | 47 ++++++++------------------------ src/engine/renderer/tr_shade.cpp | 44 ------------------------------ 2 files changed, 12 insertions(+), 79 deletions(-) diff --git a/src/engine/renderer/Material.cpp b/src/engine/renderer/Material.cpp index cb291bf141..a7cb04f3b6 100644 --- a/src/engine/renderer/Material.cpp +++ b/src/engine/renderer/Material.cpp @@ -142,8 +142,7 @@ void UpdateSurfaceDataNOP( uint32_t*, shaderStage_t* ) { void UpdateSurfaceDataGeneric3D( uint32_t* materials, shaderStage_t* pStage ) { // shader_t* shader = pStage->shader; - const uint32_t paddedOffset = pStage->bufferOffset; - materials += paddedOffset; + materials += pStage->bufferOffset; // u_AlphaThreshold gl_genericShaderMaterial->SetUniform_AlphaTest( pStage->stateBits ); @@ -170,8 +169,7 @@ void UpdateSurfaceDataGeneric3D( uint32_t* materials, shaderStage_t* pStage ) { void UpdateSurfaceDataLightMapping( uint32_t* materials, shaderStage_t* pStage ) { shader_t* shader = pStage->shader; - const uint32_t paddedOffset = pStage->bufferOffset; - materials += paddedOffset; + materials += pStage->bufferOffset; // u_ColorModulate colorGen_t rgbGen = SetRgbGen( pStage ); @@ -223,8 +221,7 @@ void UpdateSurfaceDataLightMapping( uint32_t* materials, shaderStage_t* pStage ) void UpdateSurfaceDataReflection( uint32_t* materials, shaderStage_t* pStage) { shader_t* shader = pStage->shader; - const uint32_t paddedOffset = pStage->bufferOffset; - materials += paddedOffset; + materials += pStage->bufferOffset; // bind u_ColorMap vec3_t position; @@ -265,8 +262,7 @@ void UpdateSurfaceDataReflection( uint32_t* materials, shaderStage_t* pStage) { void UpdateSurfaceDataSkybox( uint32_t* materials, shaderStage_t* pStage ) { // shader_t* shader = pStage->shader; - const uint32_t paddedOffset = pStage->bufferOffset; - materials += paddedOffset; + materials += pStage->bufferOffset; // u_AlphaThreshold gl_skyboxShaderMaterial->SetUniform_AlphaTest( GLS_ATEST_NONE ); @@ -277,8 +273,7 @@ void UpdateSurfaceDataSkybox( uint32_t* materials, shaderStage_t* pStage ) { void UpdateSurfaceDataScreen( uint32_t* materials, shaderStage_t* pStage) { // shader_t* shader = pStage->shader; - const uint32_t paddedOffset = pStage->bufferOffset; - materials += paddedOffset; + materials += pStage->bufferOffset; // bind u_CurrentMap /* FIXME: This is currently unused, but u_CurrentMap was made global for other shaders, @@ -291,8 +286,7 @@ void UpdateSurfaceDataScreen( uint32_t* materials, shaderStage_t* pStage) { void UpdateSurfaceDataHeatHaze( uint32_t* materials, shaderStage_t* pStage) { // shader_t* shader = pStage->shader; - const uint32_t paddedOffset = pStage->bufferOffset; - materials += paddedOffset; + materials += pStage->bufferOffset; float deformMagnitude = RB_EvalExpression( &pStage->deformMagnitudeExp, 1.0 ); gl_heatHazeShaderMaterial->SetUniform_DeformMagnitude( deformMagnitude ); @@ -311,8 +305,7 @@ void UpdateSurfaceDataHeatHaze( uint32_t* materials, shaderStage_t* pStage) { void UpdateSurfaceDataLiquid( uint32_t* materials, shaderStage_t* pStage) { // shader_t* shader = pStage->shader; - const uint32_t paddedOffset = pStage->bufferOffset; - materials += paddedOffset; + materials += pStage->bufferOffset; float fogDensity = RB_EvalExpression( &pStage->fogDensityExp, 0.001 ); vec4_t fogColor; @@ -364,8 +357,7 @@ void UpdateSurfaceDataLiquid( uint32_t* materials, shaderStage_t* pStage) { void UpdateSurfaceDataFog( uint32_t* materials, shaderStage_t* pStage ) { // shader_t* shader = pStage->shader; - const uint32_t paddedOffset = pStage->bufferOffset; - materials += paddedOffset; + materials += pStage->bufferOffset; gl_fogQuake3ShaderMaterial->WriteUniformsToBuffer( materials ); } @@ -468,7 +460,7 @@ void MaterialSystem::GenerateWorldMaterialsBuffer() { Tess_Begin( Tess_StageIteratorDummy, nullptr, nullptr, false, -1, 0 ); rb_surfaceTable[Util::ordinal( *drawSurf->surface )]( drawSurf->surface ); - remappedStage->colorRenderer( remappedStage ); + Tess_DrawElements(); Tess_Clear(); drawSurf->drawCommandIDs[stage] = lastCommandID; @@ -493,7 +485,7 @@ void MaterialSystem::GenerateMaterialsBuffer( std::vector& stage memset( materialsData, 0, size * sizeof( uint32_t ) ); for ( shaderStage_t* pStage : stages ) { /* Stage variants are essentially copies of the same stage with slightly different values that - normally come from a drawSurf_t */ + normally come from a drawSurf_t */ uint32_t variants = 0; for ( int i = 0; i < Util::ordinal( ShaderStageVariant::ALL ) && variants < pStage->variantOffset; i++ ) { if ( pStage->variantOffsets[i] != -1 ) { @@ -1368,21 +1360,6 @@ void MaterialSystem::ProcessStage( drawSurf_t* drawSurf, shaderStage_t* pStage, ComputeDynamics( pStage ); - AddStage( drawSurf, pStage, stage ); - - /* if ( pStage->initialized ) { - Material* material = &materialPacks[drawSurf->materialPackIDs[stage]].materials[drawSurf->materialIDs[stage]]; - if ( std::find( material->drawSurfs.begin(), material->drawSurfs.end(), drawSurf ) - == material->drawSurfs.end() ) { - material->drawSurfs.emplace_back( drawSurf ); - } - - AddStageTextures( drawSurf, stage, material ); - - stage++; - return; - } */ - Material material; uint32_t materialPack = 0; @@ -1448,6 +1425,7 @@ void MaterialSystem::ProcessStage( drawSurf_t* drawSurf, shaderStage_t* pStage, pStage->useMaterialSystem = true; pStage->initialized = true; + AddStage( drawSurf, pStage, stage ); AddStageTextures( drawSurf, stage, &materials[previousMaterialID] ); if ( std::find( materials[previousMaterialID].drawSurfs.begin(), materials[previousMaterialID].drawSurfs.end(), drawSurf ) @@ -1487,13 +1465,12 @@ void MaterialSystem::GenerateWorldMaterials() { backEnd.currentEntity = &tr.worldEntity; - drawSurf_t* drawSurf; totalDrawSurfs = 0; uint32_t packIDs[3] = { 0, 0, 0 }; for ( int i = 0; i < tr.refdef.numDrawSurfs; i++ ) { - drawSurf = &tr.refdef.drawSurfs[i]; + drawSurf_t* drawSurf = &tr.refdef.drawSurfs[i]; if ( drawSurf->entity != &tr.worldEntity ) { continue; } diff --git a/src/engine/renderer/tr_shade.cpp b/src/engine/renderer/tr_shade.cpp index 8eb915f689..88891a0757 100644 --- a/src/engine/renderer/tr_shade.cpp +++ b/src/engine/renderer/tr_shade.cpp @@ -818,11 +818,6 @@ void Render_generic3D( shaderStage_t *pStage ) { GLimp_LogComment( "--- Render_generic3D ---\n" ); - if ( materialSystem.generatingWorldCommandBuffer ) { - Tess_DrawElements(); - return; - } - GL_State( pStage->stateBits ); bool hasDepthFade = pStage->hasDepthFade; @@ -949,11 +944,6 @@ void Render_lightMapping( shaderStage_t *pStage ) { GLimp_LogComment( "--- Render_lightMapping ---\n" ); - if ( materialSystem.generatingWorldCommandBuffer ) { - Tess_DrawElements(); - return; - } - lightMode_t lightMode; deluxeMode_t deluxeMode; SetLightDeluxeMode( &tess, pStage->type, lightMode, deluxeMode ); @@ -1238,10 +1228,6 @@ static void Render_shadowFill( shaderStage_t *pStage ) GLimp_LogComment( "--- Render_shadowFill ---\n" ); - if ( materialSystem.generatingWorldCommandBuffer ) { - return; - } - // remove blend modes stateBits = pStage->stateBits; stateBits &= ~( GLS_SRCBLEND_BITS | GLS_DSTBLEND_BITS ); @@ -1872,11 +1858,6 @@ void Render_reflection_CB( shaderStage_t *pStage ) { GLimp_LogComment( "--- Render_reflection_CB ---\n" ); - if ( materialSystem.generatingWorldCommandBuffer ) { - Tess_DrawElements(); - return; - } - GL_State( pStage->stateBits ); // choose right shader program ---------------------------------- @@ -1968,11 +1949,6 @@ void Render_skybox( shaderStage_t *pStage ) { GLimp_LogComment( "--- Render_skybox ---\n" ); - if ( materialSystem.generatingWorldCommandBuffer ) { - Tess_DrawElements(); - return; - } - GL_State( pStage->stateBits ); gl_skyboxShader->BindProgram( pStage->deformIndex ); @@ -1998,11 +1974,6 @@ void Render_screen( shaderStage_t *pStage ) { GLimp_LogComment( "--- Render_screen ---\n" ); - if ( materialSystem.generatingWorldCommandBuffer ) { - Tess_DrawElements(); - return; - } - GL_State( pStage->stateBits ); gl_screenShader->BindProgram( pStage->deformIndex ); @@ -2058,11 +2029,6 @@ void Render_heatHaze( shaderStage_t *pStage ) GLimp_LogComment( "--- Render_heatHaze ---\n" ); - if ( materialSystem.generatingWorldCommandBuffer ) { - Tess_DrawElements(); - return; - } - // remove alpha test stateBits = pStage->stateBits; stateBits &= ~GLS_ATEST_BITS; @@ -2151,11 +2117,6 @@ void Render_liquid( shaderStage_t *pStage ) GLimp_LogComment( "--- Render_liquid ---\n" ); - if ( materialSystem.generatingWorldCommandBuffer ) { - Tess_DrawElements(); - return; - } - // Tr3B: don't allow blend effects GL_State( pStage->stateBits & ~( GLS_SRCBLEND_BITS | GLS_DSTBLEND_BITS | GLS_DEPTHMASK_TRUE ) ); @@ -2250,11 +2211,6 @@ void Render_liquid( shaderStage_t *pStage ) void Render_fog( shaderStage_t* pStage ) { - if ( materialSystem.generatingWorldCommandBuffer ) { - Tess_DrawElements(); - return; - } - if ( r_noFog->integer || !r_wolfFog->integer || ( backEnd.refdef.rdflags & RDF_NOWORLDMODEL ) ) { return; From d29feae55b82b39c6939a57965571bfb7149e341 Mon Sep 17 00:00:00 2001 From: VReaperV Date: Thu, 2 Jan 2025 15:29:52 +0300 Subject: [PATCH 09/27] Use a UBO for materials instead of an SSBO --- src/engine/renderer/Material.cpp | 46 +++++++++++++++---------------- src/engine/renderer/Material.h | 4 +-- src/engine/renderer/gl_shader.cpp | 13 +++++---- src/engine/renderer/tr_vbo.cpp | 8 +++--- 4 files changed, 36 insertions(+), 35 deletions(-) diff --git a/src/engine/renderer/Material.cpp b/src/engine/renderer/Material.cpp index a7cb04f3b6..d1613b5c29 100644 --- a/src/engine/renderer/Material.cpp +++ b/src/engine/renderer/Material.cpp @@ -37,8 +37,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "Material.h" #include "ShadeCommon.h" -GLSSBO materialsSSBO( "materials", 0, GL_MAP_WRITE_BIT, GL_MAP_INVALIDATE_RANGE_BIT ); -GLBuffer texDataSSBO( "texData", 6, GL_MAP_WRITE_BIT, GL_MAP_FLUSH_EXPLICIT_BIT ); +GLUBO materialsUBO( "materials", 0, GL_MAP_WRITE_BIT, GL_MAP_INVALIDATE_RANGE_BIT ); +GLBuffer texDataBuffer( "texData", 6, GL_MAP_WRITE_BIT, GL_MAP_FLUSH_EXPLICIT_BIT ); GLUBO lightmapDataUBO( "texData", 7, GL_MAP_WRITE_BIT, GL_MAP_FLUSH_EXPLICIT_BIT ); GLSSBO surfaceDescriptorsSSBO( "surfaceDescriptors", 1, GL_MAP_WRITE_BIT, GL_MAP_INVALIDATE_RANGE_BIT ); @@ -388,7 +388,7 @@ void UpdateSurfaceDataFog( uint32_t* materials, shaderStage_t* pStage ) { void MaterialSystem::GenerateWorldMaterialsBuffer() { Log::Debug( "Generating materials buffer" ); - materialsSSBO.BindBuffer(); + materialsUBO.BindBuffer(); // Sort by padded size to avoid extra padding std::sort( materialStages.begin(), materialStages.end(), @@ -432,8 +432,8 @@ void MaterialSystem::GenerateWorldMaterialsBuffer() { totalStageSize = offset; // 4 bytes per component - glBufferData( GL_SHADER_STORAGE_BUFFER, offset * sizeof( uint32_t ), nullptr, GL_DYNAMIC_DRAW ); - uint32_t* materialsData = materialsSSBO.MapBufferRange( offset ); + glBufferData( GL_UNIFORM_BUFFER, offset * sizeof( uint32_t ), nullptr, GL_DYNAMIC_DRAW ); + uint32_t* materialsData = materialsUBO.MapBufferRange( offset ); GenerateMaterialsBuffer( materialStages, offset, materialsData ); @@ -477,7 +477,7 @@ void MaterialSystem::GenerateWorldMaterialsBuffer() { } } - materialsSSBO.UnmapBuffer(); + materialsUBO.UnmapBuffer(); } void MaterialSystem::GenerateMaterialsBuffer( std::vector& stages, const uint32_t size, uint32_t* materialsData ) { @@ -577,10 +577,10 @@ void MaterialSystem::GenerateWorldCommandBuffer() { texDataBufferType = glConfig2.maxUniformBlockSize >= MIN_MATERIAL_UBO_SIZE ? GL_UNIFORM_BUFFER : GL_SHADER_STORAGE_BUFFER; - texDataSSBO.BindBuffer( texDataBufferType ); - texDataSSBO.BufferStorage( texDataBufferType, ( texData.size() + dynamicTexData.size() ) * TEX_BUNDLE_SIZE, 1, nullptr ); - texDataSSBO.MapAll( texDataBufferType ); - TexBundle* textureBundles = ( TexBundle* ) texDataSSBO.GetData(); + texDataBuffer.BindBuffer( texDataBufferType ); + texDataBuffer.BufferStorage( texDataBufferType, ( texData.size() + dynamicTexData.size() ) * TEX_BUNDLE_SIZE, 1, nullptr ); + texDataBuffer.MapAll( texDataBufferType ); + TexBundle* textureBundles = ( TexBundle* ) texDataBuffer.GetData(); memset( textureBundles, 0, ( texData.size() + dynamicTexData.size() ) * TEX_BUNDLE_SIZE * sizeof( uint32_t ) ); GenerateTexturesBuffer( texData, textureBundles ); @@ -592,9 +592,9 @@ void MaterialSystem::GenerateWorldCommandBuffer() { dynamicTexDataOffset = texData.size() * TEX_BUNDLE_SIZE; dynamicTexDataSize = dynamicTexData.size() * TEX_BUNDLE_SIZE; - texDataSSBO.FlushAll( texDataBufferType ); - texDataSSBO.UnmapBuffer(); - texDataSSBO.UnBindBuffer( texDataBufferType ); + texDataBuffer.FlushAll( texDataBufferType ); + texDataBuffer.UnmapBuffer(); + texDataBuffer.UnBindBuffer( texDataBufferType ); lightmapDataUBO.BindBuffer(); lightmapDataUBO.BufferStorage( MAX_LIGHTMAPS * LIGHTMAP_SIZE, 1, nullptr ); @@ -1606,24 +1606,24 @@ void MaterialSystem::AddStageTextures( drawSurf_t* drawSurf, const uint32_t stag // Dynamic surfaces are those whose values in the SSBO can be updated void MaterialSystem::UpdateDynamicSurfaces() { if ( dynamicStagesSize > 0 ) { - materialsSSBO.BindBuffer(); - uint32_t* materialsData = materialsSSBO.MapBufferRange( dynamicStagesOffset, dynamicStagesSize ); + materialsUBO.BindBuffer(); + uint32_t* materialsData = materialsUBO.MapBufferRange( dynamicStagesOffset, dynamicStagesSize ); GenerateMaterialsBuffer( dynamicStages, dynamicStagesSize, materialsData ); - materialsSSBO.UnmapBuffer(); + materialsUBO.UnmapBuffer(); } if ( dynamicTexDataSize > 0 ) { - texDataSSBO.BindBuffer( texDataBufferType ); + texDataBuffer.BindBuffer( texDataBufferType ); GL_CheckErrors(); TexBundle* textureBundles = - ( TexBundle* ) texDataSSBO.MapBufferRange( texDataBufferType, dynamicTexDataOffset, dynamicTexDataSize ); + ( TexBundle* ) texDataBuffer.MapBufferRange( texDataBufferType, dynamicTexDataOffset, dynamicTexDataSize ); GL_CheckErrors(); GenerateTexturesBuffer( dynamicTexData, textureBundles ); - texDataSSBO.UnmapBuffer(); + texDataBuffer.UnmapBuffer(); } } @@ -1894,7 +1894,7 @@ void MaterialSystem::Free() { surfaceCommandsSSBO.UnmapBuffer(); culledCommandsBuffer.UnmapBuffer(); atomicCommandCountersBuffer.UnmapBuffer(); - texDataSSBO.UnmapBuffer(); + texDataBuffer.UnmapBuffer(); lightmapDataUBO.UnmapBuffer(); if ( totalPortals > 0 ) { @@ -2057,7 +2057,7 @@ void MaterialSystem::RenderMaterials( const shaderSort_t fromSort, const shaderS frameStart = false; } - materialsSSBO.BindBufferBase(); + materialsUBO.BindBufferBase(); for ( MaterialPack& materialPack : materialPacks ) { if ( materialPack.fromSort >= fromSort && materialPack.toSort <= toSort ) { @@ -2199,7 +2199,7 @@ void MaterialSystem::RenderMaterial( Material& material, const uint32_t viewID ) atomicCommandCountersBuffer.BindBuffer( GL_PARAMETER_BUFFER_ARB ); - texDataSSBO.BindBufferBase( texDataBufferType ); + texDataBuffer.BindBufferBase( texDataBufferType ); lightmapDataUBO.BindBufferBase(); if ( r_showGlobalMaterials.Get() && material.sort != 0 @@ -2316,7 +2316,7 @@ void MaterialSystem::RenderMaterial( Material& material, const uint32_t viewID ) atomicCommandCountersBuffer.UnBindBuffer( GL_PARAMETER_BUFFER_ARB ); - texDataSSBO.UnBindBufferBase( texDataBufferType ); + texDataBuffer.UnBindBufferBase( texDataBufferType ); lightmapDataUBO.UnBindBufferBase(); if ( material.usePolygonOffset ) { diff --git a/src/engine/renderer/Material.h b/src/engine/renderer/Material.h index ec7cf9771c..123e4577cd 100644 --- a/src/engine/renderer/Material.h +++ b/src/engine/renderer/Material.h @@ -400,8 +400,8 @@ class MaterialSystem { void UpdateFrameData(); }; -extern GLSSBO materialsSSBO; // Global -extern GLBuffer texDataSSBO; // Global +extern GLUBO materialsUBO; // Global +extern GLBuffer texDataBuffer; // Global extern GLUBO lightmapDataUBO; // Global extern GLSSBO surfaceDescriptorsSSBO; // Global diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index c9770f95e3..9fc5164fe6 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -1359,9 +1359,12 @@ std::string GLShaderManager::ShaderPostProcess( GLShader *shader, const std::str std::string newShaderText; std::string materialStruct = "\nstruct Material {\n"; - std::string materialBlock = "layout(std430, binding = 0) restrict readonly buffer materialsSSBO {\n" - " Material materials[];\n" + // 6 kb for materials + const uint32_t count = ( 4096 + 2048 ) / shader->GetPaddedSize(); + std::string materialBlock = "layout(std140, binding = 0) uniform materialsUBO {\n" + " Material materials[" + std::to_string( count ) + "]; \n" "};\n\n"; + std::string texBuf = glConfig2.maxUniformBlockSize >= MIN_MATERIAL_UBO_SIZE ? "layout(std140, binding = 6) uniform texDataUBO {\n" " TexData texData[" + std::to_string( MAX_TEX_BUNDLES ) + "]; \n" @@ -2019,7 +2022,6 @@ void GLShader::PostProcessUniforms() { // Sort uniforms from highest to lowest alignment so we don't need to pad uniforms (other than vec3s) const uint numUniforms = _uniforms.size(); - GLuint structAlignment = 0; GLuint structSize = 0; while ( tmp.size() < numUniforms ) { // Higher-alignment uniforms first to avoid wasting memory @@ -2030,9 +2032,7 @@ void GLShader::PostProcessUniforms() { highestAlignment = _uniforms[i]->GetSTD430Alignment(); highestUniform = i; } - if ( highestAlignment > structAlignment ) { - structAlignment = highestAlignment; - } + if ( highestAlignment == 4 ) { break; // 4-component is the highest alignment in std430 } @@ -2051,6 +2051,7 @@ void GLShader::PostProcessUniforms() { } _uniforms = tmp; + const GLuint structAlignment = 4; // Material buffer is now a UBO, so it uses std140 layout, which is aligned to vec4 if ( structSize > 0 ) { padding = ( structAlignment - ( structSize % structAlignment ) ) % structAlignment; } diff --git a/src/engine/renderer/tr_vbo.cpp b/src/engine/renderer/tr_vbo.cpp index 5e6ab9b246..daf3f504bf 100644 --- a/src/engine/renderer/tr_vbo.cpp +++ b/src/engine/renderer/tr_vbo.cpp @@ -729,8 +729,8 @@ static void R_InitLightUBO() static void R_InitMaterialBuffers() { if( glConfig2.usingMaterialSystem ) { - materialsSSBO.GenBuffer(); - texDataSSBO.GenBuffer(); + materialsUBO.GenBuffer(); + texDataBuffer.GenBuffer(); lightmapDataUBO.GenBuffer(); surfaceDescriptorsSSBO.GenBuffer(); @@ -861,8 +861,8 @@ void R_ShutdownVBOs() } if ( glConfig2.usingMaterialSystem ) { - materialsSSBO.DelBuffer(); - texDataSSBO.DelBuffer(); + materialsUBO.DelBuffer(); + texDataBuffer.DelBuffer(); lightmapDataUBO.DelBuffer(); surfaceDescriptorsSSBO.DelBuffer(); From ab23a85c8a94e83ba3ab5e0610f6bad36113e07d Mon Sep 17 00:00:00 2001 From: VReaperV Date: Thu, 2 Jan 2025 20:41:09 +0300 Subject: [PATCH 10/27] Fix material system texture matrices Also fixes an incorrect matrix constructor in shaders. --- src/engine/renderer/Material.cpp | 22 ++++++++++++---------- src/engine/renderer/Material.h | 5 +++-- src/engine/renderer/gl_shader.cpp | 23 +++++++++++++---------- 3 files changed, 28 insertions(+), 22 deletions(-) diff --git a/src/engine/renderer/Material.cpp b/src/engine/renderer/Material.cpp index d1613b5c29..976f50fea8 100644 --- a/src/engine/renderer/Material.cpp +++ b/src/engine/renderer/Material.cpp @@ -524,17 +524,16 @@ void MaterialSystem::GenerateTexturesBuffer( std::vector& textures, } } - // While reflection, liquid and heatHaze shaders use the matrix from TB_NORMALMAP bundle, it's never actually parsed - RB_CalcTexMatrix( textureData.texBundles[0], tess.svars.texMatrices[TB_COLORMAP] ); + const int bundle = textureData.textureMatrixBundle; + RB_CalcTexMatrix( textureData.texBundles[bundle], tess.svars.texMatrices[bundle] ); /* We only actually need these 6 components to get the correct texture transformation, the other ones are unused */ - textureBundles->textureMatrix[0] = tess.svars.texMatrices[TB_COLORMAP][0]; - textureBundles->textureMatrix[1] = tess.svars.texMatrices[TB_COLORMAP][1]; - textureBundles->textureMatrix[2] = tess.svars.texMatrices[TB_COLORMAP][4]; - textureBundles->textureMatrix[3] = tess.svars.texMatrices[TB_COLORMAP][5]; - // These are stored as part of a vec4 in a UBO, so we need to convert them here as well - textureBundles->textureMatrix2[0] = tess.svars.texMatrices[TB_COLORMAP][12] * 32768.0f; - textureBundles->textureMatrix2[1] = tess.svars.texMatrices[TB_COLORMAP][13] * 32768.0f; + textureBundles->textureMatrix[0] = tess.svars.texMatrices[bundle][0]; + textureBundles->textureMatrix[1] = tess.svars.texMatrices[bundle][1]; + textureBundles->textureMatrix[2] = tess.svars.texMatrices[bundle][4]; + textureBundles->textureMatrix[3] = tess.svars.texMatrices[bundle][5]; + textureBundles->textureMatrix[4] = tess.svars.texMatrices[bundle][12]; + textureBundles->textureMatrix[5] = tess.svars.texMatrices[bundle][13]; textureBundles++; } } @@ -1549,7 +1548,9 @@ void MaterialSystem::AddStageTextures( drawSurf_t* drawSurf, const uint32_t stag int bundleNum = 0; bool dynamic = false; - for ( const textureBundle_t& bundle : pStage->bundle ) { + for ( int i = 0; i < MAX_TEXTURE_BUNDLES; i++ ) { + const textureBundle_t& bundle = pStage->bundle[i]; + if ( bundle.isVideoMap ) { material->AddTexture( tr.cinematicImage[bundle.videoMapHandle]->texture ); continue; @@ -1562,6 +1563,7 @@ void MaterialSystem::AddStageTextures( drawSurf_t* drawSurf, const uint32_t stag } if ( bundle.numImages > 1 || bundle.numTexMods > 0 ) { + textureData.textureMatrixBundle = i; dynamic = true; } diff --git a/src/engine/renderer/Material.h b/src/engine/renderer/Material.h index 123e4577cd..3e03121c61 100644 --- a/src/engine/renderer/Material.h +++ b/src/engine/renderer/Material.h @@ -136,8 +136,7 @@ struct Material { }; struct TexBundle { - vec_t textureMatrix[4]; - uint32_t textureMatrix2[2]; + vec_t textureMatrix[6]; GLuint64 textures[MAX_TEXTURE_BUNDLES]; }; @@ -145,6 +144,7 @@ struct TextureData { const textureBundle_t* texBundles[MAX_TEXTURE_BUNDLES] = { nullptr, nullptr, nullptr, nullptr, nullptr }; // For ST_STYLELIGHTMAP stages image_t* texBundlesOverride[MAX_TEXTURE_BUNDLES] = { nullptr, nullptr, nullptr, nullptr, nullptr }; + int textureMatrixBundle = 0; bool operator==( const TextureData& other ) const { for ( int i = 0; i < MAX_TEXTURE_BUNDLES; i++ ) { @@ -193,6 +193,7 @@ struct TextureData { TextureData( const TextureData& other ) { memcpy( texBundles, other.texBundles, MAX_TEXTURE_BUNDLES * sizeof( textureBundle_t* ) ); memcpy( texBundlesOverride, other.texBundlesOverride, MAX_TEXTURE_BUNDLES * sizeof( image_t* ) ); + textureMatrixBundle = other.textureMatrixBundle; } }; diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index 9fc5164fe6..6a1323001f 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -1372,20 +1372,23 @@ std::string GLShaderManager::ShaderPostProcess( GLShader *shader, const std::str : "layout(std430, binding = 6) restrict readonly buffer texDataSSBO {\n" " TexData texData[];\n" "};\n\n"; - // We have to store these as a bunch of vec4/uvec4 because std140 pads everything to a vec4 + // We have to store u_TextureMatrix as vec4 + vec2 because otherwise it would be aligned to a vec4 under std140 std::string texDataBlock = "struct TexData {\n" " vec4 u_TextureMatrix;\n" - " uvec4 u_TextureDiffuseMap;\n" - " uvec4 u_NormalHeightMap;\n" - " uvec4 u_MaterialGlowMap;\n" + " vec2 u_TextureMatrix2;\n" + " uvec2 u_DiffuseMap;\n" + " uvec2 u_NormalMap;\n" + " uvec2 u_HeightMap;\n" + " uvec2 u_MaterialMap;\n" + " uvec2 u_GlowMap;\n" "};\n\n" + texBuf + - "#define u_TextureMatrix mat3x2( texData[( baseInstance >> 12 ) & 0xFFF].u_TextureMatrix, vec2( texData[( baseInstance >> 12 ) & 0xFFF].u_TextureDiffuseMap.xy ) * vec2( 1.0f / 32768.0f ) )\n" - "#define u_DiffuseMap_initial uvec2( texData[( baseInstance >> 12 ) & 0xFFF].u_TextureDiffuseMap.zw )\n" - "#define u_NormalMap_initial uvec2( texData[( baseInstance >> 12 ) & 0xFFF].u_NormalHeightMap.xy )\n" - "#define u_HeightMap_initial uvec2( texData[( baseInstance >> 12 ) & 0xFFF].u_NormalHeightMap.zw )\n" - "#define u_MaterialMap_initial uvec2( texData[( baseInstance >> 12 ) & 0xFFF].u_MaterialGlowMap.xy )\n" - "#define u_GlowMap_initial uvec2( texData[( baseInstance >> 12 ) & 0xFFF].u_MaterialGlowMap.zw )\n\n" + "#define u_TextureMatrix mat3x2( texData[( baseInstance >> 12 ) & 0xFFF].u_TextureMatrix.xy, texData[( baseInstance >> 12 ) & 0xFFF].u_TextureMatrix.zw, texData[( baseInstance >> 12 ) & 0xFFF].u_TextureMatrix2 )\n" + "#define u_DiffuseMap_initial texData[( baseInstance >> 12 ) & 0xFFF].u_DiffuseMap\n" + "#define u_NormalMap_initial texData[( baseInstance >> 12 ) & 0xFFF].u_NormalMap\n" + "#define u_HeightMap_initial texData[( baseInstance >> 12 ) & 0xFFF].u_HeightMap\n" + "#define u_MaterialMap_initial texData[( baseInstance >> 12 ) & 0xFFF].u_MaterialMap\n" + "#define u_GlowMap_initial texData[( baseInstance >> 12 ) & 0xFFF].u_GlowMap\n\n" "struct LightMapData {\n" " uvec2 u_LightMap;\n" " uvec2 u_DeluxeMap;\n" From f42e0b46ea6607e7ee40c09678d28f6c41dd033d Mon Sep 17 00:00:00 2001 From: VReaperV Date: Sat, 11 Jan 2025 15:36:49 +0300 Subject: [PATCH 11/27] Fix dynamic lights with material system The UBO bindings were conflicting with light UBO. --- src/engine/renderer/Material.cpp | 6 +++--- src/engine/renderer/gl_shader.cpp | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/engine/renderer/Material.cpp b/src/engine/renderer/Material.cpp index 976f50fea8..64c1b3917d 100644 --- a/src/engine/renderer/Material.cpp +++ b/src/engine/renderer/Material.cpp @@ -37,9 +37,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "Material.h" #include "ShadeCommon.h" -GLUBO materialsUBO( "materials", 0, GL_MAP_WRITE_BIT, GL_MAP_INVALIDATE_RANGE_BIT ); -GLBuffer texDataBuffer( "texData", 6, GL_MAP_WRITE_BIT, GL_MAP_FLUSH_EXPLICIT_BIT ); -GLUBO lightmapDataUBO( "texData", 7, GL_MAP_WRITE_BIT, GL_MAP_FLUSH_EXPLICIT_BIT ); +GLUBO materialsUBO( "materials", 6, GL_MAP_WRITE_BIT, GL_MAP_INVALIDATE_RANGE_BIT ); +GLBuffer texDataBuffer( "texData", 7, GL_MAP_WRITE_BIT, GL_MAP_FLUSH_EXPLICIT_BIT ); +GLUBO lightmapDataUBO( "texData", 8, GL_MAP_WRITE_BIT, GL_MAP_FLUSH_EXPLICIT_BIT ); GLSSBO surfaceDescriptorsSSBO( "surfaceDescriptors", 1, GL_MAP_WRITE_BIT, GL_MAP_INVALIDATE_RANGE_BIT ); GLSSBO surfaceCommandsSSBO( "surfaceCommands", 2, GL_MAP_WRITE_BIT, GL_MAP_FLUSH_EXPLICIT_BIT ); diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index 6a1323001f..2591a820d1 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -1361,15 +1361,15 @@ std::string GLShaderManager::ShaderPostProcess( GLShader *shader, const std::str std::string materialStruct = "\nstruct Material {\n"; // 6 kb for materials const uint32_t count = ( 4096 + 2048 ) / shader->GetPaddedSize(); - std::string materialBlock = "layout(std140, binding = 0) uniform materialsUBO {\n" + std::string materialBlock = "layout(std140, binding = 6) uniform materialsUBO {\n" " Material materials[" + std::to_string( count ) + "]; \n" "};\n\n"; std::string texBuf = glConfig2.maxUniformBlockSize >= MIN_MATERIAL_UBO_SIZE ? - "layout(std140, binding = 6) uniform texDataUBO {\n" + "layout(std140, binding = 7) uniform texDataUBO {\n" " TexData texData[" + std::to_string( MAX_TEX_BUNDLES ) + "]; \n" "};\n\n" - : "layout(std430, binding = 6) restrict readonly buffer texDataSSBO {\n" + : "layout(std430, binding = 7) restrict readonly buffer texDataSSBO {\n" " TexData texData[];\n" "};\n\n"; // We have to store u_TextureMatrix as vec4 + vec2 because otherwise it would be aligned to a vec4 under std140 @@ -1393,7 +1393,7 @@ std::string GLShaderManager::ShaderPostProcess( GLShader *shader, const std::str " uvec2 u_LightMap;\n" " uvec2 u_DeluxeMap;\n" "};\n\n" - "layout(std140, binding = 7) uniform lightmapDataUBO {\n" + "layout(std140, binding = 8) uniform lightmapDataUBO {\n" " LightMapData lightmapData[256];\n" "};\n\n" "#define u_LightMap_initial lightmapData[( baseInstance >> 24 ) & 0xFF].u_LightMap\n" From b1d7d2e447e23cf053bf0bb4043e42b4a7b1ebfa Mon Sep 17 00:00:00 2001 From: VReaperV Date: Fri, 24 Jan 2025 02:30:42 +0300 Subject: [PATCH 12/27] Remove a sneaky static --- src/engine/renderer/gl_shader.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/renderer/gl_shader.h b/src/engine/renderer/gl_shader.h index 72bd4b993c..73dad8d783 100644 --- a/src/engine/renderer/gl_shader.h +++ b/src/engine/renderer/gl_shader.h @@ -2757,7 +2757,7 @@ class u_TextureMatrix : { /* We only actually need these 6 components to get the correct texture transformation, the other ones are unused */ - static vec_t m2[6]; + vec_t m2[6]; m2[0] = m[0]; m2[1] = m[1]; m2[2] = m[4]; From 01d1ee45c7ca76d716e8928dbd55adaff6667fb0 Mon Sep 17 00:00:00 2001 From: VReaperV Date: Mon, 27 Jan 2025 03:28:54 +0300 Subject: [PATCH 13/27] Fix lightMapData naming Also make it in line with other usages of `lightMap`. --- src/engine/renderer/Material.cpp | 22 +++++++++++----------- src/engine/renderer/Material.h | 2 +- src/engine/renderer/gl_shader.cpp | 8 ++++---- src/engine/renderer/tr_vbo.cpp | 4 ++-- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/engine/renderer/Material.cpp b/src/engine/renderer/Material.cpp index 64c1b3917d..3c3c7277f0 100644 --- a/src/engine/renderer/Material.cpp +++ b/src/engine/renderer/Material.cpp @@ -39,7 +39,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. GLUBO materialsUBO( "materials", 6, GL_MAP_WRITE_BIT, GL_MAP_INVALIDATE_RANGE_BIT ); GLBuffer texDataBuffer( "texData", 7, GL_MAP_WRITE_BIT, GL_MAP_FLUSH_EXPLICIT_BIT ); -GLUBO lightmapDataUBO( "texData", 8, GL_MAP_WRITE_BIT, GL_MAP_FLUSH_EXPLICIT_BIT ); +GLUBO lightMapDataUBO( "lightMapData", 8, GL_MAP_WRITE_BIT, GL_MAP_FLUSH_EXPLICIT_BIT ); GLSSBO surfaceDescriptorsSSBO( "surfaceDescriptors", 1, GL_MAP_WRITE_BIT, GL_MAP_INVALIDATE_RANGE_BIT ); GLSSBO surfaceCommandsSSBO( "surfaceCommands", 2, GL_MAP_WRITE_BIT, GL_MAP_FLUSH_EXPLICIT_BIT ); @@ -595,10 +595,10 @@ void MaterialSystem::GenerateWorldCommandBuffer() { texDataBuffer.UnmapBuffer(); texDataBuffer.UnBindBuffer( texDataBufferType ); - lightmapDataUBO.BindBuffer(); - lightmapDataUBO.BufferStorage( MAX_LIGHTMAPS * LIGHTMAP_SIZE, 1, nullptr ); - lightmapDataUBO.MapAll(); - uint64_t* lightmapData = ( uint64_t* ) lightmapDataUBO.GetData(); + lightMapDataUBO.BindBuffer(); + lightMapDataUBO.BufferStorage( MAX_LIGHTMAPS * LIGHTMAP_SIZE, 1, nullptr ); + lightMapDataUBO.MapAll(); + uint64_t* lightmapData = ( uint64_t* ) lightMapDataUBO.GetData(); memset( lightmapData, 0, MAX_LIGHTMAPS * LIGHTMAP_SIZE * sizeof( uint32_t ) ); for ( uint32_t i = 0; i < tr.lightmaps.size(); i++ ) { @@ -633,9 +633,9 @@ void MaterialSystem::GenerateWorldCommandBuffer() { lightmapData[255 * 2 + 1] = tr.blackImage->texture->bindlessTextureHandle; } - lightmapDataUBO.FlushAll(); - lightmapDataUBO.UnmapBuffer(); - lightmapDataUBO.UnBindBuffer(); + lightMapDataUBO.FlushAll(); + lightMapDataUBO.UnmapBuffer(); + lightMapDataUBO.UnBindBuffer(); surfaceCommandsCount = totalBatchCount * SURFACE_COMMANDS_PER_BATCH; @@ -1897,7 +1897,7 @@ void MaterialSystem::Free() { culledCommandsBuffer.UnmapBuffer(); atomicCommandCountersBuffer.UnmapBuffer(); texDataBuffer.UnmapBuffer(); - lightmapDataUBO.UnmapBuffer(); + lightMapDataUBO.UnmapBuffer(); if ( totalPortals > 0 ) { portalSurfacesSSBO.UnmapBuffer(); @@ -2202,7 +2202,7 @@ void MaterialSystem::RenderMaterial( Material& material, const uint32_t viewID ) atomicCommandCountersBuffer.BindBuffer( GL_PARAMETER_BUFFER_ARB ); texDataBuffer.BindBufferBase( texDataBufferType ); - lightmapDataUBO.BindBufferBase(); + lightMapDataUBO.BindBufferBase(); if ( r_showGlobalMaterials.Get() && material.sort != 0 && ( material.shaderBinder == BindShaderLightMapping || material.shaderBinder == BindShaderGeneric3D ) ) { @@ -2319,7 +2319,7 @@ void MaterialSystem::RenderMaterial( Material& material, const uint32_t viewID ) atomicCommandCountersBuffer.UnBindBuffer( GL_PARAMETER_BUFFER_ARB ); texDataBuffer.UnBindBufferBase( texDataBufferType ); - lightmapDataUBO.UnBindBufferBase(); + lightMapDataUBO.UnBindBufferBase(); if ( material.usePolygonOffset ) { glDisable( GL_POLYGON_OFFSET_FILL ); diff --git a/src/engine/renderer/Material.h b/src/engine/renderer/Material.h index 3e03121c61..c76f48d784 100644 --- a/src/engine/renderer/Material.h +++ b/src/engine/renderer/Material.h @@ -403,7 +403,7 @@ class MaterialSystem { extern GLUBO materialsUBO; // Global extern GLBuffer texDataBuffer; // Global -extern GLUBO lightmapDataUBO; // Global +extern GLUBO lightMapDataUBO; // Global extern GLSSBO surfaceDescriptorsSSBO; // Global extern GLSSBO surfaceCommandsSSBO; // Per viewframe, GPU updated diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index 2591a820d1..785662be76 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -1393,11 +1393,11 @@ std::string GLShaderManager::ShaderPostProcess( GLShader *shader, const std::str " uvec2 u_LightMap;\n" " uvec2 u_DeluxeMap;\n" "};\n\n" - "layout(std140, binding = 8) uniform lightmapDataUBO {\n" - " LightMapData lightmapData[256];\n" + "layout(std140, binding = 8) uniform lightMapDataUBO {\n" + " LightMapData lightMapData[256];\n" "};\n\n" - "#define u_LightMap_initial lightmapData[( baseInstance >> 24 ) & 0xFF].u_LightMap\n" - "#define u_DeluxeMap_initial lightmapData[( baseInstance >> 24 ) & 0xFF].u_DeluxeMap\n\n"; + "#define u_LightMap_initial lightMapData[( baseInstance >> 24 ) & 0xFF].u_LightMap\n" + "#define u_DeluxeMap_initial lightMapData[( baseInstance >> 24 ) & 0xFF].u_DeluxeMap\n\n"; std::string materialDefines; /* Generate the struct and defines in the form of: diff --git a/src/engine/renderer/tr_vbo.cpp b/src/engine/renderer/tr_vbo.cpp index daf3f504bf..e453a62d7e 100644 --- a/src/engine/renderer/tr_vbo.cpp +++ b/src/engine/renderer/tr_vbo.cpp @@ -731,7 +731,7 @@ static void R_InitMaterialBuffers() { if( glConfig2.usingMaterialSystem ) { materialsUBO.GenBuffer(); texDataBuffer.GenBuffer(); - lightmapDataUBO.GenBuffer(); + lightMapDataUBO.GenBuffer(); surfaceDescriptorsSSBO.GenBuffer(); surfaceCommandsSSBO.GenBuffer(); @@ -863,7 +863,7 @@ void R_ShutdownVBOs() if ( glConfig2.usingMaterialSystem ) { materialsUBO.DelBuffer(); texDataBuffer.DelBuffer(); - lightmapDataUBO.DelBuffer(); + lightMapDataUBO.DelBuffer(); surfaceDescriptorsSSBO.DelBuffer(); surfaceCommandsSSBO.DelBuffer(); From 65e465b9a41ac4612d1885430298d92511c2850b Mon Sep 17 00:00:00 2001 From: VReaperV Date: Mon, 27 Jan 2025 03:31:00 +0300 Subject: [PATCH 14/27] Use default constructors/destructors for TextureData --- src/engine/renderer/Material.h | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/engine/renderer/Material.h b/src/engine/renderer/Material.h index c76f48d784..30d9721927 100644 --- a/src/engine/renderer/Material.h +++ b/src/engine/renderer/Material.h @@ -186,15 +186,6 @@ struct TextureData { return true; } - - TextureData() { - } - - TextureData( const TextureData& other ) { - memcpy( texBundles, other.texBundles, MAX_TEXTURE_BUNDLES * sizeof( textureBundle_t* ) ); - memcpy( texBundlesOverride, other.texBundlesOverride, MAX_TEXTURE_BUNDLES * sizeof( image_t* ) ); - textureMatrixBundle = other.textureMatrixBundle; - } }; enum class MaterialDebugMode { From a941aa75102e27be081bc146e33ec042c62024de Mon Sep 17 00:00:00 2001 From: VReaperV Date: Mon, 27 Jan 2025 04:35:06 +0300 Subject: [PATCH 15/27] Send stage variant data through `UpdateSurfaceData*` --- src/engine/renderer/Material.cpp | 51 ++++++++++++++++---------------- src/engine/renderer/Material.h | 23 +++++++------- src/engine/renderer/tr_local.h | 7 +---- 3 files changed, 38 insertions(+), 43 deletions(-) diff --git a/src/engine/renderer/Material.cpp b/src/engine/renderer/Material.cpp index 3c3c7277f0..14f2d53611 100644 --- a/src/engine/renderer/Material.cpp +++ b/src/engine/renderer/Material.cpp @@ -132,14 +132,14 @@ static void ComputeDynamics( shaderStage_t* pStage ) { // UpdateSurface*() functions will actually write the uniform values to the SSBO // Mirrors parts of the Render_*() functions in tr_shade.cpp -void UpdateSurfaceDataNONE( uint32_t*, shaderStage_t* ) { +void UpdateSurfaceDataNONE( uint32_t*, shaderStage_t*, bool, bool, bool ) { ASSERT_UNREACHABLE(); } -void UpdateSurfaceDataNOP( uint32_t*, shaderStage_t* ) { +void UpdateSurfaceDataNOP( uint32_t*, shaderStage_t*, bool, bool, bool ) { } -void UpdateSurfaceDataGeneric3D( uint32_t* materials, shaderStage_t* pStage ) { +void UpdateSurfaceDataGeneric3D( uint32_t* materials, shaderStage_t* pStage, bool mayUseVertexOverbright, bool, bool ) { // shader_t* shader = pStage->shader; materials += pStage->bufferOffset; @@ -151,7 +151,6 @@ void UpdateSurfaceDataGeneric3D( uint32_t* materials, shaderStage_t* pStage ) { colorGen_t rgbGen = SetRgbGen( pStage ); alphaGen_t alphaGen = SetAlphaGen( pStage ); - bool mayUseVertexOverbright = pStage->mayUseVertexOverbright; const bool styleLightMap = pStage->type == stageType_t::ST_STYLELIGHTMAP || pStage->type == stageType_t::ST_STYLECOLORMAP; gl_genericShaderMaterial->SetUniform_ColorModulateColorGen( rgbGen, alphaGen, mayUseVertexOverbright, styleLightMap ); @@ -166,7 +165,7 @@ void UpdateSurfaceDataGeneric3D( uint32_t* materials, shaderStage_t* pStage ) { gl_genericShaderMaterial->WriteUniformsToBuffer( materials ); } -void UpdateSurfaceDataLightMapping( uint32_t* materials, shaderStage_t* pStage ) { +void UpdateSurfaceDataLightMapping( uint32_t* materials, shaderStage_t* pStage, bool, bool vertexLit, bool fullbright ) { shader_t* shader = pStage->shader; materials += pStage->bufferOffset; @@ -178,12 +177,12 @@ void UpdateSurfaceDataLightMapping( uint32_t* materials, shaderStage_t* pStage ) Tess_ComputeColor( pStage ); // HACK: This only has effect on vertex-lit surfaces - if ( pStage->vertexLit ) { + if ( vertexLit ) { SetVertexLightingSettings( lightMode_t::VERTEX, rgbGen ); } // u_ColorModulate - gl_lightMappingShaderMaterial->SetUniform_ColorModulateColorGen( rgbGen, alphaGen, false, !pStage->fullbright ); + gl_lightMappingShaderMaterial->SetUniform_ColorModulateColorGen( rgbGen, alphaGen, false, !fullbright ); // u_Color gl_lightMappingShaderMaterial->SetUniform_Color( tess.svars.color ); @@ -218,7 +217,7 @@ void UpdateSurfaceDataLightMapping( uint32_t* materials, shaderStage_t* pStage ) gl_lightMappingShaderMaterial->WriteUniformsToBuffer( materials ); } -void UpdateSurfaceDataReflection( uint32_t* materials, shaderStage_t* pStage) { +void UpdateSurfaceDataReflection( uint32_t* materials, shaderStage_t* pStage, bool, bool, bool ) { shader_t* shader = pStage->shader; materials += pStage->bufferOffset; @@ -259,7 +258,7 @@ void UpdateSurfaceDataReflection( uint32_t* materials, shaderStage_t* pStage) { gl_reflectionShaderMaterial->WriteUniformsToBuffer( materials ); } -void UpdateSurfaceDataSkybox( uint32_t* materials, shaderStage_t* pStage ) { +void UpdateSurfaceDataSkybox( uint32_t* materials, shaderStage_t* pStage, bool, bool, bool ) { // shader_t* shader = pStage->shader; materials += pStage->bufferOffset; @@ -270,7 +269,7 @@ void UpdateSurfaceDataSkybox( uint32_t* materials, shaderStage_t* pStage ) { gl_skyboxShaderMaterial->WriteUniformsToBuffer( materials ); } -void UpdateSurfaceDataScreen( uint32_t* materials, shaderStage_t* pStage) { +void UpdateSurfaceDataScreen( uint32_t* materials, shaderStage_t* pStage, bool, bool, bool ) { // shader_t* shader = pStage->shader; materials += pStage->bufferOffset; @@ -283,7 +282,7 @@ void UpdateSurfaceDataScreen( uint32_t* materials, shaderStage_t* pStage) { gl_screenShaderMaterial->WriteUniformsToBuffer( materials ); } -void UpdateSurfaceDataHeatHaze( uint32_t* materials, shaderStage_t* pStage) { +void UpdateSurfaceDataHeatHaze( uint32_t* materials, shaderStage_t* pStage, bool, bool, bool ) { // shader_t* shader = pStage->shader; materials += pStage->bufferOffset; @@ -302,7 +301,7 @@ void UpdateSurfaceDataHeatHaze( uint32_t* materials, shaderStage_t* pStage) { gl_heatHazeShaderMaterial->WriteUniformsToBuffer( materials ); } -void UpdateSurfaceDataLiquid( uint32_t* materials, shaderStage_t* pStage) { +void UpdateSurfaceDataLiquid( uint32_t* materials, shaderStage_t* pStage, bool, bool, bool ) { // shader_t* shader = pStage->shader; materials += pStage->bufferOffset; @@ -354,7 +353,7 @@ void UpdateSurfaceDataLiquid( uint32_t* materials, shaderStage_t* pStage) { gl_liquidShaderMaterial->WriteUniformsToBuffer( materials ); } -void UpdateSurfaceDataFog( uint32_t* materials, shaderStage_t* pStage ) { +void UpdateSurfaceDataFog( uint32_t* materials, shaderStage_t* pStage, bool, bool, bool ) { // shader_t* shader = pStage->shader; materials += pStage->bufferOffset; @@ -489,15 +488,14 @@ void MaterialSystem::GenerateMaterialsBuffer( std::vector& stage uint32_t variants = 0; for ( int i = 0; i < Util::ordinal( ShaderStageVariant::ALL ) && variants < pStage->variantOffset; i++ ) { if ( pStage->variantOffsets[i] != -1 ) { - pStage->mayUseVertexOverbright = i & Util::ordinal( ShaderStageVariant::VERTEX_OVERBRIGHT ); - pStage->vertexLit = i & Util::ordinal( ShaderStageVariant::VERTEX_LIT ); - pStage->fullbright = i & Util::ordinal( ShaderStageVariant::FULLBRIGHT ); - pStage->currentOffset = pStage->variantOffsets[i]; + const bool mayUseVertexOverbright = i & Util::ordinal( ShaderStageVariant::VERTEX_OVERBRIGHT ); + const bool vertexLit = i & Util::ordinal( ShaderStageVariant::VERTEX_LIT ); + const bool fullbright = i & Util::ordinal( ShaderStageVariant::FULLBRIGHT ); const uint32_t variantOffset = pStage->variantOffsets[i] * pStage->paddedSize; pStage->bufferOffset += variantOffset; - pStage->surfaceDataUpdater( materialsData, pStage ); + pStage->surfaceDataUpdater( materialsData, pStage, mayUseVertexOverbright, vertexLit, fullbright ); pStage->bufferOffset -= variantOffset; variants++; @@ -1244,10 +1242,11 @@ void ProcessMaterialFog( Material* material, shaderStage_t* pStage, drawSurf_t* material->program = gl_fogQuake3ShaderMaterial->GetProgram( pStage->deformIndex ); } -void MaterialSystem::AddStage( drawSurf_t* drawSurf, shaderStage_t* pStage, uint32_t stage ) { - const int variant = ( pStage->mayUseVertexOverbright ? Util::ordinal( ShaderStageVariant::VERTEX_OVERBRIGHT ) : 0 ) - | ( pStage->vertexLit ? Util::ordinal( ShaderStageVariant::VERTEX_LIT ) : 0 ) - | ( pStage->fullbright ? Util::ordinal( ShaderStageVariant::FULLBRIGHT ) : 0 ); +void MaterialSystem::AddStage( drawSurf_t* drawSurf, shaderStage_t* pStage, uint32_t stage, + const bool mayUseVertexOverbright, const bool vertexLit, const bool fullbright ) { + const int variant = ( mayUseVertexOverbright ? Util::ordinal( ShaderStageVariant::VERTEX_OVERBRIGHT ) : 0 ) + | ( vertexLit ? Util::ordinal( ShaderStageVariant::VERTEX_LIT ) : 0 ) + | ( fullbright ? Util::ordinal( ShaderStageVariant::FULLBRIGHT ) : 0 ); if ( pStage->variantOffsets[variant] == -1 ) { pStage->variantOffsets[variant] = pStage->variantOffset; @@ -1353,9 +1352,9 @@ void MaterialSystem::ProcessStage( drawSurf_t* drawSurf, shaderStage_t* pStage, lightMode_t lightMode; deluxeMode_t deluxeMode; SetLightDeluxeMode( drawSurf, pStage->type, lightMode, deluxeMode ); - pStage->mayUseVertexOverbright = pStage->type == stageType_t::ST_COLORMAP && drawSurf->bspSurface && pStage->shaderBinder == BindShaderGeneric3D; - pStage->vertexLit = lightMode == lightMode_t::VERTEX && pStage->shaderBinder == BindShaderLightMapping; - pStage->fullbright = lightMode == lightMode_t::FULLBRIGHT && pStage->shaderBinder == BindShaderLightMapping; + const bool mayUseVertexOverbright = pStage->type == stageType_t::ST_COLORMAP && drawSurf->bspSurface && pStage->shaderBinder == BindShaderGeneric3D; + const bool vertexLit = lightMode == lightMode_t::VERTEX && pStage->shaderBinder == BindShaderLightMapping; + const bool fullbright = lightMode == lightMode_t::FULLBRIGHT && pStage->shaderBinder == BindShaderLightMapping; ComputeDynamics( pStage ); @@ -1424,7 +1423,7 @@ void MaterialSystem::ProcessStage( drawSurf_t* drawSurf, shaderStage_t* pStage, pStage->useMaterialSystem = true; pStage->initialized = true; - AddStage( drawSurf, pStage, stage ); + AddStage( drawSurf, pStage, stage, mayUseVertexOverbright, vertexLit, fullbright ); AddStageTextures( drawSurf, stage, &materials[previousMaterialID] ); if ( std::find( materials[previousMaterialID].drawSurfs.begin(), materials[previousMaterialID].drawSurfs.end(), drawSurf ) diff --git a/src/engine/renderer/Material.h b/src/engine/renderer/Material.h index 30d9721927..1265541fb5 100644 --- a/src/engine/renderer/Material.h +++ b/src/engine/renderer/Material.h @@ -333,7 +333,8 @@ class MaterialSystem { void GenerateDepthImages( const int width, const int height, imageParams_t imageParms ); void AddStageTextures( drawSurf_t* drawSurf, const uint32_t stage, Material* material ); - void AddStage( drawSurf_t* drawSurf, shaderStage_t* pStage, uint32_t stage ); + void AddStage( drawSurf_t* drawSurf, shaderStage_t* pStage, uint32_t stage, + const bool mayUseVertexOverbright, const bool vertexLit, const bool fullbright ); void ProcessStage( drawSurf_t* drawSurf, shaderStage_t* pStage, shader_t* shader, uint32_t* packIDs, uint32_t& stage, uint32_t& previousMaterialID ); void GenerateWorldMaterials(); @@ -407,16 +408,16 @@ extern GLSSBO debugSSBO; // Global extern MaterialSystem materialSystem; -void UpdateSurfaceDataNONE( uint32_t*, shaderStage_t* ); -void UpdateSurfaceDataNOP( uint32_t*, shaderStage_t* ); -void UpdateSurfaceDataGeneric3D( uint32_t* materials, shaderStage_t* pStage ); -void UpdateSurfaceDataLightMapping( uint32_t* materials, shaderStage_t* pStage ); -void UpdateSurfaceDataReflection( uint32_t* materials, shaderStage_t* pStage); -void UpdateSurfaceDataSkybox( uint32_t* materials, shaderStage_t* pStage ); -void UpdateSurfaceDataScreen( uint32_t* materials, shaderStage_t* pStage); -void UpdateSurfaceDataHeatHaze( uint32_t* materials, shaderStage_t* pStage); -void UpdateSurfaceDataLiquid( uint32_t* materials, shaderStage_t* pStage); -void UpdateSurfaceDataFog( uint32_t* materials, shaderStage_t* pStage ); +void UpdateSurfaceDataNONE( uint32_t*, shaderStage_t*, bool, bool, bool ); +void UpdateSurfaceDataNOP( uint32_t*, shaderStage_t*, bool, bool, bool ); +void UpdateSurfaceDataGeneric3D( uint32_t* materials, shaderStage_t* pStage, bool mayUseVertexOverbright, bool, bool ); +void UpdateSurfaceDataLightMapping( uint32_t* materials, shaderStage_t* pStage, bool, bool vertexLit, bool fullbright ); +void UpdateSurfaceDataReflection( uint32_t* materials, shaderStage_t* pStage, bool, bool, bool ); +void UpdateSurfaceDataSkybox( uint32_t* materials, shaderStage_t* pStage, bool, bool, bool ); +void UpdateSurfaceDataScreen( uint32_t* materials, shaderStage_t* pStage, bool, bool, bool ); +void UpdateSurfaceDataHeatHaze( uint32_t* materials, shaderStage_t* pStage, bool, bool, bool ); +void UpdateSurfaceDataLiquid( uint32_t* materials, shaderStage_t* pStage, bool, bool, bool ); +void UpdateSurfaceDataFog( uint32_t* materials, shaderStage_t* pStage, bool, bool, bool ); // void UpdateSurf( uint32) diff --git a/src/engine/renderer/tr_local.h b/src/engine/renderer/tr_local.h index c55836ed32..3e66feb2f4 100644 --- a/src/engine/renderer/tr_local.h +++ b/src/engine/renderer/tr_local.h @@ -1102,7 +1102,7 @@ enum class shaderProfilerRenderSubGroupsMode { struct drawSurf_t; using stageRenderer_t = void(*)(shaderStage_t *); - using surfaceDataUpdater_t = void(*)(uint32_t*, shaderStage_t*); + using surfaceDataUpdater_t = void(*)(uint32_t*, shaderStage_t*, bool, bool, bool); using stageShaderBinder_t = void(*)(Material*); using stageMaterialProcessor_t = void(*)(Material*, shaderStage_t*, drawSurf_t*); @@ -1225,11 +1225,6 @@ enum class shaderProfilerRenderSubGroupsMode { int variantOffsets[Util::ordinal( ShaderStageVariant::ALL )]; uint32_t variantOffset = 0; - uint32_t currentOffset = 0; - - bool mayUseVertexOverbright = false; - bool vertexLit = false; - bool fullbright = false; }; enum cullType_t : int From efe943039385a012591460f952f6317b3bae2161 Mon Sep 17 00:00:00 2001 From: VReaperV Date: Mon, 27 Jan 2025 04:37:33 +0300 Subject: [PATCH 16/27] Change ShaderStageVariant to an enum --- src/engine/renderer/Material.cpp | 14 +++++++------- src/engine/renderer/tr_local.h | 4 ++-- src/engine/renderer/tr_shader.cpp | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/engine/renderer/Material.cpp b/src/engine/renderer/Material.cpp index 14f2d53611..de5bedc318 100644 --- a/src/engine/renderer/Material.cpp +++ b/src/engine/renderer/Material.cpp @@ -486,11 +486,11 @@ void MaterialSystem::GenerateMaterialsBuffer( std::vector& stage /* Stage variants are essentially copies of the same stage with slightly different values that normally come from a drawSurf_t */ uint32_t variants = 0; - for ( int i = 0; i < Util::ordinal( ShaderStageVariant::ALL ) && variants < pStage->variantOffset; i++ ) { + for ( int i = 0; i < ShaderStageVariant::ALL && variants < pStage->variantOffset; i++ ) { if ( pStage->variantOffsets[i] != -1 ) { - const bool mayUseVertexOverbright = i & Util::ordinal( ShaderStageVariant::VERTEX_OVERBRIGHT ); - const bool vertexLit = i & Util::ordinal( ShaderStageVariant::VERTEX_LIT ); - const bool fullbright = i & Util::ordinal( ShaderStageVariant::FULLBRIGHT ); + const bool mayUseVertexOverbright = i & ShaderStageVariant::VERTEX_OVERBRIGHT; + const bool vertexLit = i & ShaderStageVariant::VERTEX_LIT; + const bool fullbright = i & ShaderStageVariant::FULLBRIGHT; const uint32_t variantOffset = pStage->variantOffsets[i] * pStage->paddedSize; pStage->bufferOffset += variantOffset; @@ -1244,9 +1244,9 @@ void ProcessMaterialFog( Material* material, shaderStage_t* pStage, drawSurf_t* void MaterialSystem::AddStage( drawSurf_t* drawSurf, shaderStage_t* pStage, uint32_t stage, const bool mayUseVertexOverbright, const bool vertexLit, const bool fullbright ) { - const int variant = ( mayUseVertexOverbright ? Util::ordinal( ShaderStageVariant::VERTEX_OVERBRIGHT ) : 0 ) - | ( vertexLit ? Util::ordinal( ShaderStageVariant::VERTEX_LIT ) : 0 ) - | ( fullbright ? Util::ordinal( ShaderStageVariant::FULLBRIGHT ) : 0 ); + const int variant = ( mayUseVertexOverbright ? ShaderStageVariant::VERTEX_OVERBRIGHT : 0 ) + | ( vertexLit ? ShaderStageVariant::VERTEX_LIT : 0 ) + | ( fullbright ? ShaderStageVariant::FULLBRIGHT : 0 ); if ( pStage->variantOffsets[variant] == -1 ) { pStage->variantOffsets[variant] = pStage->variantOffset; diff --git a/src/engine/renderer/tr_local.h b/src/engine/renderer/tr_local.h index 3e66feb2f4..201f142a0a 100644 --- a/src/engine/renderer/tr_local.h +++ b/src/engine/renderer/tr_local.h @@ -1106,7 +1106,7 @@ enum class shaderProfilerRenderSubGroupsMode { using stageShaderBinder_t = void(*)(Material*); using stageMaterialProcessor_t = void(*)(Material*, shaderStage_t*, drawSurf_t*); - enum class ShaderStageVariant { + enum ShaderStageVariant { VERTEX_OVERBRIGHT = 1, VERTEX_LIT = BIT( 1 ), FULLBRIGHT = BIT( 2 ), @@ -1223,7 +1223,7 @@ enum class shaderProfilerRenderSubGroupsMode { bool dynamic = false; bool colorDynamic = false; - int variantOffsets[Util::ordinal( ShaderStageVariant::ALL )]; + int variantOffsets[ShaderStageVariant::ALL]; uint32_t variantOffset = 0; }; diff --git a/src/engine/renderer/tr_shader.cpp b/src/engine/renderer/tr_shader.cpp index 81a45342c6..4f6ea8e370 100644 --- a/src/engine/renderer/tr_shader.cpp +++ b/src/engine/renderer/tr_shader.cpp @@ -5240,7 +5240,7 @@ static void FinishStages() break; } - memset( stage->variantOffsets, -1, Util::ordinal( ShaderStageVariant::ALL ) * sizeof( int ) ); + memset( stage->variantOffsets, -1, ShaderStageVariant::ALL * sizeof( int ) ); } GroupActiveStages(); From aea7820209d2149da24406ee7197a8df21b2f631 Mon Sep 17 00:00:00 2001 From: VReaperV Date: Fri, 17 Jan 2025 21:12:21 +0300 Subject: [PATCH 17/27] Fix glsl_restart with material system --- src/engine/renderer/Material.cpp | 36 ++++++++++++++++++++++++++++ src/engine/renderer/Material.h | 3 +++ src/engine/renderer/tr_init.cpp | 13 ++++++++++ src/engine/renderer/tr_vbo.cpp | 41 ++++---------------------------- 4 files changed, 56 insertions(+), 37 deletions(-) diff --git a/src/engine/renderer/Material.cpp b/src/engine/renderer/Material.cpp index de5bedc318..90d49b9989 100644 --- a/src/engine/renderer/Material.cpp +++ b/src/engine/renderer/Material.cpp @@ -1876,6 +1876,42 @@ void MaterialSystem::GeneratePortalBoundingSpheres() { portalSurfacesTmp.clear(); } +void MaterialSystem::InitGLBuffers() { + materialsUBO.GenBuffer(); + texDataBuffer.GenBuffer(); + lightMapDataUBO.GenBuffer(); + + surfaceDescriptorsSSBO.GenBuffer(); + surfaceCommandsSSBO.GenBuffer(); + culledCommandsBuffer.GenBuffer(); + surfaceBatchesUBO.GenBuffer(); + atomicCommandCountersBuffer.GenBuffer(); + + portalSurfacesSSBO.GenBuffer(); + + if ( r_materialDebug.Get() ) { + debugSSBO.GenBuffer(); + } +} + +void MaterialSystem::FreeGLBuffers() { + materialsUBO.DelBuffer(); + texDataBuffer.DelBuffer(); + lightMapDataUBO.DelBuffer(); + + surfaceDescriptorsSSBO.DelBuffer(); + surfaceCommandsSSBO.DelBuffer(); + culledCommandsBuffer.DelBuffer(); + surfaceBatchesUBO.DelBuffer(); + atomicCommandCountersBuffer.DelBuffer(); + + portalSurfacesSSBO.DelBuffer(); + + if ( r_materialDebug.Get() ) { + debugSSBO.DelBuffer(); + } +} + void MaterialSystem::Free() { generatedWorldCommandBuffer = false; diff --git a/src/engine/renderer/Material.h b/src/engine/renderer/Material.h index 1265541fb5..0343b2ce3f 100644 --- a/src/engine/renderer/Material.h +++ b/src/engine/renderer/Material.h @@ -332,6 +332,9 @@ class MaterialSystem { void GenerateDepthImages( const int width, const int height, imageParams_t imageParms ); + void InitGLBuffers(); + void FreeGLBuffers(); + void AddStageTextures( drawSurf_t* drawSurf, const uint32_t stage, Material* material ); void AddStage( drawSurf_t* drawSurf, shaderStage_t* pStage, uint32_t stage, const bool mayUseVertexOverbright, const bool vertexLit, const bool fullbright ); diff --git a/src/engine/renderer/tr_init.cpp b/src/engine/renderer/tr_init.cpp index 1354bbc132..de3d341e68 100644 --- a/src/engine/renderer/tr_init.cpp +++ b/src/engine/renderer/tr_init.cpp @@ -1118,6 +1118,19 @@ ScreenshotCmd screenshotPNGRegistration("screenshotPNG", ssFormat_t::SSF_PNG, "p stage->deformIndex = deformIndex; } } + + if ( glConfig2.usingMaterialSystem ) { + /* GLSL shaders linked to materials will be invalidated by glsl_restart, + so regenerate all the material stuff here */ + const uint8_t maxStages = materialSystem.maxStages; + materialSystem.Free(); + materialSystem.FreeGLBuffers(); + + materialSystem.InitGLBuffers(); + materialSystem.maxStages = maxStages; + + materialSystem.GenerateWorldMaterials(); + } } }; static GlslRestartCmd glslRestartCmdRegistration; diff --git a/src/engine/renderer/tr_vbo.cpp b/src/engine/renderer/tr_vbo.cpp index e453a62d7e..85bc83e700 100644 --- a/src/engine/renderer/tr_vbo.cpp +++ b/src/engine/renderer/tr_vbo.cpp @@ -726,27 +726,6 @@ static void R_InitLightUBO() glBindBuffer( GL_UNIFORM_BUFFER, 0 ); } } - -static void R_InitMaterialBuffers() { - if( glConfig2.usingMaterialSystem ) { - materialsUBO.GenBuffer(); - texDataBuffer.GenBuffer(); - lightMapDataUBO.GenBuffer(); - - surfaceDescriptorsSSBO.GenBuffer(); - surfaceCommandsSSBO.GenBuffer(); - culledCommandsBuffer.GenBuffer(); - surfaceBatchesUBO.GenBuffer(); - atomicCommandCountersBuffer.GenBuffer(); - - portalSurfacesSSBO.GenBuffer(); - - if ( r_materialDebug.Get() ) { - debugSSBO.GenBuffer(); - } - } -} - /* ============ R_InitVBOs @@ -790,7 +769,9 @@ void R_InitVBOs() R_InitLightUBO(); - R_InitMaterialBuffers(); + if ( glConfig2.usingMaterialSystem ) { + materialSystem.InitGLBuffers(); + } GL_CheckErrors(); } @@ -861,21 +842,7 @@ void R_ShutdownVBOs() } if ( glConfig2.usingMaterialSystem ) { - materialsUBO.DelBuffer(); - texDataBuffer.DelBuffer(); - lightMapDataUBO.DelBuffer(); - - surfaceDescriptorsSSBO.DelBuffer(); - surfaceCommandsSSBO.DelBuffer(); - culledCommandsBuffer.DelBuffer(); - surfaceBatchesUBO.DelBuffer(); - atomicCommandCountersBuffer.DelBuffer(); - - portalSurfacesSSBO.DelBuffer(); - - if ( r_materialDebug.Get() ) { - debugSSBO.DelBuffer(); - } + materialSystem.FreeGLBuffers(); } tess.verts = tess.vertsBuffer = nullptr; From 5edf14d99825e3bb833e1b84d3175cad91c1aaff Mon Sep 17 00:00:00 2001 From: VReaperV Date: Sun, 12 Jan 2025 13:40:53 +0300 Subject: [PATCH 18/27] Clean-up GLBuffer interface, use DSA --- src/engine/renderer/Material.cpp | 31 ++-- src/engine/renderer/gl_shader.cpp | 4 +- src/engine/renderer/gl_shader.h | 248 +++++++----------------------- src/engine/renderer/tr_public.h | 1 + src/engine/sys/sdl_glimp.cpp | 9 +- 5 files changed, 77 insertions(+), 216 deletions(-) diff --git a/src/engine/renderer/Material.cpp b/src/engine/renderer/Material.cpp index 90d49b9989..0f94cc6cc2 100644 --- a/src/engine/renderer/Material.cpp +++ b/src/engine/renderer/Material.cpp @@ -574,9 +574,8 @@ void MaterialSystem::GenerateWorldCommandBuffer() { texDataBufferType = glConfig2.maxUniformBlockSize >= MIN_MATERIAL_UBO_SIZE ? GL_UNIFORM_BUFFER : GL_SHADER_STORAGE_BUFFER; - texDataBuffer.BindBuffer( texDataBufferType ); - texDataBuffer.BufferStorage( texDataBufferType, ( texData.size() + dynamicTexData.size() ) * TEX_BUNDLE_SIZE, 1, nullptr ); - texDataBuffer.MapAll( texDataBufferType ); + texDataBuffer.BufferStorage( ( texData.size() + dynamicTexData.size() ) * TEX_BUNDLE_SIZE, 1, nullptr ); + texDataBuffer.MapAll(); TexBundle* textureBundles = ( TexBundle* ) texDataBuffer.GetData(); memset( textureBundles, 0, ( texData.size() + dynamicTexData.size() ) * TEX_BUNDLE_SIZE * sizeof( uint32_t ) ); @@ -589,11 +588,9 @@ void MaterialSystem::GenerateWorldCommandBuffer() { dynamicTexDataOffset = texData.size() * TEX_BUNDLE_SIZE; dynamicTexDataSize = dynamicTexData.size() * TEX_BUNDLE_SIZE; - texDataBuffer.FlushAll( texDataBufferType ); + texDataBuffer.FlushAll(); texDataBuffer.UnmapBuffer(); - texDataBuffer.UnBindBuffer( texDataBufferType ); - lightMapDataUBO.BindBuffer(); lightMapDataUBO.BufferStorage( MAX_LIGHTMAPS * LIGHTMAP_SIZE, 1, nullptr ); lightMapDataUBO.MapAll(); uint64_t* lightmapData = ( uint64_t* ) lightMapDataUBO.GetData(); @@ -633,7 +630,6 @@ void MaterialSystem::GenerateWorldCommandBuffer() { lightMapDataUBO.FlushAll(); lightMapDataUBO.UnmapBuffer(); - lightMapDataUBO.UnBindBuffer(); surfaceCommandsCount = totalBatchCount * SURFACE_COMMANDS_PER_BATCH; @@ -643,13 +639,11 @@ void MaterialSystem::GenerateWorldCommandBuffer() { SurfaceCommand* surfaceCommands = ( SurfaceCommand* ) surfaceCommandsSSBO.GetData(); memset( surfaceCommands, 0, surfaceCommandsCount * sizeof( SurfaceCommand ) * MAX_VIEWFRAMES ); - culledCommandsBuffer.BindBuffer( GL_SHADER_STORAGE_BUFFER ); - culledCommandsBuffer.BufferStorage( GL_SHADER_STORAGE_BUFFER, - surfaceCommandsCount * INDIRECT_COMMAND_SIZE * MAX_VIEWFRAMES, 1, nullptr ); - culledCommandsBuffer.MapAll( GL_SHADER_STORAGE_BUFFER ); + culledCommandsBuffer.BufferStorage( surfaceCommandsCount * INDIRECT_COMMAND_SIZE * MAX_VIEWFRAMES, 1, nullptr ); + culledCommandsBuffer.MapAll(); GLIndirectBuffer::GLIndirectCommand* culledCommands = ( GLIndirectBuffer::GLIndirectCommand* ) culledCommandsBuffer.GetData(); memset( culledCommands, 0, surfaceCommandsCount * sizeof( GLIndirectBuffer::GLIndirectCommand ) * MAX_VIEWFRAMES ); - culledCommandsBuffer.FlushAll( GL_SHADER_STORAGE_BUFFER ); + culledCommandsBuffer.FlushAll(); surfaceBatchesUBO.BindBuffer(); glBufferData( GL_UNIFORM_BUFFER, MAX_SURFACE_COMMAND_BATCHES * sizeof( SurfaceCommandBatch ), nullptr, GL_STATIC_DRAW ); @@ -675,10 +669,8 @@ void MaterialSystem::GenerateWorldCommandBuffer() { } } - atomicCommandCountersBuffer.BindBuffer( GL_ATOMIC_COUNTER_BUFFER ); - atomicCommandCountersBuffer.BufferStorage( GL_ATOMIC_COUNTER_BUFFER, - MAX_COMMAND_COUNTERS * MAX_VIEWS, MAX_FRAMES, nullptr ); - atomicCommandCountersBuffer.MapAll( GL_ATOMIC_COUNTER_BUFFER ); + atomicCommandCountersBuffer.BufferStorage( MAX_COMMAND_COUNTERS * MAX_VIEWS, MAX_FRAMES, nullptr ); + atomicCommandCountersBuffer.MapAll(); uint32_t* atomicCommandCounters = ( uint32_t* ) atomicCommandCountersBuffer.GetData(); memset( atomicCommandCounters, 0, MAX_COMMAND_COUNTERS * MAX_VIEWFRAMES * sizeof( uint32_t ) ); @@ -786,19 +778,14 @@ void MaterialSystem::GenerateWorldCommandBuffer() { memcpy( surfaceCommands + surfaceCommandsCount * i, surfaceCommands, surfaceCommandsCount * sizeof( SurfaceCommand ) ); } - surfaceDescriptorsSSBO.BindBuffer(); surfaceDescriptorsSSBO.UnmapBuffer(); - surfaceCommandsSSBO.BindBuffer(); surfaceCommandsSSBO.UnmapBuffer(); - culledCommandsBuffer.BindBuffer( GL_SHADER_STORAGE_BUFFER ); culledCommandsBuffer.UnmapBuffer(); - atomicCommandCountersBuffer.BindBuffer( GL_ATOMIC_COUNTER_BUFFER); atomicCommandCountersBuffer.UnmapBuffer(); - surfaceBatchesUBO.BindBuffer(); surfaceBatchesUBO.UnmapBuffer(); GL_CheckErrors(); @@ -1619,7 +1606,7 @@ void MaterialSystem::UpdateDynamicSurfaces() { texDataBuffer.BindBuffer( texDataBufferType ); GL_CheckErrors(); TexBundle* textureBundles = - ( TexBundle* ) texDataBuffer.MapBufferRange( texDataBufferType, dynamicTexDataOffset, dynamicTexDataSize ); + ( TexBundle* ) texDataBuffer.MapBufferRange( dynamicTexDataOffset, dynamicTexDataSize ); GL_CheckErrors(); GenerateTexturesBuffer( dynamicTexData, textureBundles ); diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index 785662be76..d4569fe799 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -1393,7 +1393,9 @@ std::string GLShaderManager::ShaderPostProcess( GLShader *shader, const std::str " uvec2 u_LightMap;\n" " uvec2 u_DeluxeMap;\n" "};\n\n" - "layout(std140, binding = 8) uniform lightMapDataUBO {\n" + "layout(std140, binding = " + + std::to_string( Util::ordinal( BufferBind::LIGHTMAP_DATA ) ) + + ") uniform lightMapDataUBO {\n" " LightMapData lightMapData[256];\n" "};\n\n" "#define u_LightMap_initial lightMapData[( baseInstance >> 24 ) & 0xFF].u_LightMap\n" diff --git a/src/engine/renderer/gl_shader.h b/src/engine/renderer/gl_shader.h index 73dad8d783..b11d951be9 100644 --- a/src/engine/renderer/gl_shader.h +++ b/src/engine/renderer/gl_shader.h @@ -1370,43 +1370,52 @@ class GLUniformBlock class GLBuffer { public: - std::string _name; - const GLuint _bindingPoint; - const GLbitfield _flags; - const GLbitfield _mapFlags; + std::string name; const GLuint64 SYNC_TIMEOUT = 10000000000; // 10 seconds - GLBuffer( const char* name, const GLuint bindingPoint, const GLbitfield flags, const GLbitfield mapFlags ) : - _name( name ), - _bindingPoint( bindingPoint ), - _flags( flags ), - _mapFlags( mapFlags ) { + GLBuffer( const char* newName, const GLuint newBindingPoint, const GLbitfield newFlags, const GLbitfield newMapFlags ) : + name( newName ), + internalTarget( 0 ), + internalBindingPoint( newBindingPoint ), + flags( newFlags ), + mapFlags( newMapFlags ) { } - const char* GetName() { - return _name.c_str(); + GLBuffer( const char* newName, const GLenum newTarget, const GLuint newBindingPoint, + const GLbitfield newFlags, const GLbitfield newMapFlags ) : + name( newName ), + internalTarget( newTarget ), + internalBindingPoint( newBindingPoint ), + flags( newFlags ), + mapFlags( newMapFlags ) { } - void BindBufferBase( const GLenum target ) { - glBindBufferBase( target, _bindingPoint, handle ); + void BindBufferBase( GLenum target = 0, GLuint bindingPoint = 0 ) { + target = target ? target : internalTarget; + bindingPoint = bindingPoint ? bindingPoint : internalBindingPoint; + glBindBufferBase( target, bindingPoint, id ); } - void UnBindBufferBase( const GLenum target ) { - glBindBufferBase( target, _bindingPoint, 0 ); + void UnBindBufferBase( GLenum target = 0, GLuint bindingPoint = 0 ) { + target = target ? target : internalTarget; + bindingPoint = bindingPoint ? bindingPoint : internalBindingPoint; + glBindBufferBase( target, bindingPoint, 0 ); } - void BindBuffer( const GLenum target ) { - glBindBuffer( target, handle ); + void BindBuffer( GLenum target = 0 ) { + target = target ? target : internalTarget; + glBindBuffer( target, id ); } - void UnBindBuffer( const GLenum target ) { + void UnBindBuffer( GLenum target = 0 ) { + target = target ? target : internalTarget; glBindBuffer( target, 0 ); } - void BufferStorage( const GLenum target, const GLsizeiptr newAreaSize, const GLsizeiptr areaCount, const void* data ) { + void BufferStorage( const GLsizeiptr newAreaSize, const GLsizeiptr areaCount, const void* data ) { areaSize = newAreaSize; maxAreas = areaCount; - glBufferStorage( target, areaSize * areaCount * sizeof(uint32_t), data, _flags ); + glNamedBufferStorage( id, areaSize * areaCount * sizeof( uint32_t ), data, flags ); syncs.resize( areaCount ); } @@ -1418,18 +1427,17 @@ class GLBuffer { } } - void MapAll( const GLenum target ) { + void MapAll() { if ( !mapped ) { mapped = true; - mappedTarget = target; - data = ( uint32_t* ) glMapBufferRange( target, 0, areaSize * maxAreas * sizeof( uint32_t ), _flags | _mapFlags ); + data = ( uint32_t* ) glMapNamedBufferRange( id, 0, areaSize * maxAreas * sizeof( uint32_t ), flags | mapFlags ); } } uint32_t* GetCurrentAreaData() { if ( syncs[area] != nullptr ) { if ( glClientWaitSync( syncs[area], GL_SYNC_FLUSH_COMMANDS_BIT, SYNC_TIMEOUT ) == GL_TIMEOUT_EXPIRED ) { - Sys::Drop( "Failed buffer %s area %u sync", _name, area ); + Sys::Drop( "Failed buffer %s area %u sync", name, area ); } glDeleteSync( syncs[area] ); } @@ -1441,33 +1449,24 @@ class GLBuffer { return data; } - void FlushCurrentArea( GLenum target ) { - glFlushMappedBufferRange( target, area * areaSize * sizeof( uint32_t ), areaSize * sizeof( uint32_t ) ); + void FlushCurrentArea() { + glFlushMappedNamedBufferRange( id, area * areaSize * sizeof( uint32_t ), areaSize * sizeof( uint32_t ) ); } - void FlushAll( GLenum target ) { - glFlushMappedBufferRange( target, 0, maxAreas * areaSize * sizeof( uint32_t ) ); + void FlushAll() { + glFlushMappedNamedBufferRange( id, 0, maxAreas * areaSize * sizeof( uint32_t ) ); } - uint32_t* MapBufferRange( const GLenum target, const GLuint count ) { - if ( !mapped ) { - mapped = true; - mappedTarget = target; - data = ( uint32_t* ) glMapBufferRange( target, - 0, count * sizeof( uint32_t ), - _flags | _mapFlags ); - } - - return data; + uint32_t* MapBufferRange( const GLuint count ) { + return MapBufferRange( 0, count ); } - uint32_t* MapBufferRange( const GLenum target, const GLuint offset, const GLuint count ) { + uint32_t* MapBufferRange( const GLuint offset, const GLuint count ) { if ( !mapped ) { mapped = true; - mappedTarget = target; - data = ( uint32_t* ) glMapBufferRange( target, + data = ( uint32_t* ) glMapNamedBufferRange( id, offset * sizeof( uint32_t ), count * sizeof( uint32_t ), - _flags | _mapFlags ); + flags | mapFlags ); } return data; @@ -1476,22 +1475,28 @@ class GLBuffer { void UnmapBuffer() { if ( mapped ) { mapped = false; - glUnmapBuffer( mappedTarget ); + glUnmapNamedBuffer( id ); } } void GenBuffer() { - glGenBuffers( 1, &handle ); + glCreateBuffers( 1, &id ); } void DelBuffer() { - glDeleteBuffers( 1, &handle ); + glDeleteBuffers( 1, &id ); } private: - GLenum mappedTarget; - GLuint handle; + const GLenum internalTarget; + const GLuint internalBindingPoint; + + GLuint id; + bool mapped = false; + const GLbitfield flags; + const GLbitfield mapFlags; + std::vector syncs; GLsizeiptr area = 0; GLsizeiptr areaSize = 0; @@ -1502,158 +1507,26 @@ class GLBuffer { class GLSSBO : public GLBuffer { public: GLSSBO( const char* name, const GLuint bindingPoint, const GLbitfield flags, const GLbitfield mapFlags ) : - GLBuffer( name, bindingPoint, flags, mapFlags ) { - } - - public: - const char* GetName() { - return _name.c_str(); - } - - void BindBufferBase() { - GLBuffer::BindBufferBase( GL_SHADER_STORAGE_BUFFER ); - } - - void UnBindBufferBase() { - GLBuffer::UnBindBufferBase( GL_SHADER_STORAGE_BUFFER ); - } - - void BindBuffer() { - GLBuffer::BindBuffer( GL_SHADER_STORAGE_BUFFER ); - } - - void UnBindBuffer() { - GLBuffer::UnBindBuffer( GL_SHADER_STORAGE_BUFFER ); - } - - void BufferStorage( const GLsizeiptr areaSize, const GLsizeiptr areaCount, const void* data ) { - GLBuffer::BufferStorage( GL_SHADER_STORAGE_BUFFER, areaSize, areaCount, data ); - } - - void MapAll() { - GLBuffer::MapAll( GL_SHADER_STORAGE_BUFFER ); - } - - void FlushCurrentArea() { - GLBuffer::FlushCurrentArea( GL_SHADER_STORAGE_BUFFER ); - } - - void FlushAll() { - GLBuffer::FlushAll( GL_SHADER_STORAGE_BUFFER ); - } - - uint32_t* MapBufferRange( const GLsizeiptr count ) { - return GLBuffer::MapBufferRange( GL_SHADER_STORAGE_BUFFER, count ); - } - - uint32_t* MapBufferRange( const GLsizeiptr offset, const GLsizeiptr count ) { - return GLBuffer::MapBufferRange( GL_SHADER_STORAGE_BUFFER, offset, count ); + GLBuffer( name, GL_SHADER_STORAGE_BUFFER, bindingPoint, flags, mapFlags ) { } }; class GLUBO : public GLBuffer { public: GLUBO( const char* name, const GLsizeiptr bindingPoint, const GLbitfield flags, const GLbitfield mapFlags ) : - GLBuffer( name, bindingPoint, flags, mapFlags ) { - } - - public: - const char* GetName() { - return _name.c_str(); - } - - void BindBufferBase() { - GLBuffer::BindBufferBase( GL_UNIFORM_BUFFER ); - } - - void UnBindBufferBase() { - GLBuffer::UnBindBufferBase( GL_UNIFORM_BUFFER ); - } - - void BindBuffer() { - GLBuffer::BindBuffer( GL_UNIFORM_BUFFER ); - } - - void UnBindBuffer() { - GLBuffer::UnBindBuffer( GL_UNIFORM_BUFFER ); - } - - void BufferStorage( const GLsizeiptr areaSize, const GLsizeiptr areaCount, const void* data ) { - GLBuffer::BufferStorage( GL_UNIFORM_BUFFER, areaSize, areaCount, data ); - } - - void MapAll() { - GLBuffer::MapAll( GL_UNIFORM_BUFFER ); - } - - void FlushCurrentArea() { - GLBuffer::FlushCurrentArea( GL_UNIFORM_BUFFER ); - } - - void FlushAll() { - GLBuffer::FlushAll( GL_UNIFORM_BUFFER ); - } - - uint32_t* MapBufferRange( const GLsizeiptr count ) { - return GLBuffer::MapBufferRange( GL_UNIFORM_BUFFER, count ); - } - - uint32_t* MapBufferRange( const GLsizeiptr offset, const GLsizeiptr count ) { - return GLBuffer::MapBufferRange( GL_UNIFORM_BUFFER, offset, count ); + GLBuffer( name, GL_UNIFORM_BUFFER, bindingPoint, flags, mapFlags ) { } }; class GLAtomicCounterBuffer : public GLBuffer { public: GLAtomicCounterBuffer( const char* name, const GLsizeiptr bindingPoint, const GLbitfield flags, const GLbitfield mapFlags ) : - GLBuffer( name, bindingPoint, flags, mapFlags ) { - } - - public: - const char* GetName() { - return _name.c_str(); - } - - void BindBufferBase() { - GLBuffer::BindBufferBase( GL_ATOMIC_COUNTER_BUFFER ); - } - - void UnBindBufferBase() { - GLBuffer::UnBindBufferBase( GL_ATOMIC_COUNTER_BUFFER ); - } - - void BindBuffer() { - GLBuffer::BindBuffer( GL_ATOMIC_COUNTER_BUFFER ); - } - - void BufferStorage( const GLsizeiptr areaSize, const GLsizeiptr areaCount, const void* data ) { - GLBuffer::BufferStorage( GL_ATOMIC_COUNTER_BUFFER, areaSize, areaCount, data ); - } - - void MapAll() { - GLBuffer::MapAll( GL_ATOMIC_COUNTER_BUFFER ); - } - - void FlushCurrentArea() { - GLBuffer::FlushCurrentArea( GL_ATOMIC_COUNTER_BUFFER ); - } - - void FlushAll() { - GLBuffer::FlushAll( GL_ATOMIC_COUNTER_BUFFER ); - } - - uint32_t* MapBufferRange( const GLsizeiptr count ) { - return GLBuffer::MapBufferRange( GL_ATOMIC_COUNTER_BUFFER, count ); - } - - uint32_t* MapBufferRange( const GLsizeiptr offset, const GLsizeiptr count ) { - return GLBuffer::MapBufferRange( GL_ATOMIC_COUNTER_BUFFER, offset, count ); + GLBuffer( name, GL_ATOMIC_COUNTER_BUFFER, bindingPoint, flags, mapFlags ) { } }; class GLIndirectBuffer { public: - struct GLIndirectCommand { GLuint count; GLuint instanceCount; @@ -1662,16 +1535,7 @@ class GLIndirectBuffer { GLuint baseInstance; }; - std::string _name; - - GLIndirectBuffer( const char* name ) : - _name( name ) { - } - - public: - - const char* GetName() { - return _name.c_str(); + GLIndirectBuffer( const char* name ) { } void BindBuffer() { diff --git a/src/engine/renderer/tr_public.h b/src/engine/renderer/tr_public.h index b5b320a3d9..5f4a253aaf 100644 --- a/src/engine/renderer/tr_public.h +++ b/src/engine/renderer/tr_public.h @@ -102,6 +102,7 @@ struct glconfig2_t bool indirectParametersAvailable; bool shadingLanguage420PackAvailable; bool explicitUniformLocationAvailable; + bool directStateAccessAvailable; bool shaderImageLoadStoreAvailable; bool shaderAtomicCountersAvailable; bool shaderAtomicCounterOpsAvailable; diff --git a/src/engine/sys/sdl_glimp.cpp b/src/engine/sys/sdl_glimp.cpp index a6cf29903a..9b9d5296a1 100644 --- a/src/engine/sys/sdl_glimp.cpp +++ b/src/engine/sys/sdl_glimp.cpp @@ -70,6 +70,8 @@ static Cvar::Cvar r_arb_buffer_storage( "r_arb_buffer_storage", "Use GL_ARB_buffer_storage if available", Cvar::NONE, true ); static Cvar::Cvar r_arb_compute_shader( "r_arb_compute_shader", "Use GL_ARB_compute_shader if available", Cvar::NONE, true ); +static Cvar::Cvar r_arb_direct_state_access( "r_arb_direct_state_access", + "Use GL_ARB_direct_state_access if available", Cvar::NONE, true ); static Cvar::Cvar r_arb_framebuffer_object( "r_arb_framebuffer_object", "Use GL_ARB_framebuffer_object if available", Cvar::NONE, true ); static Cvar::Cvar r_arb_explicit_uniform_location( "r_arb_explicit_uniform_location", @@ -1975,6 +1977,7 @@ static void GLimp_InitExtensions() Cvar::Latch( r_arb_bindless_texture ); Cvar::Latch( r_arb_buffer_storage ); Cvar::Latch( r_arb_compute_shader ); + Cvar::Latch( r_arb_direct_state_access ); Cvar::Latch( r_arb_explicit_uniform_location ); Cvar::Latch( r_arb_framebuffer_object ); Cvar::Latch( r_arb_gpu_shader5 ); @@ -2544,11 +2547,15 @@ static void GLimp_InitExtensions() // made required in OpenGL 4.6 glConfig2.indirectParametersAvailable = LOAD_EXTENSION_WITH_TEST( ExtFlag_NONE, ARB_indirect_parameters, r_arb_indirect_parameters.Get() ); + // made required in OpenGL 4.5 + glConfig2.directStateAccessAvailable = LOAD_EXTENSION_WITH_TEST( ExtFlag_NONE, ARB_direct_state_access, r_arb_direct_state_access.Get() ); + glConfig2.materialSystemAvailable = glConfig2.shaderDrawParametersAvailable && glConfig2.SSBOAvailable && glConfig2.multiDrawIndirectAvailable && glConfig2.bindlessTexturesAvailable && glConfig2.computeShaderAvailable && glConfig2.shadingLanguage420PackAvailable && glConfig2.explicitUniformLocationAvailable && glConfig2.shaderImageLoadStoreAvailable - && glConfig2.shaderAtomicCountersAvailable && glConfig2.indirectParametersAvailable; + && glConfig2.shaderAtomicCountersAvailable && glConfig2.indirectParametersAvailable + && glConfig2.directStateAccessAvailable; // This requires GLEW 2.2+, so skip if it's a lower version #ifdef GL_KHR_shader_subgroup From 2a2eac690aab162e7b0fd8b5f2b90ddad3715e05 Mon Sep 17 00:00:00 2001 From: VReaperV Date: Sat, 18 Jan 2025 01:35:42 +0300 Subject: [PATCH 19/27] Add GLBuffer::BufferData, minor clean-up --- src/engine/renderer/Material.cpp | 37 +++++++++++--------------------- src/engine/renderer/gl_shader.h | 5 +++++ 2 files changed, 18 insertions(+), 24 deletions(-) diff --git a/src/engine/renderer/Material.cpp b/src/engine/renderer/Material.cpp index 0f94cc6cc2..a91ade31c3 100644 --- a/src/engine/renderer/Material.cpp +++ b/src/engine/renderer/Material.cpp @@ -387,8 +387,6 @@ void UpdateSurfaceDataFog( uint32_t* materials, shaderStage_t* pStage, bool, boo void MaterialSystem::GenerateWorldMaterialsBuffer() { Log::Debug( "Generating materials buffer" ); - materialsUBO.BindBuffer(); - // Sort by padded size to avoid extra padding std::sort( materialStages.begin(), materialStages.end(), [&]( const shaderStage_t* lhs, const shaderStage_t* rhs ) { @@ -431,7 +429,7 @@ void MaterialSystem::GenerateWorldMaterialsBuffer() { totalStageSize = offset; // 4 bytes per component - glBufferData( GL_UNIFORM_BUFFER, offset * sizeof( uint32_t ), nullptr, GL_DYNAMIC_DRAW ); + materialsUBO.BufferData( offset, nullptr, GL_DYNAMIC_DRAW ); uint32_t* materialsData = materialsUBO.MapBufferRange( offset ); GenerateMaterialsBuffer( materialStages, offset, materialsData ); @@ -565,11 +563,9 @@ void MaterialSystem::GenerateWorldCommandBuffer() { Log::Debug( "Total batch count: %u", totalBatchCount ); - surfaceDescriptorsSSBO.BindBuffer(); surfaceDescriptorsCount = totalDrawSurfs; descriptorSize = BOUNDING_SPHERE_SIZE + maxStages; - glBufferData( GL_SHADER_STORAGE_BUFFER, surfaceDescriptorsCount * descriptorSize * sizeof( uint32_t ), - nullptr, GL_STATIC_DRAW ); + surfaceDescriptorsSSBO.BufferData( surfaceDescriptorsCount * descriptorSize, nullptr, GL_STATIC_DRAW ); uint32_t* surfaceDescriptors = surfaceDescriptorsSSBO.MapBufferRange( surfaceDescriptorsCount * descriptorSize ); texDataBufferType = glConfig2.maxUniformBlockSize >= MIN_MATERIAL_UBO_SIZE ? GL_UNIFORM_BUFFER : GL_SHADER_STORAGE_BUFFER; @@ -593,20 +589,20 @@ void MaterialSystem::GenerateWorldCommandBuffer() { lightMapDataUBO.BufferStorage( MAX_LIGHTMAPS * LIGHTMAP_SIZE, 1, nullptr ); lightMapDataUBO.MapAll(); - uint64_t* lightmapData = ( uint64_t* ) lightMapDataUBO.GetData(); - memset( lightmapData, 0, MAX_LIGHTMAPS * LIGHTMAP_SIZE * sizeof( uint32_t ) ); + uint64_t* lightMapData = ( uint64_t* ) lightMapDataUBO.GetData(); + memset( lightMapData, 0, MAX_LIGHTMAPS * LIGHTMAP_SIZE * sizeof( uint32_t ) ); for ( uint32_t i = 0; i < tr.lightmaps.size(); i++ ) { if ( !tr.lightmaps[i]->texture->hasBindlessHandle ) { tr.lightmaps[i]->texture->GenBindlessHandle(); } - lightmapData[i * 2] = tr.lightmaps[i]->texture->bindlessTextureHandle; + lightMapData[i * 2] = tr.lightmaps[i]->texture->bindlessTextureHandle; } for ( uint32_t i = 0; i < tr.deluxemaps.size(); i++ ) { if ( !tr.deluxemaps[i]->texture->hasBindlessHandle ) { tr.deluxemaps[i]->texture->GenBindlessHandle(); } - lightmapData[i * 2 + 1] = tr.deluxemaps[i]->texture->bindlessTextureHandle; + lightMapData[i * 2 + 1] = tr.deluxemaps[i]->texture->bindlessTextureHandle; } ASSERT_LE( tr.lightmaps.size(), 256 ); // Engine supports up to 256 lightmaps currently, so we use 8 bits to address them @@ -624,8 +620,8 @@ void MaterialSystem::GenerateWorldCommandBuffer() { tr.blackImage->texture->GenBindlessHandle(); } // Use lightmap 255 for drawSurfs that use a full white image for their lightmap - lightmapData[255 * 2] = tr.whiteImage->texture->bindlessTextureHandle; - lightmapData[255 * 2 + 1] = tr.blackImage->texture->bindlessTextureHandle; + lightMapData[255 * 2] = tr.whiteImage->texture->bindlessTextureHandle; + lightMapData[255 * 2 + 1] = tr.blackImage->texture->bindlessTextureHandle; } lightMapDataUBO.FlushAll(); @@ -633,7 +629,6 @@ void MaterialSystem::GenerateWorldCommandBuffer() { surfaceCommandsCount = totalBatchCount * SURFACE_COMMANDS_PER_BATCH; - surfaceCommandsSSBO.BindBuffer(); surfaceCommandsSSBO.BufferStorage( surfaceCommandsCount * SURFACE_COMMAND_SIZE * MAX_VIEWFRAMES, 1, nullptr ); surfaceCommandsSSBO.MapAll(); SurfaceCommand* surfaceCommands = ( SurfaceCommand* ) surfaceCommandsSSBO.GetData(); @@ -645,12 +640,11 @@ void MaterialSystem::GenerateWorldCommandBuffer() { memset( culledCommands, 0, surfaceCommandsCount * sizeof( GLIndirectBuffer::GLIndirectCommand ) * MAX_VIEWFRAMES ); culledCommandsBuffer.FlushAll(); - surfaceBatchesUBO.BindBuffer(); - glBufferData( GL_UNIFORM_BUFFER, MAX_SURFACE_COMMAND_BATCHES * sizeof( SurfaceCommandBatch ), nullptr, GL_STATIC_DRAW ); + surfaceBatchesUBO.BufferData( MAX_SURFACE_COMMAND_BATCHES * SURFACE_COMMAND_BATCH_SIZE, nullptr, GL_STATIC_DRAW ); SurfaceCommandBatch* surfaceCommandBatches = ( SurfaceCommandBatch* ) surfaceBatchesUBO.MapBufferRange( MAX_SURFACE_COMMAND_BATCHES * SURFACE_COMMAND_BATCH_SIZE ); - // memset( (void*) surfaceCommandBatches, 0, MAX_SURFACE_COMMAND_BATCHES * sizeof( SurfaceCommandBatch ) ); + // memset( (void*) surfaceCommandBatches, 0, MAX_SURFACE_COMMAND_BATCHES * SURFACE_COMMAND_BATCH_SIZE ); // Fuck off gcc for ( int i = 0; i < MAX_SURFACE_COMMAND_BATCHES; i++ ) { surfaceCommandBatches[i] = {}; @@ -679,8 +673,7 @@ void MaterialSystem::GenerateWorldCommandBuffer() { if ( r_materialDebug.Get() ) { const uint32_t debugSize = surfaceCommandsCount * 20; - debugSSBO.BindBuffer(); - glBufferData( GL_SHADER_STORAGE_BUFFER, debugSize * sizeof( uint32_t ), nullptr, GL_STATIC_DRAW ); + debugSSBO.BufferData( debugSize, nullptr, GL_STATIC_DRAW ); uint32_t* debugBuffer = debugSSBO.MapBufferRange( debugSize ); memset( debugBuffer, 0, debugSize * sizeof( uint32_t ) ); debugSSBO.UnmapBuffer(); @@ -1594,7 +1587,6 @@ void MaterialSystem::AddStageTextures( drawSurf_t* drawSurf, const uint32_t stag // Dynamic surfaces are those whose values in the SSBO can be updated void MaterialSystem::UpdateDynamicSurfaces() { if ( dynamicStagesSize > 0 ) { - materialsUBO.BindBuffer(); uint32_t* materialsData = materialsUBO.MapBufferRange( dynamicStagesOffset, dynamicStagesSize ); GenerateMaterialsBuffer( dynamicStages, dynamicStagesSize, materialsData ); @@ -1603,16 +1595,15 @@ void MaterialSystem::UpdateDynamicSurfaces() { } if ( dynamicTexDataSize > 0 ) { - texDataBuffer.BindBuffer( texDataBufferType ); - GL_CheckErrors(); TexBundle* textureBundles = ( TexBundle* ) texDataBuffer.MapBufferRange( dynamicTexDataOffset, dynamicTexDataSize ); - GL_CheckErrors(); GenerateTexturesBuffer( dynamicTexData, textureBundles ); texDataBuffer.UnmapBuffer(); } + + GL_CheckErrors(); } void MaterialSystem::UpdateFrameData() { @@ -1855,10 +1846,8 @@ void MaterialSystem::GeneratePortalBoundingSpheres() { index++; } - portalSurfacesSSBO.BindBuffer(); portalSurfacesSSBO.BufferStorage( totalPortals * PORTAL_SURFACE_SIZE * MAX_VIEWS, 2, portalSurfs ); portalSurfacesSSBO.MapAll(); - portalSurfacesSSBO.UnBindBuffer(); portalSurfacesTmp.clear(); } diff --git a/src/engine/renderer/gl_shader.h b/src/engine/renderer/gl_shader.h index b11d951be9..1b28b15a01 100644 --- a/src/engine/renderer/gl_shader.h +++ b/src/engine/renderer/gl_shader.h @@ -1412,6 +1412,10 @@ class GLBuffer { glBindBuffer( target, 0 ); } + void BufferData( const GLsizeiptr size, const void* data, const GLenum usageFlags ) { + glNamedBufferData( id, size * sizeof( uint32_t ), data, usageFlags ); + } + void BufferStorage( const GLsizeiptr newAreaSize, const GLsizeiptr areaCount, const void* data ) { areaSize = newAreaSize; maxAreas = areaCount; @@ -1504,6 +1508,7 @@ class GLBuffer { uint32_t* data; }; +// Shorthands for buffers that are only bound to one specific target class GLSSBO : public GLBuffer { public: GLSSBO( const char* name, const GLuint bindingPoint, const GLbitfield flags, const GLbitfield mapFlags ) : From c3190554c48b3c97fe79a476c597fe15fea533b3 Mon Sep 17 00:00:00 2001 From: VReaperV Date: Sat, 18 Jan 2025 01:39:40 +0300 Subject: [PATCH 20/27] NUKE unused GLIndirectBuffer --- src/engine/renderer/Material.cpp | 8 +++---- src/engine/renderer/Material.h | 10 +++++++- src/engine/renderer/gl_shader.h | 39 -------------------------------- 3 files changed, 13 insertions(+), 44 deletions(-) diff --git a/src/engine/renderer/Material.cpp b/src/engine/renderer/Material.cpp index a91ade31c3..14fd0b51f8 100644 --- a/src/engine/renderer/Material.cpp +++ b/src/engine/renderer/Material.cpp @@ -636,8 +636,8 @@ void MaterialSystem::GenerateWorldCommandBuffer() { culledCommandsBuffer.BufferStorage( surfaceCommandsCount * INDIRECT_COMMAND_SIZE * MAX_VIEWFRAMES, 1, nullptr ); culledCommandsBuffer.MapAll(); - GLIndirectBuffer::GLIndirectCommand* culledCommands = ( GLIndirectBuffer::GLIndirectCommand* ) culledCommandsBuffer.GetData(); - memset( culledCommands, 0, surfaceCommandsCount * sizeof( GLIndirectBuffer::GLIndirectCommand ) * MAX_VIEWFRAMES ); + GLIndirectCommand* culledCommands = ( GLIndirectCommand* ) culledCommandsBuffer.GetData(); + memset( culledCommands, 0, surfaceCommandsCount * sizeof( GLIndirectCommand ) * MAX_VIEWFRAMES ); culledCommandsBuffer.FlushAll(); surfaceBatchesUBO.BufferData( MAX_SURFACE_COMMAND_BATCHES * SURFACE_COMMAND_BATCH_SIZE, nullptr, GL_STATIC_DRAW ); @@ -2100,9 +2100,9 @@ void MaterialSystem::RenderMaterials( const shaderSort_t fromSort, const shaderS void MaterialSystem::RenderIndirect( const Material& material, const uint32_t viewID, const GLenum mode = GL_TRIANGLES ) { glMultiDrawElementsIndirectCountARB( mode, GL_UNSIGNED_INT, - BUFFER_OFFSET( material.surfaceCommandBatchOffset * SURFACE_COMMANDS_PER_BATCH * sizeof( GLIndirectBuffer::GLIndirectCommand ) + BUFFER_OFFSET( material.surfaceCommandBatchOffset * SURFACE_COMMANDS_PER_BATCH * sizeof( GLIndirectCommand ) + ( surfaceCommandsCount * ( MAX_VIEWS * currentFrame + viewID ) - * sizeof( GLIndirectBuffer::GLIndirectCommand ) ) ), + * sizeof( GLIndirectCommand ) ) ), material.globalID * sizeof( uint32_t ) + ( MAX_COMMAND_COUNTERS * ( MAX_VIEWS * currentFrame + viewID ) ) * sizeof( uint32_t ), material.drawCommands.size(), 0 ); diff --git a/src/engine/renderer/Material.h b/src/engine/renderer/Material.h index 0343b2ce3f..8823181d5f 100644 --- a/src/engine/renderer/Material.h +++ b/src/engine/renderer/Material.h @@ -43,7 +43,15 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. static constexpr uint32_t MAX_DRAWCOMMAND_TEXTURES = 64; -/* Similar to GLIndirectBuffer::GLIndirectCommand, but we always set instanceCount to 1 and baseVertex to 0, +struct GLIndirectCommand { + GLuint count; + GLuint instanceCount; + GLuint firstIndex; + GLint baseVertex; + GLuint baseInstance; +}; + +/* Similar to GLIndirectCommand, but we always set instanceCount to 1 and baseVertex to 0, so no need to waste memory on those */ struct IndirectCompactCommand { GLuint count; diff --git a/src/engine/renderer/gl_shader.h b/src/engine/renderer/gl_shader.h index 1b28b15a01..00b579567b 100644 --- a/src/engine/renderer/gl_shader.h +++ b/src/engine/renderer/gl_shader.h @@ -1530,45 +1530,6 @@ class GLAtomicCounterBuffer : public GLBuffer { } }; -class GLIndirectBuffer { - public: - struct GLIndirectCommand { - GLuint count; - GLuint instanceCount; - GLuint firstIndex; - GLint baseVertex; - GLuint baseInstance; - }; - - GLIndirectBuffer( const char* name ) { - } - - void BindBuffer() { - glBindBuffer( GL_DRAW_INDIRECT_BUFFER, handle ); - } - - GLIndirectCommand* MapBufferRange( const GLsizeiptr count ) { - return (GLIndirectCommand*) glMapBufferRange( GL_DRAW_INDIRECT_BUFFER, - 0, count * sizeof( GLIndirectCommand ), - GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT ); - } - - void UnmapBuffer() const { - glUnmapBuffer( GL_DRAW_INDIRECT_BUFFER ); - } - - void GenBuffer() { - glGenBuffers( 1, &handle ); - } - - void DelBuffer() { - glDeleteBuffers( 1, &handle ); - } - - private: - GLuint handle; -}; - class GLCompileMacro { private: From f5ffb7fc282939cf7b74137c6e397c92ffcf5a77 Mon Sep 17 00:00:00 2001 From: VReaperV Date: Sat, 18 Jan 2025 02:09:47 +0300 Subject: [PATCH 21/27] Clean-up material system buffer bindings --- src/engine/renderer/Material.cpp | 24 +++++----- src/engine/renderer/Material.h | 14 ++++++ src/engine/renderer/gl_shader.cpp | 46 +++++++++++++++---- .../glsl_source/clearSurfaces_cp.glsl | 2 +- src/engine/renderer/glsl_source/cull_cp.glsl | 8 ++-- .../glsl_source/processSurfaces_cp.glsl | 8 ++-- 6 files changed, 73 insertions(+), 29 deletions(-) diff --git a/src/engine/renderer/Material.cpp b/src/engine/renderer/Material.cpp index 14fd0b51f8..84466e7266 100644 --- a/src/engine/renderer/Material.cpp +++ b/src/engine/renderer/Material.cpp @@ -37,18 +37,18 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "Material.h" #include "ShadeCommon.h" -GLUBO materialsUBO( "materials", 6, GL_MAP_WRITE_BIT, GL_MAP_INVALIDATE_RANGE_BIT ); -GLBuffer texDataBuffer( "texData", 7, GL_MAP_WRITE_BIT, GL_MAP_FLUSH_EXPLICIT_BIT ); -GLUBO lightMapDataUBO( "lightMapData", 8, GL_MAP_WRITE_BIT, GL_MAP_FLUSH_EXPLICIT_BIT ); +GLUBO materialsUBO( "materials", Util::ordinal( BufferBind::MATERIALS ), GL_MAP_WRITE_BIT, GL_MAP_INVALIDATE_RANGE_BIT ); +GLBuffer texDataBuffer( "texData", Util::ordinal( BufferBind::TEX_DATA ), GL_MAP_WRITE_BIT, GL_MAP_FLUSH_EXPLICIT_BIT ); +GLUBO lightMapDataUBO( "lightMapData", Util::ordinal( BufferBind::LIGHTMAP_DATA ), GL_MAP_WRITE_BIT, GL_MAP_FLUSH_EXPLICIT_BIT ); -GLSSBO surfaceDescriptorsSSBO( "surfaceDescriptors", 1, GL_MAP_WRITE_BIT, GL_MAP_INVALIDATE_RANGE_BIT ); -GLSSBO surfaceCommandsSSBO( "surfaceCommands", 2, GL_MAP_WRITE_BIT, GL_MAP_FLUSH_EXPLICIT_BIT ); -GLBuffer culledCommandsBuffer( "culledCommands", 3, GL_MAP_WRITE_BIT, GL_MAP_FLUSH_EXPLICIT_BIT ); -GLUBO surfaceBatchesUBO( "surfaceBatches", 0, GL_MAP_WRITE_BIT, GL_MAP_INVALIDATE_RANGE_BIT ); -GLBuffer atomicCommandCountersBuffer( "atomicCommandCounters", 4, GL_MAP_WRITE_BIT, GL_MAP_FLUSH_EXPLICIT_BIT ); -GLSSBO portalSurfacesSSBO( "portalSurfaces", 5, GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT, 0 ); +GLSSBO surfaceDescriptorsSSBO( "surfaceDescriptors", Util::ordinal( BufferBind::SURFACE_DESCRIPTORS ), GL_MAP_WRITE_BIT, GL_MAP_INVALIDATE_RANGE_BIT ); +GLSSBO surfaceCommandsSSBO( "surfaceCommands", Util::ordinal( BufferBind::SURFACE_COMMANDS ), GL_MAP_WRITE_BIT, GL_MAP_FLUSH_EXPLICIT_BIT ); +GLBuffer culledCommandsBuffer( "culledCommands", Util::ordinal( BufferBind::CULLED_COMMANDS ), GL_MAP_WRITE_BIT, GL_MAP_FLUSH_EXPLICIT_BIT ); +GLUBO surfaceBatchesUBO( "surfaceBatches", Util::ordinal( BufferBind::SURFACE_BATCHES ), GL_MAP_WRITE_BIT, GL_MAP_INVALIDATE_RANGE_BIT ); +GLBuffer atomicCommandCountersBuffer( "atomicCommandCounters", Util::ordinal( BufferBind::COMMAND_COUNTERS_ATOMIC ), GL_MAP_WRITE_BIT, GL_MAP_FLUSH_EXPLICIT_BIT ); +GLSSBO portalSurfacesSSBO( "portalSurfaces", Util::ordinal( BufferBind::PORTAL_SURFACES ), GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT, 0 ); -GLSSBO debugSSBO( "debug", 10, GL_MAP_WRITE_BIT, GL_MAP_INVALIDATE_RANGE_BIT ); +GLSSBO debugSSBO( "debug", Util::ordinal( BufferBind::DEBUG ), GL_MAP_WRITE_BIT, GL_MAP_INVALIDATE_RANGE_BIT ); PortalView portalStack[MAX_VIEWS]; @@ -1607,11 +1607,11 @@ void MaterialSystem::UpdateDynamicSurfaces() { } void MaterialSystem::UpdateFrameData() { - atomicCommandCountersBuffer.BindBufferBase( GL_SHADER_STORAGE_BUFFER ); + atomicCommandCountersBuffer.BindBufferBase( GL_SHADER_STORAGE_BUFFER, Util::ordinal( BufferBind::COMMAND_COUNTERS_STORAGE ) ); gl_clearSurfacesShader->BindProgram( 0 ); gl_clearSurfacesShader->SetUniform_Frame( nextFrame ); gl_clearSurfacesShader->DispatchCompute( MAX_VIEWS, 1, 1 ); - atomicCommandCountersBuffer.UnBindBufferBase( GL_SHADER_STORAGE_BUFFER ); + atomicCommandCountersBuffer.UnBindBufferBase( GL_SHADER_STORAGE_BUFFER, Util::ordinal( BufferBind::COMMAND_COUNTERS_STORAGE ) ); GL_CheckErrors(); } diff --git a/src/engine/renderer/Material.h b/src/engine/renderer/Material.h index 8823181d5f..52d21fbfe0 100644 --- a/src/engine/renderer/Material.h +++ b/src/engine/renderer/Material.h @@ -280,6 +280,20 @@ struct SurfaceCommandBatch { uint32_t materialIDs[2] { 0, 0 }; }; +enum class BufferBind { + MATERIALS = 1, // LightTile UBO uses binding point 0, so avoid it here + TEX_DATA = 6, + LIGHTMAP_DATA = 2, + SURFACE_DESCRIPTORS = 0, + SURFACE_COMMANDS = 1, + CULLED_COMMANDS = 2, + SURFACE_BATCHES = 3, + COMMAND_COUNTERS_ATOMIC = 0, + COMMAND_COUNTERS_STORAGE = 4, // Avoid needlessly rebinding buffers + PORTAL_SURFACES = 5, + DEBUG = 10 +}; + class MaterialSystem { public: bool generatedWorldCommandBuffer = false; diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index d4569fe799..7ba2cc311d 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -532,6 +532,12 @@ static std::string GenVertexHeader() { str += "#define baseInstance gl_BaseInstanceARB\n\n"; } + if ( glConfig2.usingMaterialSystem ) { + AddDefine( str, "BIND_MATERIALS", Util::ordinal( BufferBind::MATERIALS ) ); + AddDefine( str, "BIND_TEX_DATA", Util::ordinal( BufferBind::TEX_DATA ) ); + AddDefine( str, "BIND_LIGHTMAP_DATA", Util::ordinal( BufferBind::LIGHTMAP_DATA ) ); + } + return str; } @@ -566,6 +572,12 @@ static std::string GenFragmentHeader() { str += "#define baseInstance in_baseInstance\n\n"; } + if ( glConfig2.usingMaterialSystem ) { + AddDefine( str, "BIND_MATERIALS", Util::ordinal( BufferBind::MATERIALS ) ); + AddDefine( str, "BIND_TEX_DATA", Util::ordinal( BufferBind::TEX_DATA ) ); + AddDefine( str, "BIND_LIGHTMAP_DATA", Util::ordinal( BufferBind::LIGHTMAP_DATA ) ); + } + return str; } @@ -573,11 +585,23 @@ static std::string GenComputeHeader() { std::string str; // Compute shader compatibility defines - AddDefine( str, "MAX_VIEWS", MAX_VIEWS ); - AddDefine( str, "MAX_FRAMES", MAX_FRAMES ); - AddDefine( str, "MAX_VIEWFRAMES", MAX_VIEWFRAMES ); - AddDefine( str, "MAX_SURFACE_COMMAND_BATCHES", MAX_SURFACE_COMMAND_BATCHES ); - AddDefine( str, "MAX_COMMAND_COUNTERS", MAX_COMMAND_COUNTERS ); + if ( glConfig2.usingMaterialSystem ) { + AddDefine( str, "MAX_VIEWS", MAX_VIEWS ); + AddDefine( str, "MAX_FRAMES", MAX_FRAMES ); + AddDefine( str, "MAX_VIEWFRAMES", MAX_VIEWFRAMES ); + AddDefine( str, "MAX_SURFACE_COMMAND_BATCHES", MAX_SURFACE_COMMAND_BATCHES ); + AddDefine( str, "MAX_COMMAND_COUNTERS", MAX_COMMAND_COUNTERS ); + + AddDefine( str, "BIND_SURFACE_DESCRIPTORS", Util::ordinal( BufferBind::SURFACE_DESCRIPTORS ) ); + AddDefine( str, "BIND_SURFACE_COMMANDS", Util::ordinal( BufferBind::SURFACE_COMMANDS ) ); + AddDefine( str, "BIND_CULLED_COMMANDS", Util::ordinal( BufferBind::CULLED_COMMANDS ) ); + AddDefine( str, "BIND_SURFACE_BATCHES", Util::ordinal( BufferBind::SURFACE_BATCHES ) ); + AddDefine( str, "BIND_COMMAND_COUNTERS_ATOMIC", Util::ordinal( BufferBind::COMMAND_COUNTERS_ATOMIC ) ); + AddDefine( str, "BIND_COMMAND_COUNTERS_STORAGE", Util::ordinal( BufferBind::COMMAND_COUNTERS_STORAGE ) ); + AddDefine( str, "BIND_PORTAL_SURFACES", Util::ordinal( BufferBind::PORTAL_SURFACES ) ); + + AddDefine( str, "BIND_DEBUG", Util::ordinal( BufferBind::DEBUG ) ); + } if ( glConfig2.usingBindlessTextures ) { str += "layout(bindless_image) uniform;\n"; @@ -1361,15 +1385,21 @@ std::string GLShaderManager::ShaderPostProcess( GLShader *shader, const std::str std::string materialStruct = "\nstruct Material {\n"; // 6 kb for materials const uint32_t count = ( 4096 + 2048 ) / shader->GetPaddedSize(); - std::string materialBlock = "layout(std140, binding = 6) uniform materialsUBO {\n" + std::string materialBlock = "layout(std140, binding = " + + std::to_string( Util::ordinal( BufferBind::MATERIALS ) ) + + ") uniform materialsUBO {\n" " Material materials[" + std::to_string( count ) + "]; \n" "};\n\n"; std::string texBuf = glConfig2.maxUniformBlockSize >= MIN_MATERIAL_UBO_SIZE ? - "layout(std140, binding = 7) uniform texDataUBO {\n" + "layout(std140, binding = " + + std::to_string( Util::ordinal( BufferBind::TEX_DATA ) ) + + ") uniform texDataUBO {\n" " TexData texData[" + std::to_string( MAX_TEX_BUNDLES ) + "]; \n" "};\n\n" - : "layout(std430, binding = 7) restrict readonly buffer texDataSSBO {\n" + : "layout(std430, binding = " + + std::to_string( Util::ordinal( BufferBind::TEX_DATA ) ) + + ") restrict readonly buffer texDataSSBO {\n" " TexData texData[];\n" "};\n\n"; // We have to store u_TextureMatrix as vec4 + vec2 because otherwise it would be aligned to a vec4 under std140 diff --git a/src/engine/renderer/glsl_source/clearSurfaces_cp.glsl b/src/engine/renderer/glsl_source/clearSurfaces_cp.glsl index 5ab1b2396d..07ed88da9f 100644 --- a/src/engine/renderer/glsl_source/clearSurfaces_cp.glsl +++ b/src/engine/renderer/glsl_source/clearSurfaces_cp.glsl @@ -38,7 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. layout (local_size_x = 64, local_size_y = 1, local_size_z = 1) in; -layout(std430, binding = 4) writeonly buffer atomicCommandCountersBuffer { +layout(std430, binding = BIND_COMMAND_COUNTERS_STORAGE) writeonly buffer atomicCommandCountersBuffer { uint atomicCommandCounters[MAX_COMMAND_COUNTERS * MAX_VIEWFRAMES]; }; diff --git a/src/engine/renderer/glsl_source/cull_cp.glsl b/src/engine/renderer/glsl_source/cull_cp.glsl index eb93e72590..8c19d55706 100644 --- a/src/engine/renderer/glsl_source/cull_cp.glsl +++ b/src/engine/renderer/glsl_source/cull_cp.glsl @@ -41,15 +41,15 @@ layout (local_size_x = 64, local_size_y = 1, local_size_z = 1) in; layout(binding = 0) uniform sampler2D depthImage; -layout(std430, binding = 1) readonly restrict buffer surfaceDescriptorsSSBO { +layout(std430, binding = BIND_SURFACE_DESCRIPTORS) readonly restrict buffer surfaceDescriptorsSSBO { SurfaceDescriptor surfaces[]; }; -layout(std430, binding = 2) writeonly restrict buffer surfaceCommandsSSBO { +layout(std430, binding = BIND_SURFACE_COMMANDS) writeonly restrict buffer surfaceCommandsSSBO { SurfaceCommand surfaceCommands[]; }; -layout(std430, binding = 5) restrict buffer portalSurfacesSSBO { +layout(std430, binding = BIND_PORTAL_SURFACES) restrict buffer portalSurfacesSSBO { PortalSurface portalSurfaces[]; }; @@ -57,7 +57,7 @@ layout(std430, binding = 5) restrict buffer portalSurfacesSSBO { #define DEBUG_INVOCATION_SIZE 5 #define DEBUG_ID( id ) ( id * DEBUG_INVOCATION_SIZE ) - layout(std430, binding = 10) writeonly restrict buffer debugSSBO { + layout(std430, binding = BIND_DEBUG) writeonly restrict buffer debugSSBO { uvec4 debug[]; }; #endif diff --git a/src/engine/renderer/glsl_source/processSurfaces_cp.glsl b/src/engine/renderer/glsl_source/processSurfaces_cp.glsl index a3eaa267d0..c5d28513b3 100644 --- a/src/engine/renderer/glsl_source/processSurfaces_cp.glsl +++ b/src/engine/renderer/glsl_source/processSurfaces_cp.glsl @@ -41,19 +41,19 @@ layout (local_size_x = 64, local_size_y = 1, local_size_z = 1) in; #define SurfaceCommandBatch uvec4 -layout(std430, binding = 2) readonly restrict buffer surfaceCommandsSSBO { +layout(std430, binding = BIND_SURFACE_COMMANDS) readonly restrict buffer surfaceCommandsSSBO { SurfaceCommand surfaceCommands[]; }; -layout(std430, binding = 3) writeonly restrict buffer culledCommandsSSBO { +layout(std430, binding = BIND_CULLED_COMMANDS) writeonly restrict buffer culledCommandsSSBO { GLIndirectCommand culledCommands[]; }; -layout(std140, binding = 0) uniform ub_SurfaceBatches { +layout(std140, binding = BIND_SURFACE_BATCHES) uniform ub_SurfaceBatches { SurfaceCommandBatch surfaceBatches[MAX_SURFACE_COMMAND_BATCHES]; }; -layout (binding = 4) uniform atomic_uint atomicCommandCounters[MAX_COMMAND_COUNTERS * MAX_VIEWFRAMES]; +layout (binding = BIND_COMMAND_COUNTERS_ATOMIC) uniform atomic_uint atomicCommandCounters[MAX_COMMAND_COUNTERS * MAX_VIEWFRAMES]; uniform uint u_Frame; uniform uint u_ViewID; From 07410115947b9485042bedb149ff4661a4195f05 Mon Sep 17 00:00:00 2001 From: VReaperV Date: Tue, 21 Jan 2025 14:35:17 +0300 Subject: [PATCH 22/27] Fix r_forceAmbient comparison --- src/engine/renderer/tr_bsp.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/engine/renderer/tr_bsp.cpp b/src/engine/renderer/tr_bsp.cpp index c1b1c6c32e..1fd1c9599f 100644 --- a/src/engine/renderer/tr_bsp.cpp +++ b/src/engine/renderer/tr_bsp.cpp @@ -4124,10 +4124,11 @@ void R_LoadLightGrid( lump_t *l ) tmpDirected[ 2 ] = in->directed[ 2 ]; tmpDirected[ 3 ] = 255; - if ( tmpAmbient[0] < r_forceAmbient.Get() && - tmpAmbient[1] < r_forceAmbient.Get() && - tmpAmbient[2] < r_forceAmbient.Get() ) { - VectorSet( tmpAmbient, r_forceAmbient.Get(), r_forceAmbient.Get(), r_forceAmbient.Get() ); + const byte forceAmbientNormalised = floatToUnorm8( r_forceAmbient.Get() ); + if ( tmpAmbient[0] < forceAmbientNormalised && + tmpAmbient[1] < forceAmbientNormalised && + tmpAmbient[2] < forceAmbientNormalised ) { + VectorSet( tmpAmbient, forceAmbientNormalised, forceAmbientNormalised, forceAmbientNormalised ); } if ( tr.legacyOverBrightClamping ) From 53f5c7333c5c799fb2ed6d614ba94877466ade2b Mon Sep 17 00:00:00 2001 From: VReaperV Date: Wed, 22 Jan 2025 03:09:06 +0300 Subject: [PATCH 23/27] Use colorModulateColorGen instead of disabling vertex color Originally, vertex color array was disabled if colorGen CGEN_VERTEX or CGEN_ONE_MINUS_VERTEX or alphaGen CGEN_VERTEX or CGEN_ONE_MINUS_VERTEX were used, resulting in the shader receiving the default OpenGL values for the disabled arrays (0.0, 0.0, 0.0, 1.0). Now it will instead be set via setting a bit in `u_ColorModulateColorGen`, which allows skipping the vertex format change. It will also be necessary for the geometry cache. Also fixes incorrect lighting with `tr.mapOverBrightBits = 3`. --- src/engine/renderer/Material.cpp | 20 ------------------- src/engine/renderer/Material.h | 5 +---- src/engine/renderer/gl_shader.cpp | 4 ++-- src/engine/renderer/gl_shader.h | 19 ++++++++++-------- src/engine/renderer/glsl_source/common.glsl | 10 ++++++++-- .../renderer/glsl_source/generic_vp.glsl | 1 + 6 files changed, 23 insertions(+), 36 deletions(-) diff --git a/src/engine/renderer/Material.cpp b/src/engine/renderer/Material.cpp index 84466e7266..8c69f44e76 100644 --- a/src/engine/renderer/Material.cpp +++ b/src/engine/renderer/Material.cpp @@ -1087,12 +1087,6 @@ void ProcessMaterialGeneric3D( Material* material, shaderStage_t* pStage, drawSu material->tcGen_Lightmap = pStage->tcGen_Lightmap; material->deformIndex = pStage->deformIndex; - colorGen_t rgbGen = SetRgbGen( pStage ); - alphaGen_t alphaGen = SetAlphaGen( pStage ); - - material->useAttrColor = rgbGen == colorGen_t::CGEN_VERTEX || rgbGen == colorGen_t::CGEN_ONE_MINUS_VERTEX - || alphaGen == alphaGen_t::AGEN_VERTEX || alphaGen == alphaGen_t::AGEN_ONE_MINUS_VERTEX; - gl_genericShaderMaterial->SetTCGenEnvironment( pStage->tcGen_Environment ); gl_genericShaderMaterial->SetTCGenLightmap( pStage->tcGen_Lightmap ); @@ -1118,14 +1112,6 @@ void ProcessMaterialLightMapping( Material* material, shaderStage_t* pStage, dra DAEMON_ASSERT( !( enableDeluxeMapping && enableGridDeluxeMapping ) ); - // useAttrColor has no effect since the lightMapping shader has ATTR_COLOR forced to be always - // on (_requiredVertexAttribs). If we removed ATTR_COLOR from there, we would need to detect - // implicit vertex lighting as well, not only rgbgen (see SetLightDeluxeMode). - /* colorGen_t rgbGen = SetRgbGen( pStage ); - alphaGen_t alphaGen = SetAlphaGen( pStage ); - material->useAttrColor = rgbGen == colorGen_t::CGEN_VERTEX || rgbGen == colorGen_t::CGEN_ONE_MINUS_VERTEX - || alphaGen == alphaGen_t::AGEN_VERTEX || alphaGen == alphaGen_t::AGEN_ONE_MINUS_VERTEX; */ - material->enableDeluxeMapping = enableDeluxeMapping; material->enableGridLighting = enableGridLighting; material->enableGridDeluxeMapping = enableGridDeluxeMapping; @@ -2150,12 +2136,6 @@ void MaterialSystem::RenderMaterial( Material& material, const uint32_t viewID ) backEnd.currentEntity = &tr.worldEntity; - if ( material.useAttrColor ) { - material.shader->AddVertexAttribBit( ATTR_COLOR ); - } else { - material.shader->DelVertexAttribBit( ATTR_COLOR ); - } - GL_State( stateBits ); if ( material.usePolygonOffset ) { glEnable( GL_POLYGON_OFFSET_FILL ); diff --git a/src/engine/renderer/Material.h b/src/engine/renderer/Material.h index 52d21fbfe0..ea49e676b1 100644 --- a/src/engine/renderer/Material.h +++ b/src/engine/renderer/Material.h @@ -108,8 +108,6 @@ struct Material { bool enableSpecularMapping; bool enablePhysicalMapping; - bool useAttrColor = false; - cullType_t cullType; uint32_t sort; @@ -128,8 +126,7 @@ struct Material { bool operator==( const Material& other ) { return program == other.program && stateBits == other.stateBits && vbo == other.vbo && ibo == other.ibo - && fog == other.fog && cullType == other.cullType && usePolygonOffset == other.usePolygonOffset - && useAttrColor == other.useAttrColor; + && fog == other.fog && cullType == other.cullType && usePolygonOffset == other.usePolygonOffset; } void AddTexture( Texture* texture ) { diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index 7ba2cc311d..058ca81543 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -2252,7 +2252,7 @@ void GLShader::WriteUniformsToBuffer( uint32_t* buffer ) { } GLShader_generic::GLShader_generic( GLShaderManager *manager ) : - GLShader( "generic", ATTR_POSITION | ATTR_TEXCOORD | ATTR_QTANGENT, manager ), + GLShader( "generic", ATTR_POSITION | ATTR_TEXCOORD | ATTR_QTANGENT | ATTR_COLOR, manager ), u_ColorMap( this ), u_DepthMap( this ), u_TextureMatrix( this ), @@ -2284,7 +2284,7 @@ void GLShader_generic::SetShaderProgramUniforms( shaderProgram_t *shaderProgram } GLShader_genericMaterial::GLShader_genericMaterial( GLShaderManager* manager ) : - GLShader( "genericMaterial", "generic", true, ATTR_POSITION | ATTR_TEXCOORD | ATTR_QTANGENT, manager ), + GLShader( "genericMaterial", "generic", true, ATTR_POSITION | ATTR_TEXCOORD | ATTR_QTANGENT | ATTR_COLOR, manager ), u_ColorMap( this ), u_DepthMap( this ), u_TextureMatrix( this ), diff --git a/src/engine/renderer/gl_shader.h b/src/engine/renderer/gl_shader.h index 00b579567b..e75a0c6d59 100644 --- a/src/engine/renderer/gl_shader.h +++ b/src/engine/renderer/gl_shader.h @@ -3494,7 +3494,8 @@ enum class ColorModulate { COLOR_MINUS_ONE = BIT( 1 ), COLOR_LIGHTFACTOR = BIT( 2 ), ALPHA_ONE = BIT( 3 ), - ALPHA_MINUS_ONE = BIT( 4 ) + ALPHA_MINUS_ONE = BIT( 4 ), + ALPHA_ADD_ONE = BIT( 5 ) }; class u_ColorModulateColorGen : @@ -3524,7 +3525,7 @@ class u_ColorModulateColorGen : // vertexOverbright is only needed for non-lightmapped cases. When there is a // lightmap, this is done by multiplying with the overbright-scaled white image colorModulate |= Util::ordinal( ColorModulate::COLOR_LIGHTFACTOR ); - lightFactor = uint32_t( tr.mapLightFactor ) << 5; + lightFactor = uint32_t( tr.mapLightFactor ) << 6; } else { colorModulate |= Util::ordinal( ColorModulate::COLOR_ONE ); } @@ -3541,10 +3542,10 @@ class u_ColorModulateColorGen : if ( useMapLightFactor ) { ASSERT_EQ( vertexOverbright, false ); - lightFactor = uint32_t( tr.mapLightFactor ) << 5; + lightFactor = uint32_t( tr.mapLightFactor ) << 6; } - colorModulate |= lightFactor ? lightFactor : 1 << 5; + colorModulate |= lightFactor ? lightFactor : 1 << 6; switch ( alphaGen ) { case alphaGen_t::AGEN_VERTEX: @@ -3561,10 +3562,12 @@ class u_ColorModulateColorGen : break; } - if ( needAttrib ) { - _shader->AddVertexAttribBit( ATTR_COLOR ); - } else { - _shader->DelVertexAttribBit( ATTR_COLOR ); + if ( !needAttrib ) { + /* Originally, this controlled whether the vertex color array was used, + now it does the equivalent by setting the color in the shader in such way as if it was using + the default OpenGL values for the disabled arrays (0.0, 0.0, 0.0, 1.0) + This allows to skip the vertex format change */ + colorModulate |= Util::ordinal( ColorModulate::ALPHA_ADD_ONE ); } this->SetValue( colorModulate ); } diff --git a/src/engine/renderer/glsl_source/common.glsl b/src/engine/renderer/glsl_source/common.glsl index a539da8276..82850db73e 100644 --- a/src/engine/renderer/glsl_source/common.glsl +++ b/src/engine/renderer/glsl_source/common.glsl @@ -48,7 +48,8 @@ Bit 1: color * ( -1 ) Bit 2: color += lightFactor Bit 3: alpha * 1 Bit 4: alpha * ( -1 ) -Bit 5-7: lightFactor */ +Bit 5: alpha = 1 +Bit 6-9: lightFactor */ float colorModArray[3] = float[3] ( 0.0f, 1.0f, -1.0f ); @@ -65,5 +66,10 @@ vec4 ColorModulateToColor( const in uint colorMod, const in float lightFactor ) } float ColorModulateToLightFactor( const in uint colorMod ) { - return ( colorMod >> 5 ) & 0x7; + return ( colorMod >> 6 ) & 0xF; +} + +// This is used to skip vertex colours if the colorMod doesn't need them +bool ColorModulateToVertexColor( const in uint colorMod ) { + return ( colorMod & 0xFF ) == 0xFF; } diff --git a/src/engine/renderer/glsl_source/generic_vp.glsl b/src/engine/renderer/glsl_source/generic_vp.glsl index 09042277f4..3affc9a91d 100644 --- a/src/engine/renderer/glsl_source/generic_vp.glsl +++ b/src/engine/renderer/glsl_source/generic_vp.glsl @@ -68,6 +68,7 @@ void main() VertexFetch( position, LB, color, texCoord, lmCoord ); float lightFactor = ColorModulateToLightFactor( u_ColorModulateColorGen ); + color.a = ColorModulateToVertexColor( u_ColorModulateColorGen ) ? 1.0 : color.a; color = color * ColorModulateToColor( u_ColorModulateColorGen, lightFactor ) + unpackUnorm4x8( u_Color ) * vec4( lightFactor, lightFactor, lightFactor, 1.0 ); From 0c0823a2b734182684c9c7283aab96341cbf8a04 Mon Sep 17 00:00:00 2001 From: VReaperV Date: Mon, 20 Jan 2025 20:54:06 +0300 Subject: [PATCH 24/27] Implement geometry cache The geometry cache represents 3 buffers: a VBO, IBO, and inputVBO. These buffers will replace the old separate input VBOs and IBOs when enabled. This allows binding only a VAO before rendering, rather than setting up vertex pointers with the correct offset and formats every time. Additionally, it means that there's no need to switch between different VBOs/IBOs. The `inputVBO` is currently unused, but it will be needed to make models work with the geometry cache (model animations and world transform will be processed in a compute shader). Currently this is only used by the material system, but it should be possible to make the core renderer use it as well. --- src.cmake | 2 + src/engine/renderer/GeometryCache.cpp | 100 ++++++++++++++++++++++++++ src/engine/renderer/GeometryCache.h | 70 ++++++++++++++++++ src/engine/renderer/Material.cpp | 17 ++--- src/engine/renderer/Material.h | 10 +-- src/engine/renderer/gl_shader.h | 74 +++++++++++++++++++ src/engine/renderer/tr_bsp.cpp | 5 ++ src/engine/renderer/tr_init.cpp | 11 ++- src/engine/renderer/tr_local.h | 5 ++ src/engine/renderer/tr_public.h | 3 + src/engine/renderer/tr_shade.cpp | 2 + src/engine/renderer/tr_vbo.cpp | 13 +++- src/engine/sys/sdl_glimp.cpp | 11 ++- 13 files changed, 302 insertions(+), 21 deletions(-) create mode 100644 src/engine/renderer/GeometryCache.cpp create mode 100644 src/engine/renderer/GeometryCache.h diff --git a/src.cmake b/src.cmake index 7976806708..c765a9c56b 100644 --- a/src.cmake +++ b/src.cmake @@ -115,6 +115,8 @@ set(RENDERERLIST ${ENGINE_DIR}/renderer/tr_fbo.cpp ${ENGINE_DIR}/renderer/tr_flares.cpp ${ENGINE_DIR}/renderer/tr_font.cpp + ${ENGINE_DIR}/renderer/GeometryCache.cpp + ${ENGINE_DIR}/renderer/GeometryCache.h ${ENGINE_DIR}/renderer/InternalImage.cpp ${ENGINE_DIR}/renderer/InternalImage.h ${ENGINE_DIR}/renderer/Material.cpp diff --git a/src/engine/renderer/GeometryCache.cpp b/src/engine/renderer/GeometryCache.cpp new file mode 100644 index 0000000000..a34e9b0cac --- /dev/null +++ b/src/engine/renderer/GeometryCache.cpp @@ -0,0 +1,100 @@ +/* +=========================================================================== + +Daemon BSD Source Code +Copyright (c) 2025 Daemon Developers +All rights reserved. + +This file is part of the Daemon BSD Source Code (Daemon Source Code). + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Daemon developers nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL DAEMON DEVELOPERS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================== +*/ +// GeometryCache.cpp + +#include "GeometryCache.h" + +#include "tr_local.h" + +GeometryCache geometryCache; + +void GeometryCache::Bind() { + VAO.Bind(); +} + +void GeometryCache::InitGLBuffers() { + inputVBO.GenBuffer(); + VBO.GenBuffer(); + IBO.GenBuffer(); + + VAO.GenVAO(); +} + +void GeometryCache::FreeGLBuffers() { + inputVBO.DelBuffer(); + VBO.DelBuffer(); + IBO.DelBuffer(); + + VAO.DelVAO(); +} + +void GeometryCache::Free() { +} + +void GeometryCache::AllocBuffers() { + VBO.BufferData( mapVerticesNumber * 8, nullptr, GL_STATIC_DRAW ); + + IBO.BufferData( mapIndicesNumber, nullptr, GL_STATIC_DRAW ); +} + +void GeometryCache::AddMapGeometry( const uint32_t verticesNumber, const uint32_t indicesNumber, + const vertexAttributeSpec_t* attrBegin, const vertexAttributeSpec_t* attrEnd, + const glIndex_t* indices ) { + mapVerticesNumber = verticesNumber; + mapIndicesNumber = indicesNumber; + + VAO.Bind(); + + AllocBuffers(); + + VAO.SetAttrs( attrBegin, attrEnd ); + + VAO.SetVertexBuffer( VBO, 0 ); + VAO.SetIndexBuffer( IBO ); + + uint32_t* VBOVerts = VBO.MapBufferRange( mapVerticesNumber * 8 ); + memset( VBOVerts, 0, mapVerticesNumber * 8 * sizeof( uint32_t ) ); + for ( const vertexAttributeSpec_t* spec = attrBegin; spec < attrEnd; spec++ ) { + vboAttributeLayout_t& attr = VAO.attrs[spec->attrIndex]; + + CopyVertexAttribute( attr, *spec, mapVerticesNumber, ( byte* ) VBOVerts ); + } + VBO.UnmapBuffer(); + + uint32_t* VBOIndices = IBO.MapBufferRange( mapIndicesNumber ); + memcpy( VBOIndices, indices, mapIndicesNumber * sizeof( uint32_t ) ); + IBO.UnmapBuffer(); + + glBindVertexArray( backEnd.currentVAO ); +} diff --git a/src/engine/renderer/GeometryCache.h b/src/engine/renderer/GeometryCache.h new file mode 100644 index 0000000000..134b8513bf --- /dev/null +++ b/src/engine/renderer/GeometryCache.h @@ -0,0 +1,70 @@ +/* +=========================================================================== + +Daemon BSD Source Code +Copyright (c) 2025 Daemon Developers +All rights reserved. + +This file is part of the Daemon BSD Source Code (Daemon Source Code). + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Daemon developers nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL DAEMON DEVELOPERS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================== +*/ +// GeometryCache.h + +#ifndef GEOMETRY_CACHE_H +#define GEOMETRY_CACHE_H + +#include "gl_shader.h" +#include "Material.h" + +class GeometryCache { + public: + void Bind(); + + void InitGLBuffers(); + void FreeGLBuffers(); + + void Free(); + + void AllocBuffers(); + void AddMapGeometry( const uint32_t verticesNumber, const uint32_t indicesNumber, + const vertexAttributeSpec_t* attrBegin, + const vertexAttributeSpec_t* attrEnd, + const glIndex_t* indices ); + + private: + uint32_t mapVerticesNumber; + uint32_t mapIndicesNumber; + + GLVAO VAO = GLVAO( 0 ); + + GLBuffer inputVBO = GLBuffer( "geometryCacheInputVBO", Util::ordinal( BufferBind::GEOMETRY_CACHE_INPUT_VBO ), GL_MAP_WRITE_BIT, GL_MAP_INVALIDATE_RANGE_BIT ); + GLBuffer VBO = GLBuffer( "geometryCacheVBO", Util::ordinal( BufferBind::GEOMETRY_CACHE_VBO ), GL_MAP_WRITE_BIT, GL_MAP_FLUSH_EXPLICIT_BIT ); + GLBuffer IBO = GLBuffer( "geometryCacheIBO", Util::ordinal( BufferBind::UNUSED ), GL_MAP_WRITE_BIT, GL_MAP_INVALIDATE_RANGE_BIT ); +}; + +extern GeometryCache geometryCache; + +#endif // GEOMETRY_CACHE_H diff --git a/src/engine/renderer/Material.cpp b/src/engine/renderer/Material.cpp index 8c69f44e76..94b0c37e5e 100644 --- a/src/engine/renderer/Material.cpp +++ b/src/engine/renderer/Material.cpp @@ -36,6 +36,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "tr_local.h" #include "Material.h" #include "ShadeCommon.h" +#include "GeometryCache.h" GLUBO materialsUBO( "materials", Util::ordinal( BufferBind::MATERIALS ), GL_MAP_WRITE_BIT, GL_MAP_INVALIDATE_RANGE_BIT ); GLBuffer texDataBuffer( "texData", Util::ordinal( BufferBind::TEX_DATA ), GL_MAP_WRITE_BIT, GL_MAP_FLUSH_EXPLICIT_BIT ); @@ -1353,9 +1354,6 @@ void MaterialSystem::ProcessStage( drawSurf_t* drawSurf, shaderStage_t* pStage, material.cullType = shader->cullType; material.usePolygonOffset = shader->polygonOffset; - material.vbo = glState.currentVBO; - material.ibo = glState.currentIBO; - material.bspSurface = drawSurf->bspSurface; pStage->materialProcessor( &material, pStage, drawSurf ); pStage->paddedSize = material.shader->GetPaddedSize(); @@ -1454,11 +1452,6 @@ void MaterialSystem::GenerateWorldMaterials() { continue; } - // The verts aren't used; it's only to get the VBO/IBO. - Tess_Begin( Tess_StageIteratorDummy, shader, nullptr, true, -1, 0 ); - rb_surfaceTable[Util::ordinal( *( drawSurf->surface ) )]( drawSurf->surface ); - Tess_Clear(); - // Only add the main surface for surfaces with depth pre-pass or fog to the total count if ( !drawSurf->materialSystemSkip ) { totalDrawSurfs++; @@ -2058,6 +2051,8 @@ void MaterialSystem::RenderMaterials( const shaderSort_t fromSort, const shaderS materialsUBO.BindBufferBase(); + geometryCache.Bind(); + for ( MaterialPack& materialPack : materialPacks ) { if ( materialPack.fromSort >= fromSort && materialPack.toSort <= toSort ) { for ( Material& material : materialPack.materials ) { @@ -2067,6 +2062,8 @@ void MaterialSystem::RenderMaterials( const shaderSort_t fromSort, const shaderS } } + glBindVertexArray( backEnd.currentVAO ); + // Draw the skybox here because we skipped R_AddWorldSurfaces() const bool environmentFogDraw = ( fromSort <= shaderSort_t::SS_ENVIRONMENT_FOG ) && ( toSort >= shaderSort_t::SS_ENVIRONMENT_FOG ); const bool environmentNoFogDraw = ( fromSort <= shaderSort_t::SS_ENVIRONMENT_NOFOG ) && toSort >= ( shaderSort_t::SS_ENVIRONMENT_NOFOG ); @@ -2150,10 +2147,6 @@ void MaterialSystem::RenderMaterial( Material& material, const uint32_t viewID ) material.shaderBinder( &material ); - R_BindVBO( material.vbo ); - R_BindIBO( material.ibo ); - material.shader->SetRequiredVertexPointers(); - if ( !material.texturesResident ) { for ( Texture* texture : material.textures ) { if ( !texture->IsResident() ) { diff --git a/src/engine/renderer/Material.h b/src/engine/renderer/Material.h index ea49e676b1..aac4e40391 100644 --- a/src/engine/renderer/Material.h +++ b/src/engine/renderer/Material.h @@ -114,9 +114,6 @@ struct Material { bool usePolygonOffset = false; - VBO_t* vbo; - IBO_t* ibo; - fog_t* fog = nullptr; std::vector drawSurfs; @@ -125,7 +122,7 @@ struct Material { std::vector textures; bool operator==( const Material& other ) { - return program == other.program && stateBits == other.stateBits && vbo == other.vbo && ibo == other.ibo + return program == other.program && stateBits == other.stateBits && fog == other.fog && cullType == other.cullType && usePolygonOffset == other.usePolygonOffset; } @@ -288,7 +285,10 @@ enum class BufferBind { COMMAND_COUNTERS_ATOMIC = 0, COMMAND_COUNTERS_STORAGE = 4, // Avoid needlessly rebinding buffers PORTAL_SURFACES = 5, - DEBUG = 10 + GEOMETRY_CACHE_INPUT_VBO = 6, + GEOMETRY_CACHE_VBO = 7, + DEBUG = 10, + UNUSED = INT32_MAX }; class MaterialSystem { diff --git a/src/engine/renderer/gl_shader.h b/src/engine/renderer/gl_shader.h index e75a0c6d59..6b6672ffa8 100644 --- a/src/engine/renderer/gl_shader.h +++ b/src/engine/renderer/gl_shader.h @@ -1370,6 +1370,8 @@ class GLUniformBlock class GLBuffer { public: + friend class GLVAO; + std::string name; const GLuint64 SYNC_TIMEOUT = 10000000000; // 10 seconds @@ -1530,6 +1532,78 @@ class GLAtomicCounterBuffer : public GLBuffer { } }; +class GLVAO { + public: + vboAttributeLayout_t attrs[ATTR_INDEX_MAX]; + uint32_t enabledAttrs; + + GLVAO( const GLuint newVBOBindingPoint ) : + VBOBindingPoint( newVBOBindingPoint ) { + } + + ~GLVAO() = default; + + void Bind() { + glBindVertexArray( id ); + } + + void SetAttrs( const vertexAttributeSpec_t* attrBegin, const vertexAttributeSpec_t* attrEnd ) { + uint32_t ofs = 0; + for ( const vertexAttributeSpec_t* spec = attrBegin; spec < attrEnd; spec++ ) { + vboAttributeLayout_t& attr = attrs[spec->attrIndex]; + ASSERT_NQ( spec->numComponents, 0U ); + // vbo->attribBits |= 1 << spec->attrIndex; + attr.componentType = spec->componentStorageType; + if ( attr.componentType == GL_HALF_FLOAT && !glConfig2.halfFloatVertexAvailable ) { + attr.componentType = GL_FLOAT; + } + attr.numComponents = spec->numComponents; + attr.normalize = spec->attrOptions & ATTR_OPTION_NORMALIZE ? GL_TRUE : GL_FALSE; + + attr.ofs = ofs; + ofs += attr.numComponents * ComponentSize( attr.componentType ); + ofs = ( ofs + 3 ) & ~3; // 4 is minimum alignment for any vertex attribute + + enabledAttrs |= 1 << spec->attrIndex; + } + + stride = ofs; + + for ( const vertexAttributeSpec_t* spec = attrBegin; spec < attrEnd; spec++ ) { + const int index = spec->attrIndex; + vboAttributeLayout_t& attr = attrs[index]; + + attr.stride = stride; + + glEnableVertexArrayAttrib( id, index ); + glVertexArrayAttribFormat( id, index, attr.numComponents, attr.componentType, + attr.normalize, attr.ofs ); + glVertexArrayAttribBinding( id, index, VBOBindingPoint ); + } + } + + void SetVertexBuffer( const GLBuffer buffer, const GLuint offset ) { + glVertexArrayVertexBuffer( id, VBOBindingPoint, buffer.id, offset, stride ); + } + + void SetIndexBuffer( const GLBuffer buffer ) { + glVertexArrayElementBuffer( id, buffer.id ); + } + + void GenVAO() { + glGenVertexArrays( 1, &id ); + } + + void DelVAO() { + glDeleteVertexArrays( 1, &id ); + } + + private: + GLuint id; + const GLuint VBOBindingPoint; + GLuint stride; +}; + class GLCompileMacro { private: diff --git a/src/engine/renderer/tr_bsp.cpp b/src/engine/renderer/tr_bsp.cpp index 1fd1c9599f..576139ff98 100644 --- a/src/engine/renderer/tr_bsp.cpp +++ b/src/engine/renderer/tr_bsp.cpp @@ -24,6 +24,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // tr_bsp.c #include "tr_local.h" #include "framework/CommandSystem.h" +#include "GeometryCache.h" /* ======================================================== @@ -3208,6 +3209,10 @@ static void R_CreateWorldVBO() { ATTR_INDEX_TEXCOORD, GL_FLOAT, GL_HALF_FLOAT, &vboVerts[ 0 ].st, 4, sizeof( *vboVerts ), 0 }, }; + if ( glConfig2.usingGeometryCache ) { + geometryCache.AddMapGeometry( vboNumVerts, vboNumIndexes, std::begin( attrs ), std::end( attrs ), vboIdxs ); + } + s_worldData.vbo = R_CreateStaticVBO( "staticWorld_VBO", std::begin( attrs ), std::end( attrs ), vboNumVerts ); s_worldData.ibo = R_CreateStaticIBO2( "staticWorld_IBO", numTriangles, vboIdxs ); diff --git a/src/engine/renderer/tr_init.cpp b/src/engine/renderer/tr_init.cpp index de3d341e68..e28e8839ba 100644 --- a/src/engine/renderer/tr_init.cpp +++ b/src/engine/renderer/tr_init.cpp @@ -25,6 +25,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "framework/CvarSystem.h" #include "DetectGLVendors.h" #include "Material.h" +#include "GeometryCache.h" glconfig_t glConfig; glconfig2_t glConfig2; @@ -92,6 +93,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Cvar::Cvar r_gpuFrustumCulling( "r_gpuFrustumCulling", "Use frustum culling on the GPU for the Material System", Cvar::NONE, true ); Cvar::Cvar r_gpuOcclusionCulling( "r_gpuOcclusionCulling", "Use occlusion culling on the GPU for the Material System", Cvar::NONE, false ); Cvar::Cvar r_materialSystemSkip( "r_materialSystemSkip", "Temporarily skip Material System rendering, using only core renderer instead", Cvar::NONE, false ); + Cvar::Cvar r_geometryCache( "r_geometryCache", "Use Geometry Cache", Cvar::NONE, true ); cvar_t *r_lightStyles; cvar_t *r_exportTextures; cvar_t *r_heatHaze; @@ -1241,6 +1243,7 @@ ScreenshotCmd screenshotPNGRegistration("screenshotPNG", ssFormat_t::SSF_PNG, "p Cvar::Latch( r_realtimeLightLayers ); Cvar::Latch( r_preferBindlessTextures ); Cvar::Latch( r_materialSystem ); + Cvar::Latch( r_geometryCache ); r_drawworld = Cvar_Get( "r_drawworld", "1", CVAR_CHEAT ); r_max_portal_levels = Cvar_Get( "r_max_portal_levels", "5", 0 ); @@ -1566,7 +1569,13 @@ ScreenshotCmd screenshotPNGRegistration("screenshotPNG", ssFormat_t::SSF_PNG, "p R_DoneFreeType(); - materialSystem.Free(); + if ( glConfig2.usingMaterialSystem ) { + materialSystem.Free(); + } + + if ( glConfig2.usingGeometryCache ) { + geometryCache.Free(); + } // shut down platform specific OpenGL stuff if ( destroyWindow ) diff --git a/src/engine/renderer/tr_local.h b/src/engine/renderer/tr_local.h index 201f142a0a..9072884474 100644 --- a/src/engine/renderer/tr_local.h +++ b/src/engine/renderer/tr_local.h @@ -2966,6 +2966,7 @@ enum class shaderProfilerRenderSubGroupsMode { extern Cvar::Cvar r_gpuFrustumCulling; extern Cvar::Cvar r_gpuOcclusionCulling; extern Cvar::Cvar r_materialSystemSkip; + extern Cvar::Cvar r_geometryCache; extern cvar_t *r_lightStyles; extern cvar_t *r_exportTextures; extern cvar_t *r_heatHaze; @@ -3715,6 +3716,10 @@ inline bool checkGLErrors() ============================================================ */ + uint32_t ComponentSize( GLenum type ); + void CopyVertexAttribute( const vboAttributeLayout_t& attrib, const vertexAttributeSpec_t& spec, + uint32_t count, byte* interleavedData ); + VBO_t *R_CreateStaticVBO( Str::StringRef name, const vertexAttributeSpec_t *attrBegin, const vertexAttributeSpec_t *attrEnd, uint32_t numVerts, uint32_t numFrames = 0 ); diff --git a/src/engine/renderer/tr_public.h b/src/engine/renderer/tr_public.h index 5f4a253aaf..5cf5a414a3 100644 --- a/src/engine/renderer/tr_public.h +++ b/src/engine/renderer/tr_public.h @@ -103,6 +103,7 @@ struct glconfig2_t bool shadingLanguage420PackAvailable; bool explicitUniformLocationAvailable; bool directStateAccessAvailable; + bool vertexAttribBindingAvailable; bool shaderImageLoadStoreAvailable; bool shaderAtomicCountersAvailable; bool shaderAtomicCounterOpsAvailable; @@ -117,6 +118,8 @@ struct glconfig2_t bool shaderSubgroupQuadAvailable; bool materialSystemAvailable; // do the driver/hardware support it bool usingMaterialSystem; // are we using it right now + bool geometryCacheAvailable; + bool usingGeometryCache; bool gpuShader4Available; bool gpuShader5Available; bool textureGatherAvailable; diff --git a/src/engine/renderer/tr_shade.cpp b/src/engine/renderer/tr_shade.cpp index 88891a0757..f9d6f77d36 100644 --- a/src/engine/renderer/tr_shade.cpp +++ b/src/engine/renderer/tr_shade.cpp @@ -177,6 +177,8 @@ static void EnableAvailableFeatures() glConfig2.usingMaterialSystem = r_materialSystem.Get() && glConfig2.materialSystemAvailable; glConfig2.usingBindlessTextures = glConfig2.usingMaterialSystem || ( r_preferBindlessTextures.Get() && glConfig2.bindlessTexturesAvailable ); + glConfig2.usingGeometryCache = glConfig2.usingMaterialSystem + || ( r_geometryCache.Get() && glConfig2.geometryCacheAvailable ); } // For shaders that require map data for compile-time values diff --git a/src/engine/renderer/tr_vbo.cpp b/src/engine/renderer/tr_vbo.cpp index 85bc83e700..b7cb12b398 100644 --- a/src/engine/renderer/tr_vbo.cpp +++ b/src/engine/renderer/tr_vbo.cpp @@ -22,6 +22,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // tr_vbo.c #include "tr_local.h" #include "Material.h" +#include "GeometryCache.h" // interleaved data: position, colour, qtangent, texcoord // -> struct shaderVertex_t in tr_local.h @@ -74,7 +75,7 @@ static void R_SetVBOAttributeLayouts( VBO_t *vbo ) } } -static uint32_t ComponentSize( GLenum type ) +uint32_t ComponentSize( GLenum type ) { switch ( type ) { @@ -208,7 +209,7 @@ VBO_t *R_CreateDynamicVBO( const char *name, int numVertexes, uint32_t stateBits return vbo; } -static void CopyVertexAttribute( +void CopyVertexAttribute( const vboAttributeLayout_t &attrib, const vertexAttributeSpec_t &spec, uint32_t count, byte *interleavedData ) { @@ -773,6 +774,10 @@ void R_InitVBOs() materialSystem.InitGLBuffers(); } + if ( glConfig2.usingGeometryCache ) { + geometryCache.InitGLBuffers(); + } + GL_CheckErrors(); } @@ -845,6 +850,10 @@ void R_ShutdownVBOs() materialSystem.FreeGLBuffers(); } + if ( glConfig2.usingGeometryCache ) { + geometryCache.FreeGLBuffers(); + } + tess.verts = tess.vertsBuffer = nullptr; tess.indexes = tess.indexesBuffer = nullptr; } diff --git a/src/engine/sys/sdl_glimp.cpp b/src/engine/sys/sdl_glimp.cpp index 9b9d5296a1..d09480322f 100644 --- a/src/engine/sys/sdl_glimp.cpp +++ b/src/engine/sys/sdl_glimp.cpp @@ -108,6 +108,8 @@ static Cvar::Cvar r_arb_texture_gather( "r_arb_texture_gather", "Use GL_ARB_texture_gather if available", Cvar::NONE, true ); static Cvar::Cvar r_arb_uniform_buffer_object( "r_arb_uniform_buffer_object", "Use GL_ARB_uniform_buffer_object if available", Cvar::NONE, true ); +static Cvar::Cvar r_arb_vertex_attrib_binding( "r_arb_vertex_attrib_binding", + "Use GL_ARB_vertex_attrib_binding if available", Cvar::NONE, true ); static Cvar::Cvar r_ext_draw_buffers( "r_ext_draw_buffers", "Use GL_EXT_draw_buffers if available", Cvar::NONE, true ); static Cvar::Cvar r_ext_gpu_shader4( "r_ext_gpu_shader4", @@ -1996,6 +1998,7 @@ static void GLimp_InitExtensions() Cvar::Latch( r_arb_sync ); Cvar::Latch( r_arb_texture_gather ); Cvar::Latch( r_arb_uniform_buffer_object ); + Cvar::Latch( r_arb_vertex_attrib_binding ); Cvar::Latch( r_ext_draw_buffers ); Cvar::Latch( r_ext_gpu_shader4 ); Cvar::Latch( r_ext_texture_filter_anisotropic ); @@ -2550,12 +2553,18 @@ static void GLimp_InitExtensions() // made required in OpenGL 4.5 glConfig2.directStateAccessAvailable = LOAD_EXTENSION_WITH_TEST( ExtFlag_NONE, ARB_direct_state_access, r_arb_direct_state_access.Get() ); + // made required in OpenGL 4.3 + glConfig2.vertexAttribBindingAvailable = LOAD_EXTENSION_WITH_TEST( ExtFlag_NONE, ARB_vertex_attrib_binding, r_arb_vertex_attrib_binding.Get() ); + + glConfig2.geometryCacheAvailable = glConfig2.vertexAttribBindingAvailable && glConfig2.directStateAccessAvailable; + glConfig2.materialSystemAvailable = glConfig2.shaderDrawParametersAvailable && glConfig2.SSBOAvailable && glConfig2.multiDrawIndirectAvailable && glConfig2.bindlessTexturesAvailable && glConfig2.computeShaderAvailable && glConfig2.shadingLanguage420PackAvailable && glConfig2.explicitUniformLocationAvailable && glConfig2.shaderImageLoadStoreAvailable && glConfig2.shaderAtomicCountersAvailable && glConfig2.indirectParametersAvailable - && glConfig2.directStateAccessAvailable; + && glConfig2.directStateAccessAvailable + && glConfig2.geometryCacheAvailable; // This requires GLEW 2.2+, so skip if it's a lower version #ifdef GL_KHR_shader_subgroup From dcf9aa1c1542735c9c2dfb05c1377a692ee6309c Mon Sep 17 00:00:00 2001 From: VReaperV Date: Mon, 27 Jan 2025 20:10:53 +0300 Subject: [PATCH 25/27] Change GL context cvars to new-style --- src/engine/renderer/tr_init.cpp | 15 ++++----------- src/engine/renderer/tr_local.h | 8 +------- src/engine/sys/sdl_glimp.cpp | 33 +++++++++++++++++++++++---------- 3 files changed, 28 insertions(+), 28 deletions(-) diff --git a/src/engine/renderer/tr_init.cpp b/src/engine/renderer/tr_init.cpp index e28e8839ba..d820b623ea 100644 --- a/src/engine/renderer/tr_init.cpp +++ b/src/engine/renderer/tr_init.cpp @@ -34,9 +34,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA static void GfxInfo_f(); - cvar_t *r_glMajorVersion; - cvar_t *r_glMinorVersion; - cvar_t *r_glProfile; Cvar::Cvar r_glDebugProfile( "r_glDebugProfile", "Enable GL debug message callback", Cvar::NONE, false ); Cvar::Range> r_glDebugMode( "r_glDebugMode", "GL debug message callback mode: 0: none, 1: error, 2: deprecated, 3: undefined, 4: portability, 5: performance," @@ -44,8 +41,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Util::ordinal( glDebugModes_t::GLDEBUG_NONE ), Util::ordinal( glDebugModes_t::GLDEBUG_NONE ), Util::ordinal( glDebugModes_t::GLDEBUG_ALL ) ); - cvar_t *r_glAllowSoftware; - cvar_t *r_glExtendedValidation; + Cvar::Cvar r_glExtendedValidation( "r_glExtendedValidation", + "Enable extra GL context validation", Cvar::NONE, false ); cvar_t *r_ignore; @@ -963,7 +960,7 @@ ScreenshotCmd screenshotPNGRegistration("screenshotPNG", ssFormat_t::SSF_PNG, "p glConfig.vidWidth, glConfig.vidHeight, fsstrings[ +r_fullscreen.Get() ] ); - if ( !!r_glExtendedValidation->integer ) + if ( r_glExtendedValidation.Get() ) { Log::Notice("Using OpenGL version %d.%d, requested: %d.%d, highest: %d.%d", glConfig2.glMajor, glConfig2.glMinor, glConfig2.glRequestedMajor, glConfig2.glRequestedMinor, @@ -1145,12 +1142,8 @@ ScreenshotCmd screenshotPNGRegistration("screenshotPNG", ssFormat_t::SSF_PNG, "p void R_Register() { // OpenGL context selection - r_glMajorVersion = Cvar_Get( "r_glMajorVersion", "", CVAR_LATCH ); - r_glMinorVersion = Cvar_Get( "r_glMinorVersion", "", CVAR_LATCH ); - r_glProfile = Cvar_Get( "r_glProfile", "", CVAR_LATCH ); Cvar::Latch( r_glDebugProfile ); - r_glAllowSoftware = Cvar_Get( "r_glAllowSoftware", "0", CVAR_LATCH ); - r_glExtendedValidation = Cvar_Get( "r_glExtendedValidation", "0", CVAR_LATCH ); + Cvar::Latch( r_glExtendedValidation ); // latched and archived variables r_picMip = Cvar_Get( "r_picMip", "0", CVAR_LATCH | CVAR_ARCHIVE ); diff --git a/src/engine/renderer/tr_local.h b/src/engine/renderer/tr_local.h index 9072884474..896a9b3a50 100644 --- a/src/engine/renderer/tr_local.h +++ b/src/engine/renderer/tr_local.h @@ -2918,16 +2918,10 @@ enum class shaderProfilerRenderSubGroupsMode { extern glstate_t glState; // outside of TR since it shouldn't be cleared during ref re-init -// // cvars -// - extern cvar_t *r_glMajorVersion; // override GL version autodetect (for testing) - extern cvar_t *r_glMinorVersion; - extern cvar_t *r_glProfile; extern Cvar::Cvar r_glDebugProfile; extern Cvar::Range> r_glDebugMode; - extern cvar_t *r_glAllowSoftware; - extern cvar_t *r_glExtendedValidation; + extern Cvar::Cvar r_glExtendedValidation; extern cvar_t *r_ignore; // used for debugging anything diff --git a/src/engine/sys/sdl_glimp.cpp b/src/engine/sys/sdl_glimp.cpp index d09480322f..d95e91d323 100644 --- a/src/engine/sys/sdl_glimp.cpp +++ b/src/engine/sys/sdl_glimp.cpp @@ -41,6 +41,14 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA static Log::Logger logger("glconfig", "", Log::Level::NOTICE); +static Cvar::Range> r_glMajorVersion( "r_glMajorVersion", + "Force this GL major version; 0 to set up automatically", Cvar::NONE, 0, 0, 4 ); +static Cvar::Range> r_glMinorVersion( "r_glMinorVersion", + "Force this GL minor version; 0 to set up automatically", Cvar::NONE, 0, 0, 6 ); +static Cvar::Cvar r_glProfile( "r_glProfile", + "Force this GL profile (core or compat); empty to set up automatically", Cvar::NONE, "" ); +static Cvar::Cvar r_glAllowSoftware( "r_glAllowSoftware", "Allow software rendering", Cvar::NONE, false ); + static Cvar::Modified> r_noBorder( "r_noBorder", "draw window without border", Cvar::ARCHIVE, false); static Cvar::Modified>> r_swapInterval( @@ -770,7 +778,8 @@ static void GLimp_SetAttributes( const glConfiguration &configuration ) SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE, 0 ); SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); - if ( !r_glAllowSoftware->integer ) + Cvar::Latch( r_glAllowSoftware ); + if ( !r_glAllowSoftware.Get() ) { SDL_GL_SetAttribute( SDL_GL_ACCELERATED_VISUAL, 1 ); } @@ -1124,9 +1133,9 @@ static rserr_t GLimp_ValidateBestContext( { 1, 0, glProfile::COMPATIBILITY, true }, }; - logger.Debug( "Validating best OpenGL context." ); + logger.Debug( "Validating best OpenGL context" ); - bool needHighestExtended = !!r_glExtendedValidation->integer; + bool needHighestExtended = r_glExtendedValidation.Get(); for ( int colorBits : {24, 16} ) { for ( auto& row : glSupportArray ) @@ -1182,14 +1191,16 @@ static glConfiguration GLimp_ApplyCustomOptions( const int GLEWmajor, const glCo { glConfiguration customConfiguration = {}; - if ( bestConfiguration.profile == glProfile::CORE && !Q_stricmp( r_glProfile->string, "compat" ) ) + Cvar::Latch( r_glProfile ); + const std::string glProfile = r_glProfile.Get(); + if ( bestConfiguration.profile == glProfile::CORE && !Q_stricmp( glProfile.c_str(), "compat") ) { logger.Debug( "Compatibility profile is forced by r_glProfile" ); customConfiguration.profile = glProfile::COMPATIBILITY; } - if ( bestConfiguration.profile == glProfile::COMPATIBILITY && !Q_stricmp( r_glProfile->string, "core" ) ) + if ( bestConfiguration.profile == glProfile::COMPATIBILITY && !Q_stricmp( glProfile.c_str(), "core" ) ) { if ( GLEWmajor < 2 ) { @@ -1204,8 +1215,10 @@ static glConfiguration GLimp_ApplyCustomOptions( const int GLEWmajor, const glCo } } - customConfiguration.major = std::max( 0, r_glMajorVersion->integer ); - customConfiguration.minor = std::max( 0, r_glMinorVersion->integer ); + Cvar::Latch( r_glMajorVersion ); + Cvar::Latch( r_glMinorVersion ); + customConfiguration.major = std::max( 0, r_glMajorVersion.Get() ); + customConfiguration.minor = std::max( 0, r_glMinorVersion.Get() ); if ( customConfiguration.major == 0 ) { @@ -1598,11 +1611,11 @@ static rserr_t GLimp_SetMode( const int mode, const bool fullscreen, const bool static glConfiguration bestValidatedConfiguration = {}; // considering only up to OpenGL 3.2 static glConfiguration extendedValidationResult = {}; // max available OpenGL version for diagnostic purposes - if ( r_glExtendedValidation->integer && extendedValidationResult.major != 0 ) + if ( r_glExtendedValidation.Get() && extendedValidationResult.major != 0 ) { logger.Debug( "Previously best validated context: %s", ContextDescription( extendedValidationResult ) ); } - else if ( bestValidatedConfiguration.major == 0 || r_glExtendedValidation->integer ) + else if ( bestValidatedConfiguration.major == 0 || r_glExtendedValidation.Get() ) { // Detect best configuration. rserr_t err = GLimp_ValidateBestContext( GLEWmajor, bestValidatedConfiguration, extendedValidationResult ); @@ -1621,7 +1634,7 @@ static rserr_t GLimp_SetMode( const int mode, const bool fullscreen, const bool } } - if ( r_glExtendedValidation->integer ) + if ( r_glExtendedValidation.Get() ) { logger.Notice( "Highest available context: %s", ContextDescription( extendedValidationResult ) ); } From 5b508290b140074562a12ed404a2563e63312cc2 Mon Sep 17 00:00:00 2001 From: VReaperV Date: Mon, 27 Jan 2025 21:44:27 +0300 Subject: [PATCH 26/27] Change most renderer cvars to new-style --- src/engine/renderer/InternalImage.cpp | 14 +- src/engine/renderer/Material.cpp | 42 +-- src/engine/renderer/gl_shader.cpp | 38 ++- src/engine/renderer/tr_animation.cpp | 4 +- src/engine/renderer/tr_backend.cpp | 63 ++-- src/engine/renderer/tr_bsp.cpp | 28 +- src/engine/renderer/tr_cmds.cpp | 68 ++--- src/engine/renderer/tr_curve.cpp | 4 +- src/engine/renderer/tr_image.cpp | 6 +- src/engine/renderer/tr_init.cpp | 423 +++++++++++--------------- src/engine/renderer/tr_light.cpp | 6 +- src/engine/renderer/tr_local.h | 188 ++++++------ src/engine/renderer/tr_main.cpp | 32 +- src/engine/renderer/tr_marks.cpp | 2 +- src/engine/renderer/tr_mesh.cpp | 8 +- src/engine/renderer/tr_model_iqm.cpp | 2 +- src/engine/renderer/tr_scene.cpp | 18 +- src/engine/renderer/tr_shade.cpp | 76 ++--- src/engine/renderer/tr_shader.cpp | 22 +- src/engine/renderer/tr_sky.cpp | 4 +- src/engine/renderer/tr_surface.cpp | 6 +- src/engine/renderer/tr_types.h | 2 +- src/engine/renderer/tr_world.cpp | 24 +- src/engine/sys/sdl_glimp.cpp | 8 +- 24 files changed, 519 insertions(+), 569 deletions(-) diff --git a/src/engine/renderer/InternalImage.cpp b/src/engine/renderer/InternalImage.cpp index d0c870b059..08aa8bb155 100644 --- a/src/engine/renderer/InternalImage.cpp +++ b/src/engine/renderer/InternalImage.cpp @@ -139,8 +139,8 @@ int R_GetImageCustomScalingStep( const image_t *image, const imageParams_t &imag return scalingStep; } - int materialMinDimension = r_ignoreMaterialMinDimension->integer ? 0 : imageParams.minDimension; - int materialMaxDimension = r_ignoreMaterialMaxDimension->integer ? 0 : imageParams.maxDimension; + int materialMinDimension = r_ignoreMaterialMinDimension.Get() ? 0 : imageParams.minDimension; + int materialMaxDimension = r_ignoreMaterialMaxDimension.Get() ? 0 : imageParams.maxDimension; int minDimension; @@ -148,7 +148,7 @@ int R_GetImageCustomScalingStep( const image_t *image, const imageParams_t &imag { minDimension = 1; } - else if ( r_replaceMaterialMinDimensionIfPresentWithMaxDimension->integer ) + else if ( r_replaceMaterialMinDimensionIfPresentWithMaxDimension.Get() ) { minDimension = materialMaxDimension > 0 ? materialMaxDimension : std::numeric_limits::max(); } @@ -159,16 +159,16 @@ int R_GetImageCustomScalingStep( const image_t *image, const imageParams_t &imag int maxDimension = materialMaxDimension > 0 ? materialMaxDimension : std::numeric_limits::max(); - if ( r_imageMaxDimension->integer > 0 ) + if ( r_imageMaxDimension.Get() > 0 ) { - maxDimension = std::min( maxDimension, r_imageMaxDimension->integer ); + maxDimension = std::min( maxDimension, r_imageMaxDimension.Get() ); } // 1st priority: scaledDimension >= minDimension // 2nd priority: scaledDimension <= maxDimension - // 3rd priority: scalingStep >= r_picMip->integer + // 3rd priority: scalingStep >= r_picMip.Get() // 4th priority: scalingStep as low as possible - while ( scaledDimension > maxDimension || scalingStep < r_picMip->integer ) + while ( scaledDimension > maxDimension || scalingStep < r_picMip.Get() ) { scaledDimension >>= 1; diff --git a/src/engine/renderer/Material.cpp b/src/engine/renderer/Material.cpp index 94b0c37e5e..3711da3da0 100644 --- a/src/engine/renderer/Material.cpp +++ b/src/engine/renderer/Material.cpp @@ -193,7 +193,7 @@ void UpdateSurfaceDataLightMapping( uint32_t* materials, shaderStage_t* pStage, // HeightMap if ( pStage->enableReliefMapping ) { - float depthScale = RB_EvalExpression( &pStage->depthScaleExp, r_reliefDepthScale->value ); + float depthScale = RB_EvalExpression( &pStage->depthScaleExp, r_reliefDepthScale.Get() ); depthScale *= shader->reliefDepthScale; gl_lightMappingShaderMaterial->SetUniform_ReliefDepthScale( depthScale ); @@ -209,8 +209,8 @@ void UpdateSurfaceDataLightMapping( uint32_t* materials, shaderStage_t* pStage, } if ( pStage->enableSpecularMapping ) { - float specExpMin = RB_EvalExpression( &pStage->specularExponentMin, r_specularExponentMin->value ); - float specExpMax = RB_EvalExpression( &pStage->specularExponentMax, r_specularExponentMax->value ); + float specExpMin = RB_EvalExpression( &pStage->specularExponentMin, r_specularExponentMin.Get() ); + float specExpMax = RB_EvalExpression( &pStage->specularExponentMax, r_specularExponentMax.Get() ); gl_lightMappingShaderMaterial->SetUniform_SpecularExponent( specExpMin, specExpMax ); } @@ -249,7 +249,7 @@ void UpdateSurfaceDataReflection( uint32_t* materials, shaderStage_t* pStage, bo // u_depthScale u_reliefOffsetBias if ( pStage->enableReliefMapping ) { - float depthScale = RB_EvalExpression( &pStage->depthScaleExp, r_reliefDepthScale->value ); + float depthScale = RB_EvalExpression( &pStage->depthScaleExp, r_reliefDepthScale.Get() ); float reliefDepthScale = shader->reliefDepthScale; depthScale *= reliefDepthScale == 0 ? 1 : reliefDepthScale; gl_reflectionShaderMaterial->SetUniform_ReliefDepthScale( depthScale ); @@ -322,8 +322,8 @@ void UpdateSurfaceDataLiquid( uint32_t* materials, shaderStage_t* pStage, bool, // NOTE: specular component is computed by shader. // FIXME: physical mapping is not implemented. if ( pStage->enableSpecularMapping ) { - float specMin = RB_EvalExpression( &pStage->specularExponentMin, r_specularExponentMin->value ); - float specMax = RB_EvalExpression( &pStage->specularExponentMax, r_specularExponentMax->value ); + float specMin = RB_EvalExpression( &pStage->specularExponentMin, r_specularExponentMin.Get() ); + float specMax = RB_EvalExpression( &pStage->specularExponentMax, r_specularExponentMax.Get() ); gl_liquidShaderMaterial->SetUniform_SpecularExponent( specMin, specMax ); } @@ -335,7 +335,7 @@ void UpdateSurfaceDataLiquid( uint32_t* materials, shaderStage_t* pStage, bool, float depthScale; float reliefDepthScale; - depthScale = RB_EvalExpression( &pStage->depthScaleExp, r_reliefDepthScale->value ); + depthScale = RB_EvalExpression( &pStage->depthScaleExp, r_reliefDepthScale.Get() ); reliefDepthScale = tess.surfaceShader->reliefDepthScale; depthScale *= reliefDepthScale == 0 ? 1 : reliefDepthScale; gl_liquidShaderMaterial->SetUniform_ReliefDepthScale( depthScale ); @@ -1407,10 +1407,10 @@ void MaterialSystem::ProcessStage( drawSurf_t* drawSurf, shaderStage_t* pStage, * A material represents a distinct global OpenGL state (e. g. blend function, depth test, depth write etc.) * Materials can have a dependency on other materials to make sure that consecutive stages are rendered in the proper order */ void MaterialSystem::GenerateWorldMaterials() { - const int current_r_nocull = r_nocull->integer; - const int current_r_drawworld = r_drawworld->integer; - r_nocull->integer = 1; - r_drawworld->integer = 1; + const bool current_r_nocull = r_nocull.Get(); + const bool current_r_drawworld = r_drawworld.Get(); + r_nocull.Set( true ); + r_drawworld.Set( true ); generatingWorldCommandBuffer = true; Log::Debug( "Generating world materials" ); @@ -1485,8 +1485,8 @@ void MaterialSystem::GenerateWorldMaterials() { } } */ - r_nocull->integer = current_r_nocull; - r_drawworld->integer = current_r_drawworld; + r_nocull.Set( current_r_nocull ); + r_drawworld.Set( current_r_drawworld ); AddAllWorldSurfaces(); GeneratePortalBoundingSpheres(); @@ -1602,7 +1602,7 @@ void MaterialSystem::QueueSurfaceCull( const uint32_t viewID, const vec3_t origi } void MaterialSystem::DepthReduction() { - if ( r_lockpvs->integer ) { + if ( r_lockpvs.Get() ) { if ( !PVSLocked ) { lockedDepthImage = depthImage; } @@ -1709,11 +1709,11 @@ void MaterialSystem::CullSurfaces() { } if ( PVSLocked ) { - if ( r_lockpvs->integer == 0 ) { + if ( !r_lockpvs.Get() ) { PVSLocked = false; } } - if ( r_lockpvs->integer == 1 && !PVSLocked ) { + if ( r_lockpvs.Get() && !PVSLocked ) { PVSLocked = true; for ( int i = 0; i < 6; i++ ) { VectorCopy( frustum[0][i].normal, lockedFrustums[view][i].normal ); @@ -2005,7 +2005,7 @@ void MaterialSystem::AddPortalSurfaces() { return; } - if ( r_lockpvs->integer ) { + if ( r_lockpvs.Get() ) { return; } @@ -2030,7 +2030,7 @@ void MaterialSystem::AddAutospriteSurfaces() { } void MaterialSystem::RenderMaterials( const shaderSort_t fromSort, const shaderSort_t toSort, const uint32_t viewID ) { - if ( !r_drawworld->integer ) { + if ( !r_drawworld.Get() ) { return; } @@ -2126,7 +2126,7 @@ void MaterialSystem::RenderMaterial( Material& material, const uint32_t viewID ) } if( material.shaderBinder == BindShaderFog ) { - if ( r_noFog->integer || !r_wolfFog->integer || ( backEnd.refdef.rdflags & RDF_NOWORLDMODEL ) ) { + if ( r_noFog.Get() || !r_wolfFog.Get() || ( backEnd.refdef.rdflags & RDF_NOWORLDMODEL ) ) { return; } } @@ -2136,7 +2136,7 @@ void MaterialSystem::RenderMaterial( Material& material, const uint32_t viewID ) GL_State( stateBits ); if ( material.usePolygonOffset ) { glEnable( GL_POLYGON_OFFSET_FILL ); - GL_PolygonOffset( r_offsetFactor->value, r_offsetUnits->value ); + GL_PolygonOffset( r_offsetFactor.Get(), r_offsetUnits.Get() ); } else { glDisable( GL_POLYGON_OFFSET_FILL ); } @@ -2278,7 +2278,7 @@ void MaterialSystem::RenderMaterial( Material& material, const uint32_t viewID ) RenderIndirect( material, viewID ); } - if ( r_showTris->integer + if ( r_showTris.Get() && ( material.stateBits & GLS_DEPTHMASK_TRUE ) == 0 && ( material.shaderBinder == &BindShaderLightMapping || material.shaderBinder == &BindShaderGeneric3D ) ) { diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index 058ca81543..0f15568b58 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -623,9 +623,14 @@ static std::string GenEngineConstants() { // Engine constants std::string str; - AddDefine( str, "r_AmbientScale", r_ambientScale.Get() ); - AddDefine( str, "r_SpecularScale", r_specularScale->value ); - AddDefine( str, "r_zNear", r_znear->value ); + if ( r_ambientScale.Get() ) { + AddDefine( str, "r_AmbientScale", 1 ); + } + + if ( r_specularScale.Get() ) { + AddDefine( str, "r_SpecularScale", 1 ); + } + AddDefine( str, "r_zNear", r_znear.Get() ); AddDefine( str, "M_PI", static_cast< float >( M_PI ) ); AddDefine( str, "MAX_SHADOWMAPS", MAX_SHADOWMAPS ); @@ -736,22 +741,23 @@ static std::string GenEngineConstants() { AddDefine( str, "r_realtimeLightingRenderer", r_realtimeLightingRenderer.Get() ); } - if ( r_precomputedLighting->integer ) + if ( r_precomputedLighting.Get() ) { AddDefine( str, "r_precomputedLighting", 1 ); + } - if ( r_showNormalMaps->integer ) + if ( r_showNormalMaps.Get() ) { AddDefine( str, "r_showNormalMaps", 1 ); } - else if ( r_showMaterialMaps->integer ) + else if ( r_showMaterialMaps.Get() ) { AddDefine( str, "r_showMaterialMaps", 1 ); } - else if ( r_showLightMaps->integer ) + else if ( r_showLightMaps.Get() ) { AddDefine( str, "r_showLightMaps", 1 ); } - else if ( r_showDeluxeMaps->integer ) + else if ( r_showDeluxeMaps.Get() ) { AddDefine( str, "r_showDeluxeMaps", 1 ); } @@ -793,16 +799,18 @@ static std::string GenEngineConstants() { AddConst( str, "MAX_GLSL_BONES", 4 ); } - if ( r_halfLambertLighting->integer ) + if ( r_halfLambertLighting.Get() ) + { AddDefine( str, "r_halfLambertLighting", 1 ); + } - if ( r_rimLighting->integer ) + if ( r_rimLighting.Get() ) { AddDefine( str, "r_rimLighting", 1 ); - AddConst( str, "r_RimExponent", r_rimExponent->value ); + AddConst( str, "r_RimExponent", r_rimExponent.Get() ); } - if ( r_showLightTiles->integer ) + if ( r_showLightTiles.Get() ) { AddDefine( str, "r_showLightTiles", 1 ); } @@ -812,7 +820,7 @@ static std::string GenEngineConstants() { AddDefine( str, "r_normalMapping", 1 ); } - if ( r_liquidMapping->integer ) + if ( r_liquidMapping.Get() ) { AddDefine( str, "r_liquidMapping", 1 ); } @@ -827,7 +835,7 @@ static std::string GenEngineConstants() { AddDefine( str, "r_physicalMapping", 1 ); } - if ( r_glowMapping->integer ) + if ( r_glowMapping.Get() ) { AddDefine( str, "r_glowMapping", 1 ); } @@ -837,8 +845,6 @@ static std::string GenEngineConstants() { AddDefine( str, "r_colorGrading", 1 ); } - AddDefine( str, "r_zNear", r_znear->value ); - return str; } diff --git a/src/engine/renderer/tr_animation.cpp b/src/engine/renderer/tr_animation.cpp index ea39201019..b1c7ad419e 100644 --- a/src/engine/renderer/tr_animation.cpp +++ b/src/engine/renderer/tr_animation.cpp @@ -683,7 +683,7 @@ void R_AddMD5Surfaces( trRefEntity_t *ent ) // see if we are in a fog volume fogNum = R_FogWorldBox( ent->worldBounds ); - if ( !r_vboModels->integer || !model->numVBOSurfaces || + if ( !r_vboModels.Get() || !model->numVBOSurfaces || ( !glConfig2.vboVertexSkinningAvailable && ent->e.skeleton.type == refSkeletonType_t::SK_ABSOLUTE ) ) { shader_t *shader; @@ -983,7 +983,7 @@ void R_AddMD5Interactions( trRefEntity_t *ent, trRefLight_t *light, interactionT cubeSideBits = R_CalcLightCubeSideBits( light, ent->worldBounds ); - if ( !r_vboModels->integer || !model->numVBOSurfaces || + if ( !r_vboModels.Get() || !model->numVBOSurfaces || ( !glConfig2.vboVertexSkinningAvailable && ent->e.skeleton.type == refSkeletonType_t::SK_ABSOLUTE ) ) { shader_t *shader = nullptr; diff --git a/src/engine/renderer/tr_backend.cpp b/src/engine/renderer/tr_backend.cpp index 72c040ab27..c996fdef39 100644 --- a/src/engine/renderer/tr_backend.cpp +++ b/src/engine/renderer/tr_backend.cpp @@ -55,7 +55,7 @@ void GL_Bind( image_t *image ) texnum = image->texnum; - if ( r_nobind->integer && tr.blackImage ) + if ( r_nobind.Get() && tr.blackImage ) { // performance evaluation option texnum = tr.blackImage->texnum; @@ -1239,7 +1239,7 @@ static void RB_RenderInteractions() GLimp_LogComment( "--- RB_RenderInteractions ---\n" ); - if ( r_speeds->integer == Util::ordinal(renderSpeeds_t::RSPEEDS_SHADING_TIMES)) + if ( r_speeds.Get() == Util::ordinal( renderSpeeds_t::RSPEEDS_SHADING_TIMES ) ) { glFinish(); startTime = ri.Milliseconds(); @@ -1366,7 +1366,7 @@ static void RB_RenderInteractions() GL_CheckErrors(); - if ( r_speeds->integer == Util::ordinal(renderSpeeds_t::RSPEEDS_SHADING_TIMES) ) + if ( r_speeds.Get() == Util::ordinal( renderSpeeds_t::RSPEEDS_SHADING_TIMES ) ) { glFinish(); endTime = ri.Milliseconds(); @@ -2117,7 +2117,7 @@ static void RB_RenderInteractionsShadowMapped() GLimp_LogComment( "--- RB_RenderInteractionsShadowMapped ---\n" ); - if ( r_speeds->integer == Util::ordinal(renderSpeeds_t::RSPEEDS_SHADING_TIMES) ) + if ( r_speeds.Get() == Util::ordinal( renderSpeeds_t::RSPEEDS_SHADING_TIMES ) ) { glFinish(); startTime = ri.Milliseconds(); @@ -2665,7 +2665,7 @@ static void RB_RenderInteractionsShadowMapped() GL_CheckErrors(); - if ( r_speeds->integer == Util::ordinal(renderSpeeds_t::RSPEEDS_SHADING_TIMES) ) + if ( r_speeds.Get() == Util::ordinal( renderSpeeds_t::RSPEEDS_SHADING_TIMES ) ) { glFinish(); endTime = ri.Milliseconds(); @@ -2963,7 +2963,7 @@ void RB_RenderGlobalFog() return; } - if ( r_noFog->integer ) + if ( r_noFog.Get() ) { return; } @@ -3212,7 +3212,7 @@ void RB_RenderSSAO() GL_State( GLS_DEPTHTEST_DISABLE | GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ZERO ); GL_Cull( cullType_t::CT_TWO_SIDED ); - if ( r_ssao->integer < 0 ) { + if ( r_ssao.Get() < 0 ) { // clear the screen to show only SSAO GL_ClearColor( 1.0, 1.0, 1.0, 1.0 ); glClear( GL_COLOR_BUFFER_BIT ); @@ -3228,9 +3228,9 @@ void RB_RenderSSAO() gl_ssaoShader->SetUniform_zFar( zParams ); vec3_t unprojectionParams; - unprojectionParams[ 0 ] = -r_znear->value * zParams[ 2 ]; - unprojectionParams[ 1 ] = 2.0 * ( zParams[ 2 ] - r_znear->value ); - unprojectionParams[ 2 ] = 2.0 * zParams[ 2 ] - r_znear->value; + unprojectionParams[ 0 ] = -r_znear.Get() * zParams[ 2 ]; + unprojectionParams[ 1 ] = 2.0 * ( zParams[ 2 ] - r_znear.Get() ); + unprojectionParams[ 2 ] = 2.0 * zParams[ 2 ] - r_znear.Get(); gl_ssaoShader->SetUniform_UnprojectionParams( unprojectionParams ); @@ -3267,7 +3267,7 @@ void RB_FXAA() return; } - if ( !r_FXAA->integer || !gl_fxaaShader ) + if ( !r_FXAA.Get() || !gl_fxaaShader ) { return; } @@ -3330,7 +3330,7 @@ void RB_CameraPostFX() gl_cameraEffectsShader->SetUniform_ColorModulate( backEnd.viewParms.gradingWeights ); - gl_cameraEffectsShader->SetUniform_InverseGamma( 1.0 / r_gamma->value ); + gl_cameraEffectsShader->SetUniform_InverseGamma( 1.0 / r_gamma.Get() ); // This shader is run last, so let it render to screen instead of // tr.mainFBO @@ -3359,7 +3359,7 @@ static void RB_RenderDebugUtils() { GLimp_LogComment( "--- RB_RenderDebugUtils ---\n" ); - if ( r_showLightTransforms->integer || r_showShadowLod->integer ) + if ( r_showLightTransforms.Get() || r_showShadowLod->integer ) { const interaction_t *ia; trRefLight_t *light; @@ -3495,7 +3495,7 @@ static void RB_RenderDebugUtils() GL_LoadModelViewMatrix( backEnd.viewParms.world.modelViewMatrix ); } - if ( r_showLightInteractions->integer ) + if ( r_showLightInteractions.Get() ) { int i; int cubeSides; @@ -3617,7 +3617,7 @@ static void RB_RenderDebugUtils() GL_LoadModelViewMatrix( backEnd.viewParms.world.modelViewMatrix ); } - if ( r_showEntityTransforms->integer ) + if ( r_showEntityTransforms.Get() ) { trRefEntity_t *ent; int i; @@ -3679,7 +3679,7 @@ static void RB_RenderDebugUtils() GL_LoadModelViewMatrix( backEnd.viewParms.world.modelViewMatrix ); } - if ( r_showSkeleton->integer ) + if ( r_showSkeleton.Get() ) { int i, j, k, parentIndex; trRefEntity_t *ent; @@ -3897,7 +3897,7 @@ static void RB_RenderDebugUtils() } } - if ( r_showLightScissors->integer ) + if ( r_showLightScissors.Get() ) { interaction_t *ia; int iaCount; @@ -4111,7 +4111,7 @@ static void RB_RenderDebugUtils() GL_LoadModelViewMatrix( backEnd.viewParms.world.modelViewMatrix ); } - if ( r_showLightGrid->integer && !( backEnd.refdef.rdflags & RDF_NOWORLDMODEL ) ) + if ( r_showLightGrid.Get() && !( backEnd.refdef.rdflags & RDF_NOWORLDMODEL ) ) { int x, y, z, k; vec3_t offset; @@ -4205,7 +4205,7 @@ static void RB_RenderDebugUtils() Tess_End(); } - if ( r_showBspNodes->integer ) + if ( r_showBspNodes.Get() ) { if ( ( backEnd.refdef.rdflags & ( RDF_NOWORLDMODEL ) ) || !tr.world ) { @@ -4388,7 +4388,7 @@ static void RB_RenderDebugUtils() if ( node->contents != -1 ) { - if ( r_showBspNodes->integer == 3 ) + if ( r_showBspNodes.Get() == 3 ) { continue; } @@ -4412,7 +4412,7 @@ static void RB_RenderDebugUtils() } else { - if ( r_showBspNodes->integer == 2 ) + if ( r_showBspNodes.Get() == 2 ) { continue; } @@ -4430,7 +4430,7 @@ static void RB_RenderDebugUtils() if ( node->contents != -1 ) { glEnable( GL_POLYGON_OFFSET_FILL ); - GL_PolygonOffset( r_offsetFactor->value, r_offsetUnits->value ); + GL_PolygonOffset( r_offsetFactor.Get(), r_offsetUnits.Get() ); } Tess_Begin( Tess_StageIteratorDebug, nullptr, nullptr, true, -1, 0 ); @@ -4650,7 +4650,7 @@ static void RB_RenderView( bool depthPass ) GL_CheckErrors(); - if ( r_speeds->integer == Util::ordinal(renderSpeeds_t::RSPEEDS_SHADING_TIMES) ) + if ( r_speeds.Get() == Util::ordinal( renderSpeeds_t::RSPEEDS_SHADING_TIMES ) ) { glFinish(); startTime = ri.Milliseconds(); @@ -4693,11 +4693,11 @@ static void RB_RenderView( bool depthPass ) RB_RenderDrawSurfaces( shaderSort_t::SS_ENVIRONMENT_FOG, shaderSort_t::SS_OPAQUE, DRAWSURFACES_ALL ); } - if ( r_ssao->integer ) { + if ( r_ssao.Get() ) { RB_RenderSSAO(); } - if ( r_speeds->integer == Util::ordinal(renderSpeeds_t::RSPEEDS_SHADING_TIMES) ) + if ( r_speeds.Get() == Util::ordinal( renderSpeeds_t::RSPEEDS_SHADING_TIMES ) ) { glFinish(); endTime = ri.Milliseconds(); @@ -4734,7 +4734,7 @@ static void RB_RenderView( bool depthPass ) if ( backEnd.viewParms.portalLevel > 0 ) { - if ( r_liquidMapping->integer ) + if ( r_liquidMapping.Get() ) { // capture current color buffer // liquid shader will then bind tr.portalRenderImage @@ -5376,13 +5376,14 @@ const RenderCommand *ClearBufferCommand::ExecuteSelf( ) const GL_CheckErrors(); // sync with gl if needed - if ( r_finish->integer == 1 && !glState.finishCalled ) + if ( r_finish.Get() && !glState.finishCalled ) { glFinish(); glState.finishCalled = true; } - if ( r_finish->integer == 0 ) + // WTF? + if ( !r_finish.Get() ) { glState.finishCalled = true; } @@ -5672,7 +5673,7 @@ void RB_ShowImages() y = i / 20 * h; // show in proportional size in mode 2 - if ( r_showImages->integer == 2 ) + if ( r_showImages.Get() == 2 ) { w *= image->uploadWidth / 512.0f; h *= image->uploadHeight / 512.0f; @@ -5707,7 +5708,7 @@ const RenderCommand *SwapBuffersCommand::ExecuteSelf( ) const Tess_End(); // texture swapping test - if ( r_showImages->integer ) + if ( r_showImages.Get() ) { RB_ShowImages(); } @@ -5791,7 +5792,7 @@ void RB_ExecuteRenderCommands( const void *data ) t1 = ri.Milliseconds(); - if ( !r_smp->integer || data == backEndData[ 0 ]->commands.cmds ) + if ( !r_smp.Get() || data == backEndData[0]->commands.cmds ) { backEnd.smpFrame = 0; } diff --git a/src/engine/renderer/tr_bsp.cpp b/src/engine/renderer/tr_bsp.cpp index 576139ff98..eb84440152 100644 --- a/src/engine/renderer/tr_bsp.cpp +++ b/src/engine/renderer/tr_bsp.cpp @@ -489,7 +489,7 @@ R_LoadLightmaps */ static void R_LoadLightmaps( lump_t *l, const char *bspName ) { - tr.worldLightMapping = r_precomputedLighting->integer && tr.lightMode == lightMode_t::MAP; + tr.worldLightMapping = r_precomputedLighting.Get() && tr.lightMode == lightMode_t::MAP; /* All lightmaps will be loaded if either light mapping or deluxe mapping is enabled. */ @@ -976,7 +976,7 @@ static void ParseFace( dsurface_t *ds, drawVert_t *verts, bspSurface_t *surf, in // get shader value surf->shader = ShaderForShaderNum( ds->shaderNum ); - if ( r_singleShader->integer && !surf->shader->isSky ) + if ( r_singleShader.Get() && !surf->shader->isSky ) { surf->shader = tr.defaultShader; } @@ -1187,7 +1187,7 @@ static void ParseMesh( dsurface_t *ds, drawVert_t *verts, bspSurface_t *surf ) // get shader value surf->shader = ShaderForShaderNum( ds->shaderNum ); - if ( r_singleShader->integer && !surf->shader->isSky ) + if ( r_singleShader.Get() && !surf->shader->isSky ) { surf->shader = tr.defaultShader; } @@ -1313,7 +1313,7 @@ static void ParseTriSurf( dsurface_t *ds, drawVert_t *verts, bspSurface_t *surf, // get shader surf->shader = ShaderForShaderNum( ds->shaderNum ); - if ( r_singleShader->integer && !surf->shader->isSky ) + if ( r_singleShader.Get() && !surf->shader->isSky ) { surf->shader = tr.defaultShader; } @@ -1493,7 +1493,7 @@ static void ParseFlare( dsurface_t *ds, bspSurface_t *surf ) // get shader surf->shader = ShaderForShaderNum( ds->shaderNum ); - if ( r_singleShader->integer && !surf->shader->isSky ) + if ( r_singleShader.Get() && !surf->shader->isSky ) { surf->shader = tr.defaultShader; } @@ -3220,7 +3220,7 @@ static void R_CreateWorldVBO() ri.Hunk_FreeTempMemory( vboIdxs ); ri.Hunk_FreeTempMemory( vboVerts ); - if ( r_mergeLeafSurfaces->integer ) + if ( r_mergeLeafSurfaces.Get() ) { // count merged/unmerged surfaces int numUnmergedSurfaces = 0; @@ -3490,17 +3490,17 @@ static void R_LoadSurfaces( lump_t *surfs, lump_t *verts, lump_t *indexLump ) } } - Log::Debug("...loaded %d faces, %i meshes, %i trisurfs, %i flares %i foliages", numFaces, numMeshes, numTriSurfs, + Log::Debug( "...loaded %d faces, %i meshes, %i trisurfs, %i flares %i foliages", numFaces, numMeshes, numTriSurfs, numFlares, numFoliages ); - if ( r_stitchCurves->integer ) + if ( r_stitchCurves.Get() ) { R_StitchAllPatches(); } R_FixSharedVertexLodError(); - if ( r_stitchCurves->integer ) + if ( r_stitchCurves.Get() ) { R_MovePatchSurfacesToHunk(); } @@ -3672,7 +3672,7 @@ static void R_LoadNodesAndLeafs( lump_t *nodeLump, lump_t *leafLump ) backEndData[ 0 ]->traversalList = ( bspNode_t ** ) ri.Hunk_Alloc( sizeof( bspNode_t * ) * s_worldData.numnodes, ha_pref::h_low ); backEndData[ 0 ]->traversalLength = 0; - if ( r_smp->integer ) + if ( r_smp.Get() ) { backEndData[ 1 ]->traversalList = ( bspNode_t ** ) ri.Hunk_Alloc( sizeof( bspNode_t * ) * s_worldData.numnodes, ha_pref::h_low ); backEndData[ 1 ]->traversalLength = 0; @@ -4050,7 +4050,7 @@ void R_LoadLightGrid( lump_t *l ) R_SetConstantColorLightGrid( color ); } - if ( !r_precomputedLighting->integer ) + if ( !r_precomputedLighting.Get() ) { const byte color[3] { 64, 64, 64 }; R_SetConstantColorLightGrid( color ); @@ -4817,8 +4817,8 @@ void R_BuildCubeMaps() r_gpuOcclusionCulling.Set( false ); // We still need to run the cameraEffects shader for overbright, so set r_gamma to 1.0 here to avoid applying it twice to the reflection - const float gamma = r_gamma->value; - Cvar_SetValue( "r_gamma", 1.0 ); + const float gamma = r_gamma.Get(); + r_gamma.Set( 1.0f ); for ( size_t i = 0; i < tr.cubeProbes.size(); i++ ) { @@ -5019,7 +5019,7 @@ void R_BuildCubeMaps() r_gpuOcclusionCulling.Set( gpuOcclusionCulling ); - Cvar_SetValue( "r_gamma", gamma ); + r_gamma.Set( gamma ); // turn pixel targets off tr.refdef.pixelTarget = nullptr; diff --git a/src/engine/renderer/tr_cmds.cpp b/src/engine/renderer/tr_cmds.cpp index 441da7184a..43635152f7 100644 --- a/src/engine/renderer/tr_cmds.cpp +++ b/src/engine/renderer/tr_cmds.cpp @@ -32,7 +32,7 @@ R_PerformanceCounters */ void R_PerformanceCounters() { - if ( !r_speeds->integer ) + if ( !r_speeds.Get() ) { // clear the counters even if we aren't printing tr.pc = {}; @@ -40,73 +40,73 @@ void R_PerformanceCounters() return; } - if ( r_speeds->integer == Util::ordinal(renderSpeeds_t::RSPEEDS_GENERAL)) + if ( r_speeds.Get() == Util::ordinal( renderSpeeds_t::RSPEEDS_GENERAL ) ) { - Log::Notice("%i views %i portals %i batches %i surfs %i leafs %i verts %i tris", + Log::Notice( "%i views %i portals %i batches %i surfs %i leafs %i verts %i tris", backEnd.pc.c_views, backEnd.pc.c_portals, backEnd.pc.c_batches, backEnd.pc.c_surfaces, tr.pc.c_leafs, backEnd.pc.c_vertexes, backEnd.pc.c_indexes / 3 ); - Log::Notice("%i lights %i bout %i pvsout %i interactions", + Log::Notice( "%i lights %i bout %i pvsout %i interactions", tr.pc.c_dlights, tr.pc.c_box_cull_light_out, tr.pc.c_pvs_cull_light_out, tr.pc.c_dlightInteractions ); - Log::Notice("%i draws %i vbos %i ibos %i verts %i tris", + Log::Notice( "%i draws %i vbos %i ibos %i verts %i tris", backEnd.pc.c_drawElements, backEnd.pc.c_vboVertexBuffers, backEnd.pc.c_vboIndexBuffers, backEnd.pc.c_vboVertexes, backEnd.pc.c_vboIndexes / 3 ); - Log::Notice("%i multidraws %i primitives %i tris", + Log::Notice( "%i multidraws %i primitives %i tris", backEnd.pc.c_multiDrawElements, backEnd.pc.c_multiDrawPrimitives, backEnd.pc.c_multiVboIndexes / 3 ); } - else if ( r_speeds->integer == Util::ordinal(renderSpeeds_t::RSPEEDS_CULLING )) + else if ( r_speeds.Get() == Util::ordinal( renderSpeeds_t::RSPEEDS_CULLING ) ) { - Log::Notice("(gen) %i pin %i pout %i bin %i bclip %i bout", + Log::Notice( "(gen) %i pin %i pout %i bin %i bclip %i bout", tr.pc.c_plane_cull_in, tr.pc.c_plane_cull_out, tr.pc.c_box_cull_in, tr.pc.c_box_cull_clip, tr.pc.c_box_cull_out ); - Log::Notice("(mdv) %i sin %i sclip %i sout %i bin %i bclip %i bout", + Log::Notice( "(mdv) %i sin %i sclip %i sout %i bin %i bclip %i bout", tr.pc.c_sphere_cull_mdv_in, tr.pc.c_sphere_cull_mdv_clip, tr.pc.c_sphere_cull_mdv_out, tr.pc.c_box_cull_mdv_in, tr.pc.c_box_cull_mdv_clip, tr.pc.c_box_cull_mdv_out ); - Log::Notice("(md5) %i bin %i bclip %i bout", + Log::Notice( "(md5) %i bin %i bclip %i bout", tr.pc.c_box_cull_md5_in, tr.pc.c_box_cull_md5_clip, tr.pc.c_box_cull_md5_out ); } - else if ( r_speeds->integer == Util::ordinal(renderSpeeds_t::RSPEEDS_VIEWCLUSTER )) + else if ( r_speeds.Get() == Util::ordinal( renderSpeeds_t::RSPEEDS_VIEWCLUSTER ) ) { - Log::Notice("viewcluster: %i", tr.visClusters[ tr.visIndex ] ); + Log::Notice( "viewcluster: %i", tr.visClusters[ tr.visIndex ] ); } - else if ( r_speeds->integer == Util::ordinal(renderSpeeds_t::RSPEEDS_LIGHTS )) + else if ( r_speeds.Get() == Util::ordinal( renderSpeeds_t::RSPEEDS_LIGHTS ) ) { - Log::Notice("dlight srf:%i culled:%i", tr.pc.c_dlightSurfaces, tr.pc.c_dlightSurfacesCulled ); + Log::Notice( "dlight srf:%i culled:%i", tr.pc.c_dlightSurfaces, tr.pc.c_dlightSurfacesCulled ); - Log::Notice("dlights:%i interactions:%i", tr.pc.c_dlights, tr.pc.c_dlightInteractions ); + Log::Notice( "dlights:%i interactions:%i", tr.pc.c_dlights, tr.pc.c_dlightInteractions ); } - else if ( r_speeds->integer == Util::ordinal(renderSpeeds_t::RSPEEDS_SHADOWCUBE_CULLING )) + else if ( r_speeds.Get() == Util::ordinal( renderSpeeds_t::RSPEEDS_SHADOWCUBE_CULLING ) ) { - Log::Notice("omni pyramid tests:%i bin:%i bclip:%i bout:%i", + Log::Notice( "omni pyramid tests:%i bin:%i bclip:%i bout:%i", tr.pc.c_pyramidTests, tr.pc.c_pyramid_cull_ent_in, tr.pc.c_pyramid_cull_ent_clip, tr.pc.c_pyramid_cull_ent_out ); } - else if ( r_speeds->integer == Util::ordinal(renderSpeeds_t::RSPEEDS_FOG )) + else if ( r_speeds.Get() == Util::ordinal( renderSpeeds_t::RSPEEDS_FOG ) ) { - Log::Notice("fog srf:%i batches:%i", backEnd.pc.c_fogSurfaces, backEnd.pc.c_fogBatches ); + Log::Notice( "fog srf:%i batches:%i", backEnd.pc.c_fogSurfaces, backEnd.pc.c_fogBatches ); } - else if ( r_speeds->integer == Util::ordinal(renderSpeeds_t::RSPEEDS_FLARES )) + else if ( r_speeds.Get() == Util::ordinal( renderSpeeds_t::RSPEEDS_FLARES ) ) { - Log::Notice("flare adds:%i tests:%i renders:%i", + Log::Notice( "flare adds:%i tests:%i renders:%i", backEnd.pc.c_flareAdds, backEnd.pc.c_flareTests, backEnd.pc.c_flareRenders ); } - else if ( r_speeds->integer == Util::ordinal(renderSpeeds_t::RSPEEDS_SHADING_TIMES )) + else if ( r_speeds.Get() == Util::ordinal( renderSpeeds_t::RSPEEDS_SHADING_TIMES ) ) { - Log::Notice("forward shading times: ambient:%i lighting:%i", backEnd.pc.c_forwardAmbientTime, + Log::Notice( "forward shading times: ambient:%i lighting:%i", backEnd.pc.c_forwardAmbientTime, backEnd.pc.c_forwardLightingTime ); } - else if ( r_speeds->integer == Util::ordinal(renderSpeeds_t::RSPEEDS_NEAR_FAR )) + else if ( r_speeds.Get() == Util::ordinal( renderSpeeds_t::RSPEEDS_NEAR_FAR ) ) { - Log::Notice("zNear: %.0f zFar: %.0f", tr.viewParms.zNear, tr.viewParms.zFar ); + Log::Notice( "zNear: %.0f zFar: %.0f", tr.viewParms.zNear, tr.viewParms.zFar ); } tr.pc = {}; @@ -140,18 +140,18 @@ void R_IssueRenderCommands( bool runPerformanceCounters ) { c_blockedOnRender++; - if ( r_showSmp->integer ) + if ( r_showSmp.Get() ) { - Log::Notice("R"); + Log::Notice( "R" ); } } else { c_blockedOnMain++; - if ( r_showSmp->integer ) + if ( r_showSmp.Get() ) { - Log::Notice("."); + Log::Notice( "." ); } } @@ -167,7 +167,7 @@ void R_IssueRenderCommands( bool runPerformanceCounters ) } // actually start the commands going - if ( !r_skipBackEnd->integer ) + if ( !r_skipBackEnd.Get() ) { // let it start on the new batch if ( !glConfig.smpActive ) @@ -598,7 +598,7 @@ void RE_2DPolyies( polyVert_t *verts, int numverts, qhandle_t hShader ) { Poly2dCommand *cmd; - if ( r_numPolyVerts + numverts > r_maxPolyVerts->integer ) + if ( r_numPolyVerts + numverts > r_maxPolyVerts.Get() ) { return; } @@ -622,12 +622,12 @@ void RE_2DPolyiesIndexed( polyVert_t *verts, int numverts, int *indexes, int num { Poly2dIndexedCommand *cmd; - if ( r_numPolyVerts + numverts > r_maxPolyVerts->integer ) + if ( r_numPolyVerts + numverts > r_maxPolyVerts.Get() ) { return; } - if ( r_numPolyIndexes + numindexes > r_maxPolyVerts->integer ) + if ( r_numPolyIndexes + numindexes > r_maxPolyVerts.Get() ) { return; } @@ -855,7 +855,7 @@ void RE_BeginFrame() return; } - if ( !Q_stricmp( r_drawBuffer->string, "GL_FRONT" ) ) + if ( !Q_stricmp( r_drawBuffer.Get().c_str(), "GL_FRONT" ) ) { cmd->buffer = ( int ) GL_FRONT; } diff --git a/src/engine/renderer/tr_curve.cpp b/src/engine/renderer/tr_curve.cpp index 2d53d824e4..2b6b70a63b 100644 --- a/src/engine/renderer/tr_curve.cpp +++ b/src/engine/renderer/tr_curve.cpp @@ -420,7 +420,7 @@ static srfGridMesh_t *R_CreateSurfaceGridMesh( int width, int height, // copy the results out to a grid size = sizeof( *grid ); - if ( r_stitchCurves->integer ) + if ( r_stitchCurves.Get() ) { grid = (srfGridMesh_t*)/*ri.Hunk_Alloc */ Z_Calloc( size ); @@ -588,7 +588,7 @@ srfGridMesh_t *R_SubdividePatchToGrid( int width, int height, srfVert_t points[ continue; // can't subdivide any more } - if ( maxLen <= r_subdivisions->value ) + if ( maxLen <= r_subdivisions.Get() ) { errorTable[ dir ][ j + 1 ] = 1.0f / maxLen; continue; // didn't need subdivision diff --git a/src/engine/renderer/tr_image.cpp b/src/engine/renderer/tr_image.cpp index 974d84848a..df2c15d02c 100644 --- a/src/engine/renderer/tr_image.cpp +++ b/src/engine/renderer/tr_image.cpp @@ -1476,7 +1476,7 @@ image_t *R_CreateImage( const char *name, const byte **pic, int width, int heigh R_UploadImage( name, pic, 1, numMips, image, imageParams ); - if( r_exportTextures->integer ) { + if( r_exportTextures.Get() ) { R_ExportTexture( image ); } @@ -1557,7 +1557,7 @@ image_t *R_CreateCubeImage( const char *name, const byte *pic[ 6 ], int width, i R_UploadImage( name, pic, 6, 1, image, imageParams ); - if( r_exportTextures->integer ) { + if( r_exportTextures.Get() ) { R_ExportTexture( image ); } @@ -1608,7 +1608,7 @@ image_t *R_Create3DImage( const char *name, const byte *pic, int width, int heig ri.Hunk_FreeTempMemory( pics ); } - if( r_exportTextures->integer ) { + if( r_exportTextures.Get() ) { R_ExportTexture( image ); } diff --git a/src/engine/renderer/tr_init.cpp b/src/engine/renderer/tr_init.cpp index d820b623ea..f4ee5279de 100644 --- a/src/engine/renderer/tr_init.cpp +++ b/src/engine/renderer/tr_init.cpp @@ -46,28 +46,35 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA cvar_t *r_ignore; - cvar_t *r_znear; - cvar_t *r_zfar; + Cvar::Cvar r_znear( "r_znear", "Near frustum plane distance", Cvar::CHEAT, 3.0f ); + Cvar::Cvar r_zfar( "r_zfar", "Near frustum plane distance", Cvar::CHEAT, 0.0f ); - cvar_t *r_smp; - cvar_t *r_showSmp; - cvar_t *r_skipBackEnd; + Cvar::Cvar r_smp( "r_smp", "Enable SMP (use 2 different threads for renderer frontend and backend", + Cvar::NONE, false ); + Cvar::Cvar r_showSmp( "r_showSmp", "Show which of the threads is executing with r_smp on", Cvar::NONE, false ); + Cvar::Cvar r_skipBackEnd( "r_skipBackEnd", "Skip renderer backend", Cvar::NONE, false ); cvar_t *r_measureOverdraw; - cvar_t *r_lodBias; - cvar_t *r_lodScale; - - cvar_t *r_norefresh; - cvar_t *r_drawentities; - cvar_t *r_drawworld; - cvar_t *r_drawpolies; - cvar_t *r_speeds; - cvar_t *r_novis; - cvar_t *r_nocull; - cvar_t *r_facePlaneCull; - cvar_t *r_nocurves; - cvar_t *r_lightScissors; + Cvar::Cvar r_lodBias( "r_lodBias", "Add this to model lod selection", Cvar::NONE, 0 ); + Cvar::Cvar r_lodScale( "r_lodScale", "Scale model lod selection by this", Cvar::NONE, 5 ); + + Cvar::Cvar r_norefresh( "r_norefresh", "Skip renderer frontend", Cvar::NONE, false ); + Cvar::Cvar r_drawentities( "r_drawentities", "Render entities", Cvar::NONE, true ); + Cvar::Cvar r_drawworld( "r_drawworld", "Render world", Cvar::CHEAT, true ); + Cvar::Cvar r_drawpolies( "r_drawpolies", "Render polies", Cvar::CHEAT, true ); + Cvar::Range> r_speeds( "r_speeds", + "Renderer timings: 0: disabled, 1: general, 2: culling, 3: view cluster, 4: lights, 5: shadowcube culling," + "6: fog, 7: flares, 8: shading times, 9: chc, 10: show z_near/z_far", Cvar::NONE, + 0, + 0, + Util::ordinal( renderSpeeds_t::RSPEEDS_NEAR_FAR ) ); + Cvar::Cvar r_novis( "r_novis", "Skip PVS for rendering world", Cvar::NONE, false ); + Cvar::Cvar r_nocull( "r_nocull", "Skip culling", Cvar::CHEAT, false ); + Cvar::Cvar r_facePlaneCull( "r_facePlaneCull", "Back-face culling of planar surfaces (CPU-side)", Cvar::NONE, true ); + Cvar::Cvar r_nocurves( "r_nocurves", "Cull all SF_GRID surfaces", Cvar::CHEAT, false ); + Cvar::Range> r_lightScissors( "r_lightScissors", "Light clipping: 0: disabled, 1: near plane, 2: all planes", + Cvar::NONE, 0, 0, 2 ); cvar_t *r_noLightVisCull; cvar_t *r_noInteractionSort; Cvar::Range> r_realtimeLightingRenderer( "r_realtimeLightingRenderer", @@ -78,8 +85,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Cvar::Cvar r_realtimeLighting( "r_realtimeLighting", "Enable realtime light rendering", Cvar::NONE, true ); Cvar::Range> r_realtimeLightLayers( "r_realtimeLightLayers", "Dynamic light layers per tile, each layer holds 16 lights", Cvar::NONE, 4, 1, MAX_REF_LIGHTS / 16 ); - cvar_t *r_realtimeLightingCastShadows; - cvar_t *r_precomputedLighting; + Cvar::Cvar r_realtimeLightingCastShadows( "r_realtimeLightingCastShadows", "Enable realtime light shadows", + Cvar::NONE, true ); + Cvar::Cvar r_precomputedLighting( "r_precomputedLighting", "Use lightMaps if available", Cvar::CHEAT, true ); Cvar::Cvar r_overbrightDefaultExponent("r_overbrightDefaultExponent", "default map light color shift (multiply by 2^x)", Cvar::NONE, 2); Cvar::Cvar r_overbrightDefaultClamp("r_overbrightDefaultClamp", "clamp lightmap colors to 1 (in absence of map worldspawn value)", Cvar::NONE, false); Cvar::Cvar r_overbrightIgnoreMapSettings("r_overbrightIgnoreMapSettings", "force usage of r_overbrightDefaultClamp / r_overbrightDefaultExponent, ignoring worldspawn", Cvar::NONE, false); @@ -91,10 +99,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Cvar::Cvar r_gpuOcclusionCulling( "r_gpuOcclusionCulling", "Use occlusion culling on the GPU for the Material System", Cvar::NONE, false ); Cvar::Cvar r_materialSystemSkip( "r_materialSystemSkip", "Temporarily skip Material System rendering, using only core renderer instead", Cvar::NONE, false ); Cvar::Cvar r_geometryCache( "r_geometryCache", "Use Geometry Cache", Cvar::NONE, true ); - cvar_t *r_lightStyles; - cvar_t *r_exportTextures; - cvar_t *r_heatHaze; - cvar_t *r_noMarksOnTrisurfs; + Cvar::Cvar r_lightStyles( "r_lightStyles", "Enable light styles", Cvar::ARCHIVE, true ); + Cvar::Cvar r_exportTextures( "r_exportTextures", "Save all textures that get created to /texexp", Cvar::NONE, false ); + Cvar::Cvar r_heatHaze( "r_heatHaze", "Enable heat haze mapping", Cvar::ARCHIVE, true ); + Cvar::Cvar r_noMarksOnTrisurfs( "r_noMarksOnTrisurfs", "Disable marks on SF_TRIANGLES surfaces", Cvar::NONE, true ); /* Default value is 1: Delay GLSL shader build until first map load. @@ -108,12 +116,15 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA "r_lazyShaders", "build GLSL shaders (0) on startup, (1) on map load or (2) when used", Cvar::NONE, 1, 0, 2); - cvar_t *r_checkGLErrors; + Cvar::Range> r_checkGLErrors( "r_checkGLErrors", "Enable GL error checking: -1: in debug builds, 0: never, 1: always", + Cvar::NONE, -1, -1, 1 ); cvar_t *r_logFile; - cvar_t *r_colorbits; + Cvar::Cvar r_colorbits( "r_colorbits", "Number of desired color bits, only relevant for fullscreen; 0 to set up automatically", + Cvar::NONE, 0 ); - cvar_t *r_drawBuffer; + Cvar::Cvar r_drawBuffer( "r_drawBuffer", "Render to front or back buffer (GL_FRONT and GL_BACK)", + Cvar::NONE, "GL_BACK" ); Cvar::Range> r_shadows( "cg_shadows", "shadowing mode", Cvar::NONE, Util::ordinal(shadowingMode_t::SHADOWING_BLOB), @@ -148,34 +159,35 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA cvar_t *r_parallelShadowSplits; cvar_t *r_parallelShadowSplitWeight; - cvar_t *r_mode; - cvar_t *r_nobind; - cvar_t *r_singleShader; - cvar_t *r_picMip; - cvar_t *r_imageMaxDimension; - cvar_t *r_ignoreMaterialMinDimension; - cvar_t *r_ignoreMaterialMaxDimension; - cvar_t *r_replaceMaterialMinDimensionIfPresentWithMaxDimension; + Cvar::Cvar r_mode( "r_mode", "Video mode", Cvar::ARCHIVE, -2 ); + Cvar::Cvar r_nobind( "r_nobind", "Bind a black image for all textures", Cvar::NONE, false ); + Cvar::Cvar r_singleShader( "r_singleShader", "Use the default shader on most world surfaces", Cvar::CHEAT, false ); + Cvar::Cvar r_picMip( "r_picMip", "Downscale textures this many times", Cvar::ARCHIVE, 0 ); + Cvar::Cvar r_imageMaxDimension( "r_imageMaxDimension", "Downscale textures to this dimension", Cvar::ARCHIVE, 0 ); + Cvar::Cvar r_ignoreMaterialMinDimension( "r_ignoreMaterialMinDimension", "Ignore material min dimension", Cvar::NONE, false ); + Cvar::Cvar r_ignoreMaterialMaxDimension( "r_ignoreMaterialMaxDimension", "Ignore material max dimension", Cvar::NONE, false ); + Cvar::Cvar r_replaceMaterialMinDimensionIfPresentWithMaxDimension( "r_replaceMaterialMinDimensionIfPresentWithMaxDimension", + "Replace material min dimension with max dimension if present", Cvar::NONE, false ); Cvar::Range> r_imageFitScreen("r_imageFitScreen", "downscale “fitscreen” images to fit the screen size: 0: disable, 1: downscale as much as possible without being smaller than screen size (default), 2: downscale to never be larger then screen size", Cvar::NONE, 1, 0, 2); - cvar_t *r_finish; - Cvar::Modified> r_textureMode( - "r_textureMode", "default texture filter mode", Cvar::NONE, "GL_LINEAR_MIPMAP_LINEAR"); - cvar_t *r_offsetFactor; - cvar_t *r_offsetUnits; - - cvar_t *r_physicalMapping; - cvar_t *r_specularExponentMin; - cvar_t *r_specularExponentMax; - cvar_t *r_specularScale; - cvar_t *r_specularMapping; - cvar_t *r_deluxeMapping; - cvar_t *r_normalScale; - cvar_t *r_normalMapping; - cvar_t *r_liquidMapping; - cvar_t *r_highQualityNormalMapping; - cvar_t *r_reliefDepthScale; - cvar_t *r_reliefMapping; - cvar_t *r_glowMapping; + Cvar::Cvar r_finish( "r_finish", "Use glFinish() at the end of rendering a frame", Cvar::NONE, false ); + Cvar::Modified> r_textureMode( "r_textureMode", "default texture filter mode", + Cvar::NONE, "GL_LINEAR_MIPMAP_LINEAR" ); + Cvar::Cvar r_offsetFactor( "r_offsetFactor", "Polygon offset factor", Cvar::CHEAT, -1 ); + Cvar::Cvar r_offsetUnits( "r_offsetUnits", "Polygon offset units", Cvar::CHEAT, -2 ); + + Cvar::Cvar r_physicalMapping( "r_physicalMapping", "Enable PBR", Cvar::ARCHIVE, true ); + Cvar::Cvar r_specularExponentMin( "r_specularExponentMin", "Minimum specular exponent", Cvar::CHEAT, 0.001f ); + Cvar::Cvar r_specularExponentMax( "r_specularExponentMax", "Maximum specular exponent", Cvar::CHEAT, 16.0f ); + Cvar::Cvar r_specularScale( "r_specularScale", "Specular scale", Cvar::CHEAT, 1.0f ); + Cvar::Cvar r_specularMapping( "r_specularMapping", "Enable specular mapping", Cvar::ARCHIVE, true ); + Cvar::Cvar r_deluxeMapping( "r_deluxeMapping", "Enable deluxe mapping", Cvar::ARCHIVE, true ); + Cvar::Cvar r_normalScale( "r_normalScale", "Normal scale", Cvar::NONE, 1.0f ); + Cvar::Cvar r_normalMapping( "r_normalMapping", "Enable normal mapping", Cvar::ARCHIVE, true ); + Cvar::Cvar r_liquidMapping( "r_liquidMapping", "Enable liquid mapping", Cvar::ARCHIVE, false ); + Cvar::Cvar r_highQualityNormalMapping( "r_highQualityNormalMapping", "Enable high quality normal mapping", Cvar::NONE, false ); + Cvar::Cvar r_reliefDepthScale( "r_reliefDepthScale", "Relief mapping depth scale", Cvar::NONE, 0.02f ); + Cvar::Cvar r_reliefMapping( "r_reliefMapping", "Enable relief mapping", Cvar::ARCHIVE, false ); + Cvar::Cvar r_glowMapping( "r_glowMapping", "Enable glow mapping", Cvar::NONE, true ); Cvar::Cvar r_reflectionMapping( "r_reflectionMapping", "Use static reflections", Cvar::NONE, false ); Cvar::Range> r_autoBuildCubeMaps( "r_autoBuildCubeMaps", "Automatically build cube maps when a map is loaded: 0: off, 1: build and store on disk if not found, 2: always build", Cvar::NONE, @@ -187,62 +199,64 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Cvar::Range> r_cubeProbeSpacing( "r_cubeProbeSpacing", "Spacing between the static reflections cubemaps", Cvar::NONE, 256, 64, 1024 ); - cvar_t *r_halfLambertLighting; - cvar_t *r_rimLighting; - cvar_t *r_rimExponent; + Cvar::Cvar r_halfLambertLighting( "r_halfLambertLighting", "Enable half-Lambert lighting (makes models brighter)", + Cvar::ARCHIVE, true ); + Cvar::Cvar r_rimLighting( "r_rimLighting", "Light the edges of modes from behind", Cvar::NONE, true ); + Cvar::Range> r_rimExponent( "r_rimExponent", "Rim lighting exponent", Cvar::NONE, 3.0f, 0.5f, 8.0f ); Cvar::Cvar r_highPrecisionRendering("r_highPrecisionRendering", "use high precision frame buffers for rendering and blending", Cvar::NONE, true); - cvar_t *r_gamma; - cvar_t *r_lockpvs; - cvar_t *r_noportals; + Cvar::Cvar r_gamma( "r_gamma", "Gamma", Cvar::ARCHIVE, 1.0f ); + Cvar::Cvar r_lockpvs( "r_lockpvs", "Lock the culling position and angles at the current viewpos", Cvar::CHEAT, false ); + Cvar::Cvar r_noportals( "r_noportals", "Skip portals", Cvar::CHEAT, false ); - cvar_t *r_max_portal_levels; + Cvar::Cvar r_max_portal_levels( "r_max_portal_levels", "Maximum portal view recursion level", Cvar::NONE, 5 ); - cvar_t *r_subdivisions; - cvar_t *r_stitchCurves; + Cvar::Cvar r_subdivisions( "r_subdivisions", "Quality of patch-mesh sub-division (lower = better)", Cvar::NONE, 4 ); + Cvar::Cvar r_stitchCurves( "r_stitchCurves", "Stitch edges of patch meshes", Cvar::CHEAT, true ); Cvar::Modified> r_fullscreen( "r_fullscreen", "use full-screen window", CVAR_ARCHIVE, true ); - cvar_t *r_customwidth; - cvar_t *r_customheight; + Cvar::Cvar r_customwidth( "r_customwidth", "Window width", Cvar::ARCHIVE, 1600 ); + Cvar::Cvar r_customheight( "r_customheight", "Window height", Cvar::ARCHIVE, 1024 ); - cvar_t *r_debugSurface; + Cvar::Cvar r_debugSurface( "r_debugSurface", "Enable debug surface rendering", Cvar::NONE, false ); - cvar_t *r_showImages; + Cvar::Range> r_showImages( "r_showImages", "Render all textures on screen: 0: disabled, 1: normal, 2: proportional", + Cvar::TEMPORARY, 0, 0, 2 ); - cvar_t *r_wolfFog; - cvar_t *r_noFog; + Cvar::Cvar r_wolfFog( "r_wolfFog", "Enable surface fog", Cvar::NONE, true ); + Cvar::Cvar r_noFog( "r_noFog", "Skip fog", Cvar::CHEAT, false ); Cvar::Range> r_forceAmbient( "r_forceAmbient", "Minimal light amount in lightGrid", Cvar::NONE, 0.125f, 0.0f, 0.3f ); Cvar::Cvar r_ambientScale( "r_ambientScale", "Scale lightGrid produced by ambientColor keyword by this much", Cvar::CHEAT, 1.0 ); cvar_t *r_lightScale; - cvar_t *r_debugSort; - cvar_t *r_printShaders; + Cvar::Cvar r_debugSort( "r_debugSort", "Stop rendering surfaces after this sort value", Cvar::CHEAT, 0 ); + Cvar::Cvar r_printShaders( "r_printShaders", "Print names of q3 shaders that are being loaded", Cvar::NONE, false ); - cvar_t *r_maxPolys; - cvar_t *r_maxPolyVerts; + Cvar::Range> r_maxPolys( "r_maxPolys", "Maximum amount of polys", Cvar::NONE, 10000, 600, 30000 ); + Cvar::Range> r_maxPolyVerts( "r_maxPolyVerts", "Maximum amount of poly vertices", Cvar::NONE, 100000, 3000, 200000 ); - cvar_t *r_showTris; - cvar_t *r_showSky; + Cvar::Cvar r_showTris( "r_showTris", "Render surfaces' wireframe", Cvar::CHEAT, false ); + Cvar::Cvar r_showSky( "r_showSky", "Render sky only", Cvar::NONE, false ); cvar_t *r_showShadowLod; cvar_t *r_showShadowMaps; - cvar_t *r_showSkeleton; - cvar_t *r_showEntityTransforms; - cvar_t *r_showLightTransforms; - cvar_t *r_showLightInteractions; - cvar_t *r_showLightScissors; - cvar_t *r_showLightBatches; - cvar_t *r_showLightGrid; - cvar_t *r_showLightTiles; - cvar_t *r_showBatches; + Cvar::Cvar r_showSkeleton( "r_showSkeleton", "Render model skeletons", Cvar::CHEAT, false ); + Cvar::Cvar r_showEntityTransforms( "r_showEntityTransforms", "Render entity transform bounds", Cvar::CHEAT, false ); + Cvar::Cvar r_showLightTransforms( "r_showLightTransforms", "Render light transform bounds", Cvar::CHEAT, false ); + Cvar::Cvar r_showLightInteractions( "r_showLightInteractions", "Render light interactions", Cvar::CHEAT, false ); + Cvar::Cvar r_showLightScissors( "r_showLightScissors", "Render light scissors", Cvar::ARCHIVE, false ); + Cvar::Cvar r_showLightBatches( "r_showLightBatches", "Render light batches", Cvar::NONE, false ); + Cvar::Cvar r_showLightGrid( "r_showLightGrid", "Render lightGrid", Cvar::NONE, false ); + Cvar::Cvar r_showLightTiles( "r_showLightTiles", "Render light tiles", Cvar::NONE, false ); + Cvar::Cvar r_showBatches( "r_showBatches", "Render batches", Cvar::NONE, false ); Cvar::Cvar r_showVertexColors("r_showVertexColors", "show vertex colors used for vertex lighting", Cvar::CHEAT, false); - cvar_t *r_showLightMaps; - cvar_t *r_showDeluxeMaps; - cvar_t *r_showNormalMaps; - cvar_t *r_showMaterialMaps; + Cvar::Cvar r_showLightMaps( "r_showLightMaps", "Render lightMaps", Cvar::NONE, false ); + Cvar::Cvar r_showDeluxeMaps( "r_showDeluxeMaps", "Render deluxe maps", Cvar::NONE, false ); + Cvar::Cvar r_showNormalMaps( "r_showNormalMaps", "Render normal maps", Cvar::NONE, false ); + Cvar::Cvar r_showMaterialMaps( "r_showMaterialMaps", "Render material maps", Cvar::NONE, false ); Cvar::Cvar r_showReflectionMaps( "r_showReflectionMaps", "Show only the static reflections on surfaces", Cvar::NONE, false ); Cvar::Range> r_showCubeProbes( "r_showCubeProbes", "Show static reflections cubemap placement: 0: off, 1: grid, " "2: unique only", Cvar::NONE, @@ -251,7 +265,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Util::ordinal( showCubeProbesMode::UNIQUE ) ); Cvar::Cvar r_showCubeProbeFace( "r_showCubeProbeFace", "Render from the perspective of a selected static reflection " "cubemap face, -1 to disable", Cvar::NONE, -1 ); - cvar_t *r_showBspNodes; + Cvar::Range> r_showBspNodes( "r_showBspNodes", "Render BSP nodes", Cvar::NONE, 0, 0, 3 ); Cvar::Range> r_showGlobalMaterials( "r_showGlobalMaterials", "Show material system materials: 0: off, 1: depth, " "2: opaque, 3: opaque + transparent", Cvar::NONE, Util::ordinal( MaterialDebugMode::NONE ), @@ -273,19 +287,19 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Cvar::Cvar r_forceRendererTime( "r_forceRendererTime", "Set a specific time (in ms, since the start of the map) for time-based shader effects; -1 to disable", Cvar::CHEAT, -1 ); - cvar_t *r_vboFaces; - cvar_t *r_vboCurves; - cvar_t *r_vboTriangles; - cvar_t *r_vboModels; - cvar_t *r_vboVertexSkinning; + Cvar::Cvar r_vboFaces( "r_vboFaces", "Use static VBO to render SF_FACE", Cvar::NONE, true ); + Cvar::Cvar r_vboCurves( "r_vboCurves", "Use static VBO to render SF_GRID", Cvar::NONE, true ); + Cvar::Cvar r_vboTriangles( "r_vboTriangles", "Use static VBO to render SF_FACE", Cvar::NONE, true ); + Cvar::Cvar r_vboModels( "r_vboModels", "Use static VBOs for models", Cvar::NONE, true ); + Cvar::Cvar r_vboVertexSkinning( "r_vboVertexSkinning", "Use GPU for skeletal animation transforms", Cvar::NONE, true ); - cvar_t *r_mergeLeafSurfaces; + Cvar::Cvar r_mergeLeafSurfaces( "r_mergeLeafSurfaces", "Merge surfaces in the same BSP leaf", Cvar::NONE, true ); Cvar::Cvar r_bloom( "r_bloom", "Use bloom", Cvar::ARCHIVE, false ); Cvar::Cvar r_bloomBlur( "r_bloomBlur", "Bloom strength", Cvar::NONE, 1.0 ); Cvar::Cvar r_bloomPasses( "r_bloomPasses", "Amount of bloom passes in each direction", Cvar::NONE, 2 ); - cvar_t *r_FXAA; - cvar_t *r_ssao; + Cvar::Cvar r_FXAA( "r_FXAA", "Use FXAA", Cvar::ARCHIVE, false ); + Cvar::Cvar r_ssao( "r_ssao", "Use SSAO", Cvar::ARCHIVE, 0 ); cvar_t *r_evsmPostProcess; @@ -354,18 +368,18 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA GLSL_InitGPUShaders(); glConfig.smpActive = false; - if ( r_smp->integer ) + if ( r_smp.Get() ) { - Log::Notice("Trying SMP acceleration..." ); + Log::Notice( "Trying SMP acceleration..." ); if ( GLimp_SpawnRenderThread( RB_RenderThread ) ) { - Log::Notice("...succeeded." ); + Log::Notice( "...succeeded." ); glConfig.smpActive = true; } else { - Log::Notice("...failed." ); + Log::Notice( "...failed." ); } } } @@ -507,8 +521,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA } else if ( mode == -1 ) { - *width = r_customwidth->integer; - *height = r_customheight->integer; + *width = r_customwidth.Get(); + *height = r_customheight.Get(); } else { @@ -956,7 +970,7 @@ ScreenshotCmd screenshotPNGRegistration("screenshotPNG", ssFormat_t::SSF_PNG, "p Log::Notice("PIXELFORMAT: color(%d-bits)", glConfig.colorBits ); Log::Notice("MODE: %d, %d x %d %s", - r_mode->integer, + r_mode.Get(), glConfig.vidWidth, glConfig.vidHeight, fsstrings[ +r_fullscreen.Get() ] ); @@ -1069,17 +1083,18 @@ ScreenshotCmd screenshotPNGRegistration("screenshotPNG", ssFormat_t::SSF_PNG, "p Log::Notice("Using dual processor acceleration." ); } - if ( r_finish->integer ) + if ( r_finish.Get() ) { - Log::Notice("Forcing glFinish." ); + Log::Notice( "Forcing glFinish()" ); } - Log::Debug("texturemode: %s", r_textureMode.Get() ); - Log::Debug("picmip: %d", r_picMip->integer ); - Log::Debug("imageMaxDimension: %d", r_imageMaxDimension->integer ); - Log::Debug("ignoreMaterialMinDimension: %d", r_ignoreMaterialMinDimension->integer ); - Log::Debug("ignoreMaterialMaxDimension: %d", r_ignoreMaterialMaxDimension->integer ); - Log::Debug("replaceMaterialMinDimensionIfPresentWithMaxDimension: %d", r_replaceMaterialMinDimensionIfPresentWithMaxDimension->integer ); + Log::Debug( "texturemode: %s", r_textureMode.Get() ); + Log::Debug( "picmip: %d", r_picMip.Get() ); + Log::Debug( "imageMaxDimension: %d", r_imageMaxDimension.Get() ); + Log::Debug( "ignoreMaterialMinDimension: %d", r_ignoreMaterialMinDimension.Get() ); + Log::Debug( "ignoreMaterialMaxDimension: %d", r_ignoreMaterialMaxDimension.Get() ); + Log::Debug( "replaceMaterialMinDimensionIfPresentWithMaxDimension: %d", + r_replaceMaterialMinDimensionIfPresentWithMaxDimension.Get() ); } // FIXME: uses regular logging not Print() @@ -1146,41 +1161,34 @@ ScreenshotCmd screenshotPNGRegistration("screenshotPNG", ssFormat_t::SSF_PNG, "p Cvar::Latch( r_glExtendedValidation ); // latched and archived variables - r_picMip = Cvar_Get( "r_picMip", "0", CVAR_LATCH | CVAR_ARCHIVE ); - r_imageMaxDimension = Cvar_Get( "r_imageMaxDimension", "0", CVAR_LATCH | CVAR_ARCHIVE ); - r_ignoreMaterialMinDimension = Cvar_Get( "r_ignoreMaterialMinDimension", "0", CVAR_LATCH | CVAR_ARCHIVE ); - r_ignoreMaterialMaxDimension = Cvar_Get( "r_ignoreMaterialMaxDimension", "0", CVAR_LATCH | CVAR_ARCHIVE ); - r_replaceMaterialMinDimensionIfPresentWithMaxDimension - = Cvar_Get( "r_replaceMaterialMinDimensionIfPresentWithMaxDimension", "0", CVAR_LATCH | CVAR_ARCHIVE ); - Cvar::Latch(r_imageFitScreen); - r_colorbits = Cvar_Get( "r_colorbits", "0", CVAR_LATCH ); - r_mode = Cvar_Get( "r_mode", "-2", CVAR_LATCH | CVAR_ARCHIVE ); - r_customwidth = Cvar_Get( "r_customwidth", "1600", CVAR_LATCH | CVAR_ARCHIVE ); - r_customheight = Cvar_Get( "r_customheight", "1024", CVAR_LATCH | CVAR_ARCHIVE ); - r_subdivisions = Cvar_Get( "r_subdivisions", "4", CVAR_LATCH ); - r_realtimeLightingCastShadows = Cvar_Get( "r_realtimeLightingCastShadows", "1", 0 ); - r_precomputedLighting = Cvar_Get( "r_precomputedLighting", "1", CVAR_CHEAT | CVAR_LATCH ); + Cvar::Latch( r_picMip ); + Cvar::Latch( r_imageMaxDimension ); + Cvar::Latch( r_ignoreMaterialMinDimension ); + Cvar::Latch( r_ignoreMaterialMaxDimension ); + Cvar::Latch( r_replaceMaterialMinDimensionIfPresentWithMaxDimension ); + Cvar::Latch( r_imageFitScreen ); + Cvar::Latch( r_colorbits ); + Cvar::Latch( r_mode ); + Cvar::Latch( r_customwidth ); + Cvar::Latch( r_customheight ); + Cvar::Latch( r_subdivisions ); + Cvar::Latch( r_precomputedLighting ); Cvar::Latch( r_overbrightDefaultExponent ); Cvar::Latch( r_overbrightDefaultClamp ); Cvar::Latch( r_overbrightIgnoreMapSettings ); Cvar::Latch( r_lightMode ); Cvar::Latch( r_colorGrading ); Cvar::Latch( r_drawSky ); - r_lightStyles = Cvar_Get( "r_lightStyles", "1", CVAR_LATCH | CVAR_ARCHIVE ); - r_exportTextures = Cvar_Get( "r_exportTextures", "0", 0 ); - r_heatHaze = Cvar_Get( "r_heatHaze", "1", CVAR_LATCH | CVAR_ARCHIVE ); - r_noMarksOnTrisurfs = Cvar_Get( "r_noMarksOnTrisurfs", "1", CVAR_CHEAT ); - - r_wolfFog = Cvar_Get( "r_wolfFog", "1", CVAR_CHEAT ); - r_noFog = Cvar_Get( "r_noFog", "0", CVAR_CHEAT ); + Cvar::Latch( r_lightStyles ); + Cvar::Latch( r_heatHaze ); Cvar::Latch( r_forceAmbient ); - r_smp = Cvar_Get( "r_smp", "0", CVAR_LATCH ); + Cvar::Latch( r_smp ); // temporary latched variables that can only change over a restart - r_singleShader = Cvar_Get( "r_singleShader", "0", CVAR_CHEAT | CVAR_LATCH ); - r_stitchCurves = Cvar_Get( "r_stitchCurves", "1", CVAR_CHEAT | CVAR_LATCH ); + Cvar::Latch( r_singleShader ); + Cvar::Latch( r_stitchCurves ); r_debugShadowMaps = Cvar_Get( "r_debugShadowMaps", "0", CVAR_CHEAT | CVAR_LATCH ); r_shadowMapLinearFilter = Cvar_Get( "r_shadowMapLinearFilter", "1", CVAR_CHEAT | CVAR_LATCH ); r_lightBleedReduction = Cvar_Get( "r_lightBleedReduction", "0", CVAR_CHEAT | CVAR_LATCH ); @@ -1192,42 +1200,21 @@ ScreenshotCmd screenshotPNGRegistration("screenshotPNG", ssFormat_t::SSF_PNG, "p AssertCvarRange( r_parallelShadowSplits, 0, MAX_SHADOWMAPS - 1, true ); // archived variables that can change at any time - r_lodBias = Cvar_Get( "r_lodBias", "0", 0 ); - r_znear = Cvar_Get( "r_znear", "3", CVAR_CHEAT ); - r_zfar = Cvar_Get( "r_zfar", "0", CVAR_CHEAT ); - r_checkGLErrors = Cvar_Get( "r_checkGLErrors", "-1", 0 ); - r_finish = Cvar_Get( "r_finish", "0", CVAR_CHEAT ); - r_gamma = Cvar_Get( "r_gamma", "1.0", CVAR_ARCHIVE ); - r_facePlaneCull = Cvar_Get( "r_facePlaneCull", "1", 0 ); - Cvar::Latch( r_ambientScale ); r_lightScale = Cvar_Get( "r_lightScale", "2", CVAR_CHEAT ); - r_vboFaces = Cvar_Get( "r_vboFaces", "1", CVAR_CHEAT ); - r_vboCurves = Cvar_Get( "r_vboCurves", "1", CVAR_CHEAT ); - r_vboTriangles = Cvar_Get( "r_vboTriangles", "1", CVAR_CHEAT ); - r_vboModels = Cvar_Get( "r_vboModels", "1", CVAR_LATCH ); - r_vboVertexSkinning = Cvar_Get( "r_vboVertexSkinning", "1", CVAR_LATCH ); + Cvar::Latch( r_vboModels ); + Cvar::Latch( r_vboVertexSkinning ); - r_mergeLeafSurfaces = Cvar_Get( "r_mergeLeafSurfaces", "1", CVAR_LATCH ); + Cvar::Latch( r_mergeLeafSurfaces ); r_evsmPostProcess = Cvar_Get( "r_evsmPostProcess", "0", CVAR_LATCH ); - r_printShaders = Cvar_Get( "r_printShaders", "0", 0 ); - Cvar::Latch( r_bloom ); - r_FXAA = Cvar_Get( "r_FXAA", "0", CVAR_LATCH | CVAR_ARCHIVE ); - r_ssao = Cvar_Get( "r_ssao", "0", CVAR_LATCH | CVAR_ARCHIVE ); + Cvar::Latch( r_FXAA ); + Cvar::Latch( r_ssao ); // temporary variables that can change at any time - r_showImages = Cvar_Get( "r_showImages", "0", CVAR_TEMP ); - - r_debugSort = Cvar_Get( "r_debugSort", "0", CVAR_CHEAT ); - - r_nocurves = Cvar_Get( "r_nocurves", "0", CVAR_CHEAT ); - r_lightScissors = Cvar_Get( "r_lightScissors", "1", CVAR_ARCHIVE ); - AssertCvarRange( r_lightScissors, 0, 2, true ); - r_noLightVisCull = Cvar_Get( "r_noLightVisCull", "0", CVAR_CHEAT ); r_noInteractionSort = Cvar_Get( "r_noInteractionSort", "0", CVAR_CHEAT ); @@ -1238,56 +1225,30 @@ ScreenshotCmd screenshotPNGRegistration("screenshotPNG", ssFormat_t::SSF_PNG, "p Cvar::Latch( r_materialSystem ); Cvar::Latch( r_geometryCache ); - r_drawworld = Cvar_Get( "r_drawworld", "1", CVAR_CHEAT ); - r_max_portal_levels = Cvar_Get( "r_max_portal_levels", "5", 0 ); - - r_showSmp = Cvar_Get( "r_showSmp", "0", CVAR_CHEAT ); - r_skipBackEnd = Cvar_Get( "r_skipBackEnd", "0", CVAR_CHEAT ); - r_measureOverdraw = Cvar_Get( "r_measureOverdraw", "0", CVAR_CHEAT ); - r_lodScale = Cvar_Get( "r_lodScale", "5", CVAR_CHEAT ); - r_norefresh = Cvar_Get( "r_norefresh", "0", CVAR_CHEAT ); - r_drawentities = Cvar_Get( "r_drawentities", "1", CVAR_CHEAT ); - r_drawpolies = Cvar_Get( "r_drawpolies", "1", CVAR_CHEAT ); r_ignore = Cvar_Get( "r_ignore", "1", CVAR_CHEAT ); - r_nocull = Cvar_Get( "r_nocull", "0", CVAR_CHEAT ); - r_novis = Cvar_Get( "r_novis", "0", CVAR_CHEAT ); - r_speeds = Cvar_Get( "r_speeds", "0", 0 ); r_logFile = Cvar_Get( "r_logFile", "0", CVAR_CHEAT ); - r_debugSurface = Cvar_Get( "r_debugSurface", "0", CVAR_CHEAT ); - r_nobind = Cvar_Get( "r_nobind", "0", CVAR_CHEAT ); - r_offsetFactor = Cvar_Get( "r_offsetFactor", "-1", CVAR_CHEAT ); - r_offsetUnits = Cvar_Get( "r_offsetUnits", "-2", CVAR_CHEAT ); - - r_physicalMapping = Cvar_Get( "r_physicalMapping", "1", CVAR_LATCH | CVAR_ARCHIVE ); - r_specularExponentMin = Cvar_Get( "r_specularExponentMin", "0.001", CVAR_CHEAT ); - r_specularExponentMax = Cvar_Get( "r_specularExponentMax", "16", CVAR_CHEAT ); - r_specularScale = Cvar_Get( "r_specularScale", "1.0", CVAR_CHEAT | CVAR_LATCH ); - r_specularMapping = Cvar_Get( "r_specularMapping", "1", CVAR_LATCH | CVAR_ARCHIVE ); - r_deluxeMapping = Cvar_Get( "r_deluxeMapping", "1", CVAR_LATCH | CVAR_ARCHIVE ); - r_normalScale = Cvar_Get( "r_normalScale", "1.0", CVAR_ARCHIVE ); - r_normalMapping = Cvar_Get( "r_normalMapping", "1", CVAR_LATCH | CVAR_ARCHIVE ); - r_highQualityNormalMapping = Cvar_Get( "r_highQualityNormalMapping", "0", CVAR_LATCH ); - r_liquidMapping = Cvar_Get( "r_liquidMapping", "0", CVAR_LATCH | CVAR_ARCHIVE ); - r_reliefDepthScale = Cvar_Get( "r_reliefDepthScale", "0.02", CVAR_CHEAT ); - r_reliefMapping = Cvar_Get( "r_reliefMapping", "0", CVAR_LATCH | CVAR_ARCHIVE ); - r_glowMapping = Cvar_Get( "r_glowMapping", "1", CVAR_LATCH ); + + Cvar::Latch( r_physicalMapping ); + Cvar::Latch( r_specularScale ); + Cvar::Latch( r_specularMapping ); + Cvar::Latch( r_deluxeMapping ); + Cvar::Latch( r_normalMapping ); + Cvar::Latch( r_highQualityNormalMapping ); + Cvar::Latch( r_liquidMapping ); + Cvar::Latch( r_reliefMapping ); + Cvar::Latch( r_glowMapping ); Cvar::Latch( r_reflectionMapping ); Cvar::Latch( r_autoBuildCubeMaps ); Cvar::Latch( r_cubeProbeSize ); Cvar::Latch( r_cubeProbeSpacing ); - r_halfLambertLighting = Cvar_Get( "r_halfLambertLighting", "1", CVAR_LATCH | CVAR_ARCHIVE ); - r_rimLighting = Cvar_Get( "r_rimLighting", "0", CVAR_LATCH | CVAR_ARCHIVE ); - r_rimExponent = Cvar_Get( "r_rimExponent", "3", CVAR_CHEAT | CVAR_LATCH ); - AssertCvarRange( r_rimExponent, 0.5, 8.0, false ); + Cvar::Latch( r_halfLambertLighting ); + Cvar::Latch( r_rimLighting ); + Cvar::Latch( r_rimExponent ); Cvar::Latch( r_highPrecisionRendering ); - r_drawBuffer = Cvar_Get( "r_drawBuffer", "GL_BACK", CVAR_CHEAT ); - r_lockpvs = Cvar_Get( "r_lockpvs", "0", CVAR_CHEAT ); - r_noportals = Cvar_Get( "r_noportals", "0", CVAR_CHEAT ); - Cvar::Latch( r_shadows ); r_softShadows = Cvar_Get( "r_softShadows", "0", CVAR_LATCH ); @@ -1345,32 +1306,18 @@ ScreenshotCmd screenshotPNGRegistration("screenshotPNG", ssFormat_t::SSF_PNG, "p r_cullShadowPyramidFaces = Cvar_Get( "r_cullShadowPyramidFaces", "0", CVAR_CHEAT ); r_noLightFrustums = Cvar_Get( "r_noLightFrustums", "1", CVAR_CHEAT ); - r_maxPolys = Cvar_Get( "r_maxpolys", "10000", CVAR_LATCH ); // 600 in vanilla Q3A - AssertCvarRange( r_maxPolys, 600, 30000, true ); + r_showShadowLod = Cvar_Get( "r_showShadowLod", "0", CVAR_CHEAT ); - r_maxPolyVerts = Cvar_Get( "r_maxpolyverts", "100000", CVAR_LATCH ); // 3000 in vanilla Q3A - AssertCvarRange( r_maxPolyVerts, 3000, 200000, true ); + Cvar::Latch( r_maxPolys ); + Cvar::Latch( r_maxPolyVerts ); - r_showTris = Cvar_Get( "r_showTris", "0", CVAR_CHEAT ); - r_showSky = Cvar_Get( "r_showSky", "0", CVAR_CHEAT ); - r_showShadowLod = Cvar_Get( "r_showShadowLod", "0", CVAR_CHEAT ); - r_showShadowMaps = Cvar_Get( "r_showShadowMaps", "0", CVAR_CHEAT ); - r_showSkeleton = Cvar_Get( "r_showSkeleton", "0", CVAR_CHEAT ); - r_showEntityTransforms = Cvar_Get( "r_showEntityTransforms", "0", CVAR_CHEAT ); - r_showLightTransforms = Cvar_Get( "r_showLightTransforms", "0", CVAR_CHEAT ); - r_showLightInteractions = Cvar_Get( "r_showLightInteractions", "0", CVAR_CHEAT ); - r_showLightScissors = Cvar_Get( "r_showLightScissors", "0", CVAR_CHEAT ); - r_showLightBatches = Cvar_Get( "r_showLightBatches", "0", CVAR_CHEAT ); - r_showLightGrid = Cvar_Get( "r_showLightGrid", "0", CVAR_CHEAT ); - r_showLightTiles = Cvar_Get("r_showLightTiles", "0", CVAR_CHEAT | CVAR_LATCH ); - r_showBatches = Cvar_Get( "r_showBatches", "0", CVAR_CHEAT ); + Cvar::Latch( r_showLightTiles ); Cvar::Latch( r_showVertexColors ); - r_showLightMaps = Cvar_Get( "r_showLightMaps", "0", CVAR_CHEAT | CVAR_LATCH ); - r_showDeluxeMaps = Cvar_Get( "r_showDeluxeMaps", "0", CVAR_CHEAT | CVAR_LATCH ); - r_showNormalMaps = Cvar_Get( "r_showNormalMaps", "0", CVAR_CHEAT | CVAR_LATCH ); - r_showMaterialMaps = Cvar_Get( "r_showMaterialMaps", "0", CVAR_CHEAT | CVAR_LATCH ); + Cvar::Latch( r_showLightMaps ); + Cvar::Latch( r_showDeluxeMaps ); + Cvar::Latch( r_showNormalMaps ); + Cvar::Latch( r_showMaterialMaps ); Cvar::Latch( r_showReflectionMaps ); - r_showBspNodes = Cvar_Get( "r_showBspNodes", "0", CVAR_CHEAT ); Cvar::Latch( r_showGlobalMaterials ); Cvar::Latch( r_materialDebug ); r_showParallelShadowSplits = Cvar_Get( "r_showParallelShadowSplits", "0", CVAR_CHEAT | CVAR_LATCH ); @@ -1453,13 +1400,13 @@ ScreenshotCmd screenshotPNGRegistration("screenshotPNG", ssFormat_t::SSF_PNG, "p } } - if ( r_showNormalMaps->integer - || r_showMaterialMaps->integer ) + if ( r_showNormalMaps.Get() + || r_showMaterialMaps.Get() ) { tr.lightMode = lightMode_t::MAP; } - else if ( r_showLightMaps->integer - || r_showDeluxeMaps->integer ) + else if ( r_showLightMaps.Get() + || r_showDeluxeMaps.Get() ) { tr.lightMode = lightMode_t::MAP; } @@ -1471,38 +1418,38 @@ ScreenshotCmd screenshotPNGRegistration("screenshotPNG", ssFormat_t::SSF_PNG, "p if ( r_reflectionMapping.Get() ) { glConfig2.reflectionMappingAvailable = true; - if ( !r_normalMapping->integer ) { + if ( !r_normalMapping.Get() ) { glConfig2.reflectionMappingAvailable = false; Log::Warn( "Unable to use static reflections without normal mapping, make sure you enable r_normalMapping" ); } - if ( !r_deluxeMapping->integer ) { + if ( !r_deluxeMapping.Get() ) { glConfig2.reflectionMappingAvailable = false; Log::Warn( "Unable to use static reflections without deluxe mapping, make sure you enable r_deluxeMapping" ); } - if ( !r_specularMapping->integer ) { + if ( !r_specularMapping.Get() ) { glConfig2.reflectionMappingAvailable = false; Log::Warn( "Unable to use static reflections without specular mapping, make sure you enable r_specularMapping" ); } - if ( r_physicalMapping->integer ) { + if ( r_physicalMapping.Get() ) { glConfig2.reflectionMappingAvailable = false; Log::Warn( "Unable to use static reflections with physical mapping, make sure you disable r_physicalMapping" ); } } backEndData[ 0 ] = ( backEndData_t * ) ri.Hunk_Alloc( sizeof( *backEndData[ 0 ] ), ha_pref::h_low ); - backEndData[ 0 ]->polys = ( srfPoly_t * ) ri.Hunk_Alloc( r_maxPolys->integer * sizeof( srfPoly_t ), ha_pref::h_low ); - backEndData[ 0 ]->polyVerts = ( polyVert_t * ) ri.Hunk_Alloc( r_maxPolyVerts->integer * sizeof( polyVert_t ), ha_pref::h_low ); - backEndData[ 0 ]->polyIndexes = ( int * ) ri.Hunk_Alloc( r_maxPolyVerts->integer * sizeof( int ), ha_pref::h_low ); + backEndData[ 0 ]->polys = ( srfPoly_t * ) ri.Hunk_Alloc( r_maxPolys.Get() * sizeof( srfPoly_t ), ha_pref::h_low ); + backEndData[ 0 ]->polyVerts = ( polyVert_t * ) ri.Hunk_Alloc( r_maxPolyVerts.Get() * sizeof( polyVert_t ), ha_pref::h_low ); + backEndData[ 0 ]->polyIndexes = ( int * ) ri.Hunk_Alloc( r_maxPolyVerts.Get() * sizeof( int ), ha_pref::h_low ); - if ( r_smp->integer ) + if ( r_smp.Get() ) { backEndData[ 1 ] = ( backEndData_t * ) ri.Hunk_Alloc( sizeof( *backEndData[ 1 ] ), ha_pref::h_low ); - backEndData[ 1 ]->polys = ( srfPoly_t * ) ri.Hunk_Alloc( r_maxPolys->integer * sizeof( srfPoly_t ), ha_pref::h_low ); - backEndData[ 1 ]->polyVerts = ( polyVert_t * ) ri.Hunk_Alloc( r_maxPolyVerts->integer * sizeof( polyVert_t ), ha_pref::h_low ); - backEndData[ 1 ]->polyIndexes = ( int * ) ri.Hunk_Alloc( r_maxPolyVerts->integer * sizeof( int ), ha_pref::h_low ); + backEndData[ 1 ]->polys = ( srfPoly_t * ) ri.Hunk_Alloc( r_maxPolys.Get() * sizeof( srfPoly_t ), ha_pref::h_low ); + backEndData[ 1 ]->polyVerts = ( polyVert_t * ) ri.Hunk_Alloc( r_maxPolyVerts.Get() * sizeof( polyVert_t ), ha_pref::h_low ); + backEndData[ 1 ]->polyIndexes = ( int * ) ri.Hunk_Alloc( r_maxPolyVerts.Get() * sizeof( int ), ha_pref::h_low ); } else { diff --git a/src/engine/renderer/tr_light.cpp b/src/engine/renderer/tr_light.cpp index c6fbaf27db..ccc919133f 100644 --- a/src/engine/renderer/tr_light.cpp +++ b/src/engine/renderer/tr_light.cpp @@ -1025,7 +1025,7 @@ static void R_AddEdgeToLightScissor( trRefLight_t *light, const vec3_t in_world1 cplane_t *frust; vec3_t clip1, clip2; - if ( r_lightScissors->integer == 1 ) + if ( r_lightScissors.Get() == 1 ) { // only clip against near plane frust = &tr.viewParms.frustums[ 0 ][ FRUSTUM_NEAR ]; @@ -1037,7 +1037,7 @@ static void R_AddEdgeToLightScissor( trRefLight_t *light, const vec3_t in_world1 R_AddPointToLightScissor( light, clip1 ); R_AddPointToLightScissor( light, clip2 ); } - else if ( r_lightScissors->integer == 2 ) + else if ( r_lightScissors.Get() == 2 ) { // clip against all planes for ( i = 0; i < FRUSTUM_PLANES; i++ ) @@ -1486,7 +1486,7 @@ cullResult_t R_CullLightWorldBounds( trRefLight_t *light, vec3_t worldBounds[ 2 bool anyClip; int r; - if ( r_nocull->integer ) + if ( r_nocull.Get() ) { return cullResult_t::CULL_CLIP; } diff --git a/src/engine/renderer/tr_local.h b/src/engine/renderer/tr_local.h index 896a9b3a50..10d8080d36 100644 --- a/src/engine/renderer/tr_local.h +++ b/src/engine/renderer/tr_local.h @@ -2927,18 +2927,18 @@ enum class shaderProfilerRenderSubGroupsMode { extern Cvar::Cvar r_dpBlend; - extern cvar_t *r_znear; // near Z clip plane - extern cvar_t *r_zfar; + extern Cvar::Cvar r_znear; // near Z clip plane + extern Cvar::Cvar r_zfar; - extern cvar_t *r_colorbits; // number of desired color bits, only relevant for fullscreen + extern Cvar::Cvar r_colorbits; extern cvar_t *r_measureOverdraw; // enables stencil buffer overdraw measurement - extern cvar_t *r_lodBias; // push/pull LOD transitions - extern cvar_t *r_lodScale; + extern Cvar::Cvar r_lodBias; // push/pull LOD transitions + extern Cvar::Cvar r_lodScale; - extern cvar_t *r_wolfFog; - extern cvar_t *r_noFog; + extern Cvar::Cvar r_wolfFog; + extern Cvar::Cvar r_noFog; extern Cvar::Range> r_forceAmbient; extern Cvar::Cvar r_ambientScale; @@ -2948,8 +2948,8 @@ enum class shaderProfilerRenderSubGroupsMode { extern Cvar::Range> r_realtimeLightingRenderer; extern Cvar::Cvar r_realtimeLighting; extern Cvar::Range> r_realtimeLightLayers; - extern cvar_t *r_realtimeLightingCastShadows; - extern cvar_t *r_precomputedLighting; + extern Cvar::Cvar r_realtimeLightingCastShadows; + extern Cvar::Cvar r_precomputedLighting; extern Cvar::Cvar r_overbrightDefaultExponent; extern Cvar::Cvar r_overbrightDefaultClamp; extern Cvar::Cvar r_overbrightIgnoreMapSettings; @@ -2961,63 +2961,63 @@ enum class shaderProfilerRenderSubGroupsMode { extern Cvar::Cvar r_gpuOcclusionCulling; extern Cvar::Cvar r_materialSystemSkip; extern Cvar::Cvar r_geometryCache; - extern cvar_t *r_lightStyles; - extern cvar_t *r_exportTextures; - extern cvar_t *r_heatHaze; - extern cvar_t *r_noMarksOnTrisurfs; + extern Cvar::Cvar r_lightStyles; + extern Cvar::Cvar r_exportTextures; + extern Cvar::Cvar r_heatHaze; + extern Cvar::Cvar r_noMarksOnTrisurfs; extern Cvar::Range> r_lazyShaders; // 0: build all shaders on program start 1: delay shader build until first map load 2: delay shader build until needed - extern cvar_t *r_norefresh; // bypasses the ref rendering - extern cvar_t *r_drawentities; // disable/enable entity rendering - extern cvar_t *r_drawworld; // disable/enable world rendering - extern cvar_t *r_drawpolies; // disable/enable world rendering - extern cvar_t *r_speeds; // various levels of information display - extern cvar_t *r_novis; // disable/enable usage of PVS - extern cvar_t *r_nocull; - extern cvar_t *r_facePlaneCull; // enables culling of planar surfaces with back side test - extern cvar_t *r_nocurves; - extern cvar_t *r_lightScissors; + extern Cvar::Cvar r_norefresh; + extern Cvar::Cvar r_drawentities; + extern Cvar::Cvar r_drawworld; + extern Cvar::Cvar r_drawpolies; + extern Cvar::Range> r_speeds; + extern Cvar::Cvar r_novis; + extern Cvar::Cvar r_nocull; + extern Cvar::Cvar r_facePlaneCull; + extern Cvar::Cvar r_nocurves; + extern Cvar::Range> r_lightScissors; extern cvar_t *r_noLightVisCull; extern cvar_t *r_noInteractionSort; - extern cvar_t *r_mode; // video mode - extern cvar_t *r_gamma; + extern Cvar::Cvar r_mode; + extern Cvar::Cvar r_gamma; - extern cvar_t *r_nobind; // turns off binding to appropriate textures - extern cvar_t *r_singleShader; // make most world faces use default shader - extern cvar_t *r_picMip; // controls picmip values - extern cvar_t *r_imageMaxDimension; - extern cvar_t *r_ignoreMaterialMinDimension; - extern cvar_t *r_ignoreMaterialMaxDimension; - extern cvar_t *r_replaceMaterialMinDimensionIfPresentWithMaxDimension; + extern Cvar::Cvar r_nobind; + extern Cvar::Cvar r_singleShader; + extern Cvar::Cvar r_picMip; + extern Cvar::Cvar r_imageMaxDimension; + extern Cvar::Cvar r_ignoreMaterialMinDimension; + extern Cvar::Cvar r_ignoreMaterialMaxDimension; + extern Cvar::Cvar r_replaceMaterialMinDimensionIfPresentWithMaxDimension; extern Cvar::Range> r_imageFitScreen; - extern cvar_t *r_finish; - extern cvar_t *r_drawBuffer; + extern Cvar::Cvar r_finish; + extern Cvar::Cvar r_drawBuffer; extern Cvar::Modified> r_textureMode; - extern cvar_t *r_offsetFactor; - extern cvar_t *r_offsetUnits; - - extern cvar_t *r_physicalMapping; - extern cvar_t *r_specularExponentMin; - extern cvar_t *r_specularExponentMax; - extern cvar_t *r_specularScale; - extern cvar_t *r_specularMapping; - extern cvar_t *r_deluxeMapping; - extern cvar_t *r_normalScale; - extern cvar_t *r_normalMapping; - extern cvar_t *r_highQualityNormalMapping; - extern cvar_t *r_liquidMapping; - extern cvar_t *r_reliefDepthScale; - extern cvar_t *r_reliefMapping; - extern cvar_t *r_glowMapping; + extern Cvar::Cvar r_offsetFactor; + extern Cvar::Cvar r_offsetUnits; + + extern Cvar::Cvar r_physicalMapping; + extern Cvar::Cvar r_specularExponentMin; + extern Cvar::Cvar r_specularExponentMax; + extern Cvar::Cvar r_specularScale; + extern Cvar::Cvar r_specularMapping; + extern Cvar::Cvar r_deluxeMapping; + extern Cvar::Cvar r_normalScale; + extern Cvar::Cvar r_normalMapping; + extern Cvar::Cvar r_highQualityNormalMapping; + extern Cvar::Cvar r_liquidMapping; + extern Cvar::Cvar r_reliefDepthScale; + extern Cvar::Cvar r_reliefMapping; + extern Cvar::Cvar r_glowMapping; extern Cvar::Cvar r_reflectionMapping; extern Cvar::Range> r_autoBuildCubeMaps; extern Cvar::Range> r_cubeProbeSize; extern Cvar::Range> r_cubeProbeSpacing; - extern cvar_t *r_halfLambertLighting; - extern cvar_t *r_rimLighting; - extern cvar_t *r_rimExponent; + extern Cvar::Cvar r_halfLambertLighting; + extern Cvar::Cvar r_rimLighting; + extern Cvar::Range> r_rimExponent; extern Cvar::Cvar r_highPrecisionRendering; @@ -3053,51 +3053,51 @@ enum class shaderProfilerRenderSubGroupsMode { extern cvar_t *r_parallelShadowSplits; extern cvar_t *r_parallelShadowSplitWeight; - extern cvar_t *r_lockpvs; - extern cvar_t *r_noportals; - extern cvar_t *r_max_portal_levels; + extern Cvar::Cvar r_lockpvs; + extern Cvar::Cvar r_noportals; + extern Cvar::Cvar r_max_portal_levels; - extern cvar_t *r_subdivisions; - extern cvar_t *r_stitchCurves; + extern Cvar::Cvar r_subdivisions; + extern Cvar::Cvar r_stitchCurves; - extern cvar_t *r_smp; - extern cvar_t *r_showSmp; - extern cvar_t *r_skipBackEnd; + extern Cvar::Cvar r_smp; + extern Cvar::Cvar r_showSmp; + extern Cvar::Cvar r_skipBackEnd; - extern cvar_t *r_checkGLErrors; + extern Cvar::Range> r_checkGLErrors; - extern cvar_t *r_debugSurface; + extern Cvar::Cvar r_debugSurface; - extern cvar_t *r_showImages; - extern cvar_t *r_debugSort; + extern Cvar::Range> r_showImages; + extern Cvar::Cvar r_debugSort; - extern cvar_t *r_printShaders; + extern Cvar::Cvar r_printShaders; - extern cvar_t *r_maxPolys; - extern cvar_t *r_maxPolyVerts; + extern Cvar::Range> r_maxPolys; + extern Cvar::Range> r_maxPolyVerts; - extern cvar_t *r_showTris; // enables wireframe rendering of the world - extern cvar_t *r_showSky; // forces sky in front of all surfaces + extern Cvar::Cvar r_showTris; + extern Cvar::Cvar r_showSky; extern cvar_t *r_showShadowLod; extern cvar_t *r_showShadowMaps; - extern cvar_t *r_showSkeleton; - extern cvar_t *r_showEntityTransforms; - extern cvar_t *r_showLightTransforms; - extern cvar_t *r_showLightInteractions; - extern cvar_t *r_showLightScissors; - extern cvar_t *r_showLightBatches; - extern cvar_t *r_showLightGrid; - extern cvar_t *r_showLightTiles; - extern cvar_t *r_showBatches; + extern Cvar::Cvar r_showSkeleton; + extern Cvar::Cvar r_showEntityTransforms; + extern Cvar::Cvar r_showLightTransforms; + extern Cvar::Cvar r_showLightInteractions; + extern Cvar::Cvar r_showLightScissors; + extern Cvar::Cvar r_showLightBatches; + extern Cvar::Cvar r_showLightGrid; + extern Cvar::Cvar r_showLightTiles; + extern Cvar::Cvar r_showBatches; extern Cvar::Cvar r_showVertexColors; - extern cvar_t *r_showLightMaps; // render lightmaps only - extern cvar_t *r_showDeluxeMaps; - extern cvar_t *r_showNormalMaps; - extern cvar_t *r_showMaterialMaps; + extern Cvar::Cvar r_showLightMaps; + extern Cvar::Cvar r_showDeluxeMaps; + extern Cvar::Cvar r_showNormalMaps; + extern Cvar::Cvar r_showMaterialMaps; extern Cvar::Cvar r_showReflectionMaps; extern Cvar::Range> r_showCubeProbes; extern Cvar::Cvar r_showCubeProbeFace; - extern cvar_t *r_showBspNodes; + extern Cvar::Range> r_showBspNodes; extern Cvar::Range> r_showGlobalMaterials; extern Cvar::Cvar r_materialDebug; extern cvar_t *r_showParallelShadowSplits; @@ -3108,19 +3108,19 @@ enum class shaderProfilerRenderSubGroupsMode { extern Cvar::Range> r_profilerRenderSubGroupsMode; extern Cvar::Cvar r_profilerRenderSubGroupsStage; - extern cvar_t *r_vboFaces; - extern cvar_t *r_vboCurves; - extern cvar_t *r_vboTriangles; - extern cvar_t *r_vboModels; - extern cvar_t *r_vboVertexSkinning; + extern Cvar::Cvar r_vboFaces; + extern Cvar::Cvar r_vboCurves; + extern Cvar::Cvar r_vboTriangles; + extern Cvar::Cvar r_vboModels; + extern Cvar::Cvar r_vboVertexSkinning; - extern cvar_t *r_mergeLeafSurfaces; + extern Cvar::Cvar r_mergeLeafSurfaces; extern Cvar::Cvar r_bloom; extern Cvar::Cvar r_bloomBlur; extern Cvar::Cvar r_bloomPasses; - extern cvar_t *r_FXAA; - extern cvar_t *r_ssao; + extern Cvar::Cvar r_FXAA; + extern Cvar::Cvar r_ssao; extern cvar_t *r_evsmPostProcess; @@ -3133,9 +3133,9 @@ enum class shaderProfilerRenderSubGroupsMode { inline bool checkGLErrors() { #ifdef DEBUG_BUILD - return r_checkGLErrors->integer != 0; + return r_checkGLErrors.Get() != 0; #else - return r_checkGLErrors->integer > 0; + return r_checkGLErrors.Get() > 0; #endif } diff --git a/src/engine/renderer/tr_main.cpp b/src/engine/renderer/tr_main.cpp index 2c8ac3d501..4718321886 100644 --- a/src/engine/renderer/tr_main.cpp +++ b/src/engine/renderer/tr_main.cpp @@ -342,7 +342,7 @@ cullResult_t R_CullBox( vec3_t worldBounds[ 2 ] ) cplane_t *frust; int i, r; - if ( r_nocull->integer ) + if ( r_nocull.Get() ) { return cullResult_t::CULL_CLIP; } @@ -421,7 +421,7 @@ cullResult_t R_CullPointAndRadius( vec3_t pt, float radius ) cplane_t *frust; bool mightBeClipped = false; - if ( r_nocull->integer ) + if ( r_nocull.Get() ) { return cullResult_t::CULL_CLIP; } @@ -895,14 +895,14 @@ static void R_SetupProjection( bool infiniteFarClip ) // portal views are constrained to their surface plane if ( tr.viewParms.portalLevel == 0 ) { - tr.viewParms.zNear = r_znear->value; + tr.viewParms.zNear = r_znear.Get(); } zNear = tr.viewParms.zNear; - if ( r_zfar->value ) + if ( r_zfar.Get() ) { - zFar = tr.viewParms.zFar = std::max( tr.viewParms.zFar, r_zfar->value ); + zFar = tr.viewParms.zFar = std::max( tr.viewParms.zFar, r_zfar.Get() ); } else if ( infiniteFarClip ) { @@ -913,7 +913,7 @@ static void R_SetupProjection( bool infiniteFarClip ) zFar = tr.viewParms.zFar; } - if ( zFar <= 0 || infiniteFarClip ) // || r_showBspNodes->integer) + if ( zFar <= 0 || infiniteFarClip ) { MatrixPerspectiveProjectionFovXYInfiniteRH( proj, tr.refdef.fov_x, tr.refdef.fov_y, zNear ); } @@ -1016,7 +1016,7 @@ static void R_SetupFrustum() tr.viewParms.frustums[ 0 ][ FRUSTUM_NEAR ].type = PLANE_NON_AXIAL; VectorCopy( tr.viewParms.orientation.axis[ 0 ], tr.viewParms.frustums[ 0 ][ FRUSTUM_NEAR ].normal ); - VectorMA( tr.viewParms.orientation.origin, r_znear->value, tr.viewParms.frustums[ 0 ][ FRUSTUM_NEAR ].normal, planeOrigin ); + VectorMA( tr.viewParms.orientation.origin, r_znear.Get(), tr.viewParms.frustums[ 0 ][ FRUSTUM_NEAR ].normal, planeOrigin ); tr.viewParms.frustums[ 0 ][ FRUSTUM_NEAR ].dist = DotProduct( planeOrigin, tr.viewParms.frustums[ 0 ][ FRUSTUM_NEAR ].normal ); SetPlaneSignbits( &tr.viewParms.frustums[ 0 ][ FRUSTUM_NEAR ] ); } @@ -1697,7 +1697,7 @@ static void R_SetupPortalFrustum( const viewParms_t& oldParms, const orientation } zNear = sqrtf(zNear); - zNear = std::max(zNear, r_znear->value); + zNear = std::max(zNear, r_znear.Get() ); newParms.zNear = zNear; } @@ -1715,7 +1715,7 @@ bool R_MirrorViewBySurface(drawSurf_t *drawSurf) screenRect_t surfRect; // don't recursively mirror too much - if ( tr.viewParms.portalLevel >= r_max_portal_levels->integer && + if ( tr.viewParms.portalLevel >= r_max_portal_levels.Get() && tr.viewParms.portalLevel > 0 ) { /* Having more than one mirror in a scene is not a bug, @@ -1725,7 +1725,7 @@ bool R_MirrorViewBySurface(drawSurf_t *drawSurf) return false; } - if (r_noportals->integer) + if ( r_noportals.Get() ) { return false; } @@ -2038,16 +2038,15 @@ R_AddEntitySurfaces */ void R_AddEntitySurfaces() { - int i; trRefEntity_t *ent; shader_t *shader; - if ( !r_drawentities->integer ) + if ( !r_drawentities.Get() ) { return; } - for ( i = 0; i < tr.refdef.numEntities; i++ ) + for ( int i = 0; i < tr.refdef.numEntities; i++ ) { ent = tr.currentEntity = &tr.refdef.entities[ i ]; @@ -2148,16 +2147,15 @@ R_AddEntityInteractions */ void R_AddEntityInteractions( trRefLight_t *light ) { - int i; trRefEntity_t *ent; interactionType_t iaType; - if ( !r_drawentities->integer ) + if ( !r_drawentities.Get() ) { return; } - for ( i = 0; i < tr.refdef.numEntities; i++ ) + for ( int i = 0; i < tr.refdef.numEntities; i++ ) { iaType = IA_DEFAULT; @@ -2464,7 +2462,7 @@ Visualization aid for movement clipping debugging */ static void R_DebugGraphics() { - if ( r_debugSurface->integer ) + if ( r_debugSurface.Get() ) { // the render thread can't make callbacks to the main thread R_SyncRenderThread(); diff --git a/src/engine/renderer/tr_marks.cpp b/src/engine/renderer/tr_marks.cpp index c54e82f383..ac67b8cd6a 100644 --- a/src/engine/renderer/tr_marks.cpp +++ b/src/engine/renderer/tr_marks.cpp @@ -479,7 +479,7 @@ int R_MarkFragments( int numPoints, const vec3_t *points, const vec3_t projectio } } } - else if ( *surfaces[ i ] == surfaceType_t::SF_TRIANGLES && !r_noMarksOnTrisurfs->integer ) + else if ( *surfaces[ i ] == surfaceType_t::SF_TRIANGLES && !r_noMarksOnTrisurfs.Get() ) { trisurf = ( srfTriangles_t * ) surfaces[ i ]; diff --git a/src/engine/renderer/tr_mesh.cpp b/src/engine/renderer/tr_mesh.cpp index 8aefcda50b..76c29701fd 100644 --- a/src/engine/renderer/tr_mesh.cpp +++ b/src/engine/renderer/tr_mesh.cpp @@ -157,7 +157,7 @@ int R_ComputeLOD( trRefEntity_t *ent ) if ( ( projectedRadius = R_ProjectRadius( radius, ent->e.origin ) ) != 0 ) { - lodscale = r_lodScale->value; + lodscale = r_lodScale.Get(); if ( lodscale > 20 ) { @@ -185,7 +185,7 @@ int R_ComputeLOD( trRefEntity_t *ent ) } } - lod += r_lodBias->integer; + lod += r_lodBias.Get(); if ( lod >= tr.currentModel->numLods ) { @@ -306,7 +306,7 @@ void R_AddMDVSurfaces( trRefEntity_t *ent ) fogNum = R_FogWorldBox( ent->worldBounds ); // draw all surfaces - if ( r_vboModels->integer && model->numVBOSurfaces ) + if ( r_vboModels.Get() && model->numVBOSurfaces ) { srfVBOMDVMesh_t *vboSurface; @@ -416,7 +416,7 @@ void R_AddMDVInteractions( trRefEntity_t *ent, trRefLight_t *light, interactionT cubeSideBits = R_CalcLightCubeSideBits( light, ent->worldBounds ); // generate interactions with all surfaces - if ( r_vboModels->integer && model->numVBOSurfaces ) + if ( r_vboModels.Get() && model->numVBOSurfaces ) { // new brute force method: just render everthing with static VBOs srfVBOMDVMesh_t *vboSurface; diff --git a/src/engine/renderer/tr_model_iqm.cpp b/src/engine/renderer/tr_model_iqm.cpp index c865571542..6d937d41a4 100644 --- a/src/engine/renderer/tr_model_iqm.cpp +++ b/src/engine/renderer/tr_model_iqm.cpp @@ -767,7 +767,7 @@ bool R_LoadIQModel( model_t *mod, const void *buffer, int filesize, } // convert data where necessary and create VBO - if( r_vboModels->integer && glConfig2.vboVertexSkinningAvailable + if( r_vboModels.Get() && glConfig2.vboVertexSkinningAvailable && IQModel->num_joints <= glConfig2.maxVertexSkinningBones ) { uint16_t *boneFactorBuf = (uint16_t*)ri.Hunk_AllocateTempMemory( IQModel->num_vertexes * ( 4 * sizeof(uint16_t) ) ); diff --git a/src/engine/renderer/tr_scene.cpp b/src/engine/renderer/tr_scene.cpp index aa02565b4a..e6e5793f82 100644 --- a/src/engine/renderer/tr_scene.cpp +++ b/src/engine/renderer/tr_scene.cpp @@ -52,7 +52,7 @@ R_ToggleSmpFrame */ void R_ToggleSmpFrame() { - if ( r_smp->integer ) + if ( r_smp.Get() ) { // use the other buffers next frame, because another CPU // may still be rendering into the current ones @@ -118,7 +118,7 @@ void R_AddPolygonSurfaces() shader_t *sh; srfPoly_t *poly; - if ( !r_drawpolies->integer ) + if ( !r_drawpolies.Get() ) { return; } @@ -150,7 +150,7 @@ static void R_AddPolysToScene( qhandle_t hShader, int numVerts, const polyVert_t return; } - if ( !r_drawpolies->integer ) + if ( !r_drawpolies.Get() ) { return; } @@ -163,7 +163,7 @@ static void R_AddPolysToScene( qhandle_t hShader, int numVerts, const polyVert_t for ( j = 0; j < numPolys; j++ ) { - if ( r_numPolyVerts + numVerts >= r_maxPolyVerts->integer || r_numPolys >= r_maxPolys->integer ) + if ( r_numPolyVerts + numVerts >= r_maxPolyVerts.Get() || r_numPolys >= r_maxPolys.Get() ) { /* NOTE TTimo this was initially Log::Warn @@ -171,7 +171,7 @@ static void R_AddPolysToScene( qhandle_t hShader, int numVerts, const polyVert_t since we don't plan on changing the const and making for room for those effects simply cut this message to developer only */ - Log::Debug("RE_AddPolyToScene: r_max_polys or r_max_polyverts reached" ); + Log::Debug( "RE_AddPolyToScene: r_max_polys or r_max_polyverts reached" ); return; } @@ -335,7 +335,7 @@ void RE_AddDynamicLightToSceneET( const vec3_t org, float radius, float intensit light->l.color[ 2 ] = b; light->l.inverseShadows = (flags & REF_INVERSE_DLIGHT) != 0; - light->l.noShadows = !r_realtimeLightingCastShadows->integer && !light->l.inverseShadows; + light->l.noShadows = !r_realtimeLightingCastShadows.Get() && !light->l.inverseShadows; if( flags & REF_RESTRICT_DLIGHT ) { light->restrictInteractionFirst = r_numEntities - r_firstSceneEntity; @@ -500,8 +500,6 @@ to handle mirrors, */ void RE_RenderScene( const refdef_t *fd ) { - int startTime; - if ( !tr.registered ) { return; @@ -509,12 +507,12 @@ void RE_RenderScene( const refdef_t *fd ) GLimp_LogComment( "====== RE_RenderScene =====\n" ); - if ( r_norefresh->integer ) + if ( r_norefresh.Get() ) { return; } - startTime = ri.Milliseconds(); + int startTime = ri.Milliseconds(); if ( !tr.world && !( fd->rdflags & RDF_NOWORLDMODEL ) ) { diff --git a/src/engine/renderer/tr_shade.cpp b/src/engine/renderer/tr_shade.cpp index f9d6f77d36..09b14ee0e3 100644 --- a/src/engine/renderer/tr_shade.cpp +++ b/src/engine/renderer/tr_shade.cpp @@ -103,11 +103,11 @@ static void EnableAvailableFeatures() } } - glConfig2.deluxeMapping = r_deluxeMapping->integer; - glConfig2.normalMapping = r_normalMapping->integer; - glConfig2.specularMapping = r_specularMapping->integer; - glConfig2.physicalMapping = r_physicalMapping->integer; - glConfig2.reliefMapping = r_reliefMapping->integer; + glConfig2.deluxeMapping = r_deluxeMapping.Get(); + glConfig2.normalMapping = r_normalMapping.Get(); + glConfig2.specularMapping = r_specularMapping.Get(); + glConfig2.physicalMapping = r_physicalMapping.Get(); + glConfig2.reliefMapping = r_reliefMapping.Get(); /* ATI R300 and Intel GMA 3 only have 64 ALU instructions, which is not enough for some shader variants. For example the lightMapping shader permutation with macros USE_GRID_LIGHTING and @@ -308,7 +308,7 @@ static void GLSL_InitGPUShadersOrError() gl_shaderManager.load( gl_fogGlobalShader ); } - if ( r_heatHaze->integer ) + if ( r_heatHaze.Get() ) { // heatHaze post process effect gl_shaderManager.load( gl_heatHazeShader ); @@ -333,7 +333,7 @@ static void GLSL_InitGPUShadersOrError() gl_shaderManager.load( gl_contrastShader ); } - if ( !r_noportals->integer || r_liquidMapping->integer ) + if ( !r_noportals.Get() || r_liquidMapping.Get() ) { // portal process effect gl_shaderManager.load( gl_portalShader ); @@ -357,7 +357,7 @@ static void GLSL_InitGPUShadersOrError() gl_shaderManager.load( gl_debugShadowMapShader ); } - if ( r_liquidMapping->integer != 0 ) + if ( r_liquidMapping.Get() ) { gl_shaderManager.load( gl_liquidShader ); @@ -372,7 +372,7 @@ static void GLSL_InitGPUShadersOrError() gl_shaderManager.load( gl_motionblurShader ); } - if ( r_ssao->integer ) + if ( r_ssao.Get() ) { if ( glConfig2.textureGatherAvailable ) { @@ -384,7 +384,7 @@ static void GLSL_InitGPUShadersOrError() } } - if ( r_FXAA->integer != 0 ) + if ( r_FXAA.Get() != 0 ) { gl_shaderManager.load( gl_fxaaShader ); } @@ -672,7 +672,7 @@ static void DrawTris() // u_AlphaThreshold gl_genericShader->SetUniform_AlphaTest( GLS_ATEST_NONE ); - if ( r_showBatches->integer || r_showLightBatches->integer ) + if ( r_showBatches.Get() || r_showLightBatches.Get() ) { gl_genericShader->SetUniform_Color( Color::Color::Indexed( backEnd.pc.c_batches % 8 ) ); } @@ -802,7 +802,7 @@ void SetNormalScale( const shaderStage_t *pStage, vec3_t normalScale ) r_normalScale is set to zero. This is cool enough to be kept as a feature. Normal Z component equal to zero would be wrong anyway. r_normalScale is only applied on Z. */ - normalScale[ 2 ] = pStage->normalScale[ 2 ] * r_normalScale->value; + normalScale[ 2 ] = pStage->normalScale[ 2 ] * r_normalScale.Get(); } // *INDENT-ON* @@ -962,7 +962,7 @@ void Render_lightMapping( shaderStage_t *pStage ) uint32_t stateBits = pStage->stateBits; - if ( lightMode == lightMode_t::MAP && r_showLightMaps->integer ) + if ( lightMode == lightMode_t::MAP && r_showLightMaps.Get() ) { stateBits &= ~( GLS_SRCBLEND_BITS | GLS_DSTBLEND_BITS | GLS_ATEST_BITS ); } @@ -1066,7 +1066,7 @@ void Render_lightMapping( shaderStage_t *pStage ) // bind u_HeightMap if ( pStage->enableReliefMapping ) { - float depthScale = RB_EvalExpression( &pStage->depthScaleExp, r_reliefDepthScale->value ); + float depthScale = RB_EvalExpression( &pStage->depthScaleExp, r_reliefDepthScale.Get() ); depthScale *= tess.surfaceShader->reliefDepthScale; gl_lightMappingShader->SetUniform_ReliefDepthScale( depthScale ); @@ -1092,7 +1092,7 @@ void Render_lightMapping( shaderStage_t *pStage ) } // bind u_NormalMap - if ( !!r_normalMapping->integer || pStage->hasHeightMapInNormalMap ) + if ( !!r_normalMapping.Get() || pStage->hasHeightMapInNormalMap ) { gl_lightMappingShader->SetUniform_NormalMapBindless( GL_BindToTMU( BIND_NORMALMAP, pStage->bundle[TB_NORMALMAP].image[0] ) @@ -1118,8 +1118,8 @@ void Render_lightMapping( shaderStage_t *pStage ) if ( pStage->enableSpecularMapping ) { - float specExpMin = RB_EvalExpression( &pStage->specularExponentMin, r_specularExponentMin->value ); - float specExpMax = RB_EvalExpression( &pStage->specularExponentMax, r_specularExponentMax->value ); + float specExpMin = RB_EvalExpression( &pStage->specularExponentMin, r_specularExponentMin.Get() ); + float specExpMax = RB_EvalExpression( &pStage->specularExponentMax, r_specularExponentMax.Get() ); gl_lightMappingShader->SetUniform_SpecularExponent( specExpMin, specExpMax ); } @@ -1198,7 +1198,7 @@ void Render_lightMapping( shaderStage_t *pStage ) } // bind u_GlowMap - if ( !!r_glowMapping->integer ) + if ( r_glowMapping.Get() ) { gl_lightMappingShader->SetUniform_GlowMapBindless( GL_BindToTMU( BIND_GLOWMAP, pStage->bundle[TB_GLOWMAP].image[0] ) @@ -1339,7 +1339,7 @@ static void Render_forwardLighting_DBS_omni( shaderStage_t *pStage, // bind u_HeightMap if ( pStage->enableReliefMapping ) { - float depthScale = RB_EvalExpression( &pStage->depthScaleExp, r_reliefDepthScale->value ); + float depthScale = RB_EvalExpression( &pStage->depthScaleExp, r_reliefDepthScale.Get() ); depthScale *= tess.surfaceShader->reliefDepthScale; gl_forwardLightingShader_omniXYZ->SetUniform_ReliefDepthScale( depthScale ); @@ -1432,8 +1432,8 @@ static void Render_forwardLighting_DBS_omni( shaderStage_t *pStage, // FIXME: physical mapping is not implemented. if ( pStage->enableSpecularMapping ) { - float minSpec = RB_EvalExpression( &pStage->specularExponentMin, r_specularExponentMin->value ); - float maxSpec = RB_EvalExpression( &pStage->specularExponentMax, r_specularExponentMax->value ); + float minSpec = RB_EvalExpression( &pStage->specularExponentMin, r_specularExponentMin.Get() ); + float maxSpec = RB_EvalExpression( &pStage->specularExponentMax, r_specularExponentMax.Get() ); gl_forwardLightingShader_omniXYZ->SetUniform_SpecularExponent( minSpec, maxSpec ); @@ -1514,7 +1514,7 @@ static void Render_forwardLighting_DBS_proj( shaderStage_t *pStage, // bind u_HeightMap if ( pStage->enableReliefMapping ) { - float depthScale = RB_EvalExpression( &pStage->depthScaleExp, r_reliefDepthScale->value ); + float depthScale = RB_EvalExpression( &pStage->depthScaleExp, r_reliefDepthScale.Get() ); depthScale *= tess.surfaceShader->reliefDepthScale; gl_forwardLightingShader_projXYZ->SetUniform_ReliefDepthScale( depthScale ); @@ -1613,8 +1613,8 @@ static void Render_forwardLighting_DBS_proj( shaderStage_t *pStage, // FIXME: physical mapping is not implemented. if ( pStage->enableSpecularMapping ) { - float minSpec = RB_EvalExpression( &pStage->specularExponentMin, r_specularExponentMin->value ); - float maxSpec = RB_EvalExpression( &pStage->specularExponentMax, r_specularExponentMax->value ); + float minSpec = RB_EvalExpression( &pStage->specularExponentMin, r_specularExponentMin.Get() ); + float maxSpec = RB_EvalExpression( &pStage->specularExponentMax, r_specularExponentMax.Get() ); gl_forwardLightingShader_projXYZ->SetUniform_SpecularExponent( minSpec, maxSpec ); } @@ -1690,7 +1690,7 @@ static void Render_forwardLighting_DBS_directional( shaderStage_t *pStage, trRef // bind u_HeightMap if ( pStage->enableReliefMapping ) { - float depthScale = RB_EvalExpression( &pStage->depthScaleExp, r_reliefDepthScale->value ); + float depthScale = RB_EvalExpression( &pStage->depthScaleExp, r_reliefDepthScale.Get() ); depthScale *= tess.surfaceShader->reliefDepthScale; gl_forwardLightingShader_directionalSun->SetUniform_ReliefDepthScale( depthScale ); @@ -1793,8 +1793,8 @@ static void Render_forwardLighting_DBS_directional( shaderStage_t *pStage, trRef // FIXME: physical mapping is not implemented. if ( pStage->enableSpecularMapping ) { - float minSpec = RB_EvalExpression( &pStage->specularExponentMin, r_specularExponentMin->value ); - float maxSpec = RB_EvalExpression( &pStage->specularExponentMax, r_specularExponentMax->value ); + float minSpec = RB_EvalExpression( &pStage->specularExponentMin, r_specularExponentMin.Get() ); + float maxSpec = RB_EvalExpression( &pStage->specularExponentMax, r_specularExponentMax.Get() ); gl_forwardLightingShader_directionalSun->SetUniform_SpecularExponent( minSpec, maxSpec ); } @@ -1925,7 +1925,7 @@ void Render_reflection_CB( shaderStage_t *pStage ) // bind u_HeightMap u_depthScale u_reliefOffsetBias if ( pStage->enableReliefMapping ) { - float depthScale = RB_EvalExpression( &pStage->depthScaleExp, r_reliefDepthScale->value ); + float depthScale = RB_EvalExpression( &pStage->depthScaleExp, r_reliefDepthScale.Get() ); depthScale *= tess.surfaceShader->reliefDepthScale; gl_reflectionShader->SetUniform_ReliefDepthScale( depthScale ); @@ -2161,8 +2161,8 @@ void Render_liquid( shaderStage_t *pStage ) // FIXME: physical mapping is not implemented. if ( pStage->enableSpecularMapping ) { - float specMin = RB_EvalExpression( &pStage->specularExponentMin, r_specularExponentMin->value ); - float specMax = RB_EvalExpression( &pStage->specularExponentMax, r_specularExponentMax->value ); + float specMin = RB_EvalExpression( &pStage->specularExponentMin, r_specularExponentMin.Get() ); + float specMax = RB_EvalExpression( &pStage->specularExponentMax, r_specularExponentMax.Get() ); gl_liquidShader->SetUniform_SpecularExponent( specMin, specMax ); } @@ -2178,7 +2178,7 @@ void Render_liquid( shaderStage_t *pStage ) // bind u_HeightMap u_depthScale u_reliefOffsetBias if ( pStage->enableReliefMapping ) { - float depthScale = RB_EvalExpression( &pStage->depthScaleExp, r_reliefDepthScale->value ); + float depthScale = RB_EvalExpression( &pStage->depthScaleExp, r_reliefDepthScale.Get() ); depthScale *= tess.surfaceShader->reliefDepthScale; gl_liquidShader->SetUniform_ReliefDepthScale( depthScale ); @@ -2213,7 +2213,7 @@ void Render_liquid( shaderStage_t *pStage ) void Render_fog( shaderStage_t* pStage ) { - if ( r_noFog->integer || !r_wolfFog->integer || ( backEnd.refdef.rdflags & RDF_NOWORLDMODEL ) ) + if ( r_noFog.Get() || !r_wolfFog.Get() || ( backEnd.refdef.rdflags & RDF_NOWORLDMODEL ) ) { return; } @@ -2632,7 +2632,7 @@ void Tess_StageIteratorColor() if ( tess.surfaceShader->polygonOffset ) { glEnable( GL_POLYGON_OFFSET_FILL ); - GL_PolygonOffset( r_offsetFactor->value, r_offsetUnits->value ); + GL_PolygonOffset( r_offsetFactor.Get(), r_offsetUnits.Get() ); } // call shader function @@ -2745,7 +2745,7 @@ void Tess_StageIteratorShadowFill() if ( tess.surfaceShader->polygonOffset ) { glEnable( GL_POLYGON_OFFSET_FILL ); - GL_PolygonOffset( r_offsetFactor->value, r_offsetUnits->value ); + GL_PolygonOffset( r_offsetFactor.Get(), r_offsetUnits.Get() ); } // call shader function @@ -2823,7 +2823,7 @@ void Tess_StageIteratorLighting() if ( tess.surfaceShader->polygonOffset ) { glEnable( GL_POLYGON_OFFSET_FILL ); - GL_PolygonOffset( r_offsetFactor->value, r_offsetUnits->value ); + GL_PolygonOffset( r_offsetFactor.Get(), r_offsetUnits.Get() ); } // call shader function @@ -2926,8 +2926,8 @@ void Tess_End() } // for debugging of sort order issues, stop rendering after a given sort value - bool skip = r_debugSort->integer && tess.surfaceShader != nullptr - && r_debugSort->integer < tess.surfaceShader->sort; + bool skip = r_debugSort.Get() && tess.surfaceShader != nullptr + && r_debugSort.Get() < tess.surfaceShader->sort; if ( !skip ) { // update performance counter @@ -2943,7 +2943,7 @@ void Tess_End() tess.stageIteratorFunc != Tess_StageIteratorDummy ) { // draw debugging stuff - if ( r_showTris->integer || r_showBatches->integer || ( r_showLightBatches->integer && ( tess.stageIteratorFunc == Tess_StageIteratorLighting ) ) ) + if ( r_showTris.Get() || r_showBatches.Get() || ( r_showLightBatches.Get() && ( tess.stageIteratorFunc == Tess_StageIteratorLighting ) ) ) { // Skybox triangle rendering is done in Tess_StageIteratorSky() if ( tess.stageIteratorFunc != Tess_StageIteratorSky ) { diff --git a/src/engine/renderer/tr_shader.cpp b/src/engine/renderer/tr_shader.cpp index 4f6ea8e370..efac6283ba 100644 --- a/src/engine/renderer/tr_shader.cpp +++ b/src/engine/renderer/tr_shader.cpp @@ -1426,7 +1426,7 @@ static bool LoadMap( shaderStage_t *stage, const char *buffer, stageType_t type, || ( type == stageType_t::ST_HEIGHTMAP && !glConfig2.reliefMapping ) || ( type == stageType_t::ST_SPECULARMAP && !glConfig2.specularMapping ) || ( type == stageType_t::ST_PHYSICALMAP && !glConfig2.physicalMapping ) - || ( type == stageType_t::ST_GLOWMAP && !r_glowMapping->integer ) + || ( type == stageType_t::ST_GLOWMAP && !r_glowMapping.Get() ) || ( type == stageType_t::ST_REFLECTIONMAP && !glConfig2.reflectionMappingAvailable ) ) { return true; @@ -1463,7 +1463,7 @@ static bool LoadMap( shaderStage_t *stage, const char *buffer, stageType_t type, So we don't load extra light maps when light styles are not supported. The disablement of the stage is done in the ParseShader() function. */ - if ( ( tr.lightMode != lightMode_t::MAP || r_lightStyles->integer == 0 ) + if ( ( tr.lightMode != lightMode_t::MAP || !r_lightStyles.Get() ) && stage->tcGen_Lightmap ) { /* We don't return false because we properly parsed the stage @@ -1608,7 +1608,7 @@ static void ParseNormalMap( shaderStage_t *stage, const char **text, const int b char buffer[ 1024 ] = ""; // because of collapsing, this affects other textures (diffuse, specular…) too - if ( r_highQualityNormalMapping->integer ) + if ( r_highQualityNormalMapping.Get() ) { stage->overrideFilterType = true; stage->filterType = filterType_t::FT_LINEAR; @@ -4023,7 +4023,7 @@ static bool ParseShader( const char *_text ) So we disable light style stages when light mapping is disabled. */ - if ( tr.lightMode != lightMode_t::MAP || r_lightStyles->integer == 0 ) + if ( tr.lightMode != lightMode_t::MAP || !r_lightStyles.Get() ) { switch ( stage->type ) { @@ -5189,7 +5189,7 @@ static void FinishStages() { shaderStage_t *stage = &stages[ s ]; - if ( r_showLightMaps->integer && lightStageFound ) + if ( r_showLightMaps.Get() && lightStageFound ) { stage->active = false; continue; @@ -5204,11 +5204,11 @@ static void FinishStages() break; case stageType_t::ST_HEATHAZEMAP: - stage->active = r_heatHaze->integer; + stage->active = r_heatHaze.Get(); break; case stageType_t::ST_LIQUIDMAP: - if ( !r_liquidMapping->integer ) + if ( !r_liquidMapping.Get() ) { stage->type = stageType_t::ST_COLLAPSE_DIFFUSEMAP; stage->bundle[ TB_DIFFUSEMAP ].image[ 0 ] = tr.whiteImage; @@ -5271,7 +5271,7 @@ static void FinishStages() stage->enableReliefMapping = glConfig2.reliefMapping && !shader.disableReliefMapping && ( hasHeightMap || stage->hasHeightMapInNormalMap ); - stage->enableGlowMapping = r_glowMapping->integer && hasGlowMap; + stage->enableGlowMapping = r_glowMapping.Get() && hasGlowMap; if ( stage->collapseType == collapseType_t::COLLAPSE_PBR ) { @@ -6333,7 +6333,7 @@ shader_t *R_FindShader( const char *name, shaderType_t type, int flags ) // make sure the render thread is stopped, because we are probably // going to have to upload an image - if ( r_smp->integer ) + if ( r_smp.Get() ) { R_SyncRenderThread(); } @@ -6382,7 +6382,7 @@ shader_t *R_FindShader( const char *name, shaderType_t type, int flags ) { // enable this when building a pak file to get a global list // of all explicit shaders - if ( r_printShaders->integer ) + if ( r_printShaders.Get() ) { Log::Notice("loading explicit shader '%s'", strippedName ); } @@ -6545,7 +6545,7 @@ qhandle_t RE_RegisterShaderFromImage( const char *name, image_t *image ) // make sure the render thread is stopped, because we are probably // going to have to upload an image - if ( r_smp->integer ) + if ( r_smp.Get() ) { R_SyncRenderThread(); } diff --git a/src/engine/renderer/tr_sky.cpp b/src/engine/renderer/tr_sky.cpp index de1c39eb4f..21021d398b 100644 --- a/src/engine/renderer/tr_sky.cpp +++ b/src/engine/renderer/tr_sky.cpp @@ -81,7 +81,7 @@ void Tess_StageIteratorSky() GL_Cull(cullType_t::CT_BACK_SIDED); // r_showSky will draw the whole skybox in front of everything else - if ( r_showSky->integer ) + if ( r_showSky.Get() ) { glDepthRange( 0.0, 0.0 ); } @@ -123,7 +123,7 @@ void Tess_StageIteratorSky() Tess_DrawElements(); } - if ( r_showTris->integer ) { + if ( r_showTris.Get() ) { GL_State( GLS_POLYMODE_LINE | GLS_DEPTHFUNC_ALWAYS ); // bind u_ColorMap diff --git a/src/engine/renderer/tr_surface.cpp b/src/engine/renderer/tr_surface.cpp index 7540948fb2..eda718fbe5 100644 --- a/src/engine/renderer/tr_surface.cpp +++ b/src/engine/renderer/tr_surface.cpp @@ -748,7 +748,7 @@ static void Tess_SurfaceFace( srfSurfaceFace_t *srf ) { GLimp_LogComment( "--- Tess_SurfaceFace ---\n" ); - if ( !r_vboFaces->integer || !Tess_SurfaceVBO( srf->vbo, srf->ibo, srf->numTriangles * 3, srf->firstIndex ) ) + if ( !r_vboFaces.Get() || !Tess_SurfaceVBO(srf->vbo, srf->ibo, srf->numTriangles * 3, srf->firstIndex) ) { Tess_SurfaceVertsAndTris( srf->verts, srf->triangles, srf->numVerts, srf->numTriangles ); } @@ -763,7 +763,7 @@ static void Tess_SurfaceGrid( srfGridMesh_t *srf ) { GLimp_LogComment( "--- Tess_SurfaceGrid ---\n" ); - if ( !r_vboCurves->integer || !Tess_SurfaceVBO( srf->vbo, srf->ibo, srf->numTriangles * 3, srf->firstIndex ) ) + if ( !r_vboCurves.Get() || !Tess_SurfaceVBO( srf->vbo, srf->ibo, srf->numTriangles * 3, srf->firstIndex ) ) { Tess_SurfaceVertsAndTris( srf->verts, srf->triangles, srf->numVerts, srf->numTriangles ); } @@ -778,7 +778,7 @@ static void Tess_SurfaceTriangles( srfTriangles_t *srf ) { GLimp_LogComment( "--- Tess_SurfaceTriangles ---\n" ); - if ( !r_vboTriangles->integer || !Tess_SurfaceVBO( srf->vbo, srf->ibo, srf->numTriangles * 3, srf->firstIndex ) ) + if ( !r_vboTriangles.Get() || !Tess_SurfaceVBO( srf->vbo, srf->ibo, srf->numTriangles * 3, srf->firstIndex ) ) { Tess_SurfaceVertsAndTris( srf->verts, srf->triangles, srf->numVerts, srf->numTriangles ); } diff --git a/src/engine/renderer/tr_types.h b/src/engine/renderer/tr_types.h index e00a2cd016..48740e47da 100644 --- a/src/engine/renderer/tr_types.h +++ b/src/engine/renderer/tr_types.h @@ -138,7 +138,7 @@ enum class refEntityType_t // RB: having bone names for each refEntity_t takes several MiBs // in backEndData_t so only use it for debugging and development -// enabling this will show the bone names with r_showSkeleton 1 +// enabling this will show the bone names with r_showSkeleton on struct refBone_t { diff --git a/src/engine/renderer/tr_world.cpp b/src/engine/renderer/tr_world.cpp index 4ca207aec0..5bc2d7baac 100644 --- a/src/engine/renderer/tr_world.cpp +++ b/src/engine/renderer/tr_world.cpp @@ -45,13 +45,13 @@ static bool R_CullSurface( surfaceType_t *surface, shader_t *shader, int planeBi float d; // allow culling to be disabled - if ( r_nocull->integer ) + if ( r_nocull.Get() ) { return false; } // ydnar: made surface culling generic, inline with q3map2 surface classification - if ( *surface == surfaceType_t::SF_GRID && r_nocurves->integer ) + if ( *surface == surfaceType_t::SF_GRID && r_nocurves.Get() ) { return true; } @@ -65,7 +65,7 @@ static bool R_CullSurface( surfaceType_t *surface, shader_t *shader, int planeBi gen = ( srfGeneric_t * ) surface; // plane cull - if ( *surface == surfaceType_t::SF_FACE && r_facePlaneCull->integer ) + if ( *surface == surfaceType_t::SF_FACE && r_facePlaneCull.Get() ) { srfSurfaceFace_t *srf = ( srfSurfaceFace_t * )gen; d = DotProduct( tr.orientation.viewOrigin, srf->plane.normal ) - srf->plane.dist; @@ -131,13 +131,13 @@ static bool R_CullLightSurface( surfaceType_t *surface, shader_t *shader, trRefL float d; // allow culling to be disabled - if ( r_nocull->integer ) + if ( r_nocull.Get() ) { return false; } // ydnar: made surface culling generic, inline with q3map2 surface classification - if ( *surface == surfaceType_t::SF_GRID && r_nocurves->integer ) + if ( *surface == surfaceType_t::SF_GRID && r_nocurves.Get() ) { return true; } @@ -165,7 +165,7 @@ static bool R_CullLightSurface( surfaceType_t *surface, shader_t *shader, trRefL } // plane cull - if ( *surface == surfaceType_t::SF_FACE && r_facePlaneCull->integer ) + if ( *surface == surfaceType_t::SF_FACE && r_facePlaneCull.Get() ) { srfSurfaceFace_t *srf = ( srfSurfaceFace_t * )gen; if ( light->l.rlType == refLightType_t::RL_DIRECTIONAL ) @@ -418,7 +418,7 @@ static void R_RecursiveWorldNode( bspNode_t *node, int planeBits ) // if the bounding volume is outside the frustum, nothing // inside can be visible - if ( !r_nocull->integer ) + if ( !r_nocull.Get() ) { int i; int r; @@ -492,7 +492,7 @@ static void R_RecursiveInteractionNode( bspNode_t *node, trRefLight_t *light, in // Tr3B - even surfaces that belong to nodes that are outside of the view frustum // can cast shadows into the view frustum - if ( !r_nocull->integer ) + if ( !r_nocull.Get() ) { for ( i = 0; i < FRUSTUM_PLANES; i++ ) { @@ -704,7 +704,7 @@ static void R_MarkLeaves() // lockpvs lets designers walk around to determine the // extent of the current pvs - if ( r_lockpvs->integer ) + if ( r_lockpvs.Get() ) { return; } @@ -750,7 +750,7 @@ static void R_MarkLeaves() Log::Notice("update cluster:%i area:%i index:%i", cluster, leaf->area, tr.visIndex ); } - if ( r_novis->integer || tr.visClusters[ tr.visIndex ] == -1 ) + if ( r_novis.Get() || tr.visClusters[tr.visIndex] == -1 ) { for ( i = 0; i < tr.world->numnodes; i++ ) { @@ -831,7 +831,7 @@ R_AddWorldSurfaces */ void R_AddWorldSurfaces() { - if ( !r_drawworld->integer ) + if ( !r_drawworld.Get() ) { return; } @@ -879,7 +879,7 @@ void R_AddWorldInteractions( trRefLight_t *light ) { int interactionBits; - if ( !r_drawworld->integer ) + if ( !r_drawworld.Get() ) { return; } diff --git a/src/engine/sys/sdl_glimp.cpp b/src/engine/sys/sdl_glimp.cpp index d95e91d323..e2a208aa09 100644 --- a/src/engine/sys/sdl_glimp.cpp +++ b/src/engine/sys/sdl_glimp.cpp @@ -1269,7 +1269,7 @@ static glConfiguration GLimp_ApplyCustomOptions( const int GLEWmajor, const glCo customConfiguration.profile = bestConfiguration.profile; } - customConfiguration.colorBits = std::max( 0, r_colorbits->integer ); + customConfiguration.colorBits = std::max( 0, r_colorbits.Get() ); if ( customConfiguration.colorBits == 0 ) { @@ -2038,7 +2038,7 @@ static void GLimp_InitExtensions() int reservedComponents = 36 * 10; // approximation how many uniforms we have besides the bone matrices glConfig2.maxVertexSkinningBones = Math::Clamp( ( glConfig2.maxVertexUniforms - reservedComponents ) / 16, 0, MAX_BONES ); - glConfig2.vboVertexSkinningAvailable = r_vboVertexSkinning->integer && ( ( glConfig2.maxVertexSkinningBones >= 12 ) ? true : false ); + glConfig2.vboVertexSkinningAvailable = r_vboVertexSkinning.Get() && ( ( glConfig2.maxVertexSkinningBones >= 12 ) ? true : false ); /* On OpenGL Core profile the ARB_fragment_program extension doesn't exist and the related getter functions return 0. We can assume OpenGL 3 Core hardware is featureful enough to not care about those limits. */ @@ -2743,7 +2743,7 @@ bool GLimp_Init() Sys::SetEnv( "stub_occlusion_query", "true" ); } - int mode = r_mode->integer; + int mode = r_mode.Get(); bool fullscreen = r_fullscreen.Get(); bool bordered = !r_noBorder.Get(); @@ -2920,7 +2920,7 @@ Responsible for doing a swapbuffers void GLimp_EndFrame() { // don't flip if drawing to front buffer - if ( Q_stricmp( r_drawBuffer->string, "GL_FRONT" ) != 0 ) + if ( Q_stricmp( r_drawBuffer.Get().c_str(), "GL_FRONT" ) != 0 ) { SDL_GL_SwapWindow( window ); } From 1cf13add08d57e826381058fb6afee0b319d2e0c Mon Sep 17 00:00:00 2001 From: VReaperV Date: Tue, 28 Jan 2025 00:06:37 +0300 Subject: [PATCH 27/27] NUKE unused r_noLightVisCull --- src/engine/renderer/tr_init.cpp | 2 -- src/engine/renderer/tr_local.h | 1 - 2 files changed, 3 deletions(-) diff --git a/src/engine/renderer/tr_init.cpp b/src/engine/renderer/tr_init.cpp index f4ee5279de..2337808966 100644 --- a/src/engine/renderer/tr_init.cpp +++ b/src/engine/renderer/tr_init.cpp @@ -75,7 +75,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Cvar::Cvar r_nocurves( "r_nocurves", "Cull all SF_GRID surfaces", Cvar::CHEAT, false ); Cvar::Range> r_lightScissors( "r_lightScissors", "Light clipping: 0: disabled, 1: near plane, 2: all planes", Cvar::NONE, 0, 0, 2 ); - cvar_t *r_noLightVisCull; cvar_t *r_noInteractionSort; Cvar::Range> r_realtimeLightingRenderer( "r_realtimeLightingRenderer", "renderer for real time lights: 0: legacy, 1: tiled", Cvar::NONE, @@ -1215,7 +1214,6 @@ ScreenshotCmd screenshotPNGRegistration("screenshotPNG", ssFormat_t::SSF_PNG, "p Cvar::Latch( r_ssao ); // temporary variables that can change at any time - r_noLightVisCull = Cvar_Get( "r_noLightVisCull", "0", CVAR_CHEAT ); r_noInteractionSort = Cvar_Get( "r_noInteractionSort", "0", CVAR_CHEAT ); Cvar::Latch( r_realtimeLightingRenderer ); diff --git a/src/engine/renderer/tr_local.h b/src/engine/renderer/tr_local.h index 10d8080d36..5ebc87f0ad 100644 --- a/src/engine/renderer/tr_local.h +++ b/src/engine/renderer/tr_local.h @@ -2977,7 +2977,6 @@ enum class shaderProfilerRenderSubGroupsMode { extern Cvar::Cvar r_facePlaneCull; extern Cvar::Cvar r_nocurves; extern Cvar::Range> r_lightScissors; - extern cvar_t *r_noLightVisCull; extern cvar_t *r_noInteractionSort; extern Cvar::Cvar r_mode;