Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose missing rasterizer states. #36

Merged
merged 31 commits into from
Jun 26, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
2f657a4
Remove obsolete `dx12_builder.hpp`.
crud89 Jun 23, 2021
515a0f6
Expose depth/stencil state.
crud89 Jun 23, 2021
73b9ce7
Set line width in dynamic state.
crud89 Jun 23, 2021
38d11db
Minor typo fixes.
crud89 Jun 24, 2021
12be166
Add blend state to render target.
crud89 Jun 24, 2021
d49b79a
Initialize DX 12 blend state.
crud89 Jun 24, 2021
4e4a926
Implement Vulkan render target blend state.
crud89 Jun 24, 2021
3cf8848
Expose constant blend factors.
crud89 Jun 24, 2021
6ab36cd
Throw exceptions for unsupported types.
crud89 Jun 24, 2021
24aed2d
Add method to set the stencil reference.
crud89 Jun 24, 2021
73f1343
Added a2c test.
crud89 Jun 24, 2021
df163d4
Add method to request maximum number of samples.
crud89 Jun 24, 2021
2b13e09
Add multi-sampling level to swap chain.
crud89 Jun 24, 2021
bf38c13
Implement multi sampling for DirectX 12 back-end.
crud89 Jun 24, 2021
0e1b6cd
Update quick start guide, with regards to multi-sampling.
crud89 Jun 24, 2021
c62052c
Remove multi sampling back buffers in swap chain.
crud89 Jun 24, 2021
f67c701
Add multi-sampling sample for DirectX 12.
crud89 Jun 24, 2021
3bf4b80
Allow multi-sample level changes on a per-render pass basis.
crud89 Jun 24, 2021
d2cb3f5
Add support for multi-sampled image resources.
crud89 Jun 24, 2021
096522b
Properly initialize the DSV/RTV for multi-sampling.
crud89 Jun 24, 2021
65bbea3
Implemented present target resolution.
crud89 Jun 24, 2021
c1cf18d
Fix several variable names and strings.
crud89 Jun 25, 2021
eec868e
Add Vulkan multisampling sample
crud89 Jun 25, 2021
89091c6
Fix MSAA interface.
crud89 Jun 25, 2021
be62bee
Properly store samples.
crud89 Jun 25, 2021
d146748
Implement multi sampling properties.
crud89 Jun 25, 2021
09be5b2
Implemented multi sampling for Vulkan.
crud89 Jun 26, 2021
dc72b57
Fix coordinate clipping.
crud89 Jun 26, 2021
df7e6c0
Also apply axis inversion for glslc.
crud89 Jun 26, 2021
0369932
Update documentation on inversion fix.
crud89 Jun 26, 2021
d4477c6
Don't include auto-created headers in source groups.
crud89 Jun 26, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ auto pipeline = renderPass->makePipeline(0, "Basic Pipeline")
.go();
```

LiteFX is written in modern C++20, following established design patterns to make it easy to learn and adapt. It's focus is make the performance of modern graphics APIs easily accessible, whilst retaining full flexibility.
LiteFX is written in modern C++20, following established design patterns to make it easy to learn and adapt. Its focus is make the performance of modern graphics APIs easily accessible, whilst retaining full flexibility.

Shader can be built using *glslc* or *DXC*. *glslc* can be used to compile HLSL and GLSL shaders into SPIR-V for the Vulkan backend. *DXC* can only compile HLSL, but can target SPIR-V and DXIL, that's why it is preferred over *glslc*.
Shaders can be built using *glslc* or *DXC*. *glslc* can be used to compile HLSL and GLSL shaders into SPIR-V for the Vulkan backend. *DXC* can only compile HLSL, but can target SPIR-V and DXIL, that's why it is preferred over *glslc*.

## Installation

Expand Down
9 changes: 9 additions & 0 deletions docs/release-logs/0.2.1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# LiteFX 0.2.1 - Alpha 02

- Fixes issue that prevented DirectX 12 samples from being run in Release mode.
- Introduces rasterizer depth/stencil state. ([See PR #36](https://github.com/crud89/LiteFX/pull/36))
- Adds support for multisampling. ([See PR #36](https://github.com/crud89/LiteFX/pull/36))
- Introduces render target blend states ([See PR #36](https://github.com/crud89/LiteFX/pull/36)).
- Vulkan 🌋: line width is part of the dynamic rasterizer state. ([See PR #36](https://github.com/crud89/LiteFX/pull/36))
- Vulkan 🌋: Fixed validation errors about invalid attachment layout for depth/stencil only render targets.
- Vulkan 🌋: Apply the `-fvk-invert-y` (DXC)/`-finvert-y` (GLSLC) switch to vertex, geometry and tessellation evaluation shaders. This removes the requirement to manually add a flip transform to projection matrices.
6 changes: 1 addition & 5 deletions docs/tutorials/quick-start.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -220,15 +220,14 @@ In our example, however, we do not use multiple render passes and instead only c
The other values that are provided to a render target are:

- The render target format, which in our example is dictated by the swap chain format we've chosen earlier.
- The multisampling level, which we set to `x1`, since we do not yet want to use multi sampling.
- A clear value vector, which contains the values that the render target will be cleared with when starting the render pass. For our *BGRA* image, we want to clear it with black and an alpha value of `0.0`.
- A boolean switch to enable or disable clearing the values, which we set to true, since we want to clear our image with the clear values specified earlier.
- A boolean switch to enable clearing for stencil buffers. This switch is only used, if the render target is a `DepthStencil` target and the format supports stencil values. It can be used to disable clearing stencil values and only clear depth values for depth/stencil targets.
- A boolean switch that states, if we want to preserve the contents of the image after the render pass has finished. Since we do not want to use our render target as input attachment for another render pass, we also set this value to `false`.

```cxx
m_renderPass = m_device->buildRenderPass()
.renderTarget(RenderTargetType::Present, Format::B8G8R8A8_SRGB, MultiSamplingLevel::x1, { 0.f, 0.f, 0.f, 0.f }, true, false, false)
.renderTarget(RenderTargetType::Present, Format::B8G8R8A8_SRGB, { 0.f, 0.f, 0.f, 0.f }, true, false, false)
.go();
```

Expand Down Expand Up @@ -502,12 +501,9 @@ Let's move on and compute the view and projection matrix and pre-multiply them t
auto aspectRatio = m_viewport->getRectangle().width() / m_viewport->getRectangle().height();
glm::mat4 view = glm::lookAt(glm::vec3(1.5f, 1.5f, 1.5f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f));
glm::mat4 projection = glm::perspective(glm::radians(60.0f), aspectRatio, 0.0001f, 1000.0f);
projection[1][1] *= -1.f; // Fix GLM clip coordinate scaling.
camera.ViewProjection = projection * view;
```

It is important to fix the GLM clip coordinate scaling in the projection matrix. Since GLM has originally been developed for OpenGL, the y-coordinate of the camera space is inverted. The easiest way to fix this, is to pre-apply a flip transform by inverting the Y-coordinate. If you leave out this line, you image might end up beeing rendered upside-down in Vulkan.

In the last line, we pre-multiply the view/projection matrix and store it in the camera buffer, which we can now transfer to the GPU:

```cxx
Expand Down
71 changes: 45 additions & 26 deletions src/Backends/DirectX12/include/litefx/backends/dx12.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
#include <litefx/rendering.hpp>

#include "dx12_api.hpp"
#include "dx12_builders.hpp"
#include "dx12_formatters.hpp"

namespace LiteFX::Rendering::Backends {
Expand Down Expand Up @@ -769,11 +768,8 @@ namespace LiteFX::Rendering::Backends {
/// <param name="cullMode">The cull mode used by the pipeline.</param>
/// <param name="cullOrder">The cull order used by the pipeline.</param>
/// <param name="lineWidth">The line width used by the pipeline.</param>
/// <param name="useDepthBias"><c>true</c>, if the depth bias should be enabled.</param>
/// <param name="depthBiasClamp">The clamp value of the depth bias state.</param>
/// <param name="depthBiasConstantFactor">The constant factor of the depth bias state.</param>
/// <param name="depthBiasSlopeFactor">The slope factor of the depth bias state.</param>
explicit DirectX12Rasterizer(const DirectX12RenderPipeline& pipeline, const PolygonMode& polygonMode, const CullMode& cullMode, const CullOrder& cullOrder, const Float& lineWidth = 1.f, const bool& useDepthBias = false, const Float& depthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP, const Float& depthBiasConstantFactor = D3D12_DEFAULT_DEPTH_BIAS, const Float& depthBiasSlopeFactor = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS) noexcept;
/// <param name="depthStencilState">The rasterizer depth/stencil state.</param>
explicit DirectX12Rasterizer(const DirectX12RenderPipeline& pipeline, const PolygonMode& polygonMode, const CullMode& cullMode, const CullOrder& cullOrder, const Float& lineWidth = 1.f, const DepthStencilState& depthStencilState = {}) noexcept;
DirectX12Rasterizer(DirectX12Rasterizer&&) noexcept = delete;
DirectX12Rasterizer(const DirectX12Rasterizer&) noexcept = delete;
virtual ~DirectX12Rasterizer() noexcept;
Expand Down Expand Up @@ -819,16 +815,13 @@ namespace LiteFX::Rendering::Backends {
virtual DirectX12RasterizerBuilder& withLineWidth(const Float& lineWidth = 1.f) noexcept override;

/// <inheritdoc />
virtual DirectX12RasterizerBuilder& enableDepthBias(const bool& enable = false) noexcept override;
virtual DirectX12RasterizerBuilder& withDepthBias(const DepthStencilState::DepthBias& depthBias) noexcept override;

/// <inheritdoc />
virtual DirectX12RasterizerBuilder& withDepthBiasClamp(const Float& clamp = 0.f) noexcept override;
virtual DirectX12RasterizerBuilder& withDepthState(const DepthStencilState::DepthState& depthState) noexcept override;

/// <inheritdoc />
virtual DirectX12RasterizerBuilder& withDepthBiasConstantFactor(const Float& factor = 0.f) noexcept override;

/// <inheritdoc />
virtual DirectX12RasterizerBuilder& withDepthBiasSlopeFactor(const Float& factor = 0.f) noexcept override;
virtual DirectX12RasterizerBuilder& withStencilState(const DepthStencilState::StencilState& stencilState) noexcept override;
};

/// <summary>
Expand All @@ -843,10 +836,11 @@ namespace LiteFX::Rendering::Backends {
/// <summary>
/// Initializes a new DirectX12 render pipeline.
/// </summary>
/// <param name="renderPass"></param>
/// <param name="id"></param>
/// <param name="name"></param>
explicit DirectX12RenderPipeline(const DirectX12RenderPass& renderPass, const UInt32& id, UniquePtr<DirectX12RenderPipelineLayout>&& layout, SharedPtr<DirectX12InputAssembler>&& inputAssembler, SharedPtr<DirectX12Rasterizer>&& rasterizer, Array<SharedPtr<IViewport>>&& viewports, Array<SharedPtr<IScissor>>&& scissors, const String& name = "");
/// <param name="renderPass">The parent render pass.</param>
/// <param name="id">The unique ID of the pipeline within the render pass.</param>
/// <param name="name">The optional debug name of the render pipeline.</param>
/// <param name="enableAlphaToCoverage">Whether or not to enable Alpha-to-Coverage multi-sampling.</param>
explicit DirectX12RenderPipeline(const DirectX12RenderPass& renderPass, const UInt32& id, UniquePtr<DirectX12RenderPipelineLayout>&& layout, SharedPtr<DirectX12InputAssembler>&& inputAssembler, SharedPtr<DirectX12Rasterizer>&& rasterizer, Array<SharedPtr<IViewport>>&& viewports, Array<SharedPtr<IScissor>>&& scissors, const bool enableAlphaToCoverage = false, const String& name = "");
DirectX12RenderPipeline(DirectX12RenderPipeline&&) noexcept = delete;
DirectX12RenderPipeline(const DirectX12RenderPipeline&) noexcept = delete;
virtual ~DirectX12RenderPipeline() noexcept;
Expand Down Expand Up @@ -877,6 +871,15 @@ namespace LiteFX::Rendering::Backends {
/// <inheritdoc />
virtual Array<const IScissor*> scissors() const noexcept override;

/// <inheritdoc />
virtual UInt32& stencilRef() const noexcept override;

/// <inheritdoc />
virtual Vector4f& blendFactors() const noexcept override;

/// <inheritdoc />
virtual const bool& alphaToCoverage() const noexcept override;

public:
/// <inheritdoc />
/// <remarks>
Expand Down Expand Up @@ -948,6 +951,9 @@ namespace LiteFX::Rendering::Backends {
/// <inheritdoc />
virtual void use(SharedPtr<IScissor> scissor) override;

/// <inheritdoc />
virtual DirectX12RenderPipelineBuilder& enableAlphaToCoverage(const bool& enable = true) override;

// DirectX12RenderPipelineBuilder.
public:
/// <summary>
Expand Down Expand Up @@ -1083,10 +1089,11 @@ namespace LiteFX::Rendering::Backends {
/// <summary>
/// Creates and initializes a new DirectX12 render pass instance.
/// </summary>
/// <param name="device"></param>
/// <param name="renderTargets"></param>
/// <param name="inputAttachments"></param>
explicit DirectX12RenderPass(const DirectX12Device& device, Span<RenderTarget> renderTargets, Span<DirectX12InputAttachmentMapping> inputAttachments = { });
/// <param name="device">The parent device instance.</param>
/// <param name="renderTargets">The render targets that are output by the render pass.</param>
/// <param name="samples">The number of samples for the render targets in this render pass.</param>
/// <param name="inputAttachments">The input attachments that are read by the render pass.</param>
explicit DirectX12RenderPass(const DirectX12Device& device, Span<RenderTarget> renderTargets, const MultiSamplingLevel& samples = MultiSamplingLevel::x1, Span<DirectX12InputAttachmentMapping> inputAttachments = { });
DirectX12RenderPass(const DirectX12RenderPass&) = delete;
DirectX12RenderPass(DirectX12RenderPass&&) = delete;
virtual ~DirectX12RenderPass() noexcept;
Expand Down Expand Up @@ -1133,6 +1140,9 @@ namespace LiteFX::Rendering::Backends {
/// <inheritdoc />
virtual Span<const DirectX12InputAttachmentMapping> inputAttachments() const noexcept override;

/// <inheritdoc />
virtual const MultiSamplingLevel& multiSamplingLevel() const noexcept override;

public:
/// <inheritdoc />
virtual void begin(const UInt32& buffer) override;
Expand All @@ -1143,6 +1153,9 @@ namespace LiteFX::Rendering::Backends {
/// <inheritdoc />
virtual void resizeFrameBuffers(const Size2d& renderArea) override;

/// <inheritdoc />
virtual void changeMultiSamplingLevel(const MultiSamplingLevel& samples) override;

/// <inheritdoc />
virtual void updateAttachments(const DirectX12DescriptorSet& descriptorSet) const override;

Expand All @@ -1166,7 +1179,7 @@ namespace LiteFX::Rendering::Backends {
LITEFX_IMPLEMENTATION(DirectX12RenderPassBuilderImpl)

public:
explicit DirectX12RenderPassBuilder(const DirectX12Device& device) noexcept;
explicit DirectX12RenderPassBuilder(const DirectX12Device& device, const MultiSamplingLevel& multiSamplingLevel = MultiSamplingLevel::x1) noexcept;
DirectX12RenderPassBuilder(const DirectX12RenderPassBuilder&) noexcept = delete;
DirectX12RenderPassBuilder(DirectX12RenderPassBuilder&&) noexcept = delete;
virtual ~DirectX12RenderPassBuilder() noexcept;
Expand All @@ -1175,10 +1188,11 @@ namespace LiteFX::Rendering::Backends {
virtual void use(DirectX12InputAttachmentMapping&& inputAttachment) override;

public:
virtual DirectX12RenderPassBuilder& renderTarget(const RenderTargetType& type, const Format& format, const MultiSamplingLevel& samples, const Vector4f& clearValues = { 0.0f, 0.0f, 0.0f, 0.0f }, bool clearColor = true, bool clearStencil = true, bool isVolatile = false) override;
virtual DirectX12RenderPassBuilder& renderTarget(const UInt32& location, const RenderTargetType& type, const Format& format, const MultiSamplingLevel& samples, const Vector4f& clearValues = { 0.0f, 0.0f, 0.0f, 0.0f }, bool clearColor = true, bool clearStencil = true, bool isVolatile = false) override;
virtual DirectX12RenderPassBuilder& renderTarget(DirectX12InputAttachmentMapping& output, const RenderTargetType& type, const Format& format, const MultiSamplingLevel& samples, const Vector4f& clearValues = { 0.0f, 0.0f, 0.0f, 0.0f }, bool clearColor = true, bool clearStencil = true, bool isVolatile = false) override;
virtual DirectX12RenderPassBuilder& renderTarget(DirectX12InputAttachmentMapping& output, const UInt32& location, const RenderTargetType& type, const Format& format, const MultiSamplingLevel& samples, const Vector4f& clearValues = { 0.0f, 0.0f, 0.0f, 0.0f }, bool clearColor = true, bool clearStencil = true, bool isVolatile = false) override;
virtual DirectX12RenderPassBuilder& renderTarget(const RenderTargetType& type, const Format& format, const Vector4f& clearValues = { 0.0f, 0.0f, 0.0f, 0.0f }, bool clearColor = true, bool clearStencil = true, bool isVolatile = false) override;
virtual DirectX12RenderPassBuilder& renderTarget(const UInt32& location, const RenderTargetType& type, const Format& format, const Vector4f& clearValues = { 0.0f, 0.0f, 0.0f, 0.0f }, bool clearColor = true, bool clearStencil = true, bool isVolatile = false) override;
virtual DirectX12RenderPassBuilder& renderTarget(DirectX12InputAttachmentMapping& output, const RenderTargetType& type, const Format& format, const Vector4f& clearValues = { 0.0f, 0.0f, 0.0f, 0.0f }, bool clearColor = true, bool clearStencil = true, bool isVolatile = false) override;
virtual DirectX12RenderPassBuilder& renderTarget(DirectX12InputAttachmentMapping& output, const UInt32& location, const RenderTargetType& type, const Format& format, const Vector4f& clearValues = { 0.0f, 0.0f, 0.0f, 0.0f }, bool clearColor = true, bool clearStencil = true, bool isVolatile = false) override;
virtual DirectX12RenderPassBuilder& setMultiSamplingLevel(const MultiSamplingLevel& samples = MultiSamplingLevel::x4) override;
virtual DirectX12RenderPassBuilder& inputAttachment(const DirectX12InputAttachmentMapping& inputAttachment) override;
virtual DirectX12RenderPassBuilder& inputAttachment(const UInt32& inputLocation, const DirectX12RenderPass& renderPass, const UInt32& outputLocation) override;
virtual DirectX12RenderPassBuilder& inputAttachment(const UInt32& inputLocation, const DirectX12RenderPass& renderPass, const RenderTarget& renderTarget) override;
Expand Down Expand Up @@ -1505,9 +1519,10 @@ namespace LiteFX::Rendering::Backends {
/// <summary>
/// Returns a builder for a <see cref="DirectX12RenderPass" />.
/// </summary>
/// <param name="samples">The number of samples, the render targets of the render pass should be sampled with.</param>
/// <returns>An instance of a builder that is used to create a new render pass.</returns>
/// <seealso cref="IGraphicsDevice::build" />
DirectX12RenderPassBuilder buildRenderPass() const;
DirectX12RenderPassBuilder buildRenderPass(const MultiSamplingLevel& samples = MultiSamplingLevel::x1) const;

/// <summary>
/// Returns a reference of the swap chain.
Expand Down Expand Up @@ -1538,6 +1553,10 @@ namespace LiteFX::Rendering::Backends {
/// <inheritdoc />
virtual const DirectX12Queue& bufferQueue() const noexcept override;

/// <inheritdoc />
/// <seealso href="https://docs.microsoft.com/en-us/windows/win32/api/d3d11/ne-d3d11-d3d11_standard_multisample_quality_levels" />
virtual MultiSamplingLevel maximumMultiSamplingLevel(const Format& format) const noexcept override;

public:
/// <inheritdoc />
virtual void wait() const override;
Expand Down
20 changes: 20 additions & 0 deletions src/Backends/DirectX12/include/litefx/backends/dx12_api.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,26 @@ namespace LiteFX::Rendering::Backends {
/// <returns></returns>
String LITEFX_DIRECTX12_API getVendorName(const UInt32& vendorId);

/// <summary>
///
/// </summary>
D3D12_COMPARISON_FUNC LITEFX_DIRECTX12_API getCompareOp(const CompareOperation& compareOp);

/// <summary>
///
/// </summary>
D3D12_STENCIL_OP LITEFX_DIRECTX12_API getStencilOp(const StencilOperation& stencilOp);

/// <summary>
///
/// </summary>
D3D12_BLEND LITEFX_DIRECTX12_API getBlendFactor(const BlendFactor& blendFactor);

/// <summary>
///
/// </summary>
D3D12_BLEND_OP LITEFX_DIRECTX12_API getBlendOperation(const BlendOperation& blendOperation);

/// <summary>
/// Implements a DirectX12 <see cref="IGraphicsAdapter" />.
/// </summary>
Expand Down

This file was deleted.

Loading