diff --git a/Juliet/Juliet.vcxproj b/Juliet/Juliet.vcxproj
index c23400c..43918ae 100644
--- a/Juliet/Juliet.vcxproj
+++ b/Juliet/Juliet.vcxproj
@@ -144,6 +144,7 @@
+
@@ -165,6 +166,7 @@
+
@@ -206,6 +208,7 @@
+
diff --git a/Juliet/include/Graphics/Graphics.h b/Juliet/include/Graphics/Graphics.h
index f06f776..9d3e12d 100644
--- a/Juliet/include/Graphics/Graphics.h
+++ b/Juliet/include/Graphics/Graphics.h
@@ -5,6 +5,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -12,6 +13,7 @@
// Graphics Interface
namespace Juliet
{
+
// Opaque types
struct CommandList;
struct GraphicsDevice;
@@ -91,6 +93,7 @@ namespace Juliet
// SwapChain
extern JULIET_API bool AcquireSwapChainTexture(NonNullPtr commandList, NonNullPtr window,
Texture** swapChainTexture);
+ extern JULIET_API TextureFormat GetSwapChainTextureFormat(NonNullPtr device, NonNullPtr window);
// Command List
extern JULIET_API CommandList* AcquireCommandList(NonNullPtr device, QueueType queueType = QueueType::Graphics);
@@ -109,5 +112,10 @@ namespace Juliet
// Shaders
extern JULIET_API Shader* CreateShader(NonNullPtr device, String filename, ShaderCreateInfo& shaderCreateInfo);
- extern JULIET_API void DestroyShader(NonNullPtr driver, NonNullPtr shader);
+ extern JULIET_API void DestroyShader(NonNullPtr device, NonNullPtr shader);
+
+ // Pipelines
+ extern JULIET_API GraphicsPipeline* CreateGraphicsPipeline(NonNullPtr device,
+ GraphicsPipelineCreateInfo& createInfo);
+
} // namespace Juliet
diff --git a/Juliet/include/Graphics/GraphicsPipeline.h b/Juliet/include/Graphics/GraphicsPipeline.h
new file mode 100644
index 0000000..76d66d4
--- /dev/null
+++ b/Juliet/include/Graphics/GraphicsPipeline.h
@@ -0,0 +1,61 @@
+#pragma once
+#include
+
+namespace Juliet
+{
+ // Forward Declare
+ struct ColorTargetDescription;
+
+ enum class FillMode : uint8
+ {
+ Wireframe,
+ Solid
+ };
+
+ enum class CullMode : uint8
+ {
+ None,
+ Front,
+ Back
+ };
+
+ enum class FrontFace : uint8
+ {
+ CounterClockwise,
+ Clockwise
+ };
+
+ enum class PrimitiveType : uint8
+ {
+ TriangleList,
+ TriangleStrip,
+ LineList,
+ LineStrip,
+ PointList,
+ };
+
+ struct RasterizerState
+ {
+ FillMode FillMode;
+ CullMode CullMode;
+ FrontFace FrontFace;
+ };
+
+ struct GraphicsPipelineTargetInfo
+ {
+ const ColorTargetDescription* ColorTargetDescriptions;
+ size_t NumColorTargets;
+ };
+
+ struct GraphicsPipelineCreateInfo
+ {
+ Shader* VertexShader;
+ Shader* FragmentShader;
+ RasterizerState RasterizerState;
+ PrimitiveType PrimitiveType;
+ GraphicsPipelineTargetInfo TargetInfo;
+ };
+
+ // Opaque type
+ struct GraphicsPipeline;
+} // namespace Juliet
diff --git a/Juliet/include/Graphics/RenderPass.h b/Juliet/include/Graphics/RenderPass.h
index b5abb46..b8de189 100644
--- a/Juliet/include/Graphics/RenderPass.h
+++ b/Juliet/include/Graphics/RenderPass.h
@@ -41,6 +41,17 @@ namespace Juliet
StoreOperation StoreOperation;
};
+ struct ColorTargetBlendState
+ {
+
+ };
+
+ struct ColorTargetDescription
+ {
+ TextureFormat Format;
+ ColorTargetBlendState BlendState;
+ };
+
// Opaque Type
struct RenderPass;
} // namespace Juliet
diff --git a/Juliet/src/Graphics/D3D12/D3D12GraphicsPipeline.cpp b/Juliet/src/Graphics/D3D12/D3D12GraphicsPipeline.cpp
new file mode 100644
index 0000000..267b3ba
--- /dev/null
+++ b/Juliet/src/Graphics/D3D12/D3D12GraphicsPipeline.cpp
@@ -0,0 +1,14 @@
+#include
+
+#include
+
+#include
+#include
+
+namespace Juliet::D3D12
+{
+ GraphicsPipeline* CreateGraphicsPipeline(NonNullPtr driver, GraphicsPipelineCreateInfo& createInfo)
+ {
+ return nullptr;
+ }
+} // namespace Juliet::D3D12
diff --git a/Juliet/src/Graphics/D3D12/D3D12GraphicsPipeline.h b/Juliet/src/Graphics/D3D12/D3D12GraphicsPipeline.h
new file mode 100644
index 0000000..b7efc14
--- /dev/null
+++ b/Juliet/src/Graphics/D3D12/D3D12GraphicsPipeline.h
@@ -0,0 +1,15 @@
+#pragma once
+
+#include
+
+namespace Juliet
+{
+ struct GraphicsPipelineCreateInfo;
+ struct GPUDriver;
+ struct GraphicsPipeline;
+} // namespace Juliet
+
+namespace Juliet::D3D12
+{
+ extern GraphicsPipeline* CreateGraphicsPipeline(NonNullPtr driver, GraphicsPipelineCreateInfo& createInfo);
+}
diff --git a/Juliet/src/Graphics/D3D12/DX12GraphicsDevice.cpp b/Juliet/src/Graphics/D3D12/DX12GraphicsDevice.cpp
index f405818..4acfdda 100644
--- a/Juliet/src/Graphics/D3D12/DX12GraphicsDevice.cpp
+++ b/Juliet/src/Graphics/D3D12/DX12GraphicsDevice.cpp
@@ -3,6 +3,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -596,30 +597,25 @@ namespace Juliet::D3D12
}
// Assign Functions to the device
- device->DestroyDevice = DestroyGraphicsDevice;
-
- device->AttachToWindow = AttachToWindow;
- device->DetachFromWindow = DetachFromWindow;
-
- 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->CreateShader = CreateShader;
- device->DestroyShader = DestroyShader;
+ device->DestroyDevice = DestroyGraphicsDevice;
+ device->AttachToWindow = AttachToWindow;
+ device->DetachFromWindow = DetachFromWindow;
+ device->AcquireSwapChainTexture = AcquireSwapChainTexture;
+ 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->Wait = Wait;
+ device->QueryFence = QueryFence;
+ device->ReleaseFence = ReleaseFence;
+ device->CreateShader = CreateShader;
+ device->DestroyShader = DestroyShader;
+ device->CreateGraphicsPipeline = CreateGraphicsPipeline;
device->Driver = driver;
driver->GraphicsDevice = device;
diff --git a/Juliet/src/Graphics/D3D12/DX12SwapChain.cpp b/Juliet/src/Graphics/D3D12/DX12SwapChain.cpp
index 08f2792..216eead 100644
--- a/Juliet/src/Graphics/D3D12/DX12SwapChain.cpp
+++ b/Juliet/src/Graphics/D3D12/DX12SwapChain.cpp
@@ -192,6 +192,21 @@ namespace Juliet::D3D12
return AcquireSwapChainTexture(false, commandList, window, swapChainTexture);
}
+ TextureFormat GetSwapChainTextureFormat(NonNullPtr driver, NonNullPtr window)
+ {
+ auto* d3d12Driver = static_cast(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
{
bool CreateSwapChain(NonNullPtr driver, NonNullPtr windowData,
diff --git a/Juliet/src/Graphics/D3D12/DX12SwapChain.h b/Juliet/src/Graphics/D3D12/DX12SwapChain.h
index fc12aec..c9f95e4 100644
--- a/Juliet/src/Graphics/D3D12/DX12SwapChain.h
+++ b/Juliet/src/Graphics/D3D12/DX12SwapChain.h
@@ -8,6 +8,7 @@ namespace Juliet::D3D12
struct D3D12WindowData;
extern bool AcquireSwapChainTexture(NonNullPtr commandList, NonNullPtr window, Texture** swapChainTexture);
+extern TextureFormat GetSwapChainTextureFormat(NonNullPtr driver, NonNullPtr window);
namespace Internal
{
diff --git a/Juliet/src/Graphics/Graphics.cpp b/Juliet/src/Graphics/Graphics.cpp
index 3ef6b47..539a9b3 100644
--- a/Juliet/src/Graphics/Graphics.cpp
+++ b/Juliet/src/Graphics/Graphics.cpp
@@ -88,6 +88,11 @@ namespace Juliet
return true;
}
+ TextureFormat GetSwapChainTextureFormat(NonNullPtr device, NonNullPtr window)
+ {
+ return device->GetSwapChainTextureFormat(device->Driver, window);
+ }
+
CommandList* AcquireCommandList(NonNullPtr device, QueueType queueType /* = QueueType::Graphics */)
{
GPUDriver* driver = device->Driver;
@@ -213,4 +218,8 @@ namespace Juliet
device->DestroyShader(device->Driver, shader);
}
+ GraphicsPipeline* CreateGraphicsPipeline(NonNullPtr device, GraphicsPipelineCreateInfo& createInfo)
+ {
+ device->CreateGraphicsPipeline(device->Driver, createInfo);
+ }
} // namespace Juliet
diff --git a/Juliet/src/Graphics/GraphicsDevice.h b/Juliet/src/Graphics/GraphicsDevice.h
index 2615fce..b09c6d6 100644
--- a/Juliet/src/Graphics/GraphicsDevice.h
+++ b/Juliet/src/Graphics/GraphicsDevice.h
@@ -3,6 +3,7 @@
#include
#include
#include
+#include
#include
namespace Juliet
@@ -44,6 +45,7 @@ namespace Juliet
// SwapChain
bool (*AcquireSwapChainTexture)(NonNullPtr commandList, NonNullPtr window, Texture** swapChainTexture);
+ TextureFormat (*GetSwapChainTextureFormat)(NonNullPtr driver, NonNullPtr window);
// CommandLists
CommandList* (*AcquireCommandList)(NonNullPtr driver, QueueType queueType);
@@ -68,6 +70,9 @@ namespace Juliet
Shader* (*CreateShader)(NonNullPtr driver, ByteBuffer shaderByteCode, ShaderCreateInfo& shaderCreateInfo);
void (*DestroyShader)(NonNullPtr driver, NonNullPtr shader);
+ // Pipeline
+ GraphicsPipeline* (*CreateGraphicsPipeline)(NonNullPtr driver, GraphicsPipelineCreateInfo& createInfo);
+
const char* Name = "Unknown";
GPUDriver* Driver = nullptr;
};
diff --git a/JulietApp/main.cpp b/JulietApp/main.cpp
index bbca511..0e21167 100644
--- a/JulietApp/main.cpp
+++ b/JulietApp/main.cpp
@@ -14,6 +14,7 @@
#include
#include
#include
+#include
// TODO : Replace with message box from framework + call main and not winmain + subsystem
// TODO : Think how to do the draw pipeline.
@@ -60,15 +61,38 @@ void JulietApplication::Init()
{
// Create graphics pipeline
- // TODO: Assets management that handles path to assets or something.
- String shaderPath = WrapString("../../../Assets/compiled/Triangle.vert.dxil");
+ String entryPoint = WrapString("main");
ShaderCreateInfo shaderCI = {};
- shaderCI.Stage = ShaderStage::Vertex;
- shaderCI.EntryPoint = WrapString("main");
- Shader* shader = CreateShader(GraphicsDevice, shaderPath, shaderCI);
- if (shader)
+ 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 = { .Format = GetSwapChainTextureFormat(GraphicsDevice, MainWindow) };
+ GraphicsPipelineCreateInfo pipelineCI = {
+ .VertexShader = vertexShader,
+ .FragmentShader = fragmentShader,
+ .PrimitiveType = PrimitiveType::TriangleList,
+ .TargetInfo = {
+ .ColorTargetDescriptions = &colorTargetDescription,
+ .NumColorTargets = 1,
+ },
+ };
+ pipelineCI.RasterizerState.FillMode = FillMode::Solid;
+
+ if (vertexShader)
{
- DestroyShader(GraphicsDevice, shader);
+ DestroyShader(GraphicsDevice, vertexShader);
+ }
+ if (fragmentShader)
+ {
+ DestroyShader(GraphicsDevice, fragmentShader);
}
}