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 ========================================================*/
void cops::Execute(
__rd__ T_Operations const& operations ,
__rw__ T_Context& context )
__rd__ T_Operations const& operations ,
__rw__ T_Context& context )
{
for ( auto const& op : operations ) {
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 ==============================================================*/
@ -188,10 +200,10 @@ void OPDup::execute(
__rw__ T_Context& ctx ) const
{
if ( ctx.opStack.size( ) <= stackIndex ) {
std::string err( "stack does not have " );
err += stackIndex + 1;
err += " items";
throw error( err );
std::ostringstream oss;
oss << "stack does not have " << ( stackIndex + 1 )
<< " items (only " << ctx.opStack.size( ) << ")";
throw error( oss.str( ) );
}
ctx.opStack.push_back( *( ctx.opStack.end( ) - stackIndex - 1 ) );
}
@ -224,20 +236,17 @@ void OPXchg::execute(
// or, you know, a program name
OPSetUniform::OPSetUniform(
__rd__ const uint32_t program ,
__rd__ const uint32_t uniform ,
__rd__ const uint32_t count ,
__rd__ const bool integer )
: T_Op( OP_SET_UNIFORM ) , program( program ) , uniform( uniform ) ,
count( count ) , integer( integer )
: T_Op( OP_SET_UNIFORM ) , count( count ) , integer( integer )
{ }
void OPSetUniform::execute(
__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 " );
err += count;
err += count + 2;
err += " items";
throw error( err );
}
@ -249,6 +258,11 @@ void OPSetUniform::execute(
};
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 ) {
int values[ count ];
auto i = count;
@ -367,3 +381,37 @@ void OPFullscreen::execute(
glBindVertexArray( 0 );
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 {
struct T_Program;
struct T_Context
{
T_Program const* program;
float const* time;
T_SyncData const* sync;
@ -71,7 +75,9 @@ namespace cops {
OP_SET_VIEWPORT ,
//
OP_CLEAR ,
OP_FULLSCREEN
OP_FULLSCREEN ,
//
OP_CALL
};
struct T_Op
@ -86,8 +92,8 @@ namespace cops {
virtual void execute(
__rw__ T_Context& ctx ) const = 0;
std::string source;
uint32_t line;
std::string source{};
uint32_t line{0};
protected:
X_OpFailure error(
@ -108,6 +114,42 @@ namespace cops {
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
@ -199,15 +241,11 @@ namespace cops {
struct OPSetUniform : public T_Op
{
OPSetUniform(
__rd__ const uint32_t program ,
__rd__ const uint32_t uniform ,
__rd__ const uint32_t count ,
__rd__ const bool integer );
void execute(
__rw__ T_Context& ctx ) const override;
uint32_t program;
uint32_t uniform;
uint32_t count;
bool integer;
};
@ -269,10 +307,16 @@ namespace cops {
__rw__ T_Context& ctx ) const override;
};
/*====================================================================*/
/*--------------------------------------------------------------------*/
void Execute(
__rd__ T_Operations const& operations ,
__rw__ T_Context& context );
struct OPCall : public T_Op
{
explicit OPCall(
__rd__ std::string const& function );
void execute(
__rw__ T_Context& ctx ) const override;
std::string function;
};
} // 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 idPass2( spPass2_.program( E_ShaderType::FRAGMENT ) );
const auto idSampler( tm.sampler( "linear-edge" )->id( ) );
ops_.clear( );
ops_
// First pass
T_Program program;
program.function( "SetDofUniforms" , 1 )
<< OPLoadVariable( "height" )
<< OPLoadVariable( "width" )
<< OPLoadConstant( 0 )
@ -65,48 +64,46 @@ void T_DoFPass::render(
<< OPLoadVariable( "time" )
<< OPLoadVariable( "height" )
<< OPLoadVariable( "width" )
<< OPLoadConstant( U_RES_TIME )
<< OPDup( 8 )
<< OPLoadConstant( nSamples_ )
<< OPLoadConstant( U_SAMPLES )
<< OPDup( 11 )
<< OPLoadConstant( filterParams_[ 3 ] )
<< OPLoadConstant( filterParams_[ 2 ] )
<< OPLoadConstant( filterParams_[ 1 ] )
<< OPLoadConstant( filterParams_[ 0 ] )
<< OPLoadConstant( U_PARAMS )
<< OPDup( 17 )
<< OPLoadConstant( 1 )
<< OPLoadConstant( U_DEPTH )
<< OPDup( 20 )
<< OPLoadConstant( 0 )
<< OPSetUniform( idPass1 , U_INPUT , 1 , true )
<< OPSetUniform( idPass1 , U_DEPTH , 1 , true )
<< OPSetUniform( idPass1 , U_PARAMS , 4 , false )
<< OPSetUniform( idPass1 , U_SAMPLES , 1 , false )
<< OPSetUniform( idPass1 , U_RES_TIME , 3 , false )
<< OPLoadConstant( U_INPUT )
<< OPDup( 23 )
<< OPSetUniform( 1 , true )
<< OPSetUniform( 1 , true )
<< OPSetUniform( 4 , false )
<< OPSetUniform( 1 , false )
<< OPSetUniform( 3 , false )
<< OPSetViewport( )
;
program.main
// First pass
<< OPLoadConstant( idPass1 )
<< OPCall( "SetDofUniforms" )
<< OPUseTexture( 0 , imageInput_.id( ) , idSampler )
<< OPUseTexture( 1 , depthInput_.id( ) , idSampler )
<< OPUsePipeline( spPass1_.id( ) )
<< OPUseFramebuffer( rtPass1_.id( ) )
<< OPSetViewport( )
<< OPFullscreen( )
// Second pass
<< OPLoadVariable( "height" )
<< OPLoadVariable( "width" )
<< 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 )
<< OPLoadConstant( idPass2 )
<< OPCall( "SetDofUniforms" )
<< OPUseTexture( 0 , txPass1_.id( ) , idSampler )
<< OPUsePipeline( spPass2_.id( ) )
<< OPUseFramebuffer( rtPass2_.id( ) )
<< OPSetViewport( )
<< OPFullscreen( )
;
@ -114,11 +111,11 @@ void T_DoFPass::render(
printf( "GL fail in DoF" );
} );
cops::T_Context ctx;
T_Context ctx;
ctx.store( "time" , position );
ctx.store( "width" , imageInput_.width( ) );
ctx.store( "height" , imageInput_.height( ) );
cops::Execute( ops_ , ctx );
program.execute( ctx );
PEND( );
}

3
dof.hh
View file

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