Skip to content

Commit

Permalink
Use UBOs for texData when possible
Browse files Browse the repository at this point in the history
  • Loading branch information
VReaperV committed Dec 25, 2024
1 parent 3a573ff commit f7601cc
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 29 deletions.
30 changes: 18 additions & 12 deletions src/engine/renderer/Material.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 );
Expand Down Expand Up @@ -611,8 +611,9 @@ void MaterialSystem::GenerateTexturesBuffer( std::vector<TextureData>& 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++;
}
}
Expand Down Expand Up @@ -653,9 +654,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 ) );

Expand All @@ -668,9 +671,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 );
Expand Down Expand Up @@ -1700,8 +1703,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 );

Expand Down Expand Up @@ -2277,7 +2283,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
Expand Down Expand Up @@ -2394,7 +2400,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 ) {
Expand Down
13 changes: 11 additions & 2 deletions src/engine/renderer/Material.h
Original file line number Diff line number Diff line change
Expand Up @@ -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];
};

Expand Down Expand Up @@ -238,6 +239,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

Expand Down Expand Up @@ -373,6 +381,7 @@ class MaterialSystem {
std::vector<shaderStage_t*> materialStages;
std::vector<shaderStage_t*> dynamicStages;

GLenum texDataBufferType;
std::vector<TextureData> texData;
std::vector<TextureData> dynamicTexData;

Expand All @@ -394,7 +403,7 @@ class MaterialSystem {
};

extern GLSSBO materialsSSBO; // Global
extern GLSSBO texDataSSBO; // Global
extern GLBuffer texDataSSBO; // Global
extern GLUBO lightmapDataUBO; // Global

extern GLSSBO surfaceDescriptorsSSBO; // Global
Expand Down
34 changes: 19 additions & 15 deletions src/engine/renderer/gl_shader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1363,23 +1363,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"
Expand Down
1 change: 1 addition & 0 deletions src/engine/renderer/tr_public.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ struct glconfig2_t
char shadingLanguageVersionString[ MAX_STRING_CHARS ];
int shadingLanguageVersion;

int maxUniformBlockSize;
int maxVertexUniforms;
// int maxVaryingFloats;
int maxVertexAttribs;
Expand Down
1 change: 1 addition & 0 deletions src/engine/sys/sdl_glimp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2014,6 +2014,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 );

Expand Down

0 comments on commit f7601cc

Please sign in to comment.