diff --git a/demo.srd b/demo.srd index 7f603ff..f239546 100644 --- a/demo.srd +++ b/demo.srd @@ -40,7 +40,7 @@ } (program prg-scene-p1 "scene.f.glsl") - # NOT IMPLEMENTED (set-uniforms prg-scene-p1 1 $vp-width $vp-height) + (uniforms prg-scene-p1 1 $vp-width $vp-height) (pipeline pl-scene-p1 prg-fullscreen prg-scene-p1) { NOT IMPLEMENTED @@ -51,30 +51,28 @@ (fn scene-main () (profiling "Scene render" - { NOT IMPLEMENTED - (set-uniforms prg-scene-p1 0 $time) - (set-uniforms prg-scene-p1 2 - (get-input "camera-pos-x") - (get-input "camera-pos-y") - (get-input "camera-pos-z") - ) - (set-uniforms prg-scene-p1 3 - (get-input "camera-lookat-x") - (get-input "camera-lookat-y") - (get-input "camera-lookat-z") - ) - (set-uniforms prg-scene-p1 4 - (get-input "camera-up-x") - (get-input "camera-up-y") - (get-input "camera-up-z") - ) - (set-uniforms prg-scene-p1 5 - (get-input "camera-nearplane") - ) - # FIXME MOAR UNIFORMS! - (use-pipeline pl-scene-p1) - (use-framebuffer rt-scene) - } + (uniforms prg-scene-p1 0 $time) + (uniforms prg-scene-p1 2 + (get-input camera-pos-x) + (get-input camera-pos-y) + (get-input camera-pos-z) + ) + (uniforms prg-scene-p1 3 + (get-input camera-lookat-x) + (get-input camera-lookat-y) + (get-input camera-lookat-z) + ) + (uniforms prg-scene-p1 4 + (get-input camera-up-x) + (get-input camera-up-y) + (get-input camera-up-z) + ) + (uniforms prg-scene-p1 5 + (get-input camera-nearplane) + ) + # FIXME MOAR UNIFORMS! + (use-pipeline pl-scene-p1) + (use-framebuffer rt-scene) (viewport 0 0 $vp-width $vp-height) (fullscreen) ) @@ -116,12 +114,10 @@ # Programs (program prg-dof-pass1 "dof-pass1.f.glsl") (program prg-dof-pass2 "dof-pass2.f.glsl") - { NOT IMPLEMENTED - (set-uniforms-integer prg-dof-pass1 0 1) - (set-uniforms-integer prg-dof-pass1 1 1) - (set-uniforms-integer prg-dof-pass2 0 1) - (set-uniforms-integer prg-dof-pass2 1 1) - } + (uniforms-i prg-dof-pass1 0 1) + (uniforms-i prg-dof-pass1 1 1) + (uniforms-i prg-dof-pass2 0 1) + (uniforms-i prg-dof-pass2 1 1) # Pipelines (pipeline pl-dof-pass1 prg-fullscreen prg-dof-pass1) @@ -147,16 +143,14 @@ ) (fn dof-set-uniforms (prog) - { NOT IMPLEMENTED - (set-uniforms prog 2 - (get-input dof-sharp-distance) - (get-input dof-sharp-range) - (get-input dof-falloff) - (get-input dof-max-blur) - ) - (set-uniforms prog 3 (get-input dof-samples)) - (set-uniforms prog 4 $vp-width $vp-height $time) - } + (uniforms prog 2 + (get-input dof-sharp-distance) + (get-input dof-sharp-range) + (get-input dof-falloff) + (get-input dof-max-blur) + ) + (uniforms prog 3 (get-input dof-samples)) + (uniforms prog 4 $vp-width $vp-height $time) ) (fn dof-main (in-image in-depth) diff --git a/opast.cc b/opast.cc index b6437c5..e71f223 100644 --- a/opast.cc +++ b/opast.cc @@ -171,6 +171,16 @@ A_Node* opast::ASTVisitorBrowser( break; } + // Uniforms instruction + case A_Node::OP_UNIFORMS: + { + auto& n( (T_UniformsInstrNode&) node ); + if ( child < n.values( ) ) { + return &n.value( child ); + } + break; + } + // Viewport instruction case A_Node::OP_VIEWPORT: { diff --git a/opast.hh b/opast.hh index 092b833..6cac424 100644 --- a/opast.hh +++ b/opast.hh @@ -1,7 +1,4 @@ #pragma once -#ifndef REAL_BUILD -# include "externals.hh" -#endif #include "texture.hh" #include @@ -32,6 +29,7 @@ class A_Node OP_PROGRAM , // Shader program declaration OP_SET , // Set instruction OP_TEXTURE , // Define texture + OP_UNIFORMS , // Set uniforms OP_VIEWPORT , // Set viewport // "Use-" instructions OP_USE_FRAMEBUFFER , @@ -580,6 +578,53 @@ class T_TextureInstrNode : public A_InstructionNode { return *height_; } }; +// Uniform setting instruction +class T_UniformsInstrNode : public A_InstructionNode +{ + private: + bool integers_; + T_String progId_; + T_SRDLocation progIdLocation_; + uint32_t uloc_; + T_SRDLocation ulocLocation_; + T_StaticArray< P_ExpressionNode , 4 > values_; + + public: + T_UniformsInstrNode( T_InstrListNode& parent , + const bool integers , + T_SRDToken const& prog , + T_SRDToken const& loc ) noexcept + : A_InstructionNode( OP_UNIFORMS , parent ) , integers_( integers ) , + progId_( prog.stringValue( ) ) , progIdLocation_( prog.location( ) ) , + uloc_( loc.longValue( ) ) , ulocLocation_( loc.location( ) ) + { } + + bool integers( ) const noexcept + { return integers_; } + + T_String const& progId( ) const noexcept + { return progId_; } + T_SRDLocation const& progIdLocation( ) const noexcept + { return progIdLocation_; } + + uint32_t uloc( ) const noexcept + { return uloc_; } + T_SRDLocation const& ulocLocation( ) const noexcept + { return ulocLocation_; } + + void addValue( P_ExpressionNode value ) noexcept + { + if ( value ) { + values_.add( std::move( value ) ); + } + } + + uint32_t values( ) const noexcept + { return values_.size( ); } + A_ExpressionNode& value( const uint32_t index ) const noexcept + { return *values_[ index ]; } +}; + // Use-* instructions (framebuffers, programs, pipelines) // Also serves as the base for use-texture class T_UseInstrNode : public A_InstructionNode diff --git a/opparser.cc b/opparser.cc index 6b9276c..531bd07 100644 --- a/opparser.cc +++ b/opparser.cc @@ -22,6 +22,8 @@ struct T_ParserImpl_ PROGRAM , SET , TEXTURE , + UNIFORMS_FLT , + UNIFORMS_INT , USE_FRAMEBUFFER , USE_PIPELINE , USE_PROGRAM , @@ -44,6 +46,8 @@ struct T_ParserImpl_ add( "program" , E_InstrType::PROGRAM ); add( "set" , E_InstrType::SET ); add( "texture" , E_InstrType::TEXTURE ); + add( "uniforms" , E_InstrType::UNIFORMS_FLT ); + add( "uniforms-i" , E_InstrType::UNIFORMS_INT ); add( "use-framebuffer" , E_InstrType::USE_FRAMEBUFFER ); add( "use-pipeline" , E_InstrType::USE_PIPELINE ); add( "use-program" , E_InstrType::USE_PROGRAM ); @@ -163,6 +167,14 @@ struct T_ParserImpl_ M_DPARSER_( Program ); M_DPARSER_( Set ); M_DPARSER_( Texture ); + + M_DPARSER_( Uniforms ); + M_DPARSER_( UniformsI ); + void parseUniformsCommon( + T_InstrListNode& instructions , + T_SRDList const& input , + bool integers ) noexcept; + M_DPARSER_( UseFramebuffer ); M_DPARSER_( UsePipeline ); M_DPARSER_( UseProgram ); @@ -171,6 +183,7 @@ struct T_ParserImpl_ T_SRDList const& input , T_UseInstrNode::E_Type type ) noexcept; M_DPARSER_( UseTexture ); + M_DPARSER_( Viewport ); #undef M_DPARSER_ @@ -432,6 +445,8 @@ void T_ParserImpl_::parseInstructions( M_CASE_( PROGRAM , Program ); M_CASE_( SET , Set ); M_CASE_( TEXTURE , Texture ); + M_CASE_( UNIFORMS_FLT , Uniforms ); + M_CASE_( UNIFORMS_INT , UniformsI ); M_CASE_( USE_FRAMEBUFFER , UseFramebuffer ); M_CASE_( USE_PIPELINE , UsePipeline ); M_CASE_( USE_PROGRAM , UseProgram ); @@ -711,6 +726,56 @@ M_INSTR_( Texture ) } } +/*----------------------------------------------------------------------------*/ + +M_INSTR_( Uniforms ) +{ + parseUniformsCommon( instructions , input , false ); +} + +M_INSTR_( UniformsI ) +{ + parseUniformsCommon( instructions , input , true ); +} + +void T_ParserImpl_::parseUniformsCommon( + T_InstrListNode& instructions , + T_SRDList const& input , + const bool integers ) noexcept +{ + if ( input.size( ) == 1 || input[ 1 ].type( ) != E_SRDTokenType::WORD ) { + errors.addNew( "program identifier expected" , + input[ input.size( ) == 1 ? 0 : 1 ].location( ) ); + return; + } + if ( input.size( ) == 2 || !input[ 2 ].isInteger( ) ) { + errors.addNew( "uniform location expected" , + input[ input.size( ) == 2 ? 0 : 2 ].location( ) ); + return; + } + if ( input[ 2 ].longValue( ) < 0 || input[ 2 ].longValue( ) > UINT32_MAX ) { + errors.addNew( "invalid uniform location" , input[ 2 ].location( ) ); + return; + } + + auto& instr{ instructions.add< T_UniformsInstrNode >( + integers , input[ 1 ] , input[ 2 ] ) }; + instr.location( ) = input[ 0 ].location( ); + if ( input.size( ) == 3 ) { + errors.addNew( "at least one value required" , input[ 0 ].location( ) ); + return; + } + + for ( auto i = 3u ; i < input.size( ) ; i ++ ) { + if ( i == 7 ) { + errors.addNew( "too many arguments" , input[ i ].location( ) ); + return; + } + instr.addValue( parseExpression( instr , input[ i ] ) ); + } +} + + /*----------------------------------------------------------------------------*/ M_INSTR_( UseFramebuffer )