Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added UniquePtr implementation #175

Merged
merged 4 commits into from
Jan 23, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/RED4ext/Detail/AddressHashes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ constexpr std::uint32_t CNamePool_Get = 0x68DF07DC;

#pragma region CommandListContext
constexpr std::uint32_t GetFreeCommandList = 1926836641UL;
constexpr std::uint32_t CommandListContext_dtor = 4228123904UL;
constexpr std::uint32_t CommandListContext_AddPendingBarrier = 2814122829UL;
constexpr std::uint32_t CommandListContext_Close = 1163138096UL;
constexpr std::uint32_t CommandListContext_FlushPendingBarriers = 2786924000UL;
Expand Down
22 changes: 15 additions & 7 deletions include/RED4ext/GpuApi/CommandListContext-inl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@

namespace RED4ext::GpuApi
{
RED4EXT_INLINE CommandListContext::~CommandListContext()
{
using func_t = void (*)(CommandListContext*);
static const UniversalRelocFunc<func_t> func(Detail::AddressHashes::CommandListContext_dtor);
func(this);
}

RED4EXT_INLINE void CommandListContext::AddPendingBarrier(const D3D12_RESOURCE_BARRIER& aBarrier)
{
using func_t = void (*)(CommandListContext*, const D3D12_RESOURCE_BARRIER&);
Expand All @@ -29,16 +36,17 @@ RED4EXT_INLINE void CommandListContext::FlushPendingBarriers()
func(this);
}

RED4EXT_INLINE CommandListContext* AcquireFreeCommandList(CommandListType aType, const StringView& aDebugName,
uint64_t aHash)
RED4EXT_INLINE UniquePtr<CommandListContext> AcquireFreeCommandList(CommandListType aType, const StringView& aDebugName,
uint64_t aHash)
{
// NOTE: This function has parameters for debug name and hash which seem to be optional.
// Expects unique ptr as an out param and returns it by reference.
using func_t = CommandListContext*& (*)(CommandListContext*&, CommandListType, const StringView&, uint64_t);
using func_t = UniquePtr<CommandListContext>* (*)(UniquePtr<CommandListContext>&, CommandListType,
const StringView&, uint64_t);
static const UniversalRelocFunc<func_t> func(Detail::AddressHashes::GetFreeCommandList);

// TODO: This should be unique_ptr which function fills in and returns.
CommandListContext* outContext = nullptr;
return func(outContext, aType, aDebugName, aHash);
UniquePtr<CommandListContext> outContext;
func(outContext, aType, aDebugName, aHash);

return std::move(outContext);
}
} // namespace RED4ext::GpuApi
10 changes: 7 additions & 3 deletions include/RED4ext/GpuApi/CommandListContext.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <RED4ext/CString.hpp>
#include <RED4ext/Common.hpp>
#include <RED4ext/DynArray.hpp>
#include <RED4ext/Memory/UniquePtr.hpp>
#include <RED4ext/StringView.hpp>

#include <d3d12.h>
Expand All @@ -24,6 +25,10 @@ enum class CommandListType

struct CommandListContext
{
using AllocatorType = Memory::CommandListsAllocator;

~CommandListContext();

void AddPendingBarrier(const D3D12_RESOURCE_BARRIER& aBarrier);
void Close();
void FlushPendingBarriers();
Expand All @@ -46,9 +51,8 @@ RED4EXT_ASSERT_OFFSET(CommandListContext, commandList, 0x030);
RED4EXT_ASSERT_OFFSET(CommandListContext, type, 0x068);
RED4EXT_ASSERT_OFFSET(CommandListContext, pendingBarriers, 0x528);

// TODO: Change to return unique ptr.
CommandListContext* AcquireFreeCommandList(CommandListType aType, const StringView& aDebugName = "",
uint64_t aHash = 0);
UniquePtr<CommandListContext> AcquireFreeCommandList(CommandListType aType, const StringView& aDebugName = "",
uint64_t aHash = 0);

} // namespace GpuApi
} // namespace RED4ext
Expand Down
18 changes: 9 additions & 9 deletions include/RED4ext/GpuApi/DeviceData.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,15 @@ struct ResourceContainer

struct SDeviceDataBase
{
uint8_t unk00[0x02f180]; // 000000
SpinLock resourcesSpinLock; // 02F180
uint8_t unk2f180[0x5c0ae0 - 0x02f181]; // 02F181
ResourceContainer<SBufferData, 32768> buffers; // 5C0AE0
uint8_t unkb40af8[0xc97f20 - 0xb50af0]; // B50AF0
ResourceContainer<SSwapChainData, 32> swapChains; // C97F20
uint8_t unkc99678[0xd1ad80 - 0xc99570]; // C98028
ResourceContainer<CommandListContext*, 128> commandLists; // D1AD80 - TODO: Uses unique ptr wrapper.
uint8_t unkd1b598[0x13bc240 - 0xd1b690]; // D1B690
uint8_t unk00[0x02f180]; // 000000
SpinLock resourcesSpinLock; // 02F180
uint8_t unk2f180[0x5c0ae0 - 0x02f181]; // 02F181
ResourceContainer<SBufferData, 32768> buffers; // 5C0AE0
uint8_t unkb40af8[0xc97f20 - 0xb50af0]; // B50AF0
ResourceContainer<SSwapChainData, 32> swapChains; // C97F20
uint8_t unkc99678[0xd1ad80 - 0xc99570]; // C98028
ResourceContainer<UniquePtr<CommandListContext>, 128> commandLists; // D1AD80
uint8_t unkd1b598[0x13bc240 - 0xd1b690]; // D1B690
};
RED4EXT_ASSERT_SIZE(SDeviceDataBase, 0x13bc240);
RED4EXT_ASSERT_OFFSET(SDeviceDataBase, buffers, 0x5c0ae0);
Expand Down
2 changes: 1 addition & 1 deletion include/RED4ext/ISerializable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ struct ISerializable
operator const WeakHandle<ISerializable>&() const noexcept;
operator Handle<ISerializable>() noexcept;

WeakHandle<ISerializable> ref; // 00 - Initialized in Handle ctor
WeakHandle<ISerializable> ref; // 08 - Initialized in Handle ctor
WeakHandle<ISerializable> unk18; // 18
uint64_t unk28; // 28 - Global incremental ID, used in serialization
};
Expand Down
110 changes: 110 additions & 0 deletions include/RED4ext/Memory/UniquePtr.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
#pragma once

#include <memory>

#include <RED4ext/Common.hpp>
#include <RED4ext/Memory/Utils.hpp>

namespace RED4ext
{
template<typename T>
class UniquePtr
{
public:
UniquePtr(T* aPtr = nullptr)
: instance(aPtr)
{
}

UniquePtr(const UniquePtr&) = delete;

UniquePtr(UniquePtr&& aOther) noexcept
{
instance = aOther.Release();
}

~UniquePtr()
{
static_assert(Memory::IsDeleteCompatible<T>,
"UniquePtr only supports types that define the allocator type and are destructible "
"(a polymorphic type requires a virtual destructor)");

if (instance)
{
Memory::Delete(instance);
}
}

UniquePtr& operator=(const UniquePtr&) = delete;

UniquePtr& operator=(UniquePtr&& aRhs) noexcept
{
UniquePtr(std::move(aRhs)).Swap(*this);
psiberx marked this conversation as resolved.
Show resolved Hide resolved
return *this;
}

template<typename U = T, typename = std::enable_if_t<!std::is_void_v<U>>>
[[nodiscard]] inline U& operator*() const
psiberx marked this conversation as resolved.
Show resolved Hide resolved
{
return *GetPtr();
}

[[nodiscard]] inline T* operator->() const
{
return GetPtr();
}

[[nodiscard]] inline operator T*() const
{
return GetPtr();
}

explicit operator bool() const noexcept
{
return GetPtr() != nullptr;
}

[[nodiscard]] T* GetPtr() const noexcept
{
return reinterpret_cast<T*>(instance);
}

template<typename U>
[[nodiscard]] U* GetPtr() const noexcept
{
return reinterpret_cast<U*>(instance);
}

T* Release() noexcept
{
T* released = instance;
instance = nullptr;
return released;
}

void Reset() noexcept
{
UniquePtr().Swap(*this);
}

void Reset(T* aPtr) noexcept
{
UniquePtr(aPtr).Swap(*this);
}

void Swap(UniquePtr& aOther) noexcept
{
std::swap(instance, aOther.instance);
}

T* instance;
};
RED4EXT_ASSERT_SIZE(UniquePtr<void>, 0x8);
RED4EXT_ASSERT_OFFSET(UniquePtr<void>, instance, 0x0);

template<typename T, typename... Args>
inline UniquePtr<T> MakeUnique(Args&&... args)
{
return Memory::New<T>(std::forward<Args>(args)...);
}
} // namespace RED4ext
1 change: 1 addition & 0 deletions include/RED4ext/RED4ext.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <RED4ext/Hashing/Murmur3.hpp>
#include <RED4ext/Memory/Allocators.hpp>
#include <RED4ext/Memory/SharedPtr.hpp>
#include <RED4ext/Memory/UniquePtr.hpp>

#include <RED4ext/IO/BaseStream.hpp>

Expand Down