Fixes bug with crashing at random times due to texture IDX going to the moon
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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() {}
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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() };
|
||||
|
||||
|
||||
@@ -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 );
|
||||
|
||||
Reference in New Issue
Block a user