From 69196959310284b327feb13bd1630310854d2c75 Mon Sep 17 00:00:00 2001 From: Sylvain Doremus Date: Mon, 26 Feb 2024 12:17:20 +0100 Subject: [PATCH 1/2] Added .editorconfig file. --- .editorconfig | 77 +++++++++++++++++++++++++++++ CMakeLists.txt | 6 +++ source/RenderGraph/RunnablePass.cpp | 22 ++++----- test/CMakeLists.txt | 8 +++ 4 files changed, 102 insertions(+), 11 deletions(-) create mode 100644 .editorconfig 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/CMakeLists.txt b/CMakeLists.txt index ee5abdf..0a7e1e1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 () @@ -214,6 +216,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/source/RenderGraph/RunnablePass.cpp b/source/RenderGraph/RunnablePass.cpp index 6ba34a8..5b2f1a2 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 ) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 3d80ff8..d43d6fe 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -20,6 +20,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 +47,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 From 94b0fd5795df4c47c07df506390e68a69c9d615c Mon Sep 17 00:00:00 2001 From: Sylvain Doremus Date: Mon, 26 Feb 2024 15:30:41 +0100 Subject: [PATCH 2/2] Added support for coverage checks using OpenCppCoverage --- .github/codecov.yml | 38 ++ .github/workflows/cmake.yml | 21 +- .gitignore | 3 + CMakeLists.txt | 6 +- README.md | 1 + include/RenderGraph/AttachmentTransition.hpp | 1 - include/RenderGraph/GraphNode.hpp | 4 +- include/RenderGraph/Log.hpp | 204 -------- include/RenderGraph/RunnablePass.hpp | 24 - source/RenderGraph/AttachmentTransition.cpp | 64 --- source/RenderGraph/BuilderCommon.cpp | 88 ---- source/RenderGraph/BuilderCommon.hpp | 3 - source/RenderGraph/FrameGraph.cpp | 6 +- source/RenderGraph/FramePassGroup.cpp | 2 + source/RenderGraph/GraphContext.cpp | 2 + source/RenderGraph/GraphNode.cpp | 24 - source/RenderGraph/Log.cpp | 40 -- source/RenderGraph/RecordContext.cpp | 2 + source/RenderGraph/ResourceOptimiser.cpp | 104 ----- source/RenderGraph/ResourceOptimiser.hpp | 16 - source/RenderGraph/RunnablePass.cpp | 55 --- .../RunnablePasses/RenderQuadHolder.cpp | 7 +- test/CMakeLists.txt | 72 +++ test/Common.cpp | 209 +++++++++ test/Common.hpp | 1 + test/TestRenderGraph.cpp | 92 ++-- test/TestRunnablePass.cpp | 437 ++++++++++++++++++ 27 files changed, 844 insertions(+), 682 deletions(-) create mode 100644 .github/codecov.yml delete mode 100644 source/RenderGraph/BuilderCommon.cpp delete mode 100644 source/RenderGraph/ResourceOptimiser.cpp delete mode 100644 source/RenderGraph/ResourceOptimiser.hpp create mode 100644 test/TestRunnablePass.cpp 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 0a7e1e1..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}" ) @@ -96,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 @@ -118,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 ) diff --git a/README.md b/README.md index 12212c1..bb0eebf 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@

Build status +

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 5b2f1a2..cff0ae6 100644 --- a/source/RenderGraph/RunnablePass.cpp +++ b/source/RenderGraph/RunnablePass.cpp @@ -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 d43d6fe..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 ) @@ -77,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} @@ -88,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(); +}