diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..17a5ca7
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,77 @@
+root = true
+
+[*]
+charset = utf-8
+end_of_line = CRLF
+indent_style = tab
+indent_size = 4
+tab_width = 4
+trim_trailing_whitespace = true
+insert_final_newline = true
+
+[*.{c++,cc,cpp,cppm,cu,cuh,cxx,fx,h,h++,hh,hlsl,hpp,hxx,inl,ipp,ixx,tlh,tli}]
+# Visual C++ Code Style settings
+cpp_generate_documentation_comments = doxygen_slash_star
+# Visual C++ Formatting settings
+cpp_indent_braces = false
+cpp_indent_multi_line_relative_to = innermost_parenthesis
+cpp_indent_within_parentheses = indent
+cpp_indent_preserve_within_parentheses = true
+cpp_indent_case_contents = true
+cpp_indent_case_labels = false
+cpp_indent_case_contents_when_block = true
+cpp_indent_lambda_braces_when_parameter = true
+cpp_indent_goto_labels = leftmost_column
+cpp_indent_preprocessor = leftmost_column
+cpp_indent_access_specifiers = false
+cpp_indent_namespace_contents = true
+cpp_indent_preserve_comments = true
+cpp_new_line_before_open_brace_namespace = new_line
+cpp_new_line_before_open_brace_type = new_line
+cpp_new_line_before_open_brace_function = new_line
+cpp_new_line_before_open_brace_block = new_line
+cpp_new_line_before_open_brace_lambda = new_line
+cpp_new_line_scope_braces_on_separate_lines = true
+cpp_new_line_close_brace_same_line_empty_type = false
+cpp_new_line_close_brace_same_line_empty_function = false
+cpp_new_line_before_catch = true
+cpp_new_line_before_else = true
+cpp_new_line_before_while_in_do_while = true
+cpp_space_before_function_open_parenthesis = remove
+cpp_space_within_parameter_list_parentheses = true
+cpp_space_between_empty_parameter_list_parentheses = false
+cpp_space_after_keywords_in_control_flow_statements = true
+cpp_space_within_control_flow_statement_parentheses = true
+cpp_space_before_lambda_open_parenthesis = false
+cpp_space_within_cast_parentheses = true
+cpp_space_after_cast_close_parenthesis = false
+cpp_space_within_expression_parentheses = true
+cpp_space_before_block_open_brace = true
+cpp_space_between_empty_braces = false
+cpp_space_before_initializer_list_open_brace = false
+cpp_space_within_initializer_list_braces = true
+cpp_space_preserve_in_initializer_list = false
+cpp_space_before_open_square_bracket = false
+cpp_space_within_square_brackets = false
+cpp_space_before_empty_square_brackets = false
+cpp_space_between_empty_square_brackets = false
+cpp_space_group_square_brackets = true
+cpp_space_within_lambda_brackets = false
+cpp_space_between_empty_lambda_brackets = false
+cpp_space_before_comma = false
+cpp_space_after_comma = true
+cpp_space_remove_around_member_operators = true
+cpp_space_before_inheritance_colon = true
+cpp_space_before_constructor_colon = true
+cpp_space_remove_before_semicolon = true
+cpp_space_after_semicolon = true
+cpp_space_remove_around_unary_operator = true
+cpp_space_around_binary_operator = insert
+cpp_space_around_assignment_operator = insert
+cpp_space_pointer_reference_alignment = center
+cpp_space_around_ternary_operator = insert
+cpp_use_unreal_engine_macro_formatting = true
+cpp_wrap_preserve_blocks = never
+# Visual C++ Inlcude Cleanup settings
+cpp_include_cleanup_add_missing_error_tag_type = suggestion
+cpp_include_cleanup_remove_unused_error_tag_type = dimmed
diff --git a/.github/codecov.yml b/.github/codecov.yml
new file mode 100644
index 0000000..507ecc6
--- /dev/null
+++ b/.github/codecov.yml
@@ -0,0 +1,38 @@
+codecov:
+ require_ci_to_pass: yes
+
+coverage:
+ precision: 2
+ round: down
+ range: "70...100"
+ status:
+ project:
+ default:
+ target: auto
+ threshold: 100%
+ base: auto
+ patch:
+ default:
+ target: auto
+ threshold: 100%
+ base: auto
+ if_ci_failed: success
+ informational: true
+
+parsers:
+ gcov:
+ branch_detection:
+ conditional: yes
+ loop: yes
+ method: no
+ macro: no
+
+comment:
+ layout: "reach,diff,flags,files,footer"
+ behavior: default
+ require_changes: no
+ require_head: no
+ require_base: no
+
+github_checks:
+ annotations: true
\ No newline at end of file
diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml
index 17c5a1e..b121236 100644
--- a/.github/workflows/cmake.yml
+++ b/.github/workflows/cmake.yml
@@ -16,7 +16,7 @@ jobs:
strategy:
matrix:
os: [[windows-latest,x64-windows,msvc]]
- buildType: [Release]
+ buildType: [Debug]
runs-on: ${{ matrix.os[0] }}
steps:
- uses: actions/checkout@v2
@@ -30,7 +30,13 @@ jobs:
run: |
$VCPKG_ROOT/vcpkg install vulkan-headers:${{ matrix.os[1] }}
- name: Checkout submodules
- run: git submodule update --init -- "CMake"
+ run: |
+ git submodule update --init -- "CMake"
+ - name: Setup OpenCppCoverage
+ id: setup_opencppcoverage
+ run: |
+ choco install OpenCppCoverage -y
+ echo "C:\Program Files\OpenCppCoverage" >> $env:GITHUB_PATH
- name: Create Build Environment
run: |
cmake -E make_directory ${{runner.workspace}}/build-${{ matrix.buildType }}
@@ -50,17 +56,22 @@ jobs:
shell: bash
working-directory: ${{runner.workspace}}/build-${{ matrix.buildType }}
run: |
- cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=${{ matrix.buildType }} -DCMAKE_INSTALL_PREFIX=$GITHUB_WORKSPACE/package/rendergraph -DPROJECTS_WARNINGS_AS_ERRORS=$PROJ_WAE -DCRG_UNITY_BUILD=ON -DCRG_BUILD_TESTS=ON -DVULKAN_HEADERS_INCLUDE_DIRS=$VCPKG_ROOT/installed/${{matrix.os[1]}}/include
+ cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=${{ matrix.buildType }} -DCMAKE_INSTALL_PREFIX=$GITHUB_WORKSPACE/package/rendergraph -DPROJECTS_WARNINGS_AS_ERRORS=$PROJ_WAE -DPROJECTS_COVERAGE=ON -DCRG_UNITY_BUILD=ON -DCRG_BUILD_TESTS=ON -DVULKAN_HEADERS_INCLUDE_DIRS=$VCPKG_ROOT/installed/${{matrix.os[1]}}/include
- name: Build
working-directory: ${{runner.workspace}}/build-${{ matrix.buildType }}
shell: bash
run: |
cmake --build . --parallel 2 --config ${{ matrix.buildType }}
- - name: Test
+ - name: Build coverage report
working-directory: ${{runner.workspace}}/build-${{ matrix.buildType }}
shell: bash
run: |
- ctest -C ${{ matrix.buildType }}
+ cmake --build . --target RenderGraphCoverage --config ${{ matrix.buildType }}
+ - name: Upload coverage reports to Codecov
+ uses: codecov/codecov-action@v4.0.1
+ with:
+ token: ${{ secrets.CODECOV_TOKEN }}
+ file: ${{ github.workspace }}/doc/RenderGraphCoverage.xml
- name: Prepare package
if: github.event_name == 'push'
working-directory: ${{runner.workspace}}/build-${{ matrix.buildType }}
diff --git a/.gitignore b/.gitignore
index be50ff3..94e5f89 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,6 +2,9 @@
/binaries
/build
/setup
+/doc/coverage
+/doc/RenderGraphCoverage
+/doc/RenderGraphCoverage.xml
/doc/x86
/doc/x64
/.gitattributes
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ee5abdf..0f2ad95 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -10,7 +10,7 @@ set( MAIN_PROJECT_NAME "RenderGraph" )
# Set project version numbers
set( VERSION_MAJOR 1 )
set( VERSION_MINOR 4 )
-set( VERSION_BUILD 0 )
+set( VERSION_BUILD 1 )
set( VERSION_YEAR 2024 )
set( _PROJECT_VERSION "${VERSION_MAJOR}.${VERSION_MINOR}" )
@@ -52,6 +52,8 @@ set_property( GLOBAL PROPERTY USE_FOLDERS ON )
set( CRG_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR} )
set( CRG_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR} )
+set( CRG_EDITORCONFIG_FILE ${CMAKE_CURRENT_SOURCE_DIR}/.editorconfig )
+
if ( NOT DEFINED CRG_BUILD_STATIC )
option( CRG_BUILD_STATIC "Build as a static library" ON )
endif ()
@@ -94,15 +96,12 @@ if ( MSVC OR NOT "${CMAKE_BUILD_TYPE}" STREQUAL "" )
${CRG_SOURCE_DIR}/include/${PROJECT_NAME}/RunnablePass.hpp
${CRG_SOURCE_DIR}/include/${PROJECT_NAME}/Signal.hpp
${CRG_SOURCE_DIR}/include/${PROJECT_NAME}/WriteDescriptorSet.hpp
- ${CRG_SOURCE_DIR}/source/${PROJECT_NAME}/BuilderCommon.hpp
${CRG_SOURCE_DIR}/source/${PROJECT_NAME}/GraphBuilder.hpp
${CRG_SOURCE_DIR}/source/${PROJECT_NAME}/FramePassDependenciesBuilder.hpp
- ${CRG_SOURCE_DIR}/source/${PROJECT_NAME}/ResourceOptimiser.hpp
)
set( ${PROJECT_NAME}_SRC_FILES
${CRG_SOURCE_DIR}/source/${PROJECT_NAME}/Attachment.cpp
${CRG_SOURCE_DIR}/source/${PROJECT_NAME}/AttachmentTransition.cpp
- ${CRG_SOURCE_DIR}/source/${PROJECT_NAME}/BuilderCommon.cpp
${CRG_SOURCE_DIR}/source/${PROJECT_NAME}/DotExport.cpp
${CRG_SOURCE_DIR}/source/${PROJECT_NAME}/FrameGraph.cpp
${CRG_SOURCE_DIR}/source/${PROJECT_NAME}/FramePass.cpp
@@ -116,7 +115,6 @@ if ( MSVC OR NOT "${CMAKE_BUILD_TYPE}" STREQUAL "" )
${CRG_SOURCE_DIR}/source/${PROJECT_NAME}/Log.cpp
${CRG_SOURCE_DIR}/source/${PROJECT_NAME}/RecordContext.cpp
${CRG_SOURCE_DIR}/source/${PROJECT_NAME}/ResourceHandler.cpp
- ${CRG_SOURCE_DIR}/source/${PROJECT_NAME}/ResourceOptimiser.cpp
${CRG_SOURCE_DIR}/source/${PROJECT_NAME}/RunnableGraph.cpp
${CRG_SOURCE_DIR}/source/${PROJECT_NAME}/RunnablePass.cpp
)
@@ -214,6 +212,10 @@ if ( MSVC OR NOT "${CMAKE_BUILD_TYPE}" STREQUAL "" )
ALIAS
${PROJECT_NAME}
)
+ target_sources( ${PROJECT_NAME}
+ PRIVATE
+ ${CRG_EDITORCONFIG_FILE}
+ )
target_add_compilation_flags( ${PROJECT_NAME} )
target_compile_options( ${PROJECT_NAME}
PUBLIC
diff --git a/README.md b/README.md
index 12212c1..bb0eebf 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,6 @@
+
diff --git a/include/RenderGraph/AttachmentTransition.hpp b/include/RenderGraph/AttachmentTransition.hpp
index 3681317..f1a0323 100644
--- a/include/RenderGraph/AttachmentTransition.hpp
+++ b/include/RenderGraph/AttachmentTransition.hpp
@@ -28,7 +28,6 @@ namespace crg
};
AttachmentTransitions mergeIdenticalTransitions( AttachmentTransitions value );
- AttachmentTransitions reduceDirectPaths( AttachmentTransitions value );
struct FramePassTransitions
{
diff --git a/include/RenderGraph/GraphNode.hpp b/include/RenderGraph/GraphNode.hpp
index ada79e1..b2495f6 100644
--- a/include/RenderGraph/GraphNode.hpp
+++ b/include/RenderGraph/GraphNode.hpp
@@ -30,14 +30,12 @@ namespace crg
CRG_API GraphNode & operator=( GraphNode const & ) = delete;
CRG_API GraphNode( GraphNode && rhs )noexcept;
CRG_API GraphNode & operator=( GraphNode && rhs )noexcept;
-
CRG_API virtual ~GraphNode()noexcept = default;
+
CRG_API void addAttaches( ConstGraphAdjacentNode const prev
, AttachmentTransitions inputAttaches );
CRG_API void attachNode( GraphAdjacentNode next
, AttachmentTransitions inputAttaches );
- CRG_API GraphAdjacentNode findInNext( FramePass const & pass )const;
- CRG_API bool hasInNext( ConstGraphAdjacentNode const & node )const;
CRG_API AttachmentTransitions const & getInputAttaches( ConstGraphAdjacentNode pred = nullptr )const;
CRG_API virtual void accept( GraphVisitor * vis )const = 0;
diff --git a/include/RenderGraph/Log.hpp b/include/RenderGraph/Log.hpp
index da1fa71..f66e180 100644
--- a/include/RenderGraph/Log.hpp
+++ b/include/RenderGraph/Log.hpp
@@ -50,31 +50,6 @@ namespace crg
CRG_API static void logError( std::string const & message, bool newLine = true );
/**
*\brief
- * Logs a trace message.
- */
- CRG_API static void logTrace( std::ostream const & message, bool newLine = true );
- /**
- *\brief
- * Logs a debug message.
- */
- CRG_API static void logDebug( std::ostream const & message, bool newLine = true );
- /**
- *\brief
- * Logs an info message.
- */
- CRG_API static void logInfo( std::ostream const & message, bool newLine = true );
- /**
- *\brief
- * Logs a warning message.
- */
- CRG_API static void logWarning( std::ostream const & message, bool newLine = true );
- /**
- *\brief
- * Logs an error message.
- */
- CRG_API static void logError( std::ostream const & message, bool newLine = true );
- /**
- *\brief
* Sets the trace callback.
*/
CRG_API static void setTraceCallback( LogCallback callback );
@@ -111,185 +86,6 @@ namespace crg
LogCallback m_warning;
LogCallback m_error;
};
-
- namespace log
- {
- template< typename StreambufT >
- struct LogStreamT
- : public std::ostringstream
- {
- using StreambufPtrT = std::unique_ptr< StreambufT >;
-
- public:
- LogStreamT()
- : std::ostringstream{}
- , m_streambuf{ std::make_unique< StreambufT >( static_cast< std::ostream & >( *this ) ) }
- {
- this->imbue( std::locale{ "C" } );
- }
-
- private:
- StreambufPtrT m_streambuf;
- };
-
- template< typename TraitsT >
- class LogStreambufT
- : public std::streambuf
- {
- public:
- using string_type = std::string;
- using ostream_type = std::ostream;
- using streambuf_type = std::streambuf;
- using int_type = std::streambuf::int_type;
- using traits_type = std::streambuf::traits_type;
-
- LogStreambufT( LogStreambufT const & ) = delete;
- LogStreambufT & operator=( LogStreambufT const & ) = delete;
- LogStreambufT( LogStreambufT && ) = delete;
- LogStreambufT & operator=( LogStreambufT && ) = delete;
-
- explicit LogStreambufT( ostream_type & stream )
- : m_stream( stream )
- {
- m_old = m_stream.rdbuf( this );
- }
-
- ~LogStreambufT()noexcept override
- {
- try
- {
- doSync();
- m_stream.rdbuf( m_old );
- }
- catch ( ... )
- {
- // Nothing to do here
- }
- }
-
- int_type overflow( int_type c = traits_type::eof() )override
- {
- if ( traits_type::eq_int_type( c, traits_type::eof() ) )
- {
- doSync();
- }
- else if ( c == '\n' )
- {
- doSync();
- }
- else if ( c == '\r' )
- {
- m_buffer += '\r';
- doSyncNoLF();
- }
- else
- {
- m_buffer += traits_type::to_char_type( c );
- }
-
- return c;
- }
-
- int doSync()
- {
- if ( !m_buffer.empty() )
- {
- TraitsT::log( m_buffer, true );
- m_buffer.clear();
- }
-
- return 0;
- }
-
- int doSyncNoLF()
- {
- if ( !m_buffer.empty() )
- {
- TraitsT::log( m_buffer, false );
- m_buffer.clear();
- }
-
- return 0;
- }
-
- private:
- ostream_type & m_stream;
- streambuf_type * m_old;
- string_type m_buffer;
- };
- /**
- *\~english
- *\brief
- * Streambuf traits for trace logging.
- */
- struct TraceLoggerStreambufTraits
- {
- static void log( std::string const & msg, bool lf )
- {
- Logger::logTrace( msg, lf );
- }
- };
- /**
- *\~english
- *\brief
- * Streambuf traits for debug logging.
- */
- struct DebugLoggerStreambufTraits
- {
- static void log( std::string const & msg, bool lf )
- {
- Logger::logDebug( msg, lf );
- }
- };
- /**
- *\~english
- *\brief
- * Streambuf traits for info logging.
- */
- struct InfoLoggerStreambufTraits
- {
- static void log( std::string const & msg, bool lf )
- {
- Logger::logInfo( msg, lf );
- }
- };
- /**
- *\~english
- *\brief
- * Streambuf traits for warning logging.
- */
- struct WarningLoggerStreambufTraits
- {
- static void log( std::string const & msg, bool lf )
- {
- Logger::logWarning( msg, lf );
- }
- };
- /**
- *\~english
- *\brief
- * Streambuf traits for error logging.
- */
- struct ErrorLoggerStreambufTraits
- {
- static void log( std::string const & msg, bool lf )
- {
- Logger::logError( msg, lf );
- }
- };
-
- using TraceLoggerStreambuf = LogStreambufT< TraceLoggerStreambufTraits >;
- using DebugLoggerStreambuf = LogStreambufT< DebugLoggerStreambufTraits >;
- using InfoLoggerStreambuf = LogStreambufT< InfoLoggerStreambufTraits >;
- using WarningLoggerStreambuf = LogStreambufT< WarningLoggerStreambufTraits >;
- using ErrorLoggerStreambuf = LogStreambufT< ErrorLoggerStreambufTraits >;
-
- static LogStreamT< TraceLoggerStreambuf > trace;
- static LogStreamT< DebugLoggerStreambuf > debug;
- static LogStreamT< InfoLoggerStreambuf > info;
- static LogStreamT< WarningLoggerStreambuf > warn;
- static LogStreamT< ErrorLoggerStreambuf > error;
- }
}
#endif
diff --git a/include/RenderGraph/RunnablePass.hpp b/include/RenderGraph/RunnablePass.hpp
index d964f88..5382a80 100644
--- a/include/RenderGraph/RunnablePass.hpp
+++ b/include/RenderGraph/RunnablePass.hpp
@@ -260,30 +260,6 @@ namespace crg
CRG_API uint32_t reRecordCurrent();
/**
*\brief
- * Submits this pass' command buffer to the given queue.
- *\param[in] toWait
- * The semaphore to wait for.
- *\param[out] queue
- * The queue to submit to.
- *\return
- * This pass' semaphore.
- */
- CRG_API SemaphoreWaitArray run( SemaphoreWait toWait
- , VkQueue queue );
- /**
- *\brief
- * Submits this pass' command buffer to the given queue.
- *\param[in] toWait
- * The semaphores to wait for.
- *\param[out] queue
- * The queue to submit to.
- *\return
- * This pass' semaphore.
- */
- CRG_API SemaphoreWaitArray run( SemaphoreWaitArray const & toWait
- , VkQueue queue );
- /**
- *\brief
* Resets the command buffer to initial state.
*/
CRG_API void resetCommandBuffer( uint32_t passIndex );
diff --git a/source/RenderGraph/AttachmentTransition.cpp b/source/RenderGraph/AttachmentTransition.cpp
index 322eb6d..2256c4d 100644
--- a/source/RenderGraph/AttachmentTransition.cpp
+++ b/source/RenderGraph/AttachmentTransition.cpp
@@ -30,64 +30,6 @@ namespace crg
return result;
}
-
- static ViewTransitionArray reduceDirectPathsT( ViewTransitionArray transitions )
- {
- // Currently, just removes from the transitions the sampled attachments to a pass
- // that doesn't directly need them.
- auto it = std::remove_if( transitions.begin()
- , transitions.end()
- , []( ViewTransition const & transition )
- {
- bool result = false;
-
- if ( transition.inputAttach.isSampledView() )
- {
- auto & inputPass = *transition.inputAttach.pass;
- auto pit = std::find_if( inputPass.images.begin()
- , inputPass.images.end()
- , [&transition]( Attachment const & lookup )
- {
- return lookup.isSampledView()
- && lookup == transition.inputAttach;
- } );
- result = pit == inputPass.images.end();
- }
-
- return result;
- } );
- transitions.erase( it, transitions.end() );
- return transitions;
- }
-
- static BufferTransitionArray reduceDirectPathsT( BufferTransitionArray transitions )
- {
- // Currently, just removes from the transitions the sampled attachments to a pass
- // that doesn't directly need them.
- auto it = std::remove_if( transitions.begin()
- , transitions.end()
- , []( BufferTransition const & transition )
- {
- bool result = false;
-
- if ( transition.inputAttach.isStorageBuffer() )
- {
- auto & inputPass = *transition.inputAttach.pass;
- auto pit = std::find_if( inputPass.buffers.begin()
- , inputPass.buffers.end()
- , [&transition]( Attachment const & lookup )
- {
- return lookup.isStorageBuffer()
- && lookup == transition.inputAttach;
- } );
- result = pit == inputPass.buffers.end();
- }
-
- return result;
- } );
- transitions.erase( it, transitions.end() );
- return transitions;
- }
}
bool operator==( ViewTransition const & lhs, ViewTransition const & rhs )
@@ -114,10 +56,4 @@ namespace crg
return { attTran::mergeIdenticalTransitionsT( std::move( transitions.viewTransitions ) )
, attTran::mergeIdenticalTransitionsT( std::move( transitions.bufferTransitions ) ) };
}
-
- AttachmentTransitions reduceDirectPaths( AttachmentTransitions transitions )
- {
- return { attTran::reduceDirectPathsT( std::move( transitions.viewTransitions ) )
- , attTran::reduceDirectPathsT( std::move( transitions.bufferTransitions ) ) };
- }
}
diff --git a/source/RenderGraph/BuilderCommon.cpp b/source/RenderGraph/BuilderCommon.cpp
deleted file mode 100644
index 33cb0ea..0000000
--- a/source/RenderGraph/BuilderCommon.cpp
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
-This file belongs to FrameGraph.
-See LICENSE file in root folder.
-*/
-#include "BuilderCommon.hpp"
-
-#include "RenderGraph/AttachmentTransition.hpp"
-#include "RenderGraph/FramePass.hpp"
-
-#include
-
-namespace crg::builder
-{
- FramePassSet retrieveRoots( FramePassDependencies const & dependencies )
- {
- FramePassSet result;
- uint32_t dstCount = 0u;
-
- // Retrieve passes for which no transition is set.
- for ( auto & depsIt : dependencies )
- {
- if ( depsIt.transitions.viewTransitions.empty()
- && depsIt.transitions.bufferTransitions.empty() )
- {
- result.insert( depsIt.pass );
- }
- else
- {
- dstCount += uint32_t( std::count_if( depsIt.transitions.viewTransitions.begin()
- , depsIt.transitions.viewTransitions.end()
- , []( ViewTransition const & lookup )
- {
- return lookup.inputAttach.getFlags() != 0;
- } ) );
- dstCount += uint32_t( std::count_if( depsIt.transitions.bufferTransitions.begin()
- , depsIt.transitions.bufferTransitions.end()
- , []( BufferTransition const & lookup )
- {
- return lookup.inputAttach.getFlags() != 0;
- } ) );
- }
- }
-
- if ( !dstCount )
- {
- for ( auto & depsIt : dependencies )
- {
- result.insert( depsIt.pass );
- }
- }
-
- return result;
- }
-
- FramePassSet retrieveLeafs( FramePassDependencies const & dependencies )
- {
- FramePassSet result;
- // Retrieve passes that are not listed in other passes' transitions source.
- for ( auto & depsIt : dependencies )
- {
- auto it = std::find_if( dependencies.begin()
- , dependencies.end()
- , [&depsIt]( FramePassTransitions const & lookup )
- {
- return lookup.pass != depsIt.pass
- && ( lookup.transitions.viewTransitions.end() != std::find_if( lookup.transitions.viewTransitions.begin()
- , lookup.transitions.viewTransitions.end()
- , [&depsIt]( ViewTransition const & ilookup )
- {
- return ilookup.outputAttach.pass == depsIt.pass;
- } )
- || lookup.transitions.bufferTransitions.end() != std::find_if( lookup.transitions.bufferTransitions.begin()
- , lookup.transitions.bufferTransitions.end()
- , [&depsIt]( BufferTransition const & ilookup )
- {
- return ilookup.outputAttach.pass == depsIt.pass;
- } ) );
- } );
-
- if ( it == dependencies.end() )
- {
- result.insert( depsIt.pass );
- }
- }
-
- return result;
- }
-}
diff --git a/source/RenderGraph/BuilderCommon.hpp b/source/RenderGraph/BuilderCommon.hpp
index 6f1a59e..9856b73 100644
--- a/source/RenderGraph/BuilderCommon.hpp
+++ b/source/RenderGraph/BuilderCommon.hpp
@@ -12,9 +12,6 @@ namespace crg::builder
{
using FramePassSet = std::set< FramePass const * >;
- FramePassSet retrieveRoots( FramePassDependencies const & dependencies );
- FramePassSet retrieveLeafs( FramePassDependencies const & dependencies );
-
template< typename TypeT >
void filter( std::vector< TypeT > const & inputs
, std::function< bool( TypeT const & ) > filterFunc
diff --git a/source/RenderGraph/FrameGraph.cpp b/source/RenderGraph/FrameGraph.cpp
index 4526552..7272626 100644
--- a/source/RenderGraph/FrameGraph.cpp
+++ b/source/RenderGraph/FrameGraph.cpp
@@ -7,11 +7,11 @@ See LICENSE file in root folder.
#include "RenderGraph/Exception.hpp"
#include "RenderGraph/FramePass.hpp"
#include "RenderGraph/FramePassGroup.hpp"
+#include "RenderGraph/Log.hpp"
#include "RenderGraph/ResourceHandler.hpp"
#include "RenderGraph/RunnableGraph.hpp"
#include "FramePassDependenciesBuilder.hpp"
#include "GraphBuilder.hpp"
-#include "ResourceOptimiser.hpp"
#include
@@ -110,7 +110,8 @@ namespace crg
if ( !added )
{
- CRG_Exception( "Couldn't sort passes:" );
+ Logger::logError( "Couldn't sort passes" );
+ CRG_Exception( "Couldn't sort passes" );
}
}
@@ -201,6 +202,7 @@ namespace crg
if ( passes.empty() )
{
+ Logger::logWarning( "No FramePass registered." );
CRG_Exception( "No FramePass registered." );
}
diff --git a/source/RenderGraph/FramePassGroup.cpp b/source/RenderGraph/FramePassGroup.cpp
index d08f516..fa31ed8 100644
--- a/source/RenderGraph/FramePassGroup.cpp
+++ b/source/RenderGraph/FramePassGroup.cpp
@@ -5,6 +5,7 @@ See LICENSE file in root folder.
#include "RenderGraph/FramePassGroup.hpp"
#include "RenderGraph/Exception.hpp"
+#include "RenderGraph/Log.hpp"
#include "RenderGraph/FrameGraph.hpp"
#include
@@ -71,6 +72,7 @@ namespace crg
{
if ( hasPass( passName ) )
{
+ Logger::logWarning( "Duplicate FramePass name detected." );
CRG_Exception( "Duplicate FramePass name detected." );
}
diff --git a/source/RenderGraph/GraphContext.cpp b/source/RenderGraph/GraphContext.cpp
index 5c298f7..7cdf452 100644
--- a/source/RenderGraph/GraphContext.cpp
+++ b/source/RenderGraph/GraphContext.cpp
@@ -267,6 +267,7 @@ namespace crg
typeBits >>= 1;
}
+ Logger::logError( "Could not deduce memory type" );
CRG_Exception( "Could not deduce memory type" );
}
@@ -435,6 +436,7 @@ namespace crg
{
if ( result != VK_SUCCESS )
{
+ Logger::logError( stepName );
CRG_Exception( stepName );
}
}
diff --git a/source/RenderGraph/GraphNode.cpp b/source/RenderGraph/GraphNode.cpp
index 7b8fb0b..599182a 100644
--- a/source/RenderGraph/GraphNode.cpp
+++ b/source/RenderGraph/GraphNode.cpp
@@ -99,30 +99,6 @@ namespace crg
, std::move( nextInputAttaches ) );
}
- GraphAdjacentNode GraphNode::findInNext( FramePass const & pass )const
- {
- auto it = std::find_if( next.begin()
- , next.end()
- , [&pass]( ConstGraphAdjacentNode lookup )
- {
- return getFramePass( *lookup ) == &pass;
- } );
- return ( next.end() != it )
- ? *it
- : nullptr;
- }
-
- bool GraphNode::hasInNext( ConstGraphAdjacentNode const & node )const
- {
- auto it = std::find_if( next.begin()
- , next.end()
- , [&node]( ConstGraphAdjacentNode lookup )
- {
- return lookup == node;
- } );
- return it != next.end();
- }
-
AttachmentTransitions const & GraphNode::getInputAttaches( ConstGraphAdjacentNode const pred )const
{
auto it = inputAttaches.find( pred );
diff --git a/source/RenderGraph/Log.cpp b/source/RenderGraph/Log.cpp
index cd02b27..ece938b 100644
--- a/source/RenderGraph/Log.cpp
+++ b/source/RenderGraph/Log.cpp
@@ -60,46 +60,6 @@ namespace crg
doGetInstance().m_error( message, newLine );
}
- void Logger::logTrace( std::ostream const & message, bool newLine )
- {
- auto sbuf = message.rdbuf();
- std::stringstream ss;
- ss << sbuf;
- doGetInstance().m_trace( ss.str(), newLine );
- }
-
- void Logger::logDebug( std::ostream const & message, bool newLine )
- {
- auto sbuf = message.rdbuf();
- std::stringstream ss;
- ss << sbuf;
- doGetInstance().m_debug( ss.str(), newLine );
- }
-
- void Logger::logInfo( std::ostream const & message, bool newLine )
- {
- auto sbuf = message.rdbuf();
- std::stringstream ss;
- ss << sbuf;
- doGetInstance().m_info( ss.str(), newLine );
- }
-
- void Logger::logWarning( std::ostream const & message, bool newLine )
- {
- auto sbuf = message.rdbuf();
- std::stringstream ss;
- ss << sbuf;
- doGetInstance().m_warning( ss.str(), newLine );
- }
-
- void Logger::logError( std::ostream const & message, bool newLine )
- {
- auto sbuf = message.rdbuf();
- std::stringstream ss;
- ss << sbuf;
- doGetInstance().m_error( ss.str(), newLine );
- }
-
void Logger::setTraceCallback( LogCallback callback )
{
doGetInstance().m_trace = std::move( callback );
diff --git a/source/RenderGraph/RecordContext.cpp b/source/RenderGraph/RecordContext.cpp
index 8015fc5..c12a0dc 100644
--- a/source/RenderGraph/RecordContext.cpp
+++ b/source/RenderGraph/RecordContext.cpp
@@ -4,6 +4,7 @@ See LICENSE file in root folder.
#include "RenderGraph/RecordContext.hpp"
#include "RenderGraph/Exception.hpp"
+#include "RenderGraph/Log.hpp"
#include "RenderGraph/ResourceHandler.hpp"
#include "RenderGraph/RunnableGraph.hpp"
@@ -539,6 +540,7 @@ namespace crg
if ( !m_resources )
{
assert( false );
+ Logger::logError( "No resources available." );
CRG_Exception( "No resources available." );
}
diff --git a/source/RenderGraph/ResourceOptimiser.cpp b/source/RenderGraph/ResourceOptimiser.cpp
deleted file mode 100644
index 521fae4..0000000
--- a/source/RenderGraph/ResourceOptimiser.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
-This file belongs to FrameGraph.
-See LICENSE file in root folder.
-*/
-#include "ResourceOptimiser.hpp"
-
-#include "RenderGraph/AttachmentTransition.hpp"
-#include "RenderGraph/FramePass.hpp"
-#include "RenderGraph/ImageData.hpp"
-
-#include
-#include
-
-#define CRG_MarkAttachments 0
-
-namespace crg::builder
-{
-#if CRG_MarkAttachments
- namespace resopt
- {
- static void markAttachment( Attachment & attachment
- , Attachment::Flag toMark )
- {
- if ( attachment.hasFlag( toMark ) )
- {
- attachment.setUnique();
- }
- }
-
- static void markAttachment( std::optional< Attachment > & attachment
- , Attachment::Flag toMark )
- {
- if ( attachment )
- {
- markAttachment( *attachment, toMark );
- }
- }
-
- static void markAttachments( AttachmentArray & attachments
- , Attachment::Flag toMark )
- {
- for ( auto attachment : attachments )
- {
- markAttachment( attachment, toMark );
- }
- }
-
- static void markPassAttachments( FramePass & pass
- , Attachment::Flag toMark )
- {
- markAttachments( pass.sampled, toMark );
- markAttachments( pass.colourInOuts, toMark );
- markAttachment( pass.depthStencilInOut, toMark );
- }
-
- static void markPassesAttachments( FramePassSet & passes
- , Attachment::Flag toMark )
- {
- for ( auto pass : passes )
- {
- markPassAttachments( *pass, toMark );
- }
- }
-
- template< typename DataT >
- using IdDataMap = std::map< DataT *, std::vector< Id< DataT > > >;
-
- template< typename DataT >
- static IdDataMap< DataT > sortPerData( IdDataOwnerCont< DataT > const & images )
- {
- IdDataMap< DataT > result;
- return result;
- }
- }
-#endif
-
- ImageIdAliasMap optimiseImages( [[maybe_unused]] ImageIdDataOwnerCont const & images
- , [[maybe_unused]] FramePassDependencies const & dependencies
- , [[maybe_unused]] RootNode const & root )
- {
-#if CRG_MarkAttachments
- ImageIdAliasMap result;
- // We mark root and leaf nodes images as non mergeable.
- auto roots = retrieveRoots( dependencies );
- auto leaves = retrieveLeafs( dependencies );
- resopt::markPassesAttachments( roots, Attachment::Flag::Output );
- resopt::markPassesAttachments( leaves, Attachment::Flag::Input );
-
- // We'll need to see which image we can merge, given their ImageData,
- // and their flags.
- resopt::sortPerData( images );
-#endif
-
- return ImageIdAliasMap{};
- }
-
- ImageViewIdAliasMap optimiseImageViews( [[maybe_unused]] ImageViewIdDataOwnerCont const & imageViews
- , [[maybe_unused]] FramePassDependencies const & dependencies
- , [[maybe_unused]] RootNode const & root )
- {
- ImageViewIdAliasMap result;
- return result;
- }
-}
diff --git a/source/RenderGraph/ResourceOptimiser.hpp b/source/RenderGraph/ResourceOptimiser.hpp
deleted file mode 100644
index 24a9dc0..0000000
--- a/source/RenderGraph/ResourceOptimiser.hpp
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
-This file belongs to FrameGraph.
-See LICENSE file in root folder.
-*/
-#include "BuilderCommon.hpp"
-
-namespace crg::builder
-{
- void mergeViews( FramePassPtrArray const & passes );
- ImageIdAliasMap optimiseImages( ImageIdDataOwnerCont const & images
- , FramePassDependencies const & dependencies
- , RootNode const & root );
- ImageViewIdAliasMap optimiseImageViews( ImageViewIdDataOwnerCont const & imageViews
- , FramePassDependencies const & dependencies
- , RootNode const & root );
-}
diff --git a/source/RenderGraph/RunnablePass.cpp b/source/RenderGraph/RunnablePass.cpp
index 6ba34a8..cff0ae6 100644
--- a/source/RenderGraph/RunnablePass.cpp
+++ b/source/RenderGraph/RunnablePass.cpp
@@ -30,6 +30,17 @@ namespace crg
//*********************************************************************************************
+ void checkUndefinedInput( std::string const & stepName
+ , Attachment const & attach
+ , ImageViewId const & view
+ , VkImageLayout currentLayout )
+ {
+ if ( !attach.isTransitionView() && attach.isInput() && currentLayout == VK_IMAGE_LAYOUT_UNDEFINED )
+ {
+ Logger::logWarning( stepName + " - [" + attach.pass->getFullName() + "]: Input view [" + view.data->name + "] is currently in undefined layout" );
+ }
+ }
+
void convert( SemaphoreWaitArray const & toWait
, std::vector< VkSemaphore > & semaphores
, std::vector< VkPipelineStageFlags > & dstStageMasks )
@@ -389,17 +400,6 @@ namespace crg
}
}
- void checkUndefinedInput( std::string const & stepName
- , Attachment const & attach
- , ImageViewId const & view
- , VkImageLayout currentLayout )
- {
- if ( !attach.isTransitionView() && attach.isInput() && currentLayout == VK_IMAGE_LAYOUT_UNDEFINED )
- {
- Logger::logWarning( stepName + " - [" + attach.pass->getFullName() + "]: Input view [" + view.data->name + "] is currently in undefined layout" );
- }
- }
-
void RunnablePass::recordOne( CommandBuffer & enabled
, uint32_t index
, RecordContext & context )
@@ -561,61 +561,6 @@ namespace crg
}
}
- SemaphoreWaitArray RunnablePass::run( SemaphoreWait toWait
- , VkQueue queue )
- {
- return run( ( toWait.semaphore
- ? SemaphoreWaitArray{ 1u, toWait }
- : SemaphoreWaitArray{} )
- , queue );
- }
-
- SemaphoreWaitArray RunnablePass::run( SemaphoreWaitArray const & toWait
- , VkQueue queue )
- {
- if ( !m_callbacks.isEnabled() )
- {
- return toWait;
- }
-
- auto index = m_callbacks.getPassIndex();
- assert( m_passes.size() > index );
- auto & pass = m_passes[index];
-
- if ( pass.toReset )
- {
- crg::RunnablePass::resetCommandBuffer( index );
- crg::RunnablePass::reRecordCurrent();
- }
-
- if ( m_context.device )
- {
- std::vector< VkSemaphore > semaphores;
- std::vector< VkPipelineStageFlags > dstStageMasks;
- convert( toWait, semaphores, dstStageMasks );
- auto & cb = pass.commandBuffer;
- m_timer.notifyPassRender();
- VkSubmitInfo submitInfo{ VK_STRUCTURE_TYPE_SUBMIT_INFO
- , nullptr
- , uint32_t( semaphores.size() )
- , semaphores.data()
- , dstStageMasks.data()
- , 1u
- , &cb.commandBuffer
- , 1u
- , &pass.semaphore };
- pass.fence.reset();
- m_context.vkQueueSubmit( queue
- , 1u
- , &submitInfo
- , pass.fence );
- }
-
- return { 1u
- , { pass.semaphore
- , m_callbacks.getPipelineState().pipelineStage } };
- }
-
void RunnablePass::resetCommandBuffer( uint32_t passIndex )
{
if ( !m_context.device )
diff --git a/source/RenderGraph/RunnablePasses/RenderQuadHolder.cpp b/source/RenderGraph/RunnablePasses/RenderQuadHolder.cpp
index 5063012..e8432a6 100644
--- a/source/RenderGraph/RunnablePasses/RenderQuadHolder.cpp
+++ b/source/RenderGraph/RunnablePasses/RenderQuadHolder.cpp
@@ -120,7 +120,12 @@ namespace crg
m_pipeline.recordInto( context, commandBuffer, index );
m_config.recordInto( context, commandBuffer, index );
VkDeviceSize offset{};
- context->vkCmdBindVertexBuffers( commandBuffer, 0u, 1u, &m_vertexBuffer->buffer.buffer( index ), &offset );
+
+ if ( m_vertexBuffer
+ && m_vertexBuffer->buffer.buffer( index ) )
+ {
+ context->vkCmdBindVertexBuffers( commandBuffer, 0u, 1u, &m_vertexBuffer->buffer.buffer( index ), &offset );
+ }
if ( auto indirectBuffer = m_config.indirectBuffer.buffer.buffer( index ) )
{
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 3d80ff8..7707172 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -1,4 +1,55 @@
enable_testing()
+include( OpenCppCoverage )
+
+if(OpenCppCoverage_FOUND)
+ function(MyOpenCppCoverage_add_target target)
+ cmake_parse_arguments(PARSE_ARGV 1 ARG "" "WORKING_DIRECTORY" "SOURCES;MODULES;OCC_ARGS;ARGS")
+ if(ARG_UNPARSED_ARGUMENTS)
+ message(FATAL_ERROR "Invalid argument(s): ${ARG_UNPARSED_ARGUMENTS}")
+ endif()
+
+ get_property(counter GLOBAL PROPERTY OpenCppCoverage_COUNTER)
+ if(NOT counter)
+ set(counter 1)
+ else()
+ math(EXPR counter "${counter} + 1")
+ endif()
+ set(outputFile ${CMAKE_CURRENT_BINARY_DIR}/OpenCppCoverage/cov-${counter}-${target}.bin)
+ set_property(GLOBAL PROPERTY OpenCppCoverage_COUNTER "${counter}")
+ set_property(GLOBAL APPEND PROPERTY OpenCppCoverage_SOURCES "${outputFile}")
+
+ if(NOT ARG_WORKING_DIRECTORY)
+ set(ARG_WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
+ endif()
+ if(NOT ARG_SOURCES)
+ file(TO_NATIVE_PATH ${PROJECT_SOURCE_DIR} ARG_SOURCES)
+ endif()
+ if(NOT ARG_MODULES)
+ file(TO_NATIVE_PATH ${PROJECT_BINARY_DIR} ARG_MODULES)
+ endif()
+
+ set(args "${ARG_OCC_ARGS}")
+ foreach(el IN LISTS ARG_SOURCES)
+ list(APPEND args --sources ${el})
+ endforeach()
+ foreach(el IN LISTS ARG_MODULES)
+ list(APPEND args --modules ${el})
+ endforeach()
+ file( TO_NATIVE_PATH "${args}" args )
+ add_custom_command(TARGET ${target}
+ POST_BUILD
+ COMMENT "Creating coverage for ${target}"
+ COMMAND ${OpenCppCoverage_BINARY}
+ --working_dir $
+ --export_type binary:${outputFile}
+ --cover_children
+ --quiet
+ ${args}
+ -- $ ${ARG_ARGS}
+ VERBATIM
+ )
+ endfunction()
+endif ()
set( TEST_NAME TestCommon )
@@ -20,6 +71,10 @@ add_library( crg::${TEST_NAME}
ALIAS
${TEST_NAME}
)
+target_sources( ${TEST_NAME}
+ PRIVATE
+ ${CRG_EDITORCONFIG_FILE}
+)
target_link_libraries( ${TEST_NAME}
PUBLIC
crg::RenderGraph
@@ -43,6 +98,10 @@ foreach ( TEST_FILE ${TEST_FILES} )
add_executable( ${TEST_NAME}
${TEST_FILE}
)
+ target_sources( ${TEST_NAME}
+ PRIVATE
+ ${CRG_EDITORCONFIG_FILE}
+ )
target_link_libraries( ${TEST_NAME}
PRIVATE
crg::TestCommon
@@ -69,6 +128,15 @@ foreach ( TEST_FILE ${TEST_FILES} )
)
endif ()
endif ()
+ if ( PROJECTS_COVERAGE )
+ MyOpenCppCoverage_add_target( ${TEST_NAME}
+ MODULES
+ $
+ SOURCES
+ ${CRG_SOURCE_DIR}/include
+ ${CRG_SOURCE_DIR}/source
+ )
+ endif ()
add_test(
NAME ${TEST_NAME}
COMMAND ${TEST_NAME}
@@ -80,3 +148,15 @@ foreach ( TEST_FILE ${TEST_FILES} )
RUNTIME DESTINATION bin
)
endforeach ()
+
+if ( PROJECTS_COVERAGE )
+ if ( PROJECTS_COVERAGE_HTML_RESULTS )
+ OpenCppCoverage_add_merge_target( RenderGraphCoverage
+ ${PROJECTS_DOCUMENTATION_OUTPUT_DIR}/RenderGraphCoverage
+ FORMAT html )
+ else ()
+ OpenCppCoverage_add_merge_target( RenderGraphCoverage
+ ${PROJECTS_DOCUMENTATION_OUTPUT_DIR}/RenderGraphCoverage.xml
+ FORMAT cobertura )
+ endif ()
+endif ()
diff --git a/test/Common.cpp b/test/Common.cpp
index 7312285..a7b6841 100644
--- a/test/Common.cpp
+++ b/test/Common.cpp
@@ -1,6 +1,7 @@
#include "Common.hpp"
#include
+#include
#include
#include
#include
@@ -139,6 +140,214 @@ namespace test
, { aspect, baseMipLevel, levelCount, baseArrayLayer, layerCount } };
}
+ crg::GraphContext & getDummyContext()
+ {
+ static crg::GraphContext context{ nullptr
+ , nullptr
+ , nullptr
+ , VkPhysicalDeviceMemoryProperties{}
+ , VkPhysicalDeviceProperties{}
+ , false
+ , nullptr };
+ context.vkCreateGraphicsPipelines = PFN_vkCreateGraphicsPipelines( []( VkDevice, VkPipelineCache, uint32_t createInfoCount, const VkGraphicsPipelineCreateInfo * pCreateInfos, const VkAllocationCallbacks *, VkPipeline * pPipelines )
+ {
+ for ( uint32_t i = 0u; i < createInfoCount; ++i )
+ {
+ pPipelines[i] = ( VkPipeline )uintptr_t( i + 1u );
+ }
+ return VK_SUCCESS;
+ } );
+ context.vkCreateComputePipelines = PFN_vkCreateComputePipelines( []( VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkComputePipelineCreateInfo * pCreateInfos, const VkAllocationCallbacks * pAllocator, VkPipeline * pPipelines )
+ {
+ for ( uint32_t i = 0u; i < createInfoCount; ++i )
+ {
+ pPipelines[i] = ( VkPipeline )uintptr_t( i + 1u );
+ }
+ return VK_SUCCESS;
+ } );
+ context.vkCreatePipelineLayout = PFN_vkCreatePipelineLayout( []( VkDevice device, const VkPipelineLayoutCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkPipelineLayout * pPipelineLayout )
+ {
+ *pPipelineLayout = ( VkPipelineLayout )1u;
+ return VK_SUCCESS;
+ } );
+ context.vkCreateDescriptorSetLayout = PFN_vkCreateDescriptorSetLayout( []( VkDevice device, const VkDescriptorSetLayoutCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkDescriptorSetLayout * pSetLayout )
+ {
+ *pSetLayout = ( VkDescriptorSetLayout )1u;
+ return VK_SUCCESS;
+ } );
+ context.vkCreateDescriptorPool = PFN_vkCreateDescriptorPool( []( VkDevice device, const VkDescriptorPoolCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkDescriptorPool * pDescriptorPool )
+ {
+ *pDescriptorPool = ( VkDescriptorPool )1u;
+ return VK_SUCCESS;
+ } );
+ context.vkAllocateDescriptorSets = PFN_vkAllocateDescriptorSets( []( VkDevice device, const VkDescriptorSetAllocateInfo * pAllocateInfo, VkDescriptorSet * pDescriptorSets )
+ {
+ if ( !pAllocateInfo )
+ return VK_ERROR_UNKNOWN;
+
+ for ( uint32_t i = 0u; i < pAllocateInfo->descriptorSetCount; ++i )
+ {
+ pDescriptorSets[i] = ( VkDescriptorSet )uintptr_t( i + 1u );
+ }
+ return VK_SUCCESS;
+ } );
+ context.vkCreateBuffer = PFN_vkCreateBuffer( []( VkDevice device, const VkBufferCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkBuffer * pBuffer )
+ {
+ *pBuffer = ( VkBuffer )1u;
+ return VK_SUCCESS;
+ } );
+ context.vkAllocateMemory = PFN_vkAllocateMemory( []( VkDevice device, const VkMemoryAllocateInfo * pAllocateInfo, const VkAllocationCallbacks * pAllocator, VkDeviceMemory * pMemory )
+ {
+ *pMemory = ( VkDeviceMemory )1u;
+ return VK_SUCCESS;
+ } );
+ context.vkCreateRenderPass = PFN_vkCreateRenderPass( []( VkDevice device, const VkRenderPassCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkRenderPass * pRenderPass )
+ {
+ *pRenderPass = ( VkRenderPass )1u;
+ return VK_SUCCESS;
+ } );
+ context.vkCreateFramebuffer = PFN_vkCreateFramebuffer( []( VkDevice device, const VkFramebufferCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkFramebuffer * pFramebuffer )
+ {
+ *pFramebuffer = ( VkFramebuffer )1u;
+ return VK_SUCCESS;
+ } );
+ context.vkCreateImage = PFN_vkCreateImage( []( VkDevice device, const VkImageCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkImage * pImage )
+ {
+ *pImage = ( VkImage )1u;
+ return VK_SUCCESS;
+ } );
+ context.vkCreateImageView = PFN_vkCreateImageView( []( VkDevice device, const VkImageViewCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkImageView * pView )
+ {
+ *pView = ( VkImageView )1u;
+ return VK_SUCCESS;
+ } );
+ context.vkCreateSampler = PFN_vkCreateSampler( []( VkDevice device, const VkSamplerCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkSampler * pSampler )
+ {
+ *pSampler = ( VkSampler )1u;
+ return VK_SUCCESS;
+ } );
+ context.vkCreateCommandPool = PFN_vkCreateCommandPool( []( VkDevice device, const VkCommandPoolCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkCommandPool * pCommandPool )
+ {
+ *pCommandPool = ( VkCommandPool )1u;
+ return VK_SUCCESS;
+ } );
+ context.vkAllocateCommandBuffers = PFN_vkAllocateCommandBuffers( []( VkDevice device, const VkCommandBufferAllocateInfo * pAllocateInfo, VkCommandBuffer * pCommandBuffers )
+ {
+ if ( !pAllocateInfo )
+ return VK_ERROR_UNKNOWN;
+
+ for ( uint32_t i = 0u; i < pAllocateInfo->commandBufferCount; ++i )
+ {
+ pCommandBuffers[i] = ( VkCommandBuffer )uintptr_t( i + 1u );
+ }
+ return VK_SUCCESS;
+ } );
+ context.vkCreateSemaphore = PFN_vkCreateSemaphore( []( VkDevice device, const VkSemaphoreCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkSemaphore * pSemaphore )
+ {
+ *pSemaphore = ( VkSemaphore )1u;
+ return VK_SUCCESS;
+ } );
+ context.vkCreateQueryPool = PFN_vkCreateQueryPool( []( VkDevice device, const VkQueryPoolCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkQueryPool * pQueryPool )
+ {
+ *pQueryPool = ( VkQueryPool )1u;
+ return VK_SUCCESS;
+ } );
+ context.vkCreateEvent = PFN_vkCreateEvent( []( VkDevice device, const VkEventCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkEvent * pEvent )
+ {
+ *pEvent = ( VkEvent )1u;
+ return VK_SUCCESS;
+ } );
+ context.vkCreateFence = PFN_vkCreateFence( []( VkDevice device, const VkFenceCreateInfo * pCreateInfo, const VkAllocationCallbacks * pAllocator, VkFence * pFence )
+ {
+ *pFence = ( VkFence )1u;
+ return VK_SUCCESS;
+ } );
+
+ context.vkDestroyPipeline = PFN_vkDestroyPipeline( []( VkDevice device, VkPipeline pipeline, const VkAllocationCallbacks * pAllocator ){} );
+ context.vkDestroyPipelineLayout = PFN_vkDestroyPipelineLayout( []( VkDevice device, VkPipelineLayout pipelineLayout, const VkAllocationCallbacks * pAllocator ){} );
+ context.vkDestroyDescriptorSetLayout = PFN_vkDestroyDescriptorSetLayout( []( VkDevice device, VkDescriptorSetLayout descriptorSetLayout, const VkAllocationCallbacks* pAllocator ){} );
+ context.vkDestroyDescriptorPool = PFN_vkDestroyDescriptorPool( []( VkDevice device, VkDescriptorPool descriptorPool, const VkAllocationCallbacks * pAllocator ){} );
+ context.vkFreeDescriptorSets = PFN_vkFreeDescriptorSets( []( VkDevice device, VkDescriptorPool descriptorPool, uint32_t descriptorSetCount, const VkDescriptorSet * pDescriptorSets ){ return VK_SUCCESS; } );
+ context.vkDestroyBuffer = PFN_vkDestroyBuffer( []( VkDevice device, VkBuffer buffer, const VkAllocationCallbacks * pAllocator ){} );
+ context.vkFreeMemory = PFN_vkFreeMemory( []( VkDevice device, VkDeviceMemory memory, const VkAllocationCallbacks * pAllocator ){} );
+ context.vkDestroyRenderPass = PFN_vkDestroyRenderPass( []( VkDevice device, VkRenderPass renderPass, const VkAllocationCallbacks * pAllocator ){} );
+ context.vkDestroyFramebuffer = PFN_vkDestroyFramebuffer( []( VkDevice device, VkFramebuffer framebuffer, const VkAllocationCallbacks * pAllocator ){} );
+ context.vkDestroyImage = PFN_vkDestroyImage( []( VkDevice device, VkImage image, const VkAllocationCallbacks * pAllocator ){} );
+ context.vkDestroyImageView = PFN_vkDestroyImageView( []( VkDevice device, VkImageView imageView, const VkAllocationCallbacks * pAllocator ){} );
+ context.vkDestroySampler = PFN_vkDestroySampler( []( VkDevice device, VkSampler sampler, const VkAllocationCallbacks * pAllocator ){} );
+ context.vkDestroyCommandPool = PFN_vkDestroyCommandPool( []( VkDevice device, VkCommandPool commandPool, const VkAllocationCallbacks * pAllocator ){} );
+ context.vkFreeCommandBuffers = PFN_vkFreeCommandBuffers( []( VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount, const VkCommandBuffer * pCommandBuffers ){} );
+ context.vkDestroySemaphore = PFN_vkDestroySemaphore( []( VkDevice device, VkSemaphore semaphore, const VkAllocationCallbacks * pAllocator ){} );
+ context.vkDestroyQueryPool = PFN_vkDestroyQueryPool( []( VkDevice device, VkQueryPool queryPool, const VkAllocationCallbacks * pAllocator ){} );
+ context.vkDestroyEvent = PFN_vkDestroyEvent( []( VkDevice device, VkEvent event, const VkAllocationCallbacks * pAllocator ){} );
+ context.vkDestroyFence = PFN_vkDestroyFence( []( VkDevice device, VkFence fence, const VkAllocationCallbacks * pAllocator ){} );
+
+ context.vkGetBufferMemoryRequirements = PFN_vkGetBufferMemoryRequirements( []( VkDevice device, VkBuffer buffer, VkMemoryRequirements * pMemoryRequirements ){} );
+ context.vkGetImageMemoryRequirements = PFN_vkGetImageMemoryRequirements( []( VkDevice device, VkImage image, VkMemoryRequirements * pMemoryRequirements ){} );
+ context.vkBindBufferMemory = PFN_vkBindBufferMemory( []( VkDevice device, VkBuffer buffer, VkDeviceMemory memory, VkDeviceSize memoryOffset ){ return VK_SUCCESS; } );
+ context.vkBindImageMemory = PFN_vkBindImageMemory( []( VkDevice device, VkImage image, VkDeviceMemory memory, VkDeviceSize memoryOffset ){ return VK_SUCCESS; } );
+ context.vkMapMemory = PFN_vkMapMemory( []( VkDevice device, VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size, VkMemoryMapFlags flags, void ** ppData ){ return VK_SUCCESS; } );
+ context.vkUnmapMemory = PFN_vkUnmapMemory( []( VkDevice device, VkDeviceMemory memory ){} );
+ context.vkFlushMappedMemoryRanges = PFN_vkFlushMappedMemoryRanges( []( VkDevice device, uint32_t memoryRangeCount, const VkMappedMemoryRange * pMemoryRanges ){ return VK_SUCCESS; } );
+ context.vkInvalidateMappedMemoryRanges = PFN_vkInvalidateMappedMemoryRanges( []( VkDevice device, uint32_t memoryRangeCount, const VkMappedMemoryRange * pMemoryRanges ){ return VK_SUCCESS; } );
+ context.vkUpdateDescriptorSets = PFN_vkUpdateDescriptorSets( []( VkDevice device, uint32_t descriptorWriteCount, const VkWriteDescriptorSet * pDescriptorWrites, uint32_t descriptorCopyCount, const VkCopyDescriptorSet * pDescriptorCopies ){} );
+ context.vkBeginCommandBuffer = PFN_vkBeginCommandBuffer( []( VkCommandBuffer commandBuffer, const VkCommandBufferBeginInfo * pBeginInfo ){ return VK_SUCCESS; } );
+ context.vkEndCommandBuffer = PFN_vkEndCommandBuffer( []( VkCommandBuffer commandBuffer ){ return VK_SUCCESS; } );
+ context.vkQueueSubmit = PFN_vkQueueSubmit( []( VkQueue queue, uint32_t submitCount, const VkSubmitInfo * pSubmits, VkFence fence ){ return VK_SUCCESS; } );
+ context.vkGetQueryPoolResults = PFN_vkGetQueryPoolResults( []( VkDevice device, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount, size_t dataSize, void * pData, VkDeviceSize stride, VkQueryResultFlags flags ){ return VK_SUCCESS; } );
+ context.vkResetCommandBuffer = PFN_vkResetCommandBuffer( []( VkCommandBuffer commandBuffer, VkCommandBufferResetFlags flags ){ return VK_SUCCESS; } );
+ context.vkResetEvent = PFN_vkResetEvent( []( VkDevice device, VkEvent event ){ return VK_SUCCESS; } );
+ context.vkSetEvent = PFN_vkSetEvent( []( VkDevice device, VkEvent event ){ return VK_SUCCESS; } );
+ context.vkGetEventStatus = PFN_vkGetEventStatus( []( VkDevice device, VkEvent event ){ return VK_SUCCESS; } );
+ context.vkGetFenceStatus = PFN_vkGetFenceStatus( []( VkDevice device, VkFence fence ){ return VK_SUCCESS; } );
+ context.vkWaitForFences = PFN_vkWaitForFences( []( VkDevice device, uint32_t fenceCount, const VkFence * pFences, VkBool32 waitAll, uint64_t timeout ){ return VK_SUCCESS; } );
+ context.vkResetFences = PFN_vkResetFences( []( VkDevice device, uint32_t fenceCount, const VkFence * pFences ){ return VK_SUCCESS; } );
+
+ context.vkCmdBindPipeline = PFN_vkCmdBindPipeline( []( VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline ){} );
+ context.vkCmdBindDescriptorSets = PFN_vkCmdBindDescriptorSets( []( VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout, uint32_t firstSet, uint32_t descriptorSetCount, const VkDescriptorSet * pDescriptorSets, uint32_t dynamicOffsetCount, const uint32_t * pDynamicOffsets ){} );
+ context.vkCmdBindVertexBuffers = PFN_vkCmdBindVertexBuffers( []( VkCommandBuffer commandBuffer, uint32_t firstBinding, uint32_t bindingCount, const VkBuffer * pBuffers, const VkDeviceSize * pOffsets ){} );
+ context.vkCmdBindIndexBuffer = PFN_vkCmdBindIndexBuffer( []( VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkIndexType indexType ){} );
+ context.vkCmdClearColorImage = PFN_vkCmdClearColorImage( []( VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout, const VkClearColorValue * pColor, uint32_t rangeCount, const VkImageSubresourceRange * pRanges ){} );
+ context.vkCmdClearDepthStencilImage = PFN_vkCmdClearDepthStencilImage( []( VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout, const VkClearDepthStencilValue * pDepthStencil, uint32_t rangeCount, const VkImageSubresourceRange * pRanges ){} );
+ context.vkCmdDispatch = PFN_vkCmdDispatch( []( VkCommandBuffer commandBuffer, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ ){} );
+ context.vkCmdDispatchIndirect = PFN_vkCmdDispatchIndirect( []( VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset ){} );
+ context.vkCmdDraw = PFN_vkCmdDraw( []( VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance ){} );
+ context.vkCmdDrawIndexed = PFN_vkCmdDrawIndexed( []( VkCommandBuffer commandBuffer, uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance ){} );
+ context.vkCmdDrawIndexedIndirect = PFN_vkCmdDrawIndexedIndirect( []( VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride ){} );
+ context.vkCmdDrawIndirect = PFN_vkCmdDrawIndirect( []( VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride ){} );
+ context.vkCmdBeginRenderPass = PFN_vkCmdBeginRenderPass( []( VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo * pRenderPassBegin, VkSubpassContents contents ){} );
+ context.vkCmdEndRenderPass = PFN_vkCmdEndRenderPass( []( VkCommandBuffer commandBuffer ){} );
+ context.vkCmdPushConstants = PFN_vkCmdPushConstants( []( VkCommandBuffer commandBuffer, VkPipelineLayout layout, VkShaderStageFlags stageFlags, uint32_t offset, uint32_t size, const void * pValues ){} );
+ context.vkCmdResetQueryPool = PFN_vkCmdResetQueryPool( []( VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount ){} );
+ context.vkCmdWriteTimestamp = PFN_vkCmdWriteTimestamp( []( VkCommandBuffer commandBuffer, VkPipelineStageFlagBits pipelineStage, VkQueryPool queryPool, uint32_t query ){} );
+ context.vkCmdPipelineBarrier = PFN_vkCmdPipelineBarrier( []( VkCommandBuffer commandBuffer, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkDependencyFlags dependencyFlags, uint32_t memoryBarrierCount, const VkMemoryBarrier * pMemoryBarriers, uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier * pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier * pImageMemoryBarriers ){} );
+ context.vkCmdBlitImage = PFN_vkCmdBlitImage( []( VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageBlit * pRegions, VkFilter filter ){} );
+ context.vkCmdCopyBuffer = PFN_vkCmdCopyBuffer( []( VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkBuffer dstBuffer, uint32_t regionCount, const VkBufferCopy * pRegions ){} );
+ context.vkCmdCopyBufferToImage = PFN_vkCmdCopyBufferToImage( []( VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkBufferImageCopy * pRegions ){} );
+ context.vkCmdCopyImage = PFN_vkCmdCopyImage( []( VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageCopy * pRegions ){} );
+ context.vkCmdCopyImageToBuffer = PFN_vkCmdCopyImageToBuffer( []( VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkBuffer dstBuffer, uint32_t regionCount, const VkBufferImageCopy * pRegions ){} );
+ context.vkCmdExecuteCommands = PFN_vkCmdExecuteCommands( []( VkCommandBuffer commandBuffer, uint32_t commandBufferCount, const VkCommandBuffer * pCommandBuffers ){} );
+ context.vkCmdResetEvent = PFN_vkCmdResetEvent( []( VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask ){} );
+ context.vkCmdSetEvent = PFN_vkCmdSetEvent( []( VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask ){} );
+ context.vkCmdWaitEvents = PFN_vkCmdWaitEvents( []( VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent * pEvents, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, uint32_t memoryBarrierCount, const VkMemoryBarrier * pMemoryBarriers, uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier * pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier * pImageMemoryBarriers ){} );
+ context.vkCmdFillBuffer = PFN_vkCmdFillBuffer( []( VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data ){} );
+
+#if VK_EXT_debug_utils || VK_EXT_debug_marker
+# if VK_EXT_debug_utils
+ context.vkSetDebugUtilsObjectNameEXT = PFN_vkSetDebugUtilsObjectNameEXT();
+ context.vkCmdBeginDebugUtilsLabelEXT = PFN_vkCmdBeginDebugUtilsLabelEXT();
+ context.vkCmdEndDebugUtilsLabelEXT = PFN_vkCmdEndDebugUtilsLabelEXT();
+# endif
+# if VK_EXT_debug_marker
+ context.vkDebugMarkerSetObjectNameEXT = PFN_vkDebugMarkerSetObjectNameEXT();
+ context.vkCmdDebugMarkerBeginEXT = PFN_vkCmdDebugMarkerBeginEXT();
+ context.vkCmdDebugMarkerEndEXT = PFN_vkCmdDebugMarkerEndEXT();
+ context.vkCmdDebugMarkerInsertEXT = PFN_vkCmdDebugMarkerInsertEXT();
+# endif
+#endif
+ return context;
+ }
+
void display( TestCounts & testCounts
, std::ostream & stream
, crg::RunnableGraph & value
diff --git a/test/Common.hpp b/test/Common.hpp
index 1782797..d25bc13 100644
--- a/test/Common.hpp
+++ b/test/Common.hpp
@@ -23,6 +23,7 @@ namespace test
, uint32_t levelCount = 1u
, uint32_t baseArrayLayer = 0u
, uint32_t layerCount = 1u );
+ crg::GraphContext & getDummyContext();
void display( TestCounts & testCounts
, std::ostream & stream
diff --git a/test/TestRenderGraph.cpp b/test/TestRenderGraph.cpp
index ecb50b9..9e1d015 100644
--- a/test/TestRenderGraph.cpp
+++ b/test/TestRenderGraph.cpp
@@ -80,14 +80,7 @@ namespace
crg::GraphContext & getContext()
{
- static crg::GraphContext context{ nullptr
- , nullptr
- , nullptr
- , VkPhysicalDeviceMemoryProperties{}
- , VkPhysicalDeviceProperties{}
- , false
- , nullptr };
- return context;
+ return test::getDummyContext();
}
void checkOutputColourIsShaderReadOnly( test::TestCounts & testCounts
@@ -2050,23 +2043,24 @@ namespace
backgroundPass.addInOutDepthView( depthv );
backgroundPass.addOutputColourView( colourv );
- auto dirShadowMap = graph.createImage( test::createImage( "dirShadowMap", VK_FORMAT_X8_D24_UNORM_PACK32, 1u, 4u ) );
- auto dirVarianceMap = graph.createImage( test::createImage( "dirVarianceMap", VK_FORMAT_R32G32_SFLOAT, 1u, 4u ) );
- auto dirShadowMapv = graph.createView( test::createView( "dirShadowMapv", dirShadowMap, VK_FORMAT_X8_D24_UNORM_PACK32, 0u, 1u, 0u, 4u ) );
- auto dirVarianceMapv = graph.createView( test::createView( "dirVarianceMapv", dirVarianceMap, VK_FORMAT_R32G32_SFLOAT, 0u, 1u, 0u, 4u ) );
+ auto & dirGroup = graph.createPassGroup( "Directional" );
+ auto dirShadowMap = dirGroup.createImage( test::createImage( "dirShadowMap", VK_FORMAT_X8_D24_UNORM_PACK32, 1u, 4u ) );
+ auto dirVarianceMap = dirGroup.createImage( test::createImage( "dirVarianceMap", VK_FORMAT_R32G32_SFLOAT, 1u, 4u ) );
+ auto dirShadowMapv = dirGroup.createView( test::createView( "dirShadowMapv", dirShadowMap, VK_FORMAT_X8_D24_UNORM_PACK32, 0u, 1u, 0u, 4u ) );
+ auto dirVarianceMapv = dirGroup.createView( test::createView( "dirVarianceMapv", dirVarianceMap, VK_FORMAT_R32G32_SFLOAT, 0u, 1u, 0u, 4u ) );
crg::ImageViewIdArray dirShadows;
crg::ImageViewIdArray dirVariances;
{
- auto dirIntermediate = graph.createImage( test::createImage( "dirIntermediate", VK_FORMAT_R32G32_SFLOAT ) );
- auto dirIntermediatev = graph.createView( test::createView( "dirIntermediatev", dirIntermediate, VK_FORMAT_R32G32_SFLOAT ) );
+ auto dirIntermediate = dirGroup.createImage( test::createImage( "dirIntermediate", VK_FORMAT_R32G32_SFLOAT ) );
+ auto dirIntermediatev = dirGroup.createView( test::createView( "dirIntermediatev", dirIntermediate, VK_FORMAT_R32G32_SFLOAT ) );
for ( uint32_t index = 0u; index < 4u; ++index )
{
- auto shadowMapv = graph.createView( test::createView( "dirShadowMapv" + std::to_string( index ), dirShadowMap, VK_FORMAT_X8_D24_UNORM_PACK32, 0u, 1u, index ) );
+ auto shadowMapv = dirGroup.createView( test::createView( "dirShadowMapv" + std::to_string( index ), dirShadowMap, VK_FORMAT_X8_D24_UNORM_PACK32, 0u, 1u, index ) );
dirShadows.push_back( shadowMapv );
- auto varianceMapv = graph.createView( test::createView( "dirVarianceMapv" + std::to_string( index ), dirVarianceMap, VK_FORMAT_R32G32_SFLOAT, 0u, 1u, index ) );
+ auto varianceMapv = dirGroup.createView( test::createView( "dirVarianceMapv" + std::to_string( index ), dirVarianceMap, VK_FORMAT_R32G32_SFLOAT, 0u, 1u, index ) );
dirVariances.push_back( varianceMapv );
- auto & shadowPass = graph.createPass( "dirShadowPass" + std::to_string( index )
+ auto & shadowPass = dirGroup.createPass( "dirShadowPass" + std::to_string( index )
, [&testCounts]( crg::FramePass const & pass
, crg::GraphContext & context
, crg::RunnableGraph & graph )
@@ -2080,7 +2074,7 @@ namespace
shadowPass.addOutputDepthView( shadowMapv );
shadowPass.addOutputColourView( varianceMapv );
- auto & blurPassX = graph.createPass( "dirBlurPassX" + std::to_string( index )
+ auto & blurPassX = dirGroup.createPass( "dirBlurPassX" + std::to_string( index )
, [&testCounts]( crg::FramePass const & pass
, crg::GraphContext & context
, crg::RunnableGraph & graph )
@@ -2094,7 +2088,7 @@ namespace
blurPassX.addSampledView( varianceMapv, 0u );
blurPassX.addOutputColourView( dirIntermediatev );
- auto & blurPassY = graph.createPass( "dirBlurPassY" + std::to_string( index )
+ auto & blurPassY = dirGroup.createPass( "dirBlurPassY" + std::to_string( index )
, [&testCounts]( crg::FramePass const & pass
, crg::GraphContext & context
, crg::RunnableGraph & graph )
@@ -2107,25 +2101,27 @@ namespace
previous = &blurPassY;
blurPassY.addSampledView( dirIntermediatev, 0u );
blurPassY.addOutputColourView( varianceMapv );
+ dirGroup.addGroupOutput( varianceMapv );
}
}
- auto pntShadowMap = graph.createImage( test::createImage( "pntShadowMap", VK_FORMAT_X8_D24_UNORM_PACK32, 1u, 36u ) );
- auto pntVarianceMap = graph.createImage( test::createImage( "pntVarianceMap", VK_FORMAT_R32G32_SFLOAT, 1u, 36u ) );
- auto pntShadowMapv = graph.createView( test::createView( "pntShadowMapv", pntShadowMap, VK_FORMAT_X8_D24_UNORM_PACK32, 0u, 1u, 0u, 36u ) );
- auto pntVarianceMapv = graph.createView( test::createView( "pntVarianceMapv", pntVarianceMap, VK_FORMAT_R32G32_SFLOAT, 0u, 1u, 0u, 36u ) );
+ auto & pntGroup = graph.createPassGroup( "Point" );
+ auto pntShadowMap = pntGroup.createImage( test::createImage( "pntShadowMap", VK_FORMAT_X8_D24_UNORM_PACK32, 1u, 36u ) );
+ auto pntVarianceMap = pntGroup.createImage( test::createImage( "pntVarianceMap", VK_FORMAT_R32G32_SFLOAT, 1u, 36u ) );
+ auto pntShadowMapv = pntGroup.createView( test::createView( "pntShadowMapv", pntShadowMap, VK_FORMAT_X8_D24_UNORM_PACK32, 0u, 1u, 0u, 36u ) );
+ auto pntVarianceMapv = pntGroup.createView( test::createView( "pntVarianceMapv", pntVarianceMap, VK_FORMAT_R32G32_SFLOAT, 0u, 1u, 0u, 36u ) );
crg::ImageViewIdArray pntShadows;
crg::ImageViewIdArray pntVariances;
{
- auto pntIntermediate = graph.createImage( test::createImage( "pntIntermediate", VK_FORMAT_R32G32_SFLOAT ) );
- auto pntIntermediatev = graph.createView( test::createView( "pntIntermediatev", pntIntermediate, VK_FORMAT_R32G32_SFLOAT ) );
+ auto pntIntermediate = pntGroup.createImage( test::createImage( "pntIntermediate", VK_FORMAT_R32G32_SFLOAT ) );
+ auto pntIntermediatev = pntGroup.createView( test::createView( "pntIntermediatev", pntIntermediate, VK_FORMAT_R32G32_SFLOAT ) );
for ( uint32_t index = 0u; index < 36u; ++index )
{
- auto shadowMapv = graph.createView( test::createView( "pntShadowMapv" + std::to_string( index ), pntShadowMap, VK_FORMAT_X8_D24_UNORM_PACK32, 0u, 1u, index ) );
+ auto shadowMapv = pntGroup.createView( test::createView( "pntShadowMapv" + std::to_string( index ), pntShadowMap, VK_FORMAT_X8_D24_UNORM_PACK32, 0u, 1u, index ) );
pntShadows.push_back( shadowMapv );
- auto varianceMapv = graph.createView( test::createView( "pntVarianceMapv" + std::to_string( index ), pntVarianceMap, VK_FORMAT_R32G32_SFLOAT, 0u, 1u, index ) );
+ auto varianceMapv = pntGroup.createView( test::createView( "pntVarianceMapv" + std::to_string( index ), pntVarianceMap, VK_FORMAT_R32G32_SFLOAT, 0u, 1u, index ) );
pntVariances.push_back( varianceMapv );
- auto & shadowPass = graph.createPass( "pntShadowPass" + std::to_string( index )
+ auto & shadowPass = pntGroup.createPass( "pntShadowPass" + std::to_string( index )
, [&testCounts]( crg::FramePass const & pass
, crg::GraphContext & context
, crg::RunnableGraph & graph )
@@ -2139,7 +2135,7 @@ namespace
shadowPass.addOutputDepthView( shadowMapv );
shadowPass.addOutputColourView( varianceMapv );
- auto & blurPassX = graph.createPass( "pntBlurPassX" + std::to_string( index )
+ auto & blurPassX = pntGroup.createPass( "pntBlurPassX" + std::to_string( index )
, [&testCounts]( crg::FramePass const & pass
, crg::GraphContext & context
, crg::RunnableGraph & graph )
@@ -2153,7 +2149,7 @@ namespace
blurPassX.addSampledView( varianceMapv, 0u );
blurPassX.addOutputColourView( pntIntermediatev );
- auto & blurPassY = graph.createPass( "pntBlurPassY" + std::to_string( index )
+ auto & blurPassY = pntGroup.createPass( "pntBlurPassY" + std::to_string( index )
, [&testCounts]( crg::FramePass const & pass
, crg::GraphContext & context
, crg::RunnableGraph & graph )
@@ -2166,25 +2162,27 @@ namespace
previous = &blurPassY;
blurPassY.addSampledView( pntIntermediatev, 0u );
blurPassY.addOutputColourView( varianceMapv );
+ pntGroup.addGroupOutput( varianceMapv );
}
}
- auto sptShadowMap = graph.createImage( test::createImage( "sptShadowMap", VK_FORMAT_X8_D24_UNORM_PACK32, 1u, 10u ) );
- auto sptVarianceMap = graph.createImage( test::createImage( "pntVarianceMap", VK_FORMAT_R32G32_SFLOAT, 1u, 10u ) );
- auto sptShadowMapv = graph.createView( test::createView( "sptShadowMapv", sptShadowMap, VK_FORMAT_X8_D24_UNORM_PACK32, 0u, 1u, 0u, 10u ) );
- auto sptVarianceMapv = graph.createView( test::createView( "sptVarianceMapv", sptVarianceMap, VK_FORMAT_R32G32_SFLOAT, 0u, 1u, 0u, 10u ) );
+ auto & sptGroup = graph.createPassGroup( "Spot" );
+ auto sptShadowMap = sptGroup.createImage( test::createImage( "sptShadowMap", VK_FORMAT_X8_D24_UNORM_PACK32, 1u, 10u ) );
+ auto sptVarianceMap = sptGroup.createImage( test::createImage( "pntVarianceMap", VK_FORMAT_R32G32_SFLOAT, 1u, 10u ) );
+ auto sptShadowMapv = sptGroup.createView( test::createView( "sptShadowMapv", sptShadowMap, VK_FORMAT_X8_D24_UNORM_PACK32, 0u, 1u, 0u, 10u ) );
+ auto sptVarianceMapv = sptGroup.createView( test::createView( "sptVarianceMapv", sptVarianceMap, VK_FORMAT_R32G32_SFLOAT, 0u, 1u, 0u, 10u ) );
crg::ImageViewIdArray sptShadows;
crg::ImageViewIdArray sptVariances;
{
- auto sptIntermediate = graph.createImage( test::createImage( "sptIntermediate", VK_FORMAT_R32G32_SFLOAT ) );
- auto sptIntermediatev = graph.createView( test::createView( "sptIntermediatev", sptIntermediate, VK_FORMAT_R32G32_SFLOAT ) );
+ auto sptIntermediate = sptGroup.createImage( test::createImage( "sptIntermediate", VK_FORMAT_R32G32_SFLOAT ) );
+ auto sptIntermediatev = sptGroup.createView( test::createView( "sptIntermediatev", sptIntermediate, VK_FORMAT_R32G32_SFLOAT ) );
for ( uint32_t index = 0u; index < 10u; ++index )
{
- auto shadowMapv = graph.createView( test::createView( "sptShadowMapv" + std::to_string( index ), sptShadowMap, VK_FORMAT_X8_D24_UNORM_PACK32, 0u, 1u, index ) );
+ auto shadowMapv = sptGroup.createView( test::createView( "sptShadowMapv" + std::to_string( index ), sptShadowMap, VK_FORMAT_X8_D24_UNORM_PACK32, 0u, 1u, index ) );
sptShadows.push_back( shadowMapv );
- auto varianceMapv = graph.createView( test::createView( "sptVarianceMapv" + std::to_string( index ), sptVarianceMap, VK_FORMAT_R32G32_SFLOAT, 0u, 1u, index ) );
+ auto varianceMapv = sptGroup.createView( test::createView( "sptVarianceMapv" + std::to_string( index ), sptVarianceMap, VK_FORMAT_R32G32_SFLOAT, 0u, 1u, index ) );
sptVariances.push_back( varianceMapv );
- auto & shadowPass = graph.createPass( "sptShadowPass" + std::to_string( index )
+ auto & shadowPass = sptGroup.createPass( "sptShadowPass" + std::to_string( index )
, [&testCounts]( crg::FramePass const & pass
, crg::GraphContext & context
, crg::RunnableGraph & graph )
@@ -2198,7 +2196,7 @@ namespace
shadowPass.addOutputDepthView( shadowMapv );
shadowPass.addOutputColourView( varianceMapv );
- auto & blurPassX = graph.createPass( "sptBlurPassX" + std::to_string( index )
+ auto & blurPassX = sptGroup.createPass( "sptBlurPassX" + std::to_string( index )
, [&testCounts]( crg::FramePass const & pass
, crg::GraphContext & context
, crg::RunnableGraph & graph )
@@ -2212,7 +2210,7 @@ namespace
blurPassX.addSampledView( varianceMapv, 0u );
blurPassX.addOutputColourView( sptIntermediatev );
- auto & blurPassY = graph.createPass( "sptBlurPassY" + std::to_string( index )
+ auto & blurPassY = sptGroup.createPass( "sptBlurPassY" + std::to_string( index )
, [&testCounts]( crg::FramePass const & pass
, crg::GraphContext & context
, crg::RunnableGraph & graph )
@@ -2225,10 +2223,15 @@ namespace
previous = &blurPassY;
blurPassY.addSampledView( sptIntermediatev, 0u );
blurPassY.addOutputColourView( varianceMapv );
+ sptGroup.addGroupOutput( varianceMapv );
}
}
- auto & opaquePass = graph.createPass( "opaquePass"
+ auto & objGroup = graph.createPassGroup( "Objects" );
+ objGroup.addOutput( colourv
+ , crg::makeLayoutState( VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL ) );
+
+ auto & opaquePass = objGroup.createPass( "opaquePass"
, [&testCounts]( crg::FramePass const & pass
, crg::GraphContext & context
, crg::RunnableGraph & graph )
@@ -2254,7 +2257,7 @@ namespace
opaquePass.addInOutDepthView( depthv );
opaquePass.addInOutColourView( colourv );
- auto & transparentPass = graph.createPass( "transparentPass"
+ auto & transparentPass = objGroup.createPass( "transparentPass"
, [&testCounts]( crg::FramePass const & pass
, crg::GraphContext & context
, crg::RunnableGraph & graph )
@@ -2346,6 +2349,9 @@ namespace
mipsGen.addTransferOutputView( colourv );
auto runnable = graph.compile( getContext() );
+ require( runnable );
+ checkNoThrow( runnable->record() )
+ checkNoThrow( runnable->run( VkQueue{} ) )
testEnd();
}
}
diff --git a/test/TestRunnablePass.cpp b/test/TestRunnablePass.cpp
new file mode 100644
index 0000000..b512299
--- /dev/null
+++ b/test/TestRunnablePass.cpp
@@ -0,0 +1,437 @@
+#include "Common.hpp"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace
+{
+ crg::GraphContext & getContext()
+ {
+ return test::getDummyContext();
+ }
+
+ void testBufferCopy( test::TestCounts & testCounts )
+ {
+ testBegin( "testBufferCopy" )
+ crg::ResourceHandler handler;
+ crg::FrameGraph graph{ handler, testCounts.testName };
+ auto & testPass = graph.createPass( "Pass"
+ , []( crg::FramePass const & pass
+ , crg::GraphContext & context
+ , crg::RunnableGraph & runGraph )
+ {
+ return std::make_unique< crg::BufferCopy >( pass, context, runGraph
+ , 0u, 1024u );
+ } );
+ testPass.addInputStorageBuffer( crg::Buffer{ nullptr, "inBuffer" }, 0u, 0u, 1024u );
+ testPass.addOutputStorageBuffer( crg::Buffer{ nullptr, "outBuffer" }, 1u, 0u, 1024u );
+
+ auto runnable = graph.compile( getContext() );
+ require( runnable );
+ checkNoThrow( runnable->record() )
+ checkNoThrow( runnable->run( VkQueue{} ) )
+ testEnd()
+ }
+
+ void testBufferToImageCopy( test::TestCounts & testCounts )
+ {
+ testBegin( "testBufferToImageCopy" )
+ crg::ResourceHandler handler;
+ crg::FrameGraph graph{ handler, testCounts.testName };
+ auto result = graph.createImage( test::createImage( "result", VK_FORMAT_R16G16B16A16_SFLOAT ) );
+ auto resultv = graph.createView( test::createView( "resultv", result, VK_FORMAT_R16G16B16A16_SFLOAT, 0u, 1u, 0u, 1u ) );
+ auto & testPass = graph.createPass( "Pass"
+ , []( crg::FramePass const & pass
+ , crg::GraphContext & context
+ , crg::RunnableGraph & runGraph )
+ {
+ return std::make_unique< crg::BufferToImageCopy >( pass, context, runGraph
+ , VkOffset3D{}, VkExtent3D{ 1024, 1024, 1u } );
+ } );
+ testPass.addInputStorageBuffer( crg::Buffer{ nullptr, "inBuffer" }, 0u, 0u, 1024u );
+ testPass.addTransferOutputView( resultv );
+
+ auto runnable = graph.compile( getContext() );
+ require( runnable );
+ checkNoThrow( runnable->record() )
+ checkNoThrow( runnable->run( VkQueue{} ) )
+ testEnd()
+ }
+
+ void testGenerateMipmaps( test::TestCounts & testCounts )
+ {
+ testBegin( "testGenerateMipmaps" )
+ crg::ResourceHandler handler;
+ crg::FrameGraph graph{ handler, testCounts.testName };
+ auto result = graph.createImage( test::createImage( "result", VK_FORMAT_R16G16B16A16_SFLOAT, 10u ) );
+ auto resultv = graph.createView( test::createView( "resultv", result, VK_FORMAT_R16G16B16A16_SFLOAT, 0u, 10u, 0u, 1u ) );
+ auto & testPass = graph.createPass( "Pass"
+ , []( crg::FramePass const & pass
+ , crg::GraphContext & context
+ , crg::RunnableGraph & runGraph )
+ {
+ return std::make_unique< crg::GenerateMipmaps >( pass, context, runGraph );
+ } );
+ testPass.addTransferInOutView( resultv );
+
+ auto runnable = graph.compile( getContext() );
+ require( runnable );
+ checkNoThrow( runnable->record() )
+ checkNoThrow( runnable->run( VkQueue{} ) )
+ testEnd()
+ }
+
+ void testImageBlit( test::TestCounts & testCounts )
+ {
+ testBegin( "testImageBlit" )
+ crg::ResourceHandler handler;
+ crg::FrameGraph graph{ handler, testCounts.testName };
+ auto input = graph.createImage( test::createImage( "input", VK_FORMAT_R16G16B16A16_SFLOAT ) );
+ auto result = graph.createImage( test::createImage( "result", VK_FORMAT_R16G16B16A16_SFLOAT ) );
+ auto inputv = graph.createView( test::createView( "inputv", input, VK_FORMAT_R16G16B16A16_SFLOAT, 0u, 1u, 0u, 1u ) );
+ auto resultv = graph.createView( test::createView( "resultv", result, VK_FORMAT_R16G16B16A16_SFLOAT, 0u, 1u, 0u, 1u ) );
+ auto & testPass = graph.createPass( "Pass"
+ , [inputv, resultv]( crg::FramePass const & pass
+ , crg::GraphContext & context
+ , crg::RunnableGraph & runGraph )
+ {
+ return std::make_unique< crg::ImageBlit >( pass, context, runGraph
+ , VkOffset3D{}, getExtent( inputv )
+ , VkOffset3D{}, getExtent( resultv )
+ , VK_FILTER_LINEAR );
+ } );
+ testPass.addTransferInputView( inputv );
+ testPass.addTransferOutputView( resultv );
+
+ auto runnable = graph.compile( getContext() );
+ require( runnable );
+ checkNoThrow( runnable->record() )
+ checkNoThrow( runnable->run( VkQueue{} ) )
+ testEnd()
+ }
+
+ void testImageCopy( test::TestCounts & testCounts )
+ {
+ testBegin( "testImageCopy" )
+ {
+ crg::ResourceHandler handler;
+ crg::FrameGraph graph{ handler, testCounts.testName };
+ auto input = graph.createImage( test::createImage( "input", VK_FORMAT_R16G16B16A16_SFLOAT ) );
+ auto result = graph.createImage( test::createImage( "result", VK_FORMAT_R16G16B16A16_SFLOAT ) );
+ auto inputv = graph.createView( test::createView( "inputv", input, VK_FORMAT_R16G16B16A16_SFLOAT, 0u, 1u, 0u, 1u ) );
+ auto resultv = graph.createView( test::createView( "resultv", result, VK_FORMAT_R16G16B16A16_SFLOAT, 0u, 1u, 0u, 1u ) );
+ auto & testPass = graph.createPass( "Pass"
+ , [inputv]( crg::FramePass const & pass
+ , crg::GraphContext & context
+ , crg::RunnableGraph & runGraph )
+ {
+ return std::make_unique< crg::ImageCopy >( pass, context, runGraph
+ , getExtent( inputv ) );
+ } );
+ testPass.addTransferInputView( inputv );
+ testPass.addTransferOutputView( resultv );
+
+ auto runnable = graph.compile( getContext() );
+ require( runnable );
+ checkNoThrow( runnable->record() )
+ checkNoThrow( runnable->run( VkQueue{} ) )
+ }
+ {
+ crg::ResourceHandler handler;
+ crg::FrameGraph graph{ handler, testCounts.testName };
+ auto input = graph.createImage( test::createImage( "input", VK_FORMAT_R16G16B16A16_SFLOAT ) );
+ auto result = graph.createImage( test::createImage( "result", VK_FORMAT_R16G16B16A16_SFLOAT ) );
+ auto inputv = graph.createView( test::createView( "inputv", input, VK_FORMAT_R16G16B16A16_SFLOAT, 0u, 1u, 0u, 1u ) );
+ auto resultv = graph.createView( test::createView( "resultv", result, VK_FORMAT_R16G16B16A16_SFLOAT, 0u, 1u, 0u, 1u ) );
+ auto & testPass = graph.createPass( "Pass"
+ , [inputv]( crg::FramePass const & pass
+ , crg::GraphContext & context
+ , crg::RunnableGraph & runGraph )
+ {
+ return std::make_unique< crg::ImageCopy >( pass, context, runGraph
+ , getExtent( inputv )
+ , VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL );
+ } );
+ testPass.addTransferInputView( inputv );
+ testPass.addTransferOutputView( resultv );
+
+ auto runnable = graph.compile( getContext() );
+ require( runnable );
+ checkNoThrow( runnable->record() )
+ checkNoThrow( runnable->run( VkQueue{} ) )
+ }
+ {
+ crg::ResourceHandler handler;
+ crg::FrameGraph graph{ handler, testCounts.testName };
+ auto input = graph.createImage( test::createImage( "input", VK_FORMAT_R16G16B16A16_SFLOAT ) );
+ auto result = graph.createImage( test::createImage( "result", VK_FORMAT_R16G16B16A16_SFLOAT ) );
+ auto inputv = graph.createView( test::createView( "inputv", input, VK_FORMAT_R16G16B16A16_SFLOAT, 0u, 1u, 0u, 1u ) );
+ auto resultv = graph.createView( test::createView( "resultv", result, VK_FORMAT_R16G16B16A16_SFLOAT, 0u, 1u, 0u, 1u ) );
+ auto & testPass = graph.createPass( "Pass"
+ , [inputv]( crg::FramePass const & pass
+ , crg::GraphContext & context
+ , crg::RunnableGraph & runGraph )
+ {
+ return std::make_unique< crg::ImageCopy >( pass, context, runGraph
+ , getExtent( inputv )
+ , VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL );
+ } );
+ testPass.addTransferInputView( inputv );
+ testPass.addTransferOutputView( resultv );
+ testPass.addTransferInputView( resultv );
+ testPass.addTransferOutputView( inputv );
+
+ auto runnable = graph.compile( getContext() );
+ require( runnable );
+ checkNoThrow( runnable->record() )
+ checkNoThrow( runnable->run( VkQueue{} ) )
+ }
+ testEnd()
+ }
+
+ void testImageToBufferCopy( test::TestCounts & testCounts )
+ {
+ testBegin( "testImageToBufferCopy" )
+ crg::ResourceHandler handler;
+ crg::FrameGraph graph{ handler, testCounts.testName };
+ auto input = graph.createImage( test::createImage( "input", VK_FORMAT_R16G16B16A16_SFLOAT ) );
+ auto inputv = graph.createView( test::createView( "inputv", input, VK_FORMAT_R16G16B16A16_SFLOAT, 0u, 1u, 0u, 1u ) );
+ auto & testPass = graph.createPass( "Pass"
+ , [inputv]( crg::FramePass const & pass
+ , crg::GraphContext & context
+ , crg::RunnableGraph & runGraph )
+ {
+ return std::make_unique< crg::ImageToBufferCopy >( pass, context, runGraph
+ , VkOffset3D{}, getExtent( inputv ) );
+ } );
+ testPass.addTransferInputView( inputv );
+ testPass.addOutputStorageBuffer( crg::Buffer{ nullptr, "outBuffer" }, 1u, 0u, 1024u );
+
+ auto runnable = graph.compile( getContext() );
+ require( runnable );
+ checkNoThrow( runnable->record() )
+ checkNoThrow( runnable->run( VkQueue{} ) )
+ testEnd()
+ }
+
+ void testComputePass( test::TestCounts & testCounts )
+ {
+ testBegin( "testComputePass" )
+ crg::ResourceHandler handler;
+ crg::FrameGraph graph{ handler, testCounts.testName };
+ auto result = graph.createImage( test::createImage( "result", VK_FORMAT_R16G16B16A16_SFLOAT ) );
+ auto resultv = graph.createView( test::createView( "resultv", result, VK_FORMAT_R16G16B16A16_SFLOAT, 0u, 1u, 0u, 1u ) );
+ auto depth = graph.createImage( test::createImage( "result", VK_FORMAT_D32_SFLOAT ) );
+ auto depthv = graph.createView( test::createView( "resultv", depth, VK_FORMAT_D32_SFLOAT, 0u, 1u, 0u, 1u ) );
+ auto & testPass = graph.createPass( "Pass"
+ , []( crg::FramePass const & pass
+ , crg::GraphContext & context
+ , crg::RunnableGraph & runGraph )
+ {
+ crg::cp::Config cfg;
+ cfg.baseConfig( crg::pp::Config{}
+ .programCreator( crg::ProgramCreator{ 1u
+ , []( uint32_t )
+ {
+ return crg::VkPipelineShaderStageCreateInfoArray{ VkPipelineShaderStageCreateInfo{} };
+ } } ) );
+ return std::make_unique< crg::ComputePass >( pass, context, runGraph
+ , crg::ru::Config{}, cfg );
+ } );
+ testPass.addInOutStorageBuffer( crg::Buffer{ nullptr, "buffer1" }, 0u, 0u, 1024u );
+ testPass.addClearableOutputStorageBuffer( crg::Buffer{ nullptr, "buffer2" }, 1u, 0u, 1024u );
+ testPass.addClearableOutputStorageView( resultv, 2u );
+ testPass.addClearableOutputStorageView( depthv, 3u );
+
+ auto runnable = graph.compile( getContext() );
+ require( runnable );
+ checkNoThrow( runnable->record() )
+ checkNoThrow( runnable->run( VkQueue{} ) )
+ testEnd()
+ }
+
+ void testRenderPass( test::TestCounts & testCounts )
+ {
+ testBegin( "testRenderPass" )
+ {
+ crg::ResourceHandler handler;
+ crg::FrameGraph graph{ handler, testCounts.testName };
+ auto result = graph.createImage( test::createImage( "result", VK_FORMAT_R16G16B16A16_SFLOAT ) );
+ auto resultv = graph.createView( test::createView( "resultv", result, VK_FORMAT_R16G16B16A16_SFLOAT, 0u, 1u, 0u, 1u ) );
+ auto & testPass = graph.createPass( "Pass"
+ , []( crg::FramePass const & pass
+ , crg::GraphContext & context
+ , crg::RunnableGraph & runGraph )
+ {
+ return std::make_unique< crg::RenderPass >( pass, context, runGraph
+ , crg::RenderPass::Callbacks{ crg::defaultV< crg::RunnablePass::InitialiseCallback >
+ , crg::defaultV< crg::RunnablePass::RecordCallback > } );
+ } );
+ testPass.addOutputColourView( resultv );
+
+ auto runnable = graph.compile( getContext() );
+ require( runnable );
+ checkNoThrow( runnable->record() )
+ checkNoThrow( runnable->run( VkQueue{} ) )
+ }
+ {
+ crg::ResourceHandler handler;
+ crg::FrameGraph graph{ handler, testCounts.testName };
+ auto depth = graph.createImage( test::createImage( "depth", VK_FORMAT_D32_SFLOAT ) );
+ auto depthv = graph.createView( test::createView( "depthv", depth, VK_FORMAT_D32_SFLOAT, 0u, 1u, 0u, 1u ) );
+ auto & testPass = graph.createPass( "Pass"
+ , []( crg::FramePass const & pass
+ , crg::GraphContext & context
+ , crg::RunnableGraph & runGraph )
+ {
+ return std::make_unique< crg::RenderPass >( pass, context, runGraph
+ , crg::RenderPass::Callbacks{ crg::defaultV< crg::RunnablePass::InitialiseCallback >
+ , crg::defaultV< crg::RunnablePass::RecordCallback > } );
+ } );
+ testPass.addOutputDepthView( depthv );
+
+ auto runnable = graph.compile( getContext() );
+ require( runnable );
+ checkNoThrow( runnable->record() )
+ checkNoThrow( runnable->run( VkQueue{} ) )
+ }
+ {
+ crg::ResourceHandler handler;
+ crg::FrameGraph graph{ handler, testCounts.testName };
+ auto result = graph.createImage( test::createImage( "result", VK_FORMAT_R16G16B16A16_SFLOAT ) );
+ auto resultv = graph.createView( test::createView( "resultv", result, VK_FORMAT_R16G16B16A16_SFLOAT, 0u, 1u, 0u, 1u ) );
+ auto depth = graph.createImage( test::createImage( "depth", VK_FORMAT_D32_SFLOAT ) );
+ auto depthv = graph.createView( test::createView( "depthv", depth, VK_FORMAT_D32_SFLOAT, 0u, 1u, 0u, 1u ) );
+ auto & testPass = graph.createPass( "Pass"
+ , []( crg::FramePass const & pass
+ , crg::GraphContext & context
+ , crg::RunnableGraph & runGraph )
+ {
+ return std::make_unique< crg::RenderPass >( pass, context, runGraph
+ , crg::RenderPass::Callbacks{ crg::defaultV< crg::RunnablePass::InitialiseCallback >
+ , crg::defaultV< crg::RunnablePass::RecordCallback > } );
+ } );
+ testPass.addOutputColourView( resultv );
+ testPass.addOutputDepthView( depthv );
+
+ auto runnable = graph.compile( getContext() );
+ require( runnable );
+ checkNoThrow( runnable->record() )
+ checkNoThrow( runnable->run( VkQueue{} ) )
+ }
+ {
+ crg::ResourceHandler handler;
+ crg::FrameGraph graph{ handler, testCounts.testName };
+ auto result1 = graph.createImage( test::createImage( "result1", VK_FORMAT_R16G16B16A16_SFLOAT, 1u, 2u ) );
+ auto result1v = graph.createView( test::createView( "result1v", result1, VK_FORMAT_R16G16B16A16_SFLOAT, 0u, 1u, 0u, 1u ) );
+ auto result2v = graph.createView( test::createView( "result2v", result1, VK_FORMAT_R16G16B16A16_SFLOAT, 0u, 1u, 0u, 1u ) );
+ auto & testPass = graph.createPass( "Pass"
+ , []( crg::FramePass const & pass
+ , crg::GraphContext & context
+ , crg::RunnableGraph & runGraph )
+ {
+ return std::make_unique< crg::RenderPass >( pass, context, runGraph
+ , crg::RenderPass::Callbacks{ crg::defaultV< crg::RunnablePass::InitialiseCallback >
+ , crg::defaultV< crg::RunnablePass::RecordCallback > } );
+ } );
+ testPass.addOutputColourView( testPass.mergeViews( { result1v, result2v } ) );
+
+ auto runnable = graph.compile( getContext() );
+ require( runnable );
+ checkNoThrow( runnable->record() )
+ checkNoThrow( runnable->run( VkQueue{} ) )
+ }
+ testEnd()
+ }
+
+ void testRenderQuad( test::TestCounts & testCounts )
+ {
+ testBegin( "testRenderQuad" )
+ crg::ResourceHandler handler;
+ crg::FrameGraph graph{ handler, testCounts.testName };
+ auto result = graph.createImage( test::createImage( "result", VK_FORMAT_R16G16B16A16_SFLOAT ) );
+ auto resultv = graph.createView( test::createView( "resultv", result, VK_FORMAT_R16G16B16A16_SFLOAT, 0u, 1u, 0u, 1u ) );
+ auto & testPass = graph.createPass( "Pass"
+ , []( crg::FramePass const & pass
+ , crg::GraphContext & context
+ , crg::RunnableGraph & runGraph )
+ {
+ crg::rq::Config cfg;
+ cfg.baseConfig( crg::pp::Config{}
+ .programCreator( crg::ProgramCreator{ 1u
+ , []( uint32_t )
+ {
+ return crg::VkPipelineShaderStageCreateInfoArray{ VkPipelineShaderStageCreateInfo{} };
+ } } ) );
+ return std::make_unique< crg::RenderQuad >( pass, context, runGraph
+ , crg::ru::Config{}, cfg );
+ } );
+ testPass.addOutputColourView( resultv );
+
+ auto runnable = graph.compile( getContext() );
+ require( runnable );
+ checkNoThrow( runnable->record() )
+ checkNoThrow( runnable->run( VkQueue{} ) )
+ testEnd()
+ }
+
+ void testRenderMesh( test::TestCounts & testCounts )
+ {
+ testBegin( "testRenderMesh" )
+ crg::ResourceHandler handler;
+ crg::FrameGraph graph{ handler, testCounts.testName };
+ auto result = graph.createImage( test::createImage( "result", VK_FORMAT_R16G16B16A16_SFLOAT ) );
+ auto resultv = graph.createView( test::createView( "resultv", result, VK_FORMAT_R16G16B16A16_SFLOAT, 0u, 1u, 0u, 1u ) );
+ auto & testPass = graph.createPass( "Pass"
+ , []( crg::FramePass const & pass
+ , crg::GraphContext & context
+ , crg::RunnableGraph & runGraph )
+ {
+ crg::rm::Config cfg;
+ cfg.baseConfig( crg::pp::Config{}
+ .programCreator( crg::ProgramCreator{ 1u
+ , []( uint32_t )
+ {
+ return crg::VkPipelineShaderStageCreateInfoArray{ VkPipelineShaderStageCreateInfo{} };
+ } } ) );
+ return std::make_unique< crg::RenderMesh >( pass, context, runGraph
+ , crg::ru::Config{}, cfg );
+ } );
+ testPass.addOutputColourView( resultv );
+
+ auto runnable = graph.compile( getContext() );
+ require( runnable );
+ checkNoThrow( runnable->record() )
+ checkNoThrow( runnable->run( VkQueue{} ) )
+ testEnd()
+ }
+}
+
+int main( int argc, char ** argv )
+{
+ testSuiteBegin( "TestRunnablePass" );
+ testBufferCopy( testCounts );
+ testBufferToImageCopy( testCounts );
+ testGenerateMipmaps( testCounts );
+ testImageBlit( testCounts );
+ testImageCopy( testCounts );
+ testImageToBufferCopy( testCounts );
+ testComputePass( testCounts );
+ testRenderPass( testCounts );
+ testRenderQuad( testCounts );
+ testRenderMesh( testCounts );
+ testSuiteEnd();
+}