diff --git a/demo.cc b/demo.cc index c4290aa..7986671 100644 --- a/demo.cc +++ b/demo.cc @@ -1,17 +1,21 @@ #include "externals.hh" #include "demo.hh" #include "sync.hh" +#include "rendertarget.hh" #include "globals.hh" +#include +#include -T_Demo::T_Demo( __rd__ const uint32_t width , - __rd__ const uint32_t height ) +T_Demo::T_Demo( const uint32_t width , + const uint32_t height ) : width( width ) , height( height ) { } bool T_Demo::initialise( ) { +#if 0 raymarcher = std::make_unique< T_Raymarcher >( width , height ); dof = std::make_unique< T_DoFPass >( @@ -31,6 +35,11 @@ bool T_Demo::initialise( ) Globals::Sync( ).addInput( "dof-max-blur" , 16 ); Globals::Sync( ).addInput( "dof-samples" , 16 ); Globals::Sync( ).updateCurveCaches( ); +#endif + + if ( !program ) { + loadProgram( ); + } return true; } @@ -44,17 +53,25 @@ void T_Demo::makeUI( ) ImGuiSetCond_Once ); ImGui::Begin( "Demo controls" ); +#if 0 raymarcher->makeUI( ); dof->makeUI( ); bloom->makeUI( ); combine->makeUI( ); fxaa->makeUI( ); +#else + ImGui::Text( "lol, gtfo" ); +#endif ImGui::End( ); } void T_Demo::render( ) { + if ( !context ) { + runInit( ); + } + auto& sync( Globals::Sync( ) ); if ( playing ) { const float time = SDL_GetTicks( ) * 1e-3; @@ -66,28 +83,122 @@ void T_Demo::render( ) } playingPrevious = playing; +#if 0 raymarcher->render( ); dof->render( ); bloom->render( ); combine->render( ); fxaa->render( ); +#endif } void T_Demo::handleDND( - __rd__ ImVec2 const& move , - __rd__ const bool hasCtrl , - __rd__ const bool hasShift , - __rd__ const bool lmb // Left mouse button + ImVec2 const& move , + const bool hasCtrl , + const bool hasShift , + const bool lmb // Left mouse button ) { +#if 0 raymarcher->camera( ).handleDND( move , hasCtrl , hasShift , lmb ); +#endif } void T_Demo::handleWheel( - __rd__ const float wheel , - __rd__ const bool hasCtrl , - __rd__ const bool hasShift + const float wheel , + const bool hasCtrl , + const bool hasShift ) { +#if 0 raymarcher->camera( ).handleWheel( wheel , hasCtrl , hasShift ); +#endif +} + +namespace { + +/*============================================================================*/ + + +void PrintStreamError( + char const* const prefix , + T_String const& name , + ebcl::X_StreamError const& error ) +{ + T_StringBuilder sb; + sb << prefix << " '" << name << "': " << error.what( ); + if ( error.code( ) == ebcl::E_StreamError::SYSTEM_ERROR ) { + sb << " (error code " << error.systemError( ) << ")"; + } + sb << '\n' << '\0'; + fprintf( stderr , "%s" , sb.data( ) ); +} + +void WriteSRDError( + T_StringBuilder& sb , + ebcl::T_SRDError const& error ) +{ + sb << error.location( ) << " - " << error.error( ) << "\n"; +} + + +/*============================================================================*/ + +} // namespace + + +bool T_Demo::loadProgram( ) +{ + using namespace ebcl; + const T_String inputName( T_String::Pooled( "demo.srd" ) ); + T_File input( inputName , E_FileMode::READ_ONLY ); + try { + input.open( ); + } catch ( X_StreamError const& e ) { + PrintStreamError( "Could not open" , inputName , e ); + return false; + } + + // Load SRD data + T_SRDMemoryTarget srdOut; + srdOut.clearComments( true ).clearFlushToken( true ); + try { + T_SRDTextReader srdReader{ srdOut }; + T_FileInputStream fis{ input }; + srdReader.read( inputName , fis ); + } catch ( X_StreamError const& e ) { + PrintStreamError( "Could not open" , inputName , e ); + return false; + + } catch ( X_SRDErrors const& e ) { + T_StringBuilder sb; + const auto nErrors( e.errors.size( ) ); + for ( auto i = 0u ; i < nErrors ; i ++ ) { + WriteSRDError( sb , e.errors[ i ] ); + } + sb << "No parsing happened due to format errors\n" << '\0'; + fprintf( stderr , "%s" , sb.data( ) ); + return false; + } + + // Parse the fuck + opast::T_Parser parser; + if ( parser.parse( srdOut.list( ) ) ) { + printf( "Parser successful. Compiling...\n" ); + ops::T_Compiler compiler; + program = compiler.compile( *parser.result( ) ); + return true; + } + return false; +} + + +void T_Demo::runInit( ) +{ + context = NewOwned< ops::T_OpContext >( *program ); + try { + context->run( ops::T_OpContext::R_INIT , 0 , width , height ); + } catch ( ops::X_OpFailure const& fail ) { + printf( "FAILED TO RUN INIT!\n\t%s\n" , fail.what( ) ); + } } diff --git a/demo.hh b/demo.hh index ecb0652..789307c 100644 --- a/demo.hh +++ b/demo.hh @@ -1,5 +1,6 @@ #pragma once +#if 0 #include "raymarcher.hh" #include "dof.hh" #include "bloom.hh" @@ -7,6 +8,8 @@ #include "fxaa.hh" #include "profiling.hh" #include "sync.hh" +#endif +#include "control.hh" struct T_Demo @@ -17,23 +20,26 @@ struct T_Demo // --------------------------------------------------------------------- - T_Demo( __rd__ const uint32_t width , - __rd__ const uint32_t height ); + T_Demo( const uint32_t width , + const uint32_t height ); bool initialise( ); void makeUI( ); void render( ); + bool loadProgram( ); + void runInit( ); + void handleDND( - __rd__ ImVec2 const& move , - __rd__ const bool hasCtrl , - __rd__ const bool hasShift , - __rd__ const bool lmb // Left mouse button + ImVec2 const& move , + const bool hasCtrl , + const bool hasShift , + const bool lmb // Left mouse button ); void handleWheel( - __rd__ const float wheel , - __rd__ const bool hasCtrl , - __rd__ const bool hasShift + const float wheel , + const bool hasCtrl , + const bool hasShift ); // --------------------------------------------------------------------- @@ -43,11 +49,15 @@ struct T_Demo bool playing = false; +#if 0 std::unique_ptr< T_Raymarcher > raymarcher; std::unique_ptr< T_DoFPass > dof; std::unique_ptr< T_BloomPass > bloom; std::unique_ptr< T_CombinePass > combine; std::unique_ptr< T_FXAAPass > fxaa; +#endif + T_OwnPtr< ops::T_OpProgram > program; + T_OwnPtr< ops::T_OpContext > context; private: bool playingPrevious = false; diff --git a/demo.srd b/demo.srd index 987b74b..76579d8 100644 --- a/demo.srd +++ b/demo.srd @@ -37,8 +37,8 @@ # Scene (fn scene-init () - (texture tx-scene-output rgb-f16 vp-width vp-height) - (texture tx-scene-depth r-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) (framebuffer rt-scene (color tx-scene-output) (color tx-scene-depth)) @@ -408,7 +408,7 @@ (program prg-fxaa "fxaa.f.glsl") (pipeline pl-fxaa prg-fullscreen prg-fxaa) (uniforms-i prg-fxaa 0 0) - (uniforms-i prg-fxaa 1 $vp-width $vp-height) + (uniforms prg-fxaa 1 $vp-width $vp-height) (sampler smp-fxaa (sampling linear) diff --git a/ebcl b/ebcl index 9f666ee..1ce16d6 160000 --- a/ebcl +++ b/ebcl @@ -1 +1 @@ -Subproject commit 9f666eea4946dd3de23203f6c829a540a2708565 +Subproject commit 1ce16d63cbed4b152cd113121ecb06fb8358b9f1 diff --git a/main.cc b/main.cc index 343cb17..4da915e 100644 --- a/main.cc +++ b/main.cc @@ -7,6 +7,7 @@ #include "window.hh" #include "shaders.hh" #include "odbg.hh" +#include "rendertarget.hh" using ebcl::T_Optional; diff --git a/opcomp.cc b/opcomp.cc index 3fd0aec..28c1369 100644 --- a/opcomp.cc +++ b/opcomp.cc @@ -171,6 +171,9 @@ void T_CompilerImpl_::gatherConstants( ) noexcept constants.add( value.u ); return true; } ); + for ( auto i = 0u ; i < constants.size( ) ; i ++ ) { + output->constants.add( constants[ i ] ); + } #ifdef INVASIVE_TRACES printf( "%d constants\n" , constants.size( ) ); @@ -431,14 +434,14 @@ bool T_CompilerImpl_::compileNode( const auto ppos( condJumps.last( ).prevCase ); const auto diff( cpos - ppos ); assert( diff > 1 ); - output->ops.get( funcIndex , ppos ).args[ 1 ] = diff - 1; + output->ops.get( funcIndex , ppos ).args[ 0 ] = diff - 1; } else { // If there is a previous skip location, insert the skip instruction if ( !condJumps.last( ).caseEnds.empty( ) ) { addInstruction( OP_SKIP , 0 , node.location( ) ); const auto ppos( condJumps.last( ).prevCase ); assert( output->ops.get( funcIndex , ppos ).op == OP_COND_SKIP ); - output->ops.get( funcIndex , ppos ).args[ 1 ] ++; + output->ops.get( funcIndex , ppos ).args[ 0 ] ++; } // Add the conditional skip @@ -455,7 +458,7 @@ bool T_CompilerImpl_::compileNode( addInstruction( OP_SKIP , 0 , node.location( ) ); const auto ppos( condJumps.last( ).prevCase ); assert( output->ops.get( funcIndex , ppos ).op == OP_COND_SKIP ); - output->ops.get( funcIndex , ppos ).args[ 1 ] ++; + output->ops.get( funcIndex , ppos ).args[ 0 ] ++; } break; @@ -723,7 +726,7 @@ bool T_CompilerImpl_::compileNode( T_OpValue value; value.f = dynamic_cast< T_ConstantExprNode& >( node ).floatValue( ); addInstruction( OP_FP_LOAD , - constants.indexOf( value.u ) + 3 , + constants.indexOf( value.u ) + 3 + output->nVariables , node.location( ) ); } break; diff --git a/opparser.cc b/opparser.cc index 4a71043..2b72f34 100644 --- a/opparser.cc +++ b/opparser.cc @@ -781,7 +781,7 @@ void T_ParserImpl_::checkIdentifier( errors.addNew( "unknown identifier" , location ); } else if ( dt != expected ) { T_StringBuilder esb; - esb << E_DataType::TEXTURE << " expected, " << dt << " found instead"; + esb << expected << " expected, " << dt << " found instead"; errors.addNew( std::move( esb ) , location ); } } @@ -1648,15 +1648,15 @@ M_INSTR_( Texture ) errors.addNew( "width expected" , input[ 0 ].location( ) ); } if ( input.size( ) > 4 ) { - instr.setHeight( parseExpression( instr , input[ 3 ] ) ); + instr.setHeight( parseExpression( instr , input[ 4 ] ) ); } else { errors.addNew( "height expected" , input[ 0 ].location( ) ); } if ( input.size( ) > 5 ) { - instr.setLODs( parseExpression( instr , input[ 4 ] ) ); + instr.setLODs( parseExpression( instr , input[ 5 ] ) ); } if ( input.size( ) > 6 ) { - errors.addNew( "too many arguments" , input[ 5 ].location( ) ); + errors.addNew( "too many arguments" , input[ 6 ].location( ) ); } } diff --git a/ops.cc b/ops.cc index 2588ea4..db78837 100644 --- a/ops.cc +++ b/ops.cc @@ -206,8 +206,8 @@ X_OpFailure::X_OpFailure( : op_( &op ) , error_( std::move( error ) ) { T_StringBuilder sb; - sb << "operation (" << op << ") failed; source: " << op.location - << '\0'; + sb << "operation (" << op << ") failed: " + << error_ << "; source: " << op.location << '\0'; fullMessage_ = std::move( sb ); } @@ -226,19 +226,20 @@ T_OpContext::T_OpContext( const auto nc{ program.constants.size( ) }; const auto ts{ 3 + nc + program.nVariables - + program.nPrograms + program.nPipelines - + program.nSamplers + program.nTextures }; + + program.nFramebuffers + program.nPrograms + + program.nPipelines + program.nSamplers + + program.nTextures }; values.resize( ts ); initialInputs.resize( program.inputs.size( ) ); framebuffers.resize( program.nFramebuffers ); pipelines.resize( program.nPipelines ); - programs.resize( program.nPrograms ); samplers.resize( program.nSamplers ); textures.resize( program.nTextures ); + memset( &values[ 0 ] , 0 , values.size( ) * 4 ); for ( auto i = 0u ; i < nc ; i ++ ) { - values[ i + 3 ] = program.constants[ nc ]; + values[ i + 3 + program.nVariables ] = program.constants[ i ]; } } @@ -276,13 +277,40 @@ void T_OpContext::run( values[ 0 ] = time; values[ 1 ] = width; values[ 2 ] = height; + stack.clear( ); stack.add( 0xffffffff ); while ( !stack.empty( ) ) { -// if ( instrPtr >= program.ops. auto const& instr{ program.ops[ instrPtr ] }; +//#define YOUR_MUM_IS_A_TRACE +#ifdef YOUR_MUM_IS_A_TRACE + printf( "VALUES\n00" ); + for ( auto i = 0u ; i < values.size( ) ; i ++ ) { + printf( " %08x" , values[ i ].u ); + if ( i % 4 == 3 ) { + printf( "\n%02x" , i + 1 ); + } + } + if ( values.size( ) % 4 != 0 ) { + printf( "\n" ); + } + + T_StringBuilder sb; + sb << "EXECUTE " << instrPtr << ":\t(" << instr << ") {" + << instr.location << "}\nSTACK:"; + for ( auto i = 0u ; i < stack.size( ) ; i ++ ) { + sb << ' ' << stack[ i ].u; + } + sb << "\nFPU STACK:"; + for ( auto i = 0u ; i < x87sp ; i ++ ) { + sb << ' ' << x87stack[ i ]; + } + sb << '\n' << '\0'; + printf( "%s" , sb.data( ) ); +#endif + switch ( instr.op ) { case OP_END: @@ -445,7 +473,7 @@ void T_OpContext::run( if ( x87stack[ x87sp - 1 ] == 0 ) { throw X_OpFailure{ instr , "arithmetic error" }; } - x87stack[ x87sp - 2 ] *= x87stack[ x87sp - 1 ]; + x87stack[ x87sp - 2 ] /= x87stack[ x87sp - 1 ]; x87sp --; break; } @@ -647,14 +675,14 @@ void T_OpContext::run( } const auto index( sv - 1 ); + const uint32_t w( stack.last( ).f ); + stack.removeLast( ); + const uint32_t h( stack.last( ).f ); + stack.removeLast( ); const uint32_t lods( instr.args[ 1 ] ? stack.last( ).f : 1 ); if ( instr.args[ 1 ] ) { stack.removeLast( ); } - const uint32_t h( stack.last( ).f ); - stack.removeLast( ); - const uint32_t w( stack.last( ).f ); - stack.removeLast( ); textures[ index ] = NewOwned< T_Texture >( w , h , E_TexType( instr.args[ 0 ] ) , lods ); @@ -741,10 +769,7 @@ void T_OpContext::run( if ( curFb < 0 ) { throw X_OpFailure{ instr , "no framebuffer selected" }; } - if ( instr.args[ 0 ] == 0 ) { - throw X_OpFailure{ instr , "invalid argument" }; - } - framebuffers[ curFb ]->toggle( instr.args[ 0 ] + 1 , instr.args[ 1 ] ); + framebuffers[ curFb ]->toggle( instr.args[ 0 ] , instr.args[ 1 ] ); break; } @@ -755,7 +780,11 @@ void T_OpContext::run( const auto ss( stack.size( ) ); T_OpValue values[ 4 ]; for ( auto i = 0u ; i <= instr.args[ 0 ] ; i ++ ) { - values[ i ] = stack[ ss - 3 - i ]; + if ( instr.args[ 1 ] ) { + values[ i ] = uint32_t( stack[ ss - 3 - i ].f ); + } else { + values[ i ] = stack[ ss - 3 - i ]; + } } const auto sv( stack.last( ).u ); @@ -770,7 +799,7 @@ void T_OpContext::run( }; const F_SetUniform_ func{ *(F_SetUniform_*) funcs[ instr.args[ 0 ] + ( instr.args[ 1 ] ? 4 : 0 ) ] }; - func( programs[ sv ]->id( ) , stack[ ss - 2 ].u , 1 , values ); + func( programs[ sv - 1 ]->id( ) , stack[ ss - 2 ].u , 1 , values ); stack.resize( ss - 3 - instr.args[ 0 ] ); break; } diff --git a/rendertarget.cc b/rendertarget.cc index fcaa883..2ef5d32 100644 --- a/rendertarget.cc +++ b/rendertarget.cc @@ -174,8 +174,7 @@ void T_Rendertarget::toggle( const uint32_t id , const bool active ) { - assert( id > 0 ); - const auto realId( GL_COLOR_ATTACHMENT0 + id - 1 ); + const auto realId( GL_COLOR_ATTACHMENT0 + id ); const int32_t idx( buffers_.indexOf( realId ) ); if ( active && idx < 0 ) { buffers_.add( realId ); diff --git a/shaders.cc b/shaders.cc index 151ccac..52dc530 100644 --- a/shaders.cc +++ b/shaders.cc @@ -287,7 +287,7 @@ T_ShaderProgram::T_ShaderProgram( T_ShaderProgram::~T_ShaderProgram( ) { if ( id_ ) { - Globals::Shaders( ).dereferenceProgram( id_ ); + Globals::Shaders( ).dereferenceProgram( id_ - 1 ); } } @@ -296,7 +296,7 @@ T_ShaderProgram& T_ShaderProgram::operator=( { if ( this != &other ) { if ( id_ ) { - Globals::Shaders( ).dereferenceProgram( id_ ); + Globals::Shaders( ).dereferenceProgram( id_ - 1 ); } id_ = other.id_; if ( id_ ) { @@ -311,7 +311,7 @@ T_ShaderProgram& T_ShaderProgram::operator=( { if ( this != &other ) { if ( id_ ) { - Globals::Shaders( ).dereferenceProgram( id_ ); + Globals::Shaders( ).dereferenceProgram( id_ - 1 ); } id_ = other.id_; other.id_ = T_String{}; @@ -666,7 +666,8 @@ T_ShaderProgram T_ShaderManager::program( { loadProgram( name ); assert( programIndex_.contains( name ) ); - return T_ShaderProgram( *programIndex_.get( name ) ); + assert( programs_[ *programIndex_.get( name ) ].name == name ); + return T_ShaderProgram( *programIndex_.get( name ) + 1 ); } T_ShaderPipeline T_ShaderManager::pipeline( @@ -844,7 +845,7 @@ bool T_ShaderManager::useExistingProgram( void T_ShaderManager::loadProgram( T_String const& name ) { - if ( useExistingProgram( name ) ) { + if ( !useExistingProgram( name ) ) { initProgramRecord( name ); } }