diff --git a/shaders/gbuffer.frag b/shaders/gbuffer.frag index a6df606..ffdefbe 100644 --- a/shaders/gbuffer.frag +++ b/shaders/gbuffer.frag @@ -1,11 +1,12 @@ #version 450 #extension GL_EXT_nonuniform_qualifier: enable +#extension GL_EXT_debug_printf: enable layout (location = 0) in vec3 in_normal; layout (location = 1) in vec3 in_color; layout (location = 2) in vec3 in_world_pos; layout (location = 3) in vec2 in_tex_coord; -layout (location = 4) in flat int in_tex_idx; +layout (location = 4) in flat uint in_tex_idx; layout (location = 0) out vec4 out_color; layout (location = 1) out vec4 out_position; diff --git a/shaders/gbuffer.vert b/shaders/gbuffer.vert index 114abe0..48595fe 100644 --- a/shaders/gbuffer.vert +++ b/shaders/gbuffer.vert @@ -1,4 +1,5 @@ #version 450 +#extension GL_EXT_debug_printf: enable layout (location = 0) in vec3 position; layout (location = 1) in vec3 color; @@ -6,13 +7,13 @@ layout (location = 2) in vec3 normal; layout (location = 3) in vec2 uv; layout (location = 4) in mat4 instance_model_matrix; // 4, 5, 6, 7 -layout (location = 8) in int in_texture_id; +layout (location = 8) in uint in_texture_id; layout (location = 0) out vec3 out_normal; layout (location = 1) out vec3 out_color; layout (location = 2) out vec3 out_world_pos; layout (location = 3) out vec2 out_tex_coord; -layout (location = 4) out int out_texture_idx; +layout (location = 4) out uint out_texture_idx; layout (set = 0, binding = 0) uniform CameraInfo { mat4 projection; diff --git a/src/engine/buffers/BufferSuballocation.cpp b/src/engine/buffers/BufferSuballocation.cpp index fddcc85..36f1855 100644 --- a/src/engine/buffers/BufferSuballocation.cpp +++ b/src/engine/buffers/BufferSuballocation.cpp @@ -51,18 +51,24 @@ namespace fgl::engine void BufferSuballocation::flush( vk::DeviceSize beg, vk::DeviceSize end ) { + assert( beg < end ); assert( m_handle != nullptr ); assert( m_handle->mapped != nullptr && "BufferSuballocationT::flush() called before map()" ); + assert( end <= this->m_byte_size ); vk::MappedMemoryRange range {}; range.memory = m_handle->buffer.getMemory(); range.offset = m_offset + beg; const vk::DeviceSize min_atom_size { Device::getInstance().m_properties.limits.nonCoherentAtomSize }; - const auto size { end - beg }; + const vk::DeviceSize size { end - beg }; + + assert( size > 0 ); range.size = align( size, min_atom_size ); + assert( range.size > 0 ); + if ( range.size > m_byte_size ) range.size = VK_WHOLE_SIZE; if ( Device::getInstance().device().flushMappedMemoryRanges( 1, &range ) != vk::Result::eSuccess ) diff --git a/src/engine/buffers/vector/BufferVector.hpp b/src/engine/buffers/vector/BufferVector.hpp index bbe3142..57f9037 100644 --- a/src/engine/buffers/vector/BufferVector.hpp +++ b/src/engine/buffers/vector/BufferVector.hpp @@ -42,14 +42,12 @@ namespace fgl::engine public: - //! Returns the total byte capacity of the buffer - [[nodiscard]] std::size_t byteCapacity() const noexcept { return m_count * m_stride; } - //! Returns the offset count from the start of the buffer to the first element [[nodiscard]] std::uint32_t getOffsetCount() const { assert( !std::isnan( m_count ) ); assert( !std::isnan( m_stride ) ); + assert( m_count * m_stride == this->bytesize() ); assert( m_offset % m_stride == 0 && "Offset must be aligned from the stride" ); return static_cast< std::uint32_t >( this->m_offset / m_stride ); @@ -58,10 +56,16 @@ namespace fgl::engine [[nodiscard]] std::uint32_t stride() const noexcept { assert( !std::isnan( m_stride ) ); + assert( m_count * m_stride <= this->bytesize() ); return m_stride; } - [[nodiscard]] std::uint32_t size() const noexcept { return m_count; } + [[nodiscard]] std::uint32_t size() const noexcept + { + assert( !std::isnan( m_count ) ); + assert( m_count * m_stride <= this->bytesize() ); + return m_count; + } void resize( const std::uint32_t count ) { diff --git a/src/engine/buffers/vector/HostVector.hpp b/src/engine/buffers/vector/HostVector.hpp index e5f1ce8..b7cc575 100644 --- a/src/engine/buffers/vector/HostVector.hpp +++ b/src/engine/buffers/vector/HostVector.hpp @@ -20,8 +20,6 @@ namespace fgl::engine template < typename T > class HostVector final : public BufferVector { - std::uint32_t m_used { 0 }; - public: using value_type = T; @@ -32,15 +30,7 @@ namespace fgl::engine HostVector& operator=( HostVector&& ) = delete; HostVector( HostVector&& other ) = delete; - HostVector( Buffer& buffer, const std::uint32_t count = 1 ) : - BufferVector( buffer, count, sizeof( T ) ), - m_used( count ) - {} - - std::uint32_t capacity() const { return BufferVector::size(); } - - //! Returns the number of T currently used - std::uint32_t size() const { return m_used; } + HostVector( Buffer& buffer, const std::uint32_t count = 1 ) : BufferVector( buffer, count, sizeof( T ) ) {} HostVector( Buffer& buffer, const std::vector< T >& vec ) : HostVector( buffer, static_cast< std::uint32_t >( vec.size() ) ) @@ -55,13 +45,10 @@ namespace fgl::engine this->flush(); } - void flush() { this->flushRange( 0, m_used ); } + void flush() { this->flushRange( 0, size() ); } void flushRange( const std::uint32_t start_idx, const std::uint32_t end_idx ) { - if ( this->m_count == 0 ) [[unlikely]] - return; - assert( start_idx < this->m_count && "BufferSuballocationVector::flushRange start_idx index out of bounds" ); assert( end_idx <= this->m_count && "BufferSuballocationVector::flushRange end_idx index out of bounds" ); @@ -77,13 +64,13 @@ namespace fgl::engine const auto count { end_idx - start_idx }; assert( count > 0 && "Count must be larger then 0" ); + assert( count <= m_count ); - BufferSuballocation::flush( start_idx * this->m_stride, count * this->m_stride ); + BufferSuballocation::flush( start_idx * this->m_stride, end_idx * this->m_stride ); } HostVector& operator=( const std::vector< T >& vec ) { - m_used = static_cast< decltype( m_used ) >( vec.size() ); if ( this->m_stride == sizeof( T ) ) { std::memcpy( this->ptr(), vec.data(), vec.size() * sizeof( T ) ); @@ -96,15 +83,6 @@ namespace fgl::engine return *this; } - void push_back( const T& t ) - { - if ( capacity <= m_used + 1 ) resize( m_used + 1 ); - - assert( capacity >= m_used + 1 ); - - *this[ m_used++ ] = t; - } - ~HostVector() {} }; diff --git a/src/engine/model/Model.hpp b/src/engine/model/Model.hpp index c44d0a2..31bb3be 100644 --- a/src/engine/model/Model.hpp +++ b/src/engine/model/Model.hpp @@ -64,12 +64,6 @@ namespace fgl::engine //! Returns the bounding box in model space const OrientedBoundingBox< CoordinateSpace::Model >& getBoundingBox() const { return m_bounding_box; } - OrientedBoundingBox< CoordinateSpace::World > getBoundingBox( const Matrix< MatrixType::ModelToWorld > matrix ) - const - { - return matrix * m_bounding_box; - } - std::vector< Primitive > m_primitives {}; std::vector< vk::DrawIndexedIndirectCommand > getDrawCommand( const std::uint32_t index ) const; diff --git a/src/engine/model/Vertex.cpp b/src/engine/model/Vertex.cpp index ae9e6e0..6023cca 100644 --- a/src/engine/model/Vertex.cpp +++ b/src/engine/model/Vertex.cpp @@ -44,9 +44,9 @@ namespace fgl::engine attribute_descriptions.emplace_back( 6, 1, vk::Format::eR32G32B32A32Sfloat, 2 * sizeof( glm::vec4 ) ); attribute_descriptions.emplace_back( 7, 1, vk::Format::eR32G32B32A32Sfloat, 3 * sizeof( glm::vec4 ) ); - attribute_descriptions.emplace_back( 8, 1, vk::Format::eR32Sint, 4 * sizeof( glm::vec4 ) ); + attribute_descriptions.emplace_back( 8, 1, vk::Format::eR32Uint, 4 * sizeof( glm::vec4 ) ); - static_assert( 4 * sizeof( glm::vec4 ) + sizeof( int ) == sizeof( ModelMatrixInfo ) ); + static_assert( 4 * sizeof( glm::vec4 ) + sizeof( unsigned int ) == sizeof( ModelMatrixInfo ) ); return attribute_descriptions; } diff --git a/src/engine/rendering/Device.cpp b/src/engine/rendering/Device.cpp index 91098c5..94c9768 100644 --- a/src/engine/rendering/Device.cpp +++ b/src/engine/rendering/Device.cpp @@ -19,7 +19,9 @@ static VKAPI_ATTR vk::Bool32 VKAPI_CALL debugCallback( const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, [[maybe_unused]] void* pUserData ) { - if ( pCallbackData->flags & VkDebugUtilsMessageSeverityFlagBitsEXT::VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT ) + if ( pCallbackData->flags + & ( VkDebugUtilsMessageSeverityFlagBitsEXT::VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT + | VkDebugUtilsMessageSeverityFlagBitsEXT::VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT ) ) throw std::runtime_error( pCallbackData->pMessage ); else std::cout << pCallbackData->pMessage << std::endl; @@ -124,7 +126,7 @@ namespace fgl::engine appInfo.applicationVersion = VK_MAKE_VERSION( 1, 0, 0 ); appInfo.pEngineName = "titor"; appInfo.engineVersion = VK_MAKE_VERSION( 1, 0, 0 ); - appInfo.apiVersion = VK_API_VERSION_1_2; + appInfo.apiVersion = VK_API_VERSION_1_3; vk::InstanceCreateInfo createInfo {}; createInfo.pApplicationInfo = &appInfo; diff --git a/src/engine/systems/EntityRendererSystem.cpp b/src/engine/systems/EntityRendererSystem.cpp index 6f5be9e..ddb2157 100644 --- a/src/engine/systems/EntityRendererSystem.cpp +++ b/src/engine/systems/EntityRendererSystem.cpp @@ -143,8 +143,9 @@ namespace fgl::engine auto& [ itter_key, pair ] = *itter; auto& [ existing_cmd, model_matrix ] = pair; - existing_cmd.instanceCount++; + existing_cmd.instanceCount += 1; model_matrix.emplace_back( matrix_info ); + assert( model_matrix.size() == existing_cmd.instanceCount ); } else { @@ -159,6 +160,7 @@ namespace fgl::engine std::vector< ModelMatrixInfo > matrix_infos {}; matrix_infos.reserve( 1024 ); + matrix_infos.emplace_back( matrix_info ); draw_pairs.emplace( key, std::make_pair( cmd, std::move( matrix_infos ) ) ); } } @@ -178,8 +180,8 @@ namespace fgl::engine return; } - std::vector< vk::DrawIndexedIndirectCommand > draw_commands; - std::vector< ModelMatrixInfo > model_matrices; + std::vector< vk::DrawIndexedIndirectCommand > draw_commands {}; + std::vector< ModelMatrixInfo > model_matrices {}; draw_commands.reserve( draw_pairs.size() ); model_matrices.reserve( draw_pairs.size() * 2 ); @@ -188,52 +190,50 @@ namespace fgl::engine for ( auto& [ key, pair ] : draw_pairs ) { auto cmd { pair.first }; + assert( cmd != vk::DrawIndexedIndirectCommand() ); cmd.firstInstance = static_cast< std::uint32_t >( model_matrices.size() ); - auto matricies { std::move( pair.second ) }; + + assert( cmd.instanceCount == pair.second.size() ); + + assert( pair.second.size() > 0 ); draw_commands.emplace_back( cmd ); - model_matrices.insert( model_matrices.end(), matricies.begin(), matricies.end() ); + model_matrices.insert( model_matrices.end(), pair.second.begin(), pair.second.end() ); } + TracyCZoneEnd( filter_zone_TRACY ); - TracyCZoneN( draw_zone_TRACY, "Submit draw data", true ); - auto& draw_parameter_buffer { m_draw_parameter_buffers[ info.frame_idx ] }; - - if ( draw_parameter_buffer == nullptr || draw_parameter_buffer->capacity() < draw_commands.size() ) - { - draw_parameter_buffer = - std::make_unique< DrawParameterBufferSuballocation >( info.draw_parameter_buffer, draw_commands ); - } - else - { - //Simply set and flush - *draw_parameter_buffer = draw_commands; - } - const auto& draw_params { draw_parameter_buffer }; - assert( draw_params->size() == draw_commands.size() ); - - TracyCZoneEnd( draw_zone_TRACY ); - - draw_parameter_buffer->flush(); - + //Setup model matrix info buffers auto& model_matrix_info_buffer { m_model_matrix_info_buffers[ info.frame_idx ] }; - if ( model_matrix_info_buffer == nullptr || model_matrix_info_buffer->capacity() < model_matrices.size() ) - { - model_matrix_info_buffer = std::make_unique< - ModelMatrixInfoBufferSuballocation >( info.model_matrix_info_buffer, model_matrices ); - } - else - { - //We can re-use this buffer since it's of a proper size. - *model_matrix_info_buffer = model_matrices; - } - assert( model_matrix_info_buffer->size() == model_matrices.size() ); + model_matrix_info_buffer = + std::make_unique< ModelMatrixInfoBufferSuballocation >( info.model_matrix_info_buffer, model_matrices ); model_matrix_info_buffer->flush(); const auto& model_matricies_suballoc { model_matrix_info_buffer }; + for ( const auto& model_matrix : model_matrices ) + { + assert( model_matrix.texture_idx <= 100 ); + } + + assert( model_matrix_info_buffer->size() == model_matrices.size() ); + + // Setup draw parameter buffer + TracyCZoneN( draw_zone_TRACY, "Submit draw data", true ); + auto& draw_parameter_buffer { m_draw_parameter_buffers[ info.frame_idx ] }; + + draw_parameter_buffer = + std::make_unique< DrawParameterBufferSuballocation >( info.draw_parameter_buffer, draw_commands ); + + const auto& draw_params { draw_parameter_buffer }; + assert( draw_params->size() == draw_commands.size() ); + assert( draw_params->stride() == sizeof( vk::DrawIndexedIndirectCommand ) ); + + TracyCZoneEnd( draw_zone_TRACY ); + + draw_parameter_buffer->flush(); const std::vector< vk::Buffer > vertex_buffers { m_vertex_buffer->getVkBuffer(), model_matricies_suballoc->getVkBuffer() }; diff --git a/src/engine/texture/Texture.cpp b/src/engine/texture/Texture.cpp index a51d00e..5a9a0a8 100644 --- a/src/engine/texture/Texture.cpp +++ b/src/engine/texture/Texture.cpp @@ -39,8 +39,6 @@ namespace fgl::engine const auto data_c { stbi_load( path_str.data(), &x, &y, &channels, 4 ) }; - std::cout << "Loaded image with " << x << "x" << y << "\n\tImage had " << channels << " channels" << std::endl; - std::vector< unsigned char > data {}; data.resize( x * y * 4 );