Compiler - OP_{FRAMEBUFFER,USE_{FRAMEBUFFER,PROGRAM,PIPELINE}}

This commit is contained in:
Emmanuel BENOîT 2017-11-13 14:41:03 +01:00
parent 057033f2e3
commit b9d9589d80
6 changed files with 125 additions and 44 deletions

View file

@ -19,6 +19,7 @@ enum E_OpType
OP_RES_STACK ,
OP_PUSH ,
OP_POP ,
OP_DUP ,
//
OP_LOAD ,
OP_SLOAD ,
@ -40,6 +41,12 @@ enum E_OpType
OP_INIT_PIPELINE ,
OP_INIT_PROGRAM ,
OP_INIT_TEXTURE ,
OP_FB_ATTACH ,
//
OP_USE_FRAMEBUFFER ,
OP_FB_TOGGLE ,
OP_USE_PIPELINE ,
OP_USE_PROGRAM ,
//
OP_FULLSCREEN ,
OP_CLEAR ,

View file

@ -222,21 +222,22 @@ A_Node* opast::ASTVisitorBrowser(
case A_Node::OP_FRAMEBUFFER:
{
auto& n( (T_FramebufferInstrNode&) node );
auto c = child;
for ( auto i = 0u ; i < n.colorAttachments( ) ; i ++ ) {
auto* const lod( n.colorAttachmentLOD( i ) );
if ( lod ) {
if ( c == 0 ) {
return lod;
}
c --;
}
if ( child < n.colorAttachments( ) ) {
return &n.colorAttachment( child );
}
if ( c == 0 && n.hasDepthAttachment( ) ) {
return n.depthAttachmentLOD( );
if ( child == n.colorAttachments( ) && n.depthAttachment( ) ) {
return n.depthAttachment( );
}
break;
}
case A_Node::TN_FBATT:
{
auto& n( (T_FramebufferInstrNode::T_Attachment&) node );
if ( n.lod( ) && child == 0 ) {
return n.lod( );
}
break;
}
// Sampler definition may have LOD expressions
case A_Node::OP_SAMPLER:
@ -493,13 +494,13 @@ T_BinaryOperatorNode::T_BinaryOperatorNode(
bool T_FramebufferInstrNode::hasAttachment(
T_String const& name ) const noexcept
{
if ( depthAttachment_ && depthAttachment_->id == name ) {
if ( depthAttachment_ && depthAttachment_->id( ) == name ) {
return true;
}
const auto nca( colorAttachments_.size( ) );
for ( auto i = 0u ; i < nca ; i ++ ) {
if ( colorAttachments_[ i ].id == name ) {
if ( colorAttachments_[ i ]->id( ) == name ) {
return true;
}
}
@ -514,8 +515,8 @@ bool T_FramebufferInstrNode::addColorAttachment(
if ( hasAttachment( id.stringValue( ) ) ) {
return false;
}
colorAttachments_.add( T_Attachment_{ id.stringValue( ) ,
std::move( lod ) , id.location( ) } );
colorAttachments_.add( NewOwned< T_Attachment >( *this ,
false , id , std::move( lod ) ) );
return true;
}
@ -526,8 +527,8 @@ bool T_FramebufferInstrNode::setDepthAttachment(
if ( depthAttachment_ || hasAttachment( id.stringValue( ) ) ) {
return false;
}
depthAttachment_ = T_Attachment_{ id.stringValue( ) ,
std::move( lod ) , id.location( ) };
depthAttachment_ = NewOwned< T_Attachment >( *this ,
true , id , std::move( lod ) );
return true;
}

View file

@ -66,6 +66,7 @@ class A_Node
TN_CONDITION , // Expression for a conditional instruction
TN_CASE , // Valued case for a conditional instruction
TN_DEFAULT , // Default case for a conditional instruction
TN_FBATT , // Framebuffer attachment
TN_ARG , // Call argument
};
@ -627,16 +628,43 @@ class A_ResourceDefInstrNode : public A_InstructionNode
// Framebuffer definition instruction
class T_FramebufferInstrNode : public A_ResourceDefInstrNode
{
private:
struct T_Attachment_
public:
class T_Attachment : public A_Node
{
T_String id;
P_ExpressionNode lod;
T_SRDLocation location;
private:
bool depth_;
T_String id_;
P_ArgumentNode lod_;
public:
T_Attachment( T_FramebufferInstrNode& parent ,
const bool depth ,
T_SRDToken const& texId ,
P_ExpressionNode lod = { } ) noexcept
: A_Node( TN_FBATT , &parent ) ,
depth_( depth ) ,
id_( texId.stringValue( ) )
{
location() = texId.location( );
if ( lod ) {
lod_ = NewOwned< T_ArgumentNode >( *this ,
std::move( lod ) );
}
}
bool isDepth( ) const noexcept
{ return depth_; }
T_String const& id( ) const noexcept
{ return id_; }
T_ArgumentNode* lod( ) const noexcept
{ return lod_.get( ); }
};
T_AutoArray< T_Attachment_ , 8 > colorAttachments_;
T_Optional< T_Attachment_ > depthAttachment_;
private:
T_AutoArray< T_OwnPtr< T_Attachment > , 16 > colorAttachments_;
T_OwnPtr< T_Attachment > depthAttachment_;
bool hasAttachment( T_String const& name ) const noexcept;
@ -655,32 +683,17 @@ class T_FramebufferInstrNode : public A_ResourceDefInstrNode
uint32_t colorAttachments( ) const noexcept
{ return colorAttachments_.size( ); }
T_String const& colorAttachment(
T_Attachment& colorAttachment(
const uint32_t index ) const noexcept
{ return colorAttachments_[ index ].id; }
A_ExpressionNode* colorAttachmentLOD(
const uint32_t index ) const noexcept
{ return colorAttachments_[ index ].lod.get( ); }
T_SRDLocation const& colorAttachmentLocation(
const uint32_t index ) const noexcept
{ return colorAttachments_[ index ].location; }
{ return *colorAttachments_[ index ]; }
// ---------------------------------------------------------------------
bool setDepthAttachment( T_SRDToken const& token ,
P_ExpressionNode lod = {} ) noexcept;
bool hasDepthAttachment( ) const noexcept
{ return bool( depthAttachment_ ); }
T_String const& depthAttachment( ) const noexcept
{ return depthAttachment_->id; }
A_ExpressionNode* depthAttachmentLOD( ) const noexcept
{ return depthAttachment_->lod.get( ); }
T_SRDLocation const& depthAttachmentLocation( ) const noexcept
{ return depthAttachment_->location; }
T_Attachment* depthAttachment( ) const noexcept
{ return depthAttachment_.get( ); }
};
// Input declaration

View file

@ -54,6 +54,8 @@ struct T_CompilerImpl_
};
T_AutoArray< T_CondInfo_ , 16 > condJumps;
uint32_t fbCurrent; // Current framebuffer attachment
void gatherConstants( ) noexcept;
void countAssets( ) noexcept;
@ -468,6 +470,57 @@ bool T_CompilerImpl_::compileNode(
}
break;
case A_Node::OP_FRAMEBUFFER:
if ( !exit ) {
auto& fbn( (T_FramebufferInstrNode&) node );
processIdentifier( funcIndex , fbn.id( ) , fbn.idLocation( ) );
addInstruction( OP_USE_FRAMEBUFFER , fbn.location( ) );
fbCurrent = 0;
}
break;
case A_Node::TN_FBATT:
if ( exit ) {
auto& fan( (T_FramebufferInstrNode::T_Attachment&) node );
processIdentifier( funcIndex , fan.id( ) , fan.location( ) );
const uint32_t lod( fan.lod( ) ? 1 : 0 ) ,
id( fan.isDepth( ) ? 0 : ++fbCurrent );
addInstruction( OP_FB_ATTACH , { id , lod } , fan.location( ) );
if ( lod ) {
sdMain --;
}
if ( id ) {
addInstruction( OP_FB_TOGGLE , { id , 1 } , fan.location( ) );
}
}
break;
//- STATE -----------------------------------------------------------------------------
case A_Node::OP_USE_FRAMEBUFFER:
if ( exit ) {
auto& fbn( (T_UseInstrNode&) node );
processIdentifier( funcIndex , fbn.id( ) , fbn.idLocation( ) );
addInstruction( OP_USE_FRAMEBUFFER , fbn.location( ) );
}
break;
case A_Node::OP_USE_PIPELINE:
if ( exit ) {
auto& fbn( (T_UseInstrNode&) node );
processIdentifier( funcIndex , fbn.id( ) , fbn.idLocation( ) );
addInstruction( OP_USE_PIPELINE , fbn.location( ) );
}
break;
case A_Node::OP_USE_PROGRAM:
if ( exit ) {
auto& fbn( (T_UseInstrNode&) node );
processIdentifier( funcIndex , fbn.id( ) , fbn.idLocation( ) );
addInstruction( OP_USE_PROGRAM , fbn.location( ) );
}
break;
//- RENDERING -------------------------------------------------------------------------

View file

@ -1109,7 +1109,7 @@ M_INSTR_( Framebuffer )
for ( auto i = 2u ; i < input.size( ) ; i ++ ) {
ok = parseFramebufferEntry( instr , input[ i ] ) && ok;
}
if ( ok && instr.colorAttachments( ) == 0 && !instr.hasDepthAttachment( ) ) {
if ( ok && instr.colorAttachments( ) == 0 && !instr.depthAttachment( ) ) {
errors.addNew( "framebuffer has no attachments" ,
input[ 0 ].location( ) );
}

7
ops.cc
View file

@ -91,6 +91,7 @@ static T_KeyValueTable< E_OpType , T_OpInfo > OpInfoTable_{ ([]() {
infos.add( E_OpType::OP_RES_STACK , T_OpInfo{ "res-stack" , 1 } );
infos.add( E_OpType::OP_PUSH , T_OpInfo{ "push" , 0 , OpStackMain{ 1 } } );
infos.add( E_OpType::OP_POP , T_OpInfo{ "pop" , 1 } );
infos.add( E_OpType::OP_POP , T_OpInfo{ "dup" , 1 , OpStackMain{ 1 } } );
//
infos.add( E_OpType::OP_LOAD , T_OpInfo{ "load" , 1 } );
infos.add( E_OpType::OP_SLOAD , T_OpInfo{ "load-stack" , 1 } );
@ -112,6 +113,12 @@ static T_KeyValueTable< E_OpType , T_OpInfo > OpInfoTable_{ ([]() {
infos.add( E_OpType::OP_INIT_PIPELINE , T_OpInfo{ "pipeline" , 1 , OpStackMain{ -1 } } );
infos.add( E_OpType::OP_INIT_PROGRAM , T_OpInfo{ "program" , 1 , OpStackMain{ -1 } } );
infos.add( E_OpType::OP_INIT_TEXTURE , T_OpInfo{ "texture" , 2 , OpStackMain{ -3 } } );
infos.add( E_OpType::OP_FB_ATTACH , T_OpInfo{ "fb-attach" , 2 , OpStackMain{ -1 } } );
//
infos.add( E_OpType::OP_USE_FRAMEBUFFER , T_OpInfo{ "use-framebuffer" , 0 , OpStackMain{ -1 } } );
infos.add( E_OpType::OP_FB_TOGGLE , T_OpInfo{ "fb-toggle" , 2 } );
infos.add( E_OpType::OP_USE_PIPELINE , T_OpInfo{ "use-pipeline" , 0 , OpStackMain{ -1 } } );
infos.add( E_OpType::OP_USE_PROGRAM , T_OpInfo{ "use-program" , 0 , OpStackMain{ -1 } } );
//
infos.add( E_OpType::OP_FULLSCREEN , T_OpInfo{ "fullscreen" } );
infos.add( E_OpType::OP_CLEAR , T_OpInfo{ "clear" , 0 , OpStackMain{ -4 } } );