2017-11-06 10:15:38 +01:00
|
|
|
#pragma once
|
2017-11-23 23:31:24 +01:00
|
|
|
#include "c-renderdefs.hh"
|
2017-11-06 10:15:38 +01:00
|
|
|
#include <ebcl/SRDData.hh>
|
|
|
|
|
|
|
|
|
2017-11-17 20:33:56 +01:00
|
|
|
struct T_SyncOverrideSection;
|
|
|
|
|
2017-11-06 10:15:38 +01:00
|
|
|
namespace opast {
|
|
|
|
|
2017-11-10 23:09:36 +01:00
|
|
|
|
|
|
|
/*= BASE CLASS FOR AST NODES ===================================================*/
|
|
|
|
|
2017-11-06 10:15:38 +01:00
|
|
|
class T_RootNode;
|
|
|
|
|
|
|
|
class A_Node
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
enum E_Type {
|
2017-11-06 14:06:21 +01:00
|
|
|
ROOT , // Root node
|
|
|
|
ILIST , // Instruction list
|
2017-11-06 10:15:38 +01:00
|
|
|
//
|
2017-11-06 14:06:21 +01:00
|
|
|
DECL_INIT , // Initialisation block
|
|
|
|
DECL_FRAME , // Frame block
|
|
|
|
DECL_FN , // Function
|
2017-11-06 10:15:38 +01:00
|
|
|
//
|
2017-11-06 19:00:02 +01:00
|
|
|
OP_CALL , // Function call
|
2017-11-10 22:09:24 +01:00
|
|
|
OP_CLEAR , // Clear buffer
|
2017-12-23 18:40:36 +01:00
|
|
|
OP_COMPUTE , // Compute shader dispatch
|
2017-11-06 17:09:05 +01:00
|
|
|
OP_COND , // Conditional instruction
|
2017-11-10 10:15:56 +01:00
|
|
|
OP_FRAMEBUFFER ,// Define framebuffer
|
2017-11-09 18:24:39 +01:00
|
|
|
OP_FULLSCREEN , // Draw a fullscreen quad
|
2017-12-24 11:10:38 +01:00
|
|
|
OP_IMAGE , // Image unit binding
|
2017-11-07 07:43:18 +01:00
|
|
|
OP_INPUT , // Input declaration
|
2017-11-10 21:01:35 +01:00
|
|
|
OP_LOCALS , // Declare local variables
|
2017-11-10 21:56:28 +01:00
|
|
|
OP_MAINOUT , // Select the output buffer
|
2017-11-10 12:48:57 +01:00
|
|
|
OP_ODBG , // Output debugging
|
2017-11-17 20:33:56 +01:00
|
|
|
OP_OVERRIDES , // Register input overrides
|
2017-11-06 14:06:21 +01:00
|
|
|
OP_PIPELINE , // Shader pipeline declaration
|
|
|
|
OP_PROFILE , // Profiling block
|
|
|
|
OP_PROGRAM , // Shader program declaration
|
2017-11-10 17:18:29 +01:00
|
|
|
OP_SAMPLER , // Define sampler
|
2017-11-06 14:06:21 +01:00
|
|
|
OP_SET , // Set instruction
|
2017-11-06 18:15:56 +01:00
|
|
|
OP_TEXTURE , // Define texture
|
2017-11-09 23:20:48 +01:00
|
|
|
OP_UNIFORMS , // Set uniforms
|
2017-11-09 18:24:39 +01:00
|
|
|
OP_VIEWPORT , // Set viewport
|
|
|
|
// "Use-<obj type>" instructions
|
|
|
|
OP_USE_FRAMEBUFFER ,
|
|
|
|
OP_USE_PIPELINE ,
|
|
|
|
OP_USE_PROGRAM ,
|
|
|
|
OP_USE_TEXTURE ,
|
2017-11-06 16:38:04 +01:00
|
|
|
// Unary operators
|
|
|
|
EXPR_NEG , EXPR_INV , EXPR_NOT ,
|
|
|
|
EXPR_SIN , EXPR_COS , EXPR_TAN ,
|
|
|
|
EXPR_SQRT , EXPR_EXP , EXPR_LN ,
|
|
|
|
// Binary operators
|
|
|
|
EXPR_ADD , EXPR_SUB ,
|
|
|
|
EXPR_MUL , EXPR_DIV ,
|
|
|
|
EXPR_POW ,
|
|
|
|
// Binary operators - comparisons
|
|
|
|
EXPR_CMP_EQ , EXPR_CMP_NE ,
|
|
|
|
EXPR_CMP_GT , EXPR_CMP_GE ,
|
|
|
|
EXPR_CMP_LT , EXPR_CMP_LE ,
|
2017-11-06 10:15:38 +01:00
|
|
|
//
|
2017-11-06 16:38:04 +01:00
|
|
|
EXPR_ID , // Variable access
|
2017-11-09 18:24:39 +01:00
|
|
|
EXPR_INPUT , // Input value access
|
2017-11-06 14:06:21 +01:00
|
|
|
EXPR_CONST , // Numeric constant
|
2017-11-12 11:13:38 +01:00
|
|
|
// Technical nodes
|
|
|
|
TN_CONDITION , // Expression for a conditional instruction
|
|
|
|
TN_CASE , // Valued case for a conditional instruction
|
|
|
|
TN_DEFAULT , // Default case for a conditional instruction
|
2017-11-13 14:41:03 +01:00
|
|
|
TN_FBATT , // Framebuffer attachment
|
2017-11-12 17:01:13 +01:00
|
|
|
TN_ARG , // Call argument
|
2017-11-06 10:15:38 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
private:
|
|
|
|
const E_Type type_;
|
2017-12-16 10:38:17 +01:00
|
|
|
A_Node* parent_;
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDLocation location_;
|
2017-11-06 10:15:38 +01:00
|
|
|
|
|
|
|
protected:
|
2017-12-13 21:44:50 +01:00
|
|
|
T_AutoArray< T_OwnPtr< A_Node > , 8 > children_;
|
|
|
|
|
2017-11-06 10:15:38 +01:00
|
|
|
explicit A_Node( const E_Type type ,
|
|
|
|
A_Node* const parent ) noexcept;
|
|
|
|
|
|
|
|
public:
|
|
|
|
virtual ~A_Node( ) = 0;
|
|
|
|
|
|
|
|
E_Type type( ) const noexcept
|
|
|
|
{ return type_; }
|
|
|
|
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDLocation& location( ) noexcept
|
2017-11-06 10:15:38 +01:00
|
|
|
{ return location_; }
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDLocation const& location( ) const noexcept
|
2017-11-06 10:15:38 +01:00
|
|
|
{ return location_; }
|
|
|
|
|
|
|
|
A_Node& parent( ) const noexcept
|
|
|
|
{ assert( parent_ ); return *parent_; }
|
|
|
|
|
|
|
|
T_RootNode& root( ) const noexcept;
|
2017-12-12 18:30:41 +01:00
|
|
|
|
2017-12-13 21:44:50 +01:00
|
|
|
uint32_t size( ) const noexcept
|
|
|
|
{ return children_.size( ); }
|
|
|
|
|
|
|
|
T_OwnPtr< A_Node > const& child(
|
|
|
|
const uint32_t index ) const noexcept
|
|
|
|
{ return children_[ index ]; }
|
|
|
|
T_OwnPtr< A_Node >& child(
|
|
|
|
const uint32_t index ) noexcept
|
|
|
|
{ return children_[ index ]; }
|
|
|
|
|
2017-12-14 07:39:38 +01:00
|
|
|
bool replace( A_Node const& node ,
|
|
|
|
T_OwnPtr< A_Node >& replacement ) noexcept;
|
2017-12-16 10:38:17 +01:00
|
|
|
|
|
|
|
void setParent( A_Node& newParent ) noexcept
|
|
|
|
{ parent_ = &newParent; }
|
2017-11-06 10:15:38 +01:00
|
|
|
};
|
|
|
|
|
2017-11-09 12:13:08 +01:00
|
|
|
// Browser function to be used with T_Visitor
|
|
|
|
extern A_Node* ASTVisitorBrowser(
|
|
|
|
A_Node& node ,
|
|
|
|
const uint32_t child ) noexcept;
|
|
|
|
|
2017-11-10 23:09:36 +01:00
|
|
|
// Data types
|
|
|
|
enum class E_DataType {
|
|
|
|
UNKNOWN ,
|
|
|
|
BUILTIN ,
|
|
|
|
VARIABLE ,
|
|
|
|
FRAMEBUFFER ,
|
|
|
|
INPUT ,
|
|
|
|
PIPELINE ,
|
|
|
|
PROGRAM ,
|
|
|
|
SAMPLER ,
|
|
|
|
TEXTURE ,
|
|
|
|
};
|
|
|
|
M_LSHIFT_OP( T_StringBuilder , E_DataType );
|
|
|
|
|
|
|
|
|
|
|
|
/*= BASE STRUCTURES FOR INSTRUCTIONS =========================================*/
|
2017-11-06 10:15:38 +01:00
|
|
|
|
2017-11-08 11:48:24 +01:00
|
|
|
// Some instructions are restricted to either the initialisation code or the
|
|
|
|
// frame code.
|
|
|
|
enum class E_InstrRestriction
|
|
|
|
{
|
|
|
|
INIT , FRAME
|
|
|
|
};
|
|
|
|
using T_InstrRestriction = T_Flags< E_InstrRestriction >;
|
|
|
|
|
2017-11-06 16:38:04 +01:00
|
|
|
// Base class for instruction nodes
|
2017-11-06 14:06:21 +01:00
|
|
|
class A_InstructionNode : public A_Node
|
|
|
|
{
|
2017-11-08 11:48:24 +01:00
|
|
|
private:
|
|
|
|
const T_InstrRestriction restriction_;
|
|
|
|
|
2017-11-06 14:06:21 +01:00
|
|
|
protected:
|
2017-11-08 11:48:24 +01:00
|
|
|
A_InstructionNode( const E_Type type ,
|
|
|
|
A_Node& parent ,
|
|
|
|
T_InstrRestriction restriction = {} ) noexcept
|
|
|
|
: A_Node( type , &parent ) ,
|
|
|
|
restriction_( restriction )
|
|
|
|
{
|
|
|
|
assert( !restriction_.isSet({
|
|
|
|
E_InstrRestriction::INIT ,
|
|
|
|
E_InstrRestriction::FRAME }) );
|
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
|
|
|
T_InstrRestriction restriction( ) const noexcept
|
|
|
|
{ return restriction_; }
|
2017-11-06 14:06:21 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
// Nodes that store lists of instructions
|
|
|
|
class T_InstrListNode : public A_Node
|
|
|
|
{
|
|
|
|
public:
|
2017-11-08 12:29:03 +01:00
|
|
|
T_InstrListNode( A_Node& parent ) noexcept
|
|
|
|
: A_Node( ILIST , &parent ) { }
|
2017-11-06 14:06:21 +01:00
|
|
|
|
|
|
|
template<
|
|
|
|
typename IType ,
|
|
|
|
typename... ArgTypes
|
|
|
|
> IType& add( ArgTypes&&... args );
|
2017-11-07 09:10:17 +01:00
|
|
|
|
|
|
|
A_InstructionNode& node( const uint32_t index ) const noexcept
|
2017-12-13 21:44:50 +01:00
|
|
|
{ return dynamic_cast< A_InstructionNode& >( *children_[ index ] ); }
|
2017-12-16 10:38:17 +01:00
|
|
|
|
|
|
|
void replaceMultiple(
|
|
|
|
A_InstructionNode& instruction ,
|
|
|
|
T_InstrListNode* replacement ) noexcept;
|
2017-11-06 14:06:21 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
template<
|
|
|
|
typename IType ,
|
|
|
|
typename... ArgTypes
|
|
|
|
> inline IType& T_InstrListNode::add(
|
|
|
|
ArgTypes&&... args )
|
|
|
|
{
|
2017-12-13 21:44:50 +01:00
|
|
|
children_.add( NewOwned< IType >( *this ,
|
2017-11-06 14:06:21 +01:00
|
|
|
std::forward< ArgTypes >( args ) ... ) );
|
2017-12-13 21:44:50 +01:00
|
|
|
return (IType&) *children_.last( );
|
2017-11-06 14:06:21 +01:00
|
|
|
}
|
|
|
|
|
2017-11-10 23:09:36 +01:00
|
|
|
/*------------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
// Base class for expressions
|
|
|
|
class A_ExpressionNode : public A_Node
|
|
|
|
{
|
|
|
|
protected:
|
|
|
|
A_ExpressionNode( E_Type type ,
|
|
|
|
A_Node& parent ) noexcept
|
|
|
|
: A_Node( type , &parent )
|
|
|
|
{ }
|
|
|
|
};
|
|
|
|
using P_ExpressionNode = T_OwnPtr< A_ExpressionNode >;
|
|
|
|
|
2017-11-13 10:02:16 +01:00
|
|
|
// Technical node used for the arguments of various instructions
|
|
|
|
class T_ArgumentNode : public A_Node
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
T_ArgumentNode( A_Node& parent ,
|
|
|
|
P_ExpressionNode expr ) noexcept
|
2017-12-13 21:44:50 +01:00
|
|
|
: A_Node( TN_ARG , &parent )
|
2017-11-13 10:02:16 +01:00
|
|
|
{
|
2017-12-13 21:44:50 +01:00
|
|
|
if ( expr ) {
|
|
|
|
location( ) = expr->location( );
|
|
|
|
children_.add( std::move( expr ) );
|
2017-11-13 10:02:16 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
A_ExpressionNode& expression( ) const noexcept
|
2017-12-13 21:44:50 +01:00
|
|
|
{ return (A_ExpressionNode&) *child( 0 ); }
|
2017-11-13 10:02:16 +01:00
|
|
|
bool isIdentifier( ) const noexcept
|
2017-12-13 21:44:50 +01:00
|
|
|
{ return expression( ).type( ) == EXPR_ID; }
|
2017-12-01 07:30:03 +01:00
|
|
|
|
|
|
|
void expression( P_ExpressionNode expr ) noexcept
|
2017-12-13 21:44:50 +01:00
|
|
|
{ assert( expr ); child( 0 ) = std::move( expr ); }
|
2017-11-13 10:02:16 +01:00
|
|
|
};
|
|
|
|
using P_ArgumentNode = T_OwnPtr< T_ArgumentNode >;
|
|
|
|
|
2017-11-10 23:09:36 +01:00
|
|
|
|
|
|
|
/*= FUNCTIONS AND ROOT NODES =================================================*/
|
2017-11-06 14:06:21 +01:00
|
|
|
|
2017-11-06 10:15:38 +01:00
|
|
|
// Function-like nodes
|
|
|
|
class A_FuncNode : public A_Node
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
T_String name_;
|
2017-12-13 21:44:50 +01:00
|
|
|
T_InstrListNode* instructions_{ nullptr };
|
2017-11-06 10:15:38 +01:00
|
|
|
|
2017-11-11 09:54:38 +01:00
|
|
|
protected:
|
|
|
|
struct T_Local_
|
|
|
|
{
|
|
|
|
T_String name;
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDLocation location;
|
2017-11-11 09:54:38 +01:00
|
|
|
bool argument;
|
|
|
|
E_DataType type{ E_DataType::UNKNOWN };
|
|
|
|
|
|
|
|
T_Local_( T_String const& name ,
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDLocation const& location ,
|
2017-11-11 09:54:38 +01:00
|
|
|
const bool argument ) noexcept
|
|
|
|
: name{ name } , location{ location } ,
|
|
|
|
argument{ argument }
|
|
|
|
{ }
|
|
|
|
};
|
|
|
|
T_ObjectTable< T_String , T_Local_ > locals_{
|
|
|
|
[]( T_Local_ const& l ) -> T_String {
|
|
|
|
return l.name;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2017-11-06 10:15:38 +01:00
|
|
|
protected:
|
|
|
|
// For init or frame entry points.
|
|
|
|
// isInit = true => init entry point
|
|
|
|
// isInit = false => frame entry point
|
|
|
|
explicit A_FuncNode( bool isInit ,
|
|
|
|
T_RootNode* const parent ) noexcept;
|
|
|
|
|
|
|
|
// For normal functions
|
|
|
|
explicit A_FuncNode( T_String const& name ,
|
|
|
|
T_RootNode* const parent ) noexcept;
|
|
|
|
|
|
|
|
public:
|
|
|
|
T_String const& name( ) const noexcept
|
|
|
|
{ return name_; }
|
2017-11-06 14:06:21 +01:00
|
|
|
|
|
|
|
T_InstrListNode& instructions( ) noexcept
|
2017-12-13 21:44:50 +01:00
|
|
|
{
|
|
|
|
if ( !instructions_ ) {
|
|
|
|
auto p{ NewOwned< T_InstrListNode >( *this ) };
|
|
|
|
instructions_ = p.get( );
|
|
|
|
children_.add( std::move( p ) );
|
|
|
|
}
|
|
|
|
return *instructions_;
|
|
|
|
}
|
2017-11-11 09:54:38 +01:00
|
|
|
|
2017-11-11 12:00:20 +01:00
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
|
2017-11-15 18:44:34 +01:00
|
|
|
T_Optional< ebcl::T_SRDLocation > addLocalVariable(
|
2017-11-11 09:54:38 +01:00
|
|
|
T_String const& name ,
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDLocation const& location ) noexcept;
|
2017-11-11 12:00:20 +01:00
|
|
|
|
2017-11-12 17:01:13 +01:00
|
|
|
uint32_t locals( ) const noexcept
|
|
|
|
{ return locals_.size( ); }
|
2017-11-11 12:00:20 +01:00
|
|
|
bool hasLocal( T_String const& id ) const noexcept
|
|
|
|
{ return locals_.contains( id ); }
|
|
|
|
|
|
|
|
bool isArgument( T_String const& id ) const noexcept
|
|
|
|
{
|
|
|
|
auto const* const ptr( locals_.get( id ) );
|
|
|
|
return ptr && ptr->argument;
|
|
|
|
}
|
2017-11-11 15:05:20 +01:00
|
|
|
|
|
|
|
uint32_t getLocalIndex(
|
|
|
|
T_String const& name ) const noexcept
|
|
|
|
{ return locals_.indexOf( name ); }
|
|
|
|
|
|
|
|
T_String const& getLocalName(
|
|
|
|
const uint32_t index ) const noexcept
|
|
|
|
{ return locals_[ index ].name; }
|
2017-12-17 09:55:53 +01:00
|
|
|
ebcl::T_SRDLocation const& getLocalLocation(
|
|
|
|
const uint32_t index ) const noexcept
|
|
|
|
{ return locals_[ index ].location; }
|
2017-11-11 15:05:20 +01:00
|
|
|
|
|
|
|
E_DataType getLocalType(
|
|
|
|
T_String const& name ) const noexcept
|
|
|
|
{ return locals_.get( name )->type; }
|
|
|
|
E_DataType getLocalType(
|
|
|
|
const uint32_t index ) const noexcept
|
|
|
|
{ return locals_[ index ].type; }
|
|
|
|
|
|
|
|
void setLocalType(
|
|
|
|
const uint32_t index ,
|
|
|
|
const E_DataType type ) noexcept
|
|
|
|
{ locals_[ index ].type = type; }
|
2017-12-17 09:55:53 +01:00
|
|
|
|
|
|
|
void removeLocal( T_String const& name ) noexcept
|
|
|
|
{ locals_.remove( name ); }
|
2017-11-06 10:15:38 +01:00
|
|
|
};
|
2017-11-06 17:09:05 +01:00
|
|
|
using P_InstrListNode = T_OwnPtr< T_InstrListNode >;
|
2017-11-06 10:15:38 +01:00
|
|
|
|
2017-11-10 23:09:36 +01:00
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
|
2017-11-06 10:15:38 +01:00
|
|
|
// Root node, keeps track of the whole tree and related data (function table,
|
|
|
|
// assets...)
|
|
|
|
class T_RootNode : public A_Node
|
|
|
|
{
|
|
|
|
private:
|
2017-12-13 21:44:50 +01:00
|
|
|
T_KeyValueTable< T_String , uint32_t > functions_;
|
2017-11-06 10:15:38 +01:00
|
|
|
|
|
|
|
public:
|
|
|
|
T_RootNode( ) noexcept;
|
|
|
|
|
2017-11-06 14:06:21 +01:00
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
|
2017-11-06 10:15:38 +01:00
|
|
|
// Return type for addFunction. We'll always return a reference to a
|
|
|
|
// function node (which may or may not be the same as the initial one,
|
|
|
|
// if there were duplicates), and we'll return the location of the
|
|
|
|
// initial function in the case of a duplicate.
|
|
|
|
struct T_AddFunctionResult
|
|
|
|
{
|
|
|
|
A_FuncNode& function;
|
2017-11-15 18:44:34 +01:00
|
|
|
T_Optional< ebcl::T_SRDLocation > dupLocation;
|
2017-11-06 10:15:38 +01:00
|
|
|
|
|
|
|
T_AddFunctionResult( A_FuncNode& function ) noexcept
|
|
|
|
: function{ function } , dupLocation{}
|
|
|
|
{}
|
|
|
|
|
|
|
|
T_AddFunctionResult( A_FuncNode& function ,
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDLocation const& dupLocation ) noexcept
|
2017-11-06 10:15:38 +01:00
|
|
|
: function{ function } , dupLocation{ dupLocation }
|
|
|
|
{}
|
|
|
|
};
|
|
|
|
|
|
|
|
// Attempts to add a function. If the function is already present in
|
|
|
|
// the table, the result will be set up with the previous declaration's
|
|
|
|
// location, and the specified function will not be modified (a duplicate
|
|
|
|
// entry will be added to the table instead).
|
|
|
|
T_AddFunctionResult addFunction(
|
|
|
|
T_OwnPtr< A_FuncNode >& function ) noexcept;
|
2017-11-06 14:06:21 +01:00
|
|
|
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
|
|
|
|
bool hasFunction( T_String const& name ) noexcept
|
|
|
|
{ return functions_.contains( name ); }
|
|
|
|
bool hasInit( ) noexcept
|
|
|
|
{ return hasFunction( "*init*" ); }
|
|
|
|
bool hasFrame( ) noexcept
|
|
|
|
{ return hasFunction( "*frame*" ); }
|
2017-11-07 09:10:17 +01:00
|
|
|
|
|
|
|
uint32_t nFunctions( ) const noexcept
|
|
|
|
{ return functions_.size( ); }
|
2017-12-13 21:44:50 +01:00
|
|
|
|
2017-11-07 13:24:01 +01:00
|
|
|
int32_t functionIndex( T_String const& name ) const noexcept
|
2017-12-13 21:44:50 +01:00
|
|
|
{
|
|
|
|
auto const* const ip{ functions_.get( name ) };
|
|
|
|
return ip ? *ip : -1;
|
|
|
|
}
|
|
|
|
|
2017-11-07 09:10:17 +01:00
|
|
|
A_FuncNode& function( const uint32_t index ) const noexcept
|
2017-12-13 21:44:50 +01:00
|
|
|
{ return dynamic_cast< A_FuncNode& >( *child( index ) ); }
|
2017-11-30 17:56:37 +01:00
|
|
|
|
|
|
|
void removeFunction( T_String const& name ) noexcept
|
2017-12-13 21:44:50 +01:00
|
|
|
{
|
|
|
|
auto const* const ip{ functions_.get( name ) };
|
|
|
|
if ( !ip ) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
const auto i{ *ip };
|
|
|
|
functions_.remove( name );
|
|
|
|
children_.removeSwap( i );
|
|
|
|
if ( i < children_.size( ) ) {
|
|
|
|
functions_.update( function( i ).name( ) , i );
|
|
|
|
}
|
|
|
|
}
|
2017-11-06 10:15:38 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
// Init & frame functions
|
|
|
|
class T_SpecialFuncNode : public A_FuncNode
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
T_SpecialFuncNode(
|
|
|
|
bool isInit ,
|
2017-11-08 12:29:03 +01:00
|
|
|
T_RootNode& parent ) noexcept
|
|
|
|
: A_FuncNode( isInit , &parent )
|
|
|
|
{ }
|
2017-11-06 10:15:38 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
// Normal functions
|
|
|
|
class T_FuncNode : public A_FuncNode
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
T_FuncNode( T_String const& name ,
|
2017-11-08 12:29:03 +01:00
|
|
|
T_RootNode& parent ) noexcept
|
|
|
|
: A_FuncNode( name , &parent )
|
|
|
|
{ }
|
2017-11-06 10:15:38 +01:00
|
|
|
|
|
|
|
// Add an argument. If the argument is a duplicate, return the location
|
|
|
|
// of the initial argument.
|
2017-11-15 18:44:34 +01:00
|
|
|
T_Optional< ebcl::T_SRDLocation > addArgument(
|
|
|
|
ebcl::T_SRDToken const& token ) noexcept;
|
2017-11-07 13:24:01 +01:00
|
|
|
|
2017-11-11 09:54:38 +01:00
|
|
|
uint32_t arguments( ) const noexcept;
|
2017-11-06 10:15:38 +01:00
|
|
|
};
|
|
|
|
|
2017-11-06 16:38:04 +01:00
|
|
|
|
2017-11-10 23:09:36 +01:00
|
|
|
/*= GENERAL / FLOW CONTROL INSTRUCTIONS ========================================*/
|
2017-11-06 14:06:21 +01:00
|
|
|
|
2017-11-07 07:43:18 +01:00
|
|
|
// Function call
|
2017-11-06 19:00:02 +01:00
|
|
|
class T_CallInstrNode : public A_InstructionNode
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
T_String id_;
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDLocation idLocation_;
|
2017-11-06 19:00:02 +01:00
|
|
|
|
|
|
|
public:
|
|
|
|
T_CallInstrNode( T_InstrListNode& parent ,
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDToken const& idToken ) noexcept
|
2017-11-06 19:00:02 +01:00
|
|
|
: A_InstructionNode( OP_CALL , parent ) ,
|
|
|
|
id_( idToken.stringValue( ) ) ,
|
|
|
|
idLocation_( idToken.location( ) )
|
|
|
|
{ }
|
|
|
|
|
|
|
|
void addArgument( P_ExpressionNode expr ) noexcept
|
|
|
|
{
|
|
|
|
if ( expr ) {
|
2017-12-13 21:44:50 +01:00
|
|
|
children_.add( NewOwned< T_ArgumentNode >(
|
2017-11-12 17:01:13 +01:00
|
|
|
*this , std::move( expr ) ) );
|
2017-11-06 19:00:02 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
T_String const& id( ) const noexcept
|
|
|
|
{ return id_; }
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDLocation const& idLocation( ) const noexcept
|
2017-11-06 19:00:02 +01:00
|
|
|
{ return idLocation_; }
|
|
|
|
|
2017-11-13 10:02:16 +01:00
|
|
|
T_ArgumentNode& argument( const uint32_t index ) const noexcept
|
2017-12-13 21:44:50 +01:00
|
|
|
{ return (T_ArgumentNode&) *child( index ); }
|
2017-11-06 19:00:02 +01:00
|
|
|
};
|
|
|
|
|
2017-11-06 17:09:05 +01:00
|
|
|
// Conditional instruction
|
|
|
|
class T_CondInstrNode : public A_InstructionNode
|
|
|
|
{
|
2017-11-12 11:13:38 +01:00
|
|
|
public:
|
|
|
|
class T_Expression : public A_Node
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
T_Expression( T_CondInstrNode& parent ,
|
|
|
|
P_ExpressionNode expr )
|
2017-12-13 21:44:50 +01:00
|
|
|
: A_Node( TN_CONDITION , &parent )
|
|
|
|
{
|
|
|
|
children_.add( std::move( expr ) );
|
|
|
|
}
|
2017-11-12 11:13:38 +01:00
|
|
|
|
|
|
|
A_ExpressionNode& expression( ) const noexcept
|
2017-12-13 21:44:50 +01:00
|
|
|
{ return (A_ExpressionNode&) *child( 0 ); }
|
2017-12-01 07:30:03 +01:00
|
|
|
|
|
|
|
void expression( P_ExpressionNode expr ) noexcept
|
2017-12-13 21:44:50 +01:00
|
|
|
{ assert( expr ); child( 0 ) = std::move( expr ); }
|
2017-11-12 11:13:38 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
class T_ValuedCase : public A_Node
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
int64_t value_;
|
|
|
|
|
|
|
|
public:
|
|
|
|
T_ValuedCase( T_CondInstrNode& parent ,
|
|
|
|
const int64_t value ,
|
|
|
|
P_InstrListNode il )
|
|
|
|
: A_Node( TN_CASE , &parent ) ,
|
2017-12-13 21:44:50 +01:00
|
|
|
value_( value )
|
|
|
|
{
|
|
|
|
children_.add( std::move( il ) );
|
|
|
|
}
|
2017-11-12 11:13:38 +01:00
|
|
|
|
|
|
|
int64_t value( ) const noexcept
|
|
|
|
{ return value_; }
|
|
|
|
T_InstrListNode& instructions( ) const noexcept
|
2017-12-13 21:44:50 +01:00
|
|
|
{ return (T_InstrListNode&) *child( 0 ); }
|
2017-11-12 11:13:38 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
class T_DefaultCase : public A_Node
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
T_DefaultCase( T_CondInstrNode& parent ,
|
|
|
|
P_InstrListNode il )
|
2017-12-13 21:44:50 +01:00
|
|
|
: A_Node( TN_DEFAULT , &parent )
|
|
|
|
{
|
|
|
|
children_.add( std::move( il ) );
|
|
|
|
}
|
2017-11-12 11:13:38 +01:00
|
|
|
|
|
|
|
T_InstrListNode& instructions( ) const noexcept
|
2017-12-13 21:44:50 +01:00
|
|
|
{ return (T_InstrListNode&) *child( 0 ); }
|
2017-11-12 11:13:38 +01:00
|
|
|
};
|
|
|
|
|
2017-11-06 17:09:05 +01:00
|
|
|
private:
|
2017-12-13 21:44:50 +01:00
|
|
|
T_Optional< uint32_t > expression_;
|
|
|
|
T_KeyValueTable< int64_t , uint32_t > cases_;
|
|
|
|
T_Optional< uint32_t > defaultCase_;
|
|
|
|
|
|
|
|
void handleRemoval( uint32_t idx ) noexcept;
|
2017-11-06 17:09:05 +01:00
|
|
|
|
|
|
|
public:
|
|
|
|
explicit T_CondInstrNode( T_InstrListNode& parent ) noexcept
|
|
|
|
: A_InstructionNode( OP_COND , parent )
|
|
|
|
{ }
|
|
|
|
|
2017-11-12 11:13:38 +01:00
|
|
|
void setExpression( P_ExpressionNode expression ) noexcept;
|
2017-11-06 17:09:05 +01:00
|
|
|
bool hasExpression( ) const noexcept
|
|
|
|
{ return bool( expression_ ); }
|
2017-11-12 11:13:38 +01:00
|
|
|
T_Expression& expression( ) const noexcept
|
2017-12-13 21:44:50 +01:00
|
|
|
{ return (T_Expression&) *child( *expression_ ); }
|
2017-11-06 17:09:05 +01:00
|
|
|
|
|
|
|
void setCase( const int64_t value ,
|
2017-11-12 11:13:38 +01:00
|
|
|
P_InstrListNode instrList ) noexcept;
|
2017-11-06 17:09:05 +01:00
|
|
|
void rmCase( const int64_t value ) noexcept
|
|
|
|
{ cases_.remove( value ); }
|
|
|
|
|
2017-11-12 11:13:38 +01:00
|
|
|
uint32_t nCases( ) const noexcept
|
|
|
|
{ return cases_.size( ); }
|
2017-12-13 21:44:50 +01:00
|
|
|
T_Array< int64_t > const& cases( ) const noexcept
|
2017-11-06 17:09:05 +01:00
|
|
|
{ return cases_.keys( ); }
|
|
|
|
bool hasCase( const int64_t value ) const noexcept
|
|
|
|
{ return cases_.contains( value ); }
|
2017-11-12 11:13:38 +01:00
|
|
|
T_ValuedCase& getCase( const int64_t value ) const noexcept
|
2017-12-13 21:44:50 +01:00
|
|
|
{ return (T_ValuedCase&) *child( *cases_.get( value ) ); }
|
2017-11-12 11:13:38 +01:00
|
|
|
T_ValuedCase& getCaseByIndex(
|
|
|
|
const uint32_t index ) const noexcept
|
2017-12-13 21:44:50 +01:00
|
|
|
{ return (T_ValuedCase&) *child( cases_[ index ] ); }
|
2017-11-06 17:09:05 +01:00
|
|
|
|
2017-11-12 11:13:38 +01:00
|
|
|
void setDefaultCase( P_InstrListNode defaultCase ) noexcept;
|
2017-11-06 17:09:05 +01:00
|
|
|
bool hasDefaultCase( ) const noexcept
|
|
|
|
{ return bool( defaultCase_ ); }
|
2017-11-12 11:13:38 +01:00
|
|
|
T_DefaultCase& defaultCase( ) const noexcept
|
2017-12-13 21:44:50 +01:00
|
|
|
{ return (T_DefaultCase&) *child( *defaultCase_ ); }
|
2017-11-06 17:09:05 +01:00
|
|
|
};
|
|
|
|
|
2017-11-10 23:09:36 +01:00
|
|
|
// Local variable declarations
|
|
|
|
class T_LocalsInstrNode : public A_InstructionNode
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
T_AutoArray< T_String , 8 > vars_;
|
2017-11-15 18:44:34 +01:00
|
|
|
T_AutoArray< ebcl::T_SRDLocation , 8 > varLocs_;
|
2017-11-10 23:09:36 +01:00
|
|
|
|
|
|
|
public:
|
|
|
|
T_LocalsInstrNode( T_InstrListNode& parent ) noexcept
|
|
|
|
: A_InstructionNode( OP_LOCALS , parent )
|
|
|
|
{ }
|
|
|
|
|
2017-11-15 18:44:34 +01:00
|
|
|
T_Optional< ebcl::T_SRDLocation > addVariable(
|
|
|
|
ebcl::T_SRDToken const& token ) noexcept;
|
2017-11-10 23:09:36 +01:00
|
|
|
|
|
|
|
uint32_t variables( ) const noexcept
|
|
|
|
{ return vars_.size( ); }
|
|
|
|
|
|
|
|
T_String const& varName(
|
|
|
|
const uint32_t index ) const noexcept
|
|
|
|
{ return vars_[ index ]; }
|
|
|
|
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDLocation const& varLocation(
|
2017-11-10 23:09:36 +01:00
|
|
|
const uint32_t index ) const noexcept
|
|
|
|
{ return varLocs_[ index ]; }
|
|
|
|
};
|
|
|
|
|
|
|
|
// Setting a global variable
|
|
|
|
class T_SetInstrNode : public A_InstructionNode
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
T_String id_;
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDLocation idLocation_;
|
2017-11-10 23:09:36 +01:00
|
|
|
|
|
|
|
public:
|
|
|
|
T_SetInstrNode( T_InstrListNode& parent ,
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDToken const& idToken ) noexcept
|
2017-11-10 23:09:36 +01:00
|
|
|
: A_InstructionNode( OP_SET , parent ) ,
|
|
|
|
id_( idToken.stringValue( ) ) ,
|
|
|
|
idLocation_( idToken.location( ) )
|
|
|
|
{ }
|
|
|
|
|
|
|
|
T_String const& id( ) const noexcept
|
|
|
|
{ return id_; }
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDLocation const& idLocation( ) const noexcept
|
2017-11-10 23:09:36 +01:00
|
|
|
{ return idLocation_; }
|
|
|
|
|
2017-12-23 17:18:29 +01:00
|
|
|
void id( T_String const& nid ) noexcept
|
|
|
|
{ id_ = nid; }
|
|
|
|
|
2017-11-10 23:09:36 +01:00
|
|
|
void setExpression( P_ExpressionNode expression ) noexcept
|
2017-12-13 21:44:50 +01:00
|
|
|
{
|
|
|
|
if ( children_.size( ) ) {
|
|
|
|
child( 0 ) = std::move( expression );
|
|
|
|
} else {
|
|
|
|
children_.add( std::move( expression ) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-10 23:09:36 +01:00
|
|
|
bool hasExpression( ) const noexcept
|
2017-12-13 21:44:50 +01:00
|
|
|
{ return children_.size( ) && child( 0 ); }
|
2017-11-10 23:09:36 +01:00
|
|
|
A_ExpressionNode& expression( ) const noexcept
|
2017-12-13 21:44:50 +01:00
|
|
|
{ return (A_ExpressionNode&) *child( 0 ); }
|
2017-11-10 23:09:36 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/*= RESOURCE DEFINITION INSTRUCTIONS =========================================*/
|
|
|
|
|
|
|
|
// Base class
|
|
|
|
class A_ResourceDefInstrNode : public A_InstructionNode
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
T_String id_;
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDLocation idLocation_;
|
2017-11-10 23:09:36 +01:00
|
|
|
E_DataType dataType_;
|
|
|
|
|
|
|
|
protected:
|
|
|
|
A_ResourceDefInstrNode(
|
|
|
|
const E_Type type ,
|
|
|
|
T_InstrListNode& parent ,
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDToken const& identifier ,
|
2017-11-10 23:09:36 +01:00
|
|
|
const E_DataType dataType ) noexcept
|
|
|
|
: A_InstructionNode( type , parent , E_InstrRestriction::FRAME ) ,
|
|
|
|
id_( identifier.stringValue( ) ) ,
|
|
|
|
idLocation_( identifier.location( ) ) ,
|
|
|
|
dataType_( dataType )
|
|
|
|
{ }
|
|
|
|
|
|
|
|
public:
|
|
|
|
T_String const& id( ) const noexcept
|
|
|
|
{ return id_; }
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDLocation const& idLocation( ) const noexcept
|
2017-11-10 23:09:36 +01:00
|
|
|
{ return idLocation_; }
|
|
|
|
|
|
|
|
E_DataType dataType( ) const noexcept
|
|
|
|
{ return dataType_; }
|
|
|
|
};
|
|
|
|
|
|
|
|
/*------------------------------------------------------------------------------*/
|
|
|
|
|
2017-11-10 10:15:56 +01:00
|
|
|
// Framebuffer definition instruction
|
2017-11-10 23:09:36 +01:00
|
|
|
class T_FramebufferInstrNode : public A_ResourceDefInstrNode
|
2017-11-10 10:15:56 +01:00
|
|
|
{
|
2017-11-13 14:41:03 +01:00
|
|
|
public:
|
|
|
|
class T_Attachment : public A_Node
|
2017-11-10 20:38:17 +01:00
|
|
|
{
|
2017-11-13 14:41:03 +01:00
|
|
|
private:
|
|
|
|
bool depth_;
|
|
|
|
T_String id_;
|
|
|
|
|
|
|
|
public:
|
|
|
|
T_Attachment( T_FramebufferInstrNode& parent ,
|
|
|
|
const bool depth ,
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDToken const& texId ,
|
2017-11-13 14:41:03 +01:00
|
|
|
P_ExpressionNode lod = { } ) noexcept
|
|
|
|
: A_Node( TN_FBATT , &parent ) ,
|
|
|
|
depth_( depth ) ,
|
|
|
|
id_( texId.stringValue( ) )
|
|
|
|
{
|
|
|
|
location() = texId.location( );
|
|
|
|
if ( lod ) {
|
2017-12-13 21:44:50 +01:00
|
|
|
children_.add( NewOwned< T_ArgumentNode >(
|
|
|
|
*this , std::move( lod ) ) );
|
2017-11-13 14:41:03 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool isDepth( ) const noexcept
|
|
|
|
{ return depth_; }
|
|
|
|
|
|
|
|
T_String const& id( ) const noexcept
|
|
|
|
{ return id_; }
|
|
|
|
|
|
|
|
T_ArgumentNode* lod( ) const noexcept
|
2017-12-13 21:44:50 +01:00
|
|
|
{ return (T_ArgumentNode*) ( children_.size( )
|
|
|
|
? child( 0 ).get( ) : nullptr ); }
|
2017-12-23 17:18:29 +01:00
|
|
|
|
|
|
|
void id( T_String const& nid ,
|
|
|
|
ebcl::T_SRDLocation const& loc ) noexcept
|
|
|
|
{
|
|
|
|
id_ = nid;
|
|
|
|
location( ) = loc;
|
|
|
|
}
|
2017-11-10 20:38:17 +01:00
|
|
|
};
|
|
|
|
|
2017-11-13 14:41:03 +01:00
|
|
|
private:
|
2017-12-13 21:44:50 +01:00
|
|
|
T_AutoArray< uint32_t , 16 > colorAttachments_;
|
|
|
|
T_Optional< uint32_t > depthAttachment_;
|
2017-11-10 10:15:56 +01:00
|
|
|
|
2017-11-10 20:38:17 +01:00
|
|
|
bool hasAttachment( T_String const& name ) const noexcept;
|
2017-11-10 10:15:56 +01:00
|
|
|
|
|
|
|
public:
|
|
|
|
T_FramebufferInstrNode( T_InstrListNode& parent ,
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDToken const& identifier ) noexcept
|
2017-11-10 23:09:36 +01:00
|
|
|
: A_ResourceDefInstrNode( OP_FRAMEBUFFER , parent ,
|
|
|
|
identifier , E_DataType::FRAMEBUFFER )
|
2017-11-10 10:15:56 +01:00
|
|
|
{ }
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
|
2017-11-15 18:44:34 +01:00
|
|
|
bool addColorAttachment( ebcl::T_SRDToken const& id ,
|
2017-11-10 20:38:17 +01:00
|
|
|
P_ExpressionNode lod = {} ) noexcept;
|
|
|
|
|
2017-11-10 10:15:56 +01:00
|
|
|
uint32_t colorAttachments( ) const noexcept
|
2017-11-10 20:38:17 +01:00
|
|
|
{ return colorAttachments_.size( ); }
|
2017-11-10 10:15:56 +01:00
|
|
|
|
2017-11-13 14:41:03 +01:00
|
|
|
T_Attachment& colorAttachment(
|
2017-11-10 10:15:56 +01:00
|
|
|
const uint32_t index ) const noexcept
|
2017-12-13 21:44:50 +01:00
|
|
|
{ return (T_Attachment&) *child( colorAttachments_[ index ] ); }
|
2017-11-10 10:15:56 +01:00
|
|
|
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
|
2017-11-15 18:44:34 +01:00
|
|
|
bool setDepthAttachment( ebcl::T_SRDToken const& token ,
|
2017-11-10 20:38:17 +01:00
|
|
|
P_ExpressionNode lod = {} ) noexcept;
|
2017-11-10 10:15:56 +01:00
|
|
|
|
2017-11-13 14:41:03 +01:00
|
|
|
T_Attachment* depthAttachment( ) const noexcept
|
2017-12-13 21:44:50 +01:00
|
|
|
{ return depthAttachment_
|
|
|
|
? ((T_Attachment*) child( *depthAttachment_ ).get( ) )
|
|
|
|
: nullptr; }
|
2017-11-10 10:15:56 +01:00
|
|
|
};
|
|
|
|
|
2017-11-07 07:43:18 +01:00
|
|
|
// Input declaration
|
2017-11-10 23:09:36 +01:00
|
|
|
class T_InputInstrNode : public A_ResourceDefInstrNode
|
2017-11-07 07:43:18 +01:00
|
|
|
{
|
|
|
|
private:
|
|
|
|
float defValue_;
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDLocation dvLocation_;
|
2017-11-07 07:43:18 +01:00
|
|
|
|
|
|
|
public:
|
|
|
|
T_InputInstrNode( T_InstrListNode& parent ,
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDToken const& tName ) noexcept
|
2017-11-10 23:09:36 +01:00
|
|
|
: A_ResourceDefInstrNode( OP_INPUT , parent ,
|
|
|
|
tName , E_DataType::INPUT )
|
2017-11-07 07:43:18 +01:00
|
|
|
{}
|
|
|
|
|
|
|
|
T_InputInstrNode( T_InstrListNode& parent ,
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDToken const& tName ,
|
|
|
|
ebcl::T_SRDToken const& tDefault ) noexcept
|
2017-11-10 23:09:36 +01:00
|
|
|
: A_ResourceDefInstrNode( OP_INPUT , parent ,
|
|
|
|
tName , E_DataType::INPUT ) ,
|
2017-11-07 07:43:18 +01:00
|
|
|
defValue_( tDefault.floatValue( ) ) , dvLocation_( tDefault.location( ) )
|
|
|
|
{}
|
|
|
|
|
|
|
|
float defValue( ) const noexcept
|
|
|
|
{ return defValue_; }
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDLocation const& defValueLocation( ) const noexcept
|
2017-11-07 07:43:18 +01:00
|
|
|
{ return dvLocation_; }
|
|
|
|
};
|
|
|
|
|
2017-11-06 14:06:21 +01:00
|
|
|
// Pipeline declaration instruction
|
2017-11-10 23:09:36 +01:00
|
|
|
class T_PipelineInstrNode : public A_ResourceDefInstrNode
|
2017-11-06 14:06:21 +01:00
|
|
|
{
|
|
|
|
private:
|
|
|
|
T_StaticArray< T_String , 6 > pids_;
|
2017-11-15 18:44:34 +01:00
|
|
|
T_StaticArray< ebcl::T_SRDLocation , 6 > pidLocations_;
|
2017-11-06 14:06:21 +01:00
|
|
|
|
|
|
|
public:
|
|
|
|
T_PipelineInstrNode(
|
|
|
|
T_InstrListNode& parent ,
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDToken const& idToken ) noexcept
|
2017-11-10 23:09:36 +01:00
|
|
|
: A_ResourceDefInstrNode( OP_PIPELINE , parent ,
|
|
|
|
idToken , E_DataType::PIPELINE )
|
2017-11-08 12:29:03 +01:00
|
|
|
{ }
|
|
|
|
|
2017-11-06 14:06:21 +01:00
|
|
|
// Add a program identifier. The token is assumed to be a valid word,
|
|
|
|
// and the list of programs is assumed not to be full. If the identifer
|
|
|
|
// is already in the pipeline's list, the location of the first
|
|
|
|
// occurrence will be returned.
|
2017-11-15 18:44:34 +01:00
|
|
|
T_Optional< ebcl::T_SRDLocation > addProgram(
|
|
|
|
ebcl::T_SRDToken const& pidToken ) noexcept;
|
2017-11-06 14:06:21 +01:00
|
|
|
|
|
|
|
uint32_t size( ) const noexcept
|
|
|
|
{ return pids_.size( ); }
|
|
|
|
|
|
|
|
T_String const& program( const uint32_t index ) const noexcept
|
|
|
|
{ return pids_[ index ]; }
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDLocation const& pLocation( const uint32_t index ) const noexcept
|
2017-11-06 14:06:21 +01:00
|
|
|
{ return pidLocations_[ index ]; }
|
2017-12-23 17:18:29 +01:00
|
|
|
|
|
|
|
void program( const uint32_t index ,
|
|
|
|
T_String const& id ,
|
|
|
|
ebcl::T_SRDLocation const& location ) noexcept
|
|
|
|
{
|
|
|
|
pids_[ index ] = id;
|
|
|
|
pidLocations_[ index ] = location;
|
|
|
|
}
|
2017-11-06 14:06:21 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
// Program loader instruction
|
2017-11-10 23:09:36 +01:00
|
|
|
class T_ProgramInstrNode : public A_ResourceDefInstrNode
|
2017-11-06 14:06:21 +01:00
|
|
|
{
|
|
|
|
private:
|
2017-12-29 11:33:15 +01:00
|
|
|
T_FSPath path_;
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDLocation pathLocation_;
|
2017-11-06 14:06:21 +01:00
|
|
|
|
|
|
|
public:
|
|
|
|
T_ProgramInstrNode(
|
|
|
|
T_InstrListNode& parent ,
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDToken const& idToken ,
|
2017-12-29 11:33:15 +01:00
|
|
|
ebcl::T_FSPath path ,
|
|
|
|
ebcl::T_SRDLocation const& pathLoc ) noexcept
|
2017-11-10 23:09:36 +01:00
|
|
|
: A_ResourceDefInstrNode( OP_PROGRAM , parent ,
|
|
|
|
idToken , E_DataType::PROGRAM ) ,
|
2017-12-29 11:33:15 +01:00
|
|
|
path_( std::move( path ) ) ,
|
|
|
|
pathLocation_( pathLoc )
|
2017-11-08 12:29:03 +01:00
|
|
|
{ }
|
2017-11-09 18:24:39 +01:00
|
|
|
|
2017-12-29 11:33:15 +01:00
|
|
|
T_FSPath const& path( ) const noexcept
|
2017-11-10 23:09:36 +01:00
|
|
|
{ return path_; }
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDLocation const& pathLocation( ) const noexcept
|
2017-11-10 23:09:36 +01:00
|
|
|
{ return pathLocation_; }
|
2017-11-06 14:06:21 +01:00
|
|
|
};
|
|
|
|
|
2017-11-10 17:18:29 +01:00
|
|
|
// Sampler definition
|
2017-11-10 23:09:36 +01:00
|
|
|
class T_SamplerInstrNode : public A_ResourceDefInstrNode
|
2017-11-10 17:18:29 +01:00
|
|
|
{
|
|
|
|
private:
|
|
|
|
struct T_Sampling_
|
|
|
|
{
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDLocation location;
|
2017-11-10 17:18:29 +01:00
|
|
|
E_TexSampling mode;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct T_Mipmaps_
|
|
|
|
{
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDLocation location;
|
2017-11-10 17:18:29 +01:00
|
|
|
T_Optional< E_TexSampling > mode;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct T_Wrapping_
|
|
|
|
{
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDLocation location;
|
2017-11-10 17:18:29 +01:00
|
|
|
E_TexWrap mode;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct T_LOD_
|
|
|
|
{
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDLocation location;
|
2017-12-14 07:29:39 +01:00
|
|
|
T_Optional< uint32_t > min;
|
|
|
|
T_Optional< uint32_t > max;
|
2017-11-10 17:18:29 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
T_Optional< T_Sampling_ > sampling_;
|
|
|
|
T_Optional< T_Mipmaps_ > mipmaps_;
|
|
|
|
T_Optional< T_Wrapping_ > wrapping_;
|
|
|
|
T_Optional< T_LOD_ > lod_;
|
|
|
|
|
|
|
|
public:
|
|
|
|
T_SamplerInstrNode(
|
|
|
|
T_InstrListNode& parent ,
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDToken const& id ) noexcept
|
2017-11-10 23:09:36 +01:00
|
|
|
: A_ResourceDefInstrNode( OP_SAMPLER , parent ,
|
|
|
|
id , E_DataType::SAMPLER )
|
2017-11-10 17:18:29 +01:00
|
|
|
{ }
|
|
|
|
|
|
|
|
// Attempt to set sampling mode, mipmap mode, wrapping mode or
|
|
|
|
// LOD minimal/maximal, returning the location of the previous
|
|
|
|
// definition if there was one.
|
2017-11-15 18:44:34 +01:00
|
|
|
T_Optional< ebcl::T_SRDLocation > setSampling(
|
2017-11-10 17:18:29 +01:00
|
|
|
E_TexSampling mode ,
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDLocation const& location ) noexcept;
|
|
|
|
T_Optional< ebcl::T_SRDLocation > setMipmapSampling(
|
2017-11-10 17:18:29 +01:00
|
|
|
E_TexSampling mode ,
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDLocation const& location ) noexcept;
|
|
|
|
T_Optional< ebcl::T_SRDLocation > setNoMipmap(
|
|
|
|
ebcl::T_SRDLocation const& location ) noexcept;
|
|
|
|
T_Optional< ebcl::T_SRDLocation > setWrapping(
|
2017-11-10 17:18:29 +01:00
|
|
|
E_TexWrap mode ,
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDLocation const& location ) noexcept;
|
|
|
|
T_Optional< ebcl::T_SRDLocation > setLOD(
|
|
|
|
ebcl::T_SRDLocation const& location ,
|
2017-11-10 17:18:29 +01:00
|
|
|
P_ExpressionNode min ,
|
|
|
|
P_ExpressionNode max ) noexcept;
|
|
|
|
|
|
|
|
// Get either the defined values or the defaults
|
|
|
|
E_TexSampling sampling( ) const noexcept
|
|
|
|
{ return sampling_ ? sampling_->mode : E_TexSampling::NEAREST; }
|
|
|
|
T_Optional< E_TexSampling > mipmap( ) const noexcept
|
|
|
|
{ return mipmaps_ ? mipmaps_->mode : T_Optional< E_TexSampling >{}; }
|
|
|
|
E_TexWrap wrapping( ) const noexcept
|
|
|
|
{ return wrapping_ ? wrapping_->mode : E_TexWrap::REPEAT; }
|
2017-12-14 07:29:39 +01:00
|
|
|
|
2017-11-13 18:16:48 +01:00
|
|
|
T_ArgumentNode* minLod( ) const noexcept
|
2017-12-14 07:29:39 +01:00
|
|
|
{ return ( T_ArgumentNode*) ( ( lod_ && lod_->min )
|
|
|
|
? child( *( lod_->min ) ).get( )
|
|
|
|
: nullptr ); }
|
2017-11-13 18:16:48 +01:00
|
|
|
T_ArgumentNode* maxLod( ) const noexcept
|
2017-12-14 07:29:39 +01:00
|
|
|
{ return ( T_ArgumentNode*) ( ( lod_ && lod_->max )
|
|
|
|
? child( *( lod_->max ) ).get( )
|
|
|
|
: nullptr ); }
|
2017-11-10 17:18:29 +01:00
|
|
|
};
|
|
|
|
|
2017-11-06 18:15:56 +01:00
|
|
|
// Texture definition
|
2017-11-10 23:09:36 +01:00
|
|
|
class T_TextureInstrNode : public A_ResourceDefInstrNode
|
2017-11-06 18:15:56 +01:00
|
|
|
{
|
|
|
|
private:
|
|
|
|
E_TexType type_;
|
|
|
|
|
|
|
|
public:
|
|
|
|
T_TextureInstrNode(
|
|
|
|
T_InstrListNode& parent ,
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDToken const& id ,
|
2017-11-08 12:29:03 +01:00
|
|
|
E_TexType type ) noexcept
|
2017-11-10 23:09:36 +01:00
|
|
|
: A_ResourceDefInstrNode( OP_TEXTURE , parent ,
|
|
|
|
id , E_DataType::TEXTURE ) ,
|
2017-11-08 12:29:03 +01:00
|
|
|
type_( type )
|
2017-12-14 07:29:39 +01:00
|
|
|
{
|
|
|
|
children_.add( P_ArgumentNode{} );
|
|
|
|
children_.add( P_ArgumentNode{} );
|
|
|
|
children_.add( P_ArgumentNode{} );
|
|
|
|
}
|
2017-11-06 18:15:56 +01:00
|
|
|
|
2017-11-13 10:02:16 +01:00
|
|
|
E_TexType texType( ) const noexcept
|
|
|
|
{ return type_; }
|
|
|
|
|
2017-11-06 18:15:56 +01:00
|
|
|
void setWidth( P_ExpressionNode width ) noexcept
|
2017-11-13 10:02:16 +01:00
|
|
|
{
|
|
|
|
if ( width ) {
|
2017-12-14 07:29:39 +01:00
|
|
|
child( 0 ) = NewOwned< T_ArgumentNode >(
|
|
|
|
*this , std::move( width ) );
|
2017-11-13 10:02:16 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void setHeight( P_ExpressionNode height ) noexcept
|
|
|
|
{
|
|
|
|
if ( height ) {
|
2017-12-14 07:29:39 +01:00
|
|
|
child( 1 ) = NewOwned< T_ArgumentNode >(
|
|
|
|
*this , std::move( height ) );
|
2017-11-13 10:02:16 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void setLODs( P_ExpressionNode lods ) noexcept
|
|
|
|
{
|
|
|
|
if ( lods ) {
|
2017-12-14 07:29:39 +01:00
|
|
|
child( 2 ) = NewOwned< T_ArgumentNode >(
|
|
|
|
*this , std::move( lods ) );
|
2017-11-13 10:02:16 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-06 18:15:56 +01:00
|
|
|
bool hasWidth( ) const noexcept
|
2017-12-14 07:29:39 +01:00
|
|
|
{ return bool( child( 0 ) ); }
|
2017-11-13 10:02:16 +01:00
|
|
|
T_ArgumentNode& width( ) const noexcept
|
2017-12-14 07:29:39 +01:00
|
|
|
{ return (T_ArgumentNode&) *child( 0 ); }
|
2017-11-06 18:15:56 +01:00
|
|
|
|
|
|
|
bool hasHeight( ) const noexcept
|
2017-12-14 07:29:39 +01:00
|
|
|
{ return bool( child( 1 ) ); }
|
2017-11-13 10:02:16 +01:00
|
|
|
T_ArgumentNode& height( ) const noexcept
|
2017-12-14 07:29:39 +01:00
|
|
|
{ return (T_ArgumentNode&) *child( 1 ); }
|
2017-11-10 20:38:17 +01:00
|
|
|
|
2017-11-13 10:02:16 +01:00
|
|
|
T_ArgumentNode* lods( ) const noexcept
|
2017-12-14 07:29:39 +01:00
|
|
|
{ return (T_ArgumentNode*) child( 2 ).get( ); }
|
2017-11-06 18:15:56 +01:00
|
|
|
};
|
|
|
|
|
2017-11-10 23:09:36 +01:00
|
|
|
|
|
|
|
/*= TOOL CONTROL INSTRUCTIONS ==================================================*/
|
|
|
|
|
|
|
|
// Output debugging
|
|
|
|
class T_OutputDebugInstrNode : public A_InstructionNode
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
T_String idTexture_;
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDLocation locTexture_;
|
2017-11-10 23:09:36 +01:00
|
|
|
E_ODbgMode mode_;
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDLocation locMode_;
|
2017-11-10 23:09:36 +01:00
|
|
|
T_String description_;
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDLocation locDescription_;
|
2017-11-10 23:09:36 +01:00
|
|
|
|
|
|
|
public:
|
|
|
|
T_OutputDebugInstrNode(
|
|
|
|
T_InstrListNode& parent ,
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDToken const& texture ,
|
2017-11-10 23:09:36 +01:00
|
|
|
const E_ODbgMode mode ,
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDLocation const& modeLocation ,
|
|
|
|
ebcl::T_SRDToken const& description ) noexcept;
|
2017-11-10 23:09:36 +01:00
|
|
|
|
|
|
|
T_String const& texture( ) const noexcept
|
|
|
|
{ return idTexture_; }
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDLocation const& textureLocation( ) const noexcept
|
2017-11-10 23:09:36 +01:00
|
|
|
{ return locTexture_; }
|
|
|
|
|
|
|
|
E_ODbgMode mode( ) const noexcept
|
|
|
|
{ return mode_; }
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDLocation const& modeLocation( ) const noexcept
|
2017-11-10 23:09:36 +01:00
|
|
|
{ return locMode_; }
|
|
|
|
|
|
|
|
T_String const& description( ) const noexcept
|
|
|
|
{ return description_; }
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDLocation const& descriptionLocation( ) const noexcept
|
2017-11-10 23:09:36 +01:00
|
|
|
{ return locDescription_; }
|
|
|
|
};
|
|
|
|
|
2017-11-17 20:33:56 +01:00
|
|
|
// User interface overrides for inputs
|
|
|
|
class T_OverridesInstrNode : public A_InstructionNode
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
T_OwnPtr< T_SyncOverrideSection > overrides_;
|
|
|
|
|
|
|
|
public:
|
|
|
|
T_OverridesInstrNode(
|
|
|
|
T_InstrListNode& parent ,
|
|
|
|
T_OwnPtr< T_SyncOverrideSection > overrides ) noexcept
|
|
|
|
: A_InstructionNode( OP_OVERRIDES , parent , E_InstrRestriction::FRAME ) ,
|
|
|
|
overrides_( std::move( overrides ) )
|
|
|
|
{ }
|
|
|
|
|
|
|
|
T_SyncOverrideSection& root( ) const noexcept
|
|
|
|
{ return *overrides_; }
|
2017-11-18 09:48:37 +01:00
|
|
|
|
|
|
|
T_OwnPtr< T_SyncOverrideSection > extractRoot( ) noexcept
|
|
|
|
{ return std::move( overrides_ ); }
|
2017-11-17 20:33:56 +01:00
|
|
|
};
|
|
|
|
|
2017-11-10 23:09:36 +01:00
|
|
|
// Profiling instruction
|
|
|
|
class T_ProfileInstrNode : public A_InstructionNode
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
T_String text_;
|
|
|
|
|
|
|
|
public:
|
|
|
|
T_ProfileInstrNode(
|
|
|
|
T_InstrListNode& parent ,
|
|
|
|
T_String const& text ) noexcept
|
|
|
|
: A_InstructionNode( OP_PROFILE , parent , E_InstrRestriction::INIT ) ,
|
2017-12-13 21:44:50 +01:00
|
|
|
text_( text )
|
|
|
|
{
|
|
|
|
children_.add( NewOwned< T_InstrListNode >( *this ) );
|
|
|
|
}
|
2017-11-10 23:09:36 +01:00
|
|
|
|
|
|
|
T_String const& text( ) const
|
|
|
|
{ return text_; }
|
|
|
|
|
2017-12-13 21:44:50 +01:00
|
|
|
T_InstrListNode& instructions( ) const noexcept
|
|
|
|
{ return (T_InstrListNode&) *child( 0 ); }
|
2017-11-10 23:09:36 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/*= RENDERING INSTRUCTIONS =====================================================*/
|
|
|
|
|
|
|
|
// Clear instruction
|
|
|
|
class T_ClearInstrNode : public A_InstructionNode
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
T_ClearInstrNode( T_InstrListNode& parent ) noexcept
|
|
|
|
: A_InstructionNode( OP_CLEAR , parent ,
|
|
|
|
E_InstrRestriction::INIT )
|
|
|
|
{ }
|
|
|
|
|
|
|
|
void addComponent( P_ExpressionNode expr ) noexcept
|
2017-11-13 10:02:16 +01:00
|
|
|
{
|
|
|
|
if ( expr ) {
|
2017-12-13 21:44:50 +01:00
|
|
|
children_.add( NewOwned< T_ArgumentNode >(
|
2017-11-13 10:02:16 +01:00
|
|
|
*this , std::move( expr ) ) );
|
|
|
|
}
|
|
|
|
}
|
2017-11-10 23:09:36 +01:00
|
|
|
|
2017-11-13 10:02:16 +01:00
|
|
|
T_ArgumentNode& component( const uint32_t index ) const noexcept
|
2017-12-13 21:44:50 +01:00
|
|
|
{ return (T_ArgumentNode&) *child( index ); }
|
2017-11-10 23:09:36 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
// Fullscreen quad instruction
|
|
|
|
class T_FullscreenInstrNode : public A_InstructionNode
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
T_FullscreenInstrNode( T_InstrListNode& parent ) noexcept
|
|
|
|
: A_InstructionNode( OP_FULLSCREEN , parent , E_InstrRestriction::INIT )
|
|
|
|
{ }
|
|
|
|
};
|
|
|
|
|
2017-12-23 18:40:36 +01:00
|
|
|
// 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 ===============================================*/
|
|
|
|
|
2017-11-10 23:09:36 +01:00
|
|
|
// Main output selection
|
|
|
|
class T_MainOutputInstrNode : public A_InstructionNode
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
T_MainOutputInstrNode( T_InstrListNode& parent ) noexcept
|
|
|
|
: A_InstructionNode( OP_MAINOUT , parent , E_InstrRestriction::INIT )
|
|
|
|
{ }
|
|
|
|
};
|
|
|
|
|
2017-11-09 23:20:48 +01:00
|
|
|
// Uniform setting instruction
|
|
|
|
class T_UniformsInstrNode : public A_InstructionNode
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
bool integers_;
|
|
|
|
T_String progId_;
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDLocation progIdLocation_;
|
2017-11-09 23:20:48 +01:00
|
|
|
uint32_t uloc_;
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDLocation ulocLocation_;
|
2017-11-09 23:20:48 +01:00
|
|
|
|
|
|
|
public:
|
|
|
|
T_UniformsInstrNode( T_InstrListNode& parent ,
|
|
|
|
const bool integers ,
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDToken const& prog ,
|
|
|
|
ebcl::T_SRDToken const& loc ) noexcept
|
2017-12-13 21:44:50 +01:00
|
|
|
: A_InstructionNode{ OP_UNIFORMS , parent } , integers_{ integers } ,
|
|
|
|
progId_{ prog.stringValue( ) } , progIdLocation_{ prog.location( ) } ,
|
|
|
|
uloc_{ (uint32_t)loc.longValue( ) } , ulocLocation_{ loc.location( ) }
|
2017-11-09 23:20:48 +01:00
|
|
|
{ }
|
|
|
|
|
|
|
|
bool integers( ) const noexcept
|
|
|
|
{ return integers_; }
|
|
|
|
|
|
|
|
T_String const& progId( ) const noexcept
|
|
|
|
{ return progId_; }
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDLocation const& progIdLocation( ) const noexcept
|
2017-11-09 23:20:48 +01:00
|
|
|
{ return progIdLocation_; }
|
2017-12-23 17:18:29 +01:00
|
|
|
void progId( T_String const& id ,
|
|
|
|
ebcl::T_SRDLocation const& location ) noexcept
|
|
|
|
{ progId_ = id; progIdLocation_ = location; }
|
2017-11-09 23:20:48 +01:00
|
|
|
|
|
|
|
uint32_t uloc( ) const noexcept
|
|
|
|
{ return uloc_; }
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDLocation const& ulocLocation( ) const noexcept
|
2017-11-09 23:20:48 +01:00
|
|
|
{ return ulocLocation_; }
|
|
|
|
|
|
|
|
void addValue( P_ExpressionNode value ) noexcept
|
|
|
|
{
|
|
|
|
if ( value ) {
|
2017-12-13 21:44:50 +01:00
|
|
|
children_.add( NewOwned< T_ArgumentNode >(
|
2017-11-13 17:20:45 +01:00
|
|
|
*this , std::move( value ) ) );
|
2017-11-09 23:20:48 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-13 17:20:45 +01:00
|
|
|
T_ArgumentNode& value( const uint32_t index ) const noexcept
|
2017-12-13 21:44:50 +01:00
|
|
|
{ return (T_ArgumentNode&) *child( index ); }
|
2017-11-09 23:20:48 +01:00
|
|
|
};
|
|
|
|
|
2017-11-09 18:24:39 +01:00
|
|
|
// Use-* instructions (framebuffers, programs, pipelines)
|
|
|
|
// Also serves as the base for use-texture
|
|
|
|
class T_UseInstrNode : public A_InstructionNode
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
enum E_Type {
|
|
|
|
FRAMEBUFFER , PIPELINE , PROGRAM , TEXTURE
|
|
|
|
};
|
|
|
|
|
|
|
|
private:
|
|
|
|
T_String id_;
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDLocation idLocation_;
|
2017-11-09 18:24:39 +01:00
|
|
|
|
|
|
|
public:
|
|
|
|
T_UseInstrNode( T_InstrListNode& parent ,
|
|
|
|
const E_Type type ,
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDToken const& identifier ) noexcept
|
2017-11-09 18:24:39 +01:00
|
|
|
: A_InstructionNode( ([type]() {
|
|
|
|
switch ( type ) {
|
|
|
|
case FRAMEBUFFER: return OP_USE_FRAMEBUFFER;
|
|
|
|
case PIPELINE: return OP_USE_PIPELINE;
|
|
|
|
case PROGRAM: return OP_USE_PROGRAM;
|
|
|
|
case TEXTURE: return OP_USE_TEXTURE;
|
|
|
|
}
|
|
|
|
std::abort( );
|
|
|
|
} )( ) , parent ) ,
|
|
|
|
id_( identifier.stringValue( ) ) ,
|
|
|
|
idLocation_( identifier.location( ) )
|
|
|
|
{ }
|
|
|
|
|
|
|
|
T_String const& id( ) const noexcept
|
|
|
|
{ return id_; }
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDLocation const& idLocation( ) const noexcept
|
2017-11-09 18:24:39 +01:00
|
|
|
{ return idLocation_; }
|
2017-12-23 17:18:29 +01:00
|
|
|
void id( T_String const& nid ,
|
|
|
|
ebcl::T_SRDLocation const& location ) noexcept
|
|
|
|
{ id_ = nid; idLocation_ = location; }
|
2017-11-09 18:24:39 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
// Texture/sampler use instructions
|
|
|
|
class T_UseTextureInstrNode : public T_UseInstrNode
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
uint32_t bank_;
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDLocation bankLocation_;
|
2017-11-09 18:24:39 +01:00
|
|
|
T_String samplerId_;
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDLocation samplerIdLocation_;
|
2017-11-09 18:24:39 +01:00
|
|
|
|
|
|
|
public:
|
|
|
|
T_UseTextureInstrNode( T_InstrListNode& parent ,
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDToken const& bank ,
|
|
|
|
ebcl::T_SRDToken const& identifier ,
|
|
|
|
ebcl::T_SRDToken const& sampler ) noexcept
|
2017-11-09 18:24:39 +01:00
|
|
|
: T_UseInstrNode( parent , TEXTURE , identifier ) ,
|
|
|
|
bank_( bank.longValue( ) ) ,
|
|
|
|
bankLocation_( bank.location( ) ) ,
|
|
|
|
samplerId_( sampler.stringValue( ) ) ,
|
|
|
|
samplerIdLocation_( sampler.location( ) )
|
|
|
|
{ }
|
|
|
|
|
|
|
|
uint32_t bank( ) const noexcept
|
|
|
|
{ return bank_; }
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDLocation const& bankLocation( ) const noexcept
|
2017-11-09 18:24:39 +01:00
|
|
|
{ return bankLocation_; }
|
|
|
|
|
|
|
|
T_String const& samplerId( ) const noexcept
|
|
|
|
{ return samplerId_; }
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDLocation const& samplerIdLocation( ) const noexcept
|
2017-11-09 18:24:39 +01:00
|
|
|
{ return samplerIdLocation_; }
|
2017-12-23 17:18:29 +01:00
|
|
|
void samplerId( T_String const& id ,
|
|
|
|
ebcl::T_SRDLocation const& location ) noexcept
|
|
|
|
{ samplerId_ = id; samplerIdLocation_ = location; }
|
2017-11-09 18:24:39 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
// Viewport instruction
|
|
|
|
class T_ViewportInstrNode : public A_InstructionNode
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
enum E_Parameter {
|
|
|
|
PX , PY , PWIDTH , PHEIGHT
|
|
|
|
};
|
|
|
|
|
|
|
|
public:
|
|
|
|
T_ViewportInstrNode( T_InstrListNode& parent ) noexcept
|
2017-11-10 22:12:24 +01:00
|
|
|
: A_InstructionNode( OP_VIEWPORT , parent ,
|
|
|
|
E_InstrRestriction::INIT )
|
2017-12-13 21:44:50 +01:00
|
|
|
{
|
|
|
|
children_.add( P_ArgumentNode{} );
|
|
|
|
children_.add( P_ArgumentNode{} );
|
|
|
|
children_.add( P_ArgumentNode{} );
|
|
|
|
children_.add( P_ArgumentNode{} );
|
|
|
|
}
|
2017-11-09 18:24:39 +01:00
|
|
|
|
2017-11-13 17:28:57 +01:00
|
|
|
void setParameter( const E_Parameter p , P_ExpressionNode value ) noexcept
|
|
|
|
{
|
|
|
|
if ( value ) {
|
2017-12-13 21:44:50 +01:00
|
|
|
children_[ int( p ) ] = NewOwned< T_ArgumentNode >(
|
2017-11-13 17:28:57 +01:00
|
|
|
*this , std::move( value ) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-09 18:24:39 +01:00
|
|
|
bool hasParameter( const E_Parameter p ) const noexcept
|
2017-12-13 21:44:50 +01:00
|
|
|
{ return bool( children_[ int( p ) ] ); }
|
2017-11-13 17:28:57 +01:00
|
|
|
T_ArgumentNode& parameter( const E_Parameter p ) const noexcept
|
2017-12-13 21:44:50 +01:00
|
|
|
{ return (T_ArgumentNode&) *children_[ int( p ) ]; }
|
2017-11-09 18:24:39 +01:00
|
|
|
};
|
|
|
|
|
2017-12-24 11:10:38 +01:00
|
|
|
// Image unit binding
|
|
|
|
class T_ImageInstrNode : public A_InstructionNode
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
enum class E_AccessMode
|
|
|
|
{
|
|
|
|
READ ,
|
|
|
|
WRITE
|
|
|
|
};
|
|
|
|
using T_AccessMode = T_Flags< E_AccessMode >;
|
|
|
|
|
|
|
|
enum E_Parameter {
|
|
|
|
P_UNIT , P_LEVEL , P_LAYER
|
|
|
|
};
|
|
|
|
|
|
|
|
private:
|
|
|
|
T_AccessMode accessMode_ = { };
|
|
|
|
T_String id_;
|
|
|
|
ebcl::T_SRDLocation idLocation_;
|
|
|
|
|
|
|
|
public:
|
|
|
|
T_ImageInstrNode( T_InstrListNode& parent ) noexcept
|
|
|
|
: A_InstructionNode( OP_IMAGE , parent )
|
|
|
|
{
|
|
|
|
children_.add( P_ArgumentNode{} );
|
|
|
|
children_.add( P_ArgumentNode{} );
|
|
|
|
children_.add( P_ArgumentNode{} );
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
|
|
|
T_String const& id( ) const noexcept
|
|
|
|
{ return id_; }
|
|
|
|
ebcl::T_SRDLocation const& idLocation( ) const noexcept
|
|
|
|
{ return idLocation_; }
|
|
|
|
void id( T_String const& nid ,
|
|
|
|
ebcl::T_SRDLocation const& location ) noexcept
|
|
|
|
{ id_ = nid; idLocation_ = location; }
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
|
|
|
T_AccessMode accessMode( ) const noexcept
|
|
|
|
{ return accessMode_; }
|
|
|
|
void accessMode( T_AccessMode mode ) noexcept
|
|
|
|
{ assert( mode ); accessMode_ = mode; }
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
|
|
|
void setParameter( const E_Parameter p ,
|
|
|
|
P_ExpressionNode value ) noexcept
|
|
|
|
{
|
|
|
|
if ( value ) {
|
|
|
|
children_[ int( p ) ] = NewOwned< T_ArgumentNode >(
|
|
|
|
*this , std::move( value ) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool hasParameter( const E_Parameter p ) const noexcept
|
|
|
|
{ return bool( children_[ int( p ) ] ); }
|
|
|
|
T_ArgumentNode& parameter( const E_Parameter p ) const noexcept
|
|
|
|
{ return (T_ArgumentNode&) *children_[ int( p ) ]; }
|
|
|
|
};
|
|
|
|
|
2017-11-10 23:09:36 +01:00
|
|
|
|
|
|
|
/*= EXPRESSIONS ==============================================================*/
|
2017-11-06 16:38:04 +01:00
|
|
|
|
|
|
|
// A constant value
|
|
|
|
class T_ConstantExprNode : public A_ExpressionNode
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
bool wasFloat_;
|
|
|
|
double vFloat_;
|
|
|
|
int64_t vInt_;
|
|
|
|
|
|
|
|
public:
|
|
|
|
T_ConstantExprNode( A_Node& parent ,
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDToken const& token ) noexcept
|
2017-11-08 12:29:03 +01:00
|
|
|
: A_ExpressionNode( EXPR_CONST , parent ) ,
|
2017-11-15 18:44:34 +01:00
|
|
|
wasFloat_( token.type( ) == ebcl::E_SRDTokenType::FLOAT ) ,
|
2017-11-08 12:29:03 +01:00
|
|
|
vFloat_( token.floatValue( ) ) ,
|
|
|
|
vInt_( token.longValue( ) )
|
|
|
|
{ location( ) = token.location( ); }
|
2017-11-06 16:38:04 +01:00
|
|
|
|
|
|
|
T_ConstantExprNode( A_Node& parent ,
|
2017-11-08 12:29:03 +01:00
|
|
|
int64_t value ) noexcept
|
2017-12-01 07:30:03 +01:00
|
|
|
: A_ExpressionNode( EXPR_CONST , parent ) , wasFloat_( false ) ,
|
|
|
|
vFloat_( value ) , vInt_( value )
|
2017-11-08 12:29:03 +01:00
|
|
|
{ }
|
|
|
|
|
2017-11-06 16:38:04 +01:00
|
|
|
T_ConstantExprNode( A_Node& parent ,
|
2017-11-08 12:29:03 +01:00
|
|
|
double value ) noexcept
|
|
|
|
: A_ExpressionNode( EXPR_CONST , parent ) , wasFloat_( true ) ,
|
|
|
|
vFloat_( value ) , vInt_( (int64_t) value )
|
|
|
|
{ }
|
2017-11-06 16:38:04 +01:00
|
|
|
|
|
|
|
bool wasFloat( ) const noexcept
|
|
|
|
{ return wasFloat_; }
|
|
|
|
double floatValue( ) const noexcept
|
|
|
|
{ return vFloat_; }
|
|
|
|
int64_t intValue( ) const noexcept
|
|
|
|
{ return vInt_; }
|
|
|
|
};
|
|
|
|
|
|
|
|
// An identifier used in an expression
|
|
|
|
class T_IdentifierExprNode : public A_ExpressionNode
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
T_String id_;
|
|
|
|
|
|
|
|
public:
|
|
|
|
T_IdentifierExprNode( A_Node& parent ,
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDToken const& token ) noexcept
|
2017-11-08 12:29:03 +01:00
|
|
|
: T_IdentifierExprNode( parent , token.stringValue( ) )
|
|
|
|
{ location( ) = token.location( ); }
|
|
|
|
|
2017-11-06 16:38:04 +01:00
|
|
|
T_IdentifierExprNode( A_Node& parent ,
|
2017-11-08 12:29:03 +01:00
|
|
|
T_String const& id ) noexcept
|
|
|
|
: A_ExpressionNode( EXPR_ID , parent ) , id_( id )
|
|
|
|
{ }
|
2017-11-06 16:38:04 +01:00
|
|
|
|
|
|
|
T_String const& id( ) const noexcept
|
|
|
|
{ return id_; }
|
|
|
|
};
|
|
|
|
|
2017-11-09 18:24:39 +01:00
|
|
|
// Access to an input value
|
|
|
|
class T_InputExprNode : public A_ExpressionNode
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
T_String id_;
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDLocation idLocation_;
|
2017-11-09 18:24:39 +01:00
|
|
|
|
|
|
|
public:
|
|
|
|
T_InputExprNode( A_Node& parent ,
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDToken const& token ) noexcept
|
2017-11-09 18:24:39 +01:00
|
|
|
: A_ExpressionNode( EXPR_INPUT , parent ) ,
|
|
|
|
id_( token.stringValue( ) ) ,
|
|
|
|
idLocation_( token.location( ) )
|
|
|
|
{ }
|
|
|
|
|
|
|
|
T_String const& id( ) const noexcept
|
|
|
|
{ return id_; }
|
2017-11-15 18:44:34 +01:00
|
|
|
ebcl::T_SRDLocation const& idLocation( ) const noexcept
|
2017-11-09 18:24:39 +01:00
|
|
|
{ return idLocation_; }
|
|
|
|
};
|
|
|
|
|
2017-11-06 16:38:04 +01:00
|
|
|
// A unary operator
|
|
|
|
class T_UnaryOperatorNode : public A_ExpressionNode
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
enum E_Operator {
|
|
|
|
NEG , INV , NOT ,
|
|
|
|
SIN , COS , TAN ,
|
|
|
|
SQRT , EXP , LN
|
|
|
|
};
|
|
|
|
|
|
|
|
private:
|
|
|
|
E_Operator op_;
|
|
|
|
|
|
|
|
public:
|
|
|
|
T_UnaryOperatorNode(
|
|
|
|
A_Node& parent ,
|
|
|
|
const E_Operator op ) noexcept;
|
|
|
|
|
|
|
|
E_Operator op( ) const noexcept
|
|
|
|
{ return op_; }
|
|
|
|
|
2017-11-06 17:09:05 +01:00
|
|
|
void setArgument( P_ExpressionNode argument ) noexcept
|
2017-12-13 21:44:50 +01:00
|
|
|
{ child( 0 ) = std::move( argument ); }
|
2017-11-06 16:38:04 +01:00
|
|
|
|
|
|
|
bool hasArgument( ) const noexcept
|
2017-12-13 21:44:50 +01:00
|
|
|
{ return bool( child( 0 ) ); }
|
2017-11-06 16:38:04 +01:00
|
|
|
|
2017-12-13 21:44:50 +01:00
|
|
|
A_ExpressionNode& argument( ) const noexcept
|
|
|
|
{ return (A_ExpressionNode&) *child( 0 ); }
|
2017-11-06 16:38:04 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
// A binary operator
|
|
|
|
class T_BinaryOperatorNode : public A_ExpressionNode
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
enum E_Operator {
|
|
|
|
ADD , SUB ,
|
|
|
|
MUL , DIV ,
|
|
|
|
POW ,
|
|
|
|
|
|
|
|
CMP_EQ , CMP_NE ,
|
|
|
|
CMP_GT , CMP_GE ,
|
|
|
|
CMP_LT , CMP_LE ,
|
|
|
|
};
|
|
|
|
|
|
|
|
private:
|
|
|
|
E_Operator op_;
|
|
|
|
|
|
|
|
public:
|
|
|
|
T_BinaryOperatorNode(
|
|
|
|
A_Node& parent ,
|
|
|
|
const E_Operator op ) noexcept;
|
|
|
|
|
|
|
|
E_Operator op( ) const noexcept
|
|
|
|
{ return op_; }
|
|
|
|
|
2017-11-06 17:09:05 +01:00
|
|
|
void setLeft( P_ExpressionNode left ) noexcept
|
2017-12-13 21:44:50 +01:00
|
|
|
{ child( 0 ) = std::move( left ); }
|
2017-11-06 17:09:05 +01:00
|
|
|
void setRight( P_ExpressionNode right ) noexcept
|
2017-12-13 21:44:50 +01:00
|
|
|
{ child( 1 ) = std::move( right ); }
|
2017-11-06 16:38:04 +01:00
|
|
|
|
|
|
|
bool hasLeft( ) const noexcept
|
2017-12-13 21:44:50 +01:00
|
|
|
{ return bool( child( 0 ) ); }
|
2017-11-06 16:38:04 +01:00
|
|
|
bool hasRight( ) const noexcept
|
2017-12-13 21:44:50 +01:00
|
|
|
{ return bool( child( 1 ) ); }
|
2017-11-06 16:38:04 +01:00
|
|
|
|
2017-12-13 21:44:50 +01:00
|
|
|
A_ExpressionNode& left( ) const noexcept
|
|
|
|
{ return (A_ExpressionNode&) *child( 0 ); }
|
|
|
|
A_ExpressionNode& right( ) const noexcept
|
|
|
|
{ return (A_ExpressionNode&) *child( 1 ); }
|
2017-11-06 16:38:04 +01:00
|
|
|
};
|
|
|
|
|
2017-11-10 23:09:36 +01:00
|
|
|
|
2017-11-15 18:44:34 +01:00
|
|
|
} // namespace opast
|