From 8e73f81ecd384baaa23706faeea6d756095c54c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emmanuel=20Beno=C3=AEt?= Date: Fri, 24 Nov 2017 13:45:00 +0100 Subject: [PATCH] Shaders manager - Built-in shaders --- ui-shaders.cc | 83 ++++++++++++++++++++++++++++++++++++++++++++++----- ui-shaders.hh | 18 ++++++++++- 2 files changed, 92 insertions(+), 9 deletions(-) diff --git a/ui-shaders.cc b/ui-shaders.cc index 641763f..5cd3958 100644 --- a/ui-shaders.cc +++ b/ui-shaders.cc @@ -605,6 +605,19 @@ T_ShaderProgram T_ShaderManager::program( return T_ShaderProgram( *programIndex_.get( name ) + 1 ); } +T_ShaderProgram T_ShaderManager::program( + T_String const& name , + const E_ShaderType type , + char const* const source ) +{ + assert( name && name.startsWith( "*" ) ); + assert( type != E_ShaderType::__COUNT__ ); + loadBuiltinProgram( name , type , source ); + assert( programIndex_.contains( name ) ); + assert( programs_[ *programIndex_.get( name ) ].name == name ); + return T_ShaderProgram( *programIndex_.get( name ) + 1 ); +} + T_ShaderPipeline T_ShaderManager::pipeline( std::initializer_list< T_String > shaders ) { @@ -753,6 +766,7 @@ void T_ShaderManager::update( ) updates_.clear( ); } +/*----------------------------------------------------------------------------*/ void T_ShaderManager::loadProgram( T_String const& pipeline , @@ -785,6 +799,16 @@ void T_ShaderManager::loadProgram( } } +void T_ShaderManager::loadBuiltinProgram( + T_String const& name , + const E_ShaderType type , + char const* const source ) +{ + if ( !useExistingProgram( name ) ) { + initProgramRecord( name , type , source ); + } +} + bool T_ShaderManager::useExistingProgram( T_String const& name ) { @@ -796,6 +820,7 @@ bool T_ShaderManager::useExistingProgram( return true; } +/*----------------------------------------------------------------------------*/ uint32_t T_ShaderManager::newProgramRecord( ) { @@ -812,14 +837,20 @@ uint32_t T_ShaderManager::newProgramRecord( ) } T_ShaderManager::T_Program_& T_ShaderManager::initProgramRecord( - T_String const& name ) + T_String const& name , + const E_ShaderType type , + char const* const source ) { const uint32_t index( newProgramRecord( ) ); auto& program( programs_[ index ] ); programIndex_.add( name , index ); program.name = name; program.id = 0; - initProgram( program ); + if ( type == E_ShaderType::__COUNT__ || source == nullptr ) { + initProgram( program ); + } else { + initBuiltinProgram( program , type , source ); + } T_StringBuilder sb; for ( auto const& e : program.code.errors ) { @@ -829,9 +860,14 @@ T_ShaderManager::T_Program_& T_ShaderManager::initProgramRecord( sb << '\0'; printf( "%s" , sb.data( ) ); + if ( type != E_ShaderType::__COUNT__ && source != nullptr && program.id == 0 ) { + std::abort( ); + } + return program; } +/*----------------------------------------------------------------------------*/ T_ShaderInput const* T_ShaderManager::getInput( T_String const& name ) @@ -851,6 +887,7 @@ T_ShaderInput const* T_ShaderManager::getInput( return inputs_.get( name )->get( ); } +/*----------------------------------------------------------------------------*/ void T_ShaderManager::dereferencePipeline( T_String const& id ) @@ -876,7 +913,6 @@ void T_ShaderManager::dereferencePipeline( pipelines_.remove( pipeline.idString ); } - void T_ShaderManager::dereferenceProgram( const uint32_t index , T_String const& pipeline ) @@ -893,7 +929,6 @@ void T_ShaderManager::dereferenceProgram( programIndex_.remove( program.name ); } - void T_ShaderManager::dereferenceProgram( const uint32_t index ) { @@ -907,6 +942,7 @@ void T_ShaderManager::dereferenceProgram( programIndex_.remove( program.name ); } +/*----------------------------------------------------------------------------*/ void T_ShaderManager::initPipeline( T_Pipeline_& pipeline ) const @@ -996,8 +1032,33 @@ void T_ShaderManager::initProgram( if ( !( built && code.errors.empty( ) ) ) { return; } + buildProgram( program ); +} +void T_ShaderManager::initBuiltinProgram( + T_Program_& program , + E_ShaderType type , + char const* source ) +{ + auto name( program.name ); + printf( "init built-in program %s\n" , + program.name.substr( 1 ).toOSString( ).data( ) ); + + program.code.code << source << '\0'; + program.code.type = type; + program.code.counts.add( UINT32_MAX ); + program.code.starts.add( 0 ); + program.code.sources.add( program.name ); + + buildProgram( program ); +} + +void T_ShaderManager::buildProgram( + T_Program_& program ) +{ // Try to compile the program + auto& code( program.code ); + auto const& name( program.name ); char const* const list[] = { program.code.code.data( ) }; @@ -1039,6 +1100,8 @@ void T_ShaderManager::initProgram( } } +/*----------------------------------------------------------------------------*/ + void T_ShaderManager::parseGLSLError( T_ShaderCode& code , char const* errorLine ) @@ -1065,6 +1128,8 @@ void T_ShaderManager::parseGLSLError( errorLine ); } +/*----------------------------------------------------------------------------*/ + void T_ShaderManager::programUpdated( T_String const& name ) { @@ -1120,15 +1185,17 @@ void T_ShaderManager::makeUI( ) Begin( "Shaders" , &uiEnabled_ , ImGuiWindowFlags_NoCollapse ); const auto n( std::count_if( programs_.begin( ) , programs_.end( ) , - []( auto const& p ) { - return !p.plReferences.empty( ) || p.saReferences != 0; - } ) ); + []( auto const& p ) { + return ( !p.plReferences.empty( ) || p.saReferences != 0 ) + && !p.name.startsWith( "*" ); + } ) ); std::vector< size_t > indices; const auto rn = programs_.size( ); for ( auto i = 0u ; i < rn ; i ++ ) { auto const& p( programs_[ i ] ); - if ( !p.plReferences.empty( ) || p.saReferences ) { + if ( ( !p.plReferences.empty( ) || p.saReferences ) + && !p.name.startsWith( "*" ) ) { indices.push_back( i ); } } diff --git a/ui-shaders.hh b/ui-shaders.hh index 4f5e5d1..571a30e 100644 --- a/ui-shaders.hh +++ b/ui-shaders.hh @@ -156,7 +156,13 @@ struct T_ShaderManager T_ShaderManager( ) noexcept; + // Build / get a program based on its name T_ShaderProgram program( T_String const& name ); + // Build a program from its source code + T_ShaderProgram program( T_String const& name , + E_ShaderType type , + char const* source ); + T_ShaderPipeline pipeline( std::initializer_list< T_String > shaders ); T_ShaderPipeline pipeline( @@ -225,11 +231,17 @@ struct T_ShaderManager // Load/use existing program for standalone use void loadProgram( T_String const& name ); + void loadBuiltinProgram( + T_String const& name , + E_ShaderType type , + char const* source ); bool useExistingProgram( T_String const& name ); // Program management T_Program_& initProgramRecord( // Init management data - T_String const& record ); + T_String const& record , + E_ShaderType type = E_ShaderType::__COUNT__ , + char const* source = nullptr ); uint32_t newProgramRecord( ); // Allocate entry in index T_ShaderInput const* getInput( @@ -244,6 +256,10 @@ struct T_ShaderManager void initPipeline( T_Pipeline_& pipeline ) const; void initProgram( T_Program_& program ); + void initBuiltinProgram( T_Program_& program , + E_ShaderType type , + char const* source ); + void buildProgram( T_Program_& program ); void parseGLSLError( T_ShaderCode& code ,