Graphics pipeline iteration
Lot of code. Not working yet
This commit is contained in:
@@ -129,6 +129,7 @@
|
||||
<ClInclude Include="include\Core\JulietInit.h"/>
|
||||
<ClInclude Include="include\Core\Logging\LogManager.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\Memory\Allocator.h"/>
|
||||
<ClInclude Include="include\Core\Memory\Utils.h"/>
|
||||
@@ -163,6 +164,7 @@
|
||||
<ClInclude Include="src\Core\HAL\Filesystem\Filesystem_Platform.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\HAL\Win32.h"/>
|
||||
<ClInclude Include="src\Graphics\D3D12\D3D12Common.h"/>
|
||||
@@ -200,19 +202,20 @@
|
||||
<ClCompile Include="src\Core\HotReload\Win32\Win32HotReload.cpp"/>
|
||||
<ClCompile Include="src\Core\Juliet.cpp"/>
|
||||
<ClCompile Include="src\Core\Logging\LogManager.cpp"/>
|
||||
<ClCompile Include="src\Core\Memory\Allocator.cpp"/>
|
||||
<ClCompile Include="src\Core\Networking\NetworkPacket.cpp"/>
|
||||
<ClCompile Include="src\Core\Networking\Socket.cpp"/>
|
||||
<ClCompile Include="src\Core\Networking\TcpListener.cpp"/>
|
||||
<ClCompile Include="src\Core\Networking\TcpSocket.cpp"/>
|
||||
<ClCompile Include="src\Core\Networking\Win32\Win32SocketPlatformImpl.cpp"/>
|
||||
<ClCompile Include="src\Engine\Engine.cpp"/>
|
||||
<ClCompile Include="src\Graphics\D3D12\D3D12Common.cpp"/>
|
||||
<ClCompile Include="src\Core\Math\MathRound.cpp" />
|
||||
<ClCompile Include="src\Core\Memory\Allocator.cpp" />
|
||||
<ClCompile Include="src\Core\Networking\NetworkPacket.cpp" />
|
||||
<ClCompile Include="src\Core\Networking\Socket.cpp" />
|
||||
<ClCompile Include="src\Core\Networking\TcpListener.cpp" />
|
||||
<ClCompile Include="src\Core\Networking\TcpSocket.cpp" />
|
||||
<ClCompile Include="src\Core\Networking\Win32\Win32SocketPlatformImpl.cpp" />
|
||||
<ClCompile Include="src\Engine\Engine.cpp" />
|
||||
<ClCompile Include="src\Graphics\D3D12\D3D12Common.cpp" />
|
||||
<ClCompile Include="src\Graphics\D3D12\D3D12GraphicsPipeline.cpp" />
|
||||
<ClCompile Include="src\Graphics\D3D12\D3D12RenderPass.cpp"/>
|
||||
<ClCompile Include="src\Graphics\D3D12\D3D12Shader.cpp"/>
|
||||
<ClCompile Include="src\Graphics\D3D12\D3D12Synchronization.cpp"/>
|
||||
<ClCompile Include="src\Graphics\D3D12\D3D12Texture.cpp"/>
|
||||
<ClCompile Include="src\Graphics\D3D12\D3D12RenderPass.cpp" />
|
||||
<ClCompile Include="src\Graphics\D3D12\D3D12Shader.cpp" />
|
||||
<ClCompile Include="src\Graphics\D3D12\D3D12Synchronization.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" />
|
||||
@@ -277,8 +280,8 @@
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="include\Core\Thread\Mutex.h"/>
|
||||
<Content Include="src\TODO.txt"/>
|
||||
<Content Include="include\Core\Thread\Mutex.h" />
|
||||
<Content Include="src\TODO.txt" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
|
||||
@@ -73,31 +73,4 @@ namespace Juliet
|
||||
}
|
||||
|
||||
extern JULIET_API void Free(ByteBuffer& buffer);
|
||||
|
||||
// TODO move to math utils
|
||||
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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <Core/Common/CoreUtils.h>
|
||||
#include <Core/Math/MathUtils.h>
|
||||
#include <Core/Memory/Utils.h>
|
||||
|
||||
namespace Juliet
|
||||
|
||||
37
Juliet/include/Core/Math/MathUtils.h
Normal file
37
Juliet/include/Core/Math/MathUtils.h
Normal file
@@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
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
|
||||
@@ -115,7 +115,7 @@ namespace Juliet
|
||||
extern JULIET_API void DestroyShader(NonNullPtr<GraphicsDevice> device, NonNullPtr<Shader> shader);
|
||||
|
||||
// Pipelines
|
||||
extern JULIET_API GraphicsPipeline* CreateGraphicsPipeline(NonNullPtr<GraphicsDevice> device,
|
||||
GraphicsPipelineCreateInfo& createInfo);
|
||||
extern JULIET_API GraphicsPipeline* CreateGraphicsPipeline(NonNullPtr<GraphicsDevice> device,
|
||||
const GraphicsPipelineCreateInfo& createInfo);
|
||||
|
||||
} // namespace Juliet
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include <Graphics/Shader.h>
|
||||
#include <Graphics/Texture.h>
|
||||
|
||||
namespace Juliet
|
||||
{
|
||||
@@ -9,20 +10,23 @@ namespace Juliet
|
||||
enum class FillMode : uint8
|
||||
{
|
||||
Wireframe,
|
||||
Solid
|
||||
Solid,
|
||||
Count
|
||||
};
|
||||
|
||||
enum class CullMode : uint8
|
||||
{
|
||||
None,
|
||||
Front,
|
||||
Back
|
||||
Back,
|
||||
Count
|
||||
};
|
||||
|
||||
enum class FrontFace : uint8
|
||||
{
|
||||
CounterClockwise,
|
||||
Clockwise
|
||||
Clockwise,
|
||||
Count
|
||||
};
|
||||
|
||||
enum class PrimitiveType : uint8
|
||||
@@ -32,6 +36,7 @@ namespace Juliet
|
||||
LineList,
|
||||
LineStrip,
|
||||
PointList,
|
||||
Count
|
||||
};
|
||||
|
||||
struct RasterizerState
|
||||
@@ -39,21 +44,180 @@ namespace Juliet
|
||||
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;
|
||||
RasterizerState RasterizerState;
|
||||
PrimitiveType PrimitiveType;
|
||||
GraphicsPipelineTargetInfo TargetInfo;
|
||||
RasterizerState RasterizerState;
|
||||
MultisampleState MultisampleState;
|
||||
VertexInputState VertexInputState;
|
||||
DepthStencilState DepthStencilState;
|
||||
};
|
||||
|
||||
// Opaque type
|
||||
|
||||
@@ -41,14 +41,60 @@ namespace Juliet
|
||||
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;
|
||||
TextureFormat Format;
|
||||
ColorTargetBlendState BlendState;
|
||||
};
|
||||
|
||||
|
||||
@@ -124,7 +124,9 @@ namespace Juliet
|
||||
ASTC_10x8_FLOAT,
|
||||
ASTC_10x10_FLOAT,
|
||||
ASTC_12x10_FLOAT,
|
||||
ASTC_12x12_FLOAT
|
||||
ASTC_12x12_FLOAT,
|
||||
|
||||
Count
|
||||
};
|
||||
|
||||
enum struct TextureUsageFlag : uint8
|
||||
|
||||
63
Juliet/src/Core/Math/MathRound.cpp
Normal file
63
Juliet/src/Core/Math/MathRound.cpp
Normal 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
|
||||
51
Juliet/src/Core/Math/Math_Private.h
Normal file
51
Juliet/src/Core/Math/Math_Private.h
Normal 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
|
||||
@@ -329,7 +329,7 @@ namespace Juliet::D3D12
|
||||
}
|
||||
}
|
||||
|
||||
// TODO Destroy anything (buffer, texture, etc...)
|
||||
Internal::DisposePendingResourcces(d3d12Driver);
|
||||
|
||||
++d3d12Driver->FrameCounter;
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
// SRV = Shader Resource View
|
||||
// UAV = Unordered Access View
|
||||
// CBV = Constant Buffer View
|
||||
// PSO = Pipeline State Object
|
||||
|
||||
// Inspired (copy pasted a lot) by SDL GPU
|
||||
namespace Juliet::D3D12
|
||||
|
||||
@@ -620,11 +620,32 @@ namespace Juliet::D3D12
|
||||
device->Driver = driver;
|
||||
driver->GraphicsDevice = device;
|
||||
|
||||
driver->Semantic = WrapString("TEXCOORD");
|
||||
|
||||
driver->FramesInFlight = 2;
|
||||
|
||||
return device;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace Internal
|
||||
{
|
||||
void DisposePendingResourcces(NonNullPtr<D3D12Driver> driver)
|
||||
{
|
||||
// TODO Destroy anything (buffer, texture, etc...)
|
||||
for (uint32 idx = driver->GraphicsPipelinesToDisposeCount - 1; idx >= 0ul; --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
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <Core/Common/EnumUtils.h>
|
||||
#include <Graphics/D3D12/D3D12Common.h>
|
||||
#include <Graphics/D3D12/D3D12GraphicsPipeline.h>
|
||||
#include <Graphics/D3D12/D3D12Texture.h>
|
||||
#include <Graphics/GraphicsDevice.h>
|
||||
|
||||
@@ -77,8 +78,14 @@ namespace Juliet::D3D12
|
||||
uint32 AvailableFenceCount;
|
||||
uint32 AvailableFenceCapacity;
|
||||
|
||||
D3D12GraphicsPipeline** GraphicsPipelinesToDispose;
|
||||
uint32 GraphicsPipelinesToDisposeCount;
|
||||
uint32 GraphicsPipelinesToDisposeCapacity;
|
||||
|
||||
D3D12StagingDescriptorPool* StagingDescriptorPools[D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES];
|
||||
|
||||
String Semantic;
|
||||
|
||||
uint8 FramesInFlight;
|
||||
uint64 FrameCounter = 0; // Number of frame since inception
|
||||
|
||||
@@ -87,4 +94,9 @@ namespace Juliet::D3D12
|
||||
bool IsUMACacheCoherent : 1;
|
||||
bool GPUUploadHeapSupported : 1;
|
||||
};
|
||||
|
||||
namespace Internal
|
||||
{
|
||||
void DisposePendingResourcces(NonNullPtr<D3D12Driver> driver);
|
||||
}
|
||||
} // namespace Juliet::D3D12
|
||||
|
||||
@@ -1,14 +1,478 @@
|
||||
#include <pch.h>
|
||||
|
||||
#include <Graphics/D3D12/D3D12GraphicsDevice.h>
|
||||
#include <Graphics/D3D12/D3D12GraphicsPipeline.h>
|
||||
#include <Graphics/D3D12/D3D12Utils.h>
|
||||
|
||||
#include <Core/Common/NonNullPtr.h>
|
||||
#include <Graphics/GraphicsDevice.h>
|
||||
#include <Core/Memory/Allocator.h>
|
||||
|
||||
namespace Juliet::D3D12
|
||||
{
|
||||
GraphicsPipeline* CreateGraphicsPipeline(NonNullPtr<GPUDriver> driver, GraphicsPipelineCreateInfo& createInfo)
|
||||
namespace
|
||||
{
|
||||
return nullptr;
|
||||
// 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;
|
||||
}
|
||||
|
||||
D3D12GraphicsRootSignature* CreateGraphicsRootSignature(NonNullPtr<D3D12Driver> renderer, NonNullPtr<D3D12Shader> vertexShader,
|
||||
NonNullPtr<D3D12Shader> fragmentShader)
|
||||
{
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void DestroyGraphicsRootSignature(NonNullPtr<D3D12GraphicsRootSignature> rootSignature)
|
||||
{
|
||||
if (!rootSignature)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (rootSignature->handle)
|
||||
{
|
||||
ID3D12RootSignature_Release(rootSignature->handle);
|
||||
}
|
||||
Free(rootSignature.Get());
|
||||
}
|
||||
} // 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;
|
||||
|
||||
D3D12_INPUT_ELEMENT_DESC inputElementDescs[D3D12_IA_VERTEX_INPUT_STRUCTURE_ELEMENT_COUNT];
|
||||
if (createInfo.VertexInputState.NumVertexAttributes > 0)
|
||||
{
|
||||
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;
|
||||
|
||||
D3D12GraphicsRootSignature* rootSignature = CreateGraphicsRootSignature(d3d12Driver, vertexShader, fragmentShader);
|
||||
|
||||
if (rootSignature == NULL)
|
||||
{
|
||||
Internal::ReleaseGraphicsPipeline(pipeline);
|
||||
return nullptr;
|
||||
}
|
||||
pipeline->RootSignature = rootSignature;
|
||||
|
||||
ID3D12PipelineState* pipelineState;
|
||||
HRESULT res = ID3D12Device_CreateGraphicsPipelineState(d3d12Driver->D3D12Device, &psoDesc, IID_ID3D12PipelineState,
|
||||
reinterpret_cast<void**>(&pipelineState));
|
||||
if (FAILED(res))
|
||||
{
|
||||
|
||||
LogError(d3d12Driver, "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;
|
||||
|
||||
return reinterpret_cast<GraphicsPipeline*>(pipeline);
|
||||
}
|
||||
|
||||
extern 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;
|
||||
}
|
||||
|
||||
namespace Internal
|
||||
{
|
||||
void ReleaseGraphicsPipeline(NonNullPtr<D3D12GraphicsPipeline> d3d12GraphicsPipeline)
|
||||
{
|
||||
if (d3d12GraphicsPipeline->PipelineState)
|
||||
{
|
||||
ID3D12PipelineState_Release(d3d12GraphicsPipeline->PipelineState);
|
||||
}
|
||||
DestroyGraphicsRootSignature(d3d12GraphicsPipeline->RootSignature);
|
||||
Free(d3d12GraphicsPipeline.Get());
|
||||
}
|
||||
} // namespace Internal
|
||||
} // namespace Juliet::D3D12
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <Core/Common/NonNullPtr.h>
|
||||
#include <Graphics/D3D12/D3D12Includes.h>
|
||||
#include <Graphics/GraphicsDevice.h>
|
||||
#include <Graphics/GraphicsPipeline.h>
|
||||
|
||||
namespace Juliet
|
||||
{
|
||||
@@ -11,5 +14,51 @@ namespace Juliet
|
||||
|
||||
namespace Juliet::D3D12
|
||||
{
|
||||
extern GraphicsPipeline* CreateGraphicsPipeline(NonNullPtr<GPUDriver> driver, GraphicsPipelineCreateInfo& createInfo);
|
||||
}
|
||||
struct D3D12GraphicsRootSignature
|
||||
{
|
||||
ID3D12RootSignature* handle;
|
||||
|
||||
int32 VertexSamplerRootIndex;
|
||||
int32 VertexSamplerTextureRootIndex;
|
||||
int32 VertexStorageTextureRootIndex;
|
||||
int32 VertexStorageBufferRootIndex;
|
||||
|
||||
int32 VertexUniformBufferRootIndex[GPUDriver::kMaxUniformBuffersPerStage];
|
||||
|
||||
int32 FragmentSamplerRootIndex;
|
||||
int32 FragmentSamplerTextureRootIndex;
|
||||
int32 FragmentStorageTextureRootIndex;
|
||||
int32 FragmentStorageBufferRootIndex;
|
||||
|
||||
int32 FragmentUniformBufferRootIndex[GPUDriver::kMaxUniformBuffersPerStage];
|
||||
};
|
||||
|
||||
struct D3D12GraphicsPipeline
|
||||
{
|
||||
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);
|
||||
|
||||
namespace Internal
|
||||
{
|
||||
extern void ReleaseGraphicsPipeline(NonNullPtr<D3D12GraphicsPipeline> d3d12GraphicsPipeline);
|
||||
}
|
||||
} // namespace Juliet::D3D12
|
||||
|
||||
@@ -5,14 +5,6 @@
|
||||
|
||||
namespace Juliet::D3D12
|
||||
{
|
||||
namespace
|
||||
{
|
||||
struct D3D12Shader
|
||||
{
|
||||
ByteBuffer ByteCode;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
Shader* CreateShader(NonNullPtr<GPUDriver> driver, ByteBuffer shaderByteCode, ShaderCreateInfo& shaderCreateInfo)
|
||||
{
|
||||
if (!IsValid(shaderByteCode))
|
||||
|
||||
@@ -6,6 +6,16 @@
|
||||
|
||||
namespace Juliet::D3D12
|
||||
{
|
||||
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
|
||||
|
||||
@@ -66,6 +66,8 @@ namespace Juliet::D3D12
|
||||
result &= Internal::CleanCommandList(d3d12driver, d3d12driver->SubmittedCommandLists[idx], false);
|
||||
}
|
||||
|
||||
Internal::DisposePendingResourcces(d3d12driver);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -116,6 +116,117 @@ namespace Juliet::D3D12
|
||||
DXGI_FORMAT_UNKNOWN, // ASTC_12x10_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)
|
||||
{
|
||||
@@ -236,5 +347,17 @@ namespace Juliet::D3D12
|
||||
{
|
||||
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 Juliet::D3D12
|
||||
|
||||
@@ -88,5 +88,7 @@ namespace Juliet::D3D12
|
||||
|
||||
// Utils
|
||||
extern DXGI_FORMAT ConvertToD3D12TextureFormat(TextureFormat format);
|
||||
extern DXGI_FORMAT ConvertToD3D12DepthFormat(TextureFormat format);
|
||||
extern uint32 JulietToD3D12_SampleCount[];
|
||||
} // namespace Internal
|
||||
} // namespace Juliet::D3D12
|
||||
|
||||
@@ -218,8 +218,8 @@ namespace Juliet
|
||||
device->DestroyShader(device->Driver, shader);
|
||||
}
|
||||
|
||||
GraphicsPipeline* CreateGraphicsPipeline(NonNullPtr<GraphicsDevice> device, GraphicsPipelineCreateInfo& createInfo)
|
||||
GraphicsPipeline* CreateGraphicsPipeline(NonNullPtr<GraphicsDevice> device, const GraphicsPipelineCreateInfo& createInfo)
|
||||
{
|
||||
device->CreateGraphicsPipeline(device->Driver, createInfo);
|
||||
return device->CreateGraphicsPipeline(device->Driver, createInfo);
|
||||
}
|
||||
} // namespace Juliet
|
||||
|
||||
@@ -30,9 +30,11 @@ namespace Juliet
|
||||
|
||||
struct GPUDriver
|
||||
{
|
||||
static constexpr uint8 kResourceBufferCount = 2;
|
||||
static constexpr uint8 kMaxFramesInFlight = 3;
|
||||
static constexpr uint8 kMaxColorTargetInfo = 4;
|
||||
static constexpr uint8 kResourceBufferCount = 2;
|
||||
static constexpr uint8 kMaxFramesInFlight = 3;
|
||||
static constexpr uint8 kMaxColorTargetInfo = 4;
|
||||
static constexpr uint8 kMaxUniformBuffersPerStage = 4;
|
||||
static constexpr uint8 kMaxVertexBuffers = 16;
|
||||
};
|
||||
|
||||
struct GraphicsDevice
|
||||
@@ -71,7 +73,7 @@ namespace Juliet
|
||||
void (*DestroyShader)(NonNullPtr<GPUDriver> driver, NonNullPtr<Shader> shader);
|
||||
|
||||
// Pipeline
|
||||
GraphicsPipeline* (*CreateGraphicsPipeline)(NonNullPtr<GPUDriver> driver, GraphicsPipelineCreateInfo& createInfo);
|
||||
GraphicsPipeline* (*CreateGraphicsPipeline)(NonNullPtr<GPUDriver> driver, const GraphicsPipelineCreateInfo& createInfo);
|
||||
|
||||
const char* Name = "Unknown";
|
||||
GPUDriver* Driver = nullptr;
|
||||
|
||||
@@ -74,18 +74,21 @@ void JulietApplication::Init()
|
||||
shaderCI.Stage = ShaderStage::Fragment;
|
||||
Shader* fragmentShader = CreateShader(GraphicsDevice, shaderPath, shaderCI);
|
||||
|
||||
ColorTargetDescription colorTargetDescription = { .Format = GetSwapChainTextureFormat(GraphicsDevice, MainWindow) };
|
||||
GraphicsPipelineCreateInfo pipelineCI = {
|
||||
.VertexShader = vertexShader,
|
||||
.FragmentShader = fragmentShader,
|
||||
.PrimitiveType = PrimitiveType::TriangleList,
|
||||
.TargetInfo = {
|
||||
.ColorTargetDescriptions = &colorTargetDescription,
|
||||
.NumColorTargets = 1,
|
||||
},
|
||||
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,
|
||||
};
|
||||
pipelineCI.RasterizerState.FillMode = FillMode::Solid;
|
||||
|
||||
GraphicsPipeline* mainPipeline = CreateGraphicsPipeline(GraphicsDevice, pipelineCI);
|
||||
|
||||
if (vertexShader)
|
||||
{
|
||||
DestroyShader(GraphicsDevice, vertexShader);
|
||||
|
||||
Reference in New Issue
Block a user