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_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_PROGRAM: case A_Node::OP_USE_TEXTURE:
@ -168,8 +168,31 @@ A_Node* opast::ASTVisitorBrowser(
}
c --;
}
if ( n.hasHeight( ) && c == 0 ) {
return &n.height( );
if ( n.hasHeight( ) ) {
if ( c == 0 ) {
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;
}
@ -359,26 +382,44 @@ T_BinaryOperatorNode::T_BinaryOperatorNode(
/*= T_FramebufferInstrNode ===================================================*/
bool T_FramebufferInstrNode::addColorAttachment(
T_SRDToken const& id ) noexcept
bool T_FramebufferInstrNode::hasAttachment(
T_String const& name ) const noexcept
{
if ( idColorAttachments_.contains( id.stringValue( ) )
|| idDepthAttachment_ == id.stringValue( ) ) {
if ( depthAttachment_ && depthAttachment_->id == name ) {
return true;
}
const auto nca( colorAttachments_.size( ) );
for ( auto i = 0u ; i < nca ; i ++ ) {
if ( colorAttachments_[ i ].id == name ) {
return true;
}
}
return false;
}
bool T_FramebufferInstrNode::addColorAttachment(
T_SRDToken const& id ,
P_ExpressionNode lod ) noexcept
{
if ( hasAttachment( id.stringValue( ) ) ) {
return false;
}
idColorAttachments_.add( id.stringValue( ) );
locColorAttachments_.add( id.location( ) );
colorAttachments_.add( T_Attachment_{ id.stringValue( ) ,
std::move( lod ) , id.location( ) } );
return true;
}
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;
}
idDepthAttachment_ = token.stringValue( );
locDepthAttachment_ = token.location( );
depthAttachment_ = T_Attachment_{ id.stringValue( ) ,
std::move( lod ) , id.location( ) };
return true;
}

View file

@ -374,14 +374,20 @@ class T_CondInstrNode : public A_InstructionNode
class T_FramebufferInstrNode : public A_InstructionNode
{
private:
struct T_Attachment_
{
T_String id;
P_ExpressionNode lod;
T_SRDLocation location;
};
T_String idFramebuffer_;
T_SRDLocation locFramebuffer_;
T_AutoArray< T_String , 8 > idColorAttachments_;
T_AutoArray< T_SRDLocation , 8 > locColorAttachments_;
T_AutoArray< T_Attachment_ , 8 > colorAttachments_;
T_Optional< T_Attachment_ > depthAttachment_;
T_String idDepthAttachment_;
T_SRDLocation locDepthAttachment_;
bool hasAttachment( T_String const& name ) const noexcept;
public:
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
{ return idColorAttachments_.size( ); }
{ return colorAttachments_.size( ); }
T_String const& colorAttachment(
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(
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
{ return bool( idDepthAttachment_ ); }
{ return bool( depthAttachment_ ); }
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
{ return locDepthAttachment_; }
{ return depthAttachment_->location; }
};
// Fullscreen quad instruction
@ -724,6 +738,7 @@ class T_TextureInstrNode : public A_InstructionNode
E_TexType type_;
P_ExpressionNode width_;
P_ExpressionNode height_;
P_ExpressionNode lods_;
public:
T_TextureInstrNode(
@ -753,6 +768,11 @@ class T_TextureInstrNode : public A_InstructionNode
{ return bool( height_ ); }
A_ExpressionNode& height( ) const noexcept
{ return *height_; }
void setLODs( P_ExpressionNode lods ) noexcept
{ lods_ = std::move( lods ); }
A_ExpressionNode* lods( ) const noexcept
{ return lods_.get( ); }
};
// Uniform setting instruction

View file

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