Parser - Framebuffer definition command

This commit is contained in:
Emmanuel BENOîT 2017-11-10 10:15:56 +01:00
parent d02ab91767
commit 448acdf16b
4 changed files with 178 additions and 14 deletions

View file

@ -34,10 +34,9 @@
(fn scene-init () (fn scene-init ()
(texture tx-scene-output rgb-f16 vp-width vp-height) (texture tx-scene-output rgb-f16 vp-width vp-height)
(texture tx-scene-depth r-f16 vp-width vp-height) (texture tx-scene-depth r-f16 vp-width vp-height)
{ NOT IMPLEMENTED
(framebuffer rt-scene (framebuffer rt-scene
(colors tx-scene-output tx-scene-depth)) (color tx-scene-output)
} (color tx-scene-depth))
(program prg-scene-p1 "scene.f.glsl") (program prg-scene-p1 "scene.f.glsl")
(uniforms prg-scene-p1 1 $vp-width $vp-height) (uniforms prg-scene-p1 1 $vp-width $vp-height)
@ -94,15 +93,11 @@
# Texture & RT for pass 1 # Texture & RT for pass 1
(texture tx-dof-pass1 rgb-f16 vp-width vp-height) (texture tx-dof-pass1 rgb-f16 vp-width vp-height)
{ NOT IMPLEMENTED (framebuffer rt-dof-pass1 tx-dof-pass1)
(framebuffer rt-dof-pass1 (colors tx-dof-pass1))
}
# Texture & RT for pass 2 # Texture & RT for pass 2
(texture tx-dof-pass2 rgb-f16 vp-width vp-height) (texture tx-dof-pass2 rgb-f16 vp-width vp-height)
{ NOT IMPLEMENTED (framebuffer rt-dof-pass2 tx-dof-pass2)
(framebuffer rt-dof-pass2 (colors tx-dof-pass2))
}
# MAYBE ? (alias tx-dof-output tx-dof-pass2) # MAYBE ? (alias tx-dof-output tx-dof-pass2)
# Output debugging # Output debugging

View file

@ -98,8 +98,11 @@ A_Node* opast::ASTVisitorBrowser(
// Nodes that do not have children // Nodes that do not have children
case A_Node::EXPR_ID: case A_Node::EXPR_CONST: case A_Node::EXPR_ID: case A_Node::EXPR_CONST:
case A_Node::EXPR_INPUT: case A_Node::EXPR_INPUT:
//
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_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:
break; break;
@ -335,3 +338,29 @@ T_BinaryOperatorNode::T_BinaryOperatorNode(
std::abort( ); std::abort( );
})( ) , parent ) , op_( op ) })( ) , parent ) , op_( op )
{ } { }
/*= T_FramebufferInstrNode ===================================================*/
bool T_FramebufferInstrNode::addColorAttachment(
T_SRDToken const& id ) noexcept
{
if ( idColorAttachments_.contains( id.stringValue( ) )
|| idDepthAttachment_ == id.stringValue( ) ) {
return false;
}
idColorAttachments_.add( id.stringValue( ) );
locColorAttachments_.add( id.location( ) );
return true;
}
bool T_FramebufferInstrNode::setDepthAttachment(
T_SRDToken const& token ) noexcept
{
if ( idDepthAttachment_ || idColorAttachments_.contains( token.stringValue( ) ) ) {
return false;
}
idDepthAttachment_ = token.stringValue( );
locDepthAttachment_ = token.location( );
return true;
}

View file

@ -22,6 +22,7 @@ class A_Node
// //
OP_CALL , // Function call OP_CALL , // Function call
OP_COND , // Conditional instruction OP_COND , // Conditional instruction
OP_FRAMEBUFFER ,// Define framebuffer
OP_FULLSCREEN , // Draw a fullscreen quad OP_FULLSCREEN , // Draw a fullscreen quad
OP_INPUT , // Input declaration OP_INPUT , // Input declaration
OP_PIPELINE , // Shader pipeline declaration OP_PIPELINE , // Shader pipeline declaration
@ -367,6 +368,62 @@ class T_CondInstrNode : public A_InstructionNode
{ return *defaultCase_; } { return *defaultCase_; }
}; };
// Framebuffer definition instruction
class T_FramebufferInstrNode : public A_InstructionNode
{
private:
T_String idFramebuffer_;
T_SRDLocation locFramebuffer_;
T_AutoArray< T_String , 8 > idColorAttachments_;
T_AutoArray< T_SRDLocation , 8 > locColorAttachments_;
T_String idDepthAttachment_;
T_SRDLocation locDepthAttachment_;
public:
T_FramebufferInstrNode( T_InstrListNode& parent ,
T_SRDToken const& identifier ) noexcept
: A_InstructionNode( OP_FRAMEBUFFER , parent , E_InstrRestriction::FRAME ) ,
idFramebuffer_( identifier.stringValue( ) ) ,
locFramebuffer_( identifier.location( ) )
{ }
// ---------------------------------------------------------------------
T_String const& id( ) const noexcept
{ return idFramebuffer_; }
T_SRDLocation const& idLocation( ) const noexcept
{ return locFramebuffer_; }
// ---------------------------------------------------------------------
bool addColorAttachment( T_SRDToken const& id ) noexcept;
uint32_t colorAttachments( ) const noexcept
{ return idColorAttachments_.size( ); }
T_String const& colorAttachment(
const uint32_t index ) const noexcept
{ return idColorAttachments_[ index ]; }
T_SRDLocation const& colorAttachmentLocation(
const uint32_t index ) const noexcept
{ return locColorAttachments_[ index ]; }
// ---------------------------------------------------------------------
bool setDepthAttachment( T_SRDToken const& token ) noexcept;
bool hasDepthAttachment( ) const noexcept
{ return bool( idDepthAttachment_ ); }
T_String const& depthAttachment( ) const noexcept
{ return idDepthAttachment_; }
T_SRDLocation const& depthAttachmentLocation( ) const noexcept
{ return locDepthAttachment_; }
};
// Fullscreen quad instruction // Fullscreen quad instruction
class T_FullscreenInstrNode : public A_InstructionNode class T_FullscreenInstrNode : public A_InstructionNode
{ {

View file

@ -14,6 +14,7 @@ struct T_ParserImpl_
{ {
enum class E_InstrType { enum class E_InstrType {
CALL , CALL ,
FRAMEBUFFER ,
FULLSCREEN , FULLSCREEN ,
IF , IF ,
INPUT , INPUT ,
@ -32,12 +33,13 @@ struct T_ParserImpl_
}; };
const T_KeyValueTable< T_String , E_InstrType > instrMap{ ([]() { const T_KeyValueTable< T_String , E_InstrType > instrMap{ ([]() {
T_KeyValueTable< T_String , E_InstrType > temp{ 256 , 64 , 64 }; T_KeyValueTable< T_String , E_InstrType > temp{ 64 , 128 , 64 };
const auto add{ [&temp]( char const* name , E_InstrType it ) { const auto add{ [&temp]( char const* name , E_InstrType it ) {
temp.add( T_String::Pooled( name ) , it ); temp.add( T_String::Pooled( name ) , it );
} }; } };
add( "call" , E_InstrType::CALL ); add( "call" , E_InstrType::CALL );
add( "framebuffer" , E_InstrType::FRAMEBUFFER );
add( "fullscreen" , E_InstrType::FULLSCREEN ); add( "fullscreen" , E_InstrType::FULLSCREEN );
add( "if" , E_InstrType::IF ); add( "if" , E_InstrType::IF );
add( "input" , E_InstrType::INPUT ); add( "input" , E_InstrType::INPUT );
@ -58,7 +60,7 @@ struct T_ParserImpl_
})( ) }; })( ) };
const T_KeyValueTable< T_String , T_UnaryOperatorNode::E_Operator > unaryOpMap{ ([]() { const T_KeyValueTable< T_String , T_UnaryOperatorNode::E_Operator > unaryOpMap{ ([]() {
T_KeyValueTable< T_String , T_UnaryOperatorNode::E_Operator > temp{ 64 , 32 , 32 }; T_KeyValueTable< T_String , T_UnaryOperatorNode::E_Operator > temp{ 32 , 32 , 32 };
const auto add{ [&temp]( char const* name , const auto add{ [&temp]( char const* name ,
const T_UnaryOperatorNode::E_Operator it ) { const T_UnaryOperatorNode::E_Operator it ) {
temp.add( T_String::Pooled( name ) , it ); temp.add( T_String::Pooled( name ) , it );
@ -78,7 +80,7 @@ struct T_ParserImpl_
})( ) }; })( ) };
const T_KeyValueTable< T_String , E_TexType > texTypeMap{ ([]() { const T_KeyValueTable< T_String , E_TexType > texTypeMap{ ([]() {
T_KeyValueTable< T_String , E_TexType > temp{ 64 , 16 , 16 }; T_KeyValueTable< T_String , E_TexType > temp{ 16 , 16 , 16 };
const auto add{ [&temp]( char const* name , const auto add{ [&temp]( char const* name ,
const E_TexType it ) { const E_TexType it ) {
temp.add( T_String::Pooled( name ) , it ); temp.add( T_String::Pooled( name ) , it );
@ -95,7 +97,7 @@ struct T_ParserImpl_
})( ) }; })( ) };
const T_KeyValueTable< T_String , T_BinaryOperatorNode::E_Operator > binOpMap{ ([]() { const T_KeyValueTable< T_String , T_BinaryOperatorNode::E_Operator > binOpMap{ ([]() {
T_KeyValueTable< T_String , T_BinaryOperatorNode::E_Operator > temp{ 64 , 32 , 32 }; T_KeyValueTable< T_String , T_BinaryOperatorNode::E_Operator > temp{ 32 , 32 , 32 };
const auto add{ [&temp]( char const* name , const auto add{ [&temp]( char const* name ,
const T_BinaryOperatorNode::E_Operator it ) { const T_BinaryOperatorNode::E_Operator it ) {
temp.add( T_String::Pooled( name ) , it ); temp.add( T_String::Pooled( name ) , it );
@ -160,6 +162,12 @@ struct T_ParserImpl_
T_SRDList const& input ) noexcept T_SRDList const& input ) noexcept
M_DPARSER_( Call ); M_DPARSER_( Call );
M_DPARSER_( Framebuffer );
bool parseFramebufferEntry(
T_FramebufferInstrNode& instruction ,
T_SRDToken const& entry ) noexcept;
M_DPARSER_( If ); M_DPARSER_( If );
M_DPARSER_( Input ); M_DPARSER_( Input );
M_DPARSER_( Pipeline ); M_DPARSER_( Pipeline );
@ -438,6 +446,7 @@ void T_ParserImpl_::parseInstructions(
#define M_CASE_( NAME , FNAME ) case E_InstrType::NAME: parse##FNAME##Instruction( instructions , ilist ); break #define M_CASE_( NAME , FNAME ) case E_InstrType::NAME: parse##FNAME##Instruction( instructions , ilist ); break
switch ( *instrMap.get( iword ) ) { switch ( *instrMap.get( iword ) ) {
M_CASE_( CALL , Call ); M_CASE_( CALL , Call );
M_CASE_( FRAMEBUFFER , Framebuffer );
M_CASE_( IF , If ); M_CASE_( IF , If );
M_CASE_( INPUT , Input ); M_CASE_( INPUT , Input );
M_CASE_( PIPELINE , Pipeline ); M_CASE_( PIPELINE , Pipeline );
@ -500,6 +509,80 @@ M_INSTR_( Call )
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
M_INSTR_( Framebuffer )
{
if ( input.size( ) == 1 || input[ 1 ].type( ) != E_SRDTokenType::WORD ) {
errors.addNew( "framebuffer identifier expected" ,
input[ input.size( ) == 1 ? 0 : 1 ].location( ) );
return;
}
auto& instr( instructions.add< T_FramebufferInstrNode >( input[ 1 ] ) );
instr.location( ) = input[ 0 ].location( );
bool ok( true );
for ( auto i = 2u ; i < input.size( ) ; i ++ ) {
ok = parseFramebufferEntry( instr , input[ i ] ) && ok;
}
if ( ok && instr.colorAttachments( ) == 0 && !instr.hasDepthAttachment( ) ) {
errors.addNew( "framebuffer has no attachments" ,
input[ 0 ].location( ) );
}
}
bool T_ParserImpl_::parseFramebufferEntry(
T_FramebufferInstrNode& instruction ,
T_SRDToken const& entry ) noexcept
{
if ( entry.type( ) == E_SRDTokenType::WORD ) {
const bool ok( instruction.addColorAttachment( entry ) );
if ( !ok ) {
errors.addNew( "duplicate color attachment" ,
entry.location( ) );
}
return ok;
}
if ( entry.type( ) != E_SRDTokenType::LIST ) {
errors.addNew( "framebuffer attachment expected" ,
entry.location( ) );
return false;
}
T_SRDList const& l( entry.list( ) );
if ( l.size( ) != 2 || l[ 0 ].type( ) != E_SRDTokenType::WORD
|| l[ 1 ].type( ) != E_SRDTokenType::WORD ) {
errors.addNew( "invalid framebuffer attachment" ,
entry.location( ) );
return false;
}
T_String const& atype( l[ 0 ].stringValue( ) );
if ( atype == "depth" ) {
const bool ok( instruction.setDepthAttachment( l[ 1 ] ) );
if ( !ok ) {
errors.addNew( "duplicate depth attachment" ,
entry.location( ) );
}
return ok;
}
if ( atype == "color" ) {
const bool ok( instruction.addColorAttachment( l[ 1 ] ) );
if ( !ok ) {
errors.addNew( "duplicate color attachment" ,
l[ 1 ].location( ) );
}
return ok;
}
errors.addNew( "'color' or 'depth' expected" ,
l[ 0 ].location( ) );
return false;
}
/*----------------------------------------------------------------------------*/
M_INSTR_( If ) M_INSTR_( If )
{ {
if ( input.size( ) == 1 ) { if ( input.size( ) == 1 ) {