#pragma once

#include "CommonHeader.h"
#include "Graphics\Renderer.h"
#include "Platform\Window.h"

// 引入 DirectX Graphics Infrastructure（DXGI）6.0 
// 头文件，用于访问 DXGI 接口（如 IDXGIFactory6、
// IDXGIAdapter4 等），支持枚举 GPU、查询显示模式、管理
// 交换链等底层图形功能
#include <dxgi1_6.h>
// 引入 Direct3D 12 头文件，提供 D3D12 API 接口，
// 用于创建渲染管线、管理资源与 GPU 命令
#include <d3d12.h>

// 引入 Windows Runtime C++ 模板库（WRL）头文件，提供智能指针（如 Microsoft::WRL::ComPtr）
// 用于简化 COM 对象的生命周期管理
#include <wrl.h>

// 引入互斥锁头文件，用于保护资源的互斥锁
#include <mutex>


#pragma comment(lib, "dxgi.lib")
#pragma comment(lib, "d3d12.lib")

namespace XEngine::graphics::d3d12 {
    constexpr u32 frame_buffer_count{ 3 };
}

// 定义 DirectX 调试宏 DXCall，用于在调试模式下检查 DirectX API 调用返回值
// 如果调用失败（FAILED），则输出错误信息（文件名、行号、调用语句）并触发断点
// 在发布模式下，DXCall 宏不执行任何额外操作，直接执行原始调用
#ifdef _DEBUG
#ifndef DXCall
#define DXCall(x)                               \
if(FAILED(x)){									\
	char line_number[32];						\
	sprintf_s(line_number, "%u", __LINE__);		\
	OutputDebugStringA("Error in: ");			\
	OutputDebugStringA(__FILE__);				\
	OutputDebugStringA("\nLine: ");				\
	OutputDebugStringA(line_number);			\
	OutputDebugStringA("\n");					\
	OutputDebugStringA(#x);						\
	OutputDebugStringA("\n");					\
	__debugbreak();								\
}
#endif // !DXCall
#else
#ifndef DXCall
#define DXCall(x) x
#endif // !DXCall
#endif // _DEBUG

// 定义 DirectX 对象命名宏，用于在调试模式下为 Direct3D 12 对象设置调试名称
// 这些宏仅在 _DEBUG 模式下生效，可帮助开发者在 PIX、RenderDoc 等图形调试工具中
// 识别和追踪 D3D12 对象（如缓冲区、纹理、管线状态等）
// NAME_D3D12_OBJECT: 为单个对象设置名称
// NAME_D3D12_OBJECT_INDEXED: 为数组中的对象设置带索引的名称（如资源数组）
#ifdef _DEBUG
#define NAME_D3D12_OBJECT(obj,name) obj->SetName(name); OutputDebugString(L"::D3D12 Object Created: "); OutputDebugString(name); OutputDebugString(L"\n");
#define NAME_D3D12_OBJECT_INDEXED(obj,n,name)					\
{																\
wchar_t full_name[128];											\
if(swprintf_s(full_name, L"%s[%llu]", name, (u64)n) >0 ){		\
	obj->SetName(full_name);									\
	OutputDebugString(L"::D3D12 Object Created: ");				\
	OutputDebugString(full_name);								\
	OutputDebugString(L"\n");									\
}}

#else
#define NAME_D3D12_OBJECT(obj,name)
#define NAME_D3D12_OBJECT_INDEXED(obj,n,name)
#endif
