mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2026-09-22 13:57:07 +00:00
fix(zone): align loaded block buffers (#1006)
* fix(zone): align loaded block buffers * chore: move XBlockTests to correct dir * chore: align XBlocks to 4096 to match the game --------- Co-authored-by: LVEIceFire <[email protected]> Co-authored-by: Jan Laupetin <[email protected]>
This commit is contained in:
co-authored by
LVEIceFire
Jan Laupetin
parent
2547516e39
commit
fc1a0bbc38
@@ -1,5 +1,19 @@
|
||||
#include "XBlock.h"
|
||||
|
||||
#include <new>
|
||||
|
||||
namespace
|
||||
{
|
||||
// This must be higher or equal to the highest alignment value in any game struct.
|
||||
// The games always seem to align to 4096 up to T6 so we'll keep parity.
|
||||
constexpr std::align_val_t XBLOCK_BUFFER_ALIGNMENT{4096u};
|
||||
} // namespace
|
||||
|
||||
void XBlockBufferDeleter::operator()(std::uint8_t* buffer) const noexcept
|
||||
{
|
||||
::operator delete[](buffer, XBLOCK_BUFFER_ALIGNMENT);
|
||||
}
|
||||
|
||||
XBlock::XBlock(std::string name, const unsigned index, const XBlockType type)
|
||||
: m_name(std::move(name)),
|
||||
m_index(index),
|
||||
@@ -12,7 +26,7 @@ void XBlock::Alloc(const size_t blockSize)
|
||||
{
|
||||
if (blockSize > 0)
|
||||
{
|
||||
m_buffer = std::make_unique<uint8_t[]>(blockSize);
|
||||
m_buffer.reset(static_cast<std::uint8_t*>(::operator new[](blockSize, XBLOCK_BUFFER_ALIGNMENT)));
|
||||
m_buffer_size = blockSize;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -13,6 +13,11 @@ enum class XBlockType : std::uint8_t
|
||||
BLOCK_TYPE_NORMAL
|
||||
};
|
||||
|
||||
struct XBlockBufferDeleter
|
||||
{
|
||||
void operator()(std::uint8_t* buffer) const noexcept;
|
||||
};
|
||||
|
||||
class XBlock
|
||||
{
|
||||
public:
|
||||
@@ -24,6 +29,6 @@ public:
|
||||
unsigned m_index;
|
||||
XBlockType m_type;
|
||||
|
||||
std::unique_ptr<uint8_t[]> m_buffer;
|
||||
std::unique_ptr<uint8_t[], XBlockBufferDeleter> m_buffer;
|
||||
size_t m_buffer_size;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
#include "Zone/XBlock.h"
|
||||
|
||||
#include <array>
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#include <cstdint>
|
||||
|
||||
namespace
|
||||
{
|
||||
TEST_CASE("Zone block buffers provide the maximum asset alignment", "[zone-loading][stream]")
|
||||
{
|
||||
static constexpr std::uintptr_t REQUIRED_ALIGNMENT = 4096u;
|
||||
|
||||
XBlock block("test", 0, XBlockType::BLOCK_TYPE_NORMAL);
|
||||
constexpr size_t sizes[]{1u, 7u, 16u, 4096u, 65537u};
|
||||
|
||||
for (const auto size : sizes)
|
||||
{
|
||||
block.Alloc(size);
|
||||
REQUIRE(reinterpret_cast<std::uintptr_t>(block.m_buffer.get()) % REQUIRED_ALIGNMENT == 0u);
|
||||
REQUIRE(block.m_buffer_size == size);
|
||||
}
|
||||
|
||||
block.Alloc(0u);
|
||||
REQUIRE(block.m_buffer.get() == nullptr);
|
||||
REQUIRE(block.m_buffer_size == 0u);
|
||||
}
|
||||
} // namespace
|
||||
Reference in New Issue
Block a user