Parser - Support for LODs in texture and framebuffers

This commit is contained in:
Emmanuel BENOîT 2017-11-10 20:38:17 +01:00
parent 9e583c1374
commit 9515d64400
3 changed files with 99 additions and 29 deletions

View file

@ -101,7 +101,7 @@ A_Node* opast::ASTVisitorBrowser(
// //
case A_Node::OP_PROGRAM: case A_Node::OP_PIPELINE: case A_Node::OP_PROGRAM: case A_Node::OP_PIPELINE:
case A_Node::OP_INPUT: case A_Node::OP_FULLSCREEN: case A_Node::OP_INPUT: case A_Node::OP_FULLSCREEN:
case A_Node::OP_FRAMEBUFFER: case A_Node::OP_ODBG: case A_Node::OP_ODBG:
// //
case A_Node::OP_USE_FRAMEBUFFER: case A_Node::OP_USE_PIPELINE: case A_Node::OP_USE_FRAMEBUFFER: case A_Node::OP_USE_PIPELINE:
case A_Node::OP_USE_PROGRAM: case A_Node::OP_USE_TEXTURE: case A_Node::OP_USE_PROGRAM: case A_Node::OP_USE_TEXTURE:
@ -168,9 +168,32 @@ A_Node* opast::ASTVisitorBrowser(
} }
c --; c --;
} }
if ( n.hasHeight( ) && c == 0 ) { if ( n.hasHeight( ) ) {
if ( c == 0 ) {
return &n.height( ); return &n.height( );
} }
c --;
}
return n.lods( );
}
// Framebuffer definition; may have LOD expressions
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 ( c == 0 && n.depthAttachmentLOD( ) ) {
return n.depthAttachmentLOD( );
}
break; break;
} }
@ -359,26 +382,44 @@ T_BinaryOperatorNode::T_BinaryOperatorNode(
/*= T_FramebufferInstrNode ===================================================*/ /*= T_FramebufferInstrNode ===================================================*/
bool T_FramebufferInstrNode::addColorAttachment( bool T_FramebufferInstrNode::hasAttachment(
T_SRDToken const& id ) noexcept T_String const& name ) const noexcept
{ {
if ( idColorAttachments_.contains( id.stringValue( ) ) if ( depthAttachment_ && depthAttachment_->id == name ) {
|| idDepthAttachment_ == id.stringValue( ) ) { return true;
}
const auto nca( colorAttachments_.size( ) );
for ( auto i = 0u ; i < nca ; i ++ ) {
if ( colorAttachments_[ i ].id == name ) {
return true;
}
}
return false; return false;
} }
idColorAttachments_.add( id.stringValue( ) );
locColorAttachments_.add( id.location( ) ); bool T_FramebufferInstrNode::addColorAttachment(
T_SRDToken const& id ,
P_ExpressionNode lod ) noexcept
{
if ( hasAttachment( id.stringValue( ) ) ) {
return false;
}
colorAttachments_.add( T_Attachment_{ id.stringValue( ) ,
std::move( lod ) , id.location( ) } );
return true; return true;
} }
bool T_FramebufferInstrNode::setDepthAttachment( bool T_FramebufferInstrNode::setDepthAttachment(
T_SRDToken const& token ) noexcept T_SRDToken const& id ,
P_ExpressionNode lod ) noexcept
{ {
if ( idDepthAttachment_ || idColorAttachments_.contains( token.stringValue( ) ) ) { if ( depthAttachment_ || hasAttachment( id.stringValue( ) ) ) {
return false; return false;
} }
idDepthAttachment_ = token.stringValue( ); depthAttachment_ = T_Attachment_{ id.stringValue( ) ,
locDepthAttachment_ = token.location( ); std::move( lod ) , id.location( ) };
return true; return true;
} }

View file

@ -374,14 +374,20 @@ class T_CondInstrNode : public A_InstructionNode
class T_FramebufferInstrNode : public A_InstructionNode class T_FramebufferInstrNode : public A_InstructionNode
{ {
private: private:
struct T_Attachment_
{
T_String id;
P_ExpressionNode lod;
T_SRDLocation location;
};
T_String idFramebuffer_; T_String idFramebuffer_;
T_SRDLocation locFramebuffer_; T_SRDLocation locFramebuffer_;
T_AutoArray< T_String , 8 > idColorAttachments_; T_AutoArray< T_Attachment_ , 8 > colorAttachments_;
T_AutoArray< T_SRDLocation , 8 > locColorAttachments_; T_Optional< T_Attachment_ > depthAttachment_;
T_String idDepthAttachment_; bool hasAttachment( T_String const& name ) const noexcept;
T_SRDLocation locDepthAttachment_;
public: public:
T_FramebufferInstrNode( T_InstrListNode& parent , T_FramebufferInstrNode( T_InstrListNode& parent ,
@ -400,30 +406,38 @@ class T_FramebufferInstrNode : public A_InstructionNode
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
bool addColorAttachment( T_SRDToken const& id ) noexcept; bool addColorAttachment( T_SRDToken const& id ,
P_ExpressionNode lod = {} ) noexcept;
uint32_t colorAttachments( ) const noexcept uint32_t colorAttachments( ) const noexcept
{ return idColorAttachments_.size( ); } { return colorAttachments_.size( ); }
T_String const& colorAttachment( T_String const& colorAttachment(
const uint32_t index ) const noexcept const uint32_t index ) const noexcept
{ return idColorAttachments_[ index ]; } { return colorAttachments_[ index ].id; }
A_ExpressionNode* colorAttachmentLOD(
const uint32_t index ) const noexcept
{ return colorAttachments_[ index ].lod.get( ); }
T_SRDLocation const& colorAttachmentLocation( T_SRDLocation const& colorAttachmentLocation(
const uint32_t index ) const noexcept const uint32_t index ) const noexcept
{ return locColorAttachments_[ index ]; } { return colorAttachments_[ index ].location; }
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
bool setDepthAttachment( T_SRDToken const& token ) noexcept; bool setDepthAttachment( T_SRDToken const& token ,
P_ExpressionNode lod = {} ) noexcept;
bool hasDepthAttachment( ) const noexcept bool hasDepthAttachment( ) const noexcept
{ return bool( idDepthAttachment_ ); } { return bool( depthAttachment_ ); }
T_String const& depthAttachment( ) const noexcept T_String const& depthAttachment( ) const noexcept
{ return idDepthAttachment_; } { return depthAttachment_->id; }
A_ExpressionNode* depthAttachmentLOD( ) const noexcept
{ return depthAttachment_->lod.get( ); }
T_SRDLocation const& depthAttachmentLocation( ) const noexcept T_SRDLocation const& depthAttachmentLocation( ) const noexcept
{ return locDepthAttachment_; } { return depthAttachment_->location; }
}; };
// Fullscreen quad instruction // Fullscreen quad instruction
@ -724,6 +738,7 @@ class T_TextureInstrNode : public A_InstructionNode
E_TexType type_; E_TexType type_;
P_ExpressionNode width_; P_ExpressionNode width_;
P_ExpressionNode height_; P_ExpressionNode height_;
P_ExpressionNode lods_;
public: public:
T_TextureInstrNode( T_TextureInstrNode(
@ -753,6 +768,11 @@ class T_TextureInstrNode : public A_InstructionNode
{ return bool( height_ ); } { return bool( height_ ); }
A_ExpressionNode& height( ) const noexcept A_ExpressionNode& height( ) const noexcept
{ return *height_; } { return *height_; }
void setLODs( P_ExpressionNode lods ) noexcept
{ lods_ = std::move( lods ); }
A_ExpressionNode* lods( ) const noexcept
{ return lods_.get( ); }
}; };
// Uniform setting instruction // Uniform setting instruction

View file

@ -589,16 +589,21 @@ bool T_ParserImpl_::parseFramebufferEntry(
} }
T_SRDList const& l( entry.list( ) ); T_SRDList const& l( entry.list( ) );
if ( l.size( ) != 2 || l[ 0 ].type( ) != E_SRDTokenType::WORD if ( l.size( ) < 2 || l.size( ) > 3
|| l[ 0 ].type( ) != E_SRDTokenType::WORD
|| l[ 1 ].type( ) != E_SRDTokenType::WORD ) { || l[ 1 ].type( ) != E_SRDTokenType::WORD ) {
errors.addNew( "invalid framebuffer attachment" , errors.addNew( "invalid framebuffer attachment" ,
entry.location( ) ); entry.location( ) );
return false; return false;
} }
P_ExpressionNode lod{ l.size( ) > 2
? parseExpression( instruction , l[ 2 ] )
: P_ExpressionNode{} };
T_String const& atype( l[ 0 ].stringValue( ) ); T_String const& atype( l[ 0 ].stringValue( ) );
if ( atype == "depth" ) { if ( atype == "depth" ) {
const bool ok( instruction.setDepthAttachment( l[ 1 ] ) ); const bool ok( instruction.setDepthAttachment(
l[ 1 ] , std::move( lod ) ) );
if ( !ok ) { if ( !ok ) {
errors.addNew( "duplicate depth attachment" , errors.addNew( "duplicate depth attachment" ,
entry.location( ) ); entry.location( ) );
@ -607,7 +612,8 @@ bool T_ParserImpl_::parseFramebufferEntry(
} }
if ( atype == "color" ) { if ( atype == "color" ) {
const bool ok( instruction.addColorAttachment( l[ 1 ] ) ); const bool ok( instruction.addColorAttachment(
l[ 1 ] , std::move( lod ) ) );
if ( !ok ) { if ( !ok ) {
errors.addNew( "duplicate color attachment" , errors.addNew( "duplicate color attachment" ,
l[ 1 ].location( ) ); l[ 1 ].location( ) );
@ -1052,6 +1058,9 @@ M_INSTR_( Texture )
errors.addNew( "height expected" , input[ 0 ].location( ) ); errors.addNew( "height expected" , input[ 0 ].location( ) );
} }
if ( input.size( ) > 5 ) { if ( input.size( ) > 5 ) {
instr.setLODs( parseExpression( instr , input[ 4 ] ) );
}
if ( input.size( ) > 6 ) {
errors.addNew( "too many arguments" , input[ 5 ].location( ) ); errors.addNew( "too many arguments" , input[ 5 ].location( ) );
} }
} }