Compare commits

...

25 Commits

Author SHA1 Message Date
76848ab4e3 Move heap descriptor into its own file and prepare for the removing of the staging descriptor 2025-03-29 22:05:09 -04:00
94292851cc Remove Swapchain SRV (no use)
Removed useless parameters in the root signature
various small changes
Began removing staging descriptor to use unified descriptors
2025-03-29 21:47:21 -04:00
2d3a075eb6 Bindless resource first step 2025-03-24 22:19:52 -04:00
d8c36b7715 Check resource binding tier 2025-03-23 16:01:04 -04:00
c56bc43723 misc 2025-03-22 17:31:35 -04:00
f4c82f0fb3 Added support to DirectX Agility Sdk to enable shader model 6.6+ on windows 10. 2025-03-22 00:09:48 -04:00
4e0aaa129f Fixing some includes problems
Using interrupt 3 instead of system pause to break on script end while debugging but not when running
Added a .bat script to recompile all shaders.
2025-03-15 21:43:20 -04:00
f4ba25bec1 Reload of shaders working! 2025-03-15 21:17:44 -04:00
c9cd01bb31 Prepare shader reload.
- Expose wait until gpus is idle to api
- Alt+R to reload
2025-03-15 19:55:41 -04:00
f01c8c3ccb Added missing functions to allow wait for swap chain.
Proper resource tracking to allow for destruction of graphics pipeline
Textures are tracked but not released so nothing has been done yet
various changes
2025-03-13 23:07:01 -04:00
84e1194f21 Draw triangle 2025-03-11 23:36:37 -04:00
a2d9980dc8 Adding a comment on ID3D12InfoQueue1 that are apparently only available on Win11 2025-03-11 22:47:45 -04:00
df870b717e Remove useless code in dx12 debug layer initialization 2025-03-11 22:46:49 -04:00
0d93cd9e6d Graphics pipeline creation is working 2025-03-11 22:45:21 -04:00
a9fe4683fb Graphics pipeline iteration
Lot of code.
Not working yet
2025-03-09 22:52:08 -04:00
a366d75fdc Renamed DX12 files prefix to D3D12 2025-03-09 16:57:20 -04:00
aae780ec6d First pass graphics pipeline. Not functional 2025-03-09 16:54:26 -04:00
8c6c42e123 Shader: Added code to load compiled shader 2025-03-09 15:54:13 -04:00
da203c80f3 Finished first version of shader compiler. HLSL -> DXIL.
Submitting vertex and frag shader needed to display a triangle.
2025-03-08 22:36:15 -05:00
f9f292b6d6 Adding read file code 2025-03-07 23:04:30 -05:00
5fd3fc75eb IOStream can now be open on a file and write into it. 2025-03-05 22:49:57 -05:00
231fea81dd Support utf8 codepoint in win32 console 2025-03-05 16:55:08 -05:00
764824ff24 Making string struct a bit more simple and support only utf8.
Still just ascii for now but a bit easier to manager.
Use [..]A() functions from win api to not have to convert to wide char everywhere
2025-03-05 15:56:56 -05:00
09dc26ae79 Adding IOStream + String library (needed to have proper iostream) 2025-03-01 21:17:10 -05:00
fc399d52ec New shader compiler app (doing nothing) that i forgot to submit... 2025-03-01 11:02:10 -05:00
107 changed files with 83733 additions and 628 deletions

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,4 @@
float4 main(float4 Color : TEXCOORD0) : SV_Target0
{
return Color;
}

View File

@@ -0,0 +1,39 @@
struct Input
{
uint VertexIndex : SV_VertexID;
};
struct Output
{
float4 Color : TEXCOORD0;
float4 Position : SV_Position;
};
Output main(Input input)
{
Output output;
float2 pos;
if (input.VertexIndex == 0)
{
pos = (-1.0f).xx;
output.Color = float4(1.0f, 0.0f, 0.0f, 1.0f);
}
else
{
if (input.VertexIndex == 1)
{
pos = float2(1.0f, -1.0f);
output.Color = float4(0.0f, 1.0f, 0.0f, 1.0f);
}
else
{
if (input.VertexIndex == 2)
{
pos = float2(0.0f, 1.0f);
output.Color = float4(0.0f, 0.0f, 1.0f, 1.0f);
}
}
}
output.Position = float4(pos, 0.0f, 1.0f);
return output;
}

View File

@@ -3,6 +3,7 @@
#undef min #undef min
#undef max #undef max
#include <Core/HAL/Filesystem/Filesystem.h>
#include <Core/Logging/LogManager.h> #include <Core/Logging/LogManager.h>
#include <Core/Logging/LogTypes.h> #include <Core/Logging/LogTypes.h>
#include <Entity/Entity.h> #include <Entity/Entity.h>
@@ -65,5 +66,5 @@ extern "C" __declspec(dllexport) void __cdecl GameShutdown()
extern "C" __declspec(dllexport) void __cdecl GameUpdate(float deltaTime) extern "C" __declspec(dllexport) void __cdecl GameUpdate(float deltaTime)
{ {
printf("Updating game...\n"); //printf("Updating game...\n");
} }

View File

@@ -114,9 +114,13 @@
<ClInclude Include="include\Core\Common\NonMovable.h"/> <ClInclude Include="include\Core\Common\NonMovable.h"/>
<ClInclude Include="include\Core\Common\NonNullPtr.h"/> <ClInclude Include="include\Core\Common\NonNullPtr.h"/>
<ClInclude Include="include\Core\Common\Singleton.h"/> <ClInclude Include="include\Core\Common\Singleton.h"/>
<ClInclude Include="include\Core\Common\String.h"/>
<ClInclude Include="include\Core\Container\Vector.h"/> <ClInclude Include="include\Core\Container\Vector.h"/>
<ClInclude Include="include\Core\HAL\Display\Display.h"/> <ClInclude Include="include\Core\HAL\Display\Display.h"/>
<ClInclude Include="include\Core\HAL\DynLib\DynamicLibrary.h"/>
<ClInclude Include="include\Core\HAL\Event\SystemEvent.h"/> <ClInclude Include="include\Core\HAL\Event\SystemEvent.h"/>
<ClInclude Include="include\Core\HAL\Filesystem\Filesystem.h"/>
<ClInclude Include="include\Core\HAL\IO\IOStream.h"/>
<ClInclude Include="include\Core\HAL\Keyboard\Keyboard.h"/> <ClInclude Include="include\Core\HAL\Keyboard\Keyboard.h"/>
<ClInclude Include="include\Core\HAL\Keyboard\KeyCode.h"/> <ClInclude Include="include\Core\HAL\Keyboard\KeyCode.h"/>
<ClInclude Include="include\Core\HAL\Keyboard\ScanCode.h"/> <ClInclude Include="include\Core\HAL\Keyboard\ScanCode.h"/>
@@ -125,6 +129,7 @@
<ClInclude Include="include\Core\JulietInit.h"/> <ClInclude Include="include\Core\JulietInit.h"/>
<ClInclude Include="include\Core\Logging\LogManager.h"/> <ClInclude Include="include\Core\Logging\LogManager.h"/>
<ClInclude Include="include\Core\Logging\LogTypes.h"/> <ClInclude Include="include\Core\Logging\LogTypes.h"/>
<ClInclude Include="include\Core\Math\MathUtils.h" />
<ClInclude Include="include\Core\Math\Shape.h"/> <ClInclude Include="include\Core\Math\Shape.h"/>
<ClInclude Include="include\Core\Memory\Allocator.h"/> <ClInclude Include="include\Core\Memory\Allocator.h"/>
<ClInclude Include="include\Core\Memory\Utils.h"/> <ClInclude Include="include\Core\Memory\Utils.h"/>
@@ -140,7 +145,9 @@
<ClInclude Include="include\Graphics\Colors.h"/> <ClInclude Include="include\Graphics\Colors.h"/>
<ClInclude Include="include\Graphics\Graphics.h"/> <ClInclude Include="include\Graphics\Graphics.h"/>
<ClInclude Include="include\Graphics\GraphicsConfig.h"/> <ClInclude Include="include\Graphics\GraphicsConfig.h"/>
<ClInclude Include="include\Graphics\GraphicsPipeline.h" />
<ClInclude Include="include\Graphics\RenderPass.h"/> <ClInclude Include="include\Graphics\RenderPass.h"/>
<ClInclude Include="include\Graphics\Shader.h" />
<ClInclude Include="include\Graphics\Texture.h"/> <ClInclude Include="include\Graphics\Texture.h"/>
<ClInclude Include="include\Juliet.h"/> <ClInclude Include="include\Juliet.h"/>
<ClInclude Include="include\pch.h"/> <ClInclude Include="include\pch.h"/>
@@ -156,23 +163,47 @@
<ClInclude Include="src\Core\HAL\Event\WindowEvent.h"/> <ClInclude Include="src\Core\HAL\Event\WindowEvent.h"/>
<ClInclude Include="src\Core\HAL\Filesystem\Filesystem_Platform.h"/> <ClInclude Include="src\Core\HAL\Filesystem\Filesystem_Platform.h"/>
<ClInclude Include="src\Core\HAL\Filesystem\Filesystem_Private.h"/> <ClInclude Include="src\Core\HAL\Filesystem\Filesystem_Private.h"/>
<ClInclude Include="src\Core\HAL\IO\IOStream_Private.h"/>
<ClInclude Include="src\Core\Math\Math_Private.h" />
<ClInclude Include="src\Core\Networking\SocketPlatformImpl.h"/> <ClInclude Include="src\Core\Networking\SocketPlatformImpl.h"/>
<ClInclude Include="src\Core\HAL\Win32.h"/> <ClInclude Include="src\Core\HAL\Win32.h"/>
<ClInclude Include="src\Graphics\D3D12\AgilitySDK\d3d12.h" />
<ClInclude Include="src\Graphics\D3D12\AgilitySDK\d3d12compatibility.h" />
<ClInclude Include="src\Graphics\D3D12\AgilitySDK\d3d12sdklayers.h" />
<ClInclude Include="src\Graphics\D3D12\AgilitySDK\d3d12shader.h" />
<ClInclude Include="src\Graphics\D3D12\AgilitySDK\D3D12TokenizedProgramFormat.hpp" />
<ClInclude Include="src\Graphics\D3D12\AgilitySDK\d3d12video.h" />
<ClInclude Include="src\Graphics\D3D12\AgilitySDK\d3dcommon.h" />
<ClInclude Include="src\Graphics\D3D12\AgilitySDK\d3dx12\d3dx12.h" />
<ClInclude Include="src\Graphics\D3D12\AgilitySDK\d3dx12\d3dx12_barriers.h" />
<ClInclude Include="src\Graphics\D3D12\AgilitySDK\d3dx12\d3dx12_check_feature_support.h" />
<ClInclude Include="src\Graphics\D3D12\AgilitySDK\d3dx12\d3dx12_core.h" />
<ClInclude Include="src\Graphics\D3D12\AgilitySDK\d3dx12\d3dx12_default.h" />
<ClInclude Include="src\Graphics\D3D12\AgilitySDK\d3dx12\d3dx12_pipeline_state_stream.h" />
<ClInclude Include="src\Graphics\D3D12\AgilitySDK\d3dx12\d3dx12_property_format_table.h" />
<ClInclude Include="src\Graphics\D3D12\AgilitySDK\d3dx12\d3dx12_render_pass.h" />
<ClInclude Include="src\Graphics\D3D12\AgilitySDK\d3dx12\d3dx12_resource_helpers.h" />
<ClInclude Include="src\Graphics\D3D12\AgilitySDK\d3dx12\d3dx12_root_signature.h" />
<ClInclude Include="src\Graphics\D3D12\AgilitySDK\d3dx12\d3dx12_state_object.h" />
<ClInclude Include="src\Graphics\D3D12\AgilitySDK\dxgiformat.h" />
<ClInclude Include="src\Graphics\D3D12\D3D12Common.h"/> <ClInclude Include="src\Graphics\D3D12\D3D12Common.h"/>
<ClInclude Include="src\Graphics\D3D12\D3D12DescriptorHeap.h" />
<ClInclude Include="src\Graphics\D3D12\D3D12GraphicsPipeline.h" />
<ClInclude Include="src\Graphics\D3D12\D3D12RenderPass.h"/> <ClInclude Include="src\Graphics\D3D12\D3D12RenderPass.h"/>
<ClInclude Include="src\Graphics\D3D12\D3D12Shader.h"/> <ClInclude Include="src\Graphics\D3D12\D3D12Shader.h"/>
<ClInclude Include="src\Graphics\D3D12\D3D12Synchronization.h"/> <ClInclude Include="src\Graphics\D3D12\D3D12Synchronization.h"/>
<ClInclude Include="src\Graphics\D3D12\D3D12Texture.h"/> <ClInclude Include="src\Graphics\D3D12\D3D12Texture.h"/>
<ClInclude Include="src\Graphics\D3D12\DX12CommandList.h"/> <ClInclude Include="src\Graphics\D3D12\D3D12CommandList.h" />
<ClInclude Include="src\Graphics\D3D12\DX12GraphicsDevice.h"/> <ClInclude Include="src\Graphics\D3D12\D3D12GraphicsDevice.h" />
<ClInclude Include="src\Graphics\D3D12\DX12Includes.h"/> <ClInclude Include="src\Graphics\D3D12\D3D12Includes.h" />
<ClInclude Include="src\Graphics\D3D12\DX12SwapChain.h"/> <ClInclude Include="src\Graphics\D3D12\D3D12SwapChain.h" />
<ClInclude Include="src\Graphics\D3D12\DX12Utils.h"/> <ClInclude Include="src\Graphics\D3D12\D3D12Utils.h" />
<ClInclude Include="src\Graphics\GraphicsDevice.h"/> <ClInclude Include="src\Graphics\GraphicsDevice.h"/>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="src\Core\Application\ApplicationManager.cpp"/> <ClCompile Include="src\Core\Application\ApplicationManager.cpp"/>
<ClCompile Include="src\Core\Common\CoreUtils.cpp"/> <ClCompile Include="src\Core\Common\CoreUtils.cpp"/>
<ClCompile Include="src\Core\Common\String.cpp" />
<ClCompile Include="src\Core\HAL\Display\Display.cpp"/> <ClCompile Include="src\Core\HAL\Display\Display.cpp"/>
<ClCompile Include="src\Core\HAL\Display\Win32\Win32DisplayDevice.cpp"/> <ClCompile Include="src\Core\HAL\Display\Win32\Win32DisplayDevice.cpp"/>
<ClCompile Include="src\Core\HAL\Display\Win32\Win32DisplayEvent.cpp"/> <ClCompile Include="src\Core\HAL\Display\Win32\Win32DisplayEvent.cpp"/>
@@ -185,26 +216,32 @@
<ClCompile Include="src\Core\HAL\Event\WindowEvent.cpp"/> <ClCompile Include="src\Core\HAL\Event\WindowEvent.cpp"/>
<ClCompile Include="src\Core\HAL\Filesystem\Filesystem.cpp"/> <ClCompile Include="src\Core\HAL\Filesystem\Filesystem.cpp"/>
<ClCompile Include="src\Core\HAL\Filesystem\Win32\Win32Filesystem.cpp"/> <ClCompile Include="src\Core\HAL\Filesystem\Win32\Win32Filesystem.cpp"/>
<ClCompile Include="src\Core\HAL\IO\IOStream.cpp"/>
<ClCompile Include="src\Core\HAL\IO\Win32\Win32IOStream.cpp"/>
<ClCompile Include="src\Core\HotReload\HotReload.cpp"/> <ClCompile Include="src\Core\HotReload\HotReload.cpp"/>
<ClCompile Include="src\Core\HotReload\Win32\Win32HotReload.cpp"/> <ClCompile Include="src\Core\HotReload\Win32\Win32HotReload.cpp"/>
<ClCompile Include="src\Core\Juliet.cpp"/> <ClCompile Include="src\Core\Juliet.cpp"/>
<ClCompile Include="src\Core\Logging\LogManager.cpp"/> <ClCompile Include="src\Core\Logging\LogManager.cpp"/>
<ClCompile Include="src\Core\Memory\Allocator.cpp"/> <ClCompile Include="src\Core\Math\MathRound.cpp" />
<ClCompile Include="src\Core\Networking\NetworkPacket.cpp"/> <ClCompile Include="src\Core\Memory\Allocator.cpp" />
<ClCompile Include="src\Core\Networking\Socket.cpp"/> <ClCompile Include="src\Core\Networking\NetworkPacket.cpp" />
<ClCompile Include="src\Core\Networking\TcpListener.cpp"/> <ClCompile Include="src\Core\Networking\Socket.cpp" />
<ClCompile Include="src\Core\Networking\TcpSocket.cpp"/> <ClCompile Include="src\Core\Networking\TcpListener.cpp" />
<ClCompile Include="src\Core\Networking\Win32\Win32SocketPlatformImpl.cpp"/> <ClCompile Include="src\Core\Networking\TcpSocket.cpp" />
<ClCompile Include="src\Engine\Engine.cpp"/> <ClCompile Include="src\Core\Networking\Win32\Win32SocketPlatformImpl.cpp" />
<ClCompile Include="src\Graphics\D3D12\D3D12Common.cpp"/> <ClCompile Include="src\Engine\Engine.cpp" />
<ClCompile Include="src\Graphics\D3D12\D3D12RenderPass.cpp"/> <ClCompile Include="src\Graphics\D3D12\AgilitySDK\d3dx12\d3dx12_property_format_table.cpp" />
<ClCompile Include="src\Graphics\D3D12\D3D12Shader.cpp"/> <ClCompile Include="src\Graphics\D3D12\D3D12Common.cpp" />
<ClCompile Include="src\Graphics\D3D12\D3D12Synchronization.cpp"/> <ClCompile Include="src\Graphics\D3D12\D3D12DescriptorHeap.cpp" />
<ClCompile Include="src\Graphics\D3D12\D3D12Texture.cpp"/> <ClCompile Include="src\Graphics\D3D12\D3D12GraphicsPipeline.cpp" />
<ClCompile Include="src\Graphics\D3D12\DX12CommandList.cpp"/> <ClCompile Include="src\Graphics\D3D12\D3D12RenderPass.cpp" />
<ClCompile Include="src\Graphics\D3D12\DX12GraphicsDevice.cpp"/> <ClCompile Include="src\Graphics\D3D12\D3D12Shader.cpp" />
<ClCompile Include="src\Graphics\D3D12\DX12SwapChain.cpp"/> <ClCompile Include="src\Graphics\D3D12\D3D12Synchronization.cpp" />
<ClCompile Include="src\Graphics\D3D12\DX12Utils.cpp"/> <ClCompile Include="src\Graphics\D3D12\D3D12Texture.cpp" />
<ClCompile Include="src\Graphics\D3D12\D3D12CommandList.cpp" />
<ClCompile Include="src\Graphics\D3D12\D3D12GraphicsDevice.cpp" />
<ClCompile Include="src\Graphics\D3D12\D3D12SwapChain.cpp" />
<ClCompile Include="src\Graphics\D3D12\D3D12Utils.cpp" />
<ClCompile Include="src\Graphics\Graphics.cpp"> <ClCompile Include="src\Graphics\Graphics.cpp">
<RuntimeLibrary>MultiThreadedDebugDll</RuntimeLibrary> <RuntimeLibrary>MultiThreadedDebugDll</RuntimeLibrary>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
@@ -265,8 +302,15 @@
</ClCompile> </ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Content Include="include\Core\Thread\Mutex.h"/> <Content Include="include\Core\Thread\Mutex.h" />
<Content Include="src\TODO.txt"/> <Content Include="src\Graphics\D3D12\AgilitySDK\d3d12.idl" />
<Content Include="src\Graphics\D3D12\AgilitySDK\d3d12compatibility.idl" />
<Content Include="src\Graphics\D3D12\AgilitySDK\d3d12sdklayers.idl" />
<Content Include="src\Graphics\D3D12\AgilitySDK\d3d12video.idl" />
<Content Include="src\Graphics\D3D12\AgilitySDK\d3dcommon.idl" />
<Content Include="src\Graphics\D3D12\AgilitySDK\dxgiformat.idl" />
<Content Include="src\Graphics\D3D12\AgilitySDK\VERSION.txt" />
<Content Include="src\TODO.txt" />
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">

View File

@@ -20,18 +20,10 @@ using size_t = std::size_t;
struct ByteBuffer struct ByteBuffer
{ {
const Byte* Data; Byte* Data;
size_t Size; size_t Size;
}; };
template <typename CharType>
struct StringBuffer
{
CharType* Data;
size_t Size;
};
#define StringBufferParam(str) { (str), sizeof(str) }
using FunctionPtr = auto (*)(void) -> void; using FunctionPtr = auto (*)(void) -> void;
// Limits // Limits
@@ -40,7 +32,12 @@ consteval Type MaxValueOf()
{ {
return std::numeric_limits<Type>::max(); return std::numeric_limits<Type>::max();
} }
constexpr uint32 uint8Max = MaxValueOf<uint8>(); constexpr uint8 uint8Max = MaxValueOf<uint8>();
constexpr uint32 uint16Max = MaxValueOf<uint16>(); constexpr uint16 uint16Max = MaxValueOf<uint16>();
constexpr uint32 uint32Max = MaxValueOf<uint32>(); constexpr uint32 uint32Max = MaxValueOf<uint32>();
constexpr uint32 uint64Max = MaxValueOf<uint64>(); constexpr uint64 uint64Max = MaxValueOf<uint64>();
constexpr int8 int8Max = MaxValueOf<int8>();
constexpr int16 int16Max = MaxValueOf<int16>();
constexpr int32 int32Max = MaxValueOf<int32>();
constexpr int64 int64Max = MaxValueOf<int64>();

View File

@@ -1,9 +1,10 @@
#pragma once #pragma once
#include <algorithm>
#include <Core/Common/CoreTypes.h> #include <Core/Common/CoreTypes.h>
#include <Juliet.h> #include <Juliet.h>
#include <algorithm>
namespace Juliet namespace Juliet
{ {
@@ -18,8 +19,16 @@ namespace Juliet
} \ } \
while (0) while (0)
#define Unimplemented() \
do \
{ \
Juliet::JulietAssert("Unimplemented!"); \
} \
while (0)
#else #else
#define Assert(Expression) #define Assert(Expression)
#define Unimplemented()
#endif #endif
extern void JULIET_API JulietAssert(const char* expression); extern void JULIET_API JulietAssert(const char* expression);
@@ -36,31 +45,40 @@ namespace Juliet
} }
} }
#define MemCopy memcpy template <class Function>
class DeferredFunction
template <typename Type>
constexpr Type Min(Type lhs, Type rhs)
{ {
return rhs < lhs ? rhs : lhs; public:
} explicit DeferredFunction(const Function& otherFct) noexcept
: Callback(otherFct)
template <typename Type>
constexpr Type Max(Type lhs, Type rhs)
{
return lhs < rhs ? rhs : lhs;
}
template <typename Type>
constexpr Type Clamp(Type val, Type min, Type max)
{
if (val < min)
{ {
return min;
} }
if (val > max) explicit DeferredFunction(Function&& otherFct) noexcept
: Callback(std::move(otherFct))
{ {
return max;
} }
return val;
~DeferredFunction() noexcept { Callback(); }
DeferredFunction(const DeferredFunction&) = delete;
DeferredFunction(const DeferredFunction&&) = delete;
void operator=(const DeferredFunction&) = delete;
void operator=(DeferredFunction&&) = delete;
private:
Function Callback;
};
template <class Function>
auto Defer(Function&& fct) noexcept
{
return DeferredFunction<std::decay_t<Function>>{ std::forward<Function>(fct) };
} }
inline bool IsValid(ByteBuffer buffer)
{
return buffer.Size > 0 && buffer.Data;
}
extern JULIET_API void Free(ByteBuffer& buffer);
} // namespace Juliet } // namespace Juliet

View File

@@ -0,0 +1,162 @@
#pragma once
#include <Core/Math/MathUtils.h>
#include <Core/Memory/Utils.h>
namespace Juliet
{
#define ConstString(str) { const_cast<char*>((str)), sizeof(str) - 1 }
#define CStr(str) ((str).Data)
#define InplaceString(name, size) \
char name##_[size]; \
MemSet(name##_, 0, sizeof(uint32)); \
String name = { name##_, 0 }
// Everything is Little Endian
enum class StringEncoding : uint8
{
Unknown = 0,
ASCII,
LATIN1,
UTF8,
UTF16,
UTF32,
UCS2,
UCS4,
};
// Represents a UTF-8 String.
// Not null terminated.
struct String
{
char* Data;
size_t Size;
};
struct StringBuffer : String
{
size_t Capacity;
};
constexpr uint32 kInvalidUTF8 = 0xFFFD;
inline size_t StringLength(String str)
{
return str.Size;
}
inline size_t StringLength(const char* str)
{
size_t length = 0;
if (str)
{
while (char ch = *str)
{
if ((ch & 0xC0) != 0x80)
{
++length;
}
++str;
}
}
return length;
}
inline bool IsValid(String str)
{
return str.Size > 0 && str.Data != nullptr && *str.Data;
}
inline String WrapString(const char* str)
{
String result = {};
result.Data = const_cast<char*>(str);
result.Size = StringLength(str);
return result;
}
inline String FindChar(String str, char c)
{
String result = str;
while (result.Size)
{
if (*result.Data != c)
{
++result.Data;
--result.Size;
}
else
{
return result;
}
}
return {};
}
inline bool ContainsChar(String str, char c)
{
return IsValid(FindChar(str, c));
}
// Return:
// - < 0 if str1 < str2
// - = 0 : Both strings are equals
// - > 0 if str1 > str2
inline int32 StringCompare(String str1, String str2)
{
size_t len1 = StringLength(str1);
size_t len2 = StringLength(str2);
size_t minLen = Min(len1, len2);
int32 result = MemCompare(CStr(str1), CStr(str2), minLen);
if (result == 0)
{
if (len1 > len2)
{
return 1;
}
if (len1 < len2)
{
return -1;
}
return 0;
}
return result;
}
JULIET_API uint32 StepUTF8(String& inStr);
JULIET_API String FindString(String strLeft, String strRight);
// Case insensitive compare. Supports ASCII only
// TODO: Support UNICODE
extern JULIET_API int8 StringCompareCaseInsensitive(String str1, String str2);
// Do not allocate anything, you must allocate your out buffer yourself
// TODO: Version taking arena that can allocate
// Do not take String type because we dont know the string encoding we are going from/to
// src and dst will be casted based on the encoding.
// size will correspond to the number of characters
// Will convert \0 character if present.
extern JULIET_API bool ConvertString(StringEncoding from, StringEncoding to, String src, StringBuffer& dst);
extern JULIET_API bool ConvertString(String from, String to, String src, StringBuffer& dst);
} // namespace Juliet
#ifdef UNIT_TEST
namespace Juliet::UnitTest
{
inline void TestFindChar()
{
String s1 = ConstString("");
String s2 = ConstString("abcdefabcdef");
String s3 = ConstString("11111111111111111111");
Assert(FindChar(s1, 'x').Data == nullptr);
Assert(FindChar(s2, 'y').Data == nullptr);
Assert(FindChar(s2, 'a').Data - s2.Data == 0);
Assert(FindChar(s2, 'd').Data - s2.Data == 3);
Assert(FindChar(s2, 'f').Data - s2.Data == 5);
Assert(FindChar(s3, '1').Data - s3.Data == 0);
}
} // namespace Juliet::UnitTest
#endif

View File

@@ -1,7 +1,11 @@
#pragma once #pragma once
#include <Core/Common/String.h>
namespace Juliet namespace Juliet
{ {
// Returns the path to the application directory // Returns the path to the application directory
extern JULIET_API char * GetBasePath(); extern JULIET_API String GetBasePath();
}
extern JULIET_API bool IsAbsolutePath(String path);
} // namespace Juliet

View File

@@ -0,0 +1,69 @@
#pragma once
#include <Core/Common/NonNullPtr.h>
#include <Core/Common/String.h>
#include <Juliet.h>
namespace Juliet
{
// Opaque type
struct IOStream;
struct IOStreamDataPayload
{
};
enum class IOStreamStatus : uint8
{
Ready,
Error,
EndOfFile,
NotReady,
ReadOnly,
WriteOnly
};
enum class IOStreamSeekPivot : uint8
{
Begin,
Current,
End,
Count
};
// IOStream can be opened on a file or memory, or anything else.
// Use the interface to make it transparent to the user.
struct IOStreamInterface
{
uint32 Version;
int64 (*Size)(NonNullPtr<IOStreamDataPayload> data);
int64 (*Seek)(NonNullPtr<IOStreamDataPayload> data, int64 offset, IOStreamSeekPivot pivot);
size_t (*Read)(NonNullPtr<IOStreamDataPayload> data, void* outBuffer, size_t size, NonNullPtr<IOStreamStatus> status);
size_t (*Write)(NonNullPtr<IOStreamDataPayload> data, ByteBuffer inBuffer, NonNullPtr<IOStreamStatus> status);
bool (*Flush)(NonNullPtr<IOStreamDataPayload> data, NonNullPtr<IOStreamStatus> status);
bool (*Close)(NonNullPtr<IOStreamDataPayload> data);
};
extern JULIET_API IOStream* IOFromFile(String filename, String mode);
// Let you use an interface to open any io. Is used internally by IOFromFile
extern JULIET_API IOStream* IOFromInterface(NonNullPtr<const IOStreamInterface> interface, NonNullPtr<IOStreamDataPayload> payload);
// Write formatted string into the stream.
extern JULIET_API size_t IOPrintf(NonNullPtr<IOStream> stream, _Printf_format_string_ const char* format, ...);
extern JULIET_API size_t IOWrite(NonNullPtr<IOStream> stream, ByteBuffer inBuffer);
extern JULIET_API size_t IORead(NonNullPtr<IOStream> stream, void* ptr, size_t size);
extern JULIET_API int64 IOSeek(NonNullPtr<IOStream> stream, int64 offset, IOStreamSeekPivot pivot);
extern JULIET_API int64 IOSize(NonNullPtr<IOStream> stream);
// TODO : Use memory arena because that Allocates
extern JULIET_API ByteBuffer LoadFile(String filename);
extern JULIET_API ByteBuffer LoadFile(NonNullPtr<IOStream> stream, bool closeStreamWhenDone);
extern JULIET_API bool IOClose(NonNullPtr<IOStream> stream);
} // namespace Juliet

View File

@@ -20,8 +20,8 @@ namespace Juliet
uint16 Raw; uint16 Raw;
}; };
extern bool IsKeyDown(ScanCode scanCode); extern JULIET_API bool IsKeyDown(ScanCode scanCode);
extern KeyMod GetKeyModState(); extern JULIET_API KeyMod GetKeyModState();
extern KeyCode GetKeyCodeFromScanCode(ScanCode scanCode, KeyMod keyModState); extern JULIET_API KeyCode GetKeyCodeFromScanCode(ScanCode scanCode, KeyMod keyModState);
} // namespace Juliet } // namespace Juliet

View File

@@ -1,5 +1,7 @@
#pragma once #pragma once
#include <Core/Common/String.h>
namespace Juliet namespace Juliet
{ {
// Fwd Declare // Fwd Declare
@@ -7,9 +9,9 @@ namespace Juliet
struct HotReloadCode struct HotReloadCode
{ {
StringBuffer<char> DLLFullPath; String DLLFullPath;
StringBuffer<char> LockFullPath; String LockFullPath;
StringBuffer<const char> TransientDLLName; String TransientDLLName;
uint64 LastWriteTime; uint64 LastWriteTime;
@@ -24,8 +26,8 @@ namespace Juliet
bool IsValid : 1; bool IsValid : 1;
}; };
extern JULIET_API void InitHotReloadCode(HotReloadCode& code, StringBuffer<const char> dllName, extern JULIET_API void InitHotReloadCode(HotReloadCode& code, String dllName,
StringBuffer<const char> transientDllName, StringBuffer<const char> lockFilename); String transientDllName, String lockFilename);
extern JULIET_API void ShutdownHotReloadCode(HotReloadCode& code); extern JULIET_API void ShutdownHotReloadCode(HotReloadCode& code);
extern JULIET_API void LoadCode(HotReloadCode& code); extern JULIET_API void LoadCode(HotReloadCode& code);

View File

@@ -35,7 +35,7 @@ namespace Juliet
std::deque<Entry> Entries; std::deque<Entry> Entries;
bool IsInitialized : 1; bool IsInitialized : 1;
friend void Log(LogLevel level, LogCategory category, const char* fmt, ...); friend void Log(LogLevel level, LogCategory category, const char* fmt, va_list args);
void AddEntry(Entry&& entry); void AddEntry(Entry&& entry);
static void OutputLog(Entry& entry); static void OutputLog(Entry& entry);
}; };
@@ -43,4 +43,7 @@ namespace Juliet
extern void JULIET_API InitializeLogManager(); extern void JULIET_API InitializeLogManager();
extern void JULIET_API ShutdownLogManager(); extern void JULIET_API ShutdownLogManager();
extern void JULIET_API Log(LogLevel level, LogCategory category, const char* fmt, ...); extern void JULIET_API Log(LogLevel level, LogCategory category, const char* fmt, ...);
extern void JULIET_API LogMessage(LogCategory category, const char* fmt, ...);
extern void JULIET_API LogWarning(LogCategory category, const char* fmt, ...);
extern void JULIET_API LogError(LogCategory category, const char* fmt, ...);
} // namespace Juliet } // namespace Juliet

View File

@@ -15,7 +15,7 @@ namespace Juliet
Graphics = 1, Graphics = 1,
Networking = 2, Networking = 2,
Engine = 3, Engine = 3,
Editor = 4, Tool = 4,
Game = 5, Game = 5,
}; };
} // namespace Juliet } // namespace Juliet

View File

@@ -0,0 +1,40 @@
#pragma once
#include <Core/Common/CoreTypes.h>
#include <Juliet.h>
namespace Juliet
{
extern JULIET_API float RoundF(float value);
inline int32 LRoundF(float value)
{
return RoundF(value);
}
template <typename Type>
constexpr Type Min(Type lhs, Type rhs)
{
return rhs < lhs ? rhs : lhs;
}
template <typename Type>
constexpr Type Max(Type lhs, Type rhs)
{
return lhs < rhs ? rhs : lhs;
}
template <typename Type>
constexpr Type Clamp(Type val, Type min, Type max)
{
if (val < min)
{
return min;
}
if (val > max)
{
return max;
}
return val;
}
} // namespace Juliet

View File

@@ -1,6 +1,8 @@
#pragma once #pragma once
#include <memory> #include <Juliet.h>
#include <cstdlib>
namespace Juliet namespace Juliet
{ {
@@ -15,7 +17,7 @@ namespace Juliet
void Free(Type* memory) void Free(Type* memory)
{ {
Assert(memory); Assert(memory);
free(memory); ::free(memory);
} }
// Free and Set the ptr to nullptr // Free and Set the ptr to nullptr
template <typename Type> template <typename Type>
@@ -23,7 +25,7 @@ namespace Juliet
{ {
if (memory) if (memory)
{ {
free(memory); ::free(memory);
memory = nullptr; memory = nullptr;
} }
} }

View File

@@ -1,3 +1,25 @@
#pragma once #pragma once
#include <Core/Common/CoreTypes.h>
#define ArraySize(array) (sizeof(array) / sizeof(array[0])) #define ArraySize(array) (sizeof(array) / sizeof(array[0]))
namespace Juliet
{
inline int32 MemCompare(const void* leftValue, const void* rightValue, size_t size)
{
auto left = static_cast<const unsigned char*>(leftValue);
auto right = static_cast<const unsigned char*>(rightValue);
while (size && *left == *right)
{
++left;
++right;
--size;
}
return size ? *left - *right : 0;
}
// TODO: homemade versions
#define MemSet memset
#define MemCopy memcpy
} // namespace Juliet

View File

@@ -21,7 +21,7 @@ namespace Juliet
// Pack // Pack
NetworkPacket& operator<<(uint32 value); NetworkPacket& operator<<(uint32 value);
NetworkPacket& operator<<(const char* data); NetworkPacket& operator<<(char* data);
protected: protected:
void Append(ByteBuffer buffer); void Append(ByteBuffer buffer);

View File

@@ -1,12 +1,19 @@
#pragma once #pragma once
#include <Core/Common/NonNullPtr.h> #include <Core/Common/NonNullPtr.h>
#include <Core/Common/String.h>
#include <Core/HAL/Display/Display.h> #include <Core/HAL/Display/Display.h>
#include <Core/Math/Shape.h> #include <Core/Math/Shape.h>
#include <Graphics/GraphicsConfig.h> #include <Graphics/GraphicsConfig.h>
#include <Graphics/GraphicsPipeline.h>
#include <Graphics/RenderPass.h> #include <Graphics/RenderPass.h>
#include <Graphics/Shader.h>
#include <Juliet.h> #include <Juliet.h>
#ifdef JULIET_DEBUG
#define ALLOW_SHADER_HOT_RELOAD 1
#endif
// Graphics Interface // Graphics Interface
namespace Juliet namespace Juliet
{ {
@@ -89,6 +96,10 @@ namespace Juliet
// SwapChain // SwapChain
extern JULIET_API bool AcquireSwapChainTexture(NonNullPtr<CommandList> commandList, NonNullPtr<Window> window, extern JULIET_API bool AcquireSwapChainTexture(NonNullPtr<CommandList> commandList, NonNullPtr<Window> window,
Texture** swapChainTexture); Texture** swapChainTexture);
extern JULIET_API bool WaitAndAcquireSwapChainTexture(NonNullPtr<CommandList> commandList,
NonNullPtr<Window> window, Texture** swapChainTexture);
extern JULIET_API bool WaitForSwapchain(NonNullPtr<GraphicsDevice> device, NonNullPtr<Window> window);
extern JULIET_API TextureFormat GetSwapChainTextureFormat(NonNullPtr<GraphicsDevice> device, NonNullPtr<Window> window);
// Command List // Command List
extern JULIET_API CommandList* AcquireCommandList(NonNullPtr<GraphicsDevice> device, QueueType queueType = QueueType::Graphics); extern JULIET_API CommandList* AcquireCommandList(NonNullPtr<GraphicsDevice> device, QueueType queueType = QueueType::Graphics);
@@ -104,4 +115,27 @@ namespace Juliet
extern JULIET_API void SetScissorRect(NonNullPtr<RenderPass> renderPass, const Rectangle& rectangle); extern JULIET_API void SetScissorRect(NonNullPtr<RenderPass> renderPass, const Rectangle& rectangle);
extern JULIET_API void SetBlendConstants(NonNullPtr<RenderPass> renderPass, FColor blendConstants); extern JULIET_API void SetBlendConstants(NonNullPtr<RenderPass> renderPass, FColor blendConstants);
extern JULIET_API void SetStencilReference(NonNullPtr<RenderPass> renderPass, uint8 reference); extern JULIET_API void SetStencilReference(NonNullPtr<RenderPass> renderPass, uint8 reference);
extern JULIET_API void BindGraphicsPipeline(NonNullPtr<RenderPass> renderPass, NonNullPtr<GraphicsPipeline> graphicsPipeline);
extern JULIET_API void DrawPrimitives(NonNullPtr<RenderPass> renderPass, uint32 numVertices, uint32 numInstances,
uint32 firstVertex, uint32 firstInstance);
// Fences
extern JULIET_API bool WaitUntilGPUIsIdle(NonNullPtr<GraphicsDevice> device);
// Shaders
extern JULIET_API Shader* CreateShader(NonNullPtr<GraphicsDevice> device, String filename, ShaderCreateInfo& shaderCreateInfo);
extern JULIET_API void DestroyShader(NonNullPtr<GraphicsDevice> device, NonNullPtr<Shader> shader);
// Pipelines
extern JULIET_API GraphicsPipeline* CreateGraphicsPipeline(NonNullPtr<GraphicsDevice> device,
const GraphicsPipelineCreateInfo& createInfo);
extern JULIET_API void DestroyGraphicsPipeline(NonNullPtr<GraphicsDevice> device, NonNullPtr<GraphicsPipeline> graphicsPipeline);
#if ALLOW_SHADER_HOT_RELOAD
// Allows updating the graphics pipeline shaders. Can update either one or both shaders.
extern JULIET_API bool UpdateGraphicsPipelineShaders(NonNullPtr<GraphicsDevice> device, NonNullPtr<GraphicsPipeline> graphicsPipeline,
Shader* optional_vertexShader, Shader* optional_fragmentShader);
#endif
} // namespace Juliet } // namespace Juliet

View File

@@ -11,5 +11,6 @@ namespace Juliet
struct GraphicsConfig struct GraphicsConfig
{ {
DriverType PreferredDriver = DriverType::DX12; DriverType PreferredDriver = DriverType::DX12;
bool EnableDebug;
}; };
} // namespace Juliet } // namespace Juliet

View File

@@ -0,0 +1,225 @@
#pragma once
#include <Graphics/Shader.h>
#include <Graphics/Texture.h>
namespace Juliet
{
// Forward Declare
struct ColorTargetDescription;
enum class FillMode : uint8
{
Solid,
Wireframe,
Count
};
enum class CullMode : uint8
{
None,
Front,
Back,
Count
};
enum class FrontFace : uint8
{
CounterClockwise,
Clockwise,
Count
};
enum class PrimitiveType : uint8
{
TriangleList,
TriangleStrip,
LineList,
LineStrip,
PointList,
Count
};
struct RasterizerState
{
FillMode FillMode;
CullMode CullMode;
FrontFace FrontFace;
float DepthBiasConstantFactor; // How much depth value is added to each fragment
float DepthBiasClamp; // Maximum depth bias
float DepthBiasSlopeFactor; // Scalar applied to Fragment's slope
bool EnableDepthBias; // Bias fragment depth values
bool EnableDepthClip; // True to clip, false to clamp
};
enum class VertexInputRate : uint8
{
Vertex, // Use vertex index
Instance, // Use instance index
Count
};
struct VertexBufferDescription
{
uint32 Slot; // Binding Slot
uint32 PitchInBytes; // Pitch between two elements
VertexInputRate InputRate;
uint32 InstanceStepRate; // Only used when input rate == Instance. Number of instances to draw before advancing in the instance buffer by 1
};
enum class VertexElementFormat : uint8
{
Invalid,
/* 32-bit Signed Integers */
Int,
Int2,
Int3,
Int4,
/* 32-bit Unsigned Integers */
UInt,
UInt2,
UInt3,
UInt4,
/* 32-bit Floats */
Float,
Float2,
Float3,
Float4,
/* 8-bit Signed Integers */
Byte2,
Byte4,
/* 8-bit Unsigned Integers */
UByte2,
UByte4,
/* 8-bit Signed Normalized */
Byte2_Norm,
Byte4_Norm,
/* 8-bit Unsigned Normalized */
UByte2_Norm,
UByte4_Norm,
/* 16-bit Signed Integers */
Short2,
Short4,
/* 16-bit Unsigned Integers */
UShort2,
UShort4,
/* 16-bit Signed Normalized */
Short2_Norm,
Short4_Norm,
/* 16-bit Unsigned Normalized */
UShort2_Norm,
UShort4_Norm,
/* 16-bit Floats */
Half2,
Half4,
//
Count
};
struct VertexAttribute
{
uint32 Location; // Shader input location index
uint32 BufferSlot; // Binding slot of associated vertex buffer
VertexElementFormat Format; // Size and type of attribute
uint32 Offset; // Offset of this attribute relative to the start of the vertex element
};
struct VertexInputState
{
const VertexBufferDescription* VertexBufferDescriptions;
uint32 NumVertexBufferDescriptions;
const VertexAttribute* VertexAttributes;
uint32 NumVertexAttributes;
};
struct GraphicsPipelineTargetInfo
{
const ColorTargetDescription* ColorTargetDescriptions;
size_t NumColorTargets;
TextureFormat DepthStencilFormat;
bool HasDepthStencilTarget;
};
enum class CompareOperation : uint8
{
Invalid,
Never, // The comparison always evaluates false.
Less, // The comparison evaluates reference < test.
Equal, // The comparison evaluates reference == test.
LessOrEqual, // The comparison evaluates reference <= test.
Greater, // The comparison evaluates reference > test.
NotEqual, // The comparison evaluates reference != test.
GreaterOrEqual, // The comparison evalutes reference >= test.
Always, // The comparison always evaluates true.
Count
};
enum class StencilOperation : uint8
{
Invalid,
Keep, // Keeps the current value.
Zero, // Sets the value to 0.
Replace, // Sets the value to reference.
IncrementAndClamp, // Increments the current value and clamps to the maximum value.
DecrementAndClamp, // Decrements the current value and clamps to 0.
Invert, // Bitwise-inverts the current value.
IncrementAndWrap, // Increments the current value and wraps back to 0.
DecrementAndWrap, // Decrements the current value and wraps to the maximum value.
Count
};
struct StencilOperationState
{
StencilOperation FailOperation; // The action performed on samples that fail the stencil test.
StencilOperation PassOperation; // The action performed on samples that pass the depth and stencil tests.
StencilOperation DepthFailOperation; // The action performed on samples that pass the stencil test and fail the depth test.
StencilOperation CompareOperation; // The comparison operator used in the stencil test.
};
struct DepthStencilState
{
CompareOperation CompareOperation; // The comparison operator used for depth testing.
StencilOperationState BackStencilState; // The stencil op state for back-facing triangles.
StencilOperationState FrontStencilState; // The stencil op state for front-facing triangles.
uint8 CompareMask; // Selects the bits of the stencil values participating in the stencil test.
uint8 WriteMask; // Selects the bits of the stencil values updated by the stencil test.
bool EnableDepthTest : 1; // true enables the depth test.
bool EnableDepthWrite : 1; // true enables depth writes. Depth writes are always disabled when enable_depth_test is false.
bool EnableStencilTest : 1; // true enables the stencil test.
};
struct MultisampleState
{
TextureSampleCount SampleCount;
uint32 SampleMask; // Which sample should be updated. If Enabled mask == false -> 0xFFFFFFFF
bool EnableMask;
};
struct GraphicsPipelineCreateInfo
{
Shader* VertexShader;
Shader* FragmentShader;
PrimitiveType PrimitiveType;
GraphicsPipelineTargetInfo TargetInfo;
RasterizerState RasterizerState;
MultisampleState MultisampleState;
VertexInputState VertexInputState;
DepthStencilState DepthStencilState;
};
// Opaque type
struct GraphicsPipeline;
} // namespace Juliet

View File

@@ -41,6 +41,63 @@ namespace Juliet
StoreOperation StoreOperation; StoreOperation StoreOperation;
}; };
enum class BlendFactor : uint8
{
Invalid,
Zero,
One,
Src_Color,
One_Minus_Src_Color,
Dst_Color,
One_Minus_Dst_Color,
Src_Alpha,
One_Minus_Src_Alpha,
Dst_Alpha,
One_Minus_Dst_Alpha,
Constant_Color,
One_MINUS_Constant_Color,
Src_Alpha_Saturate, // min(source alpha, 1 - destination alpha)
Count
};
enum class BlendOperation : uint8
{
Invalid,
Add, // (source * source_factor) + (destination * destination_factor)
Subtract, // (source * source_factor) - (destination * destination_factor)
ReverseSubtract, // (destination * destination_factor) - (source * source_factor)
Min, // min(source, destination)
Max, // max(source, destination)
Count
};
enum class ColorComponentFlags : uint8
{
R = 1u << 0,
G = 1u << 1,
B = 1u << 2,
A = 1u << 3
};
struct ColorTargetBlendState
{
BlendFactor SourceColorBlendFactor; // The value to be multiplied by the source RGB value.
BlendFactor DestinationColorBlendFactor; // The value to be multiplied by the destination RGB value.
BlendOperation ColorBlendOperation; // The blend operation for the RGB components.
BlendFactor SourceAlphaBlendFactor; // The value to be multiplied by the source alpha.
BlendFactor DestinationAlphaBlendFactor; // The value to be multiplied by the destination alpha.
BlendOperation AlphaBlendOperation; // The blend operation for the alpha component.
ColorComponentFlags ColorWriteMask; // A bitmask specifying which of the RGBA components are enabled for writing. Writes to all channels if enable_color_write_mask is false.
bool EnableBlend : 1; // Whether blending is enabled for the color target.
bool EnableColorWriteMask : 1; // Whether the color write mask is enabled.
};
struct ColorTargetDescription
{
TextureFormat Format;
ColorTargetBlendState BlendState;
};
// Opaque Type // Opaque Type
struct RenderPass; struct RenderPass;
} // namespace Juliet } // namespace Juliet

View File

@@ -0,0 +1,23 @@
#pragma once
#include <Core/Common/String.h>
namespace Juliet
{
// Opaque type
struct Shader;
enum class ShaderStage : uint8
{
Vertex,
Fragment,
Compute
};
struct ShaderCreateInfo
{
ShaderStage Stage;
String EntryPoint;
};
} // namespace Juliet

View File

@@ -124,7 +124,9 @@ namespace Juliet
ASTC_10x8_FLOAT, ASTC_10x8_FLOAT,
ASTC_10x10_FLOAT, ASTC_10x10_FLOAT,
ASTC_12x10_FLOAT, ASTC_12x10_FLOAT,
ASTC_12x12_FLOAT ASTC_12x12_FLOAT,
Count
}; };
enum struct TextureUsageFlag : uint8 enum struct TextureUsageFlag : uint8

View File

@@ -1,10 +1,21 @@
#include <pch.h> #include <pch.h>
#include <Core/Memory/Allocator.h>
namespace Juliet namespace Juliet
{ {
void JulietAssert(const char* expression) void JulietAssert(const char* expression)
{ {
Juliet::Log(Juliet::LogLevel::Error, Juliet::LogCategory::Core, expression); Log(LogLevel::Error, LogCategory::Core, expression);
__debugbreak(); __debugbreak();
} }
void Free(ByteBuffer& buffer)
{
if (buffer.Data)
{
Free(buffer.Data);
}
buffer = {};
}
} // namespace Juliet } // namespace Juliet

View File

@@ -0,0 +1,461 @@
#include <pch.h>
#include <Core/Common/String.h>
#include <Core/Memory/Utils.h>
namespace Juliet
{
namespace
{
constexpr int32 kUnknown_UNICODE = 0xFFFD;
struct
{
String Name;
StringEncoding Format;
} Encodings[] = {
/* *INDENT-OFF* */ // clang-format off
{ ConstString("ASCII"), StringEncoding::ASCII },
{ ConstString("US-ASCII"), StringEncoding::ASCII },
{ ConstString("8859-1"), StringEncoding::LATIN1 },
{ ConstString("ISO-8859-1"), StringEncoding::LATIN1 },
#if defined(JULIET_WIN32)
{ ConstString("WCHAR_T"), StringEncoding::UTF16 },
#else
{ ConstString("WCHAR_T"), StringEncoding::UCS4 },
#endif
{ ConstString("UTF8"), StringEncoding::UTF8 },
{ ConstString("UTF-8"), StringEncoding::UTF8 },
{ ConstString("UTF16"), StringEncoding::UTF16 },
{ ConstString("UTF-16"), StringEncoding::UTF16 },
{ ConstString("UTF32"), StringEncoding::UTF32 },
{ ConstString("UTF-32"), StringEncoding::UTF32 },
{ ConstString("UCS2"), StringEncoding::UCS2 },
{ ConstString("UCS-2"), StringEncoding::UCS2 },
{ ConstString("UCS-2-INTERNAL"), StringEncoding::UCS2 },
{ ConstString("UCS4"), StringEncoding::UCS4 },
{ ConstString("UCS-4"), StringEncoding::UCS4 },
{ ConstString("UCS-4-INTERNAL"), StringEncoding::UCS4 },
/* *INDENT-ON* */ // clang-format on
};
// Returns the number of codepoint case folded (lowercase equivalent in the language)
// Takes an UTF-8 codepoint (uint32) and codefold it to up to 3 uint32
// TODO Supports more than low ASCI :)
int8 CaseFoldUnicode(uint32 from, uint32* to)
{
if (from < 128)
{
// low-ASCII, easy!
if ((from >= 'A') && (from <= 'Z'))
{
*to = 'a' + (from - 'A');
return 1;
}
}
*to = from;
return 1;
}
} // namespace
uint32 StepUTF8(String& inStr)
{
// From rfc3629, the UTF-8 spec:
// https://www.ietf.org/rfc/rfc3629.txt
//
// Char. number range | UTF-8 octet sequence
// (hexadecimal) | (binary)
// --------------------+---------------------------------------------
// 0000 0000-0000 007F | 0xxxxxxx
// 0000 0080-0000 07FF | 110xxxxx 10xxxxxx
// 0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
// 0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
//
// The function checks character validity and overlong (using too many bytes to encode the character) and return invalid utf8 char if detected.
// If string is empty then it's done.
if (inStr.Size == 0)
{
return 0;
}
auto str = reinterpret_cast<const uint8*>(CStr(inStr));
const uint32 octet = *str;
bool isOverlong = false;
bool isInvalid = false;
bool isUTF16Surrogate = false;
if (octet == 0)
{
return 0;
}
if ((octet & 0x80) == 0x0) // One byte code point: 0xxxxxxx
{
inStr.Data += 1;
inStr.Size -= 1;
return octet;
}
else if ((octet & 0xE0) == 0xC0) // Two bytes code point: 110xxxxx 10xxxxxx
{
const uint8 secondByte = str[1];
if ((secondByte & 0xC0) == 0x80) // Make sure the trailing byte is correct
{
const uint32 result = ((octet & 0x1F) << 6) | (secondByte & 0x3F);
if (result >= 0x80) // If the result is smaller than 0x80 its an overlong!
{
inStr.Data += 2;
inStr.Size -= 1;
return result;
}
else
{
isOverlong = true;
}
}
else
{
isInvalid = true;
}
}
else if (((octet & 0xF0) == 0xE0)) // Three bytes code point: 1110xxxx 10xxxxxx 10xxxxxx
{
const uint8 secondByte = str[1];
const uint8 thirdByte = str[2];
if (((secondByte & 0xC0) == 0x80) && ((thirdByte & 0xC0) == 0x80)) // Make sure the trailing bytes are correct
{
const uint32 secondOctet = static_cast<uint32>(secondByte & 0x3F) << 6;
const uint32 thirdOctet = static_cast<uint32>(thirdByte & 0x3F);
const uint32 result = ((octet & 0x0F) << 12) | secondOctet | thirdOctet;
if (result >= 0x0800) // if the result is smaller its an overlong.
{
if ((result < 0xD800) || (result > 0xDFFF)) // If out of range its an UTF-16 surrogate
{
inStr.Data += 3;
inStr.Size -= 1;
return result;
}
else
{
isUTF16Surrogate = true;
}
}
else
{
isOverlong = true;
}
}
else
{
isInvalid = true;
}
}
else if (((octet & 0xF8) == 0xF0))
{ // Four bytes code point: 11110xxxx 10xxxxxx 10xxxxxx 10xxxxxx
const uint8 secondByte = str[1];
const uint8 thirdByte = str[2];
const uint8 fourthByte = str[3];
if (((secondByte & 0xC0) == 0x80) && ((thirdByte & 0xC0) == 0x80) &&
((fourthByte & 0xC0) == 0x80)) // // Make sure the trailing bytes are correct
{
const uint32 secondOctet = static_cast<uint32>(secondByte & 0x1F) << 12;
const uint32 thirdOctet = static_cast<uint32>(thirdByte & 0x3F) << 6;
const uint32 fourthOctet = static_cast<uint32>(fourthByte & 0x3F);
const uint32 result = ((octet & 0x07) << 18) | secondOctet | thirdOctet | fourthOctet;
if (result >= 0x10000) // If smaller its an overlong
{
inStr.Data += 4;
inStr.Size -= 1;
return result;
}
else
{
isOverlong = true;
}
}
else
{
isInvalid = true;
}
}
LogError(LogCategory::Core, "StepUTF8: Non supported codepoint. IsOverlong: %s. IsInvalid %s. IsUTF16Surrogate %s",
isOverlong ? "true" : "false", isInvalid ? "true" : "false", isUTF16Surrogate ? "true" : "false");
inStr.Data += 1;
return kInvalidUTF8;
}
String FindString(String haystack, String needle)
{
if (!IsValid(needle))
{
return haystack;
}
for (; IsValid(haystack); StepUTF8(haystack))
{
String tempHaystack = haystack;
String testNeedle = needle;
while (IsValid(tempHaystack) && IsValid(testNeedle))
{
uint32 codepointHaystack = StepUTF8(tempHaystack);
uint32 codepointNeedle = StepUTF8(testNeedle);
if (codepointHaystack != codepointNeedle)
{
break;
}
}
if (!IsValid(testNeedle))
{
return haystack;
}
}
return {};
}
int8 StringCompareCaseInsensitive(String str1, String str2)
{
// TODO: Support UTF8. For now ASCII only.
uint32 left = 0;
uint32 right = 0;
while (true)
{
{
uint32 leftFolded[3];
int8 num_folded = CaseFoldUnicode(StepUTF8(str1), leftFolded);
Assert(num_folded == 1); // Only one uint32 codepoint supported for now (low ascii)
left = leftFolded[0];
}
{
uint32 rightFolded[3];
int8 num_folded = CaseFoldUnicode(StepUTF8(str2), rightFolded);
Assert(num_folded == 1); // Only one uint32 codepoint supported for now (low ascii)
right = rightFolded[0];
}
if (left < right)
{
return -1;
}
if (left > right)
{
return 1;
}
if (left == 0)
{
break;
}
}
return 0;
}
bool ConvertString(StringEncoding from, StringEncoding to, String src, StringBuffer& dst)
{
Assert(IsValid(src));
const char* srcStr = src.Data;
char* dstStr = dst.Data;
size_t remainingCapacity = dst.Capacity;
uint32 character = 0;
while (src.Size > 0)
{
// Decode in character
switch (from)
{
case StringEncoding::UTF8: // Uses RFC 3629
{
auto p = reinterpret_cast<const uint8*>(srcStr);
size_t left = 0;
bool overlong = false;
if (p[0] >= 0xF0)
{
if ((p[0] & 0xF8) != 0xF0)
{
character = kUnknown_UNICODE;
}
else
{
if (p[0] == 0xF0 && src.Size > 1 && (p[1] & 0xF0) == 0x80)
{
overlong = true;
}
character = static_cast<uint32>(p[0] & 0x07);
left = 3;
}
}
else if (p[0] >= 0xE0)
{
if ((p[0] & 0xF0) != 0xE0)
{
character = kUnknown_UNICODE;
}
else
{
if (p[0] == 0xE0 && src.Size > 1 && (p[1] & 0xE0) == 0x80)
{
overlong = true;
}
character = static_cast<uint32>(p[0] & 0x0F);
left = 2;
}
}
else if (p[0] >= 0xC0)
{
if ((p[0] & 0xE0) != 0xC0)
{
character = kUnknown_UNICODE;
}
else
{
if ((p[0] & 0xDE) == 0xC0)
{
overlong = true;
}
character = static_cast<uint32>(p[0] & 0x1F);
left = 1;
}
}
else
{
if (p[0] & 0x80)
{
character = kUnknown_UNICODE;
}
else
{
character = static_cast<uint32>(p[0]);
}
}
++srcStr;
--src.Size;
if (src.Size < left)
{
Log(LogLevel::Error, LogCategory::Core, "ConvertString: Failed to convert string. Incomplete input sequence");
return false;
}
while (left--)
{
++p;
if ((p[0] & 0xC0) != 0x80)
{
character = kUnknown_UNICODE;
break;
}
character <<= 6;
character |= (p[0] & 0x3F);
++srcStr;
--src.Size;
}
if (overlong)
{
character = kUnknown_UNICODE;
}
if ((character >= 0xD800 && character <= 0xDFFF) || (character == 0xFFFE || character == 0xFFFF) ||
character > 0x10FFFF)
{
character = kUnknown_UNICODE;
}
break;
}
case StringEncoding::Unknown: Assert(false && "ConvertString: Invalid Source Format: Unknown"); break;
case StringEncoding::ASCII:
case StringEncoding::LATIN1:
case StringEncoding::UTF16:
case StringEncoding::UTF32:
case StringEncoding::UCS2:
case StringEncoding::UCS4: Assert(false && "ConvertString: Unsupported Source Format"); break;
}
// Encode out character
switch (to)
{
case StringEncoding::UTF16: // RFC 2781
{
auto p = reinterpret_cast<uint8*>(dstStr);
if (character > 0x10FFFF)
{
character = kUnknown_UNICODE;
}
if (character < 0x10000)
{
if (remainingCapacity < 2)
{
Log(LogLevel::Error, LogCategory::Core, "ConvertString: Destination buffer too short to fit UTF16");
return false;
}
p[1] = static_cast<uint8>(character >> 8);
p[0] = static_cast<uint8>(character);
dstStr += 2;
dst.Size += 1;
remainingCapacity -= 2;
}
else
{
if (remainingCapacity < 4)
{
Log(LogLevel::Error, LogCategory::Core, "ConvertString: Destination buffer too short to fit UTF16");
return false;
}
character = character - 0x10000;
uint16 word1 = 0xD800 | static_cast<uint16>((character >> 10) & 0x3FF);
uint16 word2 = 0xDC00 | static_cast<uint16>(character & 0x3FF);
p[1] = static_cast<uint8>(word1 >> 8);
p[0] = static_cast<uint8>(word1);
p[3] = static_cast<uint8>(word2 >> 8);
p[2] = static_cast<uint8>(word2);
dstStr += 4;
dst.Size += 1;
remainingCapacity -= 4;
}
break;
}
case StringEncoding::Unknown: Assert(false && "ConvertString: Invalid Source Format: Unknown"); break;
case StringEncoding::ASCII:
case StringEncoding::LATIN1:
case StringEncoding::UTF8:
case StringEncoding::UTF32:
case StringEncoding::UCS2:
case StringEncoding::UCS4: Assert(false && "ConvertString: Unsupported Destination Format"); break;
}
}
return true;
}
bool ConvertString(String from, String to, String src, StringBuffer& dst)
{
Assert(IsValid(from));
Assert(IsValid(to));
// First find the encoding of the strings
auto sourceFormat = StringEncoding::Unknown;
auto destFormat = StringEncoding::Unknown;
for (auto& encoding : Encodings)
{
if (StringCompareCaseInsensitive(from, encoding.Name) == 0)
{
sourceFormat = encoding.Format;
if (destFormat != StringEncoding::Unknown)
{
break;
}
}
if (StringCompareCaseInsensitive(to, encoding.Name) == 0)
{
destFormat = encoding.Format;
if (sourceFormat != StringEncoding::Unknown)
{
break;
}
}
}
if (sourceFormat == StringEncoding::Unknown || destFormat == StringEncoding::Unknown)
{
return false;
}
return ConvertString(sourceFormat, destFormat, src, dst);
}
} // namespace Juliet

View File

@@ -134,10 +134,10 @@ namespace Juliet::Win32
{ {
uint8 peekedMessageCount = 0; uint8 peekedMessageCount = 0;
MSG message = {}; MSG message = {};
while (PeekMessage(&message, nullptr, 0, 0, PM_REMOVE)) while (PeekMessageA(&message, nullptr, 0, 0, PM_REMOVE))
{ {
TranslateMessage(&message); TranslateMessage(&message);
DispatchMessage(&message); DispatchMessageA(&message);
// Since we peek at all messages of the program, it's possible that it stall here so we limit the number of peeked messages to an arbitrary limit // Since we peek at all messages of the program, it's possible that it stall here so we limit the number of peeked messages to an arbitrary limit
if (++peekedMessageCount > kPeekMessageLimit) if (++peekedMessageCount > kPeekMessageLimit)
@@ -155,7 +155,7 @@ namespace Juliet::Win32
auto* windowState = GetWindowStateFromHandle(handle); auto* windowState = GetWindowStateFromHandle(handle);
if (!windowState) if (!windowState)
{ {
return CallWindowProc(DefWindowProc, handle, message, wParam, lParam); return CallWindowProcA(DefWindowProcA, handle, message, wParam, lParam);
} }
switch (message) switch (message)
@@ -267,6 +267,6 @@ namespace Juliet::Win32
return returnCode; return returnCode;
} }
return CallWindowProc(DefWindowProc, handle, message, wParam, lParam); return CallWindowProcA(DefWindowProcA, handle, message, wParam, lParam);
} }
} // namespace Juliet::Win32 } // namespace Juliet::Win32

View File

@@ -9,8 +9,8 @@ namespace Juliet::Win32
{ {
namespace namespace
{ {
constexpr auto WindowClassName = L"JulietWindowClass"; constexpr auto WindowClassName = "JulietWindowClass";
constexpr LPCWSTR WindowClassPtr = WindowClassName; constexpr LPCSTR WindowClassPtr = WindowClassName;
bool SetupWindowState(NonNullPtr<DisplayDevice> self, NonNullPtr<Window> window, HWND handle) bool SetupWindowState(NonNullPtr<DisplayDevice> self, NonNullPtr<Window> window, HWND handle)
{ {
@@ -46,7 +46,7 @@ namespace Juliet::Win32
HINSTANCE instance = GetModuleHandle(nullptr); HINSTANCE instance = GetModuleHandle(nullptr);
// TODO : Put outside, we should not create a new class for each new window // TODO : Put outside, we should not create a new class for each new window
WNDCLASSEX WindowClass = {}; WNDCLASSEXA WindowClass = {};
WindowClass.cbSize = sizeof(WNDCLASSEX); WindowClass.cbSize = sizeof(WNDCLASSEX);
WindowClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; WindowClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
WindowClass.lpfnWndProc = Win32MainWindowCallback; WindowClass.lpfnWndProc = Win32MainWindowCallback;
@@ -54,7 +54,7 @@ namespace Juliet::Win32
WindowClass.hCursor = LoadCursor(0, IDC_ARROW); WindowClass.hCursor = LoadCursor(0, IDC_ARROW);
WindowClass.hbrBackground = static_cast<HBRUSH>(GetStockObject(LTGRAY_BRUSH)); WindowClass.hbrBackground = static_cast<HBRUSH>(GetStockObject(LTGRAY_BRUSH));
WindowClass.lpszClassName = WindowClassName; WindowClass.lpszClassName = WindowClassName;
if (!RegisterClassEx(&WindowClass)) if (!RegisterClassExA(&WindowClass))
{ {
return false; return false;
} }
@@ -64,8 +64,8 @@ namespace Juliet::Win32
int x = CW_USEDEFAULT, y = CW_USEDEFAULT; int x = CW_USEDEFAULT, y = CW_USEDEFAULT;
const int w = window->Width, h = window->Height; const int w = window->Width, h = window->Height;
HWND handle = CreateWindowEx(styleEx, WindowClassPtr, L"JULIET TODO PASS TITLE", style, x, y, w, h, nullptr, HWND handle = CreateWindowExA(styleEx, WindowClassPtr, "JULIET TODO PASS TITLE", style, x, y, w, h, nullptr,
nullptr, instance, nullptr); nullptr, instance, nullptr);
PumpEvents(self); PumpEvents(self);
@@ -97,69 +97,4 @@ namespace Juliet::Win32
auto& win32State = reinterpret_cast<Window32State&>(*window->State); auto& win32State = reinterpret_cast<Window32State&>(*window->State);
::ShowWindow(win32State.Handle, SW_HIDE); ::ShowWindow(win32State.Handle, SW_HIDE);
} }
/*
namespace
{
LRESULT CALLBACK Win32MainWindowCallback(HWND Window, UINT Message, WPARAM WParam, LPARAM LParam);
}
void CreateOSWindow(WindowState& state, uint16 width, uint16 height)
{
auto& win32State = reinterpret_cast<Window32State&>(state);
HINSTANCE Instance = GetModuleHandle(0);
WNDCLASSA WindowClass = {};
WindowClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
WindowClass.lpfnWndProc = Win32MainWindowCallback;
WindowClass.hInstance = Instance;
WindowClass.hCursor = LoadCursor(0, IDC_ARROW);
WindowClass.hbrBackground = static_cast<HBRUSH>(GetStockObject(LTGRAY_BRUSH));
WindowClass.lpszClassName = WindowClassName;
if (RegisterClassA(&WindowClass))
{
HWND handle = CreateWindowExA(0, WindowClass.lpszClassName, "Juliet", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,
CW_USEDEFAULT, width, height, 0, 0, Instance, 0);
if (handle)
{
win32State.Handle = handle;
SetWindowLongPtr(win32State.Handle, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(&win32State));
ShowWindow(handle, SW_SHOW);
win32State.IsOpen = true;
}
else
{
Assert(false);
// Win32ErrorMessage(PlatformError_Fatal,
// "Unable to open game window.");
}
}
else
{
Assert(false);
// Win32ErrorMessage(PlatformError_Fatal,
// "Unable to register game window handle.");
}
}
void DestroyOSWindow(WindowState& state)
{
auto& win32State = reinterpret_cast<Window32State&>(state);
::DestroyWindow(win32State.Handle);
UnregisterClassA(WindowClassName, ::GetModuleHandle(nullptr));
}
void UpdateOSWindowState(WindowState& state)
{
auto& win32State = reinterpret_cast<Window32State&>(state);
MSG msg = {};
while (::PeekMessage(&msg, win32State.Handle, 0, 0, PM_REMOVE))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
}
*/
} // namespace Juliet::Win32 } // namespace Juliet::Win32

View File

@@ -5,38 +5,6 @@
namespace Juliet namespace Juliet
{ {
namespace
{
// TODO : Move into string file
// Use portable code + pass the memory array into parameter and not use new
// This is from http://www.rohitab.com/discuss/topic/41257-char-to-lpcwstr/
static wchar_t* UTF8ToWideChar(const char* utf8)
{
wchar_t* w;
int len = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, 0, 0);
if (len <= 0)
{
return nullptr;
}
w = new wchar_t[len];
if (!w)
{
return nullptr;
}
if (MultiByteToWideChar(CP_UTF8, 0, utf8, -1, w, len) <= 0)
{
delete[] w;
return nullptr;
}
return w;
}
} // namespace
DynamicLibrary* LoadDynamicLibrary(const char* filename) DynamicLibrary* LoadDynamicLibrary(const char* filename)
{ {
if (!filename) if (!filename)
@@ -45,9 +13,7 @@ namespace Juliet
return nullptr; return nullptr;
} }
LPWSTR wstr = UTF8ToWideChar(filename); HMODULE handle = LoadLibraryA(filename);
HMODULE handle = LoadLibraryW(wstr);
delete[] wstr;
// Generate an error message if all loads failed // Generate an error message if all loads failed
if (!handle) if (!handle)

View File

@@ -1,5 +1,6 @@
#include <pch.h> #include <pch.h>
#include <Core/Common/String.h>
#include <Core/HAL/Filesystem/Filesystem.h> #include <Core/HAL/Filesystem/Filesystem.h>
#include <Core/HAL/Filesystem/Filesystem_Platform.h> #include <Core/HAL/Filesystem/Filesystem_Platform.h>
#include <Core/HAL/Filesystem/Filesystem_Private.h> #include <Core/HAL/Filesystem/Filesystem_Private.h>
@@ -9,24 +10,35 @@ namespace Juliet
{ {
namespace namespace
{ {
char* CachedBasePath = nullptr; String CachedBasePath = {};
} }
char* GetBasePath()
String GetBasePath()
{ {
if (CachedBasePath == nullptr) if (!IsValid(CachedBasePath))
{ {
CachedBasePath = Platform::GetBasePath(); CachedBasePath = Platform::GetBasePath();
} }
return CachedBasePath; return CachedBasePath;
} }
bool IsAbsolutePath(String path)
{
if (!IsValid(path))
{
return false;
}
return Platform::IsAbsolutePath(path);
}
void InitFilesystem() {} void InitFilesystem() {}
void ShutdownFilesystem() void ShutdownFilesystem()
{ {
if (CachedBasePath != nullptr) if (IsValid(CachedBasePath))
{ {
SafeFree(CachedBasePath); CachedBasePath.Size = 0;
SafeFree(CachedBasePath.Data);
} }
} }
} // namespace Juliet } // namespace Juliet

View File

@@ -2,5 +2,6 @@
namespace Juliet::Platform namespace Juliet::Platform
{ {
extern char* GetBasePath(); extern String GetBasePath();
} extern bool IsAbsolutePath(String path);
} // namespace Juliet::Platform

View File

@@ -1,62 +1,33 @@
#include <pch.h> #include <pch.h>
#include <Core/Common/String.h>
#include <Core/HAL/Filesystem/Filesystem_Platform.h> #include <Core/HAL/Filesystem/Filesystem_Platform.h>
#include <Core/HAL/Win32.h> #include <Core/HAL/Win32.h>
#include <Core/Memory/Allocator.h> #include <Core/Memory/Allocator.h>
namespace Juliet::Platform namespace Juliet::Platform
{ {
namespace String GetBasePath()
{
// TODO : Move into string file
// Use portable code + pass the memory array into parameter and not use new
// From: https://stackoverflow.com/questions/215963/how-do-you-properly-use-widechartomultibyte
char* WideCharToUTF8(wchar_t* wcharStr)
{
char* result = nullptr;
size_t length = WideCharToMultiByte(CP_UTF8, 0, wcharStr, -1, nullptr, 0, nullptr, nullptr);
if (length <= 0)
{
return nullptr;
}
result = new char[length];
if (!result)
{
return nullptr;
}
if (WideCharToMultiByte(CP_UTF8, 0, wcharStr, -1, result, length, nullptr, nullptr) <= 0)
{
delete[] result;
return nullptr;
}
return result;
}
} // namespace
char* GetBasePath()
{ {
// Allocate a buffer that could fit the module size. // Allocate a buffer that could fit the module size.
// Max Path is a good start but could be bigger if the path include long path prefix // Max Path is a good start but could be bigger if the path include long path prefix
StringBuffer<WCHAR> buffer{ .Data = nullptr, .Size = MAX_PATH }; size_t bufferSize = MAX_PATH;
buffer.Data = static_cast<WCHAR*>(Calloc(MAX_PATH, sizeof(WCHAR))); auto buffer = static_cast<char*>(Calloc(MAX_PATH, sizeof(char)));
if (buffer.Data == nullptr) if (buffer == nullptr)
{ {
return nullptr; return {};
} }
size_t moduleFilenameLength = 0; size_t moduleFilenameLength = 0;
while (true) while (true)
{ {
moduleFilenameLength = GetModuleFileNameW(nullptr, buffer.Data, static_cast<uint32>(buffer.Size)); moduleFilenameLength = GetModuleFileNameA(nullptr, buffer, static_cast<uint32>(bufferSize));
// If the module filename length is bigger than the buffer size, we need to reallocate a bigger buffer // If the module filename length is bigger than the buffer size, we need to reallocate a bigger buffer
if (moduleFilenameLength >= buffer.Size - 1) if (moduleFilenameLength >= bufferSize - 1)
{ {
buffer.Size *= 2; bufferSize *= 2;
buffer.Data = static_cast<WCHAR*>(Realloc(buffer.Data, buffer.Size * sizeof(WCHAR))); buffer = static_cast<char*>(Realloc(buffer, bufferSize * sizeof(char)));
} }
else else
{ {
@@ -66,25 +37,58 @@ namespace Juliet::Platform
if (moduleFilenameLength == 0) if (moduleFilenameLength == 0)
{ {
SafeFree(buffer.Data); SafeFree(buffer);
Log(LogLevel::Error, LogCategory::Core, "Filesystem: Cannot locate executable path"); Log(LogLevel::Error, LogCategory::Core, "Filesystem: Cannot locate executable path");
} }
size_t idx = 0; size_t idx = 0;
for (idx = moduleFilenameLength - 1; idx > 0; --idx) for (idx = moduleFilenameLength - 1; idx > 0; --idx)
{ {
if (buffer.Data[idx] == '\\') if (buffer[idx] == '\\')
{ {
break; break;
} }
} }
Assert(idx > 0 && "Path is not absolute!"); Assert(idx > 0 && "Path is not absolute!");
buffer.Data[idx + 1] = '\0'; // Chop chop buffer[idx + 1] = '\0'; // Chop chop
// TODO: Add utils to Convert to/from UTF8W return WrapString(buffer);
char* basePath = WideCharToUTF8(buffer.Data); }
SafeFree(buffer.Data);
return basePath; bool IsAbsolutePath(String path)
{
if (path.Data || path.Size == 0)
{
return false;
}
// From https://learn.microsoft.com/en-ca/windows/win32/fileio/naming-a-file?redirectedfrom=MSDN#fully_qualified_vs._relative_paths
// Windows path starts with either:
// A UNC name of any format, which always start with two backslash characters ("\\"). For more information, see the next section.
// A disk designator with a backslash, for example "C:\" or "d:\".
// A single backslash, for example, "\directory" or "\file.txt". This is also referred to as an absolute path.
// We will only handle the first two. Single backslash is weird.
const char* pathStr = path.Data;
size_t pathLen = path.Size;
if (pathLen > 1)
{
if (pathStr[0] == '\\' && pathStr[1] == '\\')
{
return true;
}
if (pathLen > 2)
{
char first = pathStr[0];
char second = pathStr[1];
char third = pathStr[2];
return ((first >= 'a' && first <= 'z') || (first >= 'A' && first <= 'Z')) && second == ':' &&
(third == '\\' || third == '/');
}
}
return false;
} }
} // namespace Juliet::Platform } // namespace Juliet::Platform

View File

@@ -0,0 +1,230 @@
#include <pch.h>
#include <Core/Common/String.h>
#include <Core/HAL/IO/IOStream.h>
#include <Core/HAL/IO/IOStream_Private.h>
#include <Core/Memory/Allocator.h>
#include <Core/Thread/Thread.h>
#include <cstdarg>
namespace Juliet
{
IOStream* IOFromFile(String filename, String mode)
{
if (!IsValid(filename))
{
Log(LogLevel::Error, LogCategory::Core, "Trying to open IOStream on invalid filename");
return nullptr;
}
if (!IsValid(mode))
{
Log(LogLevel::Error, LogCategory::Core, "Trying to open IOStream with invalid mode");
return nullptr;
}
return Internal::IOFromFile(filename, mode);
}
IOStream* IOFromInterface(NonNullPtr<const IOStreamInterface> interface, NonNullPtr<IOStreamDataPayload> payload)
{
Assert(interface->Version >= sizeof(*interface.Get()));
auto stream = static_cast<IOStream*>(Calloc(1, sizeof(IOStream)));
if (stream)
{
IOStreamInterface* dstInterface = &stream->Interface;
const IOStreamInterface* srcInterface = interface.Get();
static_assert(sizeof(*(dstInterface)) == sizeof(*(srcInterface)), "Source and Destination type mismatch");
MemCopy(dstInterface, srcInterface, sizeof(*srcInterface));
stream->Data = payload.Get();
}
return stream;
}
size_t IOPrintf(NonNullPtr<IOStream> stream, _Printf_format_string_ const char* format, ...)
{
// TODO: Juliet format function should be able to allocate on scratch arena here.
// This buffer should be big enough until then
char formattedBuffer[4096];
va_list args;
va_start(args, format);
int writtenSize = vsprintf_s(formattedBuffer, format, args); // Cast to void to ignore the return type. TODO : Juliet format function
va_end(args);
Assert(writtenSize >= 0);
ByteBuffer buffer = {.Data = reinterpret_cast<Byte*>(formattedBuffer), .Size = static_cast<size_t>(writtenSize) };
return IOWrite(stream, buffer);
}
size_t IOWrite(NonNullPtr<IOStream> stream, ByteBuffer inBuffer)
{
if (!stream->Interface.Write)
{
stream->Status = IOStreamStatus::ReadOnly;
Log(LogLevel::Error, LogCategory::Core, "Trying to write to a readonly IOStream");
return 0;
}
stream->Status = IOStreamStatus::Ready;
if (!IsValid(inBuffer))
{
return 0;
}
size_t writtenBytes = stream->Interface.Write(stream->Data, inBuffer, &stream->Status);
if ((writtenBytes == 0) && (stream->Status == IOStreamStatus::Ready))
{
stream->Status = IOStreamStatus::Error;
}
return writtenBytes;
}
size_t IORead(NonNullPtr<IOStream> stream, void* ptr, size_t size)
{
if (!stream->Interface.Read)
{
Log(LogLevel::Error, LogCategory::Core, "Trying to read a writeonly IOStream");
stream->Status = IOStreamStatus::WriteOnly;
return 0;
}
stream->Status = IOStreamStatus::Ready;
if (size == 0)
{
return 0;
}
size_t bytes = stream->Interface.Read(stream->Data, ptr, size, &stream->Status);
if (bytes == 0 && stream->Status == IOStreamStatus::Ready)
{
// TODO: Detect error and do this stream->Status = IOStreamStatus::Error;
stream->Status = IOStreamStatus::EndOfFile;
}
return bytes;
}
int64 IOSeek(NonNullPtr<IOStream> stream, int64 offset, IOStreamSeekPivot pivot)
{
if (!stream->Interface.Seek)
{
Log(LogLevel::Error, LogCategory::Core, "IOSeek: Stream interface cannot Seek");
return -1;
}
return stream->Interface.Seek(stream->Data, offset, pivot);
}
int64 IOSize(NonNullPtr<IOStream> stream)
{
if (!stream->Interface.Size)
{
int64 pos = IOSeek(stream, 0, IOStreamSeekPivot::Current);
if (pos < 0)
{
return -1;
}
int64 size = IOSeek(stream, 0, IOStreamSeekPivot::End);
IOSeek(stream, pos, IOStreamSeekPivot::Begin);
return size;
}
return stream->Interface.Size(stream->Data);
}
ByteBuffer LoadFile(String filename)
{
IOStream* stream = IOFromFile(filename, WrapString("rb"));
if (!stream)
{
return {};
}
return LoadFile(stream, true);
}
ByteBuffer LoadFile(NonNullPtr<IOStream> stream, bool closeStreamWhenDone)
{
constexpr size_t kFileChunkSize = 1024;
uint8* data = nullptr;
uint8* newData = nullptr;
size_t totalSize = 0;
ByteBuffer resultBuffer = {};
auto deferred = Defer(
[&]()
{
if (closeStreamWhenDone)
{
IOClose(stream);
}
});
// Try reading the size from the stream, if failing we'll try to read it chunk by chunk
bool loadChunks = false;
int64 size = IOSize(stream);
if (size < 0)
{
size = kFileChunkSize;
loadChunks = true;
}
data = static_cast<uint8*>(Malloc(static_cast<size_t>(size + 1)));
if (!data)
{
return {};
}
while (true)
{
if (loadChunks)
{
if ((totalSize + kFileChunkSize) > size)
{
size = static_cast<int64>(totalSize + kFileChunkSize);
newData = static_cast<uint8*>(Realloc(data, static_cast<size_t>(size + 1)));
if (!newData)
{
Free(data);
return {};
}
data = newData;
}
}
size_t sizeRead = IORead(stream, data + totalSize, (size - totalSize));
if (sizeRead > 0)
{
totalSize += sizeRead;
continue;
}
if (stream->Status == IOStreamStatus::NotReady)
{
// Wait for the stream to be ready
wait_ms(1);
continue;
}
// The stream status will remain set for the caller to check
break;
}
// Adding null terminator
data[totalSize] = '\0';
resultBuffer.Data = reinterpret_cast<Byte*>(data);
resultBuffer.Size = totalSize;
return resultBuffer;
}
bool IOClose(NonNullPtr<IOStream> stream)
{
bool result = true;
if (stream->Interface.Close)
{
result = stream->Interface.Close(stream->Data);
}
Free(stream.Get());
return result;
}
} // namespace Juliet

View File

@@ -0,0 +1,19 @@
#pragma once
#include <Core/Common/String.h>
#include <Core/HAL/IO/IOStream.h>
namespace Juliet
{
struct IOStream
{
IOStreamInterface Interface;
IOStreamDataPayload* Data;
IOStreamStatus Status;
};
} // namespace Juliet
namespace Juliet::Internal
{
extern JULIET_API IOStream* IOFromFile(String filename, String mode);
}

View File

@@ -0,0 +1,280 @@
#include <pch.h>
#include <Core/Common/EnumUtils.h>
#include <Core/Common/String.h>
#include <Core/HAL/IO/IOStream.h>
#include <Core/HAL/Win32.h>
#include <Core/Memory/Allocator.h>
namespace Juliet::Internal
{
namespace
{
struct Win32IOStreamDataPayload : IOStreamDataPayload
{
HANDLE Handle;
void* Data;
size_t Size;
size_t SizeLeft;
bool IsAppending;
bool ShouldAutoClose;
};
constexpr size_t kFileReadBufferSize = 1024;
int64 FileSize(NonNullPtr<IOStreamDataPayload> payload)
{
auto win32Payload = static_cast<Win32IOStreamDataPayload*>(payload.Get());
LARGE_INTEGER size;
if (!GetFileSizeEx(win32Payload->Handle, &size))
{
Log(LogLevel::Error, LogCategory::Core, "IoStream:Size error: %d", GetLastError());
return 0;
}
return size.QuadPart;
}
int64 FileSeek(NonNullPtr<IOStreamDataPayload> payload, int64 offset, IOStreamSeekPivot pivot)
{
auto win32Payload = static_cast<Win32IOStreamDataPayload*>(payload.Get());
if ((pivot == IOStreamSeekPivot::Current) && (win32Payload->SizeLeft > 0))
{
offset -= static_cast<int64>(win32Payload->SizeLeft);
}
win32Payload->SizeLeft = 0;
DWORD windowsPivot = 0;
switch (pivot)
{
case IOStreamSeekPivot::Begin: windowsPivot = FILE_BEGIN; break;
case IOStreamSeekPivot::Current: windowsPivot = FILE_CURRENT; break;
case IOStreamSeekPivot::End: windowsPivot = FILE_END; break;
case IOStreamSeekPivot::Count:
Log(LogLevel::Error, LogCategory::Core, "IoStream:Seek: Invalid Pivot value");
return -1;
}
static_assert(ToUnderlying(IOStreamSeekPivot::Count) == 3, "IOStreamSeekPivot::Count must be 3");
LARGE_INTEGER windowsOffset;
windowsOffset.QuadPart = offset;
if (!SetFilePointerEx(win32Payload->Handle, windowsOffset, &windowsOffset, windowsPivot))
{
Log(LogLevel::Error, LogCategory::Core, "IoStream:Seek:Error: %d", GetLastError());
return 0;
}
return windowsOffset.QuadPart;
}
size_t FileRead(NonNullPtr<IOStreamDataPayload> payload, void* outBuffer, size_t size, NonNullPtr<IOStreamStatus> status)
{
auto win32Payload = static_cast<Win32IOStreamDataPayload*>(payload.Get());
size_t totalNeed = size;
size_t totalRead = 0;
size_t sizeToReadAhead = 0;
if (win32Payload->SizeLeft > 0)
{
uint8* data = static_cast<uint8*>(win32Payload->Data) + win32Payload->Size - win32Payload->SizeLeft;
sizeToReadAhead = Min(totalNeed, win32Payload->SizeLeft);
MemCopy(outBuffer, data, sizeToReadAhead);
win32Payload->SizeLeft -= sizeToReadAhead;
if (sizeToReadAhead == totalNeed)
{
return size;
}
outBuffer = static_cast<uint8*>(outBuffer) + sizeToReadAhead;
totalNeed -= sizeToReadAhead;
totalRead += sizeToReadAhead;
}
DWORD bytes = 0;
if (totalNeed < kFileReadBufferSize)
{
if (!ReadFile(win32Payload->Handle, win32Payload->Data, kFileReadBufferSize, &bytes, nullptr))
{
switch (DWORD error = GetLastError())
{
case ERROR_BROKEN_PIPE:
case ERROR_HANDLE_EOF: break;
case ERROR_NO_DATA: *status = IOStreamStatus::NotReady; break;
default:
Log(LogLevel::Error, LogCategory::Core, "IoStream:Win32 Read: Error reading from data stream: %d", error);
break;
}
return 0;
}
sizeToReadAhead = Min(totalNeed, static_cast<size_t>(bytes));
MemCopy(outBuffer, win32Payload->Data, sizeToReadAhead);
win32Payload->Size = bytes;
win32Payload->SizeLeft = bytes - sizeToReadAhead;
totalRead += sizeToReadAhead;
}
else
{
if (!ReadFile(win32Payload->Handle, outBuffer, static_cast<DWORD>(totalNeed), &bytes, nullptr))
{
switch (DWORD error = GetLastError())
{
case ERROR_BROKEN_PIPE:
case ERROR_HANDLE_EOF: break;
case ERROR_NO_DATA: *status = IOStreamStatus::NotReady; break;
default:
Log(LogLevel::Error, LogCategory::Core, "IoStream:Win32 Read: Error reading from data stream: %d", error);
break;
}
return 0;
}
totalRead += bytes;
}
return totalRead;
}
size_t FileWrite(NonNullPtr<IOStreamDataPayload> payload, ByteBuffer inBuffer, NonNullPtr<IOStreamStatus> status)
{
auto win32Payload = static_cast<Win32IOStreamDataPayload*>(payload.Get());
DWORD bytes;
if (win32Payload->SizeLeft)
{
if (!SetFilePointer(win32Payload->Handle, -static_cast<LONG>(win32Payload->SizeLeft), nullptr, FILE_CURRENT))
{
Log(LogLevel::Error, LogCategory::Core, "IoStream:FileWrite:Error seeking in datastream: %d", GetLastError());
return 0;
}
win32Payload->SizeLeft = 0;
}
// if in append mode, we must go to the EOF before write
if (win32Payload->IsAppending)
{
LARGE_INTEGER windowsOffset;
windowsOffset.QuadPart = 0;
if (!SetFilePointerEx(win32Payload->Handle, windowsOffset, &windowsOffset, FILE_END))
{
Log(LogLevel::Error, LogCategory::Core, "IoStream:FileWrite:Error seeking in datastream: %d", GetLastError());
return 0;
}
}
if (!WriteFile(win32Payload->Handle, inBuffer.Data, static_cast<DWORD>(inBuffer.Size), &bytes, nullptr))
{
Log(LogLevel::Error, LogCategory::Core, "IoStream:FileWrite:Error writing to datastream: %d", GetLastError());
return 0;
}
if (bytes == 0 && inBuffer.Size > 0)
{
*status = IOStreamStatus::NotReady;
}
return bytes;
}
bool FileClose(NonNullPtr<IOStreamDataPayload> payload)
{
auto win32Payload = static_cast<Win32IOStreamDataPayload*>(payload.Get());
if (win32Payload->Handle != INVALID_HANDLE_VALUE)
{
if (win32Payload->ShouldAutoClose)
{
CloseHandle(win32Payload->Handle);
}
win32Payload->Handle = INVALID_HANDLE_VALUE;
}
SafeFree(win32Payload->Data);
SafeFree(win32Payload);
return true;
}
} // namespace
IOStream* IOFromFile(String filename, String mode)
{
// "r" = reading, file must exist
// "w" = writing, truncate existing, file may not exist
// "r+"= reading or writing, file must exist
// "a" = writing, append file may not exist
// "a+"= append + read, file may not exist
// "w+" = read, write, truncate. file may not exist
#if _DEBUG
// Making sure the mode is valid
size_t modeLength = StringLength(mode);
Assert((modeLength <= 2) &&
"Mode should have at most 2 characters, one being either r,w or a and the other can only be +");
if (modeLength == 1)
{
Assert((mode.Data[0] == 'r' || mode.Data[0] == 'w' || mode.Data[0] == 'a') &&
"Invalid Mode. First char is not r,w or a");
}
else
{
Assert((mode.Data[1] == '+' || mode.Data[1] == 'b') && "Invalid Mode. Second char is not +");
}
#endif
DWORD openExisting = ContainsChar(mode, 'r') ? OPEN_EXISTING : 0;
DWORD createAlways = ContainsChar(mode, 'w') ? CREATE_ALWAYS : 0;
const bool isAppending = ContainsChar(mode, 'a');
DWORD openAlways = isAppending ? OPEN_ALWAYS : 0;
bool hasPlus = ContainsChar(mode, '+');
DWORD canRead = openExisting || hasPlus ? GENERIC_READ : 0;
DWORD canWrite = createAlways || openAlways || hasPlus ? GENERIC_WRITE : 0;
if (!canRead && !canWrite)
{
Log(LogLevel::Error, LogCategory::Core, "IOFromFile: Invalid Mode (cannot read nor write)");
return nullptr;
}
// TODO: Detect when folder is missing and create it if in w or a mode.
HANDLE hFile = CreateFileA(CStr(filename), (canWrite | canRead), (canWrite) ? 0 : FILE_SHARE_READ, nullptr,
(openExisting | createAlways | openAlways), FILE_ATTRIBUTE_NORMAL, nullptr);
if (hFile == INVALID_HANDLE_VALUE)
{
Log(LogLevel::Error, LogCategory::Core, "IOFromFile: couldn't open %s. Error: %d", CStr(filename), GetLastError());
return nullptr;
}
constexpr bool autoClose = true;
auto payload = static_cast<Win32IOStreamDataPayload*>(Calloc(1, sizeof(Win32IOStreamDataPayload)));
if (!payload)
{
if (autoClose)
{
CloseHandle(hFile);
}
return nullptr;
}
IOStreamInterface iface = {};
iface.Version = sizeof(iface);
if (GetFileType(hFile) == FILE_TYPE_DISK)
{
iface.Size = FileSize;
iface.Seek = FileSeek;
}
iface.Read = FileRead;
iface.Write = FileWrite;
iface.Close = FileClose;
payload->Handle = hFile;
payload->IsAppending = isAppending;
payload->ShouldAutoClose = autoClose;
payload->Data = static_cast<char*>(Malloc(kFileReadBufferSize));
if (!payload->Data)
{
iface.Close(payload);
return nullptr;
}
IOStream* stream = IOFromInterface(&iface, payload);
if (!stream)
{
iface.Close(payload);
}
return stream;
}
} // namespace Juliet::Internal

View File

@@ -9,33 +9,32 @@
namespace Juliet namespace Juliet
{ {
void InitHotReloadCode(HotReloadCode& code, StringBuffer<const char> dllName, void InitHotReloadCode(HotReloadCode& code, String dllName, String transientDllName, String lockFilename)
StringBuffer<const char> transientDllName, StringBuffer<const char> lockFilename)
{ {
// Get the app base path and build the dll path from there. // Get the app base path and build the dll path from there.
const char* basePath = GetBasePath(); String basePath = GetBasePath();
size_t basePathLength = strlen(basePath); size_t basePathLength = StringLength(basePath);
// Assign Transient dll path // Assign Transient dll path
code.TransientDLLName = transientDllName; code.TransientDLLName = transientDllName;
// First allocate all the full path. // First allocate all the full path.
// TODO: Add path composition into filesystem + string format + string builder // TODO: Add path composition into filesystem + string format + string builder
const size_t dllFullPathLength = basePathLength + dllName.Size; const size_t dllFullPathLength = basePathLength + StringLength(dllName) + 1; // Need +1 because snprintf needs 0 terminated strings
code.DLLFullPath.Data = static_cast<char*>(Calloc(dllFullPathLength, sizeof(char))); code.DLLFullPath.Data = static_cast<char*>(Calloc(dllFullPathLength, sizeof(char)));
int writtenSize = snprintf(code.DLLFullPath.Data, dllFullPathLength, "%s%s", basePath, dllName.Data); int writtenSize = snprintf(CStr(code.DLLFullPath), dllFullPathLength, "%s%s", CStr(basePath), CStr(dllName));
if (writtenSize < static_cast<int>(dllFullPathLength) - 1) if (writtenSize < static_cast<int>(dllFullPathLength) - 1)
{ {
SafeFree(code.DLLFullPath.Data); SafeFree(code.DLLFullPath.Data);
Log(LogLevel::Error, LogCategory::Core, "Cannot create DLL Full Path"); Log(LogLevel::Error, LogCategory::Core, "Cannot create DLL Full Path");
return; return;
} }
code.DLLFullPath.Size = writtenSize + 1; code.DLLFullPath.Size = writtenSize;
// Lock filename path // Lock filename path
const size_t lockPathLength = basePathLength + lockFilename.Size; const size_t lockPathLength = basePathLength + StringLength(lockFilename) + 1; // Need +1 because snprintf needs 0 terminated strings
code.LockFullPath.Data = static_cast<char*>(Calloc(lockPathLength, sizeof(char))); code.LockFullPath.Data = static_cast<char*>(Calloc(lockPathLength, sizeof(char)));
writtenSize = snprintf(code.LockFullPath.Data, lockPathLength, "%s%s", basePath, lockFilename.Data); writtenSize = snprintf(CStr(code.LockFullPath), lockPathLength, "%s%s", CStr(basePath), CStr(lockFilename));
if (writtenSize < static_cast<int>(lockPathLength) - 1) if (writtenSize < static_cast<int>(lockPathLength) - 1)
{ {
code.LockFullPath.Size = 0; code.LockFullPath.Size = 0;
@@ -43,7 +42,7 @@ namespace Juliet
Log(LogLevel::Error, LogCategory::Core, "Cannot create lock file full path"); Log(LogLevel::Error, LogCategory::Core, "Cannot create lock file full path");
return; return;
} }
code.LockFullPath.Size = writtenSize + 1; code.LockFullPath.Size = writtenSize;
LoadCode(code); LoadCode(code);
} }

View File

@@ -25,7 +25,7 @@ namespace Juliet
constexpr size_t kMaxAttempts = 256; constexpr size_t kMaxAttempts = 256;
constexpr size_t kMaxDLLID = 256; constexpr size_t kMaxDLLID = 256;
constexpr size_t kTempDLLBufferSizeForID = 6; // ID numbers + \0 constexpr size_t kTempDLLBufferSizeForID = 5; // Max ID numbers
} // namespace } // namespace
void LoadCode(HotReloadCode& code) void LoadCode(HotReloadCode& code)
@@ -48,20 +48,21 @@ namespace Juliet
// We'll see for better later. // We'll see for better later.
// Get the app base path and build the dll path from there. // Get the app base path and build the dll path from there.
const char* basePath = GetBasePath(); String basePath = GetBasePath();
size_t basePathLength = strlen(basePath); size_t basePathLength = StringLength(basePath);
const size_t tempDllMaxBufferSize = basePathLength + code.TransientDLLName.Size + kTempDLLBufferSizeForID; const size_t tempDllMaxBufferSize =
auto tempDllPath = static_cast<char*>(Calloc(tempDllMaxBufferSize, sizeof(char))); basePathLength + StringLength(code.TransientDLLName) + /* _ */ 1 + kTempDLLBufferSizeForID + 1 /* \0 */;
auto tempDllPath = static_cast<char*>(Calloc(tempDllMaxBufferSize, sizeof(char)));
for (uint32 attempt = 0; attempt < kMaxAttempts; ++attempt) for (uint32 attempt = 0; attempt < kMaxAttempts; ++attempt)
{ {
// int to char // int to char
char idToStr[kTempDLLBufferSizeForID]; char idToStr[kTempDLLBufferSizeForID + 1];
int idLength = snprintf(idToStr, sizeof(idToStr), "%u", code.UniqueID); int idLength = snprintf(idToStr, sizeof(idToStr), "%u", code.UniqueID);
int writtenSize = snprintf(tempDllPath, tempDllMaxBufferSize, "%s%u_%s", basePath, code.UniqueID, int writtenSize = snprintf(tempDllPath, tempDllMaxBufferSize, "%s%s_%s", CStr(basePath), idToStr,
code.TransientDLLName.Data); CStr(code.TransientDLLName));
if (writtenSize < static_cast<int>(basePathLength + idLength + code.TransientDLLName.Size)) if (writtenSize < static_cast<int>(basePathLength + idLength + code.TransientDLLName.Size) - 1)
{ {
SafeFree(tempDllPath); SafeFree(tempDllPath);
Log(LogLevel::Error, LogCategory::Core, "Cannot create temp full path"); Log(LogLevel::Error, LogCategory::Core, "Cannot create temp full path");
@@ -107,7 +108,10 @@ namespace Juliet
void UnloadCode(HotReloadCode& code) void UnloadCode(HotReloadCode& code)
{ {
code.IsValid = false; code.IsValid = false;
UnloadDynamicLibrary(code.Dll); if (code.Dll)
{
UnloadDynamicLibrary(code.Dll);
}
code.Dll = nullptr; code.Dll = nullptr;
code.LastWriteTime = 0; code.LastWriteTime = 0;

View File

@@ -7,8 +7,12 @@
#include <cstdarg> #include <cstdarg>
// Begin Todo JULIET debug output // Begin Todo JULIET debug output
#include <cinttypes>
#ifdef JULIET_WIN32
#include <Core/HAL/Win32.h> #include <Core/HAL/Win32.h>
#include <debugapi.h> #include <debugapi.h>
#endif
// End Todo // End Todo
namespace Juliet namespace Juliet
@@ -62,12 +66,19 @@ namespace Juliet
void LogManager::OutputLog(Entry& entry) void LogManager::OutputLog(Entry& entry)
{ {
// TODO Juliet Output io for each platform // TODO Juliet Output io for each platform
#ifdef JULIET_WIN32
OutputDebugStringA((entry.Value + "\n").c_str()); OutputDebugStringA((entry.Value + "\n").c_str());
#endif
printf("%s", (entry.Value + "\n").c_str()); printf("%s", (entry.Value + "\n").c_str());
} }
void InitializeLogManager() void InitializeLogManager()
{ {
#ifdef JULIET_WIN32
SetConsoleOutputCP(CP_UTF8);
SetConsoleCP(CP_UTF8);
#endif
LogManagerSingleton.Init(); LogManagerSingleton.Init();
} }
@@ -76,15 +87,12 @@ namespace Juliet
LogManagerSingleton.Shutdown(); LogManagerSingleton.Shutdown();
} }
void Log(LogLevel level, LogCategory category, const char* fmt, ...) void Log(LogLevel level, LogCategory category, const char* fmt, va_list args)
{ {
// TODO : Revisit, copy from https://github.com/Eclmist/Ether/blob/develop/src/common/logging/loggingmanager.cpp // TODO : Revisit, copy from https://github.com/Eclmist/Ether/blob/develop/src/common/logging/loggingmanager.cpp
char formattedBuffer[4096]; char formattedBuffer[4096];
va_list args;
va_start(args, fmt);
(void)vsprintf_s(formattedBuffer, fmt, args); // Cast to void to ignore the return type. TODO : Juliet format function (void)vsprintf_s(formattedBuffer, fmt, args); // Cast to void to ignore the return type. TODO : Juliet format function
va_end(args);
std::string formattedText(formattedBuffer); std::string formattedText(formattedBuffer);
@@ -103,4 +111,35 @@ namespace Juliet
} }
} }
void Log(LogLevel level, LogCategory category, const char* fmt, ...)
{
va_list args;
va_start(args, fmt);
Log(level, category, fmt, args);
va_end(args);
}
void LogMessage(LogCategory category, const char* fmt, ...)
{
va_list args;
va_start(args, fmt);
Log(LogLevel::Message, category, fmt, args);
va_end(args);
}
void LogWarning(LogCategory category, const char* fmt, ...)
{
va_list args;
va_start(args, fmt);
Log(LogLevel::Warning, category, fmt, args);
va_end(args);
}
void LogError(LogCategory category, const char* fmt, ...)
{
va_list args;
va_start(args, fmt);
Log(LogLevel::Error, category, fmt, args);
va_end(args);
}
} // namespace Juliet } // namespace Juliet

View File

@@ -0,0 +1,63 @@
#include <pch.h>
#include <Core/Math/Math_Private.h>
namespace Juliet
{
// From MUSL lib https://github.com/rofl0r/musl
#if FLT_EVAL_METHOD == 0
#define EPS FLT_EPSILON
#elif FLT_EVAL_METHOD == 1
#define EPS DBL_EPSILON
#elif FLT_EVAL_METHOD == 2
#define EPS LDBL_EPSILON
#endif
namespace
{
const float_t toint = 1 / EPS;
}
float RoundF(float value)
{
union
{
float f;
uint32_t i;
} u = { value };
int e = u.i >> 23 & 0xff;
float_t y;
if (e >= 0x7f + 23)
{
return value;
}
if (u.i >> 31)
{
value = -value;
}
if (e < 0x7f - 1)
{
FORCE_EVAL(value + toint);
return 0 * u.f;
}
y = value + toint - toint - value;
if (y > 0.5f)
{
y = y + value - 1;
}
else if (y <= -0.5f)
{
y = y + value + 1;
}
else
{
y = y + value;
}
if (u.i >> 31)
{
y = -y;
}
return y;
}
} // namespace Juliet

View File

@@ -0,0 +1,51 @@
#pragma once
namespace Juliet
{
// From MUSL lib https://github.com/rofl0r/musl
#ifndef fp_force_evalf
#define fp_force_evalf fp_force_evalf
static inline void fp_force_evalf(float x)
{
volatile float y;
y = x;
}
#endif
#ifndef fp_force_eval
#define fp_force_eval fp_force_eval
static inline void fp_force_eval(double x)
{
volatile double y;
y = x;
}
#endif
#ifndef fp_force_evall
#define fp_force_evall fp_force_evall
static inline void fp_force_evall(long double x)
{
volatile long double y;
y = x;
}
#endif
#define FORCE_EVAL(x) \
do \
{ \
if (sizeof(x) == sizeof(float)) \
{ \
fp_force_evalf(x); \
} \
else if (sizeof(x) == sizeof(double)) \
{ \
fp_force_eval(x); \
} \
else \
{ \
fp_force_evall(x); \
} \
} \
while (0)
} // namespace Juliet

View File

@@ -1,4 +1,3 @@
#include <D3D12Texture.h>
#include <pch.h> #include <pch.h>
#include <core/Memory/Allocator.h> #include <core/Memory/Allocator.h>

View File

@@ -3,7 +3,7 @@
#include <Core/Networking/NetworkPacket.h> #include <Core/Networking/NetworkPacket.h>
#include <Core/Networking/SocketPlatformImpl.h> #include <Core/Networking/SocketPlatformImpl.h>
#define TO_BUFFER(ptr) reinterpret_cast<const Byte*>(ptr) #define TO_BUFFER(ptr) reinterpret_cast<Byte*>(ptr)
namespace Juliet namespace Juliet
{ {
@@ -29,12 +29,12 @@ namespace Juliet
// Begin - Pack // Begin - Pack
NetworkPacket& NetworkPacket::operator<<(uint32 value) NetworkPacket& NetworkPacket::operator<<(uint32 value)
{ {
const uint32 toWrite = htonl(value); uint32 toWrite = htonl(value);
Append({ TO_BUFFER(&toWrite), sizeof(toWrite) }); Append({ TO_BUFFER(&toWrite), sizeof(toWrite) });
return *this; return *this;
} }
NetworkPacket& NetworkPacket::operator<<(const char* data) NetworkPacket& NetworkPacket::operator<<(char* data)
{ {
Assert(data && "NetworkPacket::operator<< Data must not be null"); Assert(data && "NetworkPacket::operator<< Data must not be null");

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,5 @@
https://www.nuget.org/packages/Microsoft.Direct3D.D3D12/1.615.1
Version 615
https://devblogs.microsoft.com/directx/directx12agility/

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,899 @@
/*-------------------------------------------------------------------------------------
*
* Copyright (c) Microsoft Corporation
* Licensed under the MIT license
*
*-------------------------------------------------------------------------------------*/
/* this ALWAYS GENERATED file contains the definitions for the interfaces */
/* File created by MIDL compiler version 8.01.0628 */
/* verify that the <rpcndr.h> version is high enough to compile this file*/
#ifndef __REQUIRED_RPCNDR_H_VERSION__
#define __REQUIRED_RPCNDR_H_VERSION__ 500
#endif
/* verify that the <rpcsal.h> version is high enough to compile this file*/
#ifndef __REQUIRED_RPCSAL_H_VERSION__
#define __REQUIRED_RPCSAL_H_VERSION__ 100
#endif
#include "rpc.h"
#include "rpcndr.h"
#ifndef __RPCNDR_H_VERSION__
#error this stub requires an updated version of <rpcndr.h>
#endif /* __RPCNDR_H_VERSION__ */
#ifndef COM_NO_WINDOWS_H
#include "windows.h"
#include "ole2.h"
#endif /*COM_NO_WINDOWS_H*/
#ifndef __d3d12compatibility_h__
#define __d3d12compatibility_h__
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
#pragma once
#endif
#ifndef DECLSPEC_XFGVIRT
#if defined(_CONTROL_FLOW_GUARD_XFG)
#define DECLSPEC_XFGVIRT(base, func) __declspec(xfg_virtual(base, func))
#else
#define DECLSPEC_XFGVIRT(base, func)
#endif
#endif
/* Forward Declarations */
#ifndef __ID3D12CompatibilityDevice_FWD_DEFINED__
#define __ID3D12CompatibilityDevice_FWD_DEFINED__
typedef interface ID3D12CompatibilityDevice ID3D12CompatibilityDevice;
#endif /* __ID3D12CompatibilityDevice_FWD_DEFINED__ */
#ifndef __D3D11On12CreatorID_FWD_DEFINED__
#define __D3D11On12CreatorID_FWD_DEFINED__
typedef interface D3D11On12CreatorID D3D11On12CreatorID;
#endif /* __D3D11On12CreatorID_FWD_DEFINED__ */
#ifndef __D3D9On12CreatorID_FWD_DEFINED__
#define __D3D9On12CreatorID_FWD_DEFINED__
typedef interface D3D9On12CreatorID D3D9On12CreatorID;
#endif /* __D3D9On12CreatorID_FWD_DEFINED__ */
#ifndef __OpenGLOn12CreatorID_FWD_DEFINED__
#define __OpenGLOn12CreatorID_FWD_DEFINED__
typedef interface OpenGLOn12CreatorID OpenGLOn12CreatorID;
#endif /* __OpenGLOn12CreatorID_FWD_DEFINED__ */
#ifndef __OpenCLOn12CreatorID_FWD_DEFINED__
#define __OpenCLOn12CreatorID_FWD_DEFINED__
typedef interface OpenCLOn12CreatorID OpenCLOn12CreatorID;
#endif /* __OpenCLOn12CreatorID_FWD_DEFINED__ */
#ifndef __VulkanOn12CreatorID_FWD_DEFINED__
#define __VulkanOn12CreatorID_FWD_DEFINED__
typedef interface VulkanOn12CreatorID VulkanOn12CreatorID;
#endif /* __VulkanOn12CreatorID_FWD_DEFINED__ */
#ifndef __DirectMLTensorFlowCreatorID_FWD_DEFINED__
#define __DirectMLTensorFlowCreatorID_FWD_DEFINED__
typedef interface DirectMLTensorFlowCreatorID DirectMLTensorFlowCreatorID;
#endif /* __DirectMLTensorFlowCreatorID_FWD_DEFINED__ */
#ifndef __DirectMLPyTorchCreatorID_FWD_DEFINED__
#define __DirectMLPyTorchCreatorID_FWD_DEFINED__
typedef interface DirectMLPyTorchCreatorID DirectMLPyTorchCreatorID;
#endif /* __DirectMLPyTorchCreatorID_FWD_DEFINED__ */
#ifndef __DirectMLWebNNCreatorID_FWD_DEFINED__
#define __DirectMLWebNNCreatorID_FWD_DEFINED__
typedef interface DirectMLWebNNCreatorID DirectMLWebNNCreatorID;
#endif /* __DirectMLWebNNCreatorID_FWD_DEFINED__ */
/* header files for imported files */
#include "oaidl.h"
#include "ocidl.h"
#include "d3d11on12.h"
#ifdef __cplusplus
extern "C"{
#endif
/* interface __MIDL_itf_d3d12compatibility_0000_0000 */
/* [local] */
#include <winapifamily.h>
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_GAMES)
typedef
enum D3D12_COMPATIBILITY_SHARED_FLAGS
{
D3D12_COMPATIBILITY_SHARED_FLAG_NONE = 0,
D3D12_COMPATIBILITY_SHARED_FLAG_NON_NT_HANDLE = 0x1,
D3D12_COMPATIBILITY_SHARED_FLAG_KEYED_MUTEX = 0x2,
D3D12_COMPATIBILITY_SHARED_FLAG_9_ON_12 = 0x4
} D3D12_COMPATIBILITY_SHARED_FLAGS;
DEFINE_ENUM_FLAG_OPERATORS( D3D12_COMPATIBILITY_SHARED_FLAGS )
typedef
enum D3D12_REFLECT_SHARED_PROPERTY
{
D3D12_REFLECT_SHARED_PROPERTY_D3D11_RESOURCE_FLAGS = 0,
D3D12_REFELCT_SHARED_PROPERTY_COMPATIBILITY_SHARED_FLAGS = ( D3D12_REFLECT_SHARED_PROPERTY_D3D11_RESOURCE_FLAGS + 1 ) ,
D3D12_REFLECT_SHARED_PROPERTY_NON_NT_SHARED_HANDLE = ( D3D12_REFELCT_SHARED_PROPERTY_COMPATIBILITY_SHARED_FLAGS + 1 )
} D3D12_REFLECT_SHARED_PROPERTY;
extern RPC_IF_HANDLE __MIDL_itf_d3d12compatibility_0000_0000_v0_0_c_ifspec;
extern RPC_IF_HANDLE __MIDL_itf_d3d12compatibility_0000_0000_v0_0_s_ifspec;
#ifndef __ID3D12CompatibilityDevice_INTERFACE_DEFINED__
#define __ID3D12CompatibilityDevice_INTERFACE_DEFINED__
/* interface ID3D12CompatibilityDevice */
/* [unique][local][object][uuid] */
EXTERN_C const IID IID_ID3D12CompatibilityDevice;
#if defined(__cplusplus) && !defined(CINTERFACE)
MIDL_INTERFACE("8f1c0e3c-fae3-4a82-b098-bfe1708207ff")
ID3D12CompatibilityDevice : public IUnknown
{
public:
virtual HRESULT STDMETHODCALLTYPE CreateSharedResource(
_In_ const D3D12_HEAP_PROPERTIES *pHeapProperties,
D3D12_HEAP_FLAGS HeapFlags,
_In_ const D3D12_RESOURCE_DESC *pDesc,
D3D12_RESOURCE_STATES InitialResourceState,
_In_opt_ const D3D12_CLEAR_VALUE *pOptimizedClearValue,
_In_opt_ const D3D11_RESOURCE_FLAGS *pFlags11,
D3D12_COMPATIBILITY_SHARED_FLAGS CompatibilityFlags,
_In_opt_ ID3D12LifetimeTracker *pLifetimeTracker,
_In_opt_ ID3D12SwapChainAssistant *pOwningSwapchain,
REFIID riid,
_COM_Outptr_opt_ void **ppResource) = 0;
virtual HRESULT STDMETHODCALLTYPE CreateSharedHeap(
_In_ const D3D12_HEAP_DESC *pHeapDesc,
D3D12_COMPATIBILITY_SHARED_FLAGS CompatibilityFlags,
REFIID riid,
_COM_Outptr_opt_ void **ppHeap) = 0;
virtual HRESULT STDMETHODCALLTYPE ReflectSharedProperties(
_In_ ID3D12Object *pHeapOrResource,
D3D12_REFLECT_SHARED_PROPERTY ReflectType,
_Out_writes_bytes_(DataSize) void *pData,
UINT DataSize) = 0;
};
#else /* C style interface */
typedef struct ID3D12CompatibilityDeviceVtbl
{
BEGIN_INTERFACE
DECLSPEC_XFGVIRT(IUnknown, QueryInterface)
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
ID3D12CompatibilityDevice * This,
REFIID riid,
_COM_Outptr_ void **ppvObject);
DECLSPEC_XFGVIRT(IUnknown, AddRef)
ULONG ( STDMETHODCALLTYPE *AddRef )(
ID3D12CompatibilityDevice * This);
DECLSPEC_XFGVIRT(IUnknown, Release)
ULONG ( STDMETHODCALLTYPE *Release )(
ID3D12CompatibilityDevice * This);
DECLSPEC_XFGVIRT(ID3D12CompatibilityDevice, CreateSharedResource)
HRESULT ( STDMETHODCALLTYPE *CreateSharedResource )(
ID3D12CompatibilityDevice * This,
_In_ const D3D12_HEAP_PROPERTIES *pHeapProperties,
D3D12_HEAP_FLAGS HeapFlags,
_In_ const D3D12_RESOURCE_DESC *pDesc,
D3D12_RESOURCE_STATES InitialResourceState,
_In_opt_ const D3D12_CLEAR_VALUE *pOptimizedClearValue,
_In_opt_ const D3D11_RESOURCE_FLAGS *pFlags11,
D3D12_COMPATIBILITY_SHARED_FLAGS CompatibilityFlags,
_In_opt_ ID3D12LifetimeTracker *pLifetimeTracker,
_In_opt_ ID3D12SwapChainAssistant *pOwningSwapchain,
REFIID riid,
_COM_Outptr_opt_ void **ppResource);
DECLSPEC_XFGVIRT(ID3D12CompatibilityDevice, CreateSharedHeap)
HRESULT ( STDMETHODCALLTYPE *CreateSharedHeap )(
ID3D12CompatibilityDevice * This,
_In_ const D3D12_HEAP_DESC *pHeapDesc,
D3D12_COMPATIBILITY_SHARED_FLAGS CompatibilityFlags,
REFIID riid,
_COM_Outptr_opt_ void **ppHeap);
DECLSPEC_XFGVIRT(ID3D12CompatibilityDevice, ReflectSharedProperties)
HRESULT ( STDMETHODCALLTYPE *ReflectSharedProperties )(
ID3D12CompatibilityDevice * This,
_In_ ID3D12Object *pHeapOrResource,
D3D12_REFLECT_SHARED_PROPERTY ReflectType,
_Out_writes_bytes_(DataSize) void *pData,
UINT DataSize);
END_INTERFACE
} ID3D12CompatibilityDeviceVtbl;
interface ID3D12CompatibilityDevice
{
CONST_VTBL struct ID3D12CompatibilityDeviceVtbl *lpVtbl;
};
#ifdef COBJMACROS
#define ID3D12CompatibilityDevice_QueryInterface(This,riid,ppvObject) \
( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
#define ID3D12CompatibilityDevice_AddRef(This) \
( (This)->lpVtbl -> AddRef(This) )
#define ID3D12CompatibilityDevice_Release(This) \
( (This)->lpVtbl -> Release(This) )
#define ID3D12CompatibilityDevice_CreateSharedResource(This,pHeapProperties,HeapFlags,pDesc,InitialResourceState,pOptimizedClearValue,pFlags11,CompatibilityFlags,pLifetimeTracker,pOwningSwapchain,riid,ppResource) \
( (This)->lpVtbl -> CreateSharedResource(This,pHeapProperties,HeapFlags,pDesc,InitialResourceState,pOptimizedClearValue,pFlags11,CompatibilityFlags,pLifetimeTracker,pOwningSwapchain,riid,ppResource) )
#define ID3D12CompatibilityDevice_CreateSharedHeap(This,pHeapDesc,CompatibilityFlags,riid,ppHeap) \
( (This)->lpVtbl -> CreateSharedHeap(This,pHeapDesc,CompatibilityFlags,riid,ppHeap) )
#define ID3D12CompatibilityDevice_ReflectSharedProperties(This,pHeapOrResource,ReflectType,pData,DataSize) \
( (This)->lpVtbl -> ReflectSharedProperties(This,pHeapOrResource,ReflectType,pData,DataSize) )
#endif /* COBJMACROS */
#endif /* C style interface */
#endif /* __ID3D12CompatibilityDevice_INTERFACE_DEFINED__ */
#ifndef __D3D11On12CreatorID_INTERFACE_DEFINED__
#define __D3D11On12CreatorID_INTERFACE_DEFINED__
/* interface D3D11On12CreatorID */
/* [unique][local][object][uuid] */
EXTERN_C const IID IID_D3D11On12CreatorID;
#if defined(__cplusplus) && !defined(CINTERFACE)
MIDL_INTERFACE("edbf5678-2960-4e81-8429-99d4b2630c4e")
D3D11On12CreatorID : public IUnknown
{
public:
};
#else /* C style interface */
typedef struct D3D11On12CreatorIDVtbl
{
BEGIN_INTERFACE
DECLSPEC_XFGVIRT(IUnknown, QueryInterface)
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
D3D11On12CreatorID * This,
REFIID riid,
_COM_Outptr_ void **ppvObject);
DECLSPEC_XFGVIRT(IUnknown, AddRef)
ULONG ( STDMETHODCALLTYPE *AddRef )(
D3D11On12CreatorID * This);
DECLSPEC_XFGVIRT(IUnknown, Release)
ULONG ( STDMETHODCALLTYPE *Release )(
D3D11On12CreatorID * This);
END_INTERFACE
} D3D11On12CreatorIDVtbl;
interface D3D11On12CreatorID
{
CONST_VTBL struct D3D11On12CreatorIDVtbl *lpVtbl;
};
#ifdef COBJMACROS
#define D3D11On12CreatorID_QueryInterface(This,riid,ppvObject) \
( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
#define D3D11On12CreatorID_AddRef(This) \
( (This)->lpVtbl -> AddRef(This) )
#define D3D11On12CreatorID_Release(This) \
( (This)->lpVtbl -> Release(This) )
#endif /* COBJMACROS */
#endif /* C style interface */
#endif /* __D3D11On12CreatorID_INTERFACE_DEFINED__ */
#ifndef __D3D9On12CreatorID_INTERFACE_DEFINED__
#define __D3D9On12CreatorID_INTERFACE_DEFINED__
/* interface D3D9On12CreatorID */
/* [unique][local][object][uuid] */
EXTERN_C const IID IID_D3D9On12CreatorID;
#if defined(__cplusplus) && !defined(CINTERFACE)
MIDL_INTERFACE("fffcbb7f-15d3-42a2-841e-9d8d32f37ddd")
D3D9On12CreatorID : public IUnknown
{
public:
};
#else /* C style interface */
typedef struct D3D9On12CreatorIDVtbl
{
BEGIN_INTERFACE
DECLSPEC_XFGVIRT(IUnknown, QueryInterface)
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
D3D9On12CreatorID * This,
REFIID riid,
_COM_Outptr_ void **ppvObject);
DECLSPEC_XFGVIRT(IUnknown, AddRef)
ULONG ( STDMETHODCALLTYPE *AddRef )(
D3D9On12CreatorID * This);
DECLSPEC_XFGVIRT(IUnknown, Release)
ULONG ( STDMETHODCALLTYPE *Release )(
D3D9On12CreatorID * This);
END_INTERFACE
} D3D9On12CreatorIDVtbl;
interface D3D9On12CreatorID
{
CONST_VTBL struct D3D9On12CreatorIDVtbl *lpVtbl;
};
#ifdef COBJMACROS
#define D3D9On12CreatorID_QueryInterface(This,riid,ppvObject) \
( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
#define D3D9On12CreatorID_AddRef(This) \
( (This)->lpVtbl -> AddRef(This) )
#define D3D9On12CreatorID_Release(This) \
( (This)->lpVtbl -> Release(This) )
#endif /* COBJMACROS */
#endif /* C style interface */
#endif /* __D3D9On12CreatorID_INTERFACE_DEFINED__ */
#ifndef __OpenGLOn12CreatorID_INTERFACE_DEFINED__
#define __OpenGLOn12CreatorID_INTERFACE_DEFINED__
/* interface OpenGLOn12CreatorID */
/* [unique][local][object][uuid] */
EXTERN_C const IID IID_OpenGLOn12CreatorID;
#if defined(__cplusplus) && !defined(CINTERFACE)
MIDL_INTERFACE("6bb3cd34-0d19-45ab-97ed-d720ba3dfc80")
OpenGLOn12CreatorID : public IUnknown
{
public:
};
#else /* C style interface */
typedef struct OpenGLOn12CreatorIDVtbl
{
BEGIN_INTERFACE
DECLSPEC_XFGVIRT(IUnknown, QueryInterface)
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
OpenGLOn12CreatorID * This,
REFIID riid,
_COM_Outptr_ void **ppvObject);
DECLSPEC_XFGVIRT(IUnknown, AddRef)
ULONG ( STDMETHODCALLTYPE *AddRef )(
OpenGLOn12CreatorID * This);
DECLSPEC_XFGVIRT(IUnknown, Release)
ULONG ( STDMETHODCALLTYPE *Release )(
OpenGLOn12CreatorID * This);
END_INTERFACE
} OpenGLOn12CreatorIDVtbl;
interface OpenGLOn12CreatorID
{
CONST_VTBL struct OpenGLOn12CreatorIDVtbl *lpVtbl;
};
#ifdef COBJMACROS
#define OpenGLOn12CreatorID_QueryInterface(This,riid,ppvObject) \
( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
#define OpenGLOn12CreatorID_AddRef(This) \
( (This)->lpVtbl -> AddRef(This) )
#define OpenGLOn12CreatorID_Release(This) \
( (This)->lpVtbl -> Release(This) )
#endif /* COBJMACROS */
#endif /* C style interface */
#endif /* __OpenGLOn12CreatorID_INTERFACE_DEFINED__ */
#ifndef __OpenCLOn12CreatorID_INTERFACE_DEFINED__
#define __OpenCLOn12CreatorID_INTERFACE_DEFINED__
/* interface OpenCLOn12CreatorID */
/* [unique][local][object][uuid] */
EXTERN_C const IID IID_OpenCLOn12CreatorID;
#if defined(__cplusplus) && !defined(CINTERFACE)
MIDL_INTERFACE("3f76bb74-91b5-4a88-b126-20ca0331cd60")
OpenCLOn12CreatorID : public IUnknown
{
public:
};
#else /* C style interface */
typedef struct OpenCLOn12CreatorIDVtbl
{
BEGIN_INTERFACE
DECLSPEC_XFGVIRT(IUnknown, QueryInterface)
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
OpenCLOn12CreatorID * This,
REFIID riid,
_COM_Outptr_ void **ppvObject);
DECLSPEC_XFGVIRT(IUnknown, AddRef)
ULONG ( STDMETHODCALLTYPE *AddRef )(
OpenCLOn12CreatorID * This);
DECLSPEC_XFGVIRT(IUnknown, Release)
ULONG ( STDMETHODCALLTYPE *Release )(
OpenCLOn12CreatorID * This);
END_INTERFACE
} OpenCLOn12CreatorIDVtbl;
interface OpenCLOn12CreatorID
{
CONST_VTBL struct OpenCLOn12CreatorIDVtbl *lpVtbl;
};
#ifdef COBJMACROS
#define OpenCLOn12CreatorID_QueryInterface(This,riid,ppvObject) \
( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
#define OpenCLOn12CreatorID_AddRef(This) \
( (This)->lpVtbl -> AddRef(This) )
#define OpenCLOn12CreatorID_Release(This) \
( (This)->lpVtbl -> Release(This) )
#endif /* COBJMACROS */
#endif /* C style interface */
#endif /* __OpenCLOn12CreatorID_INTERFACE_DEFINED__ */
#ifndef __VulkanOn12CreatorID_INTERFACE_DEFINED__
#define __VulkanOn12CreatorID_INTERFACE_DEFINED__
/* interface VulkanOn12CreatorID */
/* [unique][local][object][uuid] */
EXTERN_C const IID IID_VulkanOn12CreatorID;
#if defined(__cplusplus) && !defined(CINTERFACE)
MIDL_INTERFACE("bc806e01-3052-406c-a3e8-9fc07f048f98")
VulkanOn12CreatorID : public IUnknown
{
public:
};
#else /* C style interface */
typedef struct VulkanOn12CreatorIDVtbl
{
BEGIN_INTERFACE
DECLSPEC_XFGVIRT(IUnknown, QueryInterface)
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
VulkanOn12CreatorID * This,
REFIID riid,
_COM_Outptr_ void **ppvObject);
DECLSPEC_XFGVIRT(IUnknown, AddRef)
ULONG ( STDMETHODCALLTYPE *AddRef )(
VulkanOn12CreatorID * This);
DECLSPEC_XFGVIRT(IUnknown, Release)
ULONG ( STDMETHODCALLTYPE *Release )(
VulkanOn12CreatorID * This);
END_INTERFACE
} VulkanOn12CreatorIDVtbl;
interface VulkanOn12CreatorID
{
CONST_VTBL struct VulkanOn12CreatorIDVtbl *lpVtbl;
};
#ifdef COBJMACROS
#define VulkanOn12CreatorID_QueryInterface(This,riid,ppvObject) \
( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
#define VulkanOn12CreatorID_AddRef(This) \
( (This)->lpVtbl -> AddRef(This) )
#define VulkanOn12CreatorID_Release(This) \
( (This)->lpVtbl -> Release(This) )
#endif /* COBJMACROS */
#endif /* C style interface */
#endif /* __VulkanOn12CreatorID_INTERFACE_DEFINED__ */
#ifndef __DirectMLTensorFlowCreatorID_INTERFACE_DEFINED__
#define __DirectMLTensorFlowCreatorID_INTERFACE_DEFINED__
/* interface DirectMLTensorFlowCreatorID */
/* [unique][local][object][uuid] */
EXTERN_C const IID IID_DirectMLTensorFlowCreatorID;
#if defined(__cplusplus) && !defined(CINTERFACE)
MIDL_INTERFACE("cb7490ac-8a0f-44ec-9b7b-6f4cafe8e9ab")
DirectMLTensorFlowCreatorID : public IUnknown
{
public:
};
#else /* C style interface */
typedef struct DirectMLTensorFlowCreatorIDVtbl
{
BEGIN_INTERFACE
DECLSPEC_XFGVIRT(IUnknown, QueryInterface)
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
DirectMLTensorFlowCreatorID * This,
REFIID riid,
_COM_Outptr_ void **ppvObject);
DECLSPEC_XFGVIRT(IUnknown, AddRef)
ULONG ( STDMETHODCALLTYPE *AddRef )(
DirectMLTensorFlowCreatorID * This);
DECLSPEC_XFGVIRT(IUnknown, Release)
ULONG ( STDMETHODCALLTYPE *Release )(
DirectMLTensorFlowCreatorID * This);
END_INTERFACE
} DirectMLTensorFlowCreatorIDVtbl;
interface DirectMLTensorFlowCreatorID
{
CONST_VTBL struct DirectMLTensorFlowCreatorIDVtbl *lpVtbl;
};
#ifdef COBJMACROS
#define DirectMLTensorFlowCreatorID_QueryInterface(This,riid,ppvObject) \
( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
#define DirectMLTensorFlowCreatorID_AddRef(This) \
( (This)->lpVtbl -> AddRef(This) )
#define DirectMLTensorFlowCreatorID_Release(This) \
( (This)->lpVtbl -> Release(This) )
#endif /* COBJMACROS */
#endif /* C style interface */
#endif /* __DirectMLTensorFlowCreatorID_INTERFACE_DEFINED__ */
#ifndef __DirectMLPyTorchCreatorID_INTERFACE_DEFINED__
#define __DirectMLPyTorchCreatorID_INTERFACE_DEFINED__
/* interface DirectMLPyTorchCreatorID */
/* [unique][local][object][uuid] */
EXTERN_C const IID IID_DirectMLPyTorchCreatorID;
#if defined(__cplusplus) && !defined(CINTERFACE)
MIDL_INTERFACE("af029192-fba1-4b05-9116-235e06560354")
DirectMLPyTorchCreatorID : public IUnknown
{
public:
};
#else /* C style interface */
typedef struct DirectMLPyTorchCreatorIDVtbl
{
BEGIN_INTERFACE
DECLSPEC_XFGVIRT(IUnknown, QueryInterface)
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
DirectMLPyTorchCreatorID * This,
REFIID riid,
_COM_Outptr_ void **ppvObject);
DECLSPEC_XFGVIRT(IUnknown, AddRef)
ULONG ( STDMETHODCALLTYPE *AddRef )(
DirectMLPyTorchCreatorID * This);
DECLSPEC_XFGVIRT(IUnknown, Release)
ULONG ( STDMETHODCALLTYPE *Release )(
DirectMLPyTorchCreatorID * This);
END_INTERFACE
} DirectMLPyTorchCreatorIDVtbl;
interface DirectMLPyTorchCreatorID
{
CONST_VTBL struct DirectMLPyTorchCreatorIDVtbl *lpVtbl;
};
#ifdef COBJMACROS
#define DirectMLPyTorchCreatorID_QueryInterface(This,riid,ppvObject) \
( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
#define DirectMLPyTorchCreatorID_AddRef(This) \
( (This)->lpVtbl -> AddRef(This) )
#define DirectMLPyTorchCreatorID_Release(This) \
( (This)->lpVtbl -> Release(This) )
#endif /* COBJMACROS */
#endif /* C style interface */
#endif /* __DirectMLPyTorchCreatorID_INTERFACE_DEFINED__ */
#ifndef __DirectMLWebNNCreatorID_INTERFACE_DEFINED__
#define __DirectMLWebNNCreatorID_INTERFACE_DEFINED__
/* interface DirectMLWebNNCreatorID */
/* [unique][local][object][uuid] */
EXTERN_C const IID IID_DirectMLWebNNCreatorID;
#if defined(__cplusplus) && !defined(CINTERFACE)
MIDL_INTERFACE("fdf01a76-1e11-450f-902b-74f04ea08094")
DirectMLWebNNCreatorID : public IUnknown
{
public:
};
#else /* C style interface */
typedef struct DirectMLWebNNCreatorIDVtbl
{
BEGIN_INTERFACE
DECLSPEC_XFGVIRT(IUnknown, QueryInterface)
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
DirectMLWebNNCreatorID * This,
REFIID riid,
_COM_Outptr_ void **ppvObject);
DECLSPEC_XFGVIRT(IUnknown, AddRef)
ULONG ( STDMETHODCALLTYPE *AddRef )(
DirectMLWebNNCreatorID * This);
DECLSPEC_XFGVIRT(IUnknown, Release)
ULONG ( STDMETHODCALLTYPE *Release )(
DirectMLWebNNCreatorID * This);
END_INTERFACE
} DirectMLWebNNCreatorIDVtbl;
interface DirectMLWebNNCreatorID
{
CONST_VTBL struct DirectMLWebNNCreatorIDVtbl *lpVtbl;
};
#ifdef COBJMACROS
#define DirectMLWebNNCreatorID_QueryInterface(This,riid,ppvObject) \
( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
#define DirectMLWebNNCreatorID_AddRef(This) \
( (This)->lpVtbl -> AddRef(This) )
#define DirectMLWebNNCreatorID_Release(This) \
( (This)->lpVtbl -> Release(This) )
#endif /* COBJMACROS */
#endif /* C style interface */
#endif /* __DirectMLWebNNCreatorID_INTERFACE_DEFINED__ */
/* interface __MIDL_itf_d3d12compatibility_0000_0009 */
/* [local] */
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_GAMES) */
#pragma endregion
DEFINE_GUID(IID_ID3D12CompatibilityDevice,0x8f1c0e3c,0xfae3,0x4a82,0xb0,0x98,0xbf,0xe1,0x70,0x82,0x07,0xff);
DEFINE_GUID(IID_D3D11On12CreatorID,0xedbf5678,0x2960,0x4e81,0x84,0x29,0x99,0xd4,0xb2,0x63,0x0c,0x4e);
DEFINE_GUID(IID_D3D9On12CreatorID,0xfffcbb7f,0x15d3,0x42a2,0x84,0x1e,0x9d,0x8d,0x32,0xf3,0x7d,0xdd);
DEFINE_GUID(IID_OpenGLOn12CreatorID,0x6bb3cd34,0x0d19,0x45ab,0x97,0xed,0xd7,0x20,0xba,0x3d,0xfc,0x80);
DEFINE_GUID(IID_OpenCLOn12CreatorID,0x3f76bb74,0x91b5,0x4a88,0xb1,0x26,0x20,0xca,0x03,0x31,0xcd,0x60);
DEFINE_GUID(IID_VulkanOn12CreatorID,0xbc806e01,0x3052,0x406c,0xa3,0xe8,0x9f,0xc0,0x7f,0x04,0x8f,0x98);
DEFINE_GUID(IID_DirectMLTensorFlowCreatorID,0xcb7490ac,0x8a0f,0x44ec,0x9b,0x7b,0x6f,0x4c,0xaf,0xe8,0xe9,0xab);
DEFINE_GUID(IID_DirectMLPyTorchCreatorID,0xaf029192,0xfba1,0x4b05,0x91,0x16,0x23,0x5e,0x06,0x56,0x03,0x54);
DEFINE_GUID(IID_DirectMLWebNNCreatorID,0xfdf01a76,0x1e11,0x450f,0x90,0x2b,0x74,0xf0,0x4e,0xa0,0x80,0x94);
extern RPC_IF_HANDLE __MIDL_itf_d3d12compatibility_0000_0009_v0_0_c_ifspec;
extern RPC_IF_HANDLE __MIDL_itf_d3d12compatibility_0000_0009_v0_0_s_ifspec;
/* Additional Prototypes for ALL interfaces */
/* end of Additional Prototypes */
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,100 @@
/*-------------------------------------------------------------------------------------
*
* Copyright (c) Microsoft Corporation
* Licensed under the MIT license
*
*-------------------------------------------------------------------------------------*/
import "oaidl.idl";
import "ocidl.idl";
import "d3d11on12.idl";
cpp_quote("#include <winapifamily.h>")
#pragma region Desktop Family
cpp_quote("#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_GAMES)")
typedef enum D3D12_COMPATIBILITY_SHARED_FLAGS
{
D3D12_COMPATIBILITY_SHARED_FLAG_NONE = 0,
D3D12_COMPATIBILITY_SHARED_FLAG_NON_NT_HANDLE = 0x1,
D3D12_COMPATIBILITY_SHARED_FLAG_KEYED_MUTEX = 0x2,
D3D12_COMPATIBILITY_SHARED_FLAG_9_ON_12 = 0x4,
} D3D12_COMPATIBILITY_SHARED_FLAGS;
cpp_quote( "DEFINE_ENUM_FLAG_OPERATORS( D3D12_COMPATIBILITY_SHARED_FLAGS )" )
typedef enum D3D12_REFLECT_SHARED_PROPERTY
{
D3D12_REFLECT_SHARED_PROPERTY_D3D11_RESOURCE_FLAGS, // D3D11_RESOURCE_FLAGS
D3D12_REFELCT_SHARED_PROPERTY_COMPATIBILITY_SHARED_FLAGS, // D3D12_COMPATIBILITY_SHARED_FLAGS
D3D12_REFLECT_SHARED_PROPERTY_NON_NT_SHARED_HANDLE, // HANDLE
} D3D12_REFLECT_SHARED_PROPERTY;
[ uuid( 8f1c0e3c-fae3-4a82-b098-bfe1708207ff ), object, local, pointer_default( unique ) ]
interface ID3D12CompatibilityDevice
: IUnknown
{
HRESULT CreateSharedResource(
[annotation("_In_")] const D3D12_HEAP_PROPERTIES* pHeapProperties,
D3D12_HEAP_FLAGS HeapFlags,
[annotation("_In_")] const D3D12_RESOURCE_DESC* pDesc,
D3D12_RESOURCE_STATES InitialResourceState,
[annotation("_In_opt_")] const D3D12_CLEAR_VALUE* pOptimizedClearValue,
[annotation("_In_opt_")] const D3D11_RESOURCE_FLAGS* pFlags11,
D3D12_COMPATIBILITY_SHARED_FLAGS CompatibilityFlags,
[annotation("_In_opt_")] ID3D12LifetimeTracker* pLifetimeTracker,
[annotation("_In_opt_")] ID3D12SwapChainAssistant* pOwningSwapchain,
REFIID riid,
[out, iid_is(riid), annotation("_COM_Outptr_opt_")] void** ppResource);
HRESULT CreateSharedHeap(
[annotation("_In_")] const D3D12_HEAP_DESC* pHeapDesc,
D3D12_COMPATIBILITY_SHARED_FLAGS CompatibilityFlags,
REFIID riid,
[out, iid_is(riid), annotation("_COM_Outptr_opt_")] void** ppHeap);
HRESULT ReflectSharedProperties(
[annotation("_In_")] ID3D12Object* pHeapOrResource,
D3D12_REFLECT_SHARED_PROPERTY ReflectType,
[annotation("_Out_writes_bytes_(DataSize)")] void* pData,
UINT DataSize);
}
[uuid(edbf5678-2960-4e81-8429-99d4b2630c4e), object, local, pointer_default(unique)]
interface D3D11On12CreatorID : IUnknown { };
[uuid(fffcbb7f-15d3-42a2-841e-9d8d32f37ddd), object, local, pointer_default(unique)]
interface D3D9On12CreatorID : IUnknown { };
[uuid(6bb3cd34-0d19-45ab-97ed-d720ba3dfc80), object, local, pointer_default(unique)]
interface OpenGLOn12CreatorID : IUnknown { };
[uuid(3f76bb74-91b5-4a88-b126-20ca0331cd60), object, local, pointer_default(unique)]
interface OpenCLOn12CreatorID : IUnknown { };
[uuid(bc806e01-3052-406c-a3e8-9fc07f048f98), object, local, pointer_default(unique)]
interface VulkanOn12CreatorID : IUnknown { };
[uuid(cb7490ac-8a0f-44ec-9b7b-6f4cafe8e9ab), object, local, pointer_default(unique)]
interface DirectMLTensorFlowCreatorID : IUnknown { };
[uuid(af029192-fba1-4b05-9116-235e06560354), object, local, pointer_default(unique)]
interface DirectMLPyTorchCreatorID : IUnknown { };
[uuid(fdf01a76-1e11-450f-902b-74f04ea08094), object, local, pointer_default(unique)]
interface DirectMLWebNNCreatorID : IUnknown { };
cpp_quote("#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_GAMES) */")
#pragma endregion
cpp_quote( "DEFINE_GUID(IID_ID3D12CompatibilityDevice,0x8f1c0e3c,0xfae3,0x4a82,0xb0,0x98,0xbf,0xe1,0x70,0x82,0x07,0xff);" )
cpp_quote( "DEFINE_GUID(IID_D3D11On12CreatorID,0xedbf5678,0x2960,0x4e81,0x84,0x29,0x99,0xd4,0xb2,0x63,0x0c,0x4e);" )
cpp_quote( "DEFINE_GUID(IID_D3D9On12CreatorID,0xfffcbb7f,0x15d3,0x42a2,0x84,0x1e,0x9d,0x8d,0x32,0xf3,0x7d,0xdd);" )
cpp_quote( "DEFINE_GUID(IID_OpenGLOn12CreatorID,0x6bb3cd34,0x0d19,0x45ab,0x97,0xed,0xd7,0x20,0xba,0x3d,0xfc,0x80);" )
cpp_quote( "DEFINE_GUID(IID_OpenCLOn12CreatorID,0x3f76bb74,0x91b5,0x4a88,0xb1,0x26,0x20,0xca,0x03,0x31,0xcd,0x60);" )
cpp_quote( "DEFINE_GUID(IID_VulkanOn12CreatorID,0xbc806e01,0x3052,0x406c,0xa3,0xe8,0x9f,0xc0,0x7f,0x04,0x8f,0x98);" )
cpp_quote( "DEFINE_GUID(IID_DirectMLTensorFlowCreatorID,0xcb7490ac,0x8a0f,0x44ec,0x9b,0x7b,0x6f,0x4c,0xaf,0xe8,0xe9,0xab);" )
cpp_quote( "DEFINE_GUID(IID_DirectMLPyTorchCreatorID,0xaf029192,0xfba1,0x4b05,0x91,0x16,0x23,0x5e,0x06,0x56,0x03,0x54);" )
cpp_quote( "DEFINE_GUID(IID_DirectMLWebNNCreatorID,0xfdf01a76,0x1e11,0x450f,0x90,0x2b,0x74,0xf0,0x4e,0xa0,0x80,0x94);" )

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,494 @@
//////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
//
// File: D3D12Shader.h
// Content: D3D12 Shader Types and APIs
//
//////////////////////////////////////////////////////////////////////////////
#ifndef __D3D12SHADER_H__
#define __D3D12SHADER_H__
#include "d3dcommon.h"
typedef enum D3D12_SHADER_VERSION_TYPE
{
D3D12_SHVER_PIXEL_SHADER = 0,
D3D12_SHVER_VERTEX_SHADER = 1,
D3D12_SHVER_GEOMETRY_SHADER = 2,
// D3D11 Shaders
D3D12_SHVER_HULL_SHADER = 3,
D3D12_SHVER_DOMAIN_SHADER = 4,
D3D12_SHVER_COMPUTE_SHADER = 5,
// D3D12 Shaders
D3D12_SHVER_LIBRARY = 6,
D3D12_SHVER_RAY_GENERATION_SHADER = 7,
D3D12_SHVER_INTERSECTION_SHADER = 8,
D3D12_SHVER_ANY_HIT_SHADER = 9,
D3D12_SHVER_CLOSEST_HIT_SHADER = 10,
D3D12_SHVER_MISS_SHADER = 11,
D3D12_SHVER_CALLABLE_SHADER = 12,
D3D12_SHVER_MESH_SHADER = 13,
D3D12_SHVER_AMPLIFICATION_SHADER = 14,
D3D12_SHVER_NODE_SHADER = 15,
D3D12_SHVER_RESERVED0 = 0xFFF0,
} D3D12_SHADER_VERSION_TYPE;
#define D3D12_SHVER_GET_TYPE(_Version) \
(((_Version) >> 16) & 0xffff)
#define D3D12_SHVER_GET_MAJOR(_Version) \
(((_Version) >> 4) & 0xf)
#define D3D12_SHVER_GET_MINOR(_Version) \
(((_Version) >> 0) & 0xf)
// Slot ID for library function return
#define D3D_RETURN_PARAMETER_INDEX (-1)
typedef D3D_RESOURCE_RETURN_TYPE D3D12_RESOURCE_RETURN_TYPE;
typedef D3D_CBUFFER_TYPE D3D12_CBUFFER_TYPE;
typedef struct _D3D12_SIGNATURE_PARAMETER_DESC
{
LPCSTR SemanticName; // Name of the semantic
UINT SemanticIndex; // Index of the semantic
UINT Register; // Number of member variables
D3D_NAME SystemValueType;// A predefined system value, or D3D_NAME_UNDEFINED if not applicable
D3D_REGISTER_COMPONENT_TYPE ComponentType; // Scalar type (e.g. uint, float, etc.)
BYTE Mask; // Mask to indicate which components of the register
// are used (combination of D3D10_COMPONENT_MASK values)
BYTE ReadWriteMask; // Mask to indicate whether a given component is
// never written (if this is an output signature) or
// always read (if this is an input signature).
// (combination of D3D_MASK_* values)
UINT Stream; // Stream index
D3D_MIN_PRECISION MinPrecision; // Minimum desired interpolation precision
} D3D12_SIGNATURE_PARAMETER_DESC;
typedef struct _D3D12_SHADER_BUFFER_DESC
{
LPCSTR Name; // Name of the constant buffer
D3D_CBUFFER_TYPE Type; // Indicates type of buffer content
UINT Variables; // Number of member variables
UINT Size; // Size of CB (in bytes)
UINT uFlags; // Buffer description flags
} D3D12_SHADER_BUFFER_DESC;
typedef struct _D3D12_SHADER_VARIABLE_DESC
{
LPCSTR Name; // Name of the variable
UINT StartOffset; // Offset in constant buffer's backing store
UINT Size; // Size of variable (in bytes)
UINT uFlags; // Variable flags
LPVOID DefaultValue; // Raw pointer to default value
UINT StartTexture; // First texture index (or -1 if no textures used)
UINT TextureSize; // Number of texture slots possibly used.
UINT StartSampler; // First sampler index (or -1 if no textures used)
UINT SamplerSize; // Number of sampler slots possibly used.
} D3D12_SHADER_VARIABLE_DESC;
typedef struct _D3D12_SHADER_TYPE_DESC
{
D3D_SHADER_VARIABLE_CLASS Class; // Variable class (e.g. object, matrix, etc.)
D3D_SHADER_VARIABLE_TYPE Type; // Variable type (e.g. float, sampler, etc.)
UINT Rows; // Number of rows (for matrices, 1 for other numeric, 0 if not applicable)
UINT Columns; // Number of columns (for vectors & matrices, 1 for other numeric, 0 if not applicable)
UINT Elements; // Number of elements (0 if not an array)
UINT Members; // Number of members (0 if not a structure)
UINT Offset; // Offset from the start of structure (0 if not a structure member)
LPCSTR Name; // Name of type, can be NULL
} D3D12_SHADER_TYPE_DESC;
typedef D3D_TESSELLATOR_DOMAIN D3D12_TESSELLATOR_DOMAIN;
typedef D3D_TESSELLATOR_PARTITIONING D3D12_TESSELLATOR_PARTITIONING;
typedef D3D_TESSELLATOR_OUTPUT_PRIMITIVE D3D12_TESSELLATOR_OUTPUT_PRIMITIVE;
typedef struct _D3D12_SHADER_DESC
{
UINT Version; // Shader version
LPCSTR Creator; // Creator string
UINT Flags; // Shader compilation/parse flags
UINT ConstantBuffers; // Number of constant buffers
UINT BoundResources; // Number of bound resources
UINT InputParameters; // Number of parameters in the input signature
UINT OutputParameters; // Number of parameters in the output signature
UINT InstructionCount; // Number of emitted instructions
UINT TempRegisterCount; // Number of temporary registers used
UINT TempArrayCount; // Number of temporary arrays used
UINT DefCount; // Number of constant defines
UINT DclCount; // Number of declarations (input + output)
UINT TextureNormalInstructions; // Number of non-categorized texture instructions
UINT TextureLoadInstructions; // Number of texture load instructions
UINT TextureCompInstructions; // Number of texture comparison instructions
UINT TextureBiasInstructions; // Number of texture bias instructions
UINT TextureGradientInstructions; // Number of texture gradient instructions
UINT FloatInstructionCount; // Number of floating point arithmetic instructions used
UINT IntInstructionCount; // Number of signed integer arithmetic instructions used
UINT UintInstructionCount; // Number of unsigned integer arithmetic instructions used
UINT StaticFlowControlCount; // Number of static flow control instructions used
UINT DynamicFlowControlCount; // Number of dynamic flow control instructions used
UINT MacroInstructionCount; // Number of macro instructions used
UINT ArrayInstructionCount; // Number of array instructions used
UINT CutInstructionCount; // Number of cut instructions used
UINT EmitInstructionCount; // Number of emit instructions used
D3D_PRIMITIVE_TOPOLOGY GSOutputTopology; // Geometry shader output topology
UINT GSMaxOutputVertexCount; // Geometry shader maximum output vertex count
D3D_PRIMITIVE InputPrimitive; // GS/HS input primitive
UINT PatchConstantParameters; // Number of parameters in the patch constant signature
UINT cGSInstanceCount; // Number of Geometry shader instances
UINT cControlPoints; // Number of control points in the HS->DS stage
D3D_TESSELLATOR_OUTPUT_PRIMITIVE HSOutputPrimitive; // Primitive output by the tessellator
D3D_TESSELLATOR_PARTITIONING HSPartitioning; // Partitioning mode of the tessellator
D3D_TESSELLATOR_DOMAIN TessellatorDomain; // Domain of the tessellator (quad, tri, isoline)
// instruction counts
UINT cBarrierInstructions; // Number of barrier instructions in a compute shader
UINT cInterlockedInstructions; // Number of interlocked instructions
UINT cTextureStoreInstructions; // Number of texture writes
} D3D12_SHADER_DESC;
typedef struct _D3D12_SHADER_INPUT_BIND_DESC
{
LPCSTR Name; // Name of the resource
D3D_SHADER_INPUT_TYPE Type; // Type of resource (e.g. texture, cbuffer, etc.)
UINT BindPoint; // Starting bind point
UINT BindCount; // Number of contiguous bind points (for arrays)
UINT uFlags; // Input binding flags
D3D_RESOURCE_RETURN_TYPE ReturnType; // Return type (if texture)
D3D_SRV_DIMENSION Dimension; // Dimension (if texture)
UINT NumSamples; // Number of samples (0 if not MS texture)
UINT Space; // Register space
UINT uID; // Range ID in the bytecode
} D3D12_SHADER_INPUT_BIND_DESC;
#define D3D_SHADER_REQUIRES_DOUBLES 0x00000001
#define D3D_SHADER_REQUIRES_EARLY_DEPTH_STENCIL 0x00000002
#define D3D_SHADER_REQUIRES_UAVS_AT_EVERY_STAGE 0x00000004
#define D3D_SHADER_REQUIRES_64_UAVS 0x00000008
#define D3D_SHADER_REQUIRES_MINIMUM_PRECISION 0x00000010
#define D3D_SHADER_REQUIRES_11_1_DOUBLE_EXTENSIONS 0x00000020
#define D3D_SHADER_REQUIRES_11_1_SHADER_EXTENSIONS 0x00000040
#define D3D_SHADER_REQUIRES_LEVEL_9_COMPARISON_FILTERING 0x00000080
#define D3D_SHADER_REQUIRES_TILED_RESOURCES 0x00000100
#define D3D_SHADER_REQUIRES_STENCIL_REF 0x00000200
#define D3D_SHADER_REQUIRES_INNER_COVERAGE 0x00000400
#define D3D_SHADER_REQUIRES_TYPED_UAV_LOAD_ADDITIONAL_FORMATS 0x00000800
#define D3D_SHADER_REQUIRES_ROVS 0x00001000
#define D3D_SHADER_REQUIRES_VIEWPORT_AND_RT_ARRAY_INDEX_FROM_ANY_SHADER_FEEDING_RASTERIZER 0x00002000
#define D3D_SHADER_REQUIRES_WAVE_OPS 0x00004000
#define D3D_SHADER_REQUIRES_INT64_OPS 0x00008000
#define D3D_SHADER_REQUIRES_VIEW_ID 0x00010000
#define D3D_SHADER_REQUIRES_BARYCENTRICS 0x00020000
#define D3D_SHADER_REQUIRES_NATIVE_16BIT_OPS 0x00040000
#define D3D_SHADER_REQUIRES_SHADING_RATE 0x00080000
#define D3D_SHADER_REQUIRES_RAYTRACING_TIER_1_1 0x00100000
#define D3D_SHADER_REQUIRES_SAMPLER_FEEDBACK 0x00200000
#define D3D_SHADER_REQUIRES_ATOMIC_INT64_ON_TYPED_RESOURCE 0x00400000
#define D3D_SHADER_REQUIRES_ATOMIC_INT64_ON_GROUP_SHARED 0x00800000
#define D3D_SHADER_REQUIRES_DERIVATIVES_IN_MESH_AND_AMPLIFICATION_SHADERS 0x01000000
#define D3D_SHADER_REQUIRES_RESOURCE_DESCRIPTOR_HEAP_INDEXING 0x02000000
#define D3D_SHADER_REQUIRES_SAMPLER_DESCRIPTOR_HEAP_INDEXING 0x04000000
#define D3D_SHADER_REQUIRES_WAVE_MMA 0x08000000
#define D3D_SHADER_REQUIRES_ATOMIC_INT64_ON_DESCRIPTOR_HEAP_RESOURCE 0x10000000
#define D3D_SHADER_REQUIRES_ADVANCED_TEXTURE_OPS 0x20000000
#define D3D_SHADER_REQUIRES_WRITEABLE_MSAA_TEXTURES 0x40000000
#define D3D_SHADER_REQUIRES_SAMPLE_CMP_GRADIENT_OR_BIAS 0x80000000
#define D3D_SHADER_REQUIRES_EXTENDED_COMMAND_INFO 0x100000000ull
typedef struct _D3D12_LIBRARY_DESC
{
LPCSTR Creator; // The name of the originator of the library.
UINT Flags; // Compilation flags.
UINT FunctionCount; // Number of functions exported from the library.
} D3D12_LIBRARY_DESC;
typedef struct _D3D12_FUNCTION_DESC
{
UINT Version; // Shader version
LPCSTR Creator; // Creator string
UINT Flags; // Shader compilation/parse flags
UINT ConstantBuffers; // Number of constant buffers
UINT BoundResources; // Number of bound resources
UINT InstructionCount; // Number of emitted instructions
UINT TempRegisterCount; // Number of temporary registers used
UINT TempArrayCount; // Number of temporary arrays used
UINT DefCount; // Number of constant defines
UINT DclCount; // Number of declarations (input + output)
UINT TextureNormalInstructions; // Number of non-categorized texture instructions
UINT TextureLoadInstructions; // Number of texture load instructions
UINT TextureCompInstructions; // Number of texture comparison instructions
UINT TextureBiasInstructions; // Number of texture bias instructions
UINT TextureGradientInstructions; // Number of texture gradient instructions
UINT FloatInstructionCount; // Number of floating point arithmetic instructions used
UINT IntInstructionCount; // Number of signed integer arithmetic instructions used
UINT UintInstructionCount; // Number of unsigned integer arithmetic instructions used
UINT StaticFlowControlCount; // Number of static flow control instructions used
UINT DynamicFlowControlCount; // Number of dynamic flow control instructions used
UINT MacroInstructionCount; // Number of macro instructions used
UINT ArrayInstructionCount; // Number of array instructions used
UINT MovInstructionCount; // Number of mov instructions used
UINT MovcInstructionCount; // Number of movc instructions used
UINT ConversionInstructionCount; // Number of type conversion instructions used
UINT BitwiseInstructionCount; // Number of bitwise arithmetic instructions used
D3D_FEATURE_LEVEL MinFeatureLevel; // Min target of the function byte code
UINT64 RequiredFeatureFlags; // Required feature flags
LPCSTR Name; // Function name
INT FunctionParameterCount; // Number of logical parameters in the function signature (not including return)
BOOL HasReturn; // TRUE, if function returns a value, false - it is a subroutine
BOOL Has10Level9VertexShader; // TRUE, if there is a 10L9 VS blob
BOOL Has10Level9PixelShader; // TRUE, if there is a 10L9 PS blob
} D3D12_FUNCTION_DESC;
typedef struct _D3D12_PARAMETER_DESC
{
LPCSTR Name; // Parameter name.
LPCSTR SemanticName; // Parameter semantic name (+index).
D3D_SHADER_VARIABLE_TYPE Type; // Element type.
D3D_SHADER_VARIABLE_CLASS Class; // Scalar/Vector/Matrix.
UINT Rows; // Rows are for matrix parameters.
UINT Columns; // Components or Columns in matrix.
D3D_INTERPOLATION_MODE InterpolationMode; // Interpolation mode.
D3D_PARAMETER_FLAGS Flags; // Parameter modifiers.
UINT FirstInRegister; // The first input register for this parameter.
UINT FirstInComponent; // The first input register component for this parameter.
UINT FirstOutRegister; // The first output register for this parameter.
UINT FirstOutComponent; // The first output register component for this parameter.
} D3D12_PARAMETER_DESC;
//////////////////////////////////////////////////////////////////////////////
// Interfaces ////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
typedef interface ID3D12ShaderReflectionType ID3D12ShaderReflectionType;
typedef interface ID3D12ShaderReflectionType *LPD3D12SHADERREFLECTIONTYPE;
typedef interface ID3D12ShaderReflectionVariable ID3D12ShaderReflectionVariable;
typedef interface ID3D12ShaderReflectionVariable *LPD3D12SHADERREFLECTIONVARIABLE;
typedef interface ID3D12ShaderReflectionConstantBuffer ID3D12ShaderReflectionConstantBuffer;
typedef interface ID3D12ShaderReflectionConstantBuffer *LPD3D12SHADERREFLECTIONCONSTANTBUFFER;
typedef interface ID3D12ShaderReflection ID3D12ShaderReflection;
typedef interface ID3D12ShaderReflection *LPD3D12SHADERREFLECTION;
typedef interface ID3D12LibraryReflection ID3D12LibraryReflection;
typedef interface ID3D12LibraryReflection *LPD3D12LIBRARYREFLECTION;
typedef interface ID3D12FunctionReflection ID3D12FunctionReflection;
typedef interface ID3D12FunctionReflection *LPD3D12FUNCTIONREFLECTION;
typedef interface ID3D12FunctionParameterReflection ID3D12FunctionParameterReflection;
typedef interface ID3D12FunctionParameterReflection *LPD3D12FUNCTIONPARAMETERREFLECTION;
// {E913C351-783D-48CA-A1D1-4F306284AD56}
interface DECLSPEC_UUID("E913C351-783D-48CA-A1D1-4F306284AD56") ID3D12ShaderReflectionType;
DEFINE_GUID(IID_ID3D12ShaderReflectionType,
0xe913c351, 0x783d, 0x48ca, 0xa1, 0xd1, 0x4f, 0x30, 0x62, 0x84, 0xad, 0x56);
#undef INTERFACE
#define INTERFACE ID3D12ShaderReflectionType
DECLARE_INTERFACE(ID3D12ShaderReflectionType)
{
STDMETHOD(GetDesc)(THIS_ _Out_ D3D12_SHADER_TYPE_DESC *pDesc) PURE;
STDMETHOD_(ID3D12ShaderReflectionType*, GetMemberTypeByIndex)(THIS_ _In_ UINT Index) PURE;
STDMETHOD_(ID3D12ShaderReflectionType*, GetMemberTypeByName)(THIS_ _In_ LPCSTR Name) PURE;
STDMETHOD_(LPCSTR, GetMemberTypeName)(THIS_ _In_ UINT Index) PURE;
STDMETHOD(IsEqual)(THIS_ _In_ ID3D12ShaderReflectionType* pType) PURE;
STDMETHOD_(ID3D12ShaderReflectionType*, GetSubType)(THIS) PURE;
STDMETHOD_(ID3D12ShaderReflectionType*, GetBaseClass)(THIS) PURE;
STDMETHOD_(UINT, GetNumInterfaces)(THIS) PURE;
STDMETHOD_(ID3D12ShaderReflectionType*, GetInterfaceByIndex)(THIS_ _In_ UINT uIndex) PURE;
STDMETHOD(IsOfType)(THIS_ _In_ ID3D12ShaderReflectionType* pType) PURE;
STDMETHOD(ImplementsInterface)(THIS_ _In_ ID3D12ShaderReflectionType* pBase) PURE;
};
// {8337A8A6-A216-444A-B2F4-314733A73AEA}
interface DECLSPEC_UUID("8337A8A6-A216-444A-B2F4-314733A73AEA") ID3D12ShaderReflectionVariable;
DEFINE_GUID(IID_ID3D12ShaderReflectionVariable,
0x8337a8a6, 0xa216, 0x444a, 0xb2, 0xf4, 0x31, 0x47, 0x33, 0xa7, 0x3a, 0xea);
#undef INTERFACE
#define INTERFACE ID3D12ShaderReflectionVariable
DECLARE_INTERFACE(ID3D12ShaderReflectionVariable)
{
STDMETHOD(GetDesc)(THIS_ _Out_ D3D12_SHADER_VARIABLE_DESC *pDesc) PURE;
STDMETHOD_(ID3D12ShaderReflectionType*, GetType)(THIS) PURE;
STDMETHOD_(ID3D12ShaderReflectionConstantBuffer*, GetBuffer)(THIS) PURE;
STDMETHOD_(UINT, GetInterfaceSlot)(THIS_ _In_ UINT uArrayIndex) PURE;
};
// {C59598B4-48B3-4869-B9B1-B1618B14A8B7}
interface DECLSPEC_UUID("C59598B4-48B3-4869-B9B1-B1618B14A8B7") ID3D12ShaderReflectionConstantBuffer;
DEFINE_GUID(IID_ID3D12ShaderReflectionConstantBuffer,
0xc59598b4, 0x48b3, 0x4869, 0xb9, 0xb1, 0xb1, 0x61, 0x8b, 0x14, 0xa8, 0xb7);
#undef INTERFACE
#define INTERFACE ID3D12ShaderReflectionConstantBuffer
DECLARE_INTERFACE(ID3D12ShaderReflectionConstantBuffer)
{
STDMETHOD(GetDesc)(THIS_ D3D12_SHADER_BUFFER_DESC *pDesc) PURE;
STDMETHOD_(ID3D12ShaderReflectionVariable*, GetVariableByIndex)(THIS_ _In_ UINT Index) PURE;
STDMETHOD_(ID3D12ShaderReflectionVariable*, GetVariableByName)(THIS_ _In_ LPCSTR Name) PURE;
};
// The ID3D12ShaderReflection IID may change from SDK version to SDK version
// if the reflection API changes. This prevents new code with the new API
// from working with an old binary. Recompiling with the new header
// will pick up the new IID.
// {5A58797D-A72C-478D-8BA2-EFC6B0EFE88E}
interface DECLSPEC_UUID("5A58797D-A72C-478D-8BA2-EFC6B0EFE88E") ID3D12ShaderReflection;
DEFINE_GUID(IID_ID3D12ShaderReflection,
0x5a58797d, 0xa72c, 0x478d, 0x8b, 0xa2, 0xef, 0xc6, 0xb0, 0xef, 0xe8, 0x8e);
#undef INTERFACE
#define INTERFACE ID3D12ShaderReflection
DECLARE_INTERFACE_(ID3D12ShaderReflection, IUnknown)
{
STDMETHOD(QueryInterface)(THIS_ _In_ REFIID iid,
_Out_ LPVOID *ppv) PURE;
STDMETHOD_(ULONG, AddRef)(THIS) PURE;
STDMETHOD_(ULONG, Release)(THIS) PURE;
STDMETHOD(GetDesc)(THIS_ _Out_ D3D12_SHADER_DESC *pDesc) PURE;
STDMETHOD_(ID3D12ShaderReflectionConstantBuffer*, GetConstantBufferByIndex)(THIS_ _In_ UINT Index) PURE;
STDMETHOD_(ID3D12ShaderReflectionConstantBuffer*, GetConstantBufferByName)(THIS_ _In_ LPCSTR Name) PURE;
STDMETHOD(GetResourceBindingDesc)(THIS_ _In_ UINT ResourceIndex,
_Out_ D3D12_SHADER_INPUT_BIND_DESC *pDesc) PURE;
STDMETHOD(GetInputParameterDesc)(THIS_ _In_ UINT ParameterIndex,
_Out_ D3D12_SIGNATURE_PARAMETER_DESC *pDesc) PURE;
STDMETHOD(GetOutputParameterDesc)(THIS_ _In_ UINT ParameterIndex,
_Out_ D3D12_SIGNATURE_PARAMETER_DESC *pDesc) PURE;
STDMETHOD(GetPatchConstantParameterDesc)(THIS_ _In_ UINT ParameterIndex,
_Out_ D3D12_SIGNATURE_PARAMETER_DESC *pDesc) PURE;
STDMETHOD_(ID3D12ShaderReflectionVariable*, GetVariableByName)(THIS_ _In_ LPCSTR Name) PURE;
STDMETHOD(GetResourceBindingDescByName)(THIS_ _In_ LPCSTR Name,
_Out_ D3D12_SHADER_INPUT_BIND_DESC *pDesc) PURE;
STDMETHOD_(UINT, GetMovInstructionCount)(THIS) PURE;
STDMETHOD_(UINT, GetMovcInstructionCount)(THIS) PURE;
STDMETHOD_(UINT, GetConversionInstructionCount)(THIS) PURE;
STDMETHOD_(UINT, GetBitwiseInstructionCount)(THIS) PURE;
STDMETHOD_(D3D_PRIMITIVE, GetGSInputPrimitive)(THIS) PURE;
STDMETHOD_(BOOL, IsSampleFrequencyShader)(THIS) PURE;
STDMETHOD_(UINT, GetNumInterfaceSlots)(THIS) PURE;
STDMETHOD(GetMinFeatureLevel)(THIS_ _Out_ enum D3D_FEATURE_LEVEL* pLevel) PURE;
STDMETHOD_(UINT, GetThreadGroupSize)(THIS_
_Out_opt_ UINT* pSizeX,
_Out_opt_ UINT* pSizeY,
_Out_opt_ UINT* pSizeZ) PURE;
STDMETHOD_(UINT64, GetRequiresFlags)(THIS) PURE;
};
// {8E349D19-54DB-4A56-9DC9-119D87BDB804}
interface DECLSPEC_UUID("8E349D19-54DB-4A56-9DC9-119D87BDB804") ID3D12LibraryReflection;
DEFINE_GUID(IID_ID3D12LibraryReflection,
0x8e349d19, 0x54db, 0x4a56, 0x9d, 0xc9, 0x11, 0x9d, 0x87, 0xbd, 0xb8, 0x4);
#undef INTERFACE
#define INTERFACE ID3D12LibraryReflection
DECLARE_INTERFACE_(ID3D12LibraryReflection, IUnknown)
{
STDMETHOD(QueryInterface)(THIS_ _In_ REFIID iid, _Out_ LPVOID * ppv) PURE;
STDMETHOD_(ULONG, AddRef)(THIS) PURE;
STDMETHOD_(ULONG, Release)(THIS) PURE;
STDMETHOD(GetDesc)(THIS_ _Out_ D3D12_LIBRARY_DESC * pDesc) PURE;
STDMETHOD_(ID3D12FunctionReflection *, GetFunctionByIndex)(THIS_ _In_ INT FunctionIndex) PURE;
};
// {1108795C-2772-4BA9-B2A8-D464DC7E2799}
interface DECLSPEC_UUID("1108795C-2772-4BA9-B2A8-D464DC7E2799") ID3D12FunctionReflection;
DEFINE_GUID(IID_ID3D12FunctionReflection,
0x1108795c, 0x2772, 0x4ba9, 0xb2, 0xa8, 0xd4, 0x64, 0xdc, 0x7e, 0x27, 0x99);
#undef INTERFACE
#define INTERFACE ID3D12FunctionReflection
DECLARE_INTERFACE(ID3D12FunctionReflection)
{
STDMETHOD(GetDesc)(THIS_ _Out_ D3D12_FUNCTION_DESC * pDesc) PURE;
STDMETHOD_(ID3D12ShaderReflectionConstantBuffer *, GetConstantBufferByIndex)(THIS_ _In_ UINT BufferIndex) PURE;
STDMETHOD_(ID3D12ShaderReflectionConstantBuffer *, GetConstantBufferByName)(THIS_ _In_ LPCSTR Name) PURE;
STDMETHOD(GetResourceBindingDesc)(THIS_ _In_ UINT ResourceIndex,
_Out_ D3D12_SHADER_INPUT_BIND_DESC * pDesc) PURE;
STDMETHOD_(ID3D12ShaderReflectionVariable *, GetVariableByName)(THIS_ _In_ LPCSTR Name) PURE;
STDMETHOD(GetResourceBindingDescByName)(THIS_ _In_ LPCSTR Name,
_Out_ D3D12_SHADER_INPUT_BIND_DESC * pDesc) PURE;
// Use D3D_RETURN_PARAMETER_INDEX to get description of the return value.
STDMETHOD_(ID3D12FunctionParameterReflection *, GetFunctionParameter)(THIS_ _In_ INT ParameterIndex) PURE;
};
// {EC25F42D-7006-4F2B-B33E-02CC3375733F}
interface DECLSPEC_UUID("EC25F42D-7006-4F2B-B33E-02CC3375733F") ID3D12FunctionParameterReflection;
DEFINE_GUID(IID_ID3D12FunctionParameterReflection,
0xec25f42d, 0x7006, 0x4f2b, 0xb3, 0x3e, 0x2, 0xcc, 0x33, 0x75, 0x73, 0x3f);
#undef INTERFACE
#define INTERFACE ID3D12FunctionParameterReflection
DECLARE_INTERFACE(ID3D12FunctionParameterReflection)
{
STDMETHOD(GetDesc)(THIS_ _Out_ D3D12_PARAMETER_DESC * pDesc) PURE;
};
//////////////////////////////////////////////////////////////////////////////
// APIs //////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
#ifdef __cplusplus
extern "C" {
#endif //__cplusplus
#ifdef __cplusplus
}
#endif //__cplusplus
#endif //__D3D12SHADER_H__

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,991 @@
/*-------------------------------------------------------------------------------------
*
* Copyright (c) Microsoft Corporation
* Licensed under the MIT license
*
*-------------------------------------------------------------------------------------*/
import "oaidl.idl";
import "ocidl.idl";
//----------------------------------------------------------------------------
//
// D3D-version-neutral runtime information.
//
//----------------------------------------------------------------------------
typedef enum D3D_DRIVER_TYPE
{
D3D_DRIVER_TYPE_UNKNOWN,
D3D_DRIVER_TYPE_HARDWARE,
D3D_DRIVER_TYPE_REFERENCE,
D3D_DRIVER_TYPE_NULL,
D3D_DRIVER_TYPE_SOFTWARE,
D3D_DRIVER_TYPE_WARP,
} D3D_DRIVER_TYPE;
typedef enum D3D_FEATURE_LEVEL
{
D3D_FEATURE_LEVEL_1_0_GENERIC = 0x100,
D3D_FEATURE_LEVEL_1_0_CORE = 0x1000,
D3D_FEATURE_LEVEL_9_1 = 0x9100,
D3D_FEATURE_LEVEL_9_2 = 0x9200,
D3D_FEATURE_LEVEL_9_3 = 0x9300,
D3D_FEATURE_LEVEL_10_0 = 0xa000,
D3D_FEATURE_LEVEL_10_1 = 0xa100,
D3D_FEATURE_LEVEL_11_0 = 0xb000,
D3D_FEATURE_LEVEL_11_1 = 0xb100,
D3D_FEATURE_LEVEL_12_0 = 0xc000,
D3D_FEATURE_LEVEL_12_1 = 0xc100,
D3D_FEATURE_LEVEL_12_2 = 0xc200
} D3D_FEATURE_LEVEL;
cpp_quote("#define D3D_FL9_1_REQ_TEXTURE1D_U_DIMENSION 2048")
cpp_quote("#define D3D_FL9_3_REQ_TEXTURE1D_U_DIMENSION 4096")
cpp_quote("#define D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION 2048")
cpp_quote("#define D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION 4096")
cpp_quote("#define D3D_FL9_1_REQ_TEXTURECUBE_DIMENSION 512")
cpp_quote("#define D3D_FL9_3_REQ_TEXTURECUBE_DIMENSION 4096")
cpp_quote("#define D3D_FL9_1_REQ_TEXTURE3D_U_V_OR_W_DIMENSION 256")
cpp_quote("#define D3D_FL9_1_DEFAULT_MAX_ANISOTROPY 2")
cpp_quote("#define D3D_FL9_1_IA_PRIMITIVE_MAX_COUNT 65535")
cpp_quote("#define D3D_FL9_2_IA_PRIMITIVE_MAX_COUNT 1048575")
cpp_quote("#define D3D_FL9_1_SIMULTANEOUS_RENDER_TARGET_COUNT 1")
cpp_quote("#define D3D_FL9_3_SIMULTANEOUS_RENDER_TARGET_COUNT 4")
cpp_quote("#define D3D_FL9_1_MAX_TEXTURE_REPEAT 128")
cpp_quote("#define D3D_FL9_2_MAX_TEXTURE_REPEAT 2048")
cpp_quote("#define D3D_FL9_3_MAX_TEXTURE_REPEAT 8192")
typedef enum D3D_PRIMITIVE_TOPOLOGY
{
D3D_PRIMITIVE_TOPOLOGY_UNDEFINED = 0,
D3D_PRIMITIVE_TOPOLOGY_POINTLIST = 1,
D3D_PRIMITIVE_TOPOLOGY_LINELIST = 2,
D3D_PRIMITIVE_TOPOLOGY_LINESTRIP = 3,
D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST = 4,
D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP = 5,
D3D_PRIMITIVE_TOPOLOGY_TRIANGLEFAN = 6,
// Adjacency values should be equal to (0x8 & non-adjacency):
D3D_PRIMITIVE_TOPOLOGY_LINELIST_ADJ = 10,
D3D_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ = 11,
D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ = 12,
D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ = 13,
D3D_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST = 33,
D3D_PRIMITIVE_TOPOLOGY_2_CONTROL_POINT_PATCHLIST = 34,
D3D_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST = 35,
D3D_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST = 36,
D3D_PRIMITIVE_TOPOLOGY_5_CONTROL_POINT_PATCHLIST = 37,
D3D_PRIMITIVE_TOPOLOGY_6_CONTROL_POINT_PATCHLIST = 38,
D3D_PRIMITIVE_TOPOLOGY_7_CONTROL_POINT_PATCHLIST = 39,
D3D_PRIMITIVE_TOPOLOGY_8_CONTROL_POINT_PATCHLIST = 40,
D3D_PRIMITIVE_TOPOLOGY_9_CONTROL_POINT_PATCHLIST = 41,
D3D_PRIMITIVE_TOPOLOGY_10_CONTROL_POINT_PATCHLIST = 42,
D3D_PRIMITIVE_TOPOLOGY_11_CONTROL_POINT_PATCHLIST = 43,
D3D_PRIMITIVE_TOPOLOGY_12_CONTROL_POINT_PATCHLIST = 44,
D3D_PRIMITIVE_TOPOLOGY_13_CONTROL_POINT_PATCHLIST = 45,
D3D_PRIMITIVE_TOPOLOGY_14_CONTROL_POINT_PATCHLIST = 46,
D3D_PRIMITIVE_TOPOLOGY_15_CONTROL_POINT_PATCHLIST = 47,
D3D_PRIMITIVE_TOPOLOGY_16_CONTROL_POINT_PATCHLIST = 48,
D3D_PRIMITIVE_TOPOLOGY_17_CONTROL_POINT_PATCHLIST = 49,
D3D_PRIMITIVE_TOPOLOGY_18_CONTROL_POINT_PATCHLIST = 50,
D3D_PRIMITIVE_TOPOLOGY_19_CONTROL_POINT_PATCHLIST = 51,
D3D_PRIMITIVE_TOPOLOGY_20_CONTROL_POINT_PATCHLIST = 52,
D3D_PRIMITIVE_TOPOLOGY_21_CONTROL_POINT_PATCHLIST = 53,
D3D_PRIMITIVE_TOPOLOGY_22_CONTROL_POINT_PATCHLIST = 54,
D3D_PRIMITIVE_TOPOLOGY_23_CONTROL_POINT_PATCHLIST = 55,
D3D_PRIMITIVE_TOPOLOGY_24_CONTROL_POINT_PATCHLIST = 56,
D3D_PRIMITIVE_TOPOLOGY_25_CONTROL_POINT_PATCHLIST = 57,
D3D_PRIMITIVE_TOPOLOGY_26_CONTROL_POINT_PATCHLIST = 58,
D3D_PRIMITIVE_TOPOLOGY_27_CONTROL_POINT_PATCHLIST = 59,
D3D_PRIMITIVE_TOPOLOGY_28_CONTROL_POINT_PATCHLIST = 60,
D3D_PRIMITIVE_TOPOLOGY_29_CONTROL_POINT_PATCHLIST = 61,
D3D_PRIMITIVE_TOPOLOGY_30_CONTROL_POINT_PATCHLIST = 62,
D3D_PRIMITIVE_TOPOLOGY_31_CONTROL_POINT_PATCHLIST = 63,
D3D_PRIMITIVE_TOPOLOGY_32_CONTROL_POINT_PATCHLIST = 64,
D3D10_PRIMITIVE_TOPOLOGY_UNDEFINED = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED,
D3D10_PRIMITIVE_TOPOLOGY_POINTLIST = D3D_PRIMITIVE_TOPOLOGY_POINTLIST,
D3D10_PRIMITIVE_TOPOLOGY_LINELIST = D3D_PRIMITIVE_TOPOLOGY_LINELIST,
D3D10_PRIMITIVE_TOPOLOGY_LINESTRIP = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP,
D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST,
D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP,
D3D10_PRIMITIVE_TOPOLOGY_LINELIST_ADJ = D3D_PRIMITIVE_TOPOLOGY_LINELIST_ADJ,
D3D10_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ,
D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ,
D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ,
D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED,
D3D11_PRIMITIVE_TOPOLOGY_POINTLIST = D3D_PRIMITIVE_TOPOLOGY_POINTLIST,
D3D11_PRIMITIVE_TOPOLOGY_LINELIST = D3D_PRIMITIVE_TOPOLOGY_LINELIST,
D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP,
D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST,
D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP,
D3D11_PRIMITIVE_TOPOLOGY_LINELIST_ADJ = D3D_PRIMITIVE_TOPOLOGY_LINELIST_ADJ,
D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ,
D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ,
D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ,
D3D11_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_2_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_2_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_5_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_5_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_6_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_6_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_7_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_7_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_8_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_8_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_9_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_9_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_10_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_10_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_11_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_11_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_12_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_12_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_13_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_13_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_14_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_14_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_15_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_15_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_16_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_16_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_17_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_17_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_18_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_18_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_19_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_19_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_20_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_20_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_21_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_21_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_22_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_22_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_23_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_23_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_24_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_24_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_25_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_25_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_26_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_26_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_27_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_27_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_28_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_28_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_29_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_29_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_30_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_30_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_31_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_31_CONTROL_POINT_PATCHLIST,
D3D11_PRIMITIVE_TOPOLOGY_32_CONTROL_POINT_PATCHLIST = D3D_PRIMITIVE_TOPOLOGY_32_CONTROL_POINT_PATCHLIST
} D3D_PRIMITIVE_TOPOLOGY;
typedef enum D3D_PRIMITIVE
{
D3D_PRIMITIVE_UNDEFINED = 0,
D3D_PRIMITIVE_POINT = 1,
D3D_PRIMITIVE_LINE = 2,
D3D_PRIMITIVE_TRIANGLE = 3,
// Adjacency values should be equal to (0x4 & non-adjacency):
D3D_PRIMITIVE_LINE_ADJ = 6,
D3D_PRIMITIVE_TRIANGLE_ADJ = 7,
D3D_PRIMITIVE_1_CONTROL_POINT_PATCH = 8,
D3D_PRIMITIVE_2_CONTROL_POINT_PATCH = 9,
D3D_PRIMITIVE_3_CONTROL_POINT_PATCH = 10,
D3D_PRIMITIVE_4_CONTROL_POINT_PATCH = 11,
D3D_PRIMITIVE_5_CONTROL_POINT_PATCH = 12,
D3D_PRIMITIVE_6_CONTROL_POINT_PATCH = 13,
D3D_PRIMITIVE_7_CONTROL_POINT_PATCH = 14,
D3D_PRIMITIVE_8_CONTROL_POINT_PATCH = 15,
D3D_PRIMITIVE_9_CONTROL_POINT_PATCH = 16,
D3D_PRIMITIVE_10_CONTROL_POINT_PATCH = 17,
D3D_PRIMITIVE_11_CONTROL_POINT_PATCH = 18,
D3D_PRIMITIVE_12_CONTROL_POINT_PATCH = 19,
D3D_PRIMITIVE_13_CONTROL_POINT_PATCH = 20,
D3D_PRIMITIVE_14_CONTROL_POINT_PATCH = 21,
D3D_PRIMITIVE_15_CONTROL_POINT_PATCH = 22,
D3D_PRIMITIVE_16_CONTROL_POINT_PATCH = 23,
D3D_PRIMITIVE_17_CONTROL_POINT_PATCH = 24,
D3D_PRIMITIVE_18_CONTROL_POINT_PATCH = 25,
D3D_PRIMITIVE_19_CONTROL_POINT_PATCH = 26,
D3D_PRIMITIVE_20_CONTROL_POINT_PATCH = 27,
D3D_PRIMITIVE_21_CONTROL_POINT_PATCH = 28,
D3D_PRIMITIVE_22_CONTROL_POINT_PATCH = 29,
D3D_PRIMITIVE_23_CONTROL_POINT_PATCH = 30,
D3D_PRIMITIVE_24_CONTROL_POINT_PATCH = 31,
D3D_PRIMITIVE_25_CONTROL_POINT_PATCH = 32,
D3D_PRIMITIVE_26_CONTROL_POINT_PATCH = 33,
D3D_PRIMITIVE_27_CONTROL_POINT_PATCH = 34,
D3D_PRIMITIVE_28_CONTROL_POINT_PATCH = 35,
D3D_PRIMITIVE_29_CONTROL_POINT_PATCH = 36,
D3D_PRIMITIVE_30_CONTROL_POINT_PATCH = 37,
D3D_PRIMITIVE_31_CONTROL_POINT_PATCH = 38,
D3D_PRIMITIVE_32_CONTROL_POINT_PATCH = 39,
D3D10_PRIMITIVE_UNDEFINED = D3D_PRIMITIVE_UNDEFINED,
D3D10_PRIMITIVE_POINT = D3D_PRIMITIVE_POINT,
D3D10_PRIMITIVE_LINE = D3D_PRIMITIVE_LINE,
D3D10_PRIMITIVE_TRIANGLE = D3D_PRIMITIVE_TRIANGLE,
D3D10_PRIMITIVE_LINE_ADJ = D3D_PRIMITIVE_LINE_ADJ,
D3D10_PRIMITIVE_TRIANGLE_ADJ = D3D_PRIMITIVE_TRIANGLE_ADJ,
D3D11_PRIMITIVE_UNDEFINED = D3D_PRIMITIVE_UNDEFINED,
D3D11_PRIMITIVE_POINT = D3D_PRIMITIVE_POINT,
D3D11_PRIMITIVE_LINE = D3D_PRIMITIVE_LINE,
D3D11_PRIMITIVE_TRIANGLE = D3D_PRIMITIVE_TRIANGLE,
D3D11_PRIMITIVE_LINE_ADJ = D3D_PRIMITIVE_LINE_ADJ,
D3D11_PRIMITIVE_TRIANGLE_ADJ = D3D_PRIMITIVE_TRIANGLE_ADJ,
D3D11_PRIMITIVE_1_CONTROL_POINT_PATCH = D3D_PRIMITIVE_1_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_2_CONTROL_POINT_PATCH = D3D_PRIMITIVE_2_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_3_CONTROL_POINT_PATCH = D3D_PRIMITIVE_3_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_4_CONTROL_POINT_PATCH = D3D_PRIMITIVE_4_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_5_CONTROL_POINT_PATCH = D3D_PRIMITIVE_5_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_6_CONTROL_POINT_PATCH = D3D_PRIMITIVE_6_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_7_CONTROL_POINT_PATCH = D3D_PRIMITIVE_7_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_8_CONTROL_POINT_PATCH = D3D_PRIMITIVE_8_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_9_CONTROL_POINT_PATCH = D3D_PRIMITIVE_9_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_10_CONTROL_POINT_PATCH = D3D_PRIMITIVE_10_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_11_CONTROL_POINT_PATCH = D3D_PRIMITIVE_11_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_12_CONTROL_POINT_PATCH = D3D_PRIMITIVE_12_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_13_CONTROL_POINT_PATCH = D3D_PRIMITIVE_13_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_14_CONTROL_POINT_PATCH = D3D_PRIMITIVE_14_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_15_CONTROL_POINT_PATCH = D3D_PRIMITIVE_15_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_16_CONTROL_POINT_PATCH = D3D_PRIMITIVE_16_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_17_CONTROL_POINT_PATCH = D3D_PRIMITIVE_17_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_18_CONTROL_POINT_PATCH = D3D_PRIMITIVE_18_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_19_CONTROL_POINT_PATCH = D3D_PRIMITIVE_19_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_20_CONTROL_POINT_PATCH = D3D_PRIMITIVE_20_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_21_CONTROL_POINT_PATCH = D3D_PRIMITIVE_21_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_22_CONTROL_POINT_PATCH = D3D_PRIMITIVE_22_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_23_CONTROL_POINT_PATCH = D3D_PRIMITIVE_23_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_24_CONTROL_POINT_PATCH = D3D_PRIMITIVE_24_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_25_CONTROL_POINT_PATCH = D3D_PRIMITIVE_25_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_26_CONTROL_POINT_PATCH = D3D_PRIMITIVE_26_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_27_CONTROL_POINT_PATCH = D3D_PRIMITIVE_27_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_28_CONTROL_POINT_PATCH = D3D_PRIMITIVE_28_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_29_CONTROL_POINT_PATCH = D3D_PRIMITIVE_29_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_30_CONTROL_POINT_PATCH = D3D_PRIMITIVE_30_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_31_CONTROL_POINT_PATCH = D3D_PRIMITIVE_31_CONTROL_POINT_PATCH,
D3D11_PRIMITIVE_32_CONTROL_POINT_PATCH = D3D_PRIMITIVE_32_CONTROL_POINT_PATCH,
} D3D_PRIMITIVE;
typedef enum D3D_SRV_DIMENSION
{
D3D_SRV_DIMENSION_UNKNOWN = 0,
D3D_SRV_DIMENSION_BUFFER = 1,
D3D_SRV_DIMENSION_TEXTURE1D = 2,
D3D_SRV_DIMENSION_TEXTURE1DARRAY = 3,
D3D_SRV_DIMENSION_TEXTURE2D = 4,
D3D_SRV_DIMENSION_TEXTURE2DARRAY = 5,
D3D_SRV_DIMENSION_TEXTURE2DMS = 6,
D3D_SRV_DIMENSION_TEXTURE2DMSARRAY = 7,
D3D_SRV_DIMENSION_TEXTURE3D = 8,
D3D_SRV_DIMENSION_TEXTURECUBE = 9,
D3D_SRV_DIMENSION_TEXTURECUBEARRAY = 10,
D3D_SRV_DIMENSION_BUFFEREX = 11,
D3D10_SRV_DIMENSION_UNKNOWN = D3D_SRV_DIMENSION_UNKNOWN,
D3D10_SRV_DIMENSION_BUFFER = D3D_SRV_DIMENSION_BUFFER,
D3D10_SRV_DIMENSION_TEXTURE1D = D3D_SRV_DIMENSION_TEXTURE1D,
D3D10_SRV_DIMENSION_TEXTURE1DARRAY = D3D_SRV_DIMENSION_TEXTURE1DARRAY,
D3D10_SRV_DIMENSION_TEXTURE2D = D3D_SRV_DIMENSION_TEXTURE2D,
D3D10_SRV_DIMENSION_TEXTURE2DARRAY = D3D_SRV_DIMENSION_TEXTURE2DARRAY,
D3D10_SRV_DIMENSION_TEXTURE2DMS = D3D_SRV_DIMENSION_TEXTURE2DMS,
D3D10_SRV_DIMENSION_TEXTURE2DMSARRAY = D3D_SRV_DIMENSION_TEXTURE2DMSARRAY,
D3D10_SRV_DIMENSION_TEXTURE3D = D3D_SRV_DIMENSION_TEXTURE3D,
D3D10_SRV_DIMENSION_TEXTURECUBE = D3D_SRV_DIMENSION_TEXTURECUBE,
D3D10_1_SRV_DIMENSION_UNKNOWN = D3D_SRV_DIMENSION_UNKNOWN,
D3D10_1_SRV_DIMENSION_BUFFER = D3D_SRV_DIMENSION_BUFFER,
D3D10_1_SRV_DIMENSION_TEXTURE1D = D3D_SRV_DIMENSION_TEXTURE1D,
D3D10_1_SRV_DIMENSION_TEXTURE1DARRAY = D3D_SRV_DIMENSION_TEXTURE1DARRAY,
D3D10_1_SRV_DIMENSION_TEXTURE2D = D3D_SRV_DIMENSION_TEXTURE2D,
D3D10_1_SRV_DIMENSION_TEXTURE2DARRAY = D3D_SRV_DIMENSION_TEXTURE2DARRAY,
D3D10_1_SRV_DIMENSION_TEXTURE2DMS = D3D_SRV_DIMENSION_TEXTURE2DMS,
D3D10_1_SRV_DIMENSION_TEXTURE2DMSARRAY = D3D_SRV_DIMENSION_TEXTURE2DMSARRAY,
D3D10_1_SRV_DIMENSION_TEXTURE3D = D3D_SRV_DIMENSION_TEXTURE3D,
D3D10_1_SRV_DIMENSION_TEXTURECUBE = D3D_SRV_DIMENSION_TEXTURECUBE,
D3D10_1_SRV_DIMENSION_TEXTURECUBEARRAY = D3D_SRV_DIMENSION_TEXTURECUBEARRAY,
D3D11_SRV_DIMENSION_UNKNOWN = D3D_SRV_DIMENSION_UNKNOWN,
D3D11_SRV_DIMENSION_BUFFER = D3D_SRV_DIMENSION_BUFFER,
D3D11_SRV_DIMENSION_TEXTURE1D = D3D_SRV_DIMENSION_TEXTURE1D,
D3D11_SRV_DIMENSION_TEXTURE1DARRAY = D3D_SRV_DIMENSION_TEXTURE1DARRAY,
D3D11_SRV_DIMENSION_TEXTURE2D = D3D_SRV_DIMENSION_TEXTURE2D,
D3D11_SRV_DIMENSION_TEXTURE2DARRAY = D3D_SRV_DIMENSION_TEXTURE2DARRAY,
D3D11_SRV_DIMENSION_TEXTURE2DMS = D3D_SRV_DIMENSION_TEXTURE2DMS,
D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY = D3D_SRV_DIMENSION_TEXTURE2DMSARRAY,
D3D11_SRV_DIMENSION_TEXTURE3D = D3D_SRV_DIMENSION_TEXTURE3D,
D3D11_SRV_DIMENSION_TEXTURECUBE = D3D_SRV_DIMENSION_TEXTURECUBE,
D3D11_SRV_DIMENSION_TEXTURECUBEARRAY = D3D_SRV_DIMENSION_TEXTURECUBEARRAY,
D3D11_SRV_DIMENSION_BUFFEREX = D3D_SRV_DIMENSION_BUFFEREX,
} D3D_SRV_DIMENSION;
// Bits in shaders indicating features they use which the runtime checks against current device support:
cpp_quote("#define D3D_SHADER_FEATURE_DOUBLES 0x00001")
cpp_quote("#define D3D_SHADER_FEATURE_COMPUTE_SHADERS_PLUS_RAW_AND_STRUCTURED_BUFFERS_VIA_SHADER_4_X 0x00002")
cpp_quote("#define D3D_SHADER_FEATURE_UAVS_AT_EVERY_STAGE 0x00004")
cpp_quote("#define D3D_SHADER_FEATURE_64_UAVS 0x00008")
cpp_quote("#define D3D_SHADER_FEATURE_MINIMUM_PRECISION 0x00010")
cpp_quote("#define D3D_SHADER_FEATURE_11_1_DOUBLE_EXTENSIONS 0x00020")
cpp_quote("#define D3D_SHADER_FEATURE_11_1_SHADER_EXTENSIONS 0x00040")
cpp_quote("#define D3D_SHADER_FEATURE_LEVEL_9_COMPARISON_FILTERING 0x00080")
cpp_quote("#define D3D_SHADER_FEATURE_TILED_RESOURCES 0x00100")
cpp_quote("#define D3D_SHADER_FEATURE_STENCIL_REF 0x00200")
cpp_quote("#define D3D_SHADER_FEATURE_INNER_COVERAGE 0x00400")
cpp_quote("#define D3D_SHADER_FEATURE_TYPED_UAV_LOAD_ADDITIONAL_FORMATS 0x00800")
cpp_quote("#define D3D_SHADER_FEATURE_ROVS 0x01000")
cpp_quote("#define D3D_SHADER_FEATURE_VIEWPORT_AND_RT_ARRAY_INDEX_FROM_ANY_SHADER_FEEDING_RASTERIZER 0x02000")
cpp_quote("#define D3D_SHADER_FEATURE_WAVE_OPS 0x04000")
cpp_quote("#define D3D_SHADER_FEATURE_INT64_OPS 0x08000")
cpp_quote("#define D3D_SHADER_FEATURE_VIEW_ID 0x10000")
cpp_quote("#define D3D_SHADER_FEATURE_BARYCENTRICS 0x20000")
cpp_quote("#define D3D_SHADER_FEATURE_NATIVE_16BIT_OPS 0x40000")
cpp_quote("#define D3D_SHADER_FEATURE_SHADING_RATE 0x80000")
cpp_quote("#define D3D_SHADER_FEATURE_RAYTRACING_TIER_1_1 0x100000")
cpp_quote("#define D3D_SHADER_FEATURE_SAMPLER_FEEDBACK 0x200000")
cpp_quote("#define D3D_SHADER_FEATURE_ATOMIC_INT64_ON_TYPED_RESOURCE 0x400000")
cpp_quote("#define D3D_SHADER_FEATURE_ATOMIC_INT64_ON_GROUP_SHARED 0x800000")
cpp_quote("#define D3D_SHADER_FEATURE_DERIVATIVES_IN_MESH_AND_AMPLIFICATION_SHADERS 0x1000000")
cpp_quote("#define D3D_SHADER_FEATURE_RESOURCE_DESCRIPTOR_HEAP_INDEXING 0x2000000")
cpp_quote("#define D3D_SHADER_FEATURE_SAMPLER_DESCRIPTOR_HEAP_INDEXING 0x4000000")
cpp_quote("#define D3D_SHADER_FEATURE_WAVE_MMA 0x8000000")
cpp_quote("#define D3D_SHADER_FEATURE_ATOMIC_INT64_ON_DESCRIPTOR_HEAP_RESOURCE 0x10000000")
cpp_quote("#define D3D_SHADER_FEATURE_ADVANCED_TEXTURE_OPS 0x20000000")
cpp_quote("#define D3D_SHADER_FEATURE_WRITEABLE_MSAA_TEXTURES 0x40000000")
cpp_quote("#define D3D_SHADER_FEATURE_SAMPLE_CMP_GRADIENT_OR_BIAS 0x80000000")
cpp_quote("#define D3D_SHADER_FEATURE_EXTENDED_COMMAND_INFO 0x100000000ull")
// This section is for flags that do not directly indicate a required feature,
// but are used to indicate something about the shader.
// Flag for any derivative use. This allows call-graph validation
// in the runtime to detect misuse of derivatives for an entry point that cannot
// support it, or to determine when the flag
// D3D_SHADER_FEATURE_DERIVATIVES_IN_MESH_AND_AMPLIFICATION_SHADERS is required.
cpp_quote("#define D3D_OPT_SHADER_FEATURE_USES_DERIVATIVES 0x0000010000000000ull")
cpp_quote("#define D3D_OPT_SHADER_FEATURE_REQUIRES_GROUP 0x0000020000000000ull")
// Additional internal shader feature flags are listed in dxbcutils.h (not relevant/useful for public to see)
// When adding entries here, make sure they don't conflict with what's there.
//----------------------------------------------------------------------------
//
// Shader compilation information.
//
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
// D3D_SHADER_MACRO:
// ----------
// Preprocessor macro definition. The application pass in a NULL-terminated
// array of this structure to various D3D APIs. This enables the application
// to #define tokens at runtime, before the file is parsed.
//----------------------------------------------------------------------------
typedef struct _D3D_SHADER_MACRO
{
LPCSTR Name;
LPCSTR Definition;
} D3D_SHADER_MACRO, *LPD3D_SHADER_MACRO;
//----------------------------------------------------------------------------
// ID3DBlob:
// ------------
// The buffer object is used by D3D to return arbitrary size data.
// For compatibility with D3D10 this interface is also called ID3D10Blob,
// but the version-neutral form is preferred.
//
// GetBufferPointer -
// Returns a pointer to the beginning of the buffer.
//
// GetBufferSize -
// Returns the size of the buffer, in bytes.
//----------------------------------------------------------------------------
// {8BA5FB08-5195-40e2-AC58-0D989C3A0102}
cpp_quote("DEFINE_GUID(IID_ID3D10Blob, 0x8ba5fb08, 0x5195, 0x40e2, 0xac, 0x58, 0xd, 0x98, 0x9c, 0x3a, 0x1, 0x2);")
[ uuid( 8BA5FB08-5195-40e2-AC58-0D989C3A0102 ), object, local, pointer_default( unique ) ]
interface ID3D10Blob : IUnknown
{
LPVOID GetBufferPointer();
SIZE_T GetBufferSize();
};
cpp_quote("typedef interface ID3D10Blob* LPD3D10BLOB;")
typedef ID3D10Blob ID3DBlob;
cpp_quote("typedef ID3DBlob* LPD3DBLOB;")
cpp_quote("#define IID_ID3DBlob IID_ID3D10Blob")
// ID3DDestructionNotifier: An interface to QI for, to set a callback which is triggered when the object is fully destroyed
typedef void(__stdcall *PFN_DESTRUCTION_CALLBACK)(void* pData);
[uuid(a06eb39a-50da-425b-8c31-4eecd6c270f3), object, local, pointer_default(unique)]
interface ID3DDestructionNotifier
: IUnknown
{
HRESULT RegisterDestructionCallback(
[annotation("_In_")] PFN_DESTRUCTION_CALLBACK callbackFn,
[annotation("_In_")] void* pData,
[annotation("_Out_")] UINT* pCallbackID
);
HRESULT UnregisterDestructionCallback(
[annotation("_In_")] UINT callbackID
);
};
typedef enum _D3D_INCLUDE_TYPE
{
D3D_INCLUDE_LOCAL,
D3D_INCLUDE_SYSTEM,
D3D10_INCLUDE_LOCAL = D3D_INCLUDE_LOCAL,
D3D10_INCLUDE_SYSTEM = D3D_INCLUDE_SYSTEM,
// force 32-bit size enum
D3D_INCLUDE_FORCE_DWORD = 0x7fffffff
} D3D_INCLUDE_TYPE;
//----------------------------------------------------------------------------
// ID3DInclude:
// -------------
// This interface is intended to be implemented by the application, and can
// be used by various D3D APIs. This enables application-specific handling
// of #include directives in source files.
//
// Open()
// Opens an include file. If successful, it should fill in ppData and
// pBytes. The data pointer returned must remain valid until Close is
// subsequently called. The name of the file is encoded in UTF-8 format.
// Close()
// Closes an include file. If Open was successful, Close is guaranteed
// to be called before the API using this interface returns.
//----------------------------------------------------------------------------
cpp_quote("typedef interface ID3DInclude ID3DInclude;")
cpp_quote("#undef INTERFACE")
cpp_quote("#define INTERFACE ID3DInclude")
cpp_quote("DECLARE_INTERFACE(ID3DInclude)")
cpp_quote("{")
cpp_quote(" STDMETHOD(Open)(THIS_ D3D_INCLUDE_TYPE IncludeType, LPCSTR pFileName, LPCVOID pParentData, LPCVOID *ppData, UINT *pBytes) PURE;")
cpp_quote(" STDMETHOD(Close)(THIS_ LPCVOID pData) PURE;")
cpp_quote("};")
cpp_quote("typedef ID3DInclude* LPD3DINCLUDE;")
//----------------------------------------------------------------------------
//
// Shader reflection information.
//
//----------------------------------------------------------------------------
typedef enum _D3D_SHADER_VARIABLE_CLASS
{
D3D_SVC_SCALAR,
D3D_SVC_VECTOR,
D3D_SVC_MATRIX_ROWS,
D3D_SVC_MATRIX_COLUMNS,
D3D_SVC_OBJECT,
D3D_SVC_STRUCT,
D3D_SVC_INTERFACE_CLASS,
D3D_SVC_INTERFACE_POINTER,
D3D10_SVC_SCALAR = D3D_SVC_SCALAR,
D3D10_SVC_VECTOR = D3D_SVC_VECTOR,
D3D10_SVC_MATRIX_ROWS = D3D_SVC_MATRIX_ROWS,
D3D10_SVC_MATRIX_COLUMNS = D3D_SVC_MATRIX_COLUMNS,
D3D10_SVC_OBJECT = D3D_SVC_OBJECT,
D3D10_SVC_STRUCT = D3D_SVC_STRUCT,
D3D11_SVC_INTERFACE_CLASS = D3D_SVC_INTERFACE_CLASS,
D3D11_SVC_INTERFACE_POINTER = D3D_SVC_INTERFACE_POINTER,
// force 32-bit size enum
D3D_SVC_FORCE_DWORD = 0x7fffffff
} D3D_SHADER_VARIABLE_CLASS;
typedef enum _D3D_SHADER_VARIABLE_FLAGS
{
D3D_SVF_USERPACKED = 1,
D3D_SVF_USED = 2,
D3D_SVF_INTERFACE_POINTER = 4,
D3D_SVF_INTERFACE_PARAMETER = 8,
D3D10_SVF_USERPACKED = D3D_SVF_USERPACKED,
D3D10_SVF_USED = D3D_SVF_USED,
D3D11_SVF_INTERFACE_POINTER = D3D_SVF_INTERFACE_POINTER,
D3D11_SVF_INTERFACE_PARAMETER = D3D_SVF_INTERFACE_PARAMETER,
// force 32-bit size enum
D3D_SVF_FORCE_DWORD = 0x7fffffff
} D3D_SHADER_VARIABLE_FLAGS;
typedef enum _D3D_SHADER_VARIABLE_TYPE
{
D3D_SVT_VOID = 0,
D3D_SVT_BOOL = 1,
D3D_SVT_INT = 2,
D3D_SVT_FLOAT = 3,
D3D_SVT_STRING = 4,
D3D_SVT_TEXTURE = 5,
D3D_SVT_TEXTURE1D = 6,
D3D_SVT_TEXTURE2D = 7,
D3D_SVT_TEXTURE3D = 8,
D3D_SVT_TEXTURECUBE = 9,
D3D_SVT_SAMPLER = 10,
D3D_SVT_SAMPLER1D = 11,
D3D_SVT_SAMPLER2D = 12,
D3D_SVT_SAMPLER3D = 13,
D3D_SVT_SAMPLERCUBE = 14,
D3D_SVT_PIXELSHADER = 15,
D3D_SVT_VERTEXSHADER = 16,
D3D_SVT_PIXELFRAGMENT = 17,
D3D_SVT_VERTEXFRAGMENT = 18,
D3D_SVT_UINT = 19,
D3D_SVT_UINT8 = 20,
D3D_SVT_GEOMETRYSHADER = 21,
D3D_SVT_RASTERIZER = 22,
D3D_SVT_DEPTHSTENCIL = 23,
D3D_SVT_BLEND = 24,
D3D_SVT_BUFFER = 25,
D3D_SVT_CBUFFER = 26,
D3D_SVT_TBUFFER = 27,
D3D_SVT_TEXTURE1DARRAY = 28,
D3D_SVT_TEXTURE2DARRAY = 29,
D3D_SVT_RENDERTARGETVIEW = 30,
D3D_SVT_DEPTHSTENCILVIEW = 31,
D3D_SVT_TEXTURE2DMS = 32,
D3D_SVT_TEXTURE2DMSARRAY = 33,
D3D_SVT_TEXTURECUBEARRAY = 34,
D3D_SVT_HULLSHADER = 35,
D3D_SVT_DOMAINSHADER = 36,
D3D_SVT_INTERFACE_POINTER = 37,
D3D_SVT_COMPUTESHADER = 38,
D3D_SVT_DOUBLE = 39,
D3D_SVT_RWTEXTURE1D = 40,
D3D_SVT_RWTEXTURE1DARRAY = 41,
D3D_SVT_RWTEXTURE2D = 42,
D3D_SVT_RWTEXTURE2DARRAY = 43,
D3D_SVT_RWTEXTURE3D = 44,
D3D_SVT_RWBUFFER = 45,
D3D_SVT_BYTEADDRESS_BUFFER = 46,
D3D_SVT_RWBYTEADDRESS_BUFFER = 47,
D3D_SVT_STRUCTURED_BUFFER = 48,
D3D_SVT_RWSTRUCTURED_BUFFER = 49,
D3D_SVT_APPEND_STRUCTURED_BUFFER = 50,
D3D_SVT_CONSUME_STRUCTURED_BUFFER = 51,
D3D_SVT_MIN8FLOAT = 52,
D3D_SVT_MIN10FLOAT = 53,
D3D_SVT_MIN16FLOAT = 54,
D3D_SVT_MIN12INT = 55,
D3D_SVT_MIN16INT = 56,
D3D_SVT_MIN16UINT = 57,
D3D_SVT_INT16 = 58,
D3D_SVT_UINT16 = 59,
D3D_SVT_FLOAT16 = 60,
D3D_SVT_INT64 = 61,
D3D_SVT_UINT64 = 62,
D3D10_SVT_VOID = D3D_SVT_VOID,
D3D10_SVT_BOOL = D3D_SVT_BOOL,
D3D10_SVT_INT = D3D_SVT_INT,
D3D10_SVT_FLOAT = D3D_SVT_FLOAT,
D3D10_SVT_STRING = D3D_SVT_STRING,
D3D10_SVT_TEXTURE = D3D_SVT_TEXTURE,
D3D10_SVT_TEXTURE1D = D3D_SVT_TEXTURE1D,
D3D10_SVT_TEXTURE2D = D3D_SVT_TEXTURE2D,
D3D10_SVT_TEXTURE3D = D3D_SVT_TEXTURE3D,
D3D10_SVT_TEXTURECUBE = D3D_SVT_TEXTURECUBE,
D3D10_SVT_SAMPLER = D3D_SVT_SAMPLER,
D3D10_SVT_SAMPLER1D = D3D_SVT_SAMPLER1D,
D3D10_SVT_SAMPLER2D = D3D_SVT_SAMPLER2D,
D3D10_SVT_SAMPLER3D = D3D_SVT_SAMPLER3D,
D3D10_SVT_SAMPLERCUBE = D3D_SVT_SAMPLERCUBE,
D3D10_SVT_PIXELSHADER = D3D_SVT_PIXELSHADER,
D3D10_SVT_VERTEXSHADER = D3D_SVT_VERTEXSHADER,
D3D10_SVT_PIXELFRAGMENT = D3D_SVT_PIXELFRAGMENT,
D3D10_SVT_VERTEXFRAGMENT = D3D_SVT_VERTEXFRAGMENT,
D3D10_SVT_UINT = D3D_SVT_UINT,
D3D10_SVT_UINT8 = D3D_SVT_UINT8,
D3D10_SVT_GEOMETRYSHADER = D3D_SVT_GEOMETRYSHADER,
D3D10_SVT_RASTERIZER = D3D_SVT_RASTERIZER,
D3D10_SVT_DEPTHSTENCIL = D3D_SVT_DEPTHSTENCIL,
D3D10_SVT_BLEND = D3D_SVT_BLEND,
D3D10_SVT_BUFFER = D3D_SVT_BUFFER,
D3D10_SVT_CBUFFER = D3D_SVT_CBUFFER,
D3D10_SVT_TBUFFER = D3D_SVT_TBUFFER,
D3D10_SVT_TEXTURE1DARRAY = D3D_SVT_TEXTURE1DARRAY,
D3D10_SVT_TEXTURE2DARRAY = D3D_SVT_TEXTURE2DARRAY,
D3D10_SVT_RENDERTARGETVIEW = D3D_SVT_RENDERTARGETVIEW,
D3D10_SVT_DEPTHSTENCILVIEW = D3D_SVT_DEPTHSTENCILVIEW,
D3D10_SVT_TEXTURE2DMS = D3D_SVT_TEXTURE2DMS,
D3D10_SVT_TEXTURE2DMSARRAY = D3D_SVT_TEXTURE2DMSARRAY,
D3D10_SVT_TEXTURECUBEARRAY = D3D_SVT_TEXTURECUBEARRAY,
D3D11_SVT_HULLSHADER = D3D_SVT_HULLSHADER,
D3D11_SVT_DOMAINSHADER = D3D_SVT_DOMAINSHADER,
D3D11_SVT_INTERFACE_POINTER = D3D_SVT_INTERFACE_POINTER,
D3D11_SVT_COMPUTESHADER = D3D_SVT_COMPUTESHADER,
D3D11_SVT_DOUBLE = D3D_SVT_DOUBLE,
D3D11_SVT_RWTEXTURE1D = D3D_SVT_RWTEXTURE1D,
D3D11_SVT_RWTEXTURE1DARRAY = D3D_SVT_RWTEXTURE1DARRAY,
D3D11_SVT_RWTEXTURE2D = D3D_SVT_RWTEXTURE2D,
D3D11_SVT_RWTEXTURE2DARRAY = D3D_SVT_RWTEXTURE2DARRAY,
D3D11_SVT_RWTEXTURE3D = D3D_SVT_RWTEXTURE3D,
D3D11_SVT_RWBUFFER = D3D_SVT_RWBUFFER,
D3D11_SVT_BYTEADDRESS_BUFFER = D3D_SVT_BYTEADDRESS_BUFFER,
D3D11_SVT_RWBYTEADDRESS_BUFFER = D3D_SVT_RWBYTEADDRESS_BUFFER,
D3D11_SVT_STRUCTURED_BUFFER = D3D_SVT_STRUCTURED_BUFFER,
D3D11_SVT_RWSTRUCTURED_BUFFER = D3D_SVT_RWSTRUCTURED_BUFFER,
D3D11_SVT_APPEND_STRUCTURED_BUFFER = D3D_SVT_APPEND_STRUCTURED_BUFFER,
D3D11_SVT_CONSUME_STRUCTURED_BUFFER = D3D_SVT_CONSUME_STRUCTURED_BUFFER,
// force 32-bit size enum
D3D_SVT_FORCE_DWORD = 0x7fffffff
} D3D_SHADER_VARIABLE_TYPE;
typedef enum _D3D_SHADER_INPUT_FLAGS
{
D3D_SIF_USERPACKED = 0x01,
D3D_SIF_COMPARISON_SAMPLER = 0x02, // is this a comparison sampler?
D3D_SIF_TEXTURE_COMPONENT_0 = 0x04, // this 2-bit value encodes c - 1, where c
D3D_SIF_TEXTURE_COMPONENT_1 = 0x08, // is the number of components in the texture
D3D_SIF_TEXTURE_COMPONENTS = 0x0c,
D3D_SIF_UNUSED = 0x10,
D3D10_SIF_USERPACKED = D3D_SIF_USERPACKED,
D3D10_SIF_COMPARISON_SAMPLER = D3D_SIF_COMPARISON_SAMPLER,
D3D10_SIF_TEXTURE_COMPONENT_0 = D3D_SIF_TEXTURE_COMPONENT_0,
D3D10_SIF_TEXTURE_COMPONENT_1 = D3D_SIF_TEXTURE_COMPONENT_1,
D3D10_SIF_TEXTURE_COMPONENTS = D3D_SIF_TEXTURE_COMPONENTS,
// force 32-bit size enum
D3D_SIF_FORCE_DWORD = 0x7fffffff
} D3D_SHADER_INPUT_FLAGS;
typedef enum _D3D_SHADER_INPUT_TYPE
{
D3D_SIT_CBUFFER,
D3D_SIT_TBUFFER,
D3D_SIT_TEXTURE,
D3D_SIT_SAMPLER,
D3D_SIT_UAV_RWTYPED,
D3D_SIT_STRUCTURED,
D3D_SIT_UAV_RWSTRUCTURED,
D3D_SIT_BYTEADDRESS,
D3D_SIT_UAV_RWBYTEADDRESS,
D3D_SIT_UAV_APPEND_STRUCTURED,
D3D_SIT_UAV_CONSUME_STRUCTURED,
D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER,
D3D_SIT_RTACCELERATIONSTRUCTURE,
D3D_SIT_UAV_FEEDBACKTEXTURE,
D3D10_SIT_CBUFFER = D3D_SIT_CBUFFER,
D3D10_SIT_TBUFFER = D3D_SIT_TBUFFER,
D3D10_SIT_TEXTURE = D3D_SIT_TEXTURE,
D3D10_SIT_SAMPLER = D3D_SIT_SAMPLER,
D3D11_SIT_UAV_RWTYPED = D3D_SIT_UAV_RWTYPED,
D3D11_SIT_STRUCTURED = D3D_SIT_STRUCTURED,
D3D11_SIT_UAV_RWSTRUCTURED = D3D_SIT_UAV_RWSTRUCTURED,
D3D11_SIT_BYTEADDRESS = D3D_SIT_BYTEADDRESS,
D3D11_SIT_UAV_RWBYTEADDRESS = D3D_SIT_UAV_RWBYTEADDRESS,
D3D11_SIT_UAV_APPEND_STRUCTURED = D3D_SIT_UAV_APPEND_STRUCTURED,
D3D11_SIT_UAV_CONSUME_STRUCTURED = D3D_SIT_UAV_CONSUME_STRUCTURED,
D3D11_SIT_UAV_RWSTRUCTURED_WITH_COUNTER = D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER,
} D3D_SHADER_INPUT_TYPE;
typedef enum _D3D_SHADER_CBUFFER_FLAGS
{
D3D_CBF_USERPACKED = 1,
D3D10_CBF_USERPACKED = D3D_CBF_USERPACKED,
// force 32-bit size enum
D3D_CBF_FORCE_DWORD = 0x7fffffff
} D3D_SHADER_CBUFFER_FLAGS;
typedef enum _D3D_CBUFFER_TYPE
{
D3D_CT_CBUFFER,
D3D_CT_TBUFFER,
D3D_CT_INTERFACE_POINTERS,
D3D_CT_RESOURCE_BIND_INFO,
D3D10_CT_CBUFFER = D3D_CT_CBUFFER,
D3D10_CT_TBUFFER = D3D_CT_TBUFFER,
D3D11_CT_CBUFFER = D3D_CT_CBUFFER,
D3D11_CT_TBUFFER = D3D_CT_TBUFFER,
D3D11_CT_INTERFACE_POINTERS = D3D_CT_INTERFACE_POINTERS,
D3D11_CT_RESOURCE_BIND_INFO = D3D_CT_RESOURCE_BIND_INFO,
} D3D_CBUFFER_TYPE;
typedef enum D3D_NAME
{
D3D_NAME_UNDEFINED = 0,
// Names meaningful to both HLSL and hardware
D3D_NAME_POSITION = 1,
D3D_NAME_CLIP_DISTANCE = 2,
D3D_NAME_CULL_DISTANCE = 3,
D3D_NAME_RENDER_TARGET_ARRAY_INDEX = 4,
D3D_NAME_VIEWPORT_ARRAY_INDEX = 5,
D3D_NAME_VERTEX_ID = 6,
D3D_NAME_PRIMITIVE_ID = 7,
D3D_NAME_INSTANCE_ID = 8,
D3D_NAME_IS_FRONT_FACE = 9,
D3D_NAME_SAMPLE_INDEX = 10,
D3D_NAME_FINAL_QUAD_EDGE_TESSFACTOR = 11,
D3D_NAME_FINAL_QUAD_INSIDE_TESSFACTOR = 12,
D3D_NAME_FINAL_TRI_EDGE_TESSFACTOR = 13,
D3D_NAME_FINAL_TRI_INSIDE_TESSFACTOR = 14,
D3D_NAME_FINAL_LINE_DETAIL_TESSFACTOR = 15,
D3D_NAME_FINAL_LINE_DENSITY_TESSFACTOR = 16,
D3D_NAME_BARYCENTRICS = 23,
D3D_NAME_SHADINGRATE = 24,
D3D_NAME_CULLPRIMITIVE = 25,
// Names meaningful to HLSL only
D3D_NAME_TARGET = 64,
D3D_NAME_DEPTH = 65,
D3D_NAME_COVERAGE = 66,
D3D_NAME_DEPTH_GREATER_EQUAL = 67,
D3D_NAME_DEPTH_LESS_EQUAL = 68,
D3D_NAME_STENCIL_REF = 69,
D3D_NAME_INNER_COVERAGE = 70,
D3D10_NAME_UNDEFINED = D3D_NAME_UNDEFINED,
D3D10_NAME_POSITION = D3D_NAME_POSITION,
D3D10_NAME_CLIP_DISTANCE = D3D_NAME_CLIP_DISTANCE,
D3D10_NAME_CULL_DISTANCE = D3D_NAME_CULL_DISTANCE,
D3D10_NAME_RENDER_TARGET_ARRAY_INDEX = D3D_NAME_RENDER_TARGET_ARRAY_INDEX,
D3D10_NAME_VIEWPORT_ARRAY_INDEX = D3D_NAME_VIEWPORT_ARRAY_INDEX,
D3D10_NAME_VERTEX_ID = D3D_NAME_VERTEX_ID,
D3D10_NAME_PRIMITIVE_ID = D3D_NAME_PRIMITIVE_ID,
D3D10_NAME_INSTANCE_ID = D3D_NAME_INSTANCE_ID,
D3D10_NAME_IS_FRONT_FACE = D3D_NAME_IS_FRONT_FACE,
D3D10_NAME_SAMPLE_INDEX = D3D_NAME_SAMPLE_INDEX,
D3D10_NAME_TARGET = D3D_NAME_TARGET,
D3D10_NAME_DEPTH = D3D_NAME_DEPTH,
D3D10_NAME_COVERAGE = D3D_NAME_COVERAGE,
D3D11_NAME_FINAL_QUAD_EDGE_TESSFACTOR = D3D_NAME_FINAL_QUAD_EDGE_TESSFACTOR,
D3D11_NAME_FINAL_QUAD_INSIDE_TESSFACTOR = D3D_NAME_FINAL_QUAD_INSIDE_TESSFACTOR,
D3D11_NAME_FINAL_TRI_EDGE_TESSFACTOR = D3D_NAME_FINAL_TRI_EDGE_TESSFACTOR,
D3D11_NAME_FINAL_TRI_INSIDE_TESSFACTOR = D3D_NAME_FINAL_TRI_INSIDE_TESSFACTOR,
D3D11_NAME_FINAL_LINE_DETAIL_TESSFACTOR = D3D_NAME_FINAL_LINE_DETAIL_TESSFACTOR,
D3D11_NAME_FINAL_LINE_DENSITY_TESSFACTOR = D3D_NAME_FINAL_LINE_DENSITY_TESSFACTOR,
D3D11_NAME_DEPTH_GREATER_EQUAL = D3D_NAME_DEPTH_GREATER_EQUAL,
D3D11_NAME_DEPTH_LESS_EQUAL = D3D_NAME_DEPTH_LESS_EQUAL,
D3D11_NAME_STENCIL_REF = D3D_NAME_STENCIL_REF,
D3D11_NAME_INNER_COVERAGE = D3D_NAME_INNER_COVERAGE,
D3D12_NAME_BARYCENTRICS = D3D_NAME_BARYCENTRICS,
D3D12_NAME_SHADINGRATE = D3D_NAME_SHADINGRATE,
D3D12_NAME_CULLPRIMITIVE = D3D_NAME_CULLPRIMITIVE,
} D3D_NAME;
typedef enum D3D_RESOURCE_RETURN_TYPE
{
D3D_RETURN_TYPE_UNORM = 1,
D3D_RETURN_TYPE_SNORM = 2,
D3D_RETURN_TYPE_SINT = 3,
D3D_RETURN_TYPE_UINT = 4,
D3D_RETURN_TYPE_FLOAT = 5,
D3D_RETURN_TYPE_MIXED = 6,
D3D_RETURN_TYPE_DOUBLE = 7,
D3D_RETURN_TYPE_CONTINUED = 8,
D3D10_RETURN_TYPE_UNORM = D3D_RETURN_TYPE_UNORM,
D3D10_RETURN_TYPE_SNORM = D3D_RETURN_TYPE_SNORM,
D3D10_RETURN_TYPE_SINT = D3D_RETURN_TYPE_SINT,
D3D10_RETURN_TYPE_UINT = D3D_RETURN_TYPE_UINT,
D3D10_RETURN_TYPE_FLOAT = D3D_RETURN_TYPE_FLOAT,
D3D10_RETURN_TYPE_MIXED = D3D_RETURN_TYPE_MIXED,
D3D11_RETURN_TYPE_UNORM = D3D_RETURN_TYPE_UNORM,
D3D11_RETURN_TYPE_SNORM = D3D_RETURN_TYPE_SNORM,
D3D11_RETURN_TYPE_SINT = D3D_RETURN_TYPE_SINT,
D3D11_RETURN_TYPE_UINT = D3D_RETURN_TYPE_UINT,
D3D11_RETURN_TYPE_FLOAT = D3D_RETURN_TYPE_FLOAT,
D3D11_RETURN_TYPE_MIXED = D3D_RETURN_TYPE_MIXED,
D3D11_RETURN_TYPE_DOUBLE = D3D_RETURN_TYPE_DOUBLE,
D3D11_RETURN_TYPE_CONTINUED = D3D_RETURN_TYPE_CONTINUED,
} D3D_RESOURCE_RETURN_TYPE;
typedef enum D3D_REGISTER_COMPONENT_TYPE
{
D3D_REGISTER_COMPONENT_UNKNOWN = 0,
D3D_REGISTER_COMPONENT_UINT32 = 1,
D3D_REGISTER_COMPONENT_SINT32 = 2,
D3D_REGISTER_COMPONENT_FLOAT32 = 3,
D3D_REGISTER_COMPONENT_UINT16 = 4,
D3D_REGISTER_COMPONENT_SINT16 = 5,
D3D_REGISTER_COMPONENT_FLOAT16 = 6,
D3D_REGISTER_COMPONENT_UINT64 = 7,
D3D_REGISTER_COMPONENT_SINT64 = 8,
D3D_REGISTER_COMPONENT_FLOAT64 = 9,
D3D10_REGISTER_COMPONENT_UNKNOWN = D3D_REGISTER_COMPONENT_UNKNOWN,
D3D10_REGISTER_COMPONENT_UINT32 = D3D_REGISTER_COMPONENT_UINT32,
D3D10_REGISTER_COMPONENT_SINT32 = D3D_REGISTER_COMPONENT_SINT32,
D3D10_REGISTER_COMPONENT_FLOAT32 = D3D_REGISTER_COMPONENT_FLOAT32,
D3D10_REGISTER_COMPONENT_UINT16 = D3D_REGISTER_COMPONENT_UINT16,
D3D10_REGISTER_COMPONENT_SINT16 = D3D_REGISTER_COMPONENT_SINT16,
D3D10_REGISTER_COMPONENT_FLOAT16 = D3D_REGISTER_COMPONENT_FLOAT16,
D3D10_REGISTER_COMPONENT_UINT64 = D3D_REGISTER_COMPONENT_UINT64,
D3D10_REGISTER_COMPONENT_SINT64 = D3D_REGISTER_COMPONENT_SINT64,
D3D10_REGISTER_COMPONENT_FLOAT64 = D3D_REGISTER_COMPONENT_FLOAT64,
} D3D_REGISTER_COMPONENT_TYPE;
typedef enum D3D_TESSELLATOR_DOMAIN
{
D3D_TESSELLATOR_DOMAIN_UNDEFINED = 0,
D3D_TESSELLATOR_DOMAIN_ISOLINE = 1,
D3D_TESSELLATOR_DOMAIN_TRI = 2,
D3D_TESSELLATOR_DOMAIN_QUAD = 3,
D3D11_TESSELLATOR_DOMAIN_UNDEFINED = D3D_TESSELLATOR_DOMAIN_UNDEFINED,
D3D11_TESSELLATOR_DOMAIN_ISOLINE = D3D_TESSELLATOR_DOMAIN_ISOLINE,
D3D11_TESSELLATOR_DOMAIN_TRI = D3D_TESSELLATOR_DOMAIN_TRI,
D3D11_TESSELLATOR_DOMAIN_QUAD = D3D_TESSELLATOR_DOMAIN_QUAD,
} D3D_TESSELLATOR_DOMAIN;
typedef enum D3D_TESSELLATOR_PARTITIONING
{
D3D_TESSELLATOR_PARTITIONING_UNDEFINED = 0,
D3D_TESSELLATOR_PARTITIONING_INTEGER = 1,
D3D_TESSELLATOR_PARTITIONING_POW2 = 2,
D3D_TESSELLATOR_PARTITIONING_FRACTIONAL_ODD = 3,
D3D_TESSELLATOR_PARTITIONING_FRACTIONAL_EVEN = 4,
D3D11_TESSELLATOR_PARTITIONING_UNDEFINED = D3D_TESSELLATOR_PARTITIONING_UNDEFINED,
D3D11_TESSELLATOR_PARTITIONING_INTEGER = D3D_TESSELLATOR_PARTITIONING_INTEGER,
D3D11_TESSELLATOR_PARTITIONING_POW2 = D3D_TESSELLATOR_PARTITIONING_POW2,
D3D11_TESSELLATOR_PARTITIONING_FRACTIONAL_ODD = D3D_TESSELLATOR_PARTITIONING_FRACTIONAL_ODD,
D3D11_TESSELLATOR_PARTITIONING_FRACTIONAL_EVEN = D3D_TESSELLATOR_PARTITIONING_FRACTIONAL_EVEN,
} D3D_TESSELLATOR_PARTITIONING;
typedef enum D3D_TESSELLATOR_OUTPUT_PRIMITIVE
{
D3D_TESSELLATOR_OUTPUT_UNDEFINED = 0,
D3D_TESSELLATOR_OUTPUT_POINT = 1,
D3D_TESSELLATOR_OUTPUT_LINE = 2,
D3D_TESSELLATOR_OUTPUT_TRIANGLE_CW = 3,
D3D_TESSELLATOR_OUTPUT_TRIANGLE_CCW = 4,
D3D11_TESSELLATOR_OUTPUT_UNDEFINED = D3D_TESSELLATOR_OUTPUT_UNDEFINED,
D3D11_TESSELLATOR_OUTPUT_POINT = D3D_TESSELLATOR_OUTPUT_POINT,
D3D11_TESSELLATOR_OUTPUT_LINE = D3D_TESSELLATOR_OUTPUT_LINE,
D3D11_TESSELLATOR_OUTPUT_TRIANGLE_CW = D3D_TESSELLATOR_OUTPUT_TRIANGLE_CW,
D3D11_TESSELLATOR_OUTPUT_TRIANGLE_CCW = D3D_TESSELLATOR_OUTPUT_TRIANGLE_CCW,
} D3D_TESSELLATOR_OUTPUT_PRIMITIVE;
typedef enum D3D_MIN_PRECISION
{
D3D_MIN_PRECISION_DEFAULT = 0, // Default precision for the shader model
D3D_MIN_PRECISION_FLOAT_16 = 1, // Min 16 bit/component float
D3D_MIN_PRECISION_FLOAT_2_8 = 2, // Min 10(2.8)bit/comp. float
D3D_MIN_PRECISION_RESERVED = 3, // Reserved for future use
D3D_MIN_PRECISION_SINT_16 = 4, // Min 16 bit/comp. signed integer
D3D_MIN_PRECISION_UINT_16 = 5, // Min 16 bit/comp. unsigned integer
// These values are abstractions of width only for use in situations
// where a general width is needed instead of specific types. They
// will never be used in shader operands.
D3D_MIN_PRECISION_ANY_16 = 0xf0,
D3D_MIN_PRECISION_ANY_10 = 0xf1,
} D3D_MIN_PRECISION;
typedef enum D3D_INTERPOLATION_MODE
{
D3D_INTERPOLATION_UNDEFINED = 0,
D3D_INTERPOLATION_CONSTANT = 1,
D3D_INTERPOLATION_LINEAR = 2,
D3D_INTERPOLATION_LINEAR_CENTROID = 3,
D3D_INTERPOLATION_LINEAR_NOPERSPECTIVE = 4,
D3D_INTERPOLATION_LINEAR_NOPERSPECTIVE_CENTROID = 5,
D3D_INTERPOLATION_LINEAR_SAMPLE = 6,
D3D_INTERPOLATION_LINEAR_NOPERSPECTIVE_SAMPLE = 7,
} D3D_INTERPOLATION_MODE;
// Parameter flags.
typedef enum _D3D_PARAMETER_FLAGS
{
D3D_PF_NONE = 0x00000000,
D3D_PF_IN = 0x00000001,
D3D_PF_OUT = 0x00000002,
D3D_PF_FORCE_DWORD = 0x7fffffff
} D3D_PARAMETER_FLAGS;
// Format Layout Properties
typedef enum D3D_FORMAT_LAYOUT
{
D3DFL_STANDARD = 0, // standard layout
D3DFL_CUSTOM = -1 // custom layout
// Note, 1 bit allocated for this in FORMAT_DETAIL below. If you add fields here, add bits...
// NOTE SIGNED VALUES ARE USED SINCE COMPILER MAKES ENUMS SIGNED, AND BITFIELDS ARE SIGN EXTENDED ON READ
} D3D_FORMAT_LAYOUT;
typedef enum D3D_FORMAT_TYPE_LEVEL
{
D3DFTL_NO_TYPE = 0,
D3DFTL_PARTIAL_TYPE = -2,
D3DFTL_FULL_TYPE = -1,
// Note, 2 bits allocated for this in FORMAT_DETAIL below. If you add fields here, add bits...
// NOTE SIGNED VALUES ARE USED SINCE COMPILER MAKES ENUMS SIGNED, AND BITFIELDS ARE SIGN EXTENDED ON READ
} D3D_FORMAT_TYPE_LEVEL;
typedef enum D3D_FORMAT_COMPONENT_NAME
{
D3DFCN_R = -4,
D3DFCN_G = -3,
D3DFCN_B = -2,
D3DFCN_A = -1,
D3DFCN_D = 0,
D3DFCN_S = 1,
D3DFCN_X = 2,
// Note, 3 bits allocated for this in FORMAT_DETAIL below. If you add fields here, add bits...
// NOTE SIGNED VALUES ARE USED SINCE COMPILER MAKES ENUMS SIGNED, AND BITFIELDS ARE SIGN EXTENDED ON READ
} D3D_FORMAT_COMPONENT_NAME;
typedef enum D3D_FORMAT_COMPONENT_INTERPRETATION
{
D3DFCI_TYPELESS = 0,
D3DFCI_FLOAT = -4,
D3DFCI_SNORM = -3,
D3DFCI_UNORM = -2,
D3DFCI_SINT = -1,
D3DFCI_UINT = 1,
D3DFCI_UNORM_SRGB = 2,
D3DFCI_BIASED_FIXED_2_8 = 3,
// Note, 3 bits allocated for this in FORMAT_DETAIL below. If you add fields here, add bits...
// NOTE SIGNED VALUES ARE USED SINCE COMPILER MAKES ENUMS SIGNED, AND BITFIELDS ARE SIGN EXTENDED ON READ
} D3D_FORMAT_COMPONENT_INTERPRETATION;
// Well-Known Private Data IDs (WKPDID_*):
// WKPDID_D3DDebugObjectName provides a unique name to objects in order to assist the developer during debugging.
//
// const char c_szName[] = "texture.jpg";
// pObject->SetPrivateData( WKPDID_D3DDebugObjectName, sizeof( c_szName ) - 1, c_szName );
cpp_quote("DEFINE_GUID(WKPDID_D3DDebugObjectName,0x429b8c22,0x9188,0x4b0c,0x87,0x42,0xac,0xb0,0xbf,0x85,0xc2,0x00);")
cpp_quote("DEFINE_GUID(WKPDID_D3DDebugObjectNameW,0x4cca5fd8,0x921f,0x42c8,0x85,0x66,0x70,0xca,0xf2,0xa9,0xb7,0x41);")
cpp_quote("DEFINE_GUID(WKPDID_CommentStringW,0xd0149dc0,0x90e8,0x4ec8,0x81, 0x44, 0xe9, 0x00, 0xad, 0x26, 0x6b, 0xb2);")
cpp_quote("DEFINE_GUID(WKPDID_D3D12UniqueObjectId, 0x1b39de15, 0xec04, 0x4bae, 0xba, 0x4d, 0x8c, 0xef, 0x79, 0xfc, 0x04, 0xc1);")
cpp_quote("#define D3D_SET_OBJECT_NAME_N_A(pObject, Chars, pName) (pObject)->SetPrivateData(WKPDID_D3DDebugObjectName, Chars, pName)")
cpp_quote("#define D3D_SET_OBJECT_NAME_A(pObject, pName) D3D_SET_OBJECT_NAME_N_A(pObject, lstrlenA(pName), pName)")
cpp_quote("#define D3D_SET_OBJECT_NAME_N_W(pObject, Chars, pName) (pObject)->SetPrivateData(WKPDID_D3DDebugObjectNameW, Chars*2, pName)")
cpp_quote("#define D3D_SET_OBJECT_NAME_W(pObject, pName) D3D_SET_OBJECT_NAME_N_W(pObject, wcslen(pName), pName)")
cpp_quote("#define D3D_COMPONENT_MASK_X 1")
cpp_quote("#define D3D_COMPONENT_MASK_Y 2")
cpp_quote("#define D3D_COMPONENT_MASK_Z 4")
cpp_quote("#define D3D_COMPONENT_MASK_W 8")
cpp_quote("DEFINE_GUID(D3D_TEXTURE_LAYOUT_ROW_MAJOR,0xb5dc234f,0x72bb,0x4bec,0x97,0x05,0x8c,0xf2,0x58,0xdf,0x6b,0x6c);") // Feature_D3D1XDisplayable
cpp_quote("DEFINE_GUID(D3D_TEXTURE_LAYOUT_64KB_STANDARD_SWIZZLE,0x4c0f29e3,0x3f5f,0x4d35,0x84,0xc9,0xbc,0x09,0x83,0xb6,0x2c,0x28);") // Feature_D3D1XDisplayable

View File

@@ -0,0 +1,35 @@
//*********************************************************
//
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License (MIT).
//
//*********************************************************
#ifndef __D3DX12_H__
#define __D3DX12_H__
#include "d3d12.h"
#if defined( __cplusplus )
#include "d3dx12_barriers.h"
#include "d3dx12_core.h"
#include "d3dx12_default.h"
#include "d3dx12_pipeline_state_stream.h"
#include "d3dx12_render_pass.h"
#include "d3dx12_resource_helpers.h"
#include "d3dx12_root_signature.h"
#include "d3dx12_property_format_table.h"
#ifndef D3DX12_NO_STATE_OBJECT_HELPERS
#include "d3dx12_state_object.h"
#endif // !D3DX12_NO_STATE_OBJECT_HELPERS
#ifndef D3DX12_NO_CHECK_FEATURE_SUPPORT_CLASS
#include "d3dx12_check_feature_support.h"
#endif // !D3DX12_NO_CHECK_FEATURE_SUPPORT_CLASS
#endif // defined( __cplusplus )
#endif //__D3DX12_H__

View File

@@ -0,0 +1,192 @@
//*********************************************************
//
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License (MIT).
//
//*********************************************************
#ifndef __D3DX12_BARRIERS_H__
#define __D3DX12_BARRIERS_H__
#if defined( __cplusplus )
#include "d3d12.h"
//------------------------------------------------------------------------------------------------
struct CD3DX12_RESOURCE_BARRIER : public D3D12_RESOURCE_BARRIER
{
CD3DX12_RESOURCE_BARRIER() = default;
explicit CD3DX12_RESOURCE_BARRIER(const D3D12_RESOURCE_BARRIER &o) noexcept :
D3D12_RESOURCE_BARRIER(o)
{}
static inline CD3DX12_RESOURCE_BARRIER Transition(
_In_ ID3D12Resource* pResource,
D3D12_RESOURCE_STATES stateBefore,
D3D12_RESOURCE_STATES stateAfter,
UINT subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES,
D3D12_RESOURCE_BARRIER_FLAGS flags = D3D12_RESOURCE_BARRIER_FLAG_NONE) noexcept
{
CD3DX12_RESOURCE_BARRIER result = {};
D3D12_RESOURCE_BARRIER &barrier = result;
result.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
result.Flags = flags;
barrier.Transition.pResource = pResource;
barrier.Transition.StateBefore = stateBefore;
barrier.Transition.StateAfter = stateAfter;
barrier.Transition.Subresource = subresource;
return result;
}
static inline CD3DX12_RESOURCE_BARRIER Aliasing(
_In_opt_ ID3D12Resource* pResourceBefore,
_In_opt_ ID3D12Resource* pResourceAfter) noexcept
{
CD3DX12_RESOURCE_BARRIER result = {};
D3D12_RESOURCE_BARRIER &barrier = result;
result.Type = D3D12_RESOURCE_BARRIER_TYPE_ALIASING;
barrier.Aliasing.pResourceBefore = pResourceBefore;
barrier.Aliasing.pResourceAfter = pResourceAfter;
return result;
}
static inline CD3DX12_RESOURCE_BARRIER UAV(
_In_opt_ ID3D12Resource* pResource) noexcept
{
CD3DX12_RESOURCE_BARRIER result = {};
D3D12_RESOURCE_BARRIER &barrier = result;
result.Type = D3D12_RESOURCE_BARRIER_TYPE_UAV;
barrier.UAV.pResource = pResource;
return result;
}
};
#if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 608)
//================================================================================================
// D3DX12 Enhanced Barrier Helpers
//================================================================================================
class CD3DX12_BARRIER_SUBRESOURCE_RANGE : public D3D12_BARRIER_SUBRESOURCE_RANGE
{
public:
CD3DX12_BARRIER_SUBRESOURCE_RANGE() = default;
CD3DX12_BARRIER_SUBRESOURCE_RANGE(const D3D12_BARRIER_SUBRESOURCE_RANGE &o) noexcept :
D3D12_BARRIER_SUBRESOURCE_RANGE(o)
{}
explicit CD3DX12_BARRIER_SUBRESOURCE_RANGE(UINT Subresource) noexcept :
D3D12_BARRIER_SUBRESOURCE_RANGE{ Subresource, 0, 0, 0, 0, 0 }
{}
CD3DX12_BARRIER_SUBRESOURCE_RANGE(
UINT firstMipLevel,
UINT numMips,
UINT firstArraySlice,
UINT numArraySlices,
UINT firstPlane = 0,
UINT numPlanes = 1) noexcept :
D3D12_BARRIER_SUBRESOURCE_RANGE
{
firstMipLevel,
numMips,
firstArraySlice,
numArraySlices,
firstPlane,
numPlanes
}
{}
};
class CD3DX12_GLOBAL_BARRIER : public D3D12_GLOBAL_BARRIER
{
public:
CD3DX12_GLOBAL_BARRIER() = default;
CD3DX12_GLOBAL_BARRIER(const D3D12_GLOBAL_BARRIER &o) noexcept : D3D12_GLOBAL_BARRIER(o){}
CD3DX12_GLOBAL_BARRIER(
D3D12_BARRIER_SYNC syncBefore,
D3D12_BARRIER_SYNC syncAfter,
D3D12_BARRIER_ACCESS accessBefore,
D3D12_BARRIER_ACCESS accessAfter) noexcept : D3D12_GLOBAL_BARRIER {
syncBefore,
syncAfter,
accessBefore,
accessAfter
}
{}
};
class CD3DX12_BUFFER_BARRIER : public D3D12_BUFFER_BARRIER
{
public:
CD3DX12_BUFFER_BARRIER() = default;
CD3DX12_BUFFER_BARRIER(const D3D12_BUFFER_BARRIER &o) noexcept : D3D12_BUFFER_BARRIER(o){}
CD3DX12_BUFFER_BARRIER(
D3D12_BARRIER_SYNC syncBefore,
D3D12_BARRIER_SYNC syncAfter,
D3D12_BARRIER_ACCESS accessBefore,
D3D12_BARRIER_ACCESS accessAfter,
ID3D12Resource *pRes) noexcept : D3D12_BUFFER_BARRIER {
syncBefore,
syncAfter,
accessBefore,
accessAfter,
pRes,
0, ULLONG_MAX
}
{}
};
class CD3DX12_TEXTURE_BARRIER : public D3D12_TEXTURE_BARRIER
{
public:
CD3DX12_TEXTURE_BARRIER() = default;
CD3DX12_TEXTURE_BARRIER(const D3D12_TEXTURE_BARRIER &o) noexcept : D3D12_TEXTURE_BARRIER(o){}
CD3DX12_TEXTURE_BARRIER(
D3D12_BARRIER_SYNC syncBefore,
D3D12_BARRIER_SYNC syncAfter,
D3D12_BARRIER_ACCESS accessBefore,
D3D12_BARRIER_ACCESS accessAfter,
D3D12_BARRIER_LAYOUT layoutBefore,
D3D12_BARRIER_LAYOUT layoutAfter,
ID3D12Resource *pRes,
const D3D12_BARRIER_SUBRESOURCE_RANGE &subresources,
D3D12_TEXTURE_BARRIER_FLAGS flag = D3D12_TEXTURE_BARRIER_FLAG_NONE) noexcept : D3D12_TEXTURE_BARRIER {
syncBefore,
syncAfter,
accessBefore,
accessAfter,
layoutBefore,
layoutAfter,
pRes,
subresources,
flag
}
{}
};
class CD3DX12_BARRIER_GROUP : public D3D12_BARRIER_GROUP
{
public:
CD3DX12_BARRIER_GROUP() = default;
CD3DX12_BARRIER_GROUP(const D3D12_BARRIER_GROUP &o) noexcept : D3D12_BARRIER_GROUP(o){}
CD3DX12_BARRIER_GROUP(UINT32 numBarriers, const D3D12_BUFFER_BARRIER *pBarriers) noexcept
{
Type = D3D12_BARRIER_TYPE_BUFFER;
NumBarriers = numBarriers;
pBufferBarriers = pBarriers;
}
CD3DX12_BARRIER_GROUP(UINT32 numBarriers, const D3D12_TEXTURE_BARRIER *pBarriers) noexcept
{
Type = D3D12_BARRIER_TYPE_TEXTURE;
NumBarriers = numBarriers;
pTextureBarriers = pBarriers;
}
CD3DX12_BARRIER_GROUP(UINT32 numBarriers, const D3D12_GLOBAL_BARRIER *pBarriers) noexcept
{
Type = D3D12_BARRIER_TYPE_GLOBAL;
NumBarriers = numBarriers;
pGlobalBarriers = pBarriers;
}
};
#endif // D3D12_SDK_VERSION >= 608
#endif // defined( __cplusplus )
#endif // __D3DX12_BARRIERS_H__

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,12 @@
//*********************************************************
//
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License (MIT).
//
//*********************************************************
#pragma once
struct CD3DX12_DEFAULT {};
extern const DECLSPEC_SELECTANY CD3DX12_DEFAULT D3D12_DEFAULT;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,128 @@
//*********************************************************
//
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License (MIT).
//
//*********************************************************
#ifndef __D3D12_PROPERTY_LAYOUT_FORMAT_TABLE_H__
#define __D3D12_PROPERTY_LAYOUT_FORMAT_TABLE_H__
#include "d3d12.h"
#define MAP_ALIGN_REQUIREMENT 16 // Map is required to return 16-byte aligned addresses
struct D3D12_PROPERTY_LAYOUT_FORMAT_TABLE
{
public:
// ----------------------------------------------------------------------------
// Information describing everything about a D3D Resource Format
// ----------------------------------------------------------------------------
typedef struct FORMAT_DETAIL
{
DXGI_FORMAT DXGIFormat;
DXGI_FORMAT ParentFormat;
const DXGI_FORMAT* pDefaultFormatCastSet; // This is dependent on FL/driver version, but is here to save a lot of space
UINT8 BitsPerComponent[4]; // only used for D3DFTL_PARTIAL_TYPE or FULL_TYPE
UINT8 BitsPerUnit;
BYTE SRGBFormat : 1;
UINT WidthAlignment : 4; // number of texels to align to in a mip level.
UINT HeightAlignment : 4; // Top level dimensions must be a multiple of these
UINT DepthAlignment : 1; // values.
D3D_FORMAT_LAYOUT Layout : 1;
D3D_FORMAT_TYPE_LEVEL TypeLevel : 2;
D3D_FORMAT_COMPONENT_NAME ComponentName0 : 3; // RED ... only used for D3DFTL_PARTIAL_TYPE or FULL_TYPE
D3D_FORMAT_COMPONENT_NAME ComponentName1 : 3; // GREEN ... only used for D3DFTL_PARTIAL_TYPE or FULL_TYPE
D3D_FORMAT_COMPONENT_NAME ComponentName2 : 3; // BLUE ... only used for D3DFTL_PARTIAL_TYPE or FULL_TYPE
D3D_FORMAT_COMPONENT_NAME ComponentName3 : 3; // ALPHA ... only used for D3DFTL_PARTIAL_TYPE or FULL_TYPE
D3D_FORMAT_COMPONENT_INTERPRETATION ComponentInterpretation0 : 3; // only used for D3DFTL_FULL_TYPE
D3D_FORMAT_COMPONENT_INTERPRETATION ComponentInterpretation1 : 3; // only used for D3DFTL_FULL_TYPE
D3D_FORMAT_COMPONENT_INTERPRETATION ComponentInterpretation2 : 3; // only used for D3DFTL_FULL_TYPE
D3D_FORMAT_COMPONENT_INTERPRETATION ComponentInterpretation3 : 3; // only used for D3DFTL_FULL_TYPE
bool bDX9VertexOrIndexFormat : 1;
bool bDX9TextureFormat : 1;
bool bFloatNormFormat : 1;
bool bPlanar : 1;
bool bYUV : 1;
bool bDependantFormatCastSet : 1; // This indicates that the format cast set is dependent on FL/driver version
bool bInternal : 1;
} FORMAT_DETAIL;
private:
static const FORMAT_DETAIL s_FormatDetail[];
static const UINT s_NumFormats;
static const LPCSTR s_FormatNames[]; // separate from above structure so it can be compiled out of runtime.
public:
static UINT GetNumFormats();
static const FORMAT_DETAIL* GetFormatTable();
static D3D_FEATURE_LEVEL GetHighestDefinedFeatureLevel();
static DXGI_FORMAT GetFormat (SIZE_T Index);
static bool FormatExists (DXGI_FORMAT Format);
static bool FormatExistsInHeader (DXGI_FORMAT Format, bool bExternalHeader = true);
static UINT GetByteAlignment (DXGI_FORMAT Format);
static bool IsBlockCompressFormat (DXGI_FORMAT Format);
static LPCSTR GetName (DXGI_FORMAT Format, bool bHideInternalFormats = true);
static bool IsSRGBFormat (DXGI_FORMAT Format);
static UINT GetBitsPerStencil (DXGI_FORMAT Format);
static UINT GetBitsPerDepth (DXGI_FORMAT Format);
static void GetFormatReturnTypes (DXGI_FORMAT Format, D3D_FORMAT_COMPONENT_INTERPRETATION* pInterpretations); // return array of 4 components
static UINT GetNumComponentsInFormat(DXGI_FORMAT Format);
static UINT GetMinNumComponentsInFormats(DXGI_FORMAT FormatA, DXGI_FORMAT FormatB);
// Converts the sequential component index (range from 0 to GetNumComponentsInFormat()) to
// the absolute component index (range 0 to 3).
static UINT Sequential2AbsoluteComponentIndex (DXGI_FORMAT Format, UINT SequentialComponentIndex);
static bool CanBeCastEvenFullyTyped (DXGI_FORMAT Format, D3D_FEATURE_LEVEL fl);
static UINT8 GetAddressingBitsPerAlignedSize (DXGI_FORMAT Format);
static DXGI_FORMAT GetParentFormat (DXGI_FORMAT Format);
static const DXGI_FORMAT* GetFormatCastSet (DXGI_FORMAT Format);
static D3D_FORMAT_LAYOUT GetLayout (DXGI_FORMAT Format);
static D3D_FORMAT_TYPE_LEVEL GetTypeLevel (DXGI_FORMAT Format);
static UINT GetBitsPerUnit (DXGI_FORMAT Format);
static UINT GetBitsPerUnitThrow (DXGI_FORMAT Format);
static UINT GetBitsPerElement (DXGI_FORMAT Format); // Legacy function used to support D3D10on9 only. Do not use.
static UINT GetWidthAlignment (DXGI_FORMAT Format);
static UINT GetHeightAlignment (DXGI_FORMAT Format);
static UINT GetDepthAlignment (DXGI_FORMAT Format);
static BOOL Planar (DXGI_FORMAT Format);
static BOOL NonOpaquePlanar (DXGI_FORMAT Format);
static BOOL YUV (DXGI_FORMAT Format);
static BOOL Opaque (DXGI_FORMAT Format);
static bool FamilySupportsStencil (DXGI_FORMAT Format);
static UINT NonOpaquePlaneCount (DXGI_FORMAT Format);
static BOOL DX9VertexOrIndexFormat (DXGI_FORMAT Format);
static BOOL DX9TextureFormat (DXGI_FORMAT Format);
static BOOL FloatNormTextureFormat (DXGI_FORMAT Format);
static bool DepthOnlyFormat (DXGI_FORMAT format);
static UINT8 GetPlaneCount (DXGI_FORMAT Format);
static bool MotionEstimatorAllowedInputFormat (DXGI_FORMAT Format);
static bool SupportsSamplerFeedback (DXGI_FORMAT Format);
static bool DecodeHistogramAllowedForOutputFormatSupport(DXGI_FORMAT Format);
static UINT8 GetPlaneSliceFromViewFormat (DXGI_FORMAT ResourceFormat, DXGI_FORMAT ViewFormat);
static bool FloatAndNotFloatFormats (DXGI_FORMAT FormatA, DXGI_FORMAT FormatB);
static bool SNORMAndUNORMFormats (DXGI_FORMAT FormatA, DXGI_FORMAT FormatB);
static bool ValidCastToR32UAV (DXGI_FORMAT from, DXGI_FORMAT to);
static bool IsSupportedTextureDisplayableFormat (DXGI_FORMAT, bool bMediaFormatOnly);
static D3D_FORMAT_COMPONENT_INTERPRETATION GetFormatComponentInterpretation (DXGI_FORMAT Format, UINT AbsoluteComponentIndex);
static UINT GetBitsPerComponent (DXGI_FORMAT Format, UINT AbsoluteComponentIndex);
static D3D_FORMAT_COMPONENT_NAME GetComponentName (DXGI_FORMAT Format, UINT AbsoluteComponentIndex);
static HRESULT CalculateExtraPlanarRows (DXGI_FORMAT format, UINT plane0Height, _Out_ UINT& totalHeight);
static HRESULT CalculateMinimumRowMajorRowPitch (DXGI_FORMAT Format, UINT Width, _Out_ UINT& RowPitch);
static HRESULT CalculateMinimumRowMajorSlicePitch (DXGI_FORMAT Format, UINT ContextBasedRowPitch, UINT Height, _Out_ UINT& SlicePitch);
static void GetYCbCrChromaSubsampling (DXGI_FORMAT Format, _Out_ UINT& HorizontalSubsampling, _Out_ UINT& VerticalSubsampling);
static HRESULT CalculateResourceSize (UINT width, UINT height, UINT depth, DXGI_FORMAT format, UINT mipLevels, UINT subresources, _Out_ SIZE_T& totalByteSize, _Out_writes_opt_(subresources) D3D12_MEMCPY_DEST* pDst = nullptr);
static void GetTileShape (D3D12_TILE_SHAPE* pTileShape, DXGI_FORMAT Format, D3D12_RESOURCE_DIMENSION Dimension, UINT SampleCount);
static void Get4KTileShape (D3D12_TILE_SHAPE* pTileShape, DXGI_FORMAT Format, D3D12_RESOURCE_DIMENSION Dimension, UINT SampleCount);
static void GetMipDimensions (UINT8 mipSlice, _Inout_ UINT64* pWidth, _Inout_opt_ UINT64* pHeight = nullptr, _Inout_opt_ UINT64* pDepth = nullptr);
static void GetPlaneSubsampledSizeAndFormatForCopyableLayout(UINT PlaneSlice, DXGI_FORMAT Format, UINT Width, UINT Height, _Out_ DXGI_FORMAT& PlaneFormat, _Out_ UINT& MinPlanePitchWidth, _Out_ UINT& PlaneWidth, _Out_ UINT& PlaneHeight);
static UINT GetDetailTableIndex (DXGI_FORMAT Format);
static UINT GetDetailTableIndexNoThrow (DXGI_FORMAT Format);
static UINT GetDetailTableIndexThrow (DXGI_FORMAT Format);
static bool SupportsDepth (DXGI_FORMAT Format);
static bool SupportsStencil (DXGI_FORMAT Format);
private:
static const FORMAT_DETAIL* GetFormatDetail (DXGI_FORMAT Format);
};
#endif

View File

@@ -0,0 +1,105 @@
//*********************************************************
//
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License (MIT).
//
//*********************************************************
#pragma once
#ifndef __cplusplus
#error D3DX12 requires C++
#endif
#include "d3d12.h"
#if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 609)
inline bool operator==(const D3D12_RENDER_PASS_BEGINNING_ACCESS_PRESERVE_LOCAL_PARAMETERS& a, const D3D12_RENDER_PASS_ENDING_ACCESS_PRESERVE_LOCAL_PARAMETERS& b) noexcept
{
return ((a.AdditionalWidth == b.AdditionalWidth) && (a.AdditionalHeight == b.AdditionalHeight));
}
inline bool operator==(const D3D12_RENDER_PASS_BEGINNING_ACCESS_PRESERVE_LOCAL_PARAMETERS& a, const D3D12_RENDER_PASS_BEGINNING_ACCESS_PRESERVE_LOCAL_PARAMETERS& b) noexcept
{
return ((a.AdditionalWidth == b.AdditionalWidth) && (a.AdditionalHeight == b.AdditionalHeight));
}
inline bool operator==(const D3D12_RENDER_PASS_ENDING_ACCESS_PRESERVE_LOCAL_PARAMETERS& a, const D3D12_RENDER_PASS_ENDING_ACCESS_PRESERVE_LOCAL_PARAMETERS& b) noexcept
{
return ((a.AdditionalWidth == b.AdditionalWidth) && (a.AdditionalHeight == b.AdditionalHeight));
}
#endif
inline bool operator==( const D3D12_RENDER_PASS_BEGINNING_ACCESS_CLEAR_PARAMETERS &a, const D3D12_RENDER_PASS_BEGINNING_ACCESS_CLEAR_PARAMETERS &b) noexcept
{
return a.ClearValue == b.ClearValue;
}
inline bool operator==( const D3D12_RENDER_PASS_ENDING_ACCESS_RESOLVE_PARAMETERS &a, const D3D12_RENDER_PASS_ENDING_ACCESS_RESOLVE_PARAMETERS &b) noexcept
{
if (a.pSrcResource != b.pSrcResource) return false;
if (a.pDstResource != b.pDstResource) return false;
if (a.SubresourceCount != b.SubresourceCount) return false;
if (a.Format != b.Format) return false;
if (a.ResolveMode != b.ResolveMode) return false;
if (a.PreserveResolveSource != b.PreserveResolveSource) return false;
return true;
}
inline bool operator==( const D3D12_RENDER_PASS_BEGINNING_ACCESS &a, const D3D12_RENDER_PASS_BEGINNING_ACCESS &b) noexcept
{
if (a.Type != b.Type) return false;
switch (a.Type)
{
case D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_CLEAR:
if (!(a.Clear == b.Clear)) return false;
break;
#if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 609)
case D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE_LOCAL_RENDER:
case D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE_LOCAL_SRV:
case D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE_LOCAL_UAV:
if (!(a.PreserveLocal == b.PreserveLocal)) return false;
break;
#endif
default:
break;
}
return true;
}
inline bool operator==(const D3D12_RENDER_PASS_ENDING_ACCESS& a, const D3D12_RENDER_PASS_ENDING_ACCESS& b) noexcept
{
if (a.Type != b.Type) return false;
switch (a.Type)
{
case D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_RESOLVE:
if (!(a.Resolve == b.Resolve)) return false;
break;
#if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 609)
case D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE_LOCAL_RENDER:
case D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE_LOCAL_SRV:
case D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE_LOCAL_UAV:
if (!(a.PreserveLocal == b.PreserveLocal)) return false;
break;
#endif
default:
break;
}
return true;
}
inline bool operator==( const D3D12_RENDER_PASS_RENDER_TARGET_DESC &a, const D3D12_RENDER_PASS_RENDER_TARGET_DESC &b) noexcept
{
if (a.cpuDescriptor.ptr != b.cpuDescriptor.ptr) return false;
if (!(a.BeginningAccess == b.BeginningAccess)) return false;
if (!(a.EndingAccess == b.EndingAccess)) return false;
return true;
}
inline bool operator==( const D3D12_RENDER_PASS_DEPTH_STENCIL_DESC &a, const D3D12_RENDER_PASS_DEPTH_STENCIL_DESC &b) noexcept
{
if (a.cpuDescriptor.ptr != b.cpuDescriptor.ptr) return false;
if (!(a.DepthBeginningAccess == b.DepthBeginningAccess)) return false;
if (!(a.StencilBeginningAccess == b.StencilBeginningAccess)) return false;
if (!(a.DepthEndingAccess == b.DepthEndingAccess)) return false;
if (!(a.StencilEndingAccess == b.StencilEndingAccess)) return false;
return true;
}

View File

@@ -0,0 +1,603 @@
//*********************************************************
//
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License (MIT).
//
//*********************************************************
#pragma once
#ifndef __cplusplus
#error D3DX12 requires C++
#endif
#include "d3dx12_property_format_table.h"
#include "d3d12.h"
#include "d3dx12_core.h"
//------------------------------------------------------------------------------------------------
template <typename T, typename U, typename V>
inline void D3D12DecomposeSubresource( UINT Subresource, UINT MipLevels, UINT ArraySize, _Out_ T& MipSlice, _Out_ U& ArraySlice, _Out_ V& PlaneSlice ) noexcept
{
MipSlice = static_cast<T>(Subresource % MipLevels);
ArraySlice = static_cast<U>((Subresource / MipLevels) % ArraySize);
PlaneSlice = static_cast<V>(Subresource / (MipLevels * ArraySize));
}
//------------------------------------------------------------------------------------------------
// Row-by-row memcpy
inline void MemcpySubresource(
_In_ const D3D12_MEMCPY_DEST* pDest,
_In_ const D3D12_SUBRESOURCE_DATA* pSrc,
SIZE_T RowSizeInBytes,
UINT NumRows,
UINT NumSlices) noexcept
{
for (UINT z = 0; z < NumSlices; ++z)
{
auto pDestSlice = static_cast<BYTE*>(pDest->pData) + pDest->SlicePitch * z;
auto pSrcSlice = static_cast<const BYTE*>(pSrc->pData) + pSrc->SlicePitch * LONG_PTR(z);
for (UINT y = 0; y < NumRows; ++y)
{
memcpy(pDestSlice + pDest->RowPitch * y,
pSrcSlice + pSrc->RowPitch * LONG_PTR(y),
RowSizeInBytes);
}
}
}
//------------------------------------------------------------------------------------------------
// Row-by-row memcpy
inline void MemcpySubresource(
_In_ const D3D12_MEMCPY_DEST* pDest,
_In_ const void* pResourceData,
_In_ const D3D12_SUBRESOURCE_INFO* pSrc,
SIZE_T RowSizeInBytes,
UINT NumRows,
UINT NumSlices) noexcept
{
for (UINT z = 0; z < NumSlices; ++z)
{
auto pDestSlice = static_cast<BYTE*>(pDest->pData) + pDest->SlicePitch * z;
auto pSrcSlice = (static_cast<const BYTE*>(pResourceData) + pSrc->Offset) + pSrc->DepthPitch * ULONG_PTR(z);
for (UINT y = 0; y < NumRows; ++y)
{
memcpy(pDestSlice + pDest->RowPitch * y,
pSrcSlice + pSrc->RowPitch * ULONG_PTR(y),
RowSizeInBytes);
}
}
}
//------------------------------------------------------------------------------------------------
// Returns required size of a buffer to be used for data upload
inline UINT64 GetRequiredIntermediateSize(
_In_ ID3D12Resource* pDestinationResource,
_In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource,
_In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources) noexcept
{
#if defined(_MSC_VER) || !defined(_WIN32)
const auto Desc = pDestinationResource->GetDesc();
#else
D3D12_RESOURCE_DESC tmpDesc;
const auto& Desc = *pDestinationResource->GetDesc(&tmpDesc);
#endif
UINT64 RequiredSize = 0;
ID3D12Device* pDevice = nullptr;
pDestinationResource->GetDevice(IID_ID3D12Device, reinterpret_cast<void**>(&pDevice));
pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, 0, nullptr, nullptr, nullptr, &RequiredSize);
pDevice->Release();
return RequiredSize;
}
//------------------------------------------------------------------------------------------------
// All arrays must be populated (e.g. by calling GetCopyableFootprints)
inline UINT64 UpdateSubresources(
_In_ ID3D12GraphicsCommandList* pCmdList,
_In_ ID3D12Resource* pDestinationResource,
_In_ ID3D12Resource* pIntermediate,
_In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource,
_In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources,
UINT64 RequiredSize,
_In_reads_(NumSubresources) const D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts,
_In_reads_(NumSubresources) const UINT* pNumRows,
_In_reads_(NumSubresources) const UINT64* pRowSizesInBytes,
_In_reads_(NumSubresources) const D3D12_SUBRESOURCE_DATA* pSrcData) noexcept
{
// Minor validation
#if defined(_MSC_VER) || !defined(_WIN32)
const auto IntermediateDesc = pIntermediate->GetDesc();
const auto DestinationDesc = pDestinationResource->GetDesc();
#else
D3D12_RESOURCE_DESC tmpDesc1, tmpDesc2;
const auto& IntermediateDesc = *pIntermediate->GetDesc(&tmpDesc1);
const auto& DestinationDesc = *pDestinationResource->GetDesc(&tmpDesc2);
#endif
if (IntermediateDesc.Dimension != D3D12_RESOURCE_DIMENSION_BUFFER ||
IntermediateDesc.Width < RequiredSize + pLayouts[0].Offset ||
RequiredSize > SIZE_T(-1) ||
(DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER &&
(FirstSubresource != 0 || NumSubresources != 1)))
{
return 0;
}
BYTE* pData;
HRESULT hr = pIntermediate->Map(0, nullptr, reinterpret_cast<void**>(&pData));
if (FAILED(hr))
{
return 0;
}
for (UINT i = 0; i < NumSubresources; ++i)
{
if (pRowSizesInBytes[i] > SIZE_T(-1)) return 0;
D3D12_MEMCPY_DEST DestData = { pData + pLayouts[i].Offset, pLayouts[i].Footprint.RowPitch, SIZE_T(pLayouts[i].Footprint.RowPitch) * SIZE_T(pNumRows[i]) };
MemcpySubresource(&DestData, &pSrcData[i], static_cast<SIZE_T>(pRowSizesInBytes[i]), pNumRows[i], pLayouts[i].Footprint.Depth);
}
pIntermediate->Unmap(0, nullptr);
if (DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER)
{
pCmdList->CopyBufferRegion(
pDestinationResource, 0, pIntermediate, pLayouts[0].Offset, pLayouts[0].Footprint.Width);
}
else
{
for (UINT i = 0; i < NumSubresources; ++i)
{
const CD3DX12_TEXTURE_COPY_LOCATION Dst(pDestinationResource, i + FirstSubresource);
const CD3DX12_TEXTURE_COPY_LOCATION Src(pIntermediate, pLayouts[i]);
pCmdList->CopyTextureRegion(&Dst, 0, 0, 0, &Src, nullptr);
}
}
return RequiredSize;
}
//------------------------------------------------------------------------------------------------
// All arrays must be populated (e.g. by calling GetCopyableFootprints)
inline UINT64 UpdateSubresources(
_In_ ID3D12GraphicsCommandList* pCmdList,
_In_ ID3D12Resource* pDestinationResource,
_In_ ID3D12Resource* pIntermediate,
_In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource,
_In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources,
UINT64 RequiredSize,
_In_reads_(NumSubresources) const D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts,
_In_reads_(NumSubresources) const UINT* pNumRows,
_In_reads_(NumSubresources) const UINT64* pRowSizesInBytes,
_In_ const void* pResourceData,
_In_reads_(NumSubresources) const D3D12_SUBRESOURCE_INFO* pSrcData) noexcept
{
// Minor validation
#if defined(_MSC_VER) || !defined(_WIN32)
const auto IntermediateDesc = pIntermediate->GetDesc();
const auto DestinationDesc = pDestinationResource->GetDesc();
#else
D3D12_RESOURCE_DESC tmpDesc1, tmpDesc2;
const auto& IntermediateDesc = *pIntermediate->GetDesc(&tmpDesc1);
const auto& DestinationDesc = *pDestinationResource->GetDesc(&tmpDesc2);
#endif
if (IntermediateDesc.Dimension != D3D12_RESOURCE_DIMENSION_BUFFER ||
IntermediateDesc.Width < RequiredSize + pLayouts[0].Offset ||
RequiredSize > SIZE_T(-1) ||
(DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER &&
(FirstSubresource != 0 || NumSubresources != 1)))
{
return 0;
}
BYTE* pData;
HRESULT hr = pIntermediate->Map(0, nullptr, reinterpret_cast<void**>(&pData));
if (FAILED(hr))
{
return 0;
}
for (UINT i = 0; i < NumSubresources; ++i)
{
if (pRowSizesInBytes[i] > SIZE_T(-1)) return 0;
D3D12_MEMCPY_DEST DestData = { pData + pLayouts[i].Offset, pLayouts[i].Footprint.RowPitch, SIZE_T(pLayouts[i].Footprint.RowPitch) * SIZE_T(pNumRows[i]) };
MemcpySubresource(&DestData, pResourceData, &pSrcData[i], static_cast<SIZE_T>(pRowSizesInBytes[i]), pNumRows[i], pLayouts[i].Footprint.Depth);
}
pIntermediate->Unmap(0, nullptr);
if (DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER)
{
pCmdList->CopyBufferRegion(
pDestinationResource, 0, pIntermediate, pLayouts[0].Offset, pLayouts[0].Footprint.Width);
}
else
{
for (UINT i = 0; i < NumSubresources; ++i)
{
const CD3DX12_TEXTURE_COPY_LOCATION Dst(pDestinationResource, i + FirstSubresource);
const CD3DX12_TEXTURE_COPY_LOCATION Src(pIntermediate, pLayouts[i]);
pCmdList->CopyTextureRegion(&Dst, 0, 0, 0, &Src, nullptr);
}
}
return RequiredSize;
}
//------------------------------------------------------------------------------------------------
// Heap-allocating UpdateSubresources implementation
inline UINT64 UpdateSubresources(
_In_ ID3D12GraphicsCommandList* pCmdList,
_In_ ID3D12Resource* pDestinationResource,
_In_ ID3D12Resource* pIntermediate,
UINT64 IntermediateOffset,
_In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource,
_In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources,
_In_reads_(NumSubresources) const D3D12_SUBRESOURCE_DATA* pSrcData) noexcept
{
UINT64 RequiredSize = 0;
const auto MemToAlloc = static_cast<UINT64>(sizeof(D3D12_PLACED_SUBRESOURCE_FOOTPRINT) + sizeof(UINT) + sizeof(UINT64)) * NumSubresources;
if (MemToAlloc > SIZE_MAX)
{
return 0;
}
void* pMem = HeapAlloc(GetProcessHeap(), 0, static_cast<SIZE_T>(MemToAlloc));
if (pMem == nullptr)
{
return 0;
}
auto pLayouts = static_cast<D3D12_PLACED_SUBRESOURCE_FOOTPRINT*>(pMem);
auto pRowSizesInBytes = reinterpret_cast<UINT64*>(pLayouts + NumSubresources);
auto pNumRows = reinterpret_cast<UINT*>(pRowSizesInBytes + NumSubresources);
#if defined(_MSC_VER) || !defined(_WIN32)
const auto Desc = pDestinationResource->GetDesc();
#else
D3D12_RESOURCE_DESC tmpDesc;
const auto& Desc = *pDestinationResource->GetDesc(&tmpDesc);
#endif
ID3D12Device* pDevice = nullptr;
pDestinationResource->GetDevice(IID_ID3D12Device, reinterpret_cast<void**>(&pDevice));
pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, IntermediateOffset, pLayouts, pNumRows, pRowSizesInBytes, &RequiredSize);
pDevice->Release();
const UINT64 Result = UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, pLayouts, pNumRows, pRowSizesInBytes, pSrcData);
HeapFree(GetProcessHeap(), 0, pMem);
return Result;
}
//------------------------------------------------------------------------------------------------
// Heap-allocating UpdateSubresources implementation
inline UINT64 UpdateSubresources(
_In_ ID3D12GraphicsCommandList* pCmdList,
_In_ ID3D12Resource* pDestinationResource,
_In_ ID3D12Resource* pIntermediate,
UINT64 IntermediateOffset,
_In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource,
_In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources,
_In_ const void* pResourceData,
_In_reads_(NumSubresources) const D3D12_SUBRESOURCE_INFO* pSrcData) noexcept
{
UINT64 RequiredSize = 0;
const auto MemToAlloc = static_cast<UINT64>(sizeof(D3D12_PLACED_SUBRESOURCE_FOOTPRINT) + sizeof(UINT) + sizeof(UINT64)) * NumSubresources;
if (MemToAlloc > SIZE_MAX)
{
return 0;
}
void* pMem = HeapAlloc(GetProcessHeap(), 0, static_cast<SIZE_T>(MemToAlloc));
if (pMem == nullptr)
{
return 0;
}
auto pLayouts = static_cast<D3D12_PLACED_SUBRESOURCE_FOOTPRINT*>(pMem);
auto pRowSizesInBytes = reinterpret_cast<UINT64*>(pLayouts + NumSubresources);
auto pNumRows = reinterpret_cast<UINT*>(pRowSizesInBytes + NumSubresources);
#if defined(_MSC_VER) || !defined(_WIN32)
const auto Desc = pDestinationResource->GetDesc();
#else
D3D12_RESOURCE_DESC tmpDesc;
const auto& Desc = *pDestinationResource->GetDesc(&tmpDesc);
#endif
ID3D12Device* pDevice = nullptr;
pDestinationResource->GetDevice(IID_ID3D12Device, reinterpret_cast<void**>(&pDevice));
pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, IntermediateOffset, pLayouts, pNumRows, pRowSizesInBytes, &RequiredSize);
pDevice->Release();
const UINT64 Result = UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, pLayouts, pNumRows, pRowSizesInBytes, pResourceData, pSrcData);
HeapFree(GetProcessHeap(), 0, pMem);
return Result;
}
//------------------------------------------------------------------------------------------------
// Stack-allocating UpdateSubresources implementation
template <UINT MaxSubresources>
inline UINT64 UpdateSubresources(
_In_ ID3D12GraphicsCommandList* pCmdList,
_In_ ID3D12Resource* pDestinationResource,
_In_ ID3D12Resource* pIntermediate,
UINT64 IntermediateOffset,
_In_range_(0,MaxSubresources) UINT FirstSubresource,
_In_range_(1,MaxSubresources-FirstSubresource) UINT NumSubresources,
_In_reads_(NumSubresources) const D3D12_SUBRESOURCE_DATA* pSrcData) noexcept
{
UINT64 RequiredSize = 0;
D3D12_PLACED_SUBRESOURCE_FOOTPRINT Layouts[MaxSubresources];
UINT NumRows[MaxSubresources];
UINT64 RowSizesInBytes[MaxSubresources];
#if defined(_MSC_VER) || !defined(_WIN32)
const auto Desc = pDestinationResource->GetDesc();
#else
D3D12_RESOURCE_DESC tmpDesc;
const auto& Desc = *pDestinationResource->GetDesc(&tmpDesc);
#endif
ID3D12Device* pDevice = nullptr;
pDestinationResource->GetDevice(IID_ID3D12Device, reinterpret_cast<void**>(&pDevice));
pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, IntermediateOffset, Layouts, NumRows, RowSizesInBytes, &RequiredSize);
pDevice->Release();
return UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, Layouts, NumRows, RowSizesInBytes, pSrcData);
}
//------------------------------------------------------------------------------------------------
// Stack-allocating UpdateSubresources implementation
template <UINT MaxSubresources>
inline UINT64 UpdateSubresources(
_In_ ID3D12GraphicsCommandList* pCmdList,
_In_ ID3D12Resource* pDestinationResource,
_In_ ID3D12Resource* pIntermediate,
UINT64 IntermediateOffset,
_In_range_(0,MaxSubresources) UINT FirstSubresource,
_In_range_(1,MaxSubresources-FirstSubresource) UINT NumSubresources,
_In_ const void* pResourceData,
_In_reads_(NumSubresources) const D3D12_SUBRESOURCE_INFO* pSrcData) noexcept
{
UINT64 RequiredSize = 0;
D3D12_PLACED_SUBRESOURCE_FOOTPRINT Layouts[MaxSubresources];
UINT NumRows[MaxSubresources];
UINT64 RowSizesInBytes[MaxSubresources];
#if defined(_MSC_VER) || !defined(_WIN32)
const auto Desc = pDestinationResource->GetDesc();
#else
D3D12_RESOURCE_DESC tmpDesc;
const auto& Desc = *pDestinationResource->GetDesc(&tmpDesc);
#endif
ID3D12Device* pDevice = nullptr;
pDestinationResource->GetDevice(IID_ID3D12Device, reinterpret_cast<void**>(&pDevice));
pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, IntermediateOffset, Layouts, NumRows, RowSizesInBytes, &RequiredSize);
pDevice->Release();
return UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, Layouts, NumRows, RowSizesInBytes, pResourceData, pSrcData);
}
//------------------------------------------------------------------------------------------------
constexpr bool D3D12IsLayoutOpaque( D3D12_TEXTURE_LAYOUT Layout ) noexcept
{ return Layout == D3D12_TEXTURE_LAYOUT_UNKNOWN || Layout == D3D12_TEXTURE_LAYOUT_64KB_UNDEFINED_SWIZZLE; }
//------------------------------------------------------------------------------------------------
template< typename T >
inline T D3DX12Align(T uValue, T uAlign)
{
// Assert power of 2 alignment
D3DX12_ASSERT(0 == (uAlign & (uAlign - 1)));
T uMask = uAlign - 1;
T uResult = (uValue + uMask) & ~uMask;
D3DX12_ASSERT(uResult >= uValue);
D3DX12_ASSERT(0 == (uResult % uAlign));
return uResult;
}
//------------------------------------------------------------------------------------------------
template< typename T >
inline T D3DX12AlignAtLeast(T uValue, T uAlign)
{
T aligned = D3DX12Align(uValue, uAlign);
return aligned > uAlign ? aligned : uAlign;
}
inline const CD3DX12_RESOURCE_DESC1* D3DX12ConditionallyExpandAPIDesc(
D3D12_RESOURCE_DESC1& LclDesc,
const D3D12_RESOURCE_DESC1* pDesc)
{
return D3DX12ConditionallyExpandAPIDesc(static_cast<CD3DX12_RESOURCE_DESC1&>(LclDesc), static_cast<const CD3DX12_RESOURCE_DESC1*>(pDesc));
}
#if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 606)
//------------------------------------------------------------------------------------------------
// The difference between D3DX12GetCopyableFootprints and ID3D12Device::GetCopyableFootprints
// is that this one loses a lot of error checking by assuming the arguments are correct
inline bool D3DX12GetCopyableFootprints(
_In_ const D3D12_RESOURCE_DESC1& ResourceDesc,
_In_range_(0, D3D12_REQ_SUBRESOURCES) UINT FirstSubresource,
_In_range_(0, D3D12_REQ_SUBRESOURCES - FirstSubresource) UINT NumSubresources,
UINT64 BaseOffset,
_Out_writes_opt_(NumSubresources) D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts,
_Out_writes_opt_(NumSubresources) UINT* pNumRows,
_Out_writes_opt_(NumSubresources) UINT64* pRowSizeInBytes,
_Out_opt_ UINT64* pTotalBytes)
{
constexpr UINT64 uint64_max = ~0ull;
UINT64 TotalBytes = uint64_max;
UINT uSubRes = 0;
bool bResourceOverflow = false;
TotalBytes = 0;
const DXGI_FORMAT Format = ResourceDesc.Format;
CD3DX12_RESOURCE_DESC1 LresourceDesc;
const CD3DX12_RESOURCE_DESC1& resourceDesc = *D3DX12ConditionallyExpandAPIDesc(LresourceDesc, &ResourceDesc);
// Check if its a valid format
D3DX12_ASSERT(D3D12_PROPERTY_LAYOUT_FORMAT_TABLE::FormatExists(Format));
const UINT WidthAlignment = D3D12_PROPERTY_LAYOUT_FORMAT_TABLE::GetWidthAlignment( Format );
const UINT HeightAlignment = D3D12_PROPERTY_LAYOUT_FORMAT_TABLE::GetHeightAlignment( Format );
const UINT16 DepthAlignment = UINT16( D3D12_PROPERTY_LAYOUT_FORMAT_TABLE::GetDepthAlignment( Format ) );
for (; uSubRes < NumSubresources; ++uSubRes)
{
bool bOverflow = false;
UINT Subresource = FirstSubresource + uSubRes;
D3DX12_ASSERT(resourceDesc.MipLevels != 0);
UINT subresourceCount = resourceDesc.MipLevels * resourceDesc.ArraySize() * D3D12_PROPERTY_LAYOUT_FORMAT_TABLE::GetPlaneCount(resourceDesc.Format);
if (Subresource > subresourceCount)
{
break;
}
TotalBytes = D3DX12Align< UINT64 >( TotalBytes, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT );
UINT MipLevel, ArraySlice, PlaneSlice;
D3D12DecomposeSubresource(Subresource, resourceDesc.MipLevels, resourceDesc.ArraySize(), /*_Out_*/MipLevel, /*_Out_*/ArraySlice, /*_Out_*/PlaneSlice);
const UINT64 Width = D3DX12AlignAtLeast<UINT64>(resourceDesc.Width >> MipLevel, WidthAlignment);
const UINT Height = D3DX12AlignAtLeast(resourceDesc.Height >> MipLevel, HeightAlignment);
const UINT16 Depth = D3DX12AlignAtLeast<UINT16>(resourceDesc.Depth() >> MipLevel, DepthAlignment);
// Adjust for the current PlaneSlice. Most formats have only one plane.
DXGI_FORMAT PlaneFormat;
UINT32 MinPlanePitchWidth, PlaneWidth, PlaneHeight;
D3D12_PROPERTY_LAYOUT_FORMAT_TABLE::GetPlaneSubsampledSizeAndFormatForCopyableLayout(PlaneSlice, Format, (UINT)Width, Height, /*_Out_*/ PlaneFormat, /*_Out_*/ MinPlanePitchWidth, /* _Out_ */ PlaneWidth, /*_Out_*/ PlaneHeight);
D3D12_SUBRESOURCE_FOOTPRINT LocalPlacement = {};
auto& Placement = pLayouts ? pLayouts[uSubRes].Footprint : LocalPlacement;
Placement.Format = PlaneFormat;
Placement.Width = PlaneWidth;
Placement.Height = PlaneHeight;
Placement.Depth = Depth;
// Calculate row pitch
UINT MinPlaneRowPitch = 0;
D3D12_PROPERTY_LAYOUT_FORMAT_TABLE::CalculateMinimumRowMajorRowPitch(PlaneFormat, MinPlanePitchWidth, MinPlaneRowPitch);
// Formats with more than one plane choose a larger pitch alignment to ensure that each plane begins on the row
// immediately following the previous plane while still adhering to subresource alignment restrictions.
static_assert( D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT >= D3D12_TEXTURE_DATA_PITCH_ALIGNMENT
&& ((D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT % D3D12_TEXTURE_DATA_PITCH_ALIGNMENT) == 0),
"D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT must be >= and evenly divisible by D3D12_TEXTURE_DATA_PITCH_ALIGNMENT." );
Placement.RowPitch = D3D12_PROPERTY_LAYOUT_FORMAT_TABLE::Planar(Format)
? D3DX12Align< UINT >( MinPlaneRowPitch, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT )
: D3DX12Align< UINT >( MinPlaneRowPitch, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT );
if (pRowSizeInBytes)
{
UINT PlaneRowSize = 0;
D3D12_PROPERTY_LAYOUT_FORMAT_TABLE::CalculateMinimumRowMajorRowPitch(PlaneFormat, PlaneWidth, PlaneRowSize);
pRowSizeInBytes[uSubRes] = PlaneRowSize;
}
// Number of rows (accounting for block compression and additional planes)
UINT NumRows = 0;
if (D3D12_PROPERTY_LAYOUT_FORMAT_TABLE::Planar(Format))
{
NumRows = PlaneHeight;
}
else
{
D3DX12_ASSERT(Height % HeightAlignment == 0);
NumRows = Height / HeightAlignment;
}
if (pNumRows)
{
pNumRows[uSubRes] = NumRows;
}
// Offsetting
if (pLayouts)
{
pLayouts[uSubRes].Offset = (bOverflow ? uint64_max : TotalBytes + BaseOffset);
}
const UINT16 NumSlices = Depth;
const UINT64 SubresourceSize = (NumRows * NumSlices - 1) * Placement.RowPitch + MinPlaneRowPitch;
// uint64 addition with overflow checking
TotalBytes = TotalBytes + SubresourceSize;
if(TotalBytes < SubresourceSize)
{
TotalBytes = uint64_max;
}
bResourceOverflow = bResourceOverflow || bOverflow;
}
// Overflow error
if (bResourceOverflow)
{
TotalBytes = uint64_max;
}
if (pLayouts)
{
memset( pLayouts + uSubRes, -1, sizeof( *pLayouts ) * (NumSubresources - uSubRes) );
}
if (pNumRows)
{
memset(pNumRows + uSubRes, -1, sizeof(*pNumRows) * (NumSubresources - uSubRes));
}
if (pRowSizeInBytes)
{
memset(pRowSizeInBytes + uSubRes, -1, sizeof(*pRowSizeInBytes) * (NumSubresources - uSubRes));
}
if (pTotalBytes)
{
*pTotalBytes = TotalBytes;
}
if(TotalBytes == uint64_max)
{
return false;
}
return true;
}
//------------------------------------------------------------------------------------------------
inline D3D12_RESOURCE_DESC1 D3DX12ResourceDesc0ToDesc1(D3D12_RESOURCE_DESC const& desc0)
{
D3D12_RESOURCE_DESC1 desc1;
desc1.Dimension = desc0.Dimension;
desc1.Alignment = desc0.Alignment;
desc1.Width = desc0.Width;
desc1.Height = desc0.Height;
desc1.DepthOrArraySize = desc0.DepthOrArraySize;
desc1.MipLevels = desc0.MipLevels;
desc1.Format = desc0.Format;
desc1.SampleDesc.Count = desc0.SampleDesc.Count;
desc1.SampleDesc.Quality = desc0.SampleDesc.Quality;
desc1.Layout = desc0.Layout;
desc1.Flags = desc0.Flags;
desc1.SamplerFeedbackMipRegion.Width = 0;
desc1.SamplerFeedbackMipRegion.Height = 0;
desc1.SamplerFeedbackMipRegion.Depth = 0;
return desc1;
}
//------------------------------------------------------------------------------------------------
inline bool D3DX12GetCopyableFootprints(
_In_ const D3D12_RESOURCE_DESC& pResourceDesc,
_In_range_(0, D3D12_REQ_SUBRESOURCES) UINT FirstSubresource,
_In_range_(0, D3D12_REQ_SUBRESOURCES - FirstSubresource) UINT NumSubresources,
UINT64 BaseOffset,
_Out_writes_opt_(NumSubresources) D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts,
_Out_writes_opt_(NumSubresources) UINT* pNumRows,
_Out_writes_opt_(NumSubresources) UINT64* pRowSizeInBytes,
_Out_opt_ UINT64* pTotalBytes)
{
// From D3D12_RESOURCE_DESC to D3D12_RESOURCE_DESC1
D3D12_RESOURCE_DESC1 desc = D3DX12ResourceDesc0ToDesc1(pResourceDesc);
return D3DX12GetCopyableFootprints(
*static_cast<CD3DX12_RESOURCE_DESC1*>(&desc),// From D3D12_RESOURCE_DESC1 to CD3DX12_RESOURCE_DESC1
FirstSubresource,
NumSubresources,
BaseOffset,
pLayouts,
pNumRows,
pRowSizeInBytes,
pTotalBytes);
}
#endif // D3D12_SDK_VERSION >= 606

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,144 @@
//
// Copyright (C) Microsoft Corporation.
// Licensed under the MIT license
//
#ifndef __dxgiformat_h__
#define __dxgiformat_h__
#define DXGI_FORMAT_DEFINED 1
typedef enum DXGI_FORMAT
{
DXGI_FORMAT_UNKNOWN = 0,
DXGI_FORMAT_R32G32B32A32_TYPELESS = 1,
DXGI_FORMAT_R32G32B32A32_FLOAT = 2,
DXGI_FORMAT_R32G32B32A32_UINT = 3,
DXGI_FORMAT_R32G32B32A32_SINT = 4,
DXGI_FORMAT_R32G32B32_TYPELESS = 5,
DXGI_FORMAT_R32G32B32_FLOAT = 6,
DXGI_FORMAT_R32G32B32_UINT = 7,
DXGI_FORMAT_R32G32B32_SINT = 8,
DXGI_FORMAT_R16G16B16A16_TYPELESS = 9,
DXGI_FORMAT_R16G16B16A16_FLOAT = 10,
DXGI_FORMAT_R16G16B16A16_UNORM = 11,
DXGI_FORMAT_R16G16B16A16_UINT = 12,
DXGI_FORMAT_R16G16B16A16_SNORM = 13,
DXGI_FORMAT_R16G16B16A16_SINT = 14,
DXGI_FORMAT_R32G32_TYPELESS = 15,
DXGI_FORMAT_R32G32_FLOAT = 16,
DXGI_FORMAT_R32G32_UINT = 17,
DXGI_FORMAT_R32G32_SINT = 18,
DXGI_FORMAT_R32G8X24_TYPELESS = 19,
DXGI_FORMAT_D32_FLOAT_S8X24_UINT = 20,
DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS = 21,
DXGI_FORMAT_X32_TYPELESS_G8X24_UINT = 22,
DXGI_FORMAT_R10G10B10A2_TYPELESS = 23,
DXGI_FORMAT_R10G10B10A2_UNORM = 24,
DXGI_FORMAT_R10G10B10A2_UINT = 25,
DXGI_FORMAT_R11G11B10_FLOAT = 26,
DXGI_FORMAT_R8G8B8A8_TYPELESS = 27,
DXGI_FORMAT_R8G8B8A8_UNORM = 28,
DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = 29,
DXGI_FORMAT_R8G8B8A8_UINT = 30,
DXGI_FORMAT_R8G8B8A8_SNORM = 31,
DXGI_FORMAT_R8G8B8A8_SINT = 32,
DXGI_FORMAT_R16G16_TYPELESS = 33,
DXGI_FORMAT_R16G16_FLOAT = 34,
DXGI_FORMAT_R16G16_UNORM = 35,
DXGI_FORMAT_R16G16_UINT = 36,
DXGI_FORMAT_R16G16_SNORM = 37,
DXGI_FORMAT_R16G16_SINT = 38,
DXGI_FORMAT_R32_TYPELESS = 39,
DXGI_FORMAT_D32_FLOAT = 40,
DXGI_FORMAT_R32_FLOAT = 41,
DXGI_FORMAT_R32_UINT = 42,
DXGI_FORMAT_R32_SINT = 43,
DXGI_FORMAT_R24G8_TYPELESS = 44,
DXGI_FORMAT_D24_UNORM_S8_UINT = 45,
DXGI_FORMAT_R24_UNORM_X8_TYPELESS = 46,
DXGI_FORMAT_X24_TYPELESS_G8_UINT = 47,
DXGI_FORMAT_R8G8_TYPELESS = 48,
DXGI_FORMAT_R8G8_UNORM = 49,
DXGI_FORMAT_R8G8_UINT = 50,
DXGI_FORMAT_R8G8_SNORM = 51,
DXGI_FORMAT_R8G8_SINT = 52,
DXGI_FORMAT_R16_TYPELESS = 53,
DXGI_FORMAT_R16_FLOAT = 54,
DXGI_FORMAT_D16_UNORM = 55,
DXGI_FORMAT_R16_UNORM = 56,
DXGI_FORMAT_R16_UINT = 57,
DXGI_FORMAT_R16_SNORM = 58,
DXGI_FORMAT_R16_SINT = 59,
DXGI_FORMAT_R8_TYPELESS = 60,
DXGI_FORMAT_R8_UNORM = 61,
DXGI_FORMAT_R8_UINT = 62,
DXGI_FORMAT_R8_SNORM = 63,
DXGI_FORMAT_R8_SINT = 64,
DXGI_FORMAT_A8_UNORM = 65,
DXGI_FORMAT_R1_UNORM = 66,
DXGI_FORMAT_R9G9B9E5_SHAREDEXP = 67,
DXGI_FORMAT_R8G8_B8G8_UNORM = 68,
DXGI_FORMAT_G8R8_G8B8_UNORM = 69,
DXGI_FORMAT_BC1_TYPELESS = 70,
DXGI_FORMAT_BC1_UNORM = 71,
DXGI_FORMAT_BC1_UNORM_SRGB = 72,
DXGI_FORMAT_BC2_TYPELESS = 73,
DXGI_FORMAT_BC2_UNORM = 74,
DXGI_FORMAT_BC2_UNORM_SRGB = 75,
DXGI_FORMAT_BC3_TYPELESS = 76,
DXGI_FORMAT_BC3_UNORM = 77,
DXGI_FORMAT_BC3_UNORM_SRGB = 78,
DXGI_FORMAT_BC4_TYPELESS = 79,
DXGI_FORMAT_BC4_UNORM = 80,
DXGI_FORMAT_BC4_SNORM = 81,
DXGI_FORMAT_BC5_TYPELESS = 82,
DXGI_FORMAT_BC5_UNORM = 83,
DXGI_FORMAT_BC5_SNORM = 84,
DXGI_FORMAT_B5G6R5_UNORM = 85,
DXGI_FORMAT_B5G5R5A1_UNORM = 86,
DXGI_FORMAT_B8G8R8A8_UNORM = 87,
DXGI_FORMAT_B8G8R8X8_UNORM = 88,
DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM = 89,
DXGI_FORMAT_B8G8R8A8_TYPELESS = 90,
DXGI_FORMAT_B8G8R8A8_UNORM_SRGB = 91,
DXGI_FORMAT_B8G8R8X8_TYPELESS = 92,
DXGI_FORMAT_B8G8R8X8_UNORM_SRGB = 93,
DXGI_FORMAT_BC6H_TYPELESS = 94,
DXGI_FORMAT_BC6H_UF16 = 95,
DXGI_FORMAT_BC6H_SF16 = 96,
DXGI_FORMAT_BC7_TYPELESS = 97,
DXGI_FORMAT_BC7_UNORM = 98,
DXGI_FORMAT_BC7_UNORM_SRGB = 99,
DXGI_FORMAT_AYUV = 100,
DXGI_FORMAT_Y410 = 101,
DXGI_FORMAT_Y416 = 102,
DXGI_FORMAT_NV12 = 103,
DXGI_FORMAT_P010 = 104,
DXGI_FORMAT_P016 = 105,
DXGI_FORMAT_420_OPAQUE = 106,
DXGI_FORMAT_YUY2 = 107,
DXGI_FORMAT_Y210 = 108,
DXGI_FORMAT_Y216 = 109,
DXGI_FORMAT_NV11 = 110,
DXGI_FORMAT_AI44 = 111,
DXGI_FORMAT_IA44 = 112,
DXGI_FORMAT_P8 = 113,
DXGI_FORMAT_A8P8 = 114,
DXGI_FORMAT_B4G4R4A4_UNORM = 115,
DXGI_FORMAT_P208 = 130,
DXGI_FORMAT_V208 = 131,
DXGI_FORMAT_V408 = 132,
DXGI_FORMAT_SAMPLER_FEEDBACK_MIN_MIP_OPAQUE = 189,
DXGI_FORMAT_SAMPLER_FEEDBACK_MIP_REGION_USED_OPAQUE = 190,
DXGI_FORMAT_A4B4G4R4_UNORM = 191,
DXGI_FORMAT_FORCE_UINT = 0xffffffff
} DXGI_FORMAT;
#endif // __dxgiformat_h__

View File

@@ -0,0 +1,139 @@
//
// Copyright (C) Microsoft Corporation.
// Licensed under the MIT license
//
typedef enum DXGI_FORMAT
{
DXGI_FORMAT_UNKNOWN = 0,
DXGI_FORMAT_R32G32B32A32_TYPELESS = 1,
DXGI_FORMAT_R32G32B32A32_FLOAT = 2,
DXGI_FORMAT_R32G32B32A32_UINT = 3,
DXGI_FORMAT_R32G32B32A32_SINT = 4,
DXGI_FORMAT_R32G32B32_TYPELESS = 5,
DXGI_FORMAT_R32G32B32_FLOAT = 6,
DXGI_FORMAT_R32G32B32_UINT = 7,
DXGI_FORMAT_R32G32B32_SINT = 8,
DXGI_FORMAT_R16G16B16A16_TYPELESS = 9,
DXGI_FORMAT_R16G16B16A16_FLOAT = 10,
DXGI_FORMAT_R16G16B16A16_UNORM = 11,
DXGI_FORMAT_R16G16B16A16_UINT = 12,
DXGI_FORMAT_R16G16B16A16_SNORM = 13,
DXGI_FORMAT_R16G16B16A16_SINT = 14,
DXGI_FORMAT_R32G32_TYPELESS = 15,
DXGI_FORMAT_R32G32_FLOAT = 16,
DXGI_FORMAT_R32G32_UINT = 17,
DXGI_FORMAT_R32G32_SINT = 18,
DXGI_FORMAT_R32G8X24_TYPELESS = 19,
DXGI_FORMAT_D32_FLOAT_S8X24_UINT = 20,
DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS = 21,
DXGI_FORMAT_X32_TYPELESS_G8X24_UINT = 22,
DXGI_FORMAT_R10G10B10A2_TYPELESS = 23,
DXGI_FORMAT_R10G10B10A2_UNORM = 24,
DXGI_FORMAT_R10G10B10A2_UINT = 25,
DXGI_FORMAT_R11G11B10_FLOAT = 26,
DXGI_FORMAT_R8G8B8A8_TYPELESS = 27,
DXGI_FORMAT_R8G8B8A8_UNORM = 28,
DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = 29,
DXGI_FORMAT_R8G8B8A8_UINT = 30,
DXGI_FORMAT_R8G8B8A8_SNORM = 31,
DXGI_FORMAT_R8G8B8A8_SINT = 32,
DXGI_FORMAT_R16G16_TYPELESS = 33,
DXGI_FORMAT_R16G16_FLOAT = 34,
DXGI_FORMAT_R16G16_UNORM = 35,
DXGI_FORMAT_R16G16_UINT = 36,
DXGI_FORMAT_R16G16_SNORM = 37,
DXGI_FORMAT_R16G16_SINT = 38,
DXGI_FORMAT_R32_TYPELESS = 39,
DXGI_FORMAT_D32_FLOAT = 40,
DXGI_FORMAT_R32_FLOAT = 41,
DXGI_FORMAT_R32_UINT = 42,
DXGI_FORMAT_R32_SINT = 43,
DXGI_FORMAT_R24G8_TYPELESS = 44,
DXGI_FORMAT_D24_UNORM_S8_UINT = 45,
DXGI_FORMAT_R24_UNORM_X8_TYPELESS = 46,
DXGI_FORMAT_X24_TYPELESS_G8_UINT = 47,
DXGI_FORMAT_R8G8_TYPELESS = 48,
DXGI_FORMAT_R8G8_UNORM = 49,
DXGI_FORMAT_R8G8_UINT = 50,
DXGI_FORMAT_R8G8_SNORM = 51,
DXGI_FORMAT_R8G8_SINT = 52,
DXGI_FORMAT_R16_TYPELESS = 53,
DXGI_FORMAT_R16_FLOAT = 54,
DXGI_FORMAT_D16_UNORM = 55,
DXGI_FORMAT_R16_UNORM = 56,
DXGI_FORMAT_R16_UINT = 57,
DXGI_FORMAT_R16_SNORM = 58,
DXGI_FORMAT_R16_SINT = 59,
DXGI_FORMAT_R8_TYPELESS = 60,
DXGI_FORMAT_R8_UNORM = 61,
DXGI_FORMAT_R8_UINT = 62,
DXGI_FORMAT_R8_SNORM = 63,
DXGI_FORMAT_R8_SINT = 64,
DXGI_FORMAT_A8_UNORM = 65,
DXGI_FORMAT_R1_UNORM = 66,
DXGI_FORMAT_R9G9B9E5_SHAREDEXP = 67,
DXGI_FORMAT_R8G8_B8G8_UNORM = 68,
DXGI_FORMAT_G8R8_G8B8_UNORM = 69,
DXGI_FORMAT_BC1_TYPELESS = 70,
DXGI_FORMAT_BC1_UNORM = 71,
DXGI_FORMAT_BC1_UNORM_SRGB = 72,
DXGI_FORMAT_BC2_TYPELESS = 73,
DXGI_FORMAT_BC2_UNORM = 74,
DXGI_FORMAT_BC2_UNORM_SRGB = 75,
DXGI_FORMAT_BC3_TYPELESS = 76,
DXGI_FORMAT_BC3_UNORM = 77,
DXGI_FORMAT_BC3_UNORM_SRGB = 78,
DXGI_FORMAT_BC4_TYPELESS = 79,
DXGI_FORMAT_BC4_UNORM = 80,
DXGI_FORMAT_BC4_SNORM = 81,
DXGI_FORMAT_BC5_TYPELESS = 82,
DXGI_FORMAT_BC5_UNORM = 83,
DXGI_FORMAT_BC5_SNORM = 84,
DXGI_FORMAT_B5G6R5_UNORM = 85,
DXGI_FORMAT_B5G5R5A1_UNORM = 86,
DXGI_FORMAT_B8G8R8A8_UNORM = 87,
DXGI_FORMAT_B8G8R8X8_UNORM = 88,
DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM = 89,
DXGI_FORMAT_B8G8R8A8_TYPELESS = 90,
DXGI_FORMAT_B8G8R8A8_UNORM_SRGB = 91,
DXGI_FORMAT_B8G8R8X8_TYPELESS = 92,
DXGI_FORMAT_B8G8R8X8_UNORM_SRGB = 93,
DXGI_FORMAT_BC6H_TYPELESS = 94,
DXGI_FORMAT_BC6H_UF16 = 95,
DXGI_FORMAT_BC6H_SF16 = 96,
DXGI_FORMAT_BC7_TYPELESS = 97,
DXGI_FORMAT_BC7_UNORM = 98,
DXGI_FORMAT_BC7_UNORM_SRGB = 99,
DXGI_FORMAT_AYUV = 100,
DXGI_FORMAT_Y410 = 101,
DXGI_FORMAT_Y416 = 102,
DXGI_FORMAT_NV12 = 103,
DXGI_FORMAT_P010 = 104,
DXGI_FORMAT_P016 = 105,
DXGI_FORMAT_420_OPAQUE = 106,
DXGI_FORMAT_YUY2 = 107,
DXGI_FORMAT_Y210 = 108,
DXGI_FORMAT_Y216 = 109,
DXGI_FORMAT_NV11 = 110,
DXGI_FORMAT_AI44 = 111,
DXGI_FORMAT_IA44 = 112,
DXGI_FORMAT_P8 = 113,
DXGI_FORMAT_A8P8 = 114,
DXGI_FORMAT_B4G4R4A4_UNORM = 115,
DXGI_FORMAT_P208 = 130,
DXGI_FORMAT_V208 = 131,
DXGI_FORMAT_V408 = 132,
DXGI_FORMAT_SAMPLER_FEEDBACK_MIN_MIP_OPAQUE = 189,
DXGI_FORMAT_SAMPLER_FEEDBACK_MIP_REGION_USED_OPAQUE = 190,
DXGI_FORMAT_A4B4G4R4_UNORM = 191,
DXGI_FORMAT_FORCE_UINT = 0xffffffff
} DXGI_FORMAT;

View File

@@ -1,10 +1,11 @@
#include <D3D12CommandList.h>
#include <pch.h> #include <pch.h>
#include <Core/Memory/Allocator.h> #include <Core/Memory/Allocator.h>
#include <Graphics/D3D12/D3D12CommandList.h>
#include <Graphics/D3D12/D3D12GraphicsDevice.h>
#include <Graphics/D3D12/D3D12Synchronization.h> #include <Graphics/D3D12/D3D12Synchronization.h>
#include <Graphics/D3D12/DX12CommandList.h> #include <Graphics/D3D12/D3D12Utils.h>
#include <Graphics/D3D12/DX12GraphicsDevice.h>
#include <Graphics/D3D12/DX12Utils.h>
namespace Juliet::D3D12 namespace Juliet::D3D12
{ {
@@ -24,16 +25,15 @@ namespace Juliet::D3D12
bool CreateAllocator(NonNullPtr<D3D12Driver> driver, NonNullPtr<D3D12CommandListBaseData> baseData, bool CreateAllocator(NonNullPtr<D3D12Driver> driver, NonNullPtr<D3D12CommandListBaseData> baseData,
D3D12_COMMAND_QUEUE_DESC queueDesc) D3D12_COMMAND_QUEUE_DESC queueDesc)
{ {
for (auto& buffer : baseData->Allocator) HRESULT result = ID3D12Device5_CreateCommandAllocator(driver->D3D12Device, queueDesc.Type, IID_ID3D12CommandAllocator,
reinterpret_cast<void**>(&baseData->Allocator));
if (FAILED(result))
{ {
HRESULT result = ID3D12Device5_CreateCommandAllocator(driver->D3D12Device, queueDesc.Type, IID_ID3D12CommandAllocator, Assert(false && "Error not implemented: cannot create ID3D12CommandAllocator");
reinterpret_cast<void**>(&buffer)); return false;
if (FAILED(result))
{
Assert(false && "Error not implemented: cannot create ID3D12CommandAllocator");
return false;
}
} }
ID3D12CommandAllocator_Reset(baseData->Allocator);
return true; return true;
} }
@@ -43,6 +43,8 @@ namespace Juliet::D3D12
std::wstring wide_str = L"CommandList ID:" + std::to_wstring(commandList->ID); std::wstring wide_str = L"CommandList ID:" + std::to_wstring(commandList->ID);
// TODO: Factorize this. Flemme // TODO: Factorize this. Flemme
// Get Proper allocator for the frame. Reset all allocators and the command list with current frame allocator
auto& queueDesc = driver->QueueDesc[ToUnderlying(queueType)]; auto& queueDesc = driver->QueueDesc[ToUnderlying(queueType)];
switch (queueType) switch (queueType)
{ {
@@ -63,6 +65,8 @@ namespace Juliet::D3D12
commandList->GraphicsCommandList.CommandList = d3d12GraphicsCommandList; commandList->GraphicsCommandList.CommandList = d3d12GraphicsCommandList;
ID3D12GraphicsCommandList6_SetName(d3d12GraphicsCommandList, wide_str.c_str()); ID3D12GraphicsCommandList6_SetName(d3d12GraphicsCommandList, wide_str.c_str());
ID3D12GraphicsCommandList6_Reset(d3d12GraphicsCommandList, commandList->GraphicsCommandList.Allocator, nullptr);
return true; return true;
} }
case QueueType::Compute: case QueueType::Compute:
@@ -82,6 +86,8 @@ namespace Juliet::D3D12
commandList->ComputeCommandList.CommandList = d3d12GraphicsCommandList; commandList->ComputeCommandList.CommandList = d3d12GraphicsCommandList;
ID3D12GraphicsCommandList6_SetName(d3d12GraphicsCommandList, wide_str.c_str()); ID3D12GraphicsCommandList6_SetName(d3d12GraphicsCommandList, wide_str.c_str());
ID3D12GraphicsCommandList6_Reset(d3d12GraphicsCommandList, commandList->ComputeCommandList.Allocator, nullptr);
return true; return true;
} }
case QueueType::Copy: case QueueType::Copy:
@@ -99,6 +105,8 @@ namespace Juliet::D3D12
} }
commandList->CopyCommandList.CommandList = d3d12CopyCommandList; commandList->CopyCommandList.CommandList = d3d12CopyCommandList;
ID3D12GraphicsCommandList_SetName(d3d12CopyCommandList, wide_str.c_str()); ID3D12GraphicsCommandList_SetName(d3d12CopyCommandList, wide_str.c_str());
ID3D12GraphicsCommandList_Reset(d3d12CopyCommandList, commandList->CopyCommandList.Allocator, nullptr);
return true; return true;
} }
default: return false; default: return false;
@@ -136,11 +144,23 @@ namespace Juliet::D3D12
commandList->ID = id; commandList->ID = id;
commandList->Driver = driver; commandList->Driver = driver;
// Window Handling
commandList->PresentDataCapacity = 1; commandList->PresentDataCapacity = 1;
commandList->PresentDataCount = 0; commandList->PresentDataCount = 0;
commandList->PresentDatas = commandList->PresentDatas =
static_cast<D3D12PresentData*>(Calloc(commandList->PresentDataCapacity, sizeof(D3D12PresentData))); static_cast<D3D12PresentData*>(Calloc(commandList->PresentDataCapacity, sizeof(D3D12PresentData)));
// Resource tracking
commandList->UsedTextureCapacity = 4;
commandList->UsedTextureCount = 0;
commandList->UsedTextures =
static_cast<D3D12Texture**>(Calloc(commandList->UsedTextureCapacity, sizeof(D3D12Texture*)));
commandList->UsedGraphicsPipelineCapacity = 4;
commandList->UsedGraphicsPipelineCount = 0;
commandList->UsedGraphicsPipelines = static_cast<D3D12GraphicsPipeline**>(
Calloc(commandList->UsedGraphicsPipelineCapacity, sizeof(D3D12GraphicsPipeline*)));
// TODO : Simplify this // TODO : Simplify this
if (!HasD3D12CommandListForQueueType(commandList, queueType)) if (!HasD3D12CommandListForQueueType(commandList, queueType))
{ {
@@ -178,34 +198,6 @@ namespace Juliet::D3D12
D3D12CommandList* commandList = AcquireCommandListFromPool(d3d12Driver, queueType); D3D12CommandList* commandList = AcquireCommandListFromPool(d3d12Driver, queueType);
// Get Proper allocator for the frame and reset both it and the requested queue
uint8 bufferIndex = d3d12Driver->FrameCounter % GPUDriver::kResourceBufferCount;
switch (queueType)
{
case QueueType::Graphics:
{
auto* allocator = commandList->GraphicsCommandList.Allocator[bufferIndex];
ID3D12CommandAllocator_Reset(allocator);
ID3D12GraphicsCommandList6_Reset(commandList->GraphicsCommandList.CommandList, allocator, nullptr);
break;
}
case QueueType::Compute:
{
auto* allocator = commandList->ComputeCommandList.Allocator[bufferIndex];
ID3D12CommandAllocator_Reset(allocator);
ID3D12GraphicsCommandList6_Reset(commandList->ComputeCommandList.CommandList, allocator, nullptr);
break;
}
case QueueType::Copy:
{
auto* allocator = commandList->CopyCommandList.Allocator[bufferIndex];
ID3D12CommandAllocator_Reset(allocator);
ID3D12GraphicsCommandList6_Reset(commandList->CopyCommandList.CommandList, allocator, nullptr);
break;
}
default: Assert(false && "Unsupported QueueType"); return nullptr;
}
commandList->AutoReleaseFence = true; commandList->AutoReleaseFence = true;
return reinterpret_cast<CommandList*>(commandList); return reinterpret_cast<CommandList*>(commandList);
@@ -241,7 +233,7 @@ namespace Juliet::D3D12
HRESULT result = ID3D12GraphicsCommandList_Close(d3d12CommandList->GraphicsCommandList.CommandList); HRESULT result = ID3D12GraphicsCommandList_Close(d3d12CommandList->GraphicsCommandList.CommandList);
if (FAILED(result)) if (FAILED(result))
{ {
LogError(d3d12Driver, "Failed to close command list!", result); LogError(d3d12Driver->D3D12Device, "Failed to close command list!", result);
return false; return false;
} }
@@ -250,7 +242,7 @@ namespace Juliet::D3D12
IID_ID3D12CommandList, reinterpret_cast<void**>(&commandLists[0])); IID_ID3D12CommandList, reinterpret_cast<void**>(&commandLists[0]));
if (FAILED(result)) if (FAILED(result))
{ {
LogError(d3d12Driver, "Failed to convert command list!", result); LogError(d3d12Driver->D3D12Device, "Failed to convert command list!", result);
return false; return false;
} }
@@ -270,7 +262,7 @@ namespace Juliet::D3D12
result = ID3D12CommandQueue_Signal(d3d12Driver->GraphicsQueue, d3d12CommandList->InFlightFence->Handle, D3D12_FENCE_SIGNAL_VALUE); result = ID3D12CommandQueue_Signal(d3d12Driver->GraphicsQueue, d3d12CommandList->InFlightFence->Handle, D3D12_FENCE_SIGNAL_VALUE);
if (FAILED(result)) if (FAILED(result))
{ {
LogError(d3d12Driver, "Failed to enqueue fence signal!", result); LogError(d3d12Driver->D3D12Device, "Failed to enqueue fence signal!", result);
return false; return false;
} }
@@ -329,7 +321,7 @@ namespace Juliet::D3D12
} }
} }
// TODO Destroy anything (buffer, texture, etc...) Internal::DisposePendingResourcces(d3d12Driver);
++d3d12Driver->FrameCounter; ++d3d12Driver->FrameCounter;
@@ -376,6 +368,24 @@ namespace Juliet::D3D12
namespace Internal namespace Internal
{ {
void SetDescriptorHeaps(NonNullPtr<D3D12CommandList> commandList)
{
ID3D12DescriptorHeap* heaps[2];
D3D12DescriptorHeap* viewHeap = nullptr;
D3D12DescriptorHeap* samplerHeap = nullptr;
viewHeap = AcquireDescriptorHeapFromPool(commandList->Driver, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
samplerHeap = AcquireDescriptorHeapFromPool(commandList->Driver, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER);
commandList->CRB_SRV_UAV_Heap = viewHeap;
commandList->RTV_Heap = samplerHeap;
heaps[0] = viewHeap->Handle;
heaps[1] = samplerHeap->Handle;
ID3D12GraphicsCommandList_SetDescriptorHeaps(commandList->GraphicsCommandList.CommandList, 2, heaps);
}
void DestroyCommandList(NonNullPtr<D3D12CommandList> commandList) void DestroyCommandList(NonNullPtr<D3D12CommandList> commandList)
{ {
// TODO : Handle other kind of command list (copy compute) // TODO : Handle other kind of command list (copy compute)
@@ -384,15 +394,11 @@ namespace Juliet::D3D12
ID3D12GraphicsCommandList_Release(commandList->GraphicsCommandList.CommandList); ID3D12GraphicsCommandList_Release(commandList->GraphicsCommandList.CommandList);
} }
for (auto* allocator : commandList->GraphicsCommandList.Allocator) ID3D12CommandAllocator_Release(commandList->GraphicsCommandList.Allocator);
{
if (allocator)
{
ID3D12CommandAllocator_Release(allocator);
}
}
SafeFree(commandList->PresentDatas); SafeFree(commandList->PresentDatas);
SafeFree(commandList->UsedTextures);
SafeFree(commandList->UsedGraphicsPipelines);
Free(commandList.Get()); Free(commandList.Get());
} }
@@ -401,6 +407,40 @@ namespace Juliet::D3D12
// No more presentation data // No more presentation data
commandList->PresentDataCount = 0; commandList->PresentDataCount = 0;
HRESULT result = ID3D12CommandAllocator_Reset(commandList->GraphicsCommandList.Allocator);
if (FAILED(result))
{
LogError(driver->D3D12Device, "Could not reset command allocator", result);
return false;
}
result = ID3D12GraphicsCommandList_Reset(commandList->GraphicsCommandList.CommandList,
commandList->GraphicsCommandList.Allocator, NULL);
if (FAILED(result))
{
LogError(driver->D3D12Device, "Could not reset command list", result);
return false;
}
// Return heap descriptor to pool
ReturnDescriptorHeapToPool(driver, commandList->CRB_SRV_UAV_Heap);
ReturnDescriptorHeapToPool(driver, commandList->RTV_Heap);
commandList->CRB_SRV_UAV_Heap = nullptr;
commandList->RTV_Heap = nullptr;
// Clean up resource tracking
for (uint32 idx = 0; idx < commandList->UsedTextureCount; ++idx)
{
--commandList->UsedTextures[idx]->ReferenceCount;
}
commandList->UsedTextureCount = 0;
for (uint32 idx = 0; idx < commandList->UsedGraphicsPipelineCount; ++idx)
{
--commandList->UsedGraphicsPipelines[idx]->ReferenceCount;
}
commandList->UsedGraphicsPipelineCount = 0;
// Release Fence if needed // Release Fence if needed
if (commandList->AutoReleaseFence) if (commandList->AutoReleaseFence)
{ {
@@ -434,5 +474,35 @@ namespace Juliet::D3D12
return true; return true;
} }
#define TRACK_RESOURCE(resource, type, array, count, capacity) \
uint32 i; \
\
for (i = 0; i < commandList->count; i += 1) \
{ \
if (commandList->array[i] == (resource)) \
{ \
return; \
} \
} \
\
if (commandList->count == commandList->capacity) \
{ \
commandList->capacity += 1; \
commandList->array = (type*)Realloc(commandList->array, commandList->capacity * sizeof(type)); \
} \
commandList->array[commandList->count] = resource; \
commandList->count += 1; \
++(resource)->ReferenceCount;
void TrackGraphicsPipeline(NonNullPtr<D3D12CommandList> commandList, NonNullPtr<D3D12GraphicsPipeline> pipeline)
{
TRACK_RESOURCE(pipeline, D3D12GraphicsPipeline*, UsedGraphicsPipelines, UsedGraphicsPipelineCount, UsedGraphicsPipelineCapacity)
}
void TrackTexture(NonNullPtr<D3D12CommandList> commandList, NonNullPtr<D3D12Texture> texture)
{
TRACK_RESOURCE(texture, D3D12Texture*, UsedTextures, UsedTextureCount, UsedTextureCapacity)
}
} // namespace Internal } // namespace Internal
} // namespace Juliet::D3D12 } // namespace Juliet::D3D12

View File

@@ -2,7 +2,9 @@
#include <Core/Common/NonNullPtr.h> #include <Core/Common/NonNullPtr.h>
#include <Core/Math/Shape.h> #include <Core/Math/Shape.h>
#include <Graphics/D3D12/DX12Includes.h> #include <D3D12Common.h>
#include <D3D12GraphicsPipeline.h>
#include <Graphics/D3D12/D3D12Includes.h>
#include <Graphics/GraphicsDevice.h> #include <Graphics/GraphicsDevice.h>
namespace Juliet::D3D12 namespace Juliet::D3D12
@@ -10,12 +12,13 @@ namespace Juliet::D3D12
// Forward Declare // Forward Declare
struct D3D12Driver; struct D3D12Driver;
struct D3D12Fence; struct D3D12Fence;
struct D3D12Texture;
struct D3D12TextureSubresource; struct D3D12TextureSubresource;
struct D3D12WindowData; struct D3D12WindowData;
struct D3D12CommandListBaseData struct D3D12CommandListBaseData
{ {
ID3D12CommandAllocator* Allocator[GPUDriver::kResourceBufferCount]; ID3D12CommandAllocator* Allocator;
}; };
struct D3D12CopyCommandListData : D3D12CommandListBaseData struct D3D12CopyCommandListData : D3D12CommandListBaseData
@@ -52,8 +55,37 @@ namespace Juliet::D3D12
D3D12GraphicsCommandListData ComputeCommandList; D3D12GraphicsCommandListData ComputeCommandList;
D3D12CopyCommandListData CopyCommandList; D3D12CopyCommandListData CopyCommandList;
D3D12GraphicsPipeline* CurrentGraphicsPipeline;
D3D12TextureSubresource* ColorTargetSubresources[GPUDriver::kMaxColorTargetInfo]; D3D12TextureSubresource* ColorTargetSubresources[GPUDriver::kMaxColorTargetInfo];
D3D12TextureSubresource* ColorResolveSubresources[GPUDriver::kMaxColorTargetInfo]; D3D12TextureSubresource* ColorResolveSubresources[GPUDriver::kMaxColorTargetInfo];
bool NeedVertexBufferBind : 1;
bool NeedVertexSamplerBind : 1;
bool NeedVertexStorageTextureBind : 1;
bool NeedVertexStorageBufferBind : 1;
bool NeedFragmentSamplerBind : 1;
bool NeedFragmentStorageTextureBind : 1;
bool NeedFragmentStorageBufferBind : 1;
bool NeedVertexUniformBufferBind[GPUDriver::kMaxUniformBuffersPerStage];
bool NeedFragmentUniformBufferBind[GPUDriver::kMaxUniformBuffersPerStage];
// D3D12UniformBuffer *vertexUniformBuffers[GPUDriver::kMaxUniformBuffersPerStage];
// D3D12UniformBuffer *fragmentUniformBuffers[GPUDriver::kMaxUniformBuffersPerStage];
Internal::D3D12DescriptorHeap* CRB_SRV_UAV_Heap;
Internal::D3D12DescriptorHeap* RTV_Heap;
// Resource Tracking
D3D12Texture** UsedTextures;
uint32 UsedTextureCount;
uint32 UsedTextureCapacity;
D3D12GraphicsPipeline** UsedGraphicsPipelines;
uint32 UsedGraphicsPipelineCount;
uint32 UsedGraphicsPipelineCapacity;
}; };
extern CommandList* AcquireCommandList(NonNullPtr<GPUDriver> driver, QueueType queueType); extern CommandList* AcquireCommandList(NonNullPtr<GPUDriver> driver, QueueType queueType);
@@ -65,7 +97,12 @@ namespace Juliet::D3D12
namespace Internal namespace Internal
{ {
extern void SetDescriptorHeaps(NonNullPtr<D3D12CommandList> commandList);
extern void DestroyCommandList(NonNullPtr<D3D12CommandList> commandList); extern void DestroyCommandList(NonNullPtr<D3D12CommandList> commandList);
extern bool CleanCommandList(NonNullPtr<D3D12Driver> driver, NonNullPtr<D3D12CommandList> commandList, bool cancel); extern bool CleanCommandList(NonNullPtr<D3D12Driver> driver, NonNullPtr<D3D12CommandList> commandList, bool cancel);
extern void TrackGraphicsPipeline(NonNullPtr<D3D12CommandList> commandList, NonNullPtr<D3D12GraphicsPipeline> pipeline);
extern void TrackTexture(NonNullPtr<D3D12CommandList> commandList, NonNullPtr<D3D12Texture> texture);
} // namespace Internal } // namespace Internal
} // namespace Juliet::D3D12 } // namespace Juliet::D3D12

View File

@@ -1,12 +1,14 @@
#include <pch.h> #include <pch.h>
#include <Core/Memory/Allocator.h> #include <Core/Memory/Allocator.h>
#include <Core/Memory/Utils.h>
#include <Graphics/D3D12/D3D12Common.h> #include <Graphics/D3D12/D3D12Common.h>
#include <Graphics/D3D12/DX12GraphicsDevice.h> #include <Graphics/D3D12/D3D12GraphicsDevice.h>
#include <Graphics/D3D12/DX12Includes.h> #include <Graphics/D3D12/D3D12Includes.h>
#include <Graphics/D3D12/DX12Utils.h> #include <Graphics/D3D12/D3D12Utils.h>
namespace Juliet::D3D12 namespace Juliet::D3D12::Internal
{ {
namespace namespace
{ {
@@ -47,126 +49,72 @@ namespace Juliet::D3D12
} }
} // namespace } // namespace
namespace Internal D3D12StagingDescriptorPool* CreateStagingDescriptorPool(NonNullPtr<D3D12Driver> driver, D3D12_DESCRIPTOR_HEAP_TYPE type)
{ {
D3D12DescriptorHeap* CreateDescriptorHeap(NonNullPtr<D3D12Driver> driver, D3D12_DESCRIPTOR_HEAP_TYPE type, D3D12DescriptorHeap* heap = CreateDescriptorHeap(driver, type, kStagingHeapDescriptorExpectedCount, true);
uint32 count, bool isStaging) if (!heap)
{ {
ID3D12DescriptorHeap* handle; return nullptr;
auto heap = static_cast<D3D12DescriptorHeap*>(Calloc(1, sizeof(D3D12DescriptorHeap)));
if (!heap)
{
return nullptr;
}
heap->CurrentDescriptorIndex = 0;
D3D12_DESCRIPTOR_HEAP_DESC heapDesc;
heapDesc.NumDescriptors = count;
heapDesc.Type = type;
heapDesc.Flags = isStaging ? D3D12_DESCRIPTOR_HEAP_FLAG_NONE : D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
heapDesc.NodeMask = 0;
HRESULT result =
ID3D12Device_CreateDescriptorHeap(driver->D3D12Device, &heapDesc, IID_ID3D12DescriptorHeap, (void**)&handle);
if (FAILED(result))
{
LogError(driver, "Failed to create descriptor heap!", result);
DestroyDescriptorHeap(heap);
return nullptr;
}
heap->Handle = handle;
heap->HeapType = type;
heap->MaxDescriptors = count;
heap->Staging = isStaging;
heap->DescriptorSize = ID3D12Device_GetDescriptorHandleIncrementSize(driver->D3D12Device, type);
ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(handle, &heap->DescriptorHeapCPUStart);
if (!isStaging)
{
ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(handle, &heap->DescriptorHeapGPUStart);
}
return heap;
} }
void DestroyDescriptorHeap(NonNullPtr<D3D12DescriptorHeap> heap) auto pool = static_cast<D3D12StagingDescriptorPool*>(Calloc(1, sizeof(D3D12StagingDescriptorPool)));
// First create the heaps
pool->HeapCount = 1;
pool->Heaps = static_cast<D3D12DescriptorHeap**>(Malloc(sizeof(D3D12DescriptorHeap*)));
pool->Heaps[0] = heap;
pool->FreeDescriptorCapacity = kStagingHeapDescriptorExpectedCount;
pool->FreeDescriptorCount = kStagingHeapDescriptorExpectedCount;
pool->FreeDescriptors =
static_cast<D3D12StagingDescriptor*>(Malloc(kStagingHeapDescriptorExpectedCount * sizeof(D3D12StagingDescriptor)));
InitStagingDescriptorPool(heap, pool);
return pool;
}
bool AssignStagingDescriptor(NonNullPtr<D3D12Driver> driver, D3D12_DESCRIPTOR_HEAP_TYPE type, D3D12StagingDescriptor& outDescriptor)
{
// TODO: Make it thread safe
D3D12StagingDescriptor* descriptor = nullptr;
D3D12StagingDescriptorPool* pool = driver->StagingDescriptorPools[type];
if (pool->FreeDescriptorCount == 0)
{ {
if (heap->Handle) if (!ExtendStagingDescriptorPool(driver, *pool))
{ {
ID3D12DescriptorHeap_Release(heap->Handle); return false;
}
Free(heap.Get());
}
D3D12StagingDescriptorPool* CreateStagingDescriptorPool(NonNullPtr<D3D12Driver> driver, D3D12_DESCRIPTOR_HEAP_TYPE type)
{
D3D12DescriptorHeap* heap = CreateDescriptorHeap(driver, type, kStagingHeapDescriptorExpectedCount, true);
if (!heap)
{
return nullptr;
}
auto pool = static_cast<D3D12StagingDescriptorPool*>(Calloc(1, sizeof(D3D12StagingDescriptorPool)));
// First create the heaps
pool->HeapCount = 1;
pool->Heaps = static_cast<D3D12DescriptorHeap**>(Malloc(sizeof(D3D12DescriptorHeap*)));
pool->Heaps[0] = heap;
pool->FreeDescriptorCapacity = kStagingHeapDescriptorExpectedCount;
pool->FreeDescriptorCount = kStagingHeapDescriptorExpectedCount;
pool->FreeDescriptors = static_cast<D3D12StagingDescriptor*>(
Malloc(kStagingHeapDescriptorExpectedCount * sizeof(D3D12StagingDescriptor)));
InitStagingDescriptorPool(heap, pool);
return pool;
}
bool AssignStagingDescriptor(NonNullPtr<D3D12Driver> driver, D3D12_DESCRIPTOR_HEAP_TYPE type, D3D12StagingDescriptor& outDescriptor)
{
// TODO: Make it thread safe
D3D12StagingDescriptor* descriptor = nullptr;
D3D12StagingDescriptorPool* pool = driver->StagingDescriptorPools[type];
if (pool->FreeDescriptorCount == 0)
{
if (!ExtendStagingDescriptorPool(driver, *pool))
{
return false;
}
}
descriptor = &pool->FreeDescriptors[pool->FreeDescriptorCount - 1];
MemCopy(&outDescriptor, descriptor, sizeof(D3D12StagingDescriptor));
pool->FreeDescriptorCount -= 1;
return true;
}
void ReleaseStagingDescriptor(NonNullPtr<D3D12Driver> driver, D3D12StagingDescriptor& cpuDescriptor)
{
D3D12StagingDescriptorPool* pool = cpuDescriptor.Pool;
if (pool != nullptr)
{
MemCopy(&pool->FreeDescriptors[pool->FreeDescriptorCount], &cpuDescriptor, sizeof(D3D12StagingDescriptor));
pool->FreeDescriptorCount += 1;
} }
} }
void DestroyStagingDescriptorPool(NonNullPtr<D3D12StagingDescriptorPool> pool) descriptor = &pool->FreeDescriptors[pool->FreeDescriptorCount - 1];
{ MemCopy(&outDescriptor, descriptor, sizeof(D3D12StagingDescriptor));
for (uint32 i = 0; i < pool->HeapCount; i += 1) pool->FreeDescriptorCount -= 1;
{
DestroyDescriptorHeap(pool->Heaps[i]);
}
Free(pool->Heaps); return true;
Free(pool->FreeDescriptors); }
Free(pool.Get());
void ReleaseStagingDescriptor(NonNullPtr<D3D12Driver> driver, D3D12StagingDescriptor& cpuDescriptor)
{
D3D12StagingDescriptorPool* pool = cpuDescriptor.Pool;
if (pool != nullptr)
{
MemCopy(&pool->FreeDescriptors[pool->FreeDescriptorCount], &cpuDescriptor, sizeof(D3D12StagingDescriptor));
pool->FreeDescriptorCount += 1;
} }
} // namespace Internal }
} // namespace Juliet::D3D12
void DestroyStagingDescriptorPool(NonNullPtr<D3D12StagingDescriptorPool> pool)
{
for (uint32 i = 0; i < pool->HeapCount; i += 1)
{
DestroyDescriptorHeap(pool->Heaps[i]);
}
Free(pool->Heaps);
Free(pool->FreeDescriptors);
Free(pool.Get());
}
} // namespace Juliet::D3D12::Internal

View File

@@ -2,7 +2,8 @@
#include <Core/Common/NonNullPtr.h> #include <Core/Common/NonNullPtr.h>
#include <Core/Thread/Mutex.h> #include <Core/Thread/Mutex.h>
#include <Graphics/D3D12/DX12Includes.h> #include <Graphics/D3D12/D3D12DescriptorHeap.h>
#include <Graphics/D3D12/D3D12Includes.h>
// Definitions: // Definitions:
// RTV = Render Target View // RTV = Render Target View
@@ -10,6 +11,7 @@
// SRV = Shader Resource View // SRV = Shader Resource View
// UAV = Unordered Access View // UAV = Unordered Access View
// CBV = Constant Buffer View // CBV = Constant Buffer View
// PSO = Pipeline State Object
// Inspired (copy pasted a lot) by SDL GPU // Inspired (copy pasted a lot) by SDL GPU
namespace Juliet::D3D12 namespace Juliet::D3D12
@@ -18,22 +20,9 @@ namespace Juliet::D3D12
struct D3D12Driver; struct D3D12Driver;
struct D3D12StagingDescriptor; struct D3D12StagingDescriptor;
// https://learn.microsoft.com/en-us/windows/win32/direct3d12/descriptor-heaps
struct D3D12DescriptorHeap
{
ID3D12DescriptorHeap* Handle;
D3D12_DESCRIPTOR_HEAP_TYPE HeapType;
D3D12_CPU_DESCRIPTOR_HANDLE DescriptorHeapCPUStart;
D3D12_GPU_DESCRIPTOR_HANDLE DescriptorHeapGPUStart; // only used by GPU heaps
uint32 MaxDescriptors;
uint32 DescriptorSize;
uint32 CurrentDescriptorIndex; // only used by GPU heaps
bool Staging : 1;
};
struct D3D12StagingDescriptorPool struct D3D12StagingDescriptorPool
{ {
D3D12DescriptorHeap** Heaps; Internal::D3D12DescriptorHeap** Heaps;
uint32 HeapCount; uint32 HeapCount;
// Descriptor handles are owned by resources, so these can be thought of as descriptions of a free index within a heap. // Descriptor handles are owned by resources, so these can be thought of as descriptions of a free index within a heap.
@@ -45,18 +34,14 @@ namespace Juliet::D3D12
// https://learn.microsoft.com/en-us/windows/win32/direct3d12/descriptors-overview // https://learn.microsoft.com/en-us/windows/win32/direct3d12/descriptors-overview
struct D3D12StagingDescriptor struct D3D12StagingDescriptor
{ {
D3D12StagingDescriptorPool* Pool; D3D12StagingDescriptorPool* Pool;
D3D12DescriptorHeap* Heap; Internal::D3D12DescriptorHeap* Heap;
D3D12_CPU_DESCRIPTOR_HANDLE CpuHandle; D3D12_CPU_DESCRIPTOR_HANDLE CpuHandle;
uint32 CpuHandleIndex; uint32 CpuHandleIndex;
}; };
namespace Internal namespace Internal
{ {
extern D3D12DescriptorHeap* CreateDescriptorHeap(NonNullPtr<D3D12Driver> driver,
D3D12_DESCRIPTOR_HEAP_TYPE type, uint32 count, bool isStaging);
extern void DestroyDescriptorHeap(NonNullPtr<D3D12DescriptorHeap> heap);
extern D3D12StagingDescriptorPool* CreateStagingDescriptorPool(NonNullPtr<D3D12Driver> driver, D3D12_DESCRIPTOR_HEAP_TYPE type); extern D3D12StagingDescriptorPool* CreateStagingDescriptorPool(NonNullPtr<D3D12Driver> driver, D3D12_DESCRIPTOR_HEAP_TYPE type);
extern bool AssignStagingDescriptor(NonNullPtr<D3D12Driver> driver, D3D12_DESCRIPTOR_HEAP_TYPE type, extern bool AssignStagingDescriptor(NonNullPtr<D3D12Driver> driver, D3D12_DESCRIPTOR_HEAP_TYPE type,
D3D12StagingDescriptor& outDescriptor); D3D12StagingDescriptor& outDescriptor);

View File

@@ -0,0 +1,119 @@
#include <pch.h>
#include <Core/Memory/Allocator.h>
#include <Graphics/D3D12/D3D12DescriptorHeap.h>
#include <Graphics/D3D12/D3D12GraphicsDevice.h>
#include <Graphics/D3D12/D3D12Utils.h>
namespace Juliet::D3D12::Internal
{
D3D12DescriptorHeap* CreateDescriptorHeap(NonNullPtr<D3D12Driver> driver, D3D12_DESCRIPTOR_HEAP_TYPE type, uint32 count, bool isStaging)
{
ID3D12DescriptorHeap* handle;
auto heap = static_cast<D3D12DescriptorHeap*>(Calloc(1, sizeof(D3D12DescriptorHeap)));
if (!heap)
{
return nullptr;
}
heap->CurrentDescriptorIndex = 0;
D3D12_DESCRIPTOR_HEAP_DESC heapDesc;
heapDesc.NumDescriptors = count;
heapDesc.Type = type;
heapDesc.Flags = isStaging ? D3D12_DESCRIPTOR_HEAP_FLAG_NONE : D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
heapDesc.NodeMask = 0;
HRESULT result =
ID3D12Device_CreateDescriptorHeap(driver->D3D12Device, &heapDesc, IID_ID3D12DescriptorHeap, (void**)&handle);
if (FAILED(result))
{
LogError(driver->D3D12Device, "Failed to create descriptor heap!", result);
DestroyDescriptorHeap(heap);
return nullptr;
}
heap->Handle = handle;
heap->HeapType = type;
heap->MaxDescriptors = count;
heap->Staging = isStaging;
heap->DescriptorSize = ID3D12Device_GetDescriptorHandleIncrementSize(driver->D3D12Device, type);
ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(handle, &heap->DescriptorHeapCPUStart);
if (!isStaging)
{
ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(handle, &heap->DescriptorHeapGPUStart);
}
return heap;
}
void DestroyDescriptorHeap(NonNullPtr<D3D12DescriptorHeap> heap)
{
if (heap->Handle)
{
ID3D12DescriptorHeap_Release(heap->Handle);
}
Free(heap.Get());
}
D3D12DescriptorHeap* AcquireDescriptorHeapFromPool(NonNullPtr<D3D12Driver> d3d12Driver, D3D12_DESCRIPTOR_HEAP_TYPE type)
{
D3D12DescriptorHeapPool* pool = nullptr;
uint32 count = 0;
if (type == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV)
{
pool = &d3d12Driver->CRB_SRV_UAV_HeapPool;
count = GPUDriver::kCBV_SRV_UAV_HeapDescriptorCount;
}
else if (type == D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER)
{
pool = &d3d12Driver->RTV_HeapPool;
count = GPUDriver::kSampler_HeapDescriptorCount;
}
Assert(pool != nullptr);
D3D12DescriptorHeap* result = nullptr;
if (pool->Count > 0)
{
result = pool->Heaps[pool->Count - 1];
pool->Count -= 1;
}
else
{
result = CreateDescriptorHeap(d3d12Driver, type, count, false);
}
return result;
}
void ReturnDescriptorHeapToPool(NonNullPtr<D3D12Driver> d3d12Driver, D3D12DescriptorHeap* heap)
{
if (heap == nullptr)
{
return;
}
D3D12DescriptorHeapPool* pool = nullptr;
if (heap->HeapType == D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV)
{
pool = &d3d12Driver->CRB_SRV_UAV_HeapPool;
}
else if (heap->HeapType == D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER)
{
pool = &d3d12Driver->RTV_HeapPool;
}
Assert(pool != nullptr);
heap->CurrentDescriptorIndex = 0;
if (pool->Count >= pool->Capacity)
{
pool->Capacity *= 2;
pool->Heaps =
static_cast<D3D12DescriptorHeap**>(Realloc(pool->Heaps, pool->Capacity * sizeof(D3D12DescriptorHeap*)));
}
pool->Heaps[pool->Count] = heap;
pool->Count += 1;
}
} // namespace Juliet::D3D12::Internal

View File

@@ -0,0 +1,41 @@
#pragma once
#include <Core/Common/NonNullPtr.h>
#include <Graphics/D3D12/D3D12Includes.h>
// Forward declare
namespace Juliet::D3D12
{
struct D3D12Driver;
}
namespace Juliet::D3D12::Internal
{
// https://learn.microsoft.com/en-us/windows/win32/direct3d12/descriptor-heaps
struct D3D12DescriptorHeap
{
ID3D12DescriptorHeap* Handle;
D3D12_DESCRIPTOR_HEAP_TYPE HeapType;
D3D12_CPU_DESCRIPTOR_HANDLE DescriptorHeapCPUStart;
D3D12_GPU_DESCRIPTOR_HANDLE DescriptorHeapGPUStart; // only used by GPU heaps
uint32 MaxDescriptors;
uint32 DescriptorSize;
uint32 CurrentDescriptorIndex; // only used by GPU heaps
bool Staging : 1;
};
struct D3D12DescriptorHeapPool
{
D3D12DescriptorHeap** Heaps;
size_t Capacity;
size_t Count;
};
extern D3D12DescriptorHeap* CreateDescriptorHeap(NonNullPtr<D3D12Driver> driver,
D3D12_DESCRIPTOR_HEAP_TYPE type, uint32 count, bool isStaging);
extern void DestroyDescriptorHeap(NonNullPtr<D3D12DescriptorHeap> heap);
extern D3D12DescriptorHeap* AcquireDescriptorHeapFromPool(NonNullPtr<D3D12Driver> commandList,
D3D12_DESCRIPTOR_HEAP_TYPE type);
extern void ReturnDescriptorHeapToPool(NonNullPtr<D3D12Driver> d3d12Driver, D3D12DescriptorHeap* heap);
} // namespace Juliet::D3D12

View File

@@ -3,20 +3,31 @@
#include <Core/Common/NonNullPtr.h> #include <Core/Common/NonNullPtr.h>
#include <Core/HAL/DynLib/DynamicLibrary.h> #include <Core/HAL/DynLib/DynamicLibrary.h>
#include <Core/Memory/Allocator.h> #include <Core/Memory/Allocator.h>
#include <Graphics/D3D12/D3D12CommandList.h>
#include <Graphics/D3D12/D3D12DescriptorHeap.h>
#include <Graphics/D3D12/D3D12GraphicsDevice.h>
#include <Graphics/D3D12/D3D12GraphicsPipeline.h>
#include <Graphics/D3D12/D3D12Includes.h>
#include <Graphics/D3D12/D3D12RenderPass.h> #include <Graphics/D3D12/D3D12RenderPass.h>
#include <Graphics/D3D12/D3D12Shader.h>
#include <Graphics/D3D12/D3D12SwapChain.h>
#include <Graphics/D3D12/D3D12Synchronization.h> #include <Graphics/D3D12/D3D12Synchronization.h>
#include <Graphics/D3D12/DX12CommandList.h> #include <Graphics/D3D12/D3D12Utils.h>
#include <Graphics/D3D12/DX12GraphicsDevice.h>
#include <Graphics/D3D12/DX12Includes.h>
#include <Graphics/D3D12/DX12SwapChain.h>
#include <Graphics/Graphics.h> #include <Graphics/Graphics.h>
#include <Graphics/GraphicsDevice.h> #include <Graphics/GraphicsDevice.h>
#define D3D12_DLL "d3d12.dll" #define D3D12_DLL "d3d12.dll"
#define D3D12_CREATEDEVICE_FUNC "D3D12CreateDevice" #define D3D12_CREATEDEVICE_FUNC "D3D12CreateDevice"
#define D3D12_SERIALIZE_ROOT_SIGNATURE_FUNC "D3D12SerializeRootSignature" #define D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE_FUNC "D3D12SerializeVersionedRootSignature"
#define DXGIDEBUG_DLL "dxgidebug.dll" #define DXGIDEBUG_DLL "dxgidebug.dll"
#define DXGI_GET_DEBUG_INTERFACE_FUNC "DXGIGetDebugInterface" #define DXGI_GET_DEBUG_INTERFACE_FUNC "DXGIGetDebugInterface"
#define D3D12_GET_DEBUG_INTERFACE_FUNC "D3D12GetDebugInterface"
extern "C" {
// Used to enable the "Agility SDK" components
__declspec(dllexport) extern const unsigned int D3D12SDKVersion = 615;
__declspec(dllexport) extern const char* D3D12SDKPath = ".\\D3D12\\";
}
// TODO : Use LoadLibrary and not link to the lib. Allows failing earlier if Dx12 is not installed for some reason // TODO : Use LoadLibrary and not link to the lib. Allows failing earlier if Dx12 is not installed for some reason
// + Will load the dll when needed // + Will load the dll when needed
@@ -31,6 +42,75 @@ namespace Juliet::D3D12
constexpr D3D_FEATURE_LEVEL kD3DFeatureLevel = D3D_FEATURE_LEVEL_12_1; constexpr D3D_FEATURE_LEVEL kD3DFeatureLevel = D3D_FEATURE_LEVEL_12_1;
constexpr auto kD3DFeatureLevelStr = "12_1"; constexpr auto kD3DFeatureLevelStr = "12_1";
bool CheckResourceTypeTier(ID3D12Device5* device)
{
D3D12_FEATURE_DATA_D3D12_OPTIONS options = {};
HRESULT result = ID3D12Device5_CheckFeatureSupport(device, D3D12_FEATURE_D3D12_OPTIONS, &options,
sizeof(D3D12_FEATURE_DATA_D3D12_OPTIONS));
if (SUCCEEDED(result))
{
if (options.ResourceBindingTier < D3D12_RESOURCE_BINDING_TIER_3)
{
Juliet::LogError(LogCategory::Graphics, "Resource Binding Tier 3 not supported. :(");
return false;
}
return true;
}
Juliet::LogError(LogCategory::Graphics, "Couldn't fetch D3D12_FEATURE_D3D12_OPTIONS :(");
return false;
}
bool CheckShaderModel(ID3D12Device5* device)
{
// Check Shader Model
bool foundShaderModel = false;
D3D12_FEATURE_DATA_SHADER_MODEL shaderModel = {};
constexpr D3D_SHADER_MODEL allModelVersions[] = {
#if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 612)
D3D_SHADER_MODEL_6_9,
#endif
#if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 606)
D3D_SHADER_MODEL_6_8,
#endif
#if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 3)
D3D_SHADER_MODEL_6_7,
#endif
D3D_SHADER_MODEL_6_6, D3D_SHADER_MODEL_6_5, D3D_SHADER_MODEL_6_4, D3D_SHADER_MODEL_6_3,
D3D_SHADER_MODEL_6_2, D3D_SHADER_MODEL_6_1, D3D_SHADER_MODEL_6_0, D3D_SHADER_MODEL_5_1
};
for (auto allModelVersion : allModelVersions)
{
shaderModel.HighestShaderModel = allModelVersion;
HRESULT result = ID3D12Device5_CheckFeatureSupport(device, D3D12_FEATURE_SHADER_MODEL, &shaderModel,
sizeof(D3D12_FEATURE_DATA_SHADER_MODEL));
if (result != E_INVALIDARG)
{
if (FAILED(result))
{
shaderModel.HighestShaderModel = static_cast<D3D_SHADER_MODEL>(0);
}
else
{
foundShaderModel = true;
break;
}
}
}
if (!foundShaderModel)
{
shaderModel.HighestShaderModel = static_cast<D3D_SHADER_MODEL>(0);
}
if (shaderModel.HighestShaderModel < D3D_SHADER_MODEL_6_6)
{
Juliet::LogError(LogCategory::Graphics, "Shader Model 6.6 not supported. :(");
return false;
}
return true;
}
bool CheckDriver() bool CheckDriver()
{ {
// Can we Load D3D12.dll and the create device function // Can we Load D3D12.dll and the create device function
@@ -93,25 +173,134 @@ namespace Juliet::D3D12
return false; return false;
} }
ID3D12Device* device = nullptr; ID3D12Device5* device = nullptr;
result = D3D12CreateDeviceFuncPtr(reinterpret_cast<IUnknown*>(adapter), kD3DFeatureLevel, IID_ID3D12Device, result = D3D12CreateDeviceFuncPtr(reinterpret_cast<IUnknown*>(adapter), kD3DFeatureLevel, IID_ID3D12Device5,
reinterpret_cast<void**>(&device)); reinterpret_cast<void**>(&device));
bool driverIsValid = true;
if (SUCCEEDED(result)) if (SUCCEEDED(result))
{ {
driverIsValid &= CheckShaderModel(device);
driverIsValid &= CheckResourceTypeTier(device);
ID3D12Device5_Release(device); ID3D12Device5_Release(device);
} }
else
{
Log(LogLevel::Warning, LogCategory::Graphics,
"DX12: Failed to create a D3D12Device with feature level %s.", kD3DFeatureLevelStr);
driverIsValid = false;
}
IDXGIAdapter1_Release(adapter); IDXGIAdapter1_Release(adapter);
IDXGIFactory1_Release(factory1); IDXGIFactory1_Release(factory1);
if (FAILED(result)) return driverIsValid;
}
void DestroyGraphicsRootSignature(D3D12GraphicsRootSignature* rootSignature)
{
if (!rootSignature)
{ {
Log(LogLevel::Warning, LogCategory::Graphics, return;
"DX12: Failed to create a D3D12Device with feature level %s.", kD3DFeatureLevelStr); }
return false; if (rootSignature->Handle)
{
ID3D12RootSignature_Release(rootSignature->Handle);
}
Free(rootSignature);
}
D3D12GraphicsRootSignature* CreateGraphicsRootSignature(NonNullPtr<D3D12Driver> d3d12Driver)
{
auto d3d12GraphicsRootSignature =
static_cast<D3D12GraphicsRootSignature*>(Calloc(1, sizeof(D3D12GraphicsRootSignature)));
if (!d3d12GraphicsRootSignature)
{
return nullptr;
} }
return true; D3D12_ROOT_PARAMETER1 parameters[ToUnderlying(RootParameters::Count)] = {};
parameters[ToUnderlying(RootParameters::Constants32Bits)] = {
.ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS,
.Constants = {
.ShaderRegister = 0,
.RegisterSpace = 0,
.Num32BitValues = 58, // 58 because each root cbv takes 2 uints, and the max is 64
},
.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL
};
D3D12_STATIC_SAMPLER_DESC samplers[] = {
{
// s_nearest
.Filter = D3D12_FILTER_MIN_MAG_POINT_MIP_LINEAR,
.AddressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP,
.AddressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP,
.AddressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP,
.MipLODBias = 0.0f,
.MinLOD = 0.0f,
.MaxLOD = D3D12_FLOAT32_MAX,
.ShaderRegister = 0,
.RegisterSpace = 0,
.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL,
},
};
D3D12_VERSIONED_ROOT_SIGNATURE_DESC rootSignatureDesc = {
.Version = D3D_ROOT_SIGNATURE_VERSION_1_1,
.Desc_1_1 = {
.NumParameters = ArraySize(parameters),
.pParameters = parameters,
.NumStaticSamplers = ArraySize(samplers),
.pStaticSamplers = samplers,
.Flags = D3D12_ROOT_SIGNATURE_FLAG_DENY_VERTEX_SHADER_ROOT_ACCESS |
D3D12_ROOT_SIGNATURE_FLAG_DENY_HULL_SHADER_ROOT_ACCESS |
D3D12_ROOT_SIGNATURE_FLAG_DENY_DOMAIN_SHADER_ROOT_ACCESS |
D3D12_ROOT_SIGNATURE_FLAG_DENY_GEOMETRY_SHADER_ROOT_ACCESS |
D3D12_ROOT_SIGNATURE_FLAG_DENY_PIXEL_SHADER_ROOT_ACCESS |
D3D12_ROOT_SIGNATURE_FLAG_DENY_AMPLIFICATION_SHADER_ROOT_ACCESS |
D3D12_ROOT_SIGNATURE_FLAG_DENY_MESH_SHADER_ROOT_ACCESS |
D3D12_ROOT_SIGNATURE_FLAG_CBV_SRV_UAV_HEAP_DIRECTLY_INDEXED |
D3D12_ROOT_SIGNATURE_FLAG_SAMPLER_HEAP_DIRECTLY_INDEXED,
},
};
// Serialize the root signature
ID3DBlob* serializedRootSignature;
ID3DBlob* errorBlob;
HRESULT res =
d3d12Driver->D3D12SerializeVersionedRootSignatureFct(&rootSignatureDesc, &serializedRootSignature, &errorBlob);
if (FAILED(res))
{
if (errorBlob)
{
auto errorBuffer = ID3D10Blob_GetBufferPointer(errorBlob);
LogError(LogCategory::Graphics, "Failed to serialize RootSignature: %s", errorBuffer);
ID3D10Blob_Release(errorBlob);
}
DestroyGraphicsRootSignature(d3d12GraphicsRootSignature);
return nullptr;
}
// Create the root signature
ID3D12RootSignature* rootSignature;
res = ID3D12Device_CreateRootSignature(d3d12Driver->D3D12Device, 0, ID3D10Blob_GetBufferPointer(serializedRootSignature),
ID3D10Blob_GetBufferSize(serializedRootSignature),
IID_ID3D12RootSignature, reinterpret_cast<void**>(&rootSignature));
if (FAILED(res))
{
if (errorBlob)
{
LogError(LogCategory::Graphics, "Failed to create RootSignature: %s",
(const char*)ID3D10Blob_GetBufferPointer(errorBlob));
ID3D10Blob_Release(errorBlob);
}
DestroyGraphicsRootSignature(d3d12GraphicsRootSignature);
return nullptr;
}
d3d12GraphicsRootSignature->Handle = rootSignature;
return d3d12GraphicsRootSignature;
} }
#ifdef IDXGIINFOQUEUE_SUPPORTED #ifdef IDXGIINFOQUEUE_SUPPORTED
@@ -167,9 +356,113 @@ namespace Juliet::D3D12
} }
#endif #endif
#ifdef JULIET_DEBUG
void InitializeD3D12DebugLayer(NonNullPtr<D3D12Driver> driver)
{
auto D3D12GetDebugInterfaceFunc =
reinterpret_cast<PFN_D3D12_GET_DEBUG_INTERFACE>(LoadFunction(driver->D3D12DLL, D3D12_GET_DEBUG_INTERFACE_FUNC));
if (D3D12GetDebugInterfaceFunc == nullptr)
{
LogWarning(LogCategory::Graphics, "Could not load function: " D3D12_GET_DEBUG_INTERFACE_FUNC);
return;
}
HRESULT result = D3D12GetDebugInterfaceFunc(IID_ID3D12Debug1, reinterpret_cast<void**>(&driver->D3D12Debug));
if (FAILED(result))
{
LogWarning(LogCategory::Graphics, "Could not get ID3D12Debug interface");
return;
}
ID3D12Debug1_EnableDebugLayer(driver->D3D12Debug);
}
bool InitializeD3D12DebugInfoQueue(NonNullPtr<D3D12Driver> driver)
{
ID3D12InfoQueue* infoQueue = nullptr;
D3D12_MESSAGE_SEVERITY severities[] = { D3D12_MESSAGE_SEVERITY_INFO };
HRESULT result =
ID3D12Device_QueryInterface(driver->D3D12Device, IID_ID3D12InfoQueue, reinterpret_cast<void**>(&infoQueue));
if (FAILED(result))
{
LogError(driver->D3D12Device, "Failed to convert ID3D12Device to ID3D12InfoQueue", result);
return false;
}
D3D12_INFO_QUEUE_FILTER filter = {};
filter.DenyList.NumSeverities = 1;
filter.DenyList.pSeverityList = severities;
ID3D12InfoQueue_PushStorageFilter(infoQueue, &filter);
ID3D12InfoQueue_SetBreakOnSeverity(infoQueue, D3D12_MESSAGE_SEVERITY_CORRUPTION, true);
ID3D12InfoQueue_Release(infoQueue);
return true;
}
#ifdef ID3D12InfoQueue1_SUPPORTED
void WINAPI OnD3D12DebugInfoMsg(D3D12_MESSAGE_CATEGORY category, D3D12_MESSAGE_SEVERITY severity,
D3D12_MESSAGE_ID id, LPCSTR description, void* context)
{
String catStr;
switch (category)
{
case D3D12_MESSAGE_CATEGORY_APPLICATION_DEFINED: catStr = WrapString("APPLICATION_DEFINED"); break;
case D3D12_MESSAGE_CATEGORY_MISCELLANEOUS: catStr = WrapString("MISCELLANEOUS"); break;
case D3D12_MESSAGE_CATEGORY_INITIALIZATION: catStr = WrapString("INITIALIZATION"); break;
case D3D12_MESSAGE_CATEGORY_CLEANUP: catStr = WrapString("CLEANUP"); break;
case D3D12_MESSAGE_CATEGORY_COMPILATION: catStr = WrapString("COMPILATION"); break;
case D3D12_MESSAGE_CATEGORY_STATE_CREATION: catStr = WrapString("STATE_CREATION"); break;
case D3D12_MESSAGE_CATEGORY_STATE_SETTING: catStr = WrapString("STATE_SETTING"); break;
case D3D12_MESSAGE_CATEGORY_STATE_GETTING: catStr = WrapString("STATE_GETTING"); break;
case D3D12_MESSAGE_CATEGORY_RESOURCE_MANIPULATION: catStr = WrapString("RESOURCE_MANIPULATION"); break;
case D3D12_MESSAGE_CATEGORY_EXECUTION: catStr = WrapString("EXECUTION"); break;
case D3D12_MESSAGE_CATEGORY_SHADER: catStr = WrapString("SHADER"); break;
default: catStr = WrapString("UNKNOWN"); break;
}
String severityStr;
switch (severity)
{
case D3D12_MESSAGE_SEVERITY_CORRUPTION: severityStr = WrapString("CORRUPTION"); break;
case D3D12_MESSAGE_SEVERITY_ERROR: severityStr = WrapString("ERROR"); break;
case D3D12_MESSAGE_SEVERITY_WARNING: severityStr = WrapString("WARNING"); break;
case D3D12_MESSAGE_SEVERITY_INFO: severityStr = WrapString("INFO"); break;
case D3D12_MESSAGE_SEVERITY_MESSAGE: severityStr = WrapString("MESSAGE"); break;
default: severityStr = WrapString("UNKNOWN"); break;
}
if (severity <= D3D12_MESSAGE_SEVERITY_ERROR)
{
LogWarning(LogCategory::Graphics, "D3D12 ERROR: %s [%s %s #%d]", description, CStr(catStr), CStr(severityStr), id);
}
else
{
LogWarning(LogCategory::Graphics, "D3D12 WARNING: %s [%s %s #%d]", description, CStr(catStr),
CStr(severityStr), id);
}
}
void InitializeD3D12DebugInfoLogger(NonNullPtr<D3D12Driver> driver)
{
// Only supported on Win 11 apparently
ID3D12InfoQueue1* infoQueue = nullptr;
HRESULT result =
ID3D12Device5_QueryInterface(driver->D3D12Device, IID_ID3D12InfoQueue1, reinterpret_cast<void**>(&infoQueue));
if (FAILED(result))
{
return;
}
ID3D12InfoQueue1_RegisterMessageCallback(infoQueue, OnD3D12DebugInfoMsg, D3D12_MESSAGE_CALLBACK_FLAG_NONE, NULL, NULL);
ID3D12InfoQueue1_Release(infoQueue);
}
#endif
#endif
void DestroyDriver_Internal(NonNullPtr<D3D12Driver> driver) void DestroyDriver_Internal(NonNullPtr<D3D12Driver> driver)
{ {
// Destroy pools // Destroy Descriptor pools
for (uint32 i = 0; i < D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES; i += 1) for (uint32 i = 0; i < D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES; i += 1)
{ {
if (driver->StagingDescriptorPools[i]) if (driver->StagingDescriptorPools[i])
@@ -179,6 +472,24 @@ namespace Juliet::D3D12
} }
} }
auto DestroyDescriptorHeapPool = [](Internal::D3D12DescriptorHeapPool& heapPool)
{
if (heapPool.Heaps)
{
for (uint32 i = 0; i < heapPool.Count; ++i)
{
if (heapPool.Heaps[i])
{
Internal::DestroyDescriptorHeap(heapPool.Heaps[i]);
heapPool.Heaps[i] = nullptr;
}
}
SafeFree(heapPool.Heaps);
}
};
DestroyDescriptorHeapPool(driver->CRB_SRV_UAV_HeapPool);
DestroyDescriptorHeapPool(driver->RTV_HeapPool);
// Release command buffers // Release command buffers
for (uint32 i = 0; i < driver->AvailableCommandListCount; i += 1) for (uint32 i = 0; i < driver->AvailableCommandListCount; i += 1)
{ {
@@ -199,9 +510,12 @@ namespace Juliet::D3D12
} }
} }
DestroyGraphicsRootSignature(driver->BindlessRootSignature);
// Clean allocations // Clean allocations
SafeFree(driver->AvailableCommandLists); SafeFree(driver->AvailableCommandLists);
SafeFree(driver->SubmittedCommandLists); SafeFree(driver->SubmittedCommandLists);
SafeFree(driver->GraphicsPipelinesToDispose);
// Free(driver->WindowData); // TODO Should free the vector of WindowData, but we have only one for now // Free(driver->WindowData); // TODO Should free the vector of WindowData, but we have only one for now
SafeFree(driver->AvailableFences); SafeFree(driver->AvailableFences);
@@ -253,7 +567,7 @@ namespace Juliet::D3D12
driver->D3D12DLL = nullptr; driver->D3D12DLL = nullptr;
} }
driver->D3D12SerializeRootSignatureFct = nullptr; driver->D3D12SerializeVersionedRootSignatureFct = nullptr;
Free(driver.Get()); Free(driver.Get());
} }
@@ -297,7 +611,7 @@ namespace Juliet::D3D12
auto* windowData = d3d12Driver->WindowData; auto* windowData = d3d12Driver->WindowData;
Assert(windowData && "Trying to destroy a swapchain but no Window Data exists"); Assert(windowData && "Trying to destroy a swapchain but no Window Data exists");
Wait(driver); WaitUntilGPUIsIdle(driver);
for (uint32 idx = 0; idx < GPUDriver::kMaxFramesInFlight; idx += 1) for (uint32 idx = 0; idx < GPUDriver::kMaxFramesInFlight; idx += 1)
{ {
@@ -322,13 +636,12 @@ namespace Juliet::D3D12
Free(device.Get()); Free(device.Get());
} }
GraphicsDevice* CreateGraphicsDevice() GraphicsDevice* CreateGraphicsDevice(bool enableDebug)
{ {
auto driver = static_cast<D3D12Driver*>(Calloc(1, sizeof(D3D12Driver))); auto driver = static_cast<D3D12Driver*>(Calloc(1, sizeof(D3D12Driver)));
#ifdef IDXGIINFOQUEUE_SUPPORTED #ifdef IDXGIINFOQUEUE_SUPPORTED
static const bool kDebug = true; if (enableDebug)
if (kDebug)
{ {
InitializeDXGIDebug(driver); InitializeDXGIDebug(driver);
} }
@@ -373,7 +686,7 @@ namespace Juliet::D3D12
// 1.6 should be available on most Win10 PC if they didnt their windows update. // 1.6 should be available on most Win10 PC if they didnt their windows update.
// Lets support not having it for now... // Lets support not having it for now...
IDXGIFactory6* factory6 = nullptr; IDXGIFactory6* factory6 = nullptr;
result = IDXGIFactory4_QueryInterface(driver->DXGIFactory, IID_IDXGIFactory6, (void**)&factory6); result = IDXGIFactory4_QueryInterface(driver->DXGIFactory, IID_IDXGIFactory6, reinterpret_cast<void**>(&factory6));
if (SUCCEEDED(result)) if (SUCCEEDED(result))
{ {
// TODO: Put into the config // TODO: Put into the config
@@ -438,18 +751,22 @@ namespace Juliet::D3D12
return nullptr; return nullptr;
} }
driver->D3D12SerializeRootSignatureFct = reinterpret_cast<PFN_D3D12_SERIALIZE_ROOT_SIGNATURE>( driver->D3D12SerializeVersionedRootSignatureFct = reinterpret_cast<PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE>(
LoadFunction(driver->D3D12DLL, D3D12_SERIALIZE_ROOT_SIGNATURE_FUNC)); LoadFunction(driver->D3D12DLL, D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE_FUNC));
if (driver->D3D12SerializeRootSignatureFct == nullptr) if (driver->D3D12SerializeVersionedRootSignatureFct == nullptr)
{ {
Log(LogLevel::Error, LogCategory::Graphics, Log(LogLevel::Error, LogCategory::Graphics,
"DX12: Couldn't Load function " D3D12_SERIALIZE_ROOT_SIGNATURE_FUNC " in " D3D12_DLL); "DX12: Couldn't Load function " D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE_FUNC " in " D3D12_DLL);
DestroyDriver_Internal(driver); DestroyDriver_Internal(driver);
return nullptr; return nullptr;
} }
// TODO : D3D12 Debug Layer here #ifdef JULIET_DEBUG
// InitializeD3D12DebugLayer() if (enableDebug)
{
InitializeD3D12DebugLayer(driver);
}
#endif
result = D3D12CreateDeviceFuncPtr(reinterpret_cast<IUnknown*>(driver->DXGIAdapter), kD3DFeatureLevel, result = D3D12CreateDeviceFuncPtr(reinterpret_cast<IUnknown*>(driver->DXGIAdapter), kD3DFeatureLevel,
IID_ID3D12Device5, reinterpret_cast<void**>(&driver->D3D12Device)); IID_ID3D12Device5, reinterpret_cast<void**>(&driver->D3D12Device));
@@ -460,8 +777,18 @@ namespace Juliet::D3D12
return nullptr; return nullptr;
} }
// TODO : D3D12 Debug Info Queue #ifdef JULIET_DEBUG
// InitializeD3D12DebugInfoQueue if (enableDebug)
{
if (!InitializeD3D12DebugInfoQueue(driver))
{
return nullptr;
}
#ifdef ID3D12InfoQueue1_SUPPORTED
InitializeD3D12DebugInfoLogger(driver);
#endif
}
#endif
// Check if UMA (unified memory architecture) is available. Used on APU i think ?? // Check if UMA (unified memory architecture) is available. Used on APU i think ??
D3D12_FEATURE_DATA_ARCHITECTURE architecture; D3D12_FEATURE_DATA_ARCHITECTURE architecture;
@@ -477,10 +804,6 @@ namespace Juliet::D3D12
driver->IsUMAAvailable = architecture.UMA; driver->IsUMAAvailable = architecture.UMA;
driver->IsUMACacheCoherent = architecture.CacheCoherentUMA; driver->IsUMACacheCoherent = architecture.CacheCoherentUMA;
#ifndef E_INVALIDARG
#define E_INVALIDARG (HRESULT)0x80070057L
#endif
// Check "GPU Upload Heap" support (for fast uniform buffers. Not supported on my 5700xt // Check "GPU Upload Heap" support (for fast uniform buffers. Not supported on my 5700xt
D3D12_FEATURE_DATA_D3D12_OPTIONS16 options16; D3D12_FEATURE_DATA_D3D12_OPTIONS16 options16;
driver->GPUUploadHeapSupported = false; driver->GPUUploadHeapSupported = false;
@@ -491,6 +814,9 @@ namespace Juliet::D3D12
driver->GPUUploadHeapSupported = options16.GPUUploadHeapSupported; driver->GPUUploadHeapSupported = options16.GPUUploadHeapSupported;
} }
// Create bindless root signature
driver->BindlessRootSignature = CreateGraphicsRootSignature(driver);
// Command Queues // Command Queues
// Graphics Queue only for now // Graphics Queue only for now
D3D12_COMMAND_QUEUE_DESC queueDesc = {}; D3D12_COMMAND_QUEUE_DESC queueDesc = {};
@@ -588,6 +914,53 @@ namespace Juliet::D3D12
} }
} }
// Other Descriptor pools
auto CreateDescriptorPool = [&](Internal::D3D12DescriptorHeapPool& heapPool,
D3D12_DESCRIPTOR_HEAP_TYPE type, uint32 count) -> bool
{
heapPool.Capacity = 4;
heapPool.Count = 4;
heapPool.Heaps = static_cast<Internal::D3D12DescriptorHeap**>(Calloc(heapPool.Capacity, sizeof(Internal::D3D12DescriptorHeap*)));
for (uint32 i = 0; i < heapPool.Capacity; ++i)
{
heapPool.Heaps[i] = Internal::CreateDescriptorHeap(driver, type, count, false);
if (heapPool.Heaps[i] == nullptr)
{
return false;
}
}
return true;
};
if (!CreateDescriptorPool(driver->CRB_SRV_UAV_HeapPool, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV,
GPUDriver::kCBV_SRV_UAV_HeapDescriptorCount))
{
DestroyDriver_Internal(driver);
return nullptr;
}
if (!CreateDescriptorPool(driver->RTV_HeapPool, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, GPUDriver::kSampler_HeapDescriptorCount))
{
DestroyDriver_Internal(driver);
return nullptr;
}
// Deferred dispose vectors
driver->GraphicsPipelinesToDisposeCapacity = 4;
driver->GraphicsPipelinesToDisposeCount = 0;
driver->GraphicsPipelinesToDispose = static_cast<D3D12GraphicsPipeline**>(
Calloc(driver->GraphicsPipelinesToDisposeCapacity, sizeof(D3D12GraphicsPipeline*)));
if (!driver->GraphicsPipelinesToDispose)
{
DestroyDriver_Internal(driver);
return nullptr;
}
driver->Semantic = WrapString("TEXCOORD");
driver->FramesInFlight = 2;
auto device = static_cast<GraphicsDevice*>(Calloc(1, sizeof(GraphicsDevice))); auto device = static_cast<GraphicsDevice*>(Calloc(1, sizeof(GraphicsDevice)));
if (!device) if (!device)
{ {
@@ -596,36 +969,58 @@ namespace Juliet::D3D12
} }
// Assign Functions to the device // Assign Functions to the device
device->DestroyDevice = DestroyGraphicsDevice; device->DestroyDevice = DestroyGraphicsDevice;
device->AttachToWindow = AttachToWindow;
device->DetachFromWindow = DetachFromWindow;
device->AcquireSwapChainTexture = AcquireSwapChainTexture;
device->WaitAndAcquireSwapChainTexture = WaitAndAcquireSwapChainTexture;
device->GetSwapChainTextureFormat = GetSwapChainTextureFormat;
device->AcquireCommandList = AcquireCommandList;
device->SubmitCommandLists = SubmitCommandLists;
device->BeginRenderPass = BeginRenderPass;
device->EndRenderPass = EndRenderPass;
device->SetViewPort = SetViewPort;
device->SetScissorRect = SetScissorRect;
device->SetBlendConstants = SetBlendConstants;
device->SetStencilReference = SetStencilReference;
device->BindGraphicsPipeline = BindGraphicsPipeline;
device->DrawPrimitives = DrawPrimitives;
device->WaitUntilGPUIsIdle = WaitUntilGPUIsIdle;
device->QueryFence = QueryFence;
device->ReleaseFence = ReleaseFence;
device->CreateShader = CreateShader;
device->DestroyShader = DestroyShader;
device->CreateGraphicsPipeline = CreateGraphicsPipeline;
device->DestroyGraphicsPipeline = DestroyGraphicsPipeline;
device->UpdateGraphicsPipelineShaders = UpdateGraphicsPipelineShaders;
device->AttachToWindow = AttachToWindow; device->Driver = driver;
device->DetachFromWindow = DetachFromWindow; device->DebugEnabled = enableDebug;
device->AcquireSwapChainTexture = AcquireSwapChainTexture;
device->AcquireCommandList = AcquireCommandList;
device->SubmitCommandLists = SubmitCommandLists;
device->BeginRenderPass = BeginRenderPass;
device->EndRenderPass = EndRenderPass;
device->SetViewPort = SetViewPort;
device->SetScissorRect = SetScissorRect;
device->SetBlendConstants = SetBlendConstants;
device->SetStencilReference = SetStencilReference;
device->Wait = Wait;
device->QueryFence = QueryFence;
device->ReleaseFence = ReleaseFence;
device->Driver = driver;
driver->GraphicsDevice = device; driver->GraphicsDevice = device;
driver->FramesInFlight = 2;
return device; return device;
} }
} // namespace } // namespace
namespace Internal
{
void DisposePendingResourcces(NonNullPtr<D3D12Driver> driver)
{
// TODO Destroy anything (buffer, texture, etc...)
for (int32 idx = driver->GraphicsPipelinesToDisposeCount - 1; idx >= 0; --idx)
{
if (driver->GraphicsPipelinesToDispose[idx]->ReferenceCount == 0)
{
ReleaseGraphicsPipeline(driver->GraphicsPipelinesToDispose[idx]);
driver->GraphicsPipelinesToDispose[idx] =
driver->GraphicsPipelinesToDispose[driver->GraphicsPipelinesToDisposeCount - 1];
driver->GraphicsPipelinesToDisposeCount -= 1;
}
}
}
} // namespace Internal
} // namespace Juliet::D3D12 } // namespace Juliet::D3D12
namespace Juliet namespace Juliet

View File

@@ -2,6 +2,8 @@
#include <Core/Common/EnumUtils.h> #include <Core/Common/EnumUtils.h>
#include <Graphics/D3D12/D3D12Common.h> #include <Graphics/D3D12/D3D12Common.h>
#include <Graphics/D3D12/D3D12DescriptorHeap.h>
#include <Graphics/D3D12/D3D12GraphicsPipeline.h>
#include <Graphics/D3D12/D3D12Texture.h> #include <Graphics/D3D12/D3D12Texture.h>
#include <Graphics/GraphicsDevice.h> #include <Graphics/GraphicsDevice.h>
@@ -12,10 +14,17 @@ namespace Juliet
namespace Juliet::D3D12 namespace Juliet::D3D12
{ {
struct D3D12StagingDescriptorPool;
// Forward Declare // Forward Declare
struct D3D12CommandList; struct D3D12CommandList;
struct D3D12Fence; struct D3D12Fence;
enum class RootParameters : uint8
{
Constants32Bits,
Count,
};
struct D3D12WindowData struct D3D12WindowData
{ {
Window* Window; Window* Window;
@@ -40,11 +49,14 @@ namespace Juliet::D3D12
GraphicsDevice* GraphicsDevice; GraphicsDevice* GraphicsDevice;
// D3D12 // D3D12
DynamicLibrary* D3D12DLL; DynamicLibrary* D3D12DLL;
ID3D12Device5* D3D12Device; ID3D12Device5* D3D12Device;
PFN_D3D12_SERIALIZE_ROOT_SIGNATURE D3D12SerializeRootSignatureFct; PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE D3D12SerializeVersionedRootSignatureFct;
ID3D12CommandQueue* GraphicsQueue; ID3D12CommandQueue* GraphicsQueue;
D3D12_COMMAND_QUEUE_DESC QueueDesc[ToUnderlying(QueueType::Copy)]; D3D12_COMMAND_QUEUE_DESC QueueDesc[ToUnderlying(QueueType::Copy)];
#ifdef JULIET_DEBUG
ID3D12Debug1* D3D12Debug;
#endif
// Indirect commands signature // Indirect commands signature
ID3D12CommandSignature* IndirectDrawCommandSignature; ID3D12CommandSignature* IndirectDrawCommandSignature;
@@ -77,7 +89,17 @@ namespace Juliet::D3D12
uint32 AvailableFenceCount; uint32 AvailableFenceCount;
uint32 AvailableFenceCapacity; uint32 AvailableFenceCapacity;
D3D12StagingDescriptorPool* StagingDescriptorPools[D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES]; D3D12GraphicsPipeline** GraphicsPipelinesToDispose;
uint32 GraphicsPipelinesToDisposeCount;
uint32 GraphicsPipelinesToDisposeCapacity;
D3D12GraphicsRootSignature* BindlessRootSignature;
D3D12StagingDescriptorPool* StagingDescriptorPools[D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES];
Internal::D3D12DescriptorHeapPool CRB_SRV_UAV_HeapPool;
Internal::D3D12DescriptorHeapPool RTV_HeapPool;
String Semantic;
uint8 FramesInFlight; uint8 FramesInFlight;
uint64 FrameCounter = 0; // Number of frame since inception uint64 FrameCounter = 0; // Number of frame since inception
@@ -87,4 +109,9 @@ namespace Juliet::D3D12
bool IsUMACacheCoherent : 1; bool IsUMACacheCoherent : 1;
bool GPUUploadHeapSupported : 1; bool GPUUploadHeapSupported : 1;
}; };
namespace Internal
{
void DisposePendingResourcces(NonNullPtr<D3D12Driver> driver);
}
} // namespace Juliet::D3D12 } // namespace Juliet::D3D12

View File

@@ -0,0 +1,557 @@
#include <pch.h>
#include <Graphics/D3D12/D3D12GraphicsDevice.h>
#include <Graphics/D3D12/D3D12GraphicsPipeline.h>
#include <Graphics/D3D12/D3D12Shader.h>
#include <Graphics/D3D12/D3D12Utils.h>
#include <Core/Common/NonNullPtr.h>
#include <Core/Memory/Allocator.h>
namespace Juliet::D3D12
{
namespace
{
// clang-format off
D3D12_INPUT_CLASSIFICATION JulietToD3D12_InputRate[] =
{
D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, // VERTEX
D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA // INSTANCE
};
// clang-format on
static_assert(sizeof(JulietToD3D12_InputRate) / sizeof(JulietToD3D12_InputRate[0]) == ToUnderlying(VertexInputRate::Count));
// clang-format off
D3D12_CULL_MODE JulietToD3D12_CullMode[] =
{
D3D12_CULL_MODE_NONE,
D3D12_CULL_MODE_FRONT,
D3D12_CULL_MODE_BACK
};
// clang-format on
static_assert(sizeof(JulietToD3D12_CullMode) / sizeof(JulietToD3D12_CullMode[0]) == ToUnderlying(CullMode::Count));
// clang-format off
D3D12_FILL_MODE JulietToD3D12_FillMode[] =
{
D3D12_FILL_MODE_SOLID,
D3D12_FILL_MODE_WIREFRAME
};
// clang-format on
static_assert(sizeof(JulietToD3D12_FillMode) / sizeof(JulietToD3D12_FillMode[0]) == ToUnderlying(FillMode::Count));
DXGI_FORMAT JulietToD3D12_VertexFormat[] = {
DXGI_FORMAT_UNKNOWN, // Unknown
DXGI_FORMAT_R32_SINT, // Int
DXGI_FORMAT_R32G32_SINT, // Int2
DXGI_FORMAT_R32G32B32_SINT, // Int3
DXGI_FORMAT_R32G32B32A32_SINT, // Int4
DXGI_FORMAT_R32_UINT, // UInt
DXGI_FORMAT_R32G32_UINT, // UInt2
DXGI_FORMAT_R32G32B32_UINT, // UInt3
DXGI_FORMAT_R32G32B32A32_UINT, // UInt4
DXGI_FORMAT_R32_FLOAT, // Float
DXGI_FORMAT_R32G32_FLOAT, // Float2
DXGI_FORMAT_R32G32B32_FLOAT, // Float3
DXGI_FORMAT_R32G32B32A32_FLOAT, // Float4
DXGI_FORMAT_R8G8_SINT, // Byte2
DXGI_FORMAT_R8G8B8A8_SINT, // Byte4
DXGI_FORMAT_R8G8_UINT, // UByte2
DXGI_FORMAT_R8G8B8A8_UINT, // UByte4
DXGI_FORMAT_R8G8_SNORM, // Byte2_Norm
DXGI_FORMAT_R8G8B8A8_SNORM, // Byte4_Norm
DXGI_FORMAT_R8G8_UNORM, // UByte2_Norm
DXGI_FORMAT_R8G8B8A8_UNORM, // UByte4_Norm
DXGI_FORMAT_R16G16_SINT, // Short2
DXGI_FORMAT_R16G16B16A16_SINT, // Short4
DXGI_FORMAT_R16G16_UINT, // UShort2
DXGI_FORMAT_R16G16B16A16_UINT, // UShort4
DXGI_FORMAT_R16G16_SNORM, // Short2_Norm
DXGI_FORMAT_R16G16B16A16_SNORM, // Short4_Norm
DXGI_FORMAT_R16G16_UNORM, // UShort2_Norm
DXGI_FORMAT_R16G16B16A16_UNORM, // UShort4_Norm
DXGI_FORMAT_R16G16_FLOAT, // Half2
DXGI_FORMAT_R16G16B16A16_FLOAT // Half4
};
static_assert(sizeof(JulietToD3D12_VertexFormat) / sizeof(JulietToD3D12_VertexFormat[0]) ==
ToUnderlying(VertexElementFormat::Count));
// clang-format off
D3D12_PRIMITIVE_TOPOLOGY_TYPE JulietToD3D12_PrimitiveTopologyType[] = {
D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE,
D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE,
D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE,
D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE,
D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT
};
// clang-format on
static_assert(sizeof(JulietToD3D12_PrimitiveTopologyType) / sizeof(JulietToD3D12_PrimitiveTopologyType[0]) ==
ToUnderlying(PrimitiveType::Count));
// clang-format off
D3D12_BLEND JulietToD3D12_BlendFactor[] =
{
D3D12_BLEND_ZERO,
D3D12_BLEND_ZERO,
D3D12_BLEND_ONE,
D3D12_BLEND_SRC_COLOR,
D3D12_BLEND_INV_SRC_COLOR,
D3D12_BLEND_DEST_COLOR,
D3D12_BLEND_INV_DEST_COLOR,
D3D12_BLEND_SRC_ALPHA,
D3D12_BLEND_INV_SRC_ALPHA,
D3D12_BLEND_DEST_ALPHA,
D3D12_BLEND_INV_DEST_ALPHA,
D3D12_BLEND_BLEND_FACTOR,
D3D12_BLEND_INV_BLEND_FACTOR,
D3D12_BLEND_SRC_ALPHA_SAT,
};
// clang-format on
static_assert(sizeof(JulietToD3D12_BlendFactor) / sizeof(JulietToD3D12_BlendFactor[0]) == ToUnderlying(BlendFactor::Count));
// clang-format off
D3D12_BLEND JulietToD3D12_BlendFactorAlpha[] =
{
D3D12_BLEND_ZERO,
D3D12_BLEND_ZERO,
D3D12_BLEND_ONE,
D3D12_BLEND_SRC_ALPHA,
D3D12_BLEND_INV_SRC_ALPHA,
D3D12_BLEND_DEST_ALPHA,
D3D12_BLEND_INV_DEST_ALPHA,
D3D12_BLEND_SRC_ALPHA,
D3D12_BLEND_INV_SRC_ALPHA,
D3D12_BLEND_DEST_ALPHA,
D3D12_BLEND_INV_DEST_ALPHA,
D3D12_BLEND_BLEND_FACTOR,
D3D12_BLEND_INV_BLEND_FACTOR,
D3D12_BLEND_SRC_ALPHA_SAT,
};
// clang-format on
static_assert(sizeof(JulietToD3D12_BlendFactorAlpha) / sizeof(JulietToD3D12_BlendFactorAlpha[0]) ==
ToUnderlying(BlendFactor::Count));
// clang-format off
D3D12_BLEND_OP JulietToD3D12_BlendOperation[] =
{
D3D12_BLEND_OP_ADD,
D3D12_BLEND_OP_ADD,
D3D12_BLEND_OP_SUBTRACT,
D3D12_BLEND_OP_REV_SUBTRACT,
D3D12_BLEND_OP_MIN,
D3D12_BLEND_OP_MAX
};
// clang-format on
static_assert(sizeof(JulietToD3D12_BlendOperation) / sizeof(JulietToD3D12_BlendOperation[0]) ==
ToUnderlying(BlendOperation::Count));
// clang-format off
D3D12_COMPARISON_FUNC JulietToD3D12_CompareOperation[] =
{
D3D12_COMPARISON_FUNC_NEVER,
D3D12_COMPARISON_FUNC_NEVER,
D3D12_COMPARISON_FUNC_LESS,
D3D12_COMPARISON_FUNC_EQUAL,
D3D12_COMPARISON_FUNC_LESS_EQUAL,
D3D12_COMPARISON_FUNC_GREATER,
D3D12_COMPARISON_FUNC_NOT_EQUAL,
D3D12_COMPARISON_FUNC_GREATER_EQUAL,
D3D12_COMPARISON_FUNC_ALWAYS
};
// clang-format on
static_assert(sizeof(JulietToD3D12_CompareOperation) / sizeof(JulietToD3D12_CompareOperation[0]) ==
ToUnderlying(CompareOperation::Count));
// clang-format off
D3D12_STENCIL_OP JulietToD3D12_StencilOperation[] =
{
D3D12_STENCIL_OP_KEEP,
D3D12_STENCIL_OP_KEEP,
D3D12_STENCIL_OP_ZERO,
D3D12_STENCIL_OP_REPLACE,
D3D12_STENCIL_OP_INCR_SAT,
D3D12_STENCIL_OP_DECR_SAT,
D3D12_STENCIL_OP_INVERT,
D3D12_STENCIL_OP_INCR,
D3D12_STENCIL_OP_DECR
};
// clang-format on
static_assert(sizeof(JulietToD3D12_StencilOperation) / sizeof(JulietToD3D12_StencilOperation[0]) ==
ToUnderlying(StencilOperation::Count));
bool ConvertVertexInputState(const VertexInputState& vertexInputState, D3D12_INPUT_ELEMENT_DESC* desc, String semantic)
{
if (desc == nullptr || vertexInputState.NumVertexAttributes == 0)
{
return false;
}
for (uint32 idx = 0; idx < vertexInputState.NumVertexAttributes; ++idx)
{
VertexAttribute attribute = vertexInputState.VertexAttributes[idx];
desc[idx].SemanticName = CStr(semantic);
desc[idx].SemanticIndex = attribute.Location;
desc[idx].Format = JulietToD3D12_VertexFormat[ToUnderlying(attribute.Format)];
desc[idx].InputSlot = attribute.BufferSlot;
desc[idx].AlignedByteOffset = attribute.Offset;
desc[idx].InputSlotClass =
JulietToD3D12_InputRate[ToUnderlying(vertexInputState.VertexBufferDescriptions[attribute.BufferSlot].InputRate)];
desc[idx].InstanceDataStepRate =
(vertexInputState.VertexBufferDescriptions[attribute.BufferSlot].InputRate == VertexInputRate::Instance)
? vertexInputState.VertexBufferDescriptions[attribute.BufferSlot].InstanceStepRate
: 0;
}
return true;
}
bool ConvertRasterizerState(const RasterizerState& rasterizerState, D3D12_RASTERIZER_DESC& desc)
{
desc.FillMode = JulietToD3D12_FillMode[ToUnderlying(rasterizerState.FillMode)];
desc.CullMode = JulietToD3D12_CullMode[ToUnderlying(rasterizerState.CullMode)];
switch (rasterizerState.FrontFace)
{
case FrontFace::CounterClockwise: desc.FrontCounterClockwise = TRUE; break;
case FrontFace::Clockwise: desc.FrontCounterClockwise = FALSE; break;
default: return false;
}
static_assert(ToUnderlying(FrontFace::Count) == 2);
if (rasterizerState.EnableDepthBias)
{
desc.DepthBias = LRoundF(rasterizerState.DepthBiasConstantFactor);
desc.DepthBiasClamp = rasterizerState.DepthBiasClamp;
desc.SlopeScaledDepthBias = rasterizerState.DepthBiasSlopeFactor;
}
else
{
desc.DepthBias = 0;
desc.DepthBiasClamp = 0.0f;
desc.SlopeScaledDepthBias = 0.0f;
}
desc.DepthClipEnable = rasterizerState.EnableDepthClip;
desc.MultisampleEnable = FALSE;
desc.AntialiasedLineEnable = FALSE;
desc.ForcedSampleCount = 0;
desc.ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF;
return true;
}
bool ConvertBlendState(const GraphicsPipelineCreateInfo& createInfo, D3D12_BLEND_DESC& blendDesc)
{
ZeroStruct(blendDesc);
blendDesc.AlphaToCoverageEnable = FALSE;
blendDesc.IndependentBlendEnable = FALSE;
for (UINT i = 0; i < GPUDriver::kMaxColorTargetInfo; i += 1)
{
D3D12_RENDER_TARGET_BLEND_DESC rtBlendDesc;
rtBlendDesc.BlendEnable = FALSE;
rtBlendDesc.LogicOpEnable = FALSE;
rtBlendDesc.SrcBlend = D3D12_BLEND_ONE;
rtBlendDesc.DestBlend = D3D12_BLEND_ZERO;
rtBlendDesc.BlendOp = D3D12_BLEND_OP_ADD;
rtBlendDesc.SrcBlendAlpha = D3D12_BLEND_ONE;
rtBlendDesc.DestBlendAlpha = D3D12_BLEND_ZERO;
rtBlendDesc.BlendOpAlpha = D3D12_BLEND_OP_ADD;
rtBlendDesc.LogicOp = D3D12_LOGIC_OP_NOOP;
rtBlendDesc.RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL;
// If target_info has more blend states, you can set IndependentBlendEnable to TRUE and assign different blend states to each render target slot
if (i < createInfo.TargetInfo.NumColorTargets)
{
ColorTargetBlendState blendState = createInfo.TargetInfo.ColorTargetDescriptions[i].BlendState;
ColorComponentFlags colorWriteMask =
blendState.EnableColorWriteMask ? blendState.ColorWriteMask : static_cast<ColorComponentFlags>(0xF);
rtBlendDesc.BlendEnable = blendState.EnableBlend;
rtBlendDesc.SrcBlend = JulietToD3D12_BlendFactor[ToUnderlying(blendState.SourceColorBlendFactor)];
rtBlendDesc.DestBlend = JulietToD3D12_BlendFactor[ToUnderlying(blendState.DestinationColorBlendFactor)];
rtBlendDesc.BlendOp = JulietToD3D12_BlendOperation[ToUnderlying(blendState.ColorBlendOperation)];
rtBlendDesc.SrcBlendAlpha = JulietToD3D12_BlendFactorAlpha[ToUnderlying(blendState.SourceAlphaBlendFactor)];
rtBlendDesc.DestBlendAlpha =
JulietToD3D12_BlendFactorAlpha[ToUnderlying(blendState.DestinationAlphaBlendFactor)];
rtBlendDesc.BlendOpAlpha = JulietToD3D12_BlendOperation[ToUnderlying(blendState.AlphaBlendOperation)];
rtBlendDesc.RenderTargetWriteMask = ToUnderlying(colorWriteMask);
if (i > 0)
{
blendDesc.IndependentBlendEnable = TRUE;
}
}
blendDesc.RenderTarget[i] = rtBlendDesc;
}
return true;
}
bool ConvertDepthStencilState(DepthStencilState depthStencilState, D3D12_DEPTH_STENCIL_DESC& desc)
{
desc.DepthEnable = depthStencilState.EnableDepthTest == true ? TRUE : FALSE;
desc.DepthWriteMask = depthStencilState.EnableDepthWrite == true ? D3D12_DEPTH_WRITE_MASK_ALL : D3D12_DEPTH_WRITE_MASK_ZERO;
desc.DepthFunc = JulietToD3D12_CompareOperation[ToUnderlying(depthStencilState.CompareOperation)];
desc.StencilEnable = depthStencilState.EnableStencilTest == true ? TRUE : FALSE;
desc.StencilReadMask = depthStencilState.CompareMask;
desc.StencilWriteMask = depthStencilState.WriteMask;
desc.FrontFace.StencilFailOp =
JulietToD3D12_StencilOperation[ToUnderlying(depthStencilState.FrontStencilState.FailOperation)];
desc.FrontFace.StencilDepthFailOp =
JulietToD3D12_StencilOperation[ToUnderlying(depthStencilState.FrontStencilState.DepthFailOperation)];
desc.FrontFace.StencilPassOp =
JulietToD3D12_StencilOperation[ToUnderlying(depthStencilState.FrontStencilState.PassOperation)];
desc.FrontFace.StencilFunc =
JulietToD3D12_CompareOperation[ToUnderlying(depthStencilState.FrontStencilState.CompareOperation)];
desc.BackFace.StencilFailOp =
JulietToD3D12_StencilOperation[ToUnderlying(depthStencilState.BackStencilState.FailOperation)];
desc.BackFace.StencilDepthFailOp =
JulietToD3D12_StencilOperation[ToUnderlying(depthStencilState.BackStencilState.DepthFailOperation)];
desc.BackFace.StencilPassOp =
JulietToD3D12_StencilOperation[ToUnderlying(depthStencilState.BackStencilState.PassOperation)];
desc.BackFace.StencilFunc =
JulietToD3D12_CompareOperation[ToUnderlying(depthStencilState.BackStencilState.CompareOperation)];
return true;
}
void CopyShader(NonNullPtr<D3D12Shader> destination, NonNullPtr<D3D12Shader> source)
{
D3D12Shader* src = source.Get();
D3D12Shader* dst = destination.Get();
ByteBuffer dstBuffer = dst->ByteCode;
if (src->ByteCode.Size != dstBuffer.Size)
{
dstBuffer.Data = static_cast<Byte*>(Realloc(dstBuffer.Data, src->ByteCode.Size));
dstBuffer.Size = src->ByteCode.Size;
}
// Copy the shader data. Infortunately this will overwrite the bytecode if it exists so we patch it back just after
MemCopy(dst, src, sizeof(D3D12Shader));
dst->ByteCode = dstBuffer;
MemCopy(dst->ByteCode.Data, src->ByteCode.Data, src->ByteCode.Size);
}
} // namespace
GraphicsPipeline* CreateGraphicsPipeline(NonNullPtr<GPUDriver> driver, const GraphicsPipelineCreateInfo& createInfo)
{
auto d3d12Driver = static_cast<D3D12Driver*>(driver.Get());
auto vertexShader = reinterpret_cast<D3D12Shader*>(createInfo.VertexShader);
auto fragmentShader = reinterpret_cast<D3D12Shader*>(createInfo.FragmentShader);
D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {};
psoDesc.VS.pShaderBytecode = vertexShader->ByteCode.Data;
psoDesc.VS.BytecodeLength = vertexShader->ByteCode.Size;
psoDesc.PS.pShaderBytecode = fragmentShader->ByteCode.Data; // PS == Pixel Shader == Fragment Shader
psoDesc.PS.BytecodeLength = fragmentShader->ByteCode.Size;
if (createInfo.VertexInputState.NumVertexAttributes > 0)
{
D3D12_INPUT_ELEMENT_DESC inputElementDescs[D3D12_IA_VERTEX_INPUT_STRUCTURE_ELEMENT_COUNT];
psoDesc.InputLayout.pInputElementDescs = inputElementDescs;
psoDesc.InputLayout.NumElements = createInfo.VertexInputState.NumVertexAttributes;
ConvertVertexInputState(createInfo.VertexInputState, inputElementDescs, d3d12Driver->Semantic);
}
psoDesc.PrimitiveTopologyType = JulietToD3D12_PrimitiveTopologyType[ToUnderlying(createInfo.PrimitiveType)];
if (!ConvertRasterizerState(createInfo.RasterizerState, psoDesc.RasterizerState))
{
return nullptr;
}
if (!ConvertBlendState(createInfo, psoDesc.BlendState))
{
return nullptr;
}
if (!ConvertDepthStencilState(createInfo.DepthStencilState, psoDesc.DepthStencilState))
{
return nullptr;
}
auto pipeline = static_cast<D3D12GraphicsPipeline*>(Calloc(1, sizeof(D3D12GraphicsPipeline)));
if (!pipeline)
{
return nullptr;
}
uint32 sampleMask = createInfo.MultisampleState.EnableMask ? createInfo.MultisampleState.SampleMask : 0xFFFFFFFF;
psoDesc.SampleMask = sampleMask;
psoDesc.SampleDesc.Count = Internal::JulietToD3D12_SampleCount[ToUnderlying(createInfo.MultisampleState.SampleCount)];
psoDesc.SampleDesc.Quality =
(createInfo.MultisampleState.SampleCount > TextureSampleCount::One) ? DXGI_STANDARD_MULTISAMPLE_QUALITY_PATTERN : 0;
psoDesc.DSVFormat = Internal::ConvertToD3D12DepthFormat(createInfo.TargetInfo.DepthStencilFormat);
psoDesc.NumRenderTargets = static_cast<uint32>(createInfo.TargetInfo.NumColorTargets);
for (uint32_t idx = 0; idx < createInfo.TargetInfo.NumColorTargets; ++idx)
{
psoDesc.RTVFormats[idx] =
Internal::ConvertToD3D12TextureFormat(createInfo.TargetInfo.ColorTargetDescriptions[idx].Format);
}
// Assuming some default values or further initialization
psoDesc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE;
psoDesc.CachedPSO.CachedBlobSizeInBytes = 0;
psoDesc.CachedPSO.pCachedBlob = nullptr;
psoDesc.NodeMask = 0;
pipeline->RootSignature = d3d12Driver->BindlessRootSignature;
psoDesc.pRootSignature = d3d12Driver->BindlessRootSignature->Handle;
ID3D12PipelineState* pipelineState;
HRESULT res = ID3D12Device_CreateGraphicsPipelineState(d3d12Driver->D3D12Device, &psoDesc, IID_ID3D12PipelineState,
reinterpret_cast<void**>(&pipelineState));
if (FAILED(res))
{
LogError(d3d12Driver->D3D12Device, "Could not create graphics pipeline state", res);
Internal::ReleaseGraphicsPipeline(pipeline);
return nullptr;
}
pipeline->PipelineState = pipelineState;
for (uint32 i = 0; i < createInfo.VertexInputState.NumVertexBufferDescriptions; i += 1)
{
pipeline->VertexStrides[createInfo.VertexInputState.VertexBufferDescriptions[i].Slot] =
createInfo.VertexInputState.VertexBufferDescriptions[i].PitchInBytes;
}
pipeline->PrimitiveType = createInfo.PrimitiveType;
pipeline->VertexSamplerCount = vertexShader->NumSamplers;
pipeline->VertexStorageTextureCount = vertexShader->NumStorageTextures;
pipeline->VertexStorageBufferCount = vertexShader->NumStorageBuffers;
pipeline->VertexUniformBufferCount = vertexShader->NumUniformBuffers;
pipeline->FragmentSamplerCount = fragmentShader->NumSamplers;
pipeline->FragmentStorageTextureCount = fragmentShader->NumStorageTextures;
pipeline->FragmentStorageBufferCount = fragmentShader->NumStorageBuffers;
pipeline->FragmentUniformBufferCount = fragmentShader->NumUniformBuffers;
pipeline->ReferenceCount = 0;
#if ALLOW_SHADER_HOT_RELOAD
// Save the PSODesc and shaders to be able to recreate the graphics pipeline when needed
pipeline->PSODescTemplate = psoDesc;
pipeline->VertexShaderCache = static_cast<D3D12Shader*>(Calloc(1, sizeof(D3D12Shader)));
pipeline->FragmentShaderCache = static_cast<D3D12Shader*>(Calloc(1, sizeof(D3D12Shader)));
CopyShader(pipeline->VertexShaderCache, vertexShader);
CopyShader(pipeline->FragmentShaderCache, fragmentShader);
#endif
return reinterpret_cast<GraphicsPipeline*>(pipeline);
}
void DestroyGraphicsPipeline(NonNullPtr<GPUDriver> driver, NonNullPtr<GraphicsPipeline> graphicsPipeline)
{
auto d3d12Driver = static_cast<D3D12Driver*>(driver.Get());
auto d3d12GraphicsPipeline = reinterpret_cast<D3D12GraphicsPipeline*>(graphicsPipeline.Get());
if (d3d12Driver->GraphicsPipelinesToDisposeCount + 1 >= d3d12Driver->GraphicsPipelinesToDisposeCapacity)
{
d3d12Driver->GraphicsPipelinesToDisposeCapacity = d3d12Driver->GraphicsPipelinesToDisposeCapacity * 2;
d3d12Driver->GraphicsPipelinesToDispose = static_cast<D3D12GraphicsPipeline**>(
Realloc(d3d12Driver->GraphicsPipelinesToDispose,
sizeof(D3D12GraphicsPipeline*) * d3d12Driver->GraphicsPipelinesToDisposeCapacity));
}
d3d12Driver->GraphicsPipelinesToDispose[d3d12Driver->GraphicsPipelinesToDisposeCount] = d3d12GraphicsPipeline;
d3d12Driver->GraphicsPipelinesToDisposeCount += 1;
}
#if ALLOW_SHADER_HOT_RELOAD
bool UpdateGraphicsPipelineShaders(NonNullPtr<GPUDriver> driver, NonNullPtr<GraphicsPipeline> graphicsPipeline,
Shader* optional_vertexShader, Shader* optional_fragmentShader)
{
auto d3d12Driver = static_cast<D3D12Driver*>(driver.Get());
auto d3d12GraphicsPipeline = reinterpret_cast<D3D12GraphicsPipeline*>(graphicsPipeline.Get());
Assert(d3d12GraphicsPipeline->ReferenceCount == 0 &&
"Trying to update a d3d12 graphics pipeline that is currently being used! Call WaitUntilGPUIsIdle "
"before updating!");
auto vertexShader = reinterpret_cast<D3D12Shader*>(optional_vertexShader);
auto fragmentShader = reinterpret_cast<D3D12Shader*>(optional_fragmentShader);
if (!vertexShader)
{
vertexShader = d3d12GraphicsPipeline->VertexShaderCache;
}
if (!fragmentShader)
{
fragmentShader = d3d12GraphicsPipeline->FragmentShaderCache;
}
auto psoDesc = d3d12GraphicsPipeline->PSODescTemplate;
psoDesc.VS.pShaderBytecode = vertexShader->ByteCode.Data;
psoDesc.VS.BytecodeLength = vertexShader->ByteCode.Size;
psoDesc.PS.pShaderBytecode = fragmentShader->ByteCode.Data;
psoDesc.PS.BytecodeLength = fragmentShader->ByteCode.Size;
psoDesc.pRootSignature = d3d12Driver->BindlessRootSignature->Handle;
ID3D12PipelineState* pipelineState;
HRESULT res = ID3D12Device_CreateGraphicsPipelineState(d3d12Driver->D3D12Device, &psoDesc, IID_ID3D12PipelineState,
reinterpret_cast<void**>(&pipelineState));
if (FAILED(res))
{
LogError(d3d12Driver->D3D12Device, "Could not create graphics pipeline state", res);
return false;
}
d3d12GraphicsPipeline->VertexSamplerCount = vertexShader->NumSamplers;
d3d12GraphicsPipeline->VertexStorageTextureCount = vertexShader->NumStorageTextures;
d3d12GraphicsPipeline->VertexStorageBufferCount = vertexShader->NumStorageBuffers;
d3d12GraphicsPipeline->VertexUniformBufferCount = vertexShader->NumUniformBuffers;
d3d12GraphicsPipeline->FragmentSamplerCount = fragmentShader->NumSamplers;
d3d12GraphicsPipeline->FragmentStorageTextureCount = fragmentShader->NumStorageTextures;
d3d12GraphicsPipeline->FragmentStorageBufferCount = fragmentShader->NumStorageBuffers;
d3d12GraphicsPipeline->FragmentUniformBufferCount = fragmentShader->NumUniformBuffers;
// If everything worked, we patch the graphics pipeline and destroy everything irrelevant
if (d3d12GraphicsPipeline->PipelineState)
{
ID3D12PipelineState_Release(d3d12GraphicsPipeline->PipelineState);
}
d3d12GraphicsPipeline->PipelineState = pipelineState;
if (vertexShader != d3d12GraphicsPipeline->VertexShaderCache)
{
CopyShader(d3d12GraphicsPipeline->VertexShaderCache, vertexShader);
}
if (fragmentShader != d3d12GraphicsPipeline->FragmentShaderCache)
{
CopyShader(d3d12GraphicsPipeline->FragmentShaderCache, fragmentShader);
}
return true;
}
#endif
namespace Internal
{
void ReleaseGraphicsPipeline(NonNullPtr<D3D12GraphicsPipeline> d3d12GraphicsPipeline)
{
if (d3d12GraphicsPipeline->PipelineState)
{
ID3D12PipelineState_Release(d3d12GraphicsPipeline->PipelineState);
}
#if ALLOW_SHADER_HOT_RELOAD
SafeFree(d3d12GraphicsPipeline->VertexShaderCache);
SafeFree(d3d12GraphicsPipeline->FragmentShaderCache);
#endif
Free(d3d12GraphicsPipeline.Get());
}
} // namespace Internal
} // namespace Juliet::D3D12

View File

@@ -0,0 +1,63 @@
#pragma once
#include <Core/Common/NonNullPtr.h>
#include <D3D12Shader.h>
#include <Graphics/D3D12/D3D12Includes.h>
#include <Graphics/GraphicsDevice.h>
#include <Graphics/GraphicsPipeline.h>
namespace Juliet
{
struct GraphicsPipelineCreateInfo;
struct GPUDriver;
struct GraphicsPipeline;
} // namespace Juliet
namespace Juliet::D3D12
{
struct D3D12GraphicsRootSignature
{
ID3D12RootSignature* Handle;
};
struct D3D12GraphicsPipeline
{
#if ALLOW_SHADER_HOT_RELOAD
// Template to recreate an ID3D12PipelineState when shader are hot reloaded
// Stripped out in shipping build as the struct is huge
D3D12_GRAPHICS_PIPELINE_STATE_DESC PSODescTemplate;
// Keeping shaders byte code to make it easier to recreate the ID3D12PipelineState
// Those will be freed when the pipeline is destroyed or updated
D3D12Shader * VertexShaderCache;
D3D12Shader * FragmentShaderCache;
#endif
ID3D12PipelineState* PipelineState;
D3D12GraphicsRootSignature* RootSignature;
PrimitiveType PrimitiveType;
uint32 VertexStrides[GPUDriver::kMaxVertexBuffers];
uint32 VertexSamplerCount;
uint32 VertexUniformBufferCount;
uint32 VertexStorageBufferCount;
uint32 VertexStorageTextureCount;
uint32 FragmentSamplerCount;
uint32 FragmentUniformBufferCount;
uint32 FragmentStorageBufferCount;
uint32 FragmentStorageTextureCount;
int ReferenceCount;
};
extern GraphicsPipeline* CreateGraphicsPipeline(NonNullPtr<GPUDriver> driver, const GraphicsPipelineCreateInfo& createInfo);
extern void DestroyGraphicsPipeline(NonNullPtr<GPUDriver> driver, NonNullPtr<GraphicsPipeline> graphicsPipeline);
extern bool UpdateGraphicsPipelineShaders(NonNullPtr<GPUDriver> driver, NonNullPtr<GraphicsPipeline> graphicsPipeline,
Shader* optional_vertexShader, Shader* optional_fragmentShader);
namespace Internal
{
extern void ReleaseGraphicsPipeline(NonNullPtr<D3D12GraphicsPipeline> d3d12GraphicsPipeline);
}
} // namespace Juliet::D3D12

View File

@@ -11,27 +11,23 @@
#define COBJMACROS #define COBJMACROS
#define CINTERFACE ; #define CINTERFACE ;
#include <d3dcompiler.h> #include <Graphics/D3D12/AgilitySDK/d3d12.h>
#include <DirectXMath.h> //#include <Graphics/D3D12/AgilitySDK/d3dx12/d3dx12_check_feature_support.h>
#include <dxgi1_5.h>
#include <dxgi1_6.h> #include <dxgi1_6.h>
#include "d3d12.h"
#include <d3d12shader.h>
// TODO: Should not use this when shipping
// Prebake the shaders and embed .dxil files
// When not shipping, thats ok to compile them
// #include <dxcapi.h>
#ifdef _DEBUG #ifdef _DEBUG
#include <dxgidebug.h> #include <dxgidebug.h>
#endif #endif
#include <dxgi.h> //#include <dxgi.h>
#ifdef __IDXGIInfoQueue_INTERFACE_DEFINED__ #ifdef __IDXGIInfoQueue_INTERFACE_DEFINED__
#define IDXGIINFOQUEUE_SUPPORTED #define IDXGIINFOQUEUE_SUPPORTED
#endif #endif
#ifdef __ID3D12InfoQueue1_INTERFACE_DEFINED__
#define ID3D12InfoQueue1_SUPPORTED
#endif
#undef min #undef min
#undef max #undef max

View File

@@ -1,12 +1,28 @@
#include <pch.h> #include <pch.h>
#include <Core/Common/EnumUtils.h>
#include <Graphics/D3D12/D3D12GraphicsPipeline.h>
#include <Graphics/D3D12/D3D12RenderPass.h> #include <Graphics/D3D12/D3D12RenderPass.h>
#include <Graphics/D3D12/D3D12Texture.h> #include <Graphics/D3D12/D3D12Texture.h>
#include <algorithm>
namespace Juliet::D3D12 namespace Juliet::D3D12
{ {
namespace
{
// clang-format off
D3D12_PRIMITIVE_TOPOLOGY JulietToD3D12_PrimitiveType[] =
{
D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST,
D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP,
D3D_PRIMITIVE_TOPOLOGY_LINELIST,
D3D_PRIMITIVE_TOPOLOGY_LINESTRIP,
D3D_PRIMITIVE_TOPOLOGY_POINTLIST
};
// clang-format on
static_assert(sizeof(JulietToD3D12_PrimitiveType) / sizeof(JulietToD3D12_PrimitiveType[0]) ==
ToUnderlying(PrimitiveType::Count));
} // namespace
void BeginRenderPass(NonNullPtr<CommandList> commandList, NonNullPtr<const ColorTargetInfo> colorTargetInfos, uint32 colorTargetInfoCount) void BeginRenderPass(NonNullPtr<CommandList> commandList, NonNullPtr<const ColorTargetInfo> colorTargetInfos, uint32 colorTargetInfoCount)
{ {
auto* d3d12CommandList = reinterpret_cast<D3D12CommandList*>(commandList.Get()); auto* d3d12CommandList = reinterpret_cast<D3D12CommandList*>(commandList.Get());
@@ -54,7 +70,7 @@ namespace Juliet::D3D12
RTVs[idx] = rtv; RTVs[idx] = rtv;
d3d12CommandList->ColorTargetSubresources[idx] = subresource; d3d12CommandList->ColorTargetSubresources[idx] = subresource;
// TODO: TrackTexture Internal::TrackTexture(d3d12CommandList, subresource->Parent);
if (colorTargetInfos[idx].StoreOperation == StoreOperation::Resolve || if (colorTargetInfos[idx].StoreOperation == StoreOperation::Resolve ||
colorTargetInfos[idx].StoreOperation == StoreOperation::ResolveAndStore) colorTargetInfos[idx].StoreOperation == StoreOperation::ResolveAndStore)
@@ -69,7 +85,7 @@ namespace Juliet::D3D12
d3d12CommandList->ColorResolveSubresources[idx] = resolveSubresource; d3d12CommandList->ColorResolveSubresources[idx] = resolveSubresource;
// TODO: TrackTexture Resolve Internal::TrackTexture(d3d12CommandList, resolveSubresource->Parent);
} }
} }
@@ -146,7 +162,7 @@ namespace Juliet::D3D12
} }
// TODO : Write Depth stencil // TODO : Write Depth stencil
// TODO : Reset graphics pipeline d3d12CommandList->CurrentGraphicsPipeline = nullptr;
ID3D12GraphicsCommandList_OMSetRenderTargets(d3d12CommandList->GraphicsCommandList.CommandList, 0, NULL, false, NULL); ID3D12GraphicsCommandList_OMSetRenderTargets(d3d12CommandList->GraphicsCommandList.CommandList, 0, NULL, false, NULL);
@@ -154,7 +170,83 @@ namespace Juliet::D3D12
ZeroArray(d3d12CommandList->ColorTargetSubresources); ZeroArray(d3d12CommandList->ColorTargetSubresources);
ZeroArray(d3d12CommandList->ColorResolveSubresources); ZeroArray(d3d12CommandList->ColorResolveSubresources);
// TODO : reset depth stencil subresources // TODO : reset depth stencil subresources
// d3d12CommandList->DepthStencilTextureSubresource = NULL;
// TODO : vertex buffer // TODO : vertex buffer
// TODO :Vertex sampler and fragment sampler // TODO :Vertex sampler and fragment sampler
// ZeroArray(d3d12CommandList->VertexBuffers);
// ZeroArray(d3d12CommandList->VertexBufferOffsets);
// d3d12CommandList->VertexBufferCount = 0;
//
// ZeroArray(d3d12CommandList->VertexSamplerTextures);
// ZeroArray(d3d12CommandList->VertexSamplers);
// ZeroArray(d3d12CommandList->VertexStorageTextures);
// ZeroArray(d3d12CommandList->VertexStorageBuffers);
//
// ZeroArray(d3d12CommandList->FragmentSamplerTextures);
// ZeroArray(d3d12CommandList->FragmentSamplers);
// ZeroArray(d3d12CommandList->FragmentStorageTextures);
// ZeroArray(d3d12CommandList->FragmentStorageBuffers);
}
void BindGraphicsPipeline(NonNullPtr<CommandList> commandList, NonNullPtr<GraphicsPipeline> graphicsPipeline)
{
auto* d3d12CommandList = reinterpret_cast<D3D12CommandList*>(commandList.Get());
auto pipeline = reinterpret_cast<D3D12GraphicsPipeline*>(graphicsPipeline.Get());
d3d12CommandList->CurrentGraphicsPipeline = pipeline;
// Set the Descriptor heap
Internal::SetDescriptorHeaps(d3d12CommandList);
// Set the pipeline state
ID3D12GraphicsCommandList_SetPipelineState(d3d12CommandList->GraphicsCommandList.CommandList, pipeline->PipelineState);
ID3D12GraphicsCommandList_SetGraphicsRootSignature(d3d12CommandList->GraphicsCommandList.CommandList,
pipeline->RootSignature->Handle);
ID3D12GraphicsCommandList_IASetPrimitiveTopology(d3d12CommandList->GraphicsCommandList.CommandList,
JulietToD3D12_PrimitiveType[ToUnderlying(pipeline->PrimitiveType)]);
// Mark that bindings are needed
d3d12CommandList->NeedVertexSamplerBind = true;
d3d12CommandList->NeedVertexStorageTextureBind = true;
d3d12CommandList->NeedVertexStorageBufferBind = true;
d3d12CommandList->NeedFragmentSamplerBind = true;
d3d12CommandList->NeedFragmentStorageTextureBind = true;
d3d12CommandList->NeedFragmentStorageBufferBind = true;
for (uint32 idx = 0; idx < GPUDriver::kMaxUniformBuffersPerStage; ++idx)
{
d3d12CommandList->NeedVertexUniformBufferBind[idx] = true;
d3d12CommandList->NeedFragmentUniformBufferBind[idx] = true;
}
for (uint32 idx = 0; idx < pipeline->VertexUniformBufferCount; ++idx)
{
// if (d3d12CommandList->VertexUniformBuffers[i] == NULL)
// {
// d3d12CommandList->VertexUniformBuffers[i] = D3D12_INTERNAL_AcquireUniformBufferFromPool(d3d12CommandBuffer);
// }
}
for (uint32 idx = 0; idx < pipeline->FragmentUniformBufferCount; ++idx)
{
// if (d3d12CommandList->FragmentUniformBuffers[i] == NULL)
// {
// d3d12CommandList->FragmentUniformBuffers[i] = D3D12_INTERNAL_AcquireUniformBufferFromPool(d3d12CommandBuffer);
// }
}
Internal::TrackGraphicsPipeline(d3d12CommandList, pipeline);
}
void DrawPrimitives(NonNullPtr<CommandList> commandList, uint32 numVertices, uint32 numInstances, uint32 firstVertex, uint32 firstInstance)
{
auto* d3d12CommandList = reinterpret_cast<D3D12CommandList*>(commandList.Get());
// TODO : Last missing piece
// D3D12_INTERNAL_BindGraphicsResources(d3d12CommandBuffer);
ID3D12GraphicsCommandList_DrawInstanced(d3d12CommandList->GraphicsCommandList.CommandList, numVertices,
numInstances, firstVertex, firstInstance);
} }
} // namespace Juliet::D3D12 } // namespace Juliet::D3D12

View File

@@ -1,7 +1,7 @@
#pragma once #pragma once
#include <core/Common/NonNullPtr.h> #include <core/Common/NonNullPtr.h>
#include <Graphics/D3D12/DX12CommandList.h> #include <Graphics/D3D12/D3D12CommandList.h>
#include <Graphics/RenderPass.h> #include <Graphics/RenderPass.h>
namespace Juliet::D3D12 namespace Juliet::D3D12
@@ -9,4 +9,8 @@ namespace Juliet::D3D12
extern void BeginRenderPass(NonNullPtr<CommandList> commandList, NonNullPtr<const ColorTargetInfo> colorTargetInfos, extern void BeginRenderPass(NonNullPtr<CommandList> commandList, NonNullPtr<const ColorTargetInfo> colorTargetInfos,
uint32 colorTargetInfoCount); uint32 colorTargetInfoCount);
extern void EndRenderPass(NonNullPtr<CommandList> commandList); extern void EndRenderPass(NonNullPtr<CommandList> commandList);
extern void BindGraphicsPipeline(NonNullPtr<CommandList> commandList, NonNullPtr<GraphicsPipeline> graphicsPipeline);
extern void DrawPrimitives(NonNullPtr<CommandList> commandList, uint32 numVertices, uint32 numInstances,
uint32 firstVertex, uint32 firstInstance);
} // namespace Juliet::D3D12 } // namespace Juliet::D3D12

View File

@@ -1,16 +1,46 @@
#include <pch.h> #include <pch.h>
#include <Core/Memory/Allocator.h>
#include <Graphics/D3D12/D3D12Shader.h> #include <Graphics/D3D12/D3D12Shader.h>
namespace Juliet::D3D12 namespace Juliet::D3D12
{ {
namespace Shader* CreateShader(NonNullPtr<GPUDriver> driver, ByteBuffer shaderByteCode, ShaderCreateInfo& shaderCreateInfo)
{ {
void CompileShader(const char* shaderFile) {} if (!IsValid(shaderByteCode))
} // namespace {
LogError(LogCategory::Graphics, "Invalid shader byte code");
return nullptr;
}
void LoadShader(const char* shaderFile) size_t allocSize = sizeof(D3D12Shader) + shaderByteCode.Size;
auto shader = static_cast<D3D12Shader*>(Calloc(1, allocSize));
if (!shader)
{
LogError(LogCategory::Graphics, "Cannot allocate a new D3D12Shader: Out of memory");
return nullptr;
}
// Uses the bytes after the struct to store the shader byte code.
// TODO:MemoryArena Will use memory arena later that will do the same thing
shader->ByteCode.Data = reinterpret_cast<Byte*>(shader + 1);
shader->ByteCode.Size = shaderByteCode.Size;
MemCopy(shader->ByteCode.Data, shaderByteCode.Data, shaderByteCode.Size);
// Make sure the data is correctly copied
if (MemCompare(shader->ByteCode.Data, shaderByteCode.Data, shaderByteCode.Size) != 0)
{
LogError(LogCategory::Graphics, "Memory copy failed");
Free(shader);
return nullptr;
}
return reinterpret_cast<Shader*>(shader);
}
void DestroyShader(NonNullPtr<GPUDriver> driver, NonNullPtr<Shader> shader)
{ {
CompileShader(shaderFile); auto d3d12shader = reinterpret_cast<D3D12Shader*>(shader.Get());
Free(d3d12shader);
} }
} // namespace Juliet::D3D12 } // namespace Juliet::D3D12

View File

@@ -1,6 +1,21 @@
#pragma once #pragma once
#include <Core/Common/NonNullPtr.h>
#include <Graphics/GraphicsDevice.h>
#include <Graphics/Shader.h>
namespace Juliet::D3D12 namespace Juliet::D3D12
{ {
extern void LoadShader(const char* shaderFile); struct D3D12Shader
} {
ByteBuffer ByteCode;
uint32 NumSamplers;
uint32 NumUniformBuffers;
uint32 NumStorageBuffers;
uint32 NumStorageTextures;
};
extern Shader* CreateShader(NonNullPtr<GPUDriver> driver, ByteBuffer shaderByteCode, ShaderCreateInfo& shaderCreateInfo);
extern void DestroyShader(NonNullPtr<GPUDriver> driver, NonNullPtr<Shader> shader);
} // namespace Juliet::D3D12

View File

@@ -2,14 +2,15 @@
#include <Core/HAL/Display/Win32/Win32Window.h> #include <Core/HAL/Display/Win32/Win32Window.h>
#include <Core/Memory/Allocator.h> #include <Core/Memory/Allocator.h>
#include <Graphics/D3D12/D3D12CommandList.h>
#include <Graphics/D3D12/D3D12GraphicsDevice.h>
#include <Graphics/D3D12/D3D12Includes.h>
#include <Graphics/D3D12/D3D12SwapChain.h>
#include <Graphics/D3D12/D3D12Texture.h> #include <Graphics/D3D12/D3D12Texture.h>
#include <Graphics/D3D12/DX12CommandList.h> #include <Graphics/D3D12/D3D12Utils.h>
#include <Graphics/D3D12/DX12GraphicsDevice.h>
#include <Graphics/D3D12/DX12Includes.h>
#include <Graphics/D3D12/DX12SwapChain.h>
#include <Graphics/D3D12/DX12Utils.h>
#include <algorithm> #include <algorithm>
#include <D3D12Synchronization.h>
namespace Juliet::D3D12 namespace Juliet::D3D12
{ {
@@ -44,24 +45,24 @@ namespace Juliet::D3D12
IDXGISwapChain_GetBuffer(swapChain, index, IID_ID3D12Resource, reinterpret_cast<void**>(&swapChainTexture)); IDXGISwapChain_GetBuffer(swapChain, index, IID_ID3D12Resource, reinterpret_cast<void**>(&swapChainTexture));
if (FAILED(result)) if (FAILED(result))
{ {
LogError(driver, "Cannot get buffer from SwapChain", result); LogError(driver->D3D12Device, "Cannot get buffer from SwapChain", result);
return false; return false;
} }
auto texture = static_cast<D3D12Texture*>(Calloc(1, sizeof(D3D12Texture))); auto texture = static_cast<D3D12Texture*>(Calloc(1, sizeof(D3D12Texture)));
if (!texture) if (!texture)
{ {
LogError(driver, "Cannot allocate D3D12Texture (out of memory)", result); LogError(driver->D3D12Device, "Cannot allocate D3D12Texture (out of memory)", result);
ID3D12Resource_Release(swapChainTexture); ID3D12Resource_Release(swapChainTexture);
return false; return false;
} }
texture->RefCount += 1; texture->ReferenceCount += 1;
texture->SubresourceCount = 1; texture->SubresourceCount = 1;
texture->Subresources = static_cast<D3D12TextureSubresource*>(Calloc(1, sizeof(D3D12TextureSubresource))); texture->Subresources = static_cast<D3D12TextureSubresource*>(Calloc(1, sizeof(D3D12TextureSubresource)));
if (!texture->Subresources) if (!texture->Subresources)
{ {
LogError(driver, "Cannot allocate D3D12TextureSubresource (out of memory)", result); LogError(driver->D3D12Device, "Cannot allocate D3D12TextureSubresource (out of memory)", result);
Free(texture); Free(texture);
ID3D12Resource_Release(swapChainTexture); ID3D12Resource_Release(swapChainTexture);
return false; return false;
@@ -105,18 +106,6 @@ namespace Juliet::D3D12
texture->Container = textureContainer; texture->Container = textureContainer;
texture->IndexInContainer = 0; texture->IndexInContainer = 0;
// Assign SRV to the swapchain texture
Internal::AssignStagingDescriptor(driver, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, texture->SRVHandle);
D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc;
srvDesc.Format = SwapchainCompositionToTextureFormat[ToUnderlying(composition)];
srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
srvDesc.Texture2D.MipLevels = 1;
srvDesc.Texture2D.MostDetailedMip = 0;
srvDesc.Texture2D.ResourceMinLODClamp = 0;
srvDesc.Texture2D.PlaneSlice = 0;
ID3D12Device_CreateShaderResourceView(driver->D3D12Device, swapChainTexture, &srvDesc, texture->SRVHandle.CpuHandle);
// Assign RTV to the swapchain texture // Assign RTV to the swapchain texture
DXGI_FORMAT swapchainFormat = SwapchainCompositionToTextureFormat[ToUnderlying(composition)]; DXGI_FORMAT swapchainFormat = SwapchainCompositionToTextureFormat[ToUnderlying(composition)];
Internal::AssignStagingDescriptor(driver, D3D12_DESCRIPTOR_HEAP_TYPE_RTV, texture->Subresources[0].RTVHandles[0]); Internal::AssignStagingDescriptor(driver, D3D12_DESCRIPTOR_HEAP_TYPE_RTV, texture->Subresources[0].RTVHandles[0]);
@@ -145,8 +134,30 @@ namespace Juliet::D3D12
auto* windowData = driver->WindowData; auto* windowData = driver->WindowData;
Assert(windowData->Window == window.Get()); Assert(windowData->Window == window.Get());
// TODO : FENCES if (windowData->InFlightFences[windowData->WindowFrameCounter] != nullptr)
Assert(!block); {
if (block)
{
// Wait until the fence for the frame is signaled.
// In VSYNC this means waiting that the least recent presented frame is done
if (!Wait(driver, true, &windowData->InFlightFences[windowData->WindowFrameCounter], 1))
{
return false;
}
}
else
{
// If work is not done, the least recent fence wont be signaled.
// In that case we return true to notify that there is no error, but rendering should be skipped as their will be no swapchainTexture
if (!QueryFence(driver, windowData->InFlightFences[windowData->WindowFrameCounter]))
{
return true;
}
}
ReleaseFence(driver, windowData->InFlightFences[windowData->WindowFrameCounter]);
windowData->InFlightFences[windowData->WindowFrameCounter] = nullptr;
}
uint32 swapchainIndex = IDXGISwapChain3_GetCurrentBackBufferIndex(windowData->SwapChain); uint32 swapchainIndex = IDXGISwapChain3_GetCurrentBackBufferIndex(windowData->SwapChain);
HRESULT result = HRESULT result =
@@ -155,7 +166,7 @@ namespace Juliet::D3D12
&windowData->SwapChainTextureContainers[swapchainIndex].ActiveTexture->Resource)); &windowData->SwapChainTextureContainers[swapchainIndex].ActiveTexture->Resource));
if (FAILED(result)) if (FAILED(result))
{ {
LogError(driver, "Could not acquire swapchain", result); LogError(driver->D3D12Device, "Could not acquire swapchain", result);
return false; return false;
} }
@@ -192,6 +203,47 @@ namespace Juliet::D3D12
return AcquireSwapChainTexture(false, commandList, window, swapChainTexture); return AcquireSwapChainTexture(false, commandList, window, swapChainTexture);
} }
bool WaitAndAcquireSwapChainTexture(NonNullPtr<CommandList> commandList, NonNullPtr<Window> window, Texture** swapChainTexture)
{
return AcquireSwapChainTexture(true, commandList, window, swapChainTexture);
}
bool WaitForSwapchain(NonNullPtr<GPUDriver> driver, NonNullPtr<Window> window)
{
auto* d3d12Driver = static_cast<D3D12Driver*>(driver.Get());
auto* windowData = d3d12Driver->WindowData;
if (!windowData)
{
LogError(LogCategory::Graphics, "Cannot wait for swapchain. Window has no Swapchain");
return false;
}
if (windowData->InFlightFences[windowData->WindowFrameCounter] != nullptr)
{
if (!Wait(d3d12Driver, true, &windowData->InFlightFences[windowData->WindowFrameCounter], 1))
{
return false;
}
}
return true;
}
TextureFormat GetSwapChainTextureFormat(NonNullPtr<GPUDriver> driver, NonNullPtr<Window> window)
{
auto* d3d12Driver = static_cast<D3D12Driver*>(driver.Get());
auto* windowData = d3d12Driver->WindowData;
if (!windowData)
{
LogError(LogCategory::Graphics, "Cannot get swapchain format. Window has no Swapchain");
return TextureFormat::Invalid;
}
Assert(windowData->Window == window.Get());
return windowData->SwapChainTextureContainers[windowData->WindowFrameCounter].Header.CreateInfo.Format;
}
namespace Internal namespace Internal
{ {
bool CreateSwapChain(NonNullPtr<D3D12Driver> driver, NonNullPtr<D3D12WindowData> windowData, bool CreateSwapChain(NonNullPtr<D3D12Driver> driver, NonNullPtr<D3D12WindowData> windowData,
@@ -244,7 +296,7 @@ namespace Juliet::D3D12
windowHandle, &swapChainDesc, &swapChainFullscreenDesc, nullptr, &swapChain); windowHandle, &swapChainDesc, &swapChainFullscreenDesc, nullptr, &swapChain);
if (FAILED(result)) if (FAILED(result))
{ {
LogError(driver, "Failed to create SwapChain", result); LogError(driver->D3D12Device, "Failed to create SwapChain", result);
return false; return false;
} }
@@ -253,7 +305,7 @@ namespace Juliet::D3D12
IDXGISwapChain1_Release(swapChain); IDXGISwapChain1_Release(swapChain);
if (FAILED(result)) if (FAILED(result))
{ {
LogError(driver, "Could not query IDXGISwapChain3 interface", result); LogError(driver->D3D12Device, "Could not query IDXGISwapChain3 interface", result);
return false; return false;
} }
@@ -282,7 +334,7 @@ namespace Juliet::D3D12
IDXGISwapChain3_GetDesc1(swapChain3, &swapChainDesc); IDXGISwapChain3_GetDesc1(swapChain3, &swapChainDesc);
if (FAILED(result)) if (FAILED(result))
{ {
LogError(driver, "Failed to retrieve SwapChain descriptor", result); LogError(driver->D3D12Device, "Failed to retrieve SwapChain descriptor", result);
return false; return false;
} }
windowData->SwapChain = swapChain3; windowData->SwapChain = swapChain3;
@@ -309,7 +361,6 @@ namespace Juliet::D3D12
{ {
for (uint32 idx = 0; idx < windowData->SwapChainTextureCount; ++idx) for (uint32 idx = 0; idx < windowData->SwapChainTextureCount; ++idx)
{ {
ReleaseStagingDescriptor(driver, windowData->SwapChainTextureContainers[idx].ActiveTexture->SRVHandle);
ReleaseStagingDescriptor(driver, ReleaseStagingDescriptor(driver,
windowData->SwapChainTextureContainers[idx].ActiveTexture->Subresources[0].RTVHandles[0]); windowData->SwapChainTextureContainers[idx].ActiveTexture->Subresources[0].RTVHandles[0]);

View File

@@ -8,6 +8,9 @@ namespace Juliet::D3D12
struct D3D12WindowData; struct D3D12WindowData;
extern bool AcquireSwapChainTexture(NonNullPtr<CommandList> commandList, NonNullPtr<Window> window, Texture** swapChainTexture); extern bool AcquireSwapChainTexture(NonNullPtr<CommandList> commandList, NonNullPtr<Window> window, Texture** swapChainTexture);
extern bool WaitAndAcquireSwapChainTexture(NonNullPtr<CommandList> commandList, NonNullPtr<Window> window, Texture** swapChainTexture);
extern bool WaitForSwapchain(NonNullPtr<GPUDriver> driver, NonNullPtr<Window> window);
extern TextureFormat GetSwapChainTextureFormat(NonNullPtr<GPUDriver> driver, NonNullPtr<Window> window);
namespace Internal namespace Internal
{ {

View File

@@ -1,10 +1,10 @@
#include <pch.h> #include <pch.h>
#include <Core/Memory/Allocator.h> #include <Core/Memory/Allocator.h>
#include <Graphics/D3D12/D3D12CommandList.h>
#include <Graphics/D3D12/D3D12GraphicsDevice.h>
#include <Graphics/D3D12/D3D12Synchronization.h> #include <Graphics/D3D12/D3D12Synchronization.h>
#include <Graphics/D3D12/DX12CommandList.h> #include <Graphics/D3D12/D3D12Utils.h>
#include <Graphics/D3D12/DX12GraphicsDevice.h>
#include <Graphics/D3D12/DX12Utils.h>
namespace Juliet::D3D12 namespace Juliet::D3D12
{ {
@@ -23,7 +23,7 @@ namespace Juliet::D3D12
} }
} // namespace } // namespace
bool Wait(NonNullPtr<GPUDriver> driver) bool WaitUntilGPUIsIdle(NonNullPtr<GPUDriver> driver)
{ {
auto d3d12driver = static_cast<D3D12Driver*>(driver.Get()); auto d3d12driver = static_cast<D3D12Driver*>(driver.Get());
D3D12Fence* fence = Internal::AcquireFence(d3d12driver); D3D12Fence* fence = Internal::AcquireFence(d3d12driver);
@@ -43,14 +43,14 @@ namespace Juliet::D3D12
HRESULT result = ID3D12Fence_SetEventOnCompletion(fence->Handle, D3D12_FENCE_SIGNAL_VALUE, fence->Event); HRESULT result = ID3D12Fence_SetEventOnCompletion(fence->Handle, D3D12_FENCE_SIGNAL_VALUE, fence->Event);
if (FAILED(result)) if (FAILED(result))
{ {
LogError(d3d12driver, "Setting fence event failed!", result); LogError(d3d12driver->D3D12Device, "Setting fence event failed!", result);
return false; return false;
} }
DWORD waitResult = WaitForSingleObject(fence->Event, INFINITE); DWORD waitResult = WaitForSingleObject(fence->Event, INFINITE);
if (waitResult == WAIT_FAILED) if (waitResult == WAIT_FAILED)
{ {
LogError(d3d12driver, "Wait failed!", result); LogError(d3d12driver->D3D12Device, "Wait failed!", result);
return false; return false;
} }
} }
@@ -61,16 +61,64 @@ namespace Juliet::D3D12
bool result = true; bool result = true;
// Clean up // Clean up
for (int32 idx = d3d12driver->SubmittedCommandListCount - 1; idx >= 0; idx -= 1) for (int32 idx = d3d12driver->SubmittedCommandListCount - 1; idx >= 0; --idx)
{ {
result &= Internal::CleanCommandList(d3d12driver, d3d12driver->SubmittedCommandLists[idx], false); result &= Internal::CleanCommandList(d3d12driver, d3d12driver->SubmittedCommandLists[idx], false);
} }
Internal::DisposePendingResourcces(d3d12driver);
return result;
}
bool Wait(NonNullPtr<GPUDriver> driver, bool waitForAll, Fence* const* fences, uint32 numFences)
{
auto d3d12driver = static_cast<D3D12Driver*>(driver.Get());
// TODO: use scratch allocator for alloca (stack alloc)
auto events = static_cast<HANDLE*>(alloca(sizeof(HANDLE) * numFences));
for (uint32 i = 0; i < numFences; ++i)
{
auto fence = reinterpret_cast<D3D12Fence*>(fences[i]);
HRESULT res = ID3D12Fence_SetEventOnCompletion(fence->Handle, D3D12_FENCE_SIGNAL_VALUE, fence->Event);
if (FAILED(res))
{
LogError(d3d12driver->D3D12Device, "Setting fence event failed!", res);
return false;
}
events[i] = fence->Event;
}
DWORD waitResult = WaitForMultipleObjects(numFences, events, waitForAll, INFINITE);
if (waitResult == WAIT_FAILED)
{
LogError(LogCategory::Graphics, "Wait failed");
return false;
}
bool result = true;
// Clean up
for (int32 idx = d3d12driver->SubmittedCommandListCount - 1; idx >= 0; --idx -= 1)
{
uint64 fenceValue = ID3D12Fence_GetCompletedValue(d3d12driver->SubmittedCommandLists[idx]->InFlightFence->Handle);
if (fenceValue == D3D12_FENCE_SIGNAL_VALUE)
{
result &= Internal::CleanCommandList(d3d12driver, d3d12driver->SubmittedCommandLists[idx], false);
}
}
Internal::DisposePendingResourcces(d3d12driver);
return result; return result;
} }
bool QueryFence(NonNullPtr<GPUDriver> driver, NonNullPtr<Fence> fence) bool QueryFence(NonNullPtr<GPUDriver> driver, NonNullPtr<Fence> fence)
{ {
Unimplemented();
return true; return true;
} }
@@ -135,7 +183,7 @@ namespace Juliet::D3D12
IID_ID3D12Fence, reinterpret_cast<void**>(&handle)); IID_ID3D12Fence, reinterpret_cast<void**>(&handle));
if (FAILED(result)) if (FAILED(result))
{ {
LogError(driver, "Failed to create fence!", result); LogError(driver->D3D12Device, "Failed to create fence!", result);
return nullptr; return nullptr;
} }

View File

@@ -25,7 +25,8 @@ namespace Juliet::D3D12
int32 ReferenceCount; // TODO : Atomic int32 ReferenceCount; // TODO : Atomic
}; };
extern bool Wait(NonNullPtr<GPUDriver> driver); extern bool WaitUntilGPUIsIdle(NonNullPtr<GPUDriver> driver);
extern bool Wait(NonNullPtr<GPUDriver> driver, bool waitForAll, Fence* const* fences, uint32 numFences);
extern bool QueryFence(NonNullPtr<GPUDriver> driver, NonNullPtr<Fence> fence); extern bool QueryFence(NonNullPtr<GPUDriver> driver, NonNullPtr<Fence> fence);
extern void ReleaseFence(NonNullPtr<GPUDriver> driver, NonNullPtr<Fence> fence); extern void ReleaseFence(NonNullPtr<GPUDriver> driver, NonNullPtr<Fence> fence);

View File

@@ -1,9 +1,9 @@
#include <pch.h> #include <pch.h>
#include <Core/Common/EnumUtils.h> #include <Core/Common/EnumUtils.h>
#include <Graphics/D3D12/D3D12CommandList.h>
#include <Graphics/D3D12/D3D12Synchronization.h> #include <Graphics/D3D12/D3D12Synchronization.h>
#include <Graphics/D3D12/D3D12Texture.h> #include <Graphics/D3D12/D3D12Texture.h>
#include <Graphics/D3D12/DX12CommandList.h>
namespace Juliet::D3D12 namespace Juliet::D3D12
{ {
@@ -116,6 +116,117 @@ namespace Juliet::D3D12
DXGI_FORMAT_UNKNOWN, // ASTC_12x10_FLOAT DXGI_FORMAT_UNKNOWN, // ASTC_12x10_FLOAT
DXGI_FORMAT_UNKNOWN, // ASTC_12x12_FLOAT DXGI_FORMAT_UNKNOWN, // ASTC_12x12_FLOAT
}; };
static_assert(sizeof(JulietToD3D12_TextureFormat) / sizeof(JulietToD3D12_TextureFormat[0]) ==
ToUnderlying(TextureFormat::Count));
DXGI_FORMAT JulietToD3D12_DepthFormat[] = {
DXGI_FORMAT_UNKNOWN, // INVALID
DXGI_FORMAT_UNKNOWN, // A8_UNORM
DXGI_FORMAT_UNKNOWN, // R8_UNORM
DXGI_FORMAT_UNKNOWN, // R8G8_UNORM
DXGI_FORMAT_UNKNOWN, // R8G8B8A8_UNORM
DXGI_FORMAT_UNKNOWN, // R16_UNORM
DXGI_FORMAT_UNKNOWN, // R16G16_UNORM
DXGI_FORMAT_UNKNOWN, // R16G16B16A16_UNORM
DXGI_FORMAT_UNKNOWN, // R10G10B10A2_UNORM
DXGI_FORMAT_UNKNOWN, // B5G6R5_UNORM
DXGI_FORMAT_UNKNOWN, // B5G5R5A1_UNORM
DXGI_FORMAT_UNKNOWN, // B4G4R4A4_UNORM
DXGI_FORMAT_UNKNOWN, // B8G8R8A8_UNORM
DXGI_FORMAT_UNKNOWN, // BC1_UNORM
DXGI_FORMAT_UNKNOWN, // BC2_UNORM
DXGI_FORMAT_UNKNOWN, // BC3_UNORM
DXGI_FORMAT_UNKNOWN, // BC4_UNORM
DXGI_FORMAT_UNKNOWN, // BC5_UNORM
DXGI_FORMAT_UNKNOWN, // BC7_UNORM
DXGI_FORMAT_UNKNOWN, // BC6H_FLOAT
DXGI_FORMAT_UNKNOWN, // BC6H_UFLOAT
DXGI_FORMAT_UNKNOWN, // R8_SNORM
DXGI_FORMAT_UNKNOWN, // R8G8_SNORM
DXGI_FORMAT_UNKNOWN, // R8G8B8A8_SNORM
DXGI_FORMAT_UNKNOWN, // R16_SNORM
DXGI_FORMAT_UNKNOWN, // R16G16_SNORM
DXGI_FORMAT_UNKNOWN, // R16G16B16A16_SNORM
DXGI_FORMAT_UNKNOWN, // R16_FLOAT
DXGI_FORMAT_UNKNOWN, // R16G16_FLOAT
DXGI_FORMAT_UNKNOWN, // R16G16B16A16_FLOAT
DXGI_FORMAT_UNKNOWN, // R32_FLOAT
DXGI_FORMAT_UNKNOWN, // R32G32_FLOAT
DXGI_FORMAT_UNKNOWN, // R32G32B32A32_FLOAT
DXGI_FORMAT_UNKNOWN, // R11G11B10_UFLOAT
DXGI_FORMAT_UNKNOWN, // R8_UINT
DXGI_FORMAT_UNKNOWN, // R8G8_UINT
DXGI_FORMAT_UNKNOWN, // R8G8B8A8_UINT
DXGI_FORMAT_UNKNOWN, // R16_UINT
DXGI_FORMAT_UNKNOWN, // R16G16_UINT
DXGI_FORMAT_UNKNOWN, // R16G16B16A16_UINT
DXGI_FORMAT_UNKNOWN, // R32_UINT
DXGI_FORMAT_UNKNOWN, // R32G32_UINT
DXGI_FORMAT_UNKNOWN, // R32G32B32A32_UINT
DXGI_FORMAT_UNKNOWN, // R8_INT
DXGI_FORMAT_UNKNOWN, // R8G8_INT
DXGI_FORMAT_UNKNOWN, // R8G8B8A8_INT
DXGI_FORMAT_UNKNOWN, // R16_INT
DXGI_FORMAT_UNKNOWN, // R16G16_INT
DXGI_FORMAT_UNKNOWN, // R16G16B16A16_INT
DXGI_FORMAT_UNKNOWN, // R32_INT
DXGI_FORMAT_UNKNOWN, // R32G32_INT
DXGI_FORMAT_UNKNOWN, // R32G32B32A32_INT
DXGI_FORMAT_UNKNOWN, // R8G8B8A8_UNORM_SRGB
DXGI_FORMAT_UNKNOWN, // B8G8R8A8_UNORM_SRGB
DXGI_FORMAT_UNKNOWN, // BC1_UNORM_SRGB
DXGI_FORMAT_UNKNOWN, // BC2_UNORM_SRGB
DXGI_FORMAT_UNKNOWN, // BC3_UNORM_SRGB
DXGI_FORMAT_UNKNOWN, // BC7_UNORM_SRGB
DXGI_FORMAT_D16_UNORM, // D16_UNORM
DXGI_FORMAT_D24_UNORM_S8_UINT, // D24_UNORM
DXGI_FORMAT_D32_FLOAT, // D32_FLOAT
DXGI_FORMAT_D24_UNORM_S8_UINT, // D24_UNORM_S8_UINT
DXGI_FORMAT_D32_FLOAT_S8X24_UINT, // D32_FLOAT_S8_UINT
DXGI_FORMAT_UNKNOWN, // ASTC_4x4_UNORM
DXGI_FORMAT_UNKNOWN, // ASTC_5x4_UNORM
DXGI_FORMAT_UNKNOWN, // ASTC_5x5_UNORM
DXGI_FORMAT_UNKNOWN, // ASTC_6x5_UNORM
DXGI_FORMAT_UNKNOWN, // ASTC_6x6_UNORM
DXGI_FORMAT_UNKNOWN, // ASTC_8x5_UNORM
DXGI_FORMAT_UNKNOWN, // ASTC_8x6_UNORM
DXGI_FORMAT_UNKNOWN, // ASTC_8x8_UNORM
DXGI_FORMAT_UNKNOWN, // ASTC_10x5_UNORM
DXGI_FORMAT_UNKNOWN, // ASTC_10x6_UNORM
DXGI_FORMAT_UNKNOWN, // ASTC_10x8_UNORM
DXGI_FORMAT_UNKNOWN, // ASTC_10x10_UNORM
DXGI_FORMAT_UNKNOWN, // ASTC_12x10_UNORM
DXGI_FORMAT_UNKNOWN, // ASTC_12x12_UNORM
DXGI_FORMAT_UNKNOWN, // ASTC_4x4_UNORM_SRGB
DXGI_FORMAT_UNKNOWN, // ASTC_5x4_UNORM_SRGB
DXGI_FORMAT_UNKNOWN, // ASTC_5x5_UNORM_SRGB
DXGI_FORMAT_UNKNOWN, // ASTC_6x5_UNORM_SRGB
DXGI_FORMAT_UNKNOWN, // ASTC_6x6_UNORM_SRGB
DXGI_FORMAT_UNKNOWN, // ASTC_8x5_UNORM_SRGB
DXGI_FORMAT_UNKNOWN, // ASTC_8x6_UNORM_SRGB
DXGI_FORMAT_UNKNOWN, // ASTC_8x8_UNORM_SRGB
DXGI_FORMAT_UNKNOWN, // ASTC_10x5_UNORM_SRGB
DXGI_FORMAT_UNKNOWN, // ASTC_10x6_UNORM_SRGB
DXGI_FORMAT_UNKNOWN, // ASTC_10x8_UNORM_SRGB
DXGI_FORMAT_UNKNOWN, // ASTC_10x10_UNORM_SRGB
DXGI_FORMAT_UNKNOWN, // ASTC_12x10_UNORM_SRGB
DXGI_FORMAT_UNKNOWN, // ASTC_12x12_UNORM_SRGB
DXGI_FORMAT_UNKNOWN, // ASTC_4x4_FLOAT
DXGI_FORMAT_UNKNOWN, // ASTC_5x4_FLOAT
DXGI_FORMAT_UNKNOWN, // ASTC_5x5_FLOAT
DXGI_FORMAT_UNKNOWN, // ASTC_6x5_FLOAT
DXGI_FORMAT_UNKNOWN, // ASTC_6x6_FLOAT
DXGI_FORMAT_UNKNOWN, // ASTC_8x5_FLOAT
DXGI_FORMAT_UNKNOWN, // ASTC_8x6_FLOAT
DXGI_FORMAT_UNKNOWN, // ASTC_8x8_FLOAT
DXGI_FORMAT_UNKNOWN, // ASTC_10x5_FLOAT
DXGI_FORMAT_UNKNOWN, // ASTC_10x6_FLOAT
DXGI_FORMAT_UNKNOWN, // ASTC_10x8_FLOAT
DXGI_FORMAT_UNKNOWN, // ASTC_10x10_FLOAT
DXGI_FORMAT_UNKNOWN, // ASTC_12x10_FLOAT
DXGI_FORMAT_UNKNOWN, // ASTC_12x12_FLOAT
};
static_assert(sizeof(JulietToD3D12_DepthFormat) / sizeof(JulietToD3D12_DepthFormat[0]) == ToUnderlying(TextureFormat::Count));
uint32 ComputeSubresourceIndex(uint32 mipLevel, uint32 layer, uint32 numLevels) uint32 ComputeSubresourceIndex(uint32 mipLevel, uint32 layer, uint32 numLevels)
{ {
@@ -165,7 +276,7 @@ namespace Juliet::D3D12
D3D12_RESOURCE_STATES newTextureUsage) D3D12_RESOURCE_STATES newTextureUsage)
{ {
D3D12TextureSubresource* subresource = Internal::FetchTextureSubresource(container, layer, level); D3D12TextureSubresource* subresource = Internal::FetchTextureSubresource(container, layer, level);
if (shouldCycle and container->CanBeCycled and subresource->Parent->RefCount > 0) if (shouldCycle and container->CanBeCycled and subresource->Parent->ReferenceCount > 0)
{ {
// TODO: Cycle the active texture to an available one. Not needed for swap chain (current objective) // TODO: Cycle the active texture to an available one. Not needed for swap chain (current objective)
// CycleActiveTexture(commandList->Driver, container); // CycleActiveTexture(commandList->Driver, container);
@@ -236,5 +347,17 @@ namespace Juliet::D3D12
{ {
return JulietToD3D12_TextureFormat[ToUnderlying(format)]; return JulietToD3D12_TextureFormat[ToUnderlying(format)];
} }
DXGI_FORMAT ConvertToD3D12DepthFormat(TextureFormat format)
{
return JulietToD3D12_DepthFormat[ToUnderlying(format)];
}
uint32 JulietToD3D12_SampleCount[] = {
1, // MSAA 1x
2, // MSAA 2x
4, // MSAA 4x
8, // MSAA 8x
};
} // namespace Internal } // namespace Internal
} // namespace Juliet::D3D12 } // namespace Juliet::D3D12

View File

@@ -1,7 +1,7 @@
#pragma once #pragma once
#include <Graphics/D3D12/D3D12Common.h> #include <Graphics/D3D12/D3D12Common.h>
#include <Graphics/D3D12/DX12Includes.h> #include <Graphics/D3D12/D3D12Includes.h>
#include <Graphics/GraphicsDevice.h> #include <Graphics/GraphicsDevice.h>
struct ID3D12Resource; struct ID3D12Resource;
@@ -59,7 +59,7 @@ namespace Juliet::D3D12
D3D12StagingDescriptor SRVHandle; D3D12StagingDescriptor SRVHandle;
// TODO: Should be atomic to support multithreading // TODO: Should be atomic to support multithreading
int32 RefCount; int32 ReferenceCount;
}; };
namespace Internal namespace Internal
@@ -88,5 +88,7 @@ namespace Juliet::D3D12
// Utils // Utils
extern DXGI_FORMAT ConvertToD3D12TextureFormat(TextureFormat format); extern DXGI_FORMAT ConvertToD3D12TextureFormat(TextureFormat format);
extern DXGI_FORMAT ConvertToD3D12DepthFormat(TextureFormat format);
extern uint32 JulietToD3D12_SampleCount[];
} // namespace Internal } // namespace Internal
} // namespace Juliet::D3D12 } // namespace Juliet::D3D12

View File

@@ -1,8 +1,8 @@
#include <pch.h> #include <pch.h>
#include <Core/Common/NonNullPtr.h> #include <Core/Common/NonNullPtr.h>
#include <DX12GraphicsDevice.h> #include <D3D12GraphicsDevice.h>
#include <Graphics/D3D12/DX12Utils.h> #include <Graphics/D3D12/D3D12Utils.h>
#include <algorithm> #include <algorithm>
@@ -10,7 +10,7 @@ namespace Juliet::D3D12
{ {
// From SDLGPU // From SDLGPU
// TODO Do my own version. // TODO Do my own version.
extern void LogError(NonNullPtr<D3D12Driver> driver, const char* errorMessage, HRESULT result) extern void LogError(NonNullPtr<ID3D12Device5> D3D12Device, const char* errorMessage, HRESULT result)
{ {
#define MAX_ERROR_LEN 1024 // FIXME: Arbitrary! #define MAX_ERROR_LEN 1024 // FIXME: Arbitrary!
@@ -20,10 +20,7 @@ namespace Juliet::D3D12
if (result == DXGI_ERROR_DEVICE_REMOVED) if (result == DXGI_ERROR_DEVICE_REMOVED)
{ {
if (driver->D3D12Device) result = ID3D12Device_GetDeviceRemovedReason(D3D12Device);
{
result = ID3D12Device_GetDeviceRemovedReason(driver->D3D12Device);
}
} }
// Try to get the message from the system errors. // Try to get the message from the system errors.

View File

@@ -1,6 +1,6 @@
#pragma once #pragma once
#include <Graphics/D3D12/DX12Includes.h> #include <Graphics/D3D12/D3D12Includes.h>
#ifdef _WIN32 #ifdef _WIN32
#define HRESULT_FMT "(0x%08lX)" #define HRESULT_FMT "(0x%08lX)"
@@ -25,5 +25,5 @@ namespace Juliet::D3D12
} }
} }
extern void LogError(NonNullPtr<D3D12Driver> driver, const char* errorMessage, HRESULT result); extern void LogError(NonNullPtr<ID3D12Device5> D3D12Device, const char* errorMessage, HRESULT result);
} // namespace Juliet::D3D12 } // namespace Juliet::D3D12

View File

@@ -1,6 +1,7 @@
#include <DX12CommandList.h>
#include <pch.h> #include <pch.h>
#include <Core/HAL/Filesystem/Filesystem.h>
#include <Core/HAL/IO/IOStream.h>
#include <Graphics/Graphics.h> #include <Graphics/Graphics.h>
#include <Graphics/GraphicsDevice.h> #include <Graphics/GraphicsDevice.h>
@@ -33,6 +34,11 @@ namespace Juliet
// If not preferred renderer was set, use the first one that works in the list // If not preferred renderer was set, use the first one that works in the list
for (GraphicsDeviceFactory* factory : Factories) for (GraphicsDeviceFactory* factory : Factories)
{ {
if (factory->Type == config.PreferredDriver)
{
continue;
}
// TODO : Make sure it's supported by querying it first. If supported -> Lets go // TODO : Make sure it's supported by querying it first. If supported -> Lets go
if (factory->CheckDriver()) if (factory->CheckDriver())
{ {
@@ -47,12 +53,13 @@ namespace Juliet
GraphicsDevice* CreateGraphicsDevice(GraphicsConfig config) GraphicsDevice* CreateGraphicsDevice(GraphicsConfig config)
{ {
GraphicsDeviceFactory* chosenFactory = ChooseFactory(config); if (GraphicsDeviceFactory* chosenFactory = ChooseFactory(config))
if (chosenFactory)
{ {
GraphicsDevice* newDevice = chosenFactory->CreateGraphicsDevice(); if (GraphicsDevice* newDevice = chosenFactory->CreateGraphicsDevice(config.EnableDebug))
newDevice->Name = chosenFactory->Name; {
return newDevice; newDevice->Name = chosenFactory->Name;
return newDevice;
}
} }
return nullptr; return nullptr;
} }
@@ -78,6 +85,27 @@ namespace Juliet
{ {
auto header = reinterpret_cast<CommandListHeader*>(commandList.Get()); auto header = reinterpret_cast<CommandListHeader*>(commandList.Get());
if (header->Device->DebugEnabled)
{
bool error = false;
if (header->Submitted)
{
error = true;
Assert(false && "Cannot submit command list twice");
}
if (header->RenderPass.IsInProgress)
{
error = true;
Assert(false && "Cannot submit command list twice");
}
if (error)
{
return false;
}
}
header->Device->AcquireSwapChainTexture(commandList, window, swapChainTexture); header->Device->AcquireSwapChainTexture(commandList, window, swapChainTexture);
if (swapChainTexture) if (swapChainTexture)
{ {
@@ -87,6 +115,50 @@ namespace Juliet
return true; return true;
} }
bool WaitAndAcquireSwapChainTexture(NonNullPtr<CommandList> commandList, NonNullPtr<Window> window, Texture** swapChainTexture)
{
auto header = reinterpret_cast<CommandListHeader*>(commandList.Get());
if (header->Device->DebugEnabled)
{
bool error = false;
if (header->Submitted)
{
error = true;
Assert(false && "Cannot submit command list twice");
}
if (header->RenderPass.IsInProgress)
{
error = true;
Assert(false && "Cannot submit command list twice");
}
if (error)
{
return false;
}
}
header->Device->WaitAndAcquireSwapChainTexture(commandList, window, swapChainTexture);
if (swapChainTexture)
{
header->AcquiredSwapChain = true;
}
return true;
}
bool WaitForSwapchain(NonNullPtr<GraphicsDevice> device, NonNullPtr<Window> window)
{
return device->WaitForSwapchain(device->Driver, window);
}
TextureFormat GetSwapChainTextureFormat(NonNullPtr<GraphicsDevice> device, NonNullPtr<Window> window)
{
return device->GetSwapChainTextureFormat(device->Driver, window);
}
CommandList* AcquireCommandList(NonNullPtr<GraphicsDevice> device, QueueType queueType /* = QueueType::Graphics */) CommandList* AcquireCommandList(NonNullPtr<GraphicsDevice> device, QueueType queueType /* = QueueType::Graphics */)
{ {
GPUDriver* driver = device->Driver; GPUDriver* driver = device->Driver;
@@ -99,6 +171,7 @@ namespace Juliet
auto header = reinterpret_cast<CommandListHeader*>(cmdList); auto header = reinterpret_cast<CommandListHeader*>(cmdList);
header->Device = device.Get(); header->Device = device.Get();
header->RenderPass.CommandList = cmdList; header->RenderPass.CommandList = cmdList;
header->Submitted = false;
return cmdList; return cmdList;
} }
@@ -175,4 +248,80 @@ namespace Juliet
commandListHeader->Device->SetStencilReference(commandList, reference); commandListHeader->Device->SetStencilReference(commandList, reference);
} }
void BindGraphicsPipeline(NonNullPtr<RenderPass> renderPass, NonNullPtr<GraphicsPipeline> graphicsPipeline)
{
auto* commandList = reinterpret_cast<GPUPass*>(renderPass.Get())->CommandList;
auto* commandListHeader = reinterpret_cast<CommandListHeader*>(commandList);
commandListHeader->Device->BindGraphicsPipeline(commandList, graphicsPipeline);
}
void DrawPrimitives(NonNullPtr<RenderPass> renderPass, uint32 numVertices, uint32 numInstances, uint32 firstVertex, uint32 firstInstance)
{
auto* commandList = reinterpret_cast<GPUPass*>(renderPass.Get())->CommandList;
auto* commandListHeader = reinterpret_cast<CommandListHeader*>(commandList);
commandListHeader->Device->DrawPrimitives(commandList, numVertices, numInstances, firstVertex, firstInstance);
}
// Fences
bool WaitUntilGPUIsIdle(NonNullPtr<GraphicsDevice> device)
{
return device->WaitUntilGPUIsIdle(device->Driver);
}
// Shaders
Shader* CreateShader(NonNullPtr<GraphicsDevice> device, String filename, ShaderCreateInfo& shaderCreateInfo)
{
ByteBuffer shaderByteCode = {};
// Create path from filename
if (IsAbsolutePath(filename))
{
shaderByteCode = LoadFile(filename);
}
else
{
// TODO: Add path builder in the lib
String base = GetBasePath();
char inplaceBuffer[256];
snprintf(inplaceBuffer, sizeof(inplaceBuffer), "%s%s", base.Data, filename.Data);
String absolutePath = WrapString(inplaceBuffer);
shaderByteCode = LoadFile(absolutePath);
}
if (!IsValid(shaderByteCode))
{
return nullptr;
}
Shader* shader = device->CreateShader(device->Driver, shaderByteCode, shaderCreateInfo);
Free(shaderByteCode);
return shader;
}
void DestroyShader(NonNullPtr<GraphicsDevice> device, NonNullPtr<Shader> shader)
{
device->DestroyShader(device->Driver, shader);
}
GraphicsPipeline* CreateGraphicsPipeline(NonNullPtr<GraphicsDevice> device, const GraphicsPipelineCreateInfo& createInfo)
{
return device->CreateGraphicsPipeline(device->Driver, createInfo);
}
void DestroyGraphicsPipeline(NonNullPtr<GraphicsDevice> device, NonNullPtr<GraphicsPipeline> graphicsPipeline)
{
device->DestroyGraphicsPipeline(device->Driver, graphicsPipeline);
}
#if ALLOW_SHADER_HOT_RELOAD
bool UpdateGraphicsPipelineShaders(NonNullPtr<GraphicsDevice> device, NonNullPtr<GraphicsPipeline> graphicsPipeline,
Shader* optional_vertexShader, Shader* optional_fragmentShader)
{
return device->UpdateGraphicsPipelineShaders(device->Driver, graphicsPipeline, optional_vertexShader, optional_fragmentShader);
}
#endif
} // namespace Juliet } // namespace Juliet

View File

@@ -3,6 +3,7 @@
#include <Core/Common/NonNullPtr.h> #include <Core/Common/NonNullPtr.h>
#include <Graphics/Graphics.h> #include <Graphics/Graphics.h>
#include <Graphics/GraphicsConfig.h> #include <Graphics/GraphicsConfig.h>
#include <Graphics/GraphicsPipeline.h>
#include <Graphics/Texture.h> #include <Graphics/Texture.h>
namespace Juliet namespace Juliet
@@ -29,9 +30,13 @@ namespace Juliet
struct GPUDriver struct GPUDriver
{ {
static constexpr uint8 kResourceBufferCount = 2; static constexpr uint8 kMaxFramesInFlight = 3;
static constexpr uint8 kMaxFramesInFlight = 3; static constexpr uint8 kMaxColorTargetInfo = 4;
static constexpr uint8 kMaxColorTargetInfo = 4; static constexpr uint8 kMaxUniformBuffersPerStage = 4;
static constexpr uint8 kMaxVertexBuffers = 16;
static constexpr uint32 kCBV_SRV_UAV_HeapDescriptorCount = 65536;
static constexpr uint32 kSampler_HeapDescriptorCount = 2048;
}; };
struct GraphicsDevice struct GraphicsDevice
@@ -44,6 +49,9 @@ namespace Juliet
// SwapChain // SwapChain
bool (*AcquireSwapChainTexture)(NonNullPtr<CommandList> commandList, NonNullPtr<Window> window, Texture** swapChainTexture); bool (*AcquireSwapChainTexture)(NonNullPtr<CommandList> commandList, NonNullPtr<Window> window, Texture** swapChainTexture);
bool (*WaitAndAcquireSwapChainTexture)(NonNullPtr<CommandList> commandList, NonNullPtr<Window> window, Texture** swapChainTexture);
bool (*WaitForSwapchain)(NonNullPtr<GPUDriver> driver, NonNullPtr<Window> window);
TextureFormat (*GetSwapChainTextureFormat)(NonNullPtr<GPUDriver> driver, NonNullPtr<Window> window);
// CommandLists // CommandLists
CommandList* (*AcquireCommandList)(NonNullPtr<GPUDriver> driver, QueueType queueType); CommandList* (*AcquireCommandList)(NonNullPtr<GPUDriver> driver, QueueType queueType);
@@ -59,13 +67,28 @@ namespace Juliet
void (*SetBlendConstants)(NonNullPtr<CommandList> commandList, FColor blendConstants); void (*SetBlendConstants)(NonNullPtr<CommandList> commandList, FColor blendConstants);
void (*SetStencilReference)(NonNullPtr<CommandList> commandList, uint8 reference); void (*SetStencilReference)(NonNullPtr<CommandList> commandList, uint8 reference);
void (*BindGraphicsPipeline)(NonNullPtr<CommandList> commandList, NonNullPtr<GraphicsPipeline> graphicsPipeline);
void (*DrawPrimitives)(NonNullPtr<CommandList> commandList, uint32 numVertices, uint32 numInstances,
uint32 firstVertex, uint32 firstInstance);
// Fences // Fences
bool (*Wait)(NonNullPtr<GPUDriver> driver); bool (*WaitUntilGPUIsIdle)(NonNullPtr<GPUDriver> driver);
bool (*QueryFence)(NonNullPtr<GPUDriver> driver, NonNullPtr<Fence> fence); bool (*QueryFence)(NonNullPtr<GPUDriver> driver, NonNullPtr<Fence> fence);
void (*ReleaseFence)(NonNullPtr<GPUDriver> driver, NonNullPtr<Fence> fence); void (*ReleaseFence)(NonNullPtr<GPUDriver> driver, NonNullPtr<Fence> fence);
// Shaders
Shader* (*CreateShader)(NonNullPtr<GPUDriver> driver, ByteBuffer shaderByteCode, ShaderCreateInfo& shaderCreateInfo);
void (*DestroyShader)(NonNullPtr<GPUDriver> driver, NonNullPtr<Shader> shader);
// Pipeline
GraphicsPipeline* (*CreateGraphicsPipeline)(NonNullPtr<GPUDriver> driver, const GraphicsPipelineCreateInfo& createInfo);
void (*DestroyGraphicsPipeline)(NonNullPtr<GPUDriver> driver, NonNullPtr<GraphicsPipeline> pipeline);
bool (*UpdateGraphicsPipelineShaders)(NonNullPtr<GPUDriver> driver, NonNullPtr<GraphicsPipeline> graphicsPipeline,
Shader* optional_vertexShader, Shader* optional_fragmentShader);
const char* Name = "Unknown"; const char* Name = "Unknown";
GPUDriver* Driver = nullptr; GPUDriver* Driver = nullptr;
bool DebugEnabled : 1;
}; };
struct GraphicsDeviceFactory struct GraphicsDeviceFactory
@@ -73,7 +96,7 @@ namespace Juliet
const char* Name = "Unknown"; const char* Name = "Unknown";
DriverType Type = DriverType::Any; DriverType Type = DriverType::Any;
bool (*CheckDriver)(void); bool (*CheckDriver)(void);
GraphicsDevice* (*CreateGraphicsDevice)(void); GraphicsDevice* (*CreateGraphicsDevice)(bool enableDebug);
}; };
extern GraphicsDeviceFactory DX12DeviceFactory; extern GraphicsDeviceFactory DX12DeviceFactory;

View File

@@ -1,3 +1,5 @@
Rename DX12 files to D3D12 - Create Simple vector class to make the vector stuff a bit more easier than writing Capacity and Count
- Make a string struct instead of StringBuffer.
- Support wchar and char (template is ok) conversions, printf, compare, etc.
- Create Simple vector class to make the vector stuff a bit more easier than writing Capacity and Count - Create a post build bat script to copy stuff i need in the correct folders

3
JulietApp/JulietApp.def Normal file
View File

@@ -0,0 +1,3 @@
EXPORTS
D3D12SDKVersion=Juliet.D3D12SDKVersion
D3D12SDKPath=Juliet.D3D12SDKPath

View File

@@ -12,8 +12,8 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Game\Game.vcxproj"> <ProjectReference Include="..\Game\Game.vcxproj">
<Project>{b7b12dcc-1a69-4371-a9fe-d6e7671497b0}</Project> <Project>{b7b12dcc-1a69-4371-a9fe-d6e7671497b0}</Project>
<Name>Game</Name> <Name>Game</Name>
</ProjectReference> </ProjectReference>
<ProjectReference Include="..\Juliet\Juliet.vcxproj"> <ProjectReference Include="..\Juliet\Juliet.vcxproj">
<Project>{1bbc0b92-e4d8-4838-974b-439c5c501e82}</Project> <Project>{1bbc0b92-e4d8-4838-974b-439c5c501e82}</Project>
@@ -79,6 +79,9 @@
<AdditionalOptions>--target=amd64-pc-windows-msvc</AdditionalOptions> <AdditionalOptions>--target=amd64-pc-windows-msvc</AdditionalOptions>
</ClCompile> </ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup>
<Content Include="JulietApp.def" />
</ItemGroup>
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
<VCProjectVersion>17.0</VCProjectVersion> <VCProjectVersion>17.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword> <Keyword>Win32Proj</Keyword>
@@ -137,10 +140,15 @@
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>Juliet.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>Juliet.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)\lib\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>$(SolutionDir)\lib\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
<ModuleDefinitionFile>JulietApp.def</ModuleDefinitionFile>
</Link> </Link>
<PreBuildEvent> <PreBuildEvent>
<Command></Command> <Command></Command>
</PreBuildEvent> </PreBuildEvent>
<PostBuildEvent>
<Command>xcopy /y "$(SolutionDir)\Juliet\src\Graphics\D3D12\AgilitySDK\bin\*.*" "$(SolutionDir)\bin\$(Platform)\$(Configuration)\D3D12\*.*"</Command>
<Message>Copy DX12 Agility SDK Binaries</Message>
</PostBuildEvent>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile> <ClCompile>
@@ -163,6 +171,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>Juliet.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>Juliet.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)\lib\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>$(SolutionDir)\lib\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
<ModuleDefinitionFile>JulietApp.def</ModuleDefinitionFile>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>

View File

@@ -1,8 +1,8 @@
#include <main.h> #include <main.h>
#include <Core/Application/ApplicationManager.h> #include <Core/Application/ApplicationManager.h>
#include <Core/Common/EnumUtils.h>
#include <Core/HAL/Display/Display.h> #include <Core/HAL/Display/Display.h>
#include <Core/HAL/DynLib/DynamicLibrary.h>
#include <Core/HAL/Event/SystemEvent.h> #include <Core/HAL/Event/SystemEvent.h>
#include <Core/HAL/Filesystem/Filesystem.h> #include <Core/HAL/Filesystem/Filesystem.h>
#include <Core/JulietInit.h> #include <Core/JulietInit.h>
@@ -10,9 +10,10 @@
#include <Core/Logging/LogTypes.h> #include <Core/Logging/LogTypes.h>
#include <Graphics/Graphics.h> #include <Graphics/Graphics.h>
#include <Graphics/GraphicsConfig.h> #include <Graphics/GraphicsConfig.h>
#include <Graphics/GraphicsPipeline.h>
#include <Graphics/RenderPass.h> #include <Graphics/RenderPass.h>
#include <Windows.h>
#include <Core/Common/String.h>
#include <Core/Memory/Utils.h> #include <Core/Memory/Utils.h>
#include <cstdlib> #include <cstdlib>
@@ -44,11 +45,14 @@ namespace
void JulietApplication::Init() void JulietApplication::Init()
{ {
Log(LogLevel::Message, LogCategory::Editor, "Initializing Juliet Application..."); Log(LogLevel::Message, LogCategory::Tool, "Initializing Juliet Application...");
Log(LogLevel::Message, LogCategory::Editor, "%s", GetBasePath()); Log(LogLevel::Message, LogCategory::Tool, "%s", CStr(GetBasePath()));
GraphicsConfig config; GraphicsConfig config;
#if JULIET_DEBUG
config.EnableDebug = true;
#endif
GraphicsDevice = CreateGraphicsDevice(config); GraphicsDevice = CreateGraphicsDevice(config);
MainWindow = CreatePlatformWindow("Juliet Editor", 1280, 720); MainWindow = CreatePlatformWindow("Juliet Editor", 1280, 720);
@@ -58,12 +62,61 @@ void JulietApplication::Init()
if (Running) if (Running)
{ {
AttachToWindow(GraphicsDevice, MainWindow); AttachToWindow(GraphicsDevice, MainWindow);
// Game = LoadDynamicLibrary("Game.dll");
{
// Create graphics pipeline
String entryPoint = WrapString("main");
ShaderCreateInfo shaderCI = {};
shaderCI.EntryPoint = entryPoint;
// TODO: Assets management that handles path to assets or something.
String shaderPath = WrapString("../../../Assets/compiled/Triangle.vert.dxil");
shaderCI.Stage = ShaderStage::Vertex;
Shader* vertexShader = CreateShader(GraphicsDevice, shaderPath, shaderCI);
shaderPath = WrapString("../../../Assets/compiled/SolidColor.frag.dxil");
shaderCI.Stage = ShaderStage::Fragment;
Shader* fragmentShader = CreateShader(GraphicsDevice, shaderPath, shaderCI);
ColorTargetDescription colorTargetDescription = {};
colorTargetDescription.Format = GetSwapChainTextureFormat(GraphicsDevice, MainWindow);
GraphicsPipelineCreateInfo pipelineCI = {};
pipelineCI.VertexShader = vertexShader;
pipelineCI.FragmentShader = fragmentShader;
pipelineCI.PrimitiveType = PrimitiveType::TriangleList;
pipelineCI.TargetInfo = { .ColorTargetDescriptions = &colorTargetDescription,
.NumColorTargets = 1,
.DepthStencilFormat = {},
.HasDepthStencilTarget = false };
pipelineCI.RasterizerState.FillMode = FillMode::Solid;
GraphicsPipeline = CreateGraphicsPipeline(GraphicsDevice, pipelineCI);
if (GraphicsPipeline == nullptr)
{
LogError(LogCategory::Game, "Failed to create graphics pipeline!");
Running = false;
}
if (vertexShader)
{
DestroyShader(GraphicsDevice, vertexShader);
}
if (fragmentShader)
{
DestroyShader(GraphicsDevice, fragmentShader);
}
if (Running == false)
{
return;
}
}
GameCode.Functions = reinterpret_cast<void**>(&Game); GameCode.Functions = reinterpret_cast<void**>(&Game);
GameCode.FunctionCount = ArraySize(GameFunctionTable); GameCode.FunctionCount = ArraySize(GameFunctionTable);
GameCode.FunctionNames = GameFunctionTable; GameCode.FunctionNames = GameFunctionTable;
InitHotReloadCode(GameCode, StringBufferParam("Game.dll"), StringBufferParam("Game_Temp.dll"), StringBufferParam("lock.tmp")); InitHotReloadCode(GameCode, ConstString("Game.dll"), ConstString("Game_Temp.dll"), ConstString("lock.tmp"));
if ((Running = GameCode.IsValid)) if ((Running = GameCode.IsValid))
{ {
Game.Init(); Game.Init();
@@ -73,10 +126,18 @@ void JulietApplication::Init()
void JulietApplication::Shutdown() void JulietApplication::Shutdown()
{ {
Log(LogLevel::Message, LogCategory::Editor, "Shutting down Juliet Application..."); Log(LogLevel::Message, LogCategory::Tool, "Shutting down Juliet Application...");
Game.Shutdown(); if (GameCode.IsValid)
ShutdownHotReloadCode(GameCode); {
Game.Shutdown();
ShutdownHotReloadCode(GameCode);
}
if (GraphicsPipeline)
{
DestroyGraphicsPipeline(GraphicsDevice, GraphicsPipeline);
}
if (MainWindow && GraphicsDevice) if (MainWindow && GraphicsDevice)
{ {
@@ -93,11 +154,14 @@ void JulietApplication::Shutdown()
DestroyGraphicsDevice(GraphicsDevice); DestroyGraphicsDevice(GraphicsDevice);
} }
Log(LogLevel::Message, LogCategory::Editor, "Juliet App shutdown Completed"); Log(LogLevel::Message, LogCategory::Tool, "Juliet App shutdown Completed");
} }
void JulietApplication::Update() void JulietApplication::Update()
{ {
bool reloadShaders = false;
static bool reloadShadersDebounce = false;
SystemEvent evt; SystemEvent evt;
while (GetEvent(evt)) while (GetEvent(evt))
{ {
@@ -108,6 +172,23 @@ void JulietApplication::Update()
Running = false; Running = false;
} }
} }
if (evt.Type == EventType::Key_Down)
{
}
// Shader hot reload using keyboard.
// TODO: Add Input debounce in the library. (Just pressed vs pressed)
if (!reloadShadersDebounce && ((GetKeyModState() & KeyMod::Alt) != KeyMod::None) && IsKeyDown(ScanCode::R))
{
reloadShaders = true;
reloadShadersDebounce = true;
}
if (reloadShadersDebounce && !IsKeyDown(ScanCode::R))
{
reloadShadersDebounce = false;
}
} }
Game.Update(0.0f); Game.Update(0.0f);
@@ -117,20 +198,50 @@ void JulietApplication::Update()
ReloadCode(GameCode); ReloadCode(GameCode);
} }
if (reloadShaders)
{
// We need to wait for the gpu to be idle to recreate our graphics pipelines
WaitUntilGPUIsIdle(GraphicsDevice);
#if ALLOW_SHADER_HOT_RELOAD
String entryPoint = WrapString("main");
ShaderCreateInfo shaderCI = {};
shaderCI.EntryPoint = entryPoint;
String shaderPath = WrapString("../../../Assets/compiled/Triangle.vert.dxil");
shaderCI.Stage = ShaderStage::Vertex;
Shader* vertexShader = CreateShader(GraphicsDevice, shaderPath, shaderCI);
shaderPath = WrapString("../../../Assets/compiled/SolidColor.frag.dxil");
shaderCI.Stage = ShaderStage::Fragment;
Shader* fragmentShader = CreateShader(GraphicsDevice, shaderPath, shaderCI);
UpdateGraphicsPipelineShaders(GraphicsDevice, GraphicsPipeline, vertexShader, fragmentShader);
if (vertexShader)
{
DestroyShader(GraphicsDevice, vertexShader);
}
if (fragmentShader)
{
DestroyShader(GraphicsDevice, fragmentShader);
}
#endif
}
// Draw here for now // Draw here for now
// 1) Acquire a Command Buffer // 1) Acquire a Command Buffer
CommandList* cmdList = AcquireCommandList(GraphicsDevice, QueueType::Graphics); CommandList* cmdList = AcquireCommandList(GraphicsDevice, QueueType::Graphics);
if (cmdList == nullptr) if (cmdList == nullptr)
{ {
Log(LogLevel::Error, LogCategory::Editor, "Failed to acquire command list."); Log(LogLevel::Error, LogCategory::Tool, "Failed to acquire command list.");
Running = false; Running = false;
return; return;
} }
Texture* swapChainTexture = nullptr; Texture* swapChainTexture = nullptr;
if (!AcquireSwapChainTexture(cmdList, MainWindow, &swapChainTexture)) if (!WaitAndAcquireSwapChainTexture(cmdList, MainWindow, &swapChainTexture))
{ {
Log(LogLevel::Error, LogCategory::Editor, "Failed to acquire swapchain texture."); Log(LogLevel::Error, LogCategory::Tool, "Failed to acquire swapchain texture.");
Running = false; Running = false;
return; return;
} }
@@ -144,6 +255,8 @@ void JulietApplication::Update()
colorTargetInfo.StoreOperation = StoreOperation::Store; colorTargetInfo.StoreOperation = StoreOperation::Store;
RenderPass* renderPass = BeginRenderPass(cmdList, colorTargetInfo); RenderPass* renderPass = BeginRenderPass(cmdList, colorTargetInfo);
BindGraphicsPipeline(renderPass, GraphicsPipeline);
DrawPrimitives(renderPass, 3, 1, 0, 0);
EndRenderPass(renderPass); EndRenderPass(renderPass);
} }
@@ -168,12 +281,14 @@ JulietApplication& GetEditorApplication()
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
CreateMutex(0, false, L"Local\\Juliet.App"); // Allow only one instance to be launched.
if (GetLastError() == ERROR_ALREADY_EXISTS) // Need to create Mutex code in the lib because i dont want to include windows.h in this file anymore
{ // CreateMutex(0, false, L"Local\\Juliet.App");
MessageBox(nullptr, L"An instance of Juliet is already running.", L"Juliet", MB_OK | MB_ICONEXCLAMATION); // if (GetLastError() == ERROR_ALREADY_EXISTS)
return EXIT_FAILURE; // {
} // MessageBox(nullptr, L"An instance of Juliet is already running.", L"Juliet", MB_OK | MB_ICONEXCLAMATION);
// return EXIT_FAILURE;
// }
StartApplication(EditorApplication, JulietInit_Flags::Display); StartApplication(EditorApplication, JulietInit_Flags::Display);

View File

@@ -4,6 +4,7 @@
#include <Core/HAL/Display/Display.h> #include <Core/HAL/Display/Display.h>
#include <Core/HAL/DynLib/DynamicLibrary.h> #include <Core/HAL/DynLib/DynamicLibrary.h>
#include <Core/HotReload/HotReload.h> #include <Core/HotReload/HotReload.h>
#include <Graphics/GraphicsPipeline.h>
namespace Juliet namespace Juliet
{ {
@@ -20,9 +21,10 @@ class JulietApplication : public Juliet::IApplication
bool IsRunning() override; bool IsRunning() override;
private: private:
Juliet::Window* MainWindow = {}; Juliet::Window* MainWindow = {};
Juliet::GraphicsDevice* GraphicsDevice = {}; Juliet::GraphicsDevice* GraphicsDevice = {};
Juliet::HotReloadCode GameCode = {}; Juliet::HotReloadCode GameCode = {};
Juliet::GraphicsPipeline* GraphicsPipeline = {};
bool Running = false; bool Running = false;
}; };

Some files were not shown because too many files have changed in this diff Show More