Scripting - Support for compute shader dispatch

This commit is contained in:
Emmanuel BENOîT 2017-12-23 18:40:36 +01:00
parent 4e77e6cf16
commit 8839127c1a
8 changed files with 68 additions and 5 deletions

View file

@ -45,7 +45,7 @@ syn keyword srdKWDebug profiling odbg ui-overrides
syn keyword srdKWState use-texture use-framebuffer use-program use-pipeline
syn keyword srdKWState uniforms uniforms-i viewport main-output
syn keyword srdKWDraw clear fullscreen
syn keyword srdKWDraw clear compute fullscreen
syn keyword srdKWExpr add sub mul div pow
syn keyword srdKWExpr cmp-eq cmp-ne cmp-gt cmp-ge cmp-lt cmp-le

View file

@ -158,13 +158,13 @@ A_Node* opast::ASTVisitorBrowser(
break;
}
// Clear instruction
// Clear instruction, compute instruction
case A_Node::OP_CLEAR:
case A_Node::OP_COMPUTE:
{
auto& n( (T_ClearInstrNode&) node );
const auto nArgs( n.size( ) );
const auto nArgs( node.size( ) );
if ( child < nArgs ) {
return &n.component( nArgs - child - 1 );
return node.child( nArgs - child - 1 ).get( );
}
break;
}

View file

@ -25,6 +25,7 @@ class A_Node
//
OP_CALL , // Function call
OP_CLEAR , // Clear buffer
OP_COMPUTE , // Compute shader dispatch
OP_COND , // Conditional instruction
OP_FRAMEBUFFER ,// Define framebuffer
OP_FULLSCREEN , // Draw a fullscreen quad
@ -1101,6 +1102,29 @@ class T_FullscreenInstrNode : public A_InstructionNode
{ }
};
// Dispatch a compute job
class T_ComputeInstrNode : public A_InstructionNode
{
public:
T_ComputeInstrNode( T_InstrListNode& parent ) noexcept
: A_InstructionNode( OP_COMPUTE , parent )
{ }
void addComponent( P_ExpressionNode expr ) noexcept
{
if ( expr ) {
children_.add( NewOwned< T_ArgumentNode >(
*this , std::move( expr ) ) );
}
}
T_ArgumentNode& component( const uint32_t index ) const noexcept
{ return (T_ArgumentNode&) *child( index ); }
};
/*= RENDERING STATE INSTRUCTIONS ===============================================*/
// Main output selection
class T_MainOutputInstrNode : public A_InstructionNode
{

View file

@ -650,6 +650,12 @@ bool T_CompilerImpl_::compileNode(
}
break;
case A_Node::OP_COMPUTE:
if ( exit ) {
addInstruction( OP_COMPUTE , node.location( ) );
}
break;
//- DEBUGGING / UI CONTROLS -----------------------------------------------------------

View file

@ -26,6 +26,7 @@ struct T_ParserImpl_
enum class E_InstrType {
CALL ,
CLEAR ,
COMPUTE ,
FRAMEBUFFER ,
FULLSCREEN ,
IF ,
@ -57,6 +58,7 @@ struct T_ParserImpl_
add( "call" , E_InstrType::CALL );
add( "clear" , E_InstrType::CLEAR );
add( "compute" , E_InstrType::COMPUTE );
add( "framebuffer" , E_InstrType::FRAMEBUFFER );
add( "fullscreen" , E_InstrType::FULLSCREEN );
add( "if" , E_InstrType::IF );
@ -237,6 +239,7 @@ struct T_ParserImpl_
M_DPARSER_( Call );
M_DPARSER_( Clear );
M_DPARSER_( Compute );
M_DPARSER_( Framebuffer );
bool parseFramebufferEntry(
@ -1062,6 +1065,7 @@ void T_ParserImpl_::parseInstructions(
switch ( *instrMap.get( iword ) ) {
M_CASE_( CALL , Call );
M_CASE_( CLEAR , Clear );
M_CASE_( COMPUTE , Compute );
M_CASE_( FRAMEBUFFER , Framebuffer );
M_CASE_( IF , If );
M_CASE_( INPUT , Input );
@ -1156,6 +1160,23 @@ M_INSTR_( Clear )
/*----------------------------------------------------------------------------*/
M_INSTR_( Compute )
{
if ( input.size( ) < 4 ) {
errors.addNew( "not enough arguments" , input[ 0 ].location( ) );
} else if ( input.size( ) > 4 ) {
errors.addNew( "too many arguments" , input[ 0 ].location( ) );
}
auto& instr{ instructions.add< T_ComputeInstrNode >( ) };
instr.location( ) = input[ 0 ].location( );
for ( auto i = 1u ; i < std::max( 4u , input.size( ) ) ; i ++ ) {
instr.addComponent( parseExpression( instr , input[ i ] ) );
}
}
/*----------------------------------------------------------------------------*/
M_INSTR_( Framebuffer )
{
if ( input.size( ) == 1 || input[ 1 ].type( ) != E_SRDTokenType::WORD ) {

View file

@ -138,6 +138,7 @@ static T_KeyValueTable< E_OpType , T_OpInfo > OpInfoTable_{ ([]() {
//
infos.add( E_OpType::OP_FULLSCREEN , T_OpInfo{ "fullscreen" } );
infos.add( E_OpType::OP_CLEAR , T_OpInfo{ "clear" , 0 , OpStackMain{ -4 } } );
infos.add( E_OpType::OP_COMPUTE , T_OpInfo{ "compute" , 0 , OpStackMain{ -3 } } );
//
infos.add( E_OpType::OP_UI_PENTER , T_OpInfo{ "ui-prof-enter" , 1 } );
infos.add( E_OpType::OP_UI_PEXIT , T_OpInfo{ "ui-prof-exit" } );

View file

@ -68,6 +68,7 @@ enum E_OpType
OP_VIEWPORT ,
//
OP_FULLSCREEN ,
OP_COMPUTE ,
OP_CLEAR ,
//
OP_UI_PENTER ,

View file

@ -678,6 +678,16 @@ void T_OpContext::run(
break;
}
case OP_COMPUTE:
{
ensureStack( instr , 3 );
const auto ss( stack.size( ) );
glDispatchCompute( stack[ ss - 1 ].f , stack[ ss - 2 ].f ,
stack[ ss - 3 ].f );
stack.resize( ss - 3 );
break;
}
// --------------------------------------------------------------------------------
case OP_UI_PENTER: