feat: initial DX12 foundation framework

This commit is contained in:
SpecialX
2026-03-19 18:27:49 +08:00
commit 60f73b525d
70 changed files with 8993 additions and 0 deletions

View File

@@ -0,0 +1,55 @@
#pragma once
#ifdef _WIN64
#pragma warning(disable: 4530)
#endif // _WIN64
#include <stdint.h>
#include <assert.h>
#include <typeinfo>
#include <memory>
#include <unordered_map>
#include <string>
#include <mutex>
#include <cstring>
//#define USESTDFUNC
#if defined USESTDFUNC
#include <functional>
#endif
#if defined(_WIN64)
#include <DirectXMath.h>
#endif
#ifndef DISABLE_COPY
#define DISABLE_COPY(T) \
explicit T(const T&) = delete; \
T& operator=(const T&) = delete;
#endif
#ifndef DISABLE_MOVE
#define DISABLE_MOVE(T) \
explicit T(T&&) = delete; \
T& operator=(T&&) = delete
#endif
#ifndef DISABLE_COPY_AND_MOVE
#define DISABLE_COPY_AND_MOVE(T) DISABLE_COPY(T) DISABLE_MOVE(T);
#endif
#ifdef _DEBUG
#define DEBUG_OP(x) x
#else
#define DEBUG_OP(x)
#endif
//Common Header
#include "XEnginType.h"
#include "..\Utilities\Math.h"
#include "..\Utilities\MathTypes.h"
#include "..\Utilities\Utilities.h"
#include "Id.h"

143
Engine/Common/Id.h Normal file
View File

@@ -0,0 +1,143 @@
/**
* @file Id.h
* @brief 使用“索引 + 代数”打包方案的 32 位标识符工具。
* @details
* 位布局:
* - 低位:索引
* - 高位:代数
*
* 当索引被复用时,通过递增代数降低悬挂句柄误用风险。
*/
#pragma once
#include "CommonHeader.h"
namespace XEngine::id
{
/**
* @brief 标识符相关类型与常量。
*/
using id_type = u32;
namespace detail {
/**
* @brief 高位代数字段的位宽。
*/
constexpr u32 generation_bits{ 8 };
/**
* @brief 低位索引字段的位宽。
*/
constexpr u32 index_bit{ sizeof(id_type) * 8 - generation_bits };
/**
* @brief 用于提取索引字段的掩码。
*/
constexpr id_type index_mask{ (id_type{1} << index_bit) - 1 };
/**
* @brief 右移后用于提取代数字段的掩码。
*/
constexpr id_type generation_mask{ (id_type{1} << generation_bits) - 1 };
}
/**
* @brief 表示无效标识符的哨兵值。
*/
constexpr id_type invalid_id{ (id_type)-1 };
/**
* @brief 延迟回收删除项时的触发阈值。
*/
constexpr u32 min_deleted_elements{ 1024 };
/**
* @brief 可容纳代数字段的最小无符号整型。
*/
using generation_type = std::conditional_t<detail::generation_bits <= 16, std::conditional_t<detail::generation_bits <= 8, u8, u16>, u32>;
static_assert(sizeof(generation_type) * 8 >= detail::generation_bits);
static_assert((sizeof(id_type) - sizeof(generation_type)) > 0);
/**
* @brief 判断标识符是否有效。
* @param id 打包后的标识符。
* @return 当 @p id 不是无效哨兵值时返回 true。
*/
constexpr bool
is_valid(id_type id)
{
return id != invalid_id;
}
/**
* @brief 从打包标识符中提取索引字段。
* @param id 打包后的标识符。
* @return 低位索引字段。
* @pre 提取后的索引不能等于保留的全 1 索引值。
*/
constexpr id_type
index(id_type id)
{
id_type index{ id & detail::index_mask };
assert(index != detail::index_mask);
return index;
}
/**
* @brief 从打包标识符中提取代数字段。
* @param id 打包后的标识符。
* @return 高位代数字段。
*/
constexpr id_type
generation(id_type id)
{
return (id >> detail::index_bit) & detail::generation_mask;
}
/**
* @brief 为同一索引生成下一代标识符。
* @param id 当前打包标识符。
* @return 索引不变且代数递增后的标识符。
* @pre 代数递增后不能溢出到保留范围。
*/
constexpr id_type
new_generation(id_type id)
{
const id_type generation{ id::generation(id) + 1 };
assert(generation < (((u64)1 << detail::generation_bits) - 1));
return index(id) | (generation << detail::index_bit);
}
#if _DEBUG
namespace detail {
struct id_base
{
constexpr explicit id_base(id_type id) : _id(id) {}
constexpr operator id_type() const { return _id; }
private:
id_type _id;
};
}
/**
* @brief 在调试构建下声明强类型标识符。
* @details
* 调试构建使用派生自 id_base 的包装类型。
* 发布构建退化为 id_type 别名以保持零开销抽象。
*/
#define DEFINE_TYPED_ID(name) \
struct name final : id::detail::id_base \
{ \
constexpr explicit name(id::id_type id) \
: id_base{id}{} \
constexpr name() : id_base{ 0 }{} \
};
#else
/**
* @brief 发布模式下的零运行时开销类型别名。
*/
#define DEFINE_TYPED_ID(name) using name = id::id_type;
#endif
}

View File

@@ -0,0 +1,23 @@
#pragma once
#include <stdint.h>
using u8 = uint8_t;
using u16 = uint16_t;
using u32 = uint32_t;
using u64 = uint64_t;
using s8 = int8_t;
using s16 = int16_t;
using s32 = int32_t;
using s64 = int64_t;
constexpr u64 u64_invalid_id{ 0xffffffffffffffff };
constexpr u32 u32_invalid_id{ 0xffffffff };
constexpr u16 u16_invalid_id{ 0xffff };
constexpr u8 u8_invalid_id { 0xff };
using f32 = float;