Shaders manager - Built-in shaders

This commit is contained in:
Emmanuel BENOîT 2017-11-24 13:45:00 +01:00
parent 41e9fdbd00
commit 8e73f81ecd
2 changed files with 92 additions and 9 deletions

View file

@ -605,6 +605,19 @@ T_ShaderProgram T_ShaderManager::program(
return T_ShaderProgram( *programIndex_.get( name ) + 1 ); 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( T_ShaderPipeline T_ShaderManager::pipeline(
std::initializer_list< T_String > shaders ) std::initializer_list< T_String > shaders )
{ {
@ -753,6 +766,7 @@ void T_ShaderManager::update( )
updates_.clear( ); updates_.clear( );
} }
/*----------------------------------------------------------------------------*/
void T_ShaderManager::loadProgram( void T_ShaderManager::loadProgram(
T_String const& pipeline , 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( bool T_ShaderManager::useExistingProgram(
T_String const& name ) T_String const& name )
{ {
@ -796,6 +820,7 @@ bool T_ShaderManager::useExistingProgram(
return true; return true;
} }
/*----------------------------------------------------------------------------*/
uint32_t T_ShaderManager::newProgramRecord( ) uint32_t T_ShaderManager::newProgramRecord( )
{ {
@ -812,14 +837,20 @@ uint32_t T_ShaderManager::newProgramRecord( )
} }
T_ShaderManager::T_Program_& T_ShaderManager::initProgramRecord( 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( ) ); const uint32_t index( newProgramRecord( ) );
auto& program( programs_[ index ] ); auto& program( programs_[ index ] );
programIndex_.add( name , index ); programIndex_.add( name , index );
program.name = name; program.name = name;
program.id = 0; program.id = 0;
if ( type == E_ShaderType::__COUNT__ || source == nullptr ) {
initProgram( program ); initProgram( program );
} else {
initBuiltinProgram( program , type , source );
}
T_StringBuilder sb; T_StringBuilder sb;
for ( auto const& e : program.code.errors ) { for ( auto const& e : program.code.errors ) {
@ -829,9 +860,14 @@ T_ShaderManager::T_Program_& T_ShaderManager::initProgramRecord(
sb << '\0'; sb << '\0';
printf( "%s" , sb.data( ) ); printf( "%s" , sb.data( ) );
if ( type != E_ShaderType::__COUNT__ && source != nullptr && program.id == 0 ) {
std::abort( );
}
return program; return program;
} }
/*----------------------------------------------------------------------------*/
T_ShaderInput const* T_ShaderManager::getInput( T_ShaderInput const* T_ShaderManager::getInput(
T_String const& name ) T_String const& name )
@ -851,6 +887,7 @@ T_ShaderInput const* T_ShaderManager::getInput(
return inputs_.get( name )->get( ); return inputs_.get( name )->get( );
} }
/*----------------------------------------------------------------------------*/
void T_ShaderManager::dereferencePipeline( void T_ShaderManager::dereferencePipeline(
T_String const& id ) T_String const& id )
@ -876,7 +913,6 @@ void T_ShaderManager::dereferencePipeline(
pipelines_.remove( pipeline.idString ); pipelines_.remove( pipeline.idString );
} }
void T_ShaderManager::dereferenceProgram( void T_ShaderManager::dereferenceProgram(
const uint32_t index , const uint32_t index ,
T_String const& pipeline ) T_String const& pipeline )
@ -893,7 +929,6 @@ void T_ShaderManager::dereferenceProgram(
programIndex_.remove( program.name ); programIndex_.remove( program.name );
} }
void T_ShaderManager::dereferenceProgram( void T_ShaderManager::dereferenceProgram(
const uint32_t index ) const uint32_t index )
{ {
@ -907,6 +942,7 @@ void T_ShaderManager::dereferenceProgram(
programIndex_.remove( program.name ); programIndex_.remove( program.name );
} }
/*----------------------------------------------------------------------------*/
void T_ShaderManager::initPipeline( void T_ShaderManager::initPipeline(
T_Pipeline_& pipeline ) const T_Pipeline_& pipeline ) const
@ -996,8 +1032,33 @@ void T_ShaderManager::initProgram(
if ( !( built && code.errors.empty( ) ) ) { if ( !( built && code.errors.empty( ) ) ) {
return; 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 // Try to compile the program
auto& code( program.code );
auto const& name( program.name );
char const* const list[] = { char const* const list[] = {
program.code.code.data( ) program.code.code.data( )
}; };
@ -1039,6 +1100,8 @@ void T_ShaderManager::initProgram(
} }
} }
/*----------------------------------------------------------------------------*/
void T_ShaderManager::parseGLSLError( void T_ShaderManager::parseGLSLError(
T_ShaderCode& code , T_ShaderCode& code ,
char const* errorLine ) char const* errorLine )
@ -1065,6 +1128,8 @@ void T_ShaderManager::parseGLSLError(
errorLine ); errorLine );
} }
/*----------------------------------------------------------------------------*/
void T_ShaderManager::programUpdated( void T_ShaderManager::programUpdated(
T_String const& name ) T_String const& name )
{ {
@ -1121,14 +1186,16 @@ void T_ShaderManager::makeUI( )
const auto n( std::count_if( programs_.begin( ) , programs_.end( ) , const auto n( std::count_if( programs_.begin( ) , programs_.end( ) ,
[]( auto const& p ) { []( auto const& p ) {
return !p.plReferences.empty( ) || p.saReferences != 0; return ( !p.plReferences.empty( ) || p.saReferences != 0 )
&& !p.name.startsWith( "*" );
} ) ); } ) );
std::vector< size_t > indices; std::vector< size_t > indices;
const auto rn = programs_.size( ); const auto rn = programs_.size( );
for ( auto i = 0u ; i < rn ; i ++ ) { for ( auto i = 0u ; i < rn ; i ++ ) {
auto const& p( programs_[ 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 ); indices.push_back( i );
} }
} }

View file

@ -156,7 +156,13 @@ struct T_ShaderManager
T_ShaderManager( ) noexcept; T_ShaderManager( ) noexcept;
// Build / get a program based on its name
T_ShaderProgram program( T_String const& 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( T_ShaderPipeline pipeline(
std::initializer_list< T_String > shaders ); std::initializer_list< T_String > shaders );
T_ShaderPipeline pipeline( T_ShaderPipeline pipeline(
@ -225,11 +231,17 @@ struct T_ShaderManager
// Load/use existing program for standalone use // Load/use existing program for standalone use
void loadProgram( T_String const& name ); void loadProgram( T_String const& name );
void loadBuiltinProgram(
T_String const& name ,
E_ShaderType type ,
char const* source );
bool useExistingProgram( T_String const& name ); bool useExistingProgram( T_String const& name );
// Program management // Program management
T_Program_& initProgramRecord( // Init management data 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 uint32_t newProgramRecord( ); // Allocate entry in index
T_ShaderInput const* getInput( T_ShaderInput const* getInput(
@ -244,6 +256,10 @@ struct T_ShaderManager
void initPipeline( T_Pipeline_& pipeline ) const; void initPipeline( T_Pipeline_& pipeline ) const;
void initProgram( T_Program_& program ); void initProgram( T_Program_& program );
void initBuiltinProgram( T_Program_& program ,
E_ShaderType type ,
char const* source );
void buildProgram( T_Program_& program );
void parseGLSLError( void parseGLSLError(
T_ShaderCode& code , T_ShaderCode& code ,