Skip to content

Commit

Permalink
Merge pull request #114 from crud89/compute-post-processing
Browse files Browse the repository at this point in the history
Example for multi-queue synchronization.
  • Loading branch information
crud89 authored Jan 5, 2024
2 parents 2e1b4bf + b6f236a commit d2380ee
Show file tree
Hide file tree
Showing 53 changed files with 1,872 additions and 512 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ on:
- ready_for_review

env:
vulkanSdkVersion: '1.3.239.0' # Lowest version that ships with DXC is 1.2.148.0
vulkanSdkVersion: '1.3.268.0'

jobs:
job:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ on:
required: true

env:
vulkanSdkVersion: '1.3.239.0' # Lowest version that ships with DXC is 1.2.148.0
vulkanSdkVersion: '1.3.268.0'

jobs:
build:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/weekly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ on:
- cron: '1 0 * * 1' # Run every monday night at 00:01 AM (UTC).

env:
vulkanSdkVersion: '1.3.239.0' # Lowest version that ships with DXC is 1.2.148.0
vulkanSdkVersion: '1.3.268.0'

jobs:
job:
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ The engine design follows an descriptive approach, which means that an applicati

```cxx
UniquePtr<RenderPass> renderPass = device->buildRenderPass("Geometry")
.renderTarget(RenderTargetType::Present, Format::B8G8R8A8_UNORM, MultiSamplingLevel::x1, { 0.f, 0.f, 0.f, 1.f }, true, false)
.renderTarget(RenderTargetType::DepthStencil, Format::D32_SFLOAT, MultiSamplingLevel::x1, { 1.f, 0.f, 0.f, 0.f }, true, false);
.renderTarget(RenderTargetType::Present, Format::B8G8R8A8_UNORM, MultiSamplingLevel::x1, RenderTargetFlags::Clear, { 0.f, 0.f, 0.f, 1.f })
.renderTarget(RenderTargetType::DepthStencil, Format::D32_SFLOAT, MultiSamplingLevel::x1, RenderTargetFlags::Clear, { 1.f, 0.f, 0.f, 0.f });

UniquePtr<RenderPipeline> renderPipeline = device->buildRenderPipeline(*renderPass, "Geometry")
.inputAssembler(inputAssembler)
Expand Down
8 changes: 7 additions & 1 deletion docs/release-logs/0.4.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,17 @@
- Command buffers can now be submitted with shared ownership to a command queue, which then stores them and releases the references, if the submit fence is passed (during `waitFor`).
- Command buffer transfers can now receive resources with shared ownership. Resource references are released in a similar fashion.
- To share ownership, the `asShared` function can be used.
- Allow manual command queue allocation for advanced parallel workloads. ([See PR #112](https://github.com/crud89/LiteFX/pull/112))
- Allow manual command queue allocation for advanced parallel workloads. ([See PR #112](https://github.com/crud89/LiteFX/pull/112) and [PR #114](https://github.com/crud89/LiteFX/pull/114))
- New "Compute" example demonstrates how to use and synchronize different graphics and compute queues.
- Make most of the render pipeline state dynamic (viewports, scissors, ...). ([See PR #86](https://github.com/crud89/LiteFX/pull/86))
- Vector conversion to math types can now be done for constant vectors. ([See PR #87](https://github.com/crud89/LiteFX/pull/87))
- Backend types now import contra-variant interface functions instead of hiding them. ([See PR #91](https://github.com/crud89/LiteFX/pull/91))
- Add support for GPU time measurements (*Timing Events*). ([See PR #94](https://github.com/crud89/LiteFX/pull/94))
- Add builder interface for barriers and extent barrier flexibility. ([See PR #97](https://github.com/crud89/LiteFX/pull/97))
- Add support for static secondary command buffers aka. bundles. ([See PR #100](https://github.com/crud89/LiteFX/pull/100))
- Render targets are now created with a set of flags instead of individual boolean switches. ([See PR #114](https://github.com/crud89/LiteFX/pull/114))
- This also enables for more use cases, like using render targets in read-write bindings or sharing between different queues.
- Swap chains can now accept `present` calls without explicitly providing a frame buffer. ([See PR #114](https://github.com/crud89/LiteFX/pull/114))

**🌋 Vulkan:**

Expand All @@ -36,6 +40,8 @@
- Command buffers no longer share a command pool, improving multi-threading behavior. ([See PR #112](https://github.com/crud89/LiteFX/pull/112))
- Queue allocation has also been reworked so that a queue from the most specialized queue family for a provided `QueueType` is returned.
- Empty descriptor sets are now allowed and may be automatically created to fill gaps in descriptor set space indices. ([See PR#110](https://github.com/crud89/LiteFX/pull/110))
- Swap chain presentation uses fences instead of convoluted binary semaphores for synchronization. ([See PR #114](https://github.com/crud89/LiteFX/pull/114))
- Furthermore, the D3D interop version of the swap chain has been reworked to support proper frames in flight (as opposed to do a full CPU-wait before presenting).

**❎ DirectX 12:**

Expand Down
6 changes: 2 additions & 4 deletions docs/tutorials/quick-start.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -237,13 +237,11 @@ 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.
- 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`.
- A flag set that in our example enables clearing the render target when starting the render pass.

```cxx
m_renderPass = m_device->buildRenderPass()
.renderTarget(RenderTargetType::Present, Format::B8G8R8A8_SRGB, { 0.f, 0.f, 0.f, 0.f }, true, false, false);
.renderTarget(RenderTargetType::Present, Format::B8G8R8A8_SRGB, RenderTargetFlags::Clear, { 0.f, 0.f, 0.f, 0.f });
```
#### Creating a Render Pipeline
Expand Down
3 changes: 2 additions & 1 deletion docs/website/content/homepage/fluent.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ SharedPtr<InputAssembler> inputAssembler = device->buildInputAssembler()
UniquePtr<RenderPass> renderPass = device->
buildRenderPass("Render Pass")
.renderTarget(RenderTargetType::Present,
Format::B8G8R8A8_UNORM, { 0.0f, 0.0f, 0.0f, 1.f })
Format::B8G8R8A8_UNORM, RenderTargetFlags::Clear,
{ 0.0f, 0.0f, 0.0f, 1.f })

UniquePtr<RenderPipeline> renderPipeline =
device->buildRenderPipeline(*renderPass, "Render Pipeline")
Expand Down
40 changes: 23 additions & 17 deletions src/Backends/DirectX12/include/litefx/backends/dx12.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ namespace LiteFX::Rendering::Backends {

private:
virtual ImageLayout& layout(UInt32 subresource) = 0;
virtual ImageLayout layout(UInt32 subresource) const = 0;
};

/// <summary>
Expand Down Expand Up @@ -1082,7 +1083,7 @@ namespace LiteFX::Rendering::Backends {
/// <returns>A pointer to the descriptor heap that allocates the render targets for this frame buffer.</returns>
/// <seealso cref="depthStencilTargetHeap" />
/// <seealso cref="renderTargetDescriptorSize" />
virtual ID3D12DescriptorHeap* renderTargetHeap() const noexcept;
ID3D12DescriptorHeap* renderTargetHeap() const noexcept;

/// <summary>
/// Returns a pointer to the descriptor heap that allocates the depth/stencil views for this frame buffer.
Expand All @@ -1093,33 +1094,35 @@ namespace LiteFX::Rendering::Backends {
/// <returns>A pointer to the descriptor heap that allocates the depth/stencil views for this frame buffer.</returns>
/// <seealso cref="renderTargetHeap" />
/// <seealso cref="depthStencilDescriptorSize" />
virtual ID3D12DescriptorHeap* depthStencilTargetHeap() const noexcept;
ID3D12DescriptorHeap* depthStencilTargetHeap() const noexcept;

/// <summary>
/// Returns the size of a descriptor for a render target within the frame buffer.
/// </summary>
/// <returns>The size of a descriptor for a render target within the frame buffer.</returns>
/// <seealso cref="renderTargetHeap" />
virtual UInt32 renderTargetDescriptorSize() const noexcept;
UInt32 renderTargetDescriptorSize() const noexcept;

/// <summary>
/// Returns the size of a descriptor for a depth/stencil view within the frame buffer.
/// </summary>
/// <returns>The size of a descriptor for a depth/stencil view within the frame buffer.</returns>
/// <seealso cref="depthStencilTargetHeap" />
virtual UInt32 depthStencilTargetDescriptorSize() const noexcept;
UInt32 depthStencilTargetDescriptorSize() const noexcept;

/// <summary>
/// Returns a reference of the last fence value for the frame buffer.
/// Returns a reference to the value of the fence that indicates the last submission drawing into the frame buffer.
/// </summary>
/// <remarks>
/// The frame buffer must only be re-used, if this fence is reached in the graphics queue.
/// The frame buffer must only be re-used if this fence has been passed in the command queue that executes the parent render pass.
/// </remarks>
/// <returns>A reference of the last fence value for the frame buffer.</returns>
virtual UInt64& lastFence() const noexcept;
/// <returns>A reference to the of the last submission targeting the frame buffer.</returns>
UInt64& lastFence() noexcept;

// FrameBuffer interface.
public:
/// <inheritdoc />
UInt64 lastFence() const noexcept override;

/// <inheritdoc />
UInt32 bufferIndex() const noexcept override;

Expand All @@ -1139,10 +1142,10 @@ namespace LiteFX::Rendering::Backends {
SharedPtr<const DirectX12CommandBuffer> commandBuffer(UInt32 index) const override;

/// <inheritdoc />
Enumerable<const IDirectX12Image*> images() const noexcept override;
Enumerable<IDirectX12Image*> images() const noexcept override;

/// <inheritdoc />
const IDirectX12Image& image(UInt32 location) const override;
IDirectX12Image& image(UInt32 location) const override;

public:
/// <inheritdoc />
Expand Down Expand Up @@ -1222,7 +1225,7 @@ namespace LiteFX::Rendering::Backends {
/// <param name="name">The name of the render pass state resource.</param>
explicit DirectX12RenderPass(const DirectX12Device& device, const String& name = "") noexcept;

// IInputAttachmentMappingSource interface.
// InputAttachmentMappingSource interface.
public:
/// <inheritdoc />
const DirectX12FrameBuffer& frameBuffer(UInt32 buffer) const override;
Expand Down Expand Up @@ -1267,7 +1270,7 @@ namespace LiteFX::Rendering::Backends {
void begin(UInt32 buffer) override;

/// <inheritdoc />
void end() const override;
UInt64 end() const override;

/// <inheritdoc />
void resizeFrameBuffers(const Size2d& renderArea) override;
Expand Down Expand Up @@ -1397,14 +1400,17 @@ namespace LiteFX::Rendering::Backends {
const Size2d& renderArea() const noexcept override;

/// <inheritdoc />
const IDirectX12Image* image(UInt32 backBuffer) const override;
IDirectX12Image* image(UInt32 backBuffer) const override;

/// <inheritdoc />
Enumerable<const IDirectX12Image*> images() const noexcept override;
Enumerable<IDirectX12Image*> images() const noexcept override;

/// <inheritdoc />
void present(const DirectX12FrameBuffer& frameBuffer) const override;

/// <inheritdoc />
void present(UInt64 fence) const override;

public:
/// <inheritdoc />
Enumerable<Format> getSurfaceFormats() const noexcept override;
Expand Down Expand Up @@ -1553,10 +1559,10 @@ namespace LiteFX::Rendering::Backends {
UniquePtr<IDirectX12IndexBuffer> createIndexBuffer(const String& name, const DirectX12IndexBufferLayout& layout, BufferUsage usage, UInt32 elements) const override;

/// <inheritdoc />
UniquePtr<IDirectX12Image> createAttachment(Format format, const Size2d& size, MultiSamplingLevel samples = MultiSamplingLevel::x1) const override;
UniquePtr<IDirectX12Image> createAttachment(const RenderTarget& target, const Size2d& size, MultiSamplingLevel samples = MultiSamplingLevel::x1) const override;

/// <inheritdoc />
UniquePtr<IDirectX12Image> createAttachment(const String& name, Format format, const Size2d& size, MultiSamplingLevel samples = MultiSamplingLevel::x1) const override;
UniquePtr<IDirectX12Image> createAttachment(const String& name, const RenderTarget& target, const Size2d& size, MultiSamplingLevel samples = MultiSamplingLevel::x1) const override;

/// <inheritdoc />
UniquePtr<IDirectX12Image> createTexture(Format format, const Size3d& size, ImageDimensions dimension = ImageDimensions::DIM_2, UInt32 levels = 1, UInt32 layers = 1, MultiSamplingLevel samples = MultiSamplingLevel::x1, bool allowWrite = false) const override;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ namespace LiteFX::Rendering::Backends {
/// <param name="result">The error code returned by the operation.</param>
/// <param name="message">The error message.</param>
explicit DX12PlatformException(HRESULT result, StringView message) noexcept :
m_code(result), m_error(result), RuntimeException("{2} {1} (HRESULT 0x{0:08X})", message, static_cast<unsigned>(result), m_error.ErrorMessage()) { }
m_code(result), m_error(result), RuntimeException("{2} {1} (HRESULT 0x{0:08X})", static_cast<unsigned>(result), m_error.ErrorMessage(), message) { }

/// <summary>
/// Initializes a new exception.
Expand Down
6 changes: 5 additions & 1 deletion src/Backends/DirectX12/shaders/blit.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@ float3 applySRGB(float3 x)
{
// See: https://github.com/Microsoft/DirectX-Graphics-Samples/blob/master/MiniEngine/Core/Shaders/GenerateMipsCS.hlsli#L55
//return x < 0.0031308 ? 12.92 * x : 1.055 * pow(abs(x), 1.0 / 2.4) - 0.055;
return x < 0.0031308 ? 12.92 * x : 1.13005 * sqrt(abs(x - 0.00228)) - 0.13448 * x + 0.005719;
return float3(
x.r < 0.0031308 ? 12.92 * x.r : 1.13005 * sqrt(abs(x.r - 0.00228)) - 0.13448 * x.r + 0.005719,
x.g < 0.0031308 ? 12.92 * x.g : 1.13005 * sqrt(abs(x.g - 0.00228)) - 0.13448 * x.g + 0.005719,
x.b < 0.0031308 ? 12.92 * x.b : 1.13005 * sqrt(abs(x.b - 0.00228)) - 0.13448 * x.b + 0.005719
);
}

float4 packColor(float4 color)
Expand Down
4 changes: 2 additions & 2 deletions src/Backends/DirectX12/src/buffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ UniquePtr<IDirectX12VertexBuffer> DirectX12VertexBuffer::allocate(const DirectX1
UniquePtr<IDirectX12VertexBuffer> DirectX12VertexBuffer::allocate(const String& name, const DirectX12VertexBufferLayout& layout, AllocatorPtr allocator, UInt32 elements, const D3D12_RESOURCE_DESC1& resourceDesc, const D3D12MA::ALLOCATION_DESC& allocationDesc)
{
if (allocator == nullptr) [[unlikely]]
throw ArgumentNotInitializedException("The allocator must be initialized.");
throw ArgumentNotInitializedException("allocator", "The allocator must be initialized.");

ComPtr<ID3D12Resource> resource;
D3D12MA::Allocation* allocation;
Expand Down Expand Up @@ -294,7 +294,7 @@ UniquePtr<IDirectX12IndexBuffer> DirectX12IndexBuffer::allocate(const DirectX12I
UniquePtr<IDirectX12IndexBuffer> DirectX12IndexBuffer::allocate(const String& name, const DirectX12IndexBufferLayout& layout, AllocatorPtr allocator, UInt32 elements, const D3D12_RESOURCE_DESC1& resourceDesc, const D3D12MA::ALLOCATION_DESC& allocationDesc)
{
if (allocator == nullptr) [[unlikely]]
throw ArgumentNotInitializedException("The allocator must be initialized.");
throw ArgumentNotInitializedException("allocator", "The allocator must be initialized.");

ComPtr<ID3D12Resource> resource;
D3D12MA::Allocation* allocation;
Expand Down
6 changes: 1 addition & 5 deletions src/Backends/DirectX12/src/command_buffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -281,13 +281,9 @@ void DirectX12CommandBuffer::transfer(IDirectX12Image& source, IDirectX12Image&
if (target.elements() < targetSubresource + subresources) [[unlikely]]
throw ArgumentOutOfRangeException("targetElement", "The target image has only {0} sub-resources, but a transfer for {1} sub-resources starting from sub-resources {2} has been requested.", target.elements(), subresources, targetSubresource);

D3D12_PLACED_SUBRESOURCE_FOOTPRINT footprint;
const auto& targetDesc = std::as_const(target).handle()->GetDesc();

for (int sr(0); sr < subresources; ++sr)
{
m_impl->m_queue.device().handle()->GetCopyableFootprints(&targetDesc, sourceSubresource + sr, 1, 0, &footprint, nullptr, nullptr, nullptr);
CD3DX12_TEXTURE_COPY_LOCATION sourceLocation(std::as_const(source).handle().Get(), footprint), targetLocation(std::as_const(target).handle().Get(), targetSubresource + sr);
CD3DX12_TEXTURE_COPY_LOCATION sourceLocation(std::as_const(source).handle().Get(), sourceSubresource + sr), targetLocation(std::as_const(target).handle().Get(), targetSubresource + sr);
this->handle()->CopyTextureRegion(&targetLocation, 0, 0, 0, &sourceLocation, nullptr);
}
}
Expand Down
26 changes: 21 additions & 5 deletions src/Backends/DirectX12/src/descriptor_set.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -319,15 +319,31 @@ void DirectX12DescriptorSet::update(UInt32 binding, const IDirectX12Image& textu

break;
case ImageDimensions::DIM_2:
if (texture.layers() == 1)
if (texture.samples() == MultiSamplingLevel::x1)
{
textureView.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2D;
textureView.Texture2D = { .MipSlice = firstLevel, .PlaneSlice = 0 };
if (texture.layers() == 1)
{
textureView.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2D;
textureView.Texture2D = { .MipSlice = firstLevel, .PlaneSlice = 0 };
}
else
{
textureView.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2DARRAY;
textureView.Texture2DArray = { .MipSlice = firstLevel, .FirstArraySlice = firstLayer, .ArraySize = numLayers, .PlaneSlice = 0 };
}
}
else
{
textureView.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2DARRAY;
textureView.Texture2DArray = { .MipSlice = firstLevel, .FirstArraySlice = firstLayer, .ArraySize = numLayers, .PlaneSlice = 0 };
if (texture.layers() == 1)
{
textureView.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2DMS;
textureView.Texture2D = { .MipSlice = firstLevel, .PlaneSlice = 0 };
}
else
{
textureView.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2DMSARRAY;
textureView.Texture2DArray = { .MipSlice = firstLevel, .FirstArraySlice = firstLayer, .ArraySize = numLayers, .PlaneSlice = 0 };
}
}

break;
Expand Down
4 changes: 2 additions & 2 deletions src/Backends/DirectX12/src/device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,8 @@ class DirectX12Device::DirectX12DeviceImpl : public Implement<DirectX12Device> {
{
infoQueue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_CORRUPTION, TRUE);
infoQueue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_ERROR, TRUE);
infoQueue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_WARNING, TRUE);
//infoQueue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_INFO, TRUE);
infoQueue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_WARNING, FALSE);
infoQueue->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_INFO, FALSE);

// Suppress individual messages by their ID
D3D12_MESSAGE_ID suppressIds[] = {
Expand Down
Loading

0 comments on commit d2380ee

Please sign in to comment.