Control system: function calls

This commit is contained in:
Emmanuel BENOîT 2017-10-15 10:22:24 +02:00
parent 7b9595777a
commit 647e247916
4 changed files with 143 additions and 57 deletions

View file

@ -8,14 +8,26 @@ using namespace cops;
/*= Command execution ========================================================*/ /*= Command execution ========================================================*/
void cops::Execute( void cops::Execute(
__rd__ T_Operations const& operations , __rd__ T_Operations const& operations ,
__rw__ T_Context& context ) __rw__ T_Context& context )
{ {
for ( auto const& op : operations ) { for ( auto const& op : operations ) {
op->execute( context ); op->execute( context );
} }
} }
T_Operations& T_Program::function(
__rd__ std::string const& name ,
__rd__ const uint32_t args )
{
const auto p( functions.find( name ) );
if ( p == functions.end( ) ) {
return functions.emplace( name , T_Function{ name , args } ).first->second.operations;
}
assert( p->second.arguments == args );
return p->second.operations;
}
/*= X_OpFailure ==============================================================*/ /*= X_OpFailure ==============================================================*/
@ -188,10 +200,10 @@ void OPDup::execute(
__rw__ T_Context& ctx ) const __rw__ T_Context& ctx ) const
{ {
if ( ctx.opStack.size( ) <= stackIndex ) { if ( ctx.opStack.size( ) <= stackIndex ) {
std::string err( "stack does not have " ); std::ostringstream oss;
err += stackIndex + 1; oss << "stack does not have " << ( stackIndex + 1 )
err += " items"; << " items (only " << ctx.opStack.size( ) << ")";
throw error( err ); throw error( oss.str( ) );
} }
ctx.opStack.push_back( *( ctx.opStack.end( ) - stackIndex - 1 ) ); ctx.opStack.push_back( *( ctx.opStack.end( ) - stackIndex - 1 ) );
} }
@ -224,20 +236,17 @@ void OPXchg::execute(
// or, you know, a program name // or, you know, a program name
OPSetUniform::OPSetUniform( OPSetUniform::OPSetUniform(
__rd__ const uint32_t program ,
__rd__ const uint32_t uniform ,
__rd__ const uint32_t count , __rd__ const uint32_t count ,
__rd__ const bool integer ) __rd__ const bool integer )
: T_Op( OP_SET_UNIFORM ) , program( program ) , uniform( uniform ) , : T_Op( OP_SET_UNIFORM ) , count( count ) , integer( integer )
count( count ) , integer( integer )
{ } { }
void OPSetUniform::execute( void OPSetUniform::execute(
__rw__ T_Context& ctx ) const __rw__ T_Context& ctx ) const
{ {
if ( count == 0 || ctx.opStack.size( ) < count ) { if ( count == 0 || ctx.opStack.size( ) < count + 2 ) {
std::string err( "stack does not have " ); std::string err( "stack does not have " );
err += count; err += count + 2;
err += " items"; err += " items";
throw error( err ); throw error( err );
} }
@ -249,6 +258,11 @@ void OPSetUniform::execute(
}; };
const F_SetUniform_ func{ *(F_SetUniform_*) funcs[ count + ( integer ? 4 : 0 ) - 1 ] }; const F_SetUniform_ func{ *(F_SetUniform_*) funcs[ count + ( integer ? 4 : 0 ) - 1 ] };
const GLuint program( ctx.opStack.back( ) );
ctx.opStack.pop_back( );
const GLuint uniform( ctx.opStack.back( ) );
ctx.opStack.pop_back( );
if ( integer ) { if ( integer ) {
int values[ count ]; int values[ count ];
auto i = count; auto i = count;
@ -367,3 +381,37 @@ void OPFullscreen::execute(
glBindVertexArray( 0 ); glBindVertexArray( 0 );
glDrawArrays( GL_TRIANGLE_STRIP , 0 , 4 ); glDrawArrays( GL_TRIANGLE_STRIP , 0 , 4 );
} }
/*= Flow control =============================================================*/
OPCall::OPCall(
__rd__ std::string const& function )
: T_Op( OP_CALL ) , function( function )
{ }
void OPCall::execute(
__rw__ T_Context& ctx ) const
{
auto fp( ctx.program->functions.find( function ) );
if ( fp == ctx.program->functions.end( ) ) {
throw error( "function '" + function + "' not found" );
}
auto const& func( fp->second );
const auto ssz( ctx.opStack.size( ) );
if ( ssz < func.arguments ) {
std::string err;
err = "function '" + function + "' requires ";
err += func.arguments;
err += " argument";
err += ( func.arguments > 1 ? "s" : "" );
throw error( err );
}
Execute( func.operations , ctx );
if ( ctx.opStack.size( ) < ssz ) {
throw error( "function '" + function + "' ate the stack" );
}
ctx.opStack.resize( ssz - func.arguments );
}

View file

@ -7,8 +7,12 @@ struct T_SyncData;
namespace cops { namespace cops {
struct T_Program;
struct T_Context struct T_Context
{ {
T_Program const* program;
float const* time; float const* time;
T_SyncData const* sync; T_SyncData const* sync;
@ -71,7 +75,9 @@ namespace cops {
OP_SET_VIEWPORT , OP_SET_VIEWPORT ,
// //
OP_CLEAR , OP_CLEAR ,
OP_FULLSCREEN OP_FULLSCREEN ,
//
OP_CALL
}; };
struct T_Op struct T_Op
@ -86,8 +92,8 @@ namespace cops {
virtual void execute( virtual void execute(
__rw__ T_Context& ctx ) const = 0; __rw__ T_Context& ctx ) const = 0;
std::string source; std::string source{};
uint32_t line; uint32_t line{0};
protected: protected:
X_OpFailure error( X_OpFailure error(
@ -108,6 +114,42 @@ namespace cops {
return ops; return ops;
} }
void Execute(
__rd__ T_Operations const& operations ,
__rw__ T_Context& context );
/*--------------------------------------------------------------------*/
struct T_Function
{
std::string name;
uint32_t arguments;
T_Operations operations;
T_Function( __rd__ std::string const& name ,
__rd__ const uint32_t arguments )
: name( name ) , arguments( arguments )
{ }
DEF_COPY( T_Function );
DEF_MOVE( T_Function );
};
struct T_Program
{
std::map< std::string , T_Function > functions;
T_Operations main;
T_Operations& function(
__rd__ std::string const& name ,
__rd__ const uint32_t args );
void execute( __rw__ T_Context& context )
{
context.program = this;
Execute( main , context );
}
};
/*====================================================================*/ /*====================================================================*/
struct OPLoadConstant : public T_Op struct OPLoadConstant : public T_Op
@ -199,15 +241,11 @@ namespace cops {
struct OPSetUniform : public T_Op struct OPSetUniform : public T_Op
{ {
OPSetUniform( OPSetUniform(
__rd__ const uint32_t program ,
__rd__ const uint32_t uniform ,
__rd__ const uint32_t count , __rd__ const uint32_t count ,
__rd__ const bool integer ); __rd__ const bool integer );
void execute( void execute(
__rw__ T_Context& ctx ) const override; __rw__ T_Context& ctx ) const override;
uint32_t program;
uint32_t uniform;
uint32_t count; uint32_t count;
bool integer; bool integer;
}; };
@ -269,10 +307,16 @@ namespace cops {
__rw__ T_Context& ctx ) const override; __rw__ T_Context& ctx ) const override;
}; };
/*====================================================================*/ /*--------------------------------------------------------------------*/
void Execute( struct OPCall : public T_Op
__rd__ T_Operations const& operations , {
__rw__ T_Context& context ); explicit OPCall(
__rd__ std::string const& function );
void execute(
__rw__ T_Context& ctx ) const override;
std::string function;
};
} // namespace cops } // namespace cops

59
dof.cc
View file

@ -55,9 +55,8 @@ void T_DoFPass::render(
const auto idPass1( spPass1_.program( E_ShaderType::FRAGMENT ) ); const auto idPass1( spPass1_.program( E_ShaderType::FRAGMENT ) );
const auto idPass2( spPass2_.program( E_ShaderType::FRAGMENT ) ); const auto idPass2( spPass2_.program( E_ShaderType::FRAGMENT ) );
const auto idSampler( tm.sampler( "linear-edge" )->id( ) ); const auto idSampler( tm.sampler( "linear-edge" )->id( ) );
ops_.clear( ); T_Program program;
ops_ program.function( "SetDofUniforms" , 1 )
// First pass
<< OPLoadVariable( "height" ) << OPLoadVariable( "height" )
<< OPLoadVariable( "width" ) << OPLoadVariable( "width" )
<< OPLoadConstant( 0 ) << OPLoadConstant( 0 )
@ -65,48 +64,46 @@ void T_DoFPass::render(
<< OPLoadVariable( "time" ) << OPLoadVariable( "time" )
<< OPLoadVariable( "height" ) << OPLoadVariable( "height" )
<< OPLoadVariable( "width" ) << OPLoadVariable( "width" )
<< OPLoadConstant( U_RES_TIME )
<< OPDup( 8 )
<< OPLoadConstant( nSamples_ ) << OPLoadConstant( nSamples_ )
<< OPLoadConstant( U_SAMPLES )
<< OPDup( 11 )
<< OPLoadConstant( filterParams_[ 3 ] ) << OPLoadConstant( filterParams_[ 3 ] )
<< OPLoadConstant( filterParams_[ 2 ] ) << OPLoadConstant( filterParams_[ 2 ] )
<< OPLoadConstant( filterParams_[ 1 ] ) << OPLoadConstant( filterParams_[ 1 ] )
<< OPLoadConstant( filterParams_[ 0 ] ) << OPLoadConstant( filterParams_[ 0 ] )
<< OPLoadConstant( U_PARAMS )
<< OPDup( 17 )
<< OPLoadConstant( 1 ) << OPLoadConstant( 1 )
<< OPLoadConstant( U_DEPTH )
<< OPDup( 20 )
<< OPLoadConstant( 0 ) << OPLoadConstant( 0 )
<< OPSetUniform( idPass1 , U_INPUT , 1 , true ) << OPLoadConstant( U_INPUT )
<< OPSetUniform( idPass1 , U_DEPTH , 1 , true ) << OPDup( 23 )
<< OPSetUniform( idPass1 , U_PARAMS , 4 , false ) << OPSetUniform( 1 , true )
<< OPSetUniform( idPass1 , U_SAMPLES , 1 , false ) << OPSetUniform( 1 , true )
<< OPSetUniform( idPass1 , U_RES_TIME , 3 , false ) << OPSetUniform( 4 , false )
<< OPSetUniform( 1 , false )
<< OPSetUniform( 3 , false )
<< OPSetViewport( )
;
program.main
// First pass
<< OPLoadConstant( idPass1 )
<< OPCall( "SetDofUniforms" )
<< OPUseTexture( 0 , imageInput_.id( ) , idSampler ) << OPUseTexture( 0 , imageInput_.id( ) , idSampler )
<< OPUseTexture( 1 , depthInput_.id( ) , idSampler ) << OPUseTexture( 1 , depthInput_.id( ) , idSampler )
<< OPUsePipeline( spPass1_.id( ) ) << OPUsePipeline( spPass1_.id( ) )
<< OPUseFramebuffer( rtPass1_.id( ) ) << OPUseFramebuffer( rtPass1_.id( ) )
<< OPSetViewport( )
<< OPFullscreen( ) << OPFullscreen( )
// Second pass // Second pass
<< OPLoadVariable( "height" ) << OPLoadConstant( idPass2 )
<< OPLoadVariable( "width" ) << OPCall( "SetDofUniforms" )
<< OPLoadConstant( 0 )
<< OPLoadConstant( 0 )
<< OPLoadVariable( "time" )
<< OPLoadVariable( "height" )
<< OPLoadVariable( "width" )
<< OPLoadConstant( nSamples_ )
<< OPLoadConstant( filterParams_[ 3 ] )
<< OPLoadConstant( filterParams_[ 2 ] )
<< OPLoadConstant( filterParams_[ 1 ] )
<< OPLoadConstant( filterParams_[ 0 ] )
<< OPLoadConstant( 1 )
<< OPLoadConstant( 0 )
<< OPSetUniform( idPass2 , U_INPUT , 1 , true )
<< OPSetUniform( idPass2 , U_DEPTH , 1 , true )
<< OPSetUniform( idPass2 , U_PARAMS , 4 , false )
<< OPSetUniform( idPass2 , U_SAMPLES , 1 , false )
<< OPSetUniform( idPass2 , U_RES_TIME , 3 , false )
<< OPUseTexture( 0 , txPass1_.id( ) , idSampler ) << OPUseTexture( 0 , txPass1_.id( ) , idSampler )
<< OPUsePipeline( spPass2_.id( ) ) << OPUsePipeline( spPass2_.id( ) )
<< OPUseFramebuffer( rtPass2_.id( ) ) << OPUseFramebuffer( rtPass2_.id( ) )
<< OPSetViewport( )
<< OPFullscreen( ) << OPFullscreen( )
; ;
@ -114,11 +111,11 @@ void T_DoFPass::render(
printf( "GL fail in DoF" ); printf( "GL fail in DoF" );
} ); } );
cops::T_Context ctx; T_Context ctx;
ctx.store( "time" , position ); ctx.store( "time" , position );
ctx.store( "width" , imageInput_.width( ) ); ctx.store( "width" , imageInput_.width( ) );
ctx.store( "height" , imageInput_.height( ) ); ctx.store( "height" , imageInput_.height( ) );
cops::Execute( ops_ , ctx ); program.execute( ctx );
PEND( ); PEND( );
} }

3
dof.hh
View file

@ -36,8 +36,5 @@ struct T_DoFPass
// SharpDist/SharpRange/Falloff/MaxBlur // SharpDist/SharpRange/Falloff/MaxBlur
float filterParams_[ 4 ]; float filterParams_[ 4 ];
int nSamples_; int nSamples_;
// XXX experimenting with control system
cops::T_Operations ops_;
}; };