Started work on operators
This commit is contained in:
parent
84ebc69d54
commit
2c6b96c6e2
3 changed files with 461 additions and 0 deletions
1
Makefile
1
Makefile
|
@ -26,6 +26,7 @@ DEMO = \
|
||||||
shaders.cc \
|
shaders.cc \
|
||||||
odbg.cc \
|
odbg.cc \
|
||||||
sync.cc \
|
sync.cc \
|
||||||
|
control.cc \
|
||||||
\
|
\
|
||||||
demo.cc \
|
demo.cc \
|
||||||
\
|
\
|
||||||
|
|
246
control.cc
Normal file
246
control.cc
Normal file
|
@ -0,0 +1,246 @@
|
||||||
|
#include "externals.hh"
|
||||||
|
#include "control.hh"
|
||||||
|
#include "sync.hh"
|
||||||
|
|
||||||
|
using namespace cops;
|
||||||
|
|
||||||
|
|
||||||
|
/*= X_OpFailure ==============================================================*/
|
||||||
|
|
||||||
|
X_OpFailure::X_OpFailure(
|
||||||
|
__rd__ std::string const& source ,
|
||||||
|
__rd__ uint32_t line ,
|
||||||
|
__rd__ std::string const& error ) noexcept
|
||||||
|
: std::exception( ) , source_( source ) , line_( line ) ,
|
||||||
|
error_( error )
|
||||||
|
{
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << "Program error (" << source << ", l. " << line << "): " << error;
|
||||||
|
fullMessage_ = oss.str( );
|
||||||
|
}
|
||||||
|
|
||||||
|
char const* X_OpFailure::what( ) const noexcept
|
||||||
|
{
|
||||||
|
return fullMessage_.c_str( );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*= T_Op =====================================================================*/
|
||||||
|
|
||||||
|
T_Op::T_Op( __rd__ const E_Op op )
|
||||||
|
: op_( op )
|
||||||
|
{ }
|
||||||
|
|
||||||
|
T_Op::~T_Op( ) { }
|
||||||
|
|
||||||
|
|
||||||
|
X_OpFailure T_Op::error(
|
||||||
|
__rd__ std::string const& message ) const noexcept
|
||||||
|
{
|
||||||
|
return X_OpFailure( source , line , message );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*= OPLoadConstant ===========================================================*/
|
||||||
|
|
||||||
|
OPLoadConstant::OPLoadConstant(
|
||||||
|
__rd__ const float constant )
|
||||||
|
: T_Op( OP_LOAD_CONSTANT ) , constant( constant )
|
||||||
|
{ }
|
||||||
|
|
||||||
|
void OPLoadConstant::execute(
|
||||||
|
__rw__ T_Context& ctx )
|
||||||
|
{
|
||||||
|
ctx.opStack.push_back( constant );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*= OPLoadVariable ===========================================================*/
|
||||||
|
|
||||||
|
OPLoadVariable::OPLoadVariable(
|
||||||
|
__rd__ std::string const& variable )
|
||||||
|
: T_Op( OP_LOAD_VARIABLE ) , variable( variable )
|
||||||
|
{ }
|
||||||
|
|
||||||
|
void OPLoadVariable::execute(
|
||||||
|
__rw__ T_Context& ctx )
|
||||||
|
{
|
||||||
|
const auto vPos( ctx.varPos.find( variable ) );
|
||||||
|
if ( vPos == ctx.varPos.end( ) ) {
|
||||||
|
throw error( "variable '" + variable + "' not found" );
|
||||||
|
}
|
||||||
|
ctx.opStack.push_back( ctx.varValues[ vPos->second ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*= OPLoadInput ==============================================================*/
|
||||||
|
|
||||||
|
OPLoadInput::OPLoadInput(
|
||||||
|
__rd__ std::string const& input )
|
||||||
|
: T_Op( OP_LOAD_VARIABLE ) , input( input )
|
||||||
|
{ }
|
||||||
|
|
||||||
|
void OPLoadInput::execute(
|
||||||
|
__rw__ T_Context& ctx )
|
||||||
|
{
|
||||||
|
ctx.opStack.push_back( ctx.sync->valueOf( input , *( ctx.time ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*= OPStoreVariable ==========================================================*/
|
||||||
|
|
||||||
|
OPStoreVariable::OPStoreVariable(
|
||||||
|
__rd__ std::string const& variable )
|
||||||
|
: T_Op( OP_LOAD_VARIABLE ) , variable( variable )
|
||||||
|
{ }
|
||||||
|
|
||||||
|
void OPStoreVariable::execute(
|
||||||
|
__rw__ T_Context& ctx )
|
||||||
|
{
|
||||||
|
if ( ctx.opStack.empty( ) ) {
|
||||||
|
throw error( "stack is empty" );
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto vPos( ctx.varPos.find( variable ) );
|
||||||
|
uint32_t pos;
|
||||||
|
if ( vPos == ctx.varPos.end( ) ) {
|
||||||
|
pos = ctx.varValues.size( );
|
||||||
|
ctx.varPos.emplace( variable , pos );
|
||||||
|
} else {
|
||||||
|
pos = vPos->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.varValues[ pos ] = ctx.opStack.back( );
|
||||||
|
ctx.opStack.pop_back( );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*= Arithmetic operators =====================================================*/
|
||||||
|
|
||||||
|
void OPAdd::execute(
|
||||||
|
__rw__ T_Context& ctx )
|
||||||
|
{
|
||||||
|
if ( ctx.opStack.size( ) < 2 ) {
|
||||||
|
throw error( "missing operands in stack" );
|
||||||
|
}
|
||||||
|
const float v( ctx.opStack.back( ) );
|
||||||
|
ctx.opStack.pop_back( );
|
||||||
|
ctx.opStack.back( ) += v;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OPMul::execute(
|
||||||
|
__rw__ T_Context& ctx )
|
||||||
|
{
|
||||||
|
if ( ctx.opStack.size( ) < 2 ) {
|
||||||
|
throw error( "missing operands in stack" );
|
||||||
|
}
|
||||||
|
const float v( ctx.opStack.back( ) );
|
||||||
|
ctx.opStack.pop_back( );
|
||||||
|
ctx.opStack.back( ) *= v;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OPNeg::execute(
|
||||||
|
__rw__ T_Context& ctx )
|
||||||
|
{
|
||||||
|
if ( ctx.opStack.empty( ) ) {
|
||||||
|
throw error( "missing operand in stack" );
|
||||||
|
}
|
||||||
|
ctx.opStack.back( ) = -ctx.opStack.back( );
|
||||||
|
}
|
||||||
|
|
||||||
|
void OPInv::execute(
|
||||||
|
__rw__ T_Context& ctx )
|
||||||
|
{
|
||||||
|
if ( ctx.opStack.empty( ) || ctx.opStack.back( ) == 0 ) {
|
||||||
|
throw error( "missing operand in stack" );
|
||||||
|
}
|
||||||
|
ctx.opStack.back( ) = 1.0f / ctx.opStack.back( );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*= Stack operations =========================================================*/
|
||||||
|
|
||||||
|
OPDup::OPDup( __rd__ const uint32_t stackIndex )
|
||||||
|
: T_Op( OP_DUP ) , stackIndex( stackIndex )
|
||||||
|
{ }
|
||||||
|
|
||||||
|
void OPDup::execute(
|
||||||
|
__rw__ T_Context& ctx )
|
||||||
|
{
|
||||||
|
if ( ctx.opStack.size( ) <= stackIndex ) {
|
||||||
|
std::string err( "stack does not have " );
|
||||||
|
err += stackIndex + 1;
|
||||||
|
err += " items";
|
||||||
|
throw error( err );
|
||||||
|
}
|
||||||
|
ctx.opStack.push_back( *( ctx.opStack.end( ) - stackIndex - 1 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
OPXchg::OPXchg( __rd__ const uint32_t stackIndex )
|
||||||
|
: T_Op( OP_XCHG ) , stackIndex( stackIndex )
|
||||||
|
{ }
|
||||||
|
|
||||||
|
void OPXchg::execute(
|
||||||
|
__rw__ T_Context& ctx )
|
||||||
|
{
|
||||||
|
if ( ctx.opStack.size( ) <= stackIndex ) {
|
||||||
|
std::string err( "stack does not have " );
|
||||||
|
err += stackIndex + 1;
|
||||||
|
err += " items";
|
||||||
|
throw error( err );
|
||||||
|
}
|
||||||
|
if ( stackIndex ) {
|
||||||
|
std::swap( *( ctx.opStack.end( ) - 1 ) , *( ctx.opStack.end( ) - stackIndex - 1 ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*= OPSetUniform =============================================================*/
|
||||||
|
|
||||||
|
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 )
|
||||||
|
{ }
|
||||||
|
|
||||||
|
void OPSetUniform::execute(
|
||||||
|
__rw__ T_Context& ctx )
|
||||||
|
{
|
||||||
|
if ( count == 0 || ctx.opStack.size( ) < count ) {
|
||||||
|
std::string err( "stack does not have " );
|
||||||
|
err += count;
|
||||||
|
err += " items";
|
||||||
|
throw error( err );
|
||||||
|
}
|
||||||
|
|
||||||
|
void* funcs[] = {
|
||||||
|
&glProgramUniform1fv , &glProgramUniform2fv , &glProgramUniform3fv , &glProgramUniform4fv ,
|
||||||
|
&glProgramUniform1iv , &glProgramUniform2iv , &glProgramUniform3iv , &glProgramUniform4iv ,
|
||||||
|
};
|
||||||
|
void (*func)( int , int , int , void* ) = (void (*)( int , int , int , void* )) funcs[ count + ( integer ? 4 : 0 ) ];
|
||||||
|
|
||||||
|
if ( integer ) {
|
||||||
|
int values[ count ];
|
||||||
|
auto i = count;
|
||||||
|
while ( i != 0 ) {
|
||||||
|
values[ count - i ] = int( ctx.opStack.back( ) );
|
||||||
|
ctx.opStack.pop_back( );
|
||||||
|
i --;
|
||||||
|
}
|
||||||
|
func( program , uniform , 1 , values );
|
||||||
|
} else {
|
||||||
|
float values[ count ];
|
||||||
|
auto i = count;
|
||||||
|
while ( i != 0 ) {
|
||||||
|
values[ count - i ] = ctx.opStack.back( );
|
||||||
|
ctx.opStack.pop_back( );
|
||||||
|
i --;
|
||||||
|
}
|
||||||
|
func( program , uniform , 1 , values );
|
||||||
|
}
|
||||||
|
}
|
214
control.hh
Normal file
214
control.hh
Normal file
|
@ -0,0 +1,214 @@
|
||||||
|
#pragma once
|
||||||
|
#ifndef REAL_BUILD
|
||||||
|
# include "externals.hh"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct T_SyncData;
|
||||||
|
|
||||||
|
namespace cops {
|
||||||
|
|
||||||
|
struct T_Context
|
||||||
|
{
|
||||||
|
float const* time;
|
||||||
|
T_SyncData const* sync;
|
||||||
|
|
||||||
|
std::vector< float > varValues;
|
||||||
|
std::map< std::string , uint32_t > varPos;
|
||||||
|
|
||||||
|
std::vector< float > opStack;
|
||||||
|
};
|
||||||
|
|
||||||
|
class X_OpFailure : public std::exception
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
X_OpFailure( ) = delete;
|
||||||
|
DEF_COPY( X_OpFailure );
|
||||||
|
DEF_MOVE( X_OpFailure );
|
||||||
|
|
||||||
|
X_OpFailure(
|
||||||
|
__rd__ std::string const& source ,
|
||||||
|
__rd__ uint32_t line ,
|
||||||
|
__rd__ std::string const& error ) noexcept;
|
||||||
|
|
||||||
|
std::string const& source( ) const noexcept
|
||||||
|
{ return source_; }
|
||||||
|
uint32_t line( ) const noexcept
|
||||||
|
{ return line_; }
|
||||||
|
std::string const& error( ) const noexcept
|
||||||
|
{ return error_; }
|
||||||
|
|
||||||
|
char const* what( ) const noexcept override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string source_;
|
||||||
|
uint32_t line_;
|
||||||
|
std::string error_;
|
||||||
|
std::string fullMessage_;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
enum E_Op
|
||||||
|
{
|
||||||
|
OP_LOAD_CONSTANT ,
|
||||||
|
OP_LOAD_VARIABLE ,
|
||||||
|
OP_LOAD_INPUT ,
|
||||||
|
OP_STORE_VARIABLE ,
|
||||||
|
//
|
||||||
|
OP_ADD , OP_MUL ,
|
||||||
|
OP_NEG , OP_INV ,
|
||||||
|
//
|
||||||
|
OP_DUP , OP_XCHG ,
|
||||||
|
//
|
||||||
|
OP_SET_UNIFORM ,
|
||||||
|
OP_USE_PIPELINE ,
|
||||||
|
OP_USE_TEXTURE ,
|
||||||
|
OP_USE_FRAMEBUFFER ,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct T_Op
|
||||||
|
{
|
||||||
|
explicit T_Op(
|
||||||
|
__rd__ const E_Op op );
|
||||||
|
virtual ~T_Op( ) = 0;
|
||||||
|
|
||||||
|
E_Op op( ) const noexcept
|
||||||
|
{ return op_; }
|
||||||
|
|
||||||
|
virtual void execute(
|
||||||
|
__rw__ T_Context& ctx ) = 0;
|
||||||
|
|
||||||
|
std::string source;
|
||||||
|
uint32_t line;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
X_OpFailure error(
|
||||||
|
__rd__ std::string const& message ) const noexcept;
|
||||||
|
|
||||||
|
private:
|
||||||
|
E_Op op_;
|
||||||
|
};
|
||||||
|
using T_Operations = std::vector< cops::T_Op >;
|
||||||
|
|
||||||
|
/*====================================================================*/
|
||||||
|
|
||||||
|
struct OPLoadConstant : public T_Op
|
||||||
|
{
|
||||||
|
explicit OPLoadConstant(
|
||||||
|
__rd__ const float constant );
|
||||||
|
void execute(
|
||||||
|
__rw__ T_Context& ctx ) override;
|
||||||
|
float constant;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct OPLoadVariable : public T_Op
|
||||||
|
{
|
||||||
|
explicit OPLoadVariable(
|
||||||
|
__rd__ std::string const& variable );
|
||||||
|
void execute(
|
||||||
|
__rw__ T_Context& ctx ) override;
|
||||||
|
std::string variable;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct OPLoadInput : public T_Op
|
||||||
|
{
|
||||||
|
explicit OPLoadInput(
|
||||||
|
__rd__ std::string const& input );
|
||||||
|
void execute(
|
||||||
|
__rw__ T_Context& ctx ) override;
|
||||||
|
std::string input;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct OPStoreVariable : public T_Op
|
||||||
|
{
|
||||||
|
explicit OPStoreVariable(
|
||||||
|
__rd__ std::string const& variable );
|
||||||
|
void execute(
|
||||||
|
__rw__ T_Context& ctx ) override;
|
||||||
|
std::string variable;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
struct OPAdd : public T_Op
|
||||||
|
{
|
||||||
|
OPAdd( ) : T_Op( OP_ADD ) {}
|
||||||
|
void execute(
|
||||||
|
__rw__ T_Context& ctx ) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct OPMul : public T_Op
|
||||||
|
{
|
||||||
|
OPMul( ) : T_Op( OP_MUL ) {}
|
||||||
|
void execute(
|
||||||
|
__rw__ T_Context& ctx ) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct OPNeg : public T_Op
|
||||||
|
{
|
||||||
|
OPNeg( ) : T_Op( OP_NEG ) {}
|
||||||
|
void execute(
|
||||||
|
__rw__ T_Context& ctx ) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct OPInv : public T_Op
|
||||||
|
{
|
||||||
|
OPInv( ) : T_Op( OP_INV ) {}
|
||||||
|
void execute(
|
||||||
|
__rw__ T_Context& ctx ) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
struct OPDup : public T_Op
|
||||||
|
{
|
||||||
|
explicit OPDup( uint32_t stackIndex = 0 );
|
||||||
|
void execute(
|
||||||
|
__rw__ T_Context& ctx ) override;
|
||||||
|
uint32_t stackIndex;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct OPXchg : public T_Op
|
||||||
|
{
|
||||||
|
explicit OPXchg( uint32_t stackIndex = 1 );
|
||||||
|
void execute(
|
||||||
|
__rw__ T_Context& ctx ) override;
|
||||||
|
uint32_t stackIndex;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
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 ) override;
|
||||||
|
|
||||||
|
uint32_t program;
|
||||||
|
uint32_t uniform;
|
||||||
|
uint32_t count;
|
||||||
|
bool integer;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct OPUsePipeline : public T_Op
|
||||||
|
{
|
||||||
|
explicit OPUsePipeline(
|
||||||
|
__rd__ const uint32_t index );
|
||||||
|
void execute(
|
||||||
|
__rw__ T_Context& ctx ) override;
|
||||||
|
|
||||||
|
uint32_t pipeline;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*====================================================================*/
|
||||||
|
|
||||||
|
void Execute(
|
||||||
|
__rd__ T_Operations const& operations ,
|
||||||
|
__rw__ T_Context& context );
|
||||||
|
|
||||||
|
} // namespace cops
|
Loading…
Reference in a new issue