diff --git a/CMakeLists.txt b/CMakeLists.txt index 54e5b9fa2..a8e02d13b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -122,7 +122,7 @@ endif() # add_subdirectory(thirdparty) add_subdirectory(resources) -add_subdirectory(graphics) +add_subdirectory(Graphics) add_subdirectory(audio) add_subdirectory(src) diff --git a/graphics/CMakeLists.txt b/Graphics/CMakeLists.txt similarity index 77% rename from graphics/CMakeLists.txt rename to Graphics/CMakeLists.txt index 4cc03efe2..08a0b0d0e 100644 --- a/graphics/CMakeLists.txt +++ b/Graphics/CMakeLists.txt @@ -1,25 +1,22 @@ add_library(NovelRT-Graphics STATIC - GraphicsMemoryBlock.cpp - GraphicsMemoryBlockCollection.cpp - GraphicsPipeline.cpp GraphicsPipelineInput.cpp GraphicsPipelineInputElement.cpp GraphicsPipelineResource.cpp - GraphicsPipelineSignature.cpp - GraphicsResourceManager.cpp - ShaderProgram.cpp Vulkan/VulkanGraphicsAdapter.cpp Vulkan/VulkanGraphicsAdapterSelector.cpp + Vulkan/VulkanGraphicsBackendTraits.cpp Vulkan/VulkanGraphicsBuffer.cpp + Vulkan/VulkanGraphicsCmdList.cpp Vulkan/VulkanGraphicsContext.cpp + Vulkan/VulkanGraphicsDescriptorSet.cpp Vulkan/VulkanGraphicsDevice.cpp Vulkan/VulkanGraphicsFence.cpp Vulkan/VulkanGraphicsMemoryAllocator.cpp - Vulkan/VulkanGraphicsMemoryBlock.cpp - Vulkan/VulkanGraphicsMemoryBlockCollection.cpp Vulkan/VulkanGraphicsPipeline.cpp Vulkan/VulkanGraphicsPipelineSignature.cpp Vulkan/VulkanGraphicsPluginProvider.cpp + Vulkan/VulkanGraphicsResource.cpp + Vulkan/VulkanGraphicsResourceMemoryRegion.cpp Vulkan/VulkanGraphicsProvider.cpp Vulkan/VulkanGraphicsSurfaceContext.cpp Vulkan/VulkanGraphicsTexture.cpp @@ -32,20 +29,19 @@ target_sources(NovelRT-Graphics TYPE HEADERS BASE_DIRS include FILES - include/NovelRT/Graphics/Graphics.hpp include/NovelRT/Graphics/GraphicsAdapter.hpp + include/NovelRT/Graphics/GraphicsBackendTraits.hpp include/NovelRT/Graphics/GraphicsBuffer.hpp + include/NovelRT/Graphics/GraphicsCmdList.hpp + include/NovelRT/Graphics/GraphicsBufferCreateInfo.hpp include/NovelRT/Graphics/GraphicsBufferKind.hpp + include/NovelRT/Graphics/GraphicsCmdList.hpp include/NovelRT/Graphics/GraphicsContext.hpp + include/NovelRT/Graphics/GraphicsDescriptorSet.hpp include/NovelRT/Graphics/GraphicsDevice.hpp include/NovelRT/Graphics/GraphicsDeviceObject.hpp include/NovelRT/Graphics/GraphicsFence.hpp include/NovelRT/Graphics/GraphicsMemoryAllocator.hpp - include/NovelRT/Graphics/GraphicsMemoryAllocatorSettings.hpp - include/NovelRT/Graphics/GraphicsMemoryBlock.hpp - include/NovelRT/Graphics/GraphicsMemoryBlockCollection.hpp - include/NovelRT/Graphics/GraphicsMemoryBudget.hpp - include/NovelRT/Graphics/GraphicsMemoryRegion.hpp include/NovelRT/Graphics/GraphicsMemoryRegionAllocationFlags.hpp include/NovelRT/Graphics/GraphicsPipeline.hpp include/NovelRT/Graphics/GraphicsPipelineBlendFactor.hpp @@ -55,52 +51,45 @@ target_sources(NovelRT-Graphics include/NovelRT/Graphics/GraphicsPipelineResource.hpp include/NovelRT/Graphics/GraphicsPipelineResourceKind.hpp include/NovelRT/Graphics/GraphicsPipelineSignature.hpp - include/NovelRT/Graphics/GraphicsPrimitive.hpp include/NovelRT/Graphics/GraphicsProvider.hpp include/NovelRT/Graphics/GraphicsResource.hpp + include/NovelRT/Graphics/GraphicsResourceMemoryRegion.hpp include/NovelRT/Graphics/GraphicsResourceAccess.hpp - include/NovelRT/Graphics/GraphicsResourceManager.hpp include/NovelRT/Graphics/GraphicsSurfaceContext.hpp include/NovelRT/Graphics/GraphicsSurfaceKind.hpp include/NovelRT/Graphics/GraphicsTexture.hpp include/NovelRT/Graphics/GraphicsTextureAddressMode.hpp + include/NovelRT/Graphics/GraphicsTextureAddressMode.hpp include/NovelRT/Graphics/GraphicsTextureKind.hpp include/NovelRT/Graphics/IGraphicsAdapterSelector.hpp - include/NovelRT/Graphics/IGraphicsMemoryRegionCollection.hpp include/NovelRT/Graphics/IGraphicsSurface.hpp include/NovelRT/Graphics/RGBAColour.hpp include/NovelRT/Graphics/ShaderProgram.hpp include/NovelRT/Graphics/ShaderProgramKind.hpp include/NovelRT/Graphics/ShaderProgramVisibility.hpp include/NovelRT/Graphics/TexelFormat.hpp - include/NovelRT/Graphics/D3D12/Graphics.D3D12.hpp - include/NovelRT/Graphics/D3D12/Utilities/Graphics.D3D12.Utilities.hpp include/NovelRT/Graphics/D3D12/Utilities/PipelineBlendFactor.hpp - include/NovelRT/Graphics/Metal/Graphics.Metal.hpp - include/NovelRT/Graphics/Metal/Utilities/Graphics.Metal.Utilities.hpp include/NovelRT/Graphics/Metal/Utilities/PipelineBlendFactor.hpp - include/NovelRT/Graphics/Vulkan/Graphics.Vulkan.hpp include/NovelRT/Graphics/Vulkan/QueueFamilyIndices.hpp include/NovelRT/Graphics/Vulkan/SwapChainSupportDetails.hpp include/NovelRT/Graphics/Vulkan/VulkanGraphicsAdapter.hpp include/NovelRT/Graphics/Vulkan/VulkanGraphicsAdapterSelector.hpp include/NovelRT/Graphics/Vulkan/VulkanGraphicsBuffer.hpp + include/NovelRT/Graphics/Vulkan/VulkanGraphicsCmdList.hpp include/NovelRT/Graphics/Vulkan/VulkanGraphicsContext.hpp + include/NovelRT/Graphics/Vulkan/VulkanGraphicsDescriptorSet.hpp include/NovelRT/Graphics/Vulkan/VulkanGraphicsDevice.hpp include/NovelRT/Graphics/Vulkan/VulkanGraphicsFence.hpp include/NovelRT/Graphics/Vulkan/VulkanGraphicsMemoryAllocator.hpp - include/NovelRT/Graphics/Vulkan/VulkanGraphicsMemoryBlock.hpp - include/NovelRT/Graphics/Vulkan/VulkanGraphicsMemoryBlockCollection.hpp include/NovelRT/Graphics/Vulkan/VulkanGraphicsPipeline.hpp include/NovelRT/Graphics/Vulkan/VulkanGraphicsPipelineSignature.hpp - include/NovelRT/Graphics/Vulkan/VulkanGraphicsPluginProvider.hpp - include/NovelRT/Graphics/Vulkan/VulkanGraphicsPrimitive.hpp include/NovelRT/Graphics/Vulkan/VulkanGraphicsProvider.hpp + include/NovelRT/Graphics/Vulkan/VulkanGraphicsResource.hpp + include/NovelRT/Graphics/Vulkan/VulkanGraphicsResourceMemoryRegion.hpp include/NovelRT/Graphics/Vulkan/VulkanGraphicsSurfaceContext.hpp include/NovelRT/Graphics/Vulkan/VulkanGraphicsTexture.hpp include/NovelRT/Graphics/Vulkan/VulkanShaderProgram.hpp include/NovelRT/Graphics/Vulkan/Utilities/BufferUsageKind.hpp - include/NovelRT/Graphics/Vulkan/Utilities/Graphics.Vulkan.Utilities.hpp include/NovelRT/Graphics/Vulkan/Utilities/PipelineBlendFactor.hpp include/NovelRT/Graphics/Vulkan/Utilities/Support.hpp include/NovelRT/Graphics/Vulkan/Utilities/Texel.hpp @@ -152,4 +141,4 @@ install( EXPORT NovelRTConfig LIBRARY DESTINATION lib FILE_SET public_headers DESTINATION include -) \ No newline at end of file +) diff --git a/graphics/GraphicsPipelineInput.cpp b/Graphics/GraphicsPipelineInput.cpp similarity index 87% rename from graphics/GraphicsPipelineInput.cpp rename to Graphics/GraphicsPipelineInput.cpp index 89192ed79..0524fce2b 100644 --- a/graphics/GraphicsPipelineInput.cpp +++ b/Graphics/GraphicsPipelineInput.cpp @@ -1,7 +1,8 @@ // Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root // for more information. -#include +#include +#include namespace NovelRT::Graphics { diff --git a/graphics/GraphicsPipelineInputElement.cpp b/Graphics/GraphicsPipelineInputElement.cpp similarity index 93% rename from graphics/GraphicsPipelineInputElement.cpp rename to Graphics/GraphicsPipelineInputElement.cpp index d223547b2..67fe8aa41 100644 --- a/graphics/GraphicsPipelineInputElement.cpp +++ b/Graphics/GraphicsPipelineInputElement.cpp @@ -1,7 +1,7 @@ // Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root // for more information. -#include +#include namespace NovelRT::Graphics { diff --git a/graphics/GraphicsPipelineResource.cpp b/Graphics/GraphicsPipelineResource.cpp similarity index 73% rename from graphics/GraphicsPipelineResource.cpp rename to Graphics/GraphicsPipelineResource.cpp index 418a78bc6..0ad46013f 100644 --- a/graphics/GraphicsPipelineResource.cpp +++ b/Graphics/GraphicsPipelineResource.cpp @@ -1,12 +1,12 @@ // Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root // for more information. -#include +#include namespace NovelRT::Graphics { - GraphicsPipelineResourceKind Graphics::GraphicsPipelineResource::GetKind() const noexcept + GraphicsPipelineResourceKind GraphicsPipelineResource::GetKind() const noexcept { return _kind; } diff --git a/graphics/Vulkan/VulkanGraphicsAdapter.cpp b/Graphics/Vulkan/VulkanGraphicsAdapter.cpp similarity index 76% rename from graphics/Vulkan/VulkanGraphicsAdapter.cpp rename to Graphics/Vulkan/VulkanGraphicsAdapter.cpp index a3f93afe5..bf74685ed 100644 --- a/graphics/Vulkan/VulkanGraphicsAdapter.cpp +++ b/Graphics/Vulkan/VulkanGraphicsAdapter.cpp @@ -1,7 +1,9 @@ // Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root // for more information. -#include +#include +#include +#include namespace NovelRT::Graphics::Vulkan { @@ -24,24 +26,22 @@ namespace NovelRT::Graphics::Vulkan return physicalDeviceMemoryProperties; } - VulkanGraphicsAdapter::VulkanGraphicsAdapter(const std::shared_ptr& provider, + VulkanGraphicsAdapter::VulkanGraphicsAdapter(std::shared_ptr provider, VkPhysicalDevice physicalDevice) - : GraphicsAdapter(provider->weak_from_this()), + : _provider(provider->weak_from_this()), _vulkanPhysicalDevice(physicalDevice), _vulkanPhysicalDeviceProperties([&]() { return GetVulkanPhysicalDevicePropertiesInternal(); }), _vulkanPhysicalDeviceMemoryProperties([&]() { return GetVulkanPhysicalDeviceMemoryPropertiesInternal(); }), - _name([&]() { return GetNameInternal(); }), - _state() + _name([&]() { return GetNameInternal(); }) { - static_cast(_state.Transition(Threading::VolatileState::Initialised)); } - std::shared_ptr VulkanGraphicsAdapter::CreateVulkanGraphicsDevice( + std::shared_ptr VulkanGraphicsAdapter::CreateDevice( std::shared_ptr surfaceContext, int32_t contextCount) { return std::make_shared( - std::dynamic_pointer_cast(shared_from_this()), std::move(surfaceContext), + shared_from_this(), surfaceContext, contextCount); } } // namespace NovelRT::Graphics::Vulkan diff --git a/graphics/Vulkan/VulkanGraphicsAdapterSelector.cpp b/Graphics/Vulkan/VulkanGraphicsAdapterSelector.cpp similarity index 86% rename from graphics/Vulkan/VulkanGraphicsAdapterSelector.cpp rename to Graphics/Vulkan/VulkanGraphicsAdapterSelector.cpp index c850927a2..88b785a19 100644 --- a/graphics/Vulkan/VulkanGraphicsAdapterSelector.cpp +++ b/Graphics/Vulkan/VulkanGraphicsAdapterSelector.cpp @@ -1,7 +1,18 @@ // Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root // for more information. -#include +// TODO: clean this up good grief +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include namespace NovelRT::Graphics::Vulkan { @@ -85,18 +96,9 @@ namespace NovelRT::Graphics::Vulkan return requiredExtensionSet.empty(); } - std::shared_ptr VulkanGraphicsAdapterSelector::GetDefaultRecommendedAdapter( - const std::shared_ptr& provider, - const std::shared_ptr& surfaceContext) const - { - return std::static_pointer_cast(GetDefaultRecommendedAdapterVulkan( - std::dynamic_pointer_cast(provider), - std::dynamic_pointer_cast(surfaceContext))); - } - - std::shared_ptr VulkanGraphicsAdapterSelector::GetDefaultRecommendedAdapterVulkan( - const std::shared_ptr& provider, - const std::shared_ptr& surfaceContext) const + std::shared_ptr VulkanGraphicsAdapterSelector::GetDefaultRecommendedAdapter( + std::shared_ptr provider, + std::shared_ptr surfaceContext) const { std::shared_ptr surfaceContextVulkan = std::dynamic_pointer_cast(surfaceContext); diff --git a/Graphics/Vulkan/VulkanGraphicsBackendTraits.cpp b/Graphics/Vulkan/VulkanGraphicsBackendTraits.cpp new file mode 100644 index 000000000..9817a299d --- /dev/null +++ b/Graphics/Vulkan/VulkanGraphicsBackendTraits.cpp @@ -0,0 +1,14 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//template class NovelRT::Graphics::GraphicsProvider; +//template class NovelRT::Graphics::GraphicsAdapter; +//template class NovelRT::Graphics::GraphicsSurfaceContext; diff --git a/Graphics/Vulkan/VulkanGraphicsBuffer.cpp b/Graphics/Vulkan/VulkanGraphicsBuffer.cpp new file mode 100644 index 000000000..2c29208c2 --- /dev/null +++ b/Graphics/Vulkan/VulkanGraphicsBuffer.cpp @@ -0,0 +1,141 @@ +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#include +#include +#include +#include + +namespace NovelRT::Graphics::Vulkan +{ + std::shared_ptr VulkanGraphicsBuffer::AllocateInternal( + VmaVirtualAllocation allocation, + VkDeviceSize offset) + { + unused(offset); // TODO: figure out if we need offset + + VmaVirtualAllocationInfo allocInfo{}; + vmaGetVirtualAllocationInfo(GetVirtualBlock(), allocation, &allocInfo); + return std::make_shared>(GetDevice(), shared_from_this(), allocation, allocInfo); + } + + VulkanGraphicsBuffer::VulkanGraphicsBuffer(std::shared_ptr graphicsDevice, + std::shared_ptr allocator, + GraphicsResourceAccess cpuAccess, + GraphicsBufferKind kind, + VmaAllocation allocation, + VmaAllocationInfo allocationInfo, + size_t subAllocations, + VkBuffer vulkanBuffer) + : VulkanGraphicsResource(graphicsDevice, allocator, cpuAccess, allocation, allocationInfo), + _vulkanBuffer(vulkanBuffer), + _subAllocations(subAllocations), + _cpuAccess(cpuAccess), + _kind(kind) + {} + + VulkanGraphicsBuffer::~VulkanGraphicsBuffer() noexcept + { + auto allocator = GetAllocator()->GetVmaAllocator(); + auto allocation = GetAllocation(); + + assert_message("Attempted to destroy a VkBuffer containing mapped regions.", _subAllocations != 0); + + vmaDestroyBuffer(allocator, GetVulkanBuffer(), allocation); + } + + Utilities::Misc::Span VulkanGraphicsBuffer::MapBytes(size_t rangeOffset, size_t rangeLength) + { + size_t sizeOfBuffer = GetAllocationInfo().size; + size_t rangeValidationValue = sizeOfBuffer - rangeOffset; + + if (rangeValidationValue < rangeLength) + { + throw Exceptions::InvalidOperationException( + "Attempted to map a subrange of a VkBuffer that exceeded the VkBuffer's size."); + } + + void* data = nullptr; + VkResult result = + vmaMapMemory(GetAllocator()->GetVmaAllocator(), GetAllocation(), &data); + + if (result != VK_SUCCESS) + { + // TODO: Make this a real exception + throw std::runtime_error("Failed to map Vulkan memory to the CPU. Reason: " + std::to_string(result)); + } + + _subAllocations++; + + return Utilities::Misc::Span(reinterpret_cast(data) + rangeOffset, rangeLength); + } + + Utilities::Misc::Span VulkanGraphicsBuffer::MapBytesForRead(size_t rangeOffset, size_t rangeLength) + { + size_t sizeOfBuffer = GetAllocationInfo().size; + size_t rangeValidationValue = sizeOfBuffer - rangeOffset; + + if (rangeValidationValue < rangeLength) + { + throw Exceptions::InvalidOperationException( + "Attempted to map a subrange of a VkBuffer that exceeded the VkBuffer's size."); + } + + VmaAllocator allocator = GetAllocator()->GetVmaAllocator(); + VmaAllocation allocation = GetAllocation(); + + void* data = nullptr; + VkResult mapResult = vmaMapMemory(allocator, allocation, &data); + + if (mapResult != VK_SUCCESS) + { + // TODO: Make this a real exception + throw std::runtime_error("Failed to map Vulkan memory to the CPU. Reason: " + std::to_string(mapResult)); + } + + VkResult invalidateResult = vmaInvalidateAllocation(allocator, allocation, rangeOffset, rangeLength); + + if (invalidateResult != VK_SUCCESS) + { + // TODO: Make this a real exception + throw std::runtime_error("Failed to invalidate mapped memory. Reason: " + std::to_string(mapResult)); + } + + return Utilities::Misc::Span(reinterpret_cast(data), rangeLength); + } + + void VulkanGraphicsBuffer::UnmapBytes() + { + vmaUnmapMemory(GetAllocator()->GetVmaAllocator(), GetAllocation()); + } + + void VulkanGraphicsBuffer::UnmapBytesAndWrite(size_t writtenRangeOffset, size_t writtenRangeLength) + { + size_t sizeOfBuffer = GetAllocationInfo().size; + size_t rangeValidationValue = sizeOfBuffer - writtenRangeOffset; + + if (rangeValidationValue < writtenRangeLength) + { + throw Exceptions::InvalidOperationException( + "Attempted to write a subrange of a VkBuffer that exceeded the VkBuffer's size."); + } + + auto allocator = GetAllocator()->GetVmaAllocator(); + auto allocation = GetAllocation(); + + VkResult result = vmaFlushAllocation(allocator, allocation, writtenRangeOffset, writtenRangeLength); + + if (result != VK_SUCCESS) + { + throw std::runtime_error("Failed to write VkBuffer subrange to GPU memory. Reason: " + + std::to_string(result)); + } + + vmaUnmapMemory(allocator, allocation); + } + + VkBuffer VulkanGraphicsBuffer::GetVulkanBuffer() const noexcept + { + return _vulkanBuffer; + } +} \ No newline at end of file diff --git a/Graphics/Vulkan/VulkanGraphicsCmdList.cpp b/Graphics/Vulkan/VulkanGraphicsCmdList.cpp new file mode 100644 index 000000000..78e7c83c6 --- /dev/null +++ b/Graphics/Vulkan/VulkanGraphicsCmdList.cpp @@ -0,0 +1,12 @@ +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#include +#include +#include +#include + +namespace NovelRT::Graphics::Vulkan +{ + +} \ No newline at end of file diff --git a/graphics/Vulkan/VulkanGraphicsContext.cpp b/Graphics/Vulkan/VulkanGraphicsContext.cpp similarity index 54% rename from graphics/Vulkan/VulkanGraphicsContext.cpp rename to Graphics/Vulkan/VulkanGraphicsContext.cpp index 441f09605..b9f811f04 100644 --- a/graphics/Vulkan/VulkanGraphicsContext.cpp +++ b/Graphics/Vulkan/VulkanGraphicsContext.cpp @@ -1,7 +1,9 @@ // Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root // for more information. -#include +#include +#include +#include namespace NovelRT::Graphics::Vulkan { @@ -175,48 +177,49 @@ namespace NovelRT::Graphics::Vulkan } } - void VulkanGraphicsContext::BeginCopy(VkImage vulkanImage) noexcept - { - VkImageSubresourceRange subresourceRange{}; - subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - subresourceRange.levelCount = 1; - subresourceRange.layerCount = 1; - - VkImageMemoryBarrier vulkanImageMemoryBarrier{}; - vulkanImageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; - vulkanImageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - vulkanImageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; - vulkanImageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - vulkanImageMemoryBarrier.subresourceRange = subresourceRange; - vulkanImageMemoryBarrier.image = vulkanImage; - - vkCmdPipelineBarrier(GetVulkanCommandBuffer(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, - nullptr, 0, nullptr, 1, &vulkanImageMemoryBarrier); - } - - void VulkanGraphicsContext::EndCopy(VkImage vulkanImage) noexcept - { - VkImageSubresourceRange subresourceRange{}; - subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - subresourceRange.levelCount = 1; - subresourceRange.layerCount = 1; - - VkImageMemoryBarrier vulkanImageMemoryBarrier{}; - vulkanImageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; - vulkanImageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - vulkanImageMemoryBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; - vulkanImageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - vulkanImageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - vulkanImageMemoryBarrier.subresourceRange = subresourceRange; - vulkanImageMemoryBarrier.image = vulkanImage; - - vkCmdPipelineBarrier(GetVulkanCommandBuffer(), VK_PIPELINE_STAGE_TRANSFER_BIT, - VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, - &vulkanImageMemoryBarrier); - } + // void VulkanGraphicsContext::BeginCopy(VkImage vulkanImage) noexcept + //{ + // VkImageSubresourceRange subresourceRange{}; + // subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + // subresourceRange.levelCount = 1; + // subresourceRange.layerCount = 1; + + // VkImageMemoryBarrier vulkanImageMemoryBarrier{}; + // vulkanImageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + // vulkanImageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + // vulkanImageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; + // vulkanImageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + // vulkanImageMemoryBarrier.subresourceRange = subresourceRange; + // vulkanImageMemoryBarrier.image = vulkanImage; + + // vkCmdPipelineBarrier(GetVulkanCommandBuffer(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, + // nullptr, 0, nullptr, 1, &vulkanImageMemoryBarrier); + //} + + // void VulkanGraphicsContext::EndCopy(VkImage vulkanImage) noexcept + //{ + // VkImageSubresourceRange subresourceRange{}; + // subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + // subresourceRange.levelCount = 1; + // subresourceRange.layerCount = 1; + + // VkImageMemoryBarrier vulkanImageMemoryBarrier{}; + // vulkanImageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + // vulkanImageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + // vulkanImageMemoryBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; + // vulkanImageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + // vulkanImageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + // vulkanImageMemoryBarrier.subresourceRange = subresourceRange; + // vulkanImageMemoryBarrier.image = vulkanImage; + + // vkCmdPipelineBarrier(GetVulkanCommandBuffer(), VK_PIPELINE_STAGE_TRANSFER_BIT, + // VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, + //&vulkanImageMemoryBarrier); + //} VulkanGraphicsContext::VulkanGraphicsContext(std::shared_ptr device, size_t index) noexcept - : GraphicsContext(std::move(device), index), + : _device(device), + _index(index), _fence(std::make_shared(GetDevice(), /* isSignaled*/ true)), _waitForExecuteCompletionFence(std::make_shared(GetDevice(), /* isSignaled*/ false)), _vulkanCommandBuffer([&]() { return CreateVulkanCommandBuffer(); }), @@ -278,7 +281,7 @@ namespace NovelRT::Graphics::Vulkan void VulkanGraphicsContext::BeginFrame() { - std::shared_ptr fence = GetVulkanFence(); + std::shared_ptr fence = GetFence(); fence->Wait(); fence->Reset(); @@ -294,185 +297,6 @@ namespace NovelRT::Graphics::Vulkan } } - void VulkanGraphicsContext::Copy(std::shared_ptr destination, - std::shared_ptr source) - { - if (destination == nullptr) - { - throw Exceptions::NullPointerException("The destination graphics buffer is null."); - } - - if (source == nullptr) - { - throw Exceptions::NullPointerException("The source graphics buffer is null."); - } - VkBufferCopy vulkanBufferCopy{}; - vulkanBufferCopy.srcOffset = 0; - vulkanBufferCopy.dstOffset = 0; - vulkanBufferCopy.size = std::min(destination->GetSize(), source->GetSize()); - vkCmdCopyBuffer(GetVulkanCommandBuffer(), source->GetVulkanBuffer(), destination->GetVulkanBuffer(), 1, - &vulkanBufferCopy); - } - - void VulkanGraphicsContext::Copy(std::shared_ptr destination, - std::shared_ptr source) - { - if (destination == nullptr) - { - throw Exceptions::NullPointerException("The destination graphics texture is null."); - } - - if (source == nullptr) - { - throw Exceptions::NullPointerException("The source graphics buffer is null."); - } - - VkCommandBuffer vulkanCommandBuffer = GetVulkanCommandBuffer(); - VkImage vulkanImage = destination->GetVulkanImage(); - - BeginCopy(vulkanImage); - - VkImageSubresourceLayers imageSubresourceLayers{}; - imageSubresourceLayers.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - imageSubresourceLayers.layerCount = 1; - - VkExtent3D imageExtent{}; - imageExtent.width = destination->GetWidth(); - imageExtent.height = destination->GetHeight(); - imageExtent.depth = destination->GetDepth(); - - VkBufferImageCopy vulkanBufferImageCopy{}; - vulkanBufferImageCopy.imageSubresource = imageSubresourceLayers; - vulkanBufferImageCopy.imageExtent = imageExtent; - - vkCmdCopyBufferToImage(vulkanCommandBuffer, source->GetVulkanBuffer(), vulkanImage, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &vulkanBufferImageCopy); - - EndCopy(vulkanImage); - } - - void VulkanGraphicsContext::Draw(const std::shared_ptr& primitive, int32_t instanceCount) - { - if (primitive == nullptr) - { - throw Exceptions::NullPointerException("The provided GraphicsPrimitive is null."); - } - - VkCommandBuffer vulkanCommandBuffer = GetVulkanCommandBuffer(); - std::shared_ptr pipeline = primitive->GetPipeline(); - std::shared_ptr pipelineSignature = pipeline->GetSignature(); - VkPipeline vulkanPipeline = pipeline->GetVulkanPipeline(); - - vkCmdBindPipeline(vulkanCommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, vulkanPipeline); - - const GraphicsMemoryRegion& vertexBufferRegion = primitive->GetVertexBufferRegion(); - std::shared_ptr vertexBuffer = - std::static_pointer_cast(vertexBufferRegion.GetCollection()); - VkBuffer vulkanVertexBuffer = vertexBuffer->GetVulkanBuffer(); - size_t vulkanVertexBufferOffset = vertexBufferRegion.GetOffset(); - VkDeviceSize castedVulkanVertexBufferOffset = static_cast(vulkanVertexBufferOffset); - - vkCmdBindVertexBuffers(vulkanCommandBuffer, 0, 1, &vulkanVertexBuffer, &castedVulkanVertexBufferOffset); - - VkDescriptorSet vulkanDescriptorSet = pipelineSignature->GenerateVulkanDescriptorSet(); - - if (vulkanDescriptorSet != VK_NULL_HANDLE) - { - NovelRT::Utilities::Misc::Span> inputResourceRegions = - primitive->GetInputResourceRegions(); - size_t inputResourceRegionsLength = inputResourceRegions.size(); - - for (size_t index = 0; index < inputResourceRegionsLength; index++) - { - const GraphicsMemoryRegion& inputResourceRegion = inputResourceRegions[index]; - - VkWriteDescriptorSet writeDescriptorSet{}; - - std::shared_ptr vulkanGraphicsBuffer = - std::dynamic_pointer_cast(inputResourceRegion.GetCollection()); - std::shared_ptr vulkanGraphicsTexture = - std::dynamic_pointer_cast(inputResourceRegion.GetCollection()); - - if (vulkanGraphicsBuffer != nullptr) - { - VkDescriptorBufferInfo descriptorBufferInfo{}; - descriptorBufferInfo.buffer = vulkanGraphicsBuffer->GetVulkanBuffer(); - descriptorBufferInfo.offset = inputResourceRegion.GetOffset(); - descriptorBufferInfo.range = inputResourceRegion.GetSize(); - - writeDescriptorSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - writeDescriptorSet.dstSet = vulkanDescriptorSet; - writeDescriptorSet.dstBinding = static_cast(index); - writeDescriptorSet.descriptorCount = 1; - writeDescriptorSet.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - writeDescriptorSet.pBufferInfo = &descriptorBufferInfo; - - vkUpdateDescriptorSets(GetDevice()->GetVulkanDevice(), 1, &writeDescriptorSet, 0, nullptr); - } - else if (vulkanGraphicsTexture != nullptr) - { - VkDescriptorImageInfo descriptorImageInfo{}; - descriptorImageInfo.sampler = vulkanGraphicsTexture->GetVulkanSampler(); - descriptorImageInfo.imageView = vulkanGraphicsTexture->GetVulkanImageView(); - descriptorImageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - - writeDescriptorSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - writeDescriptorSet.dstSet = vulkanDescriptorSet; - writeDescriptorSet.dstBinding = static_cast(index); - writeDescriptorSet.descriptorCount = 1; - writeDescriptorSet.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - writeDescriptorSet.pImageInfo = &descriptorImageInfo; - - vkUpdateDescriptorSets(GetDevice()->GetVulkanDevice(), 1, &writeDescriptorSet, 0, nullptr); - } - } - - vkCmdBindDescriptorSets(vulkanCommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, - pipelineSignature->GetVulkanPipelineLayout(), 0, 1, &vulkanDescriptorSet, 0, - nullptr); - - if (_vulkanDescriptorSets.find(pipelineSignature) == _vulkanDescriptorSets.end()) - { - _vulkanDescriptorSets[pipelineSignature] = std::vector{}; - } - - _vulkanDescriptorSets[pipelineSignature].emplace_back(vulkanDescriptorSet); - } - - const GraphicsMemoryRegion& indexBufferRegion = primitive->GetIndexBufferRegion(); - std::shared_ptr indexBuffer = - std::dynamic_pointer_cast(indexBufferRegion.GetCollection()); - - if (indexBuffer != nullptr) - { - uint32_t indexBufferStride = primitive->GetIndexBufferStride(); - VkIndexType indexType = VK_INDEX_TYPE_UINT16; - - if (indexBufferStride != 2) - { - if (indexBufferStride != 4) - { - throw std::out_of_range("An out of range stride value was provided to the index buffer."); - } - - indexType = VK_INDEX_TYPE_UINT32; - } - - vkCmdBindIndexBuffer(vulkanCommandBuffer, indexBuffer->GetVulkanBuffer(), indexBufferRegion.GetOffset(), - indexType); - - vkCmdDrawIndexed(vulkanCommandBuffer, - static_cast(indexBufferRegion.GetSize() / indexBufferStride), instanceCount, 0, - 0, 0); - } - else - { - vkCmdDraw(vulkanCommandBuffer, - static_cast(vertexBufferRegion.GetSize() / primitive->GetVertexBufferStride()), - instanceCount, 0, 0); - } - } - void VulkanGraphicsContext::EndDrawing() { vkCmdEndRenderPass(GetVulkanCommandBuffer()); diff --git a/Graphics/Vulkan/VulkanGraphicsDescriptorSet.cpp b/Graphics/Vulkan/VulkanGraphicsDescriptorSet.cpp new file mode 100644 index 000000000..2a2e19f85 --- /dev/null +++ b/Graphics/Vulkan/VulkanGraphicsDescriptorSet.cpp @@ -0,0 +1,107 @@ +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#include +#include +#include +#include +#include + +namespace NovelRT::Graphics::Vulkan +{ + using namespace NovelRT::Utilities; + + VulkanGraphicsDescriptorSet::VulkanGraphicsDescriptorSet( + std::shared_ptr targetPipeline) noexcept + : _pipeline(targetPipeline), _inputResourceRegions{}, _descriptorSetHandle(VK_NULL_HANDLE) + { + _descriptorSetHandle = _pipeline->GetSignature()->GenerateVulkanDescriptorSet(); + } + + VulkanGraphicsDescriptorSet::~VulkanGraphicsDescriptorSet() + { + std::array fuck = {_descriptorSetHandle}; + _pipeline->GetSignature()->DestroyDescriptorSets(fuck); + } + + VkDescriptorSet VulkanGraphicsDescriptorSet::GetVulkanDescriptorSet() const noexcept + { + return _descriptorSetHandle; + } + + std::shared_ptr VulkanGraphicsDescriptorSet::GetPipeline() const noexcept + { + return _pipeline; + } + + void VulkanGraphicsDescriptorSet::AddMemoryRegionToInputs( + std::shared_ptr> region) + { + _inputResourceRegions.emplace_back(region); + } + + void VulkanGraphicsDescriptorSet::AddMemoryRegionsToInputs( + Misc::Span>> regions) + { + _inputResourceRegions.insert(_inputResourceRegions.end(), regions.begin(), regions.end()); + } + + void VulkanGraphicsDescriptorSet::UpdateDescriptorSetData() + { + if (_descriptorSetHandle != VK_NULL_HANDLE) + { + size_t inputResourcesLength = _inputResourceRegions.size(); + + for (size_t index = 0; index < inputResourcesLength; index++) + { + const auto inputResourceRegion = _inputResourceRegions[index]; + + VkWriteDescriptorSet writeDescriptorSet{}; + + std::shared_ptr buffer = + std::dynamic_pointer_cast(inputResourceRegion->GetOwningResource()); + std::shared_ptr texture = + std::dynamic_pointer_cast(inputResourceRegion->GetOwningResource()); + + if (buffer != nullptr) + { + VkDescriptorBufferInfo descriptorBufferInfo{}; + descriptorBufferInfo.buffer = buffer->GetVulkanBuffer(); + descriptorBufferInfo.offset = inputResourceRegion->GetRelativeOffset(); + descriptorBufferInfo.range = inputResourceRegion->GetSize(); + + writeDescriptorSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + writeDescriptorSet.dstSet = _descriptorSetHandle; + writeDescriptorSet.dstBinding = static_cast(index); + writeDescriptorSet.descriptorCount = 1; + writeDescriptorSet.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + writeDescriptorSet.pBufferInfo = &descriptorBufferInfo; + + vkUpdateDescriptorSets(_pipeline->GetDevice()->GetVulkanDevice(), 1, &writeDescriptorSet, 0, + nullptr); + } + else if (texture != nullptr) + { + VkDescriptorImageInfo descriptorImageInfo{}; + descriptorImageInfo.sampler = texture->GetOrCreateVulkanSampler(); + descriptorImageInfo.imageView = texture->GetOrCreateVulkanImageView(); + descriptorImageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + + writeDescriptorSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + writeDescriptorSet.dstSet = _descriptorSetHandle; + writeDescriptorSet.dstBinding = static_cast(index); + writeDescriptorSet.descriptorCount = 1; + writeDescriptorSet.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + writeDescriptorSet.pImageInfo = &descriptorImageInfo; + + vkUpdateDescriptorSets(_pipeline->GetDevice()->GetVulkanDevice(), 1, &writeDescriptorSet, 0, + nullptr); + } + else + { + throw std::runtime_error("HOW DID YOU EVEN GET HERE?"); + } + } + } + } +} \ No newline at end of file diff --git a/graphics/Vulkan/VulkanGraphicsDevice.cpp b/Graphics/Vulkan/VulkanGraphicsDevice.cpp similarity index 80% rename from graphics/Vulkan/VulkanGraphicsDevice.cpp rename to Graphics/Vulkan/VulkanGraphicsDevice.cpp index 5eb615746..c8fc3fb46 100644 --- a/graphics/Vulkan/VulkanGraphicsDevice.cpp +++ b/Graphics/Vulkan/VulkanGraphicsDevice.cpp @@ -1,18 +1,23 @@ // Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root // for more information. -#include +#include +#include +#include +#include +#include +#include +#include namespace NovelRT::Graphics::Vulkan { - VulkanGraphicsDevice::VulkanGraphicsDevice(const std::shared_ptr& adapter, - const std::shared_ptr& surfaceContext, + VulkanGraphicsDevice::VulkanGraphicsDevice(std::shared_ptr adapter, + std::shared_ptr surfaceContext, int32_t contextCount) - : GraphicsDevice(adapter, std::static_pointer_cast(surfaceContext)), - _presentCompletionFence([&]() { - return std::make_shared( - std::dynamic_pointer_cast(shared_from_this()), /* isSignaled*/ false); - }), + : _adapter(adapter), + _surfaceContext(surfaceContext), + _presentCompletionFence( + [&]() { return std::make_shared(shared_from_this(), /* isSignaled*/ false); }), _contextCount(contextCount), _contexts([&]() { return CreateGraphicsContexts(_contextCount); }), _contextPtrs([&]() { return CreateGraphicsContextPointers(); }), @@ -28,24 +33,23 @@ namespace NovelRT::Graphics::Vulkan _vulkanSwapchain([&]() { return CreateSwapChain(); }), _swapChainImages([&]() { return GetSwapChainImages(); }), _renderPass([&]() { return CreateRenderPass(); }), - _memoryAllocator([&]() { return CreateMemoryAllocator(); }), _indicesData{}, _state() { _logger.logInfoLine("Provided GPU device: " + GetAdapter()->GetName()); - static_cast(_state.Transition(Threading::VolatileState::Initialised)); + unused(_state.Transition(Threading::VolatileState::Initialised)); auto countFfs = GetSurface()->SizeChanged.getHandlerCount(); unused(countFfs); } - std::vector> VulkanGraphicsDevice::CreateGraphicsContextPointers() + std::vector> VulkanGraphicsDevice::CreateGraphicsContextPointers() { - std::vector> ptrs{}; + std::vector> ptrs{}; ptrs.reserve(_contexts.getActual().size()); for (auto&& context : _contexts.getActual()) { - ptrs.emplace_back(std::dynamic_pointer_cast(context->shared_from_this())); + ptrs.emplace_back(context->shared_from_this()); } return ptrs; @@ -58,20 +62,12 @@ namespace NovelRT::Graphics::Vulkan for (uint32_t i = 0; i < contextCount; i++) { - contexts[i] = std::make_shared( - std::dynamic_pointer_cast(shared_from_this()), i); + contexts[i] = std::make_shared(shared_from_this(), i); } return contexts; } - std::shared_ptr VulkanGraphicsDevice::CreateMemoryAllocator() - { - GraphicsMemoryAllocatorSettings allocatorSettings{}; - return std::make_shared( - std::dynamic_pointer_cast(shared_from_this()), allocatorSettings); - } - std::vector VulkanGraphicsDevice::GetFinalPhysicalDeviceExtensionSet() const { uint32_t extensionCount = 0; @@ -91,9 +87,9 @@ namespace NovelRT::Graphics::Vulkan for (auto&& requestedRequiredExt : EngineConfig::RequiredVulkanPhysicalDeviceExtensions()) { - auto result = std::find_if(extensionProperties.begin(), extensionProperties.end(), [&](auto& x) { - return strcmp(requestedRequiredExt.c_str(), x.extensionName) == 0; - }); + auto result = + std::find_if(extensionProperties.begin(), extensionProperties.end(), + [&](auto& x) { return strcmp(requestedRequiredExt.c_str(), x.extensionName) == 0; }); if (result == extensionProperties.end()) { @@ -106,9 +102,9 @@ namespace NovelRT::Graphics::Vulkan for (auto&& requestedOptionalExt : EngineConfig::OptionalVulkanPhysicalDeviceExtensions()) { - auto result = std::find_if(extensionProperties.begin(), extensionProperties.end(), [&](auto& x) { - return strcmp(requestedOptionalExt.c_str(), x.extensionName) == 0; - }); + auto result = + std::find_if(extensionProperties.begin(), extensionProperties.end(), + [&](auto& x) { return strcmp(requestedOptionalExt.c_str(), x.extensionName) == 0; }); if (result == extensionProperties.end()) { @@ -382,14 +378,12 @@ namespace NovelRT::Graphics::Vulkan _logger.logInfoLine("Vulkan logical device version 1.2 successfully torn down."); } - std::shared_ptr VulkanGraphicsDevice::CreateShaderProgram( + std::shared_ptr VulkanGraphicsDevice::CreateShaderProgram( std::string entryPointName, ShaderProgramKind kind, NovelRT::Utilities::Misc::Span byteData) { - return std::shared_ptr( - new VulkanShaderProgram(std::static_pointer_cast(shared_from_this()), - std::move(entryPointName), kind, byteData)); + return std::make_shared(shared_from_this(), std::move(entryPointName), kind, byteData); } VulkanGraphicsDevice::~VulkanGraphicsDevice() @@ -397,27 +391,22 @@ namespace NovelRT::Graphics::Vulkan TearDown(); } - std::shared_ptr VulkanGraphicsDevice::CreatePipeline( - std::shared_ptr signature, - std::shared_ptr vertexShader, - std::shared_ptr pixelShader) + std::shared_ptr VulkanGraphicsDevice::CreatePipeline( + std::shared_ptr signature, + std::shared_ptr vertexShader, + std::shared_ptr pixelShader) { - return std::static_pointer_cast(std::make_shared( - std::dynamic_pointer_cast(shared_from_this()), - std::dynamic_pointer_cast(signature), - std::dynamic_pointer_cast(vertexShader), - std::dynamic_pointer_cast(pixelShader))); + return std::make_shared(shared_from_this(), signature, vertexShader, pixelShader); } - std::shared_ptr VulkanGraphicsDevice::CreatePipelineSignature( + std::shared_ptr VulkanGraphicsDevice::CreatePipelineSignature( GraphicsPipelineBlendFactor srcBlendFactor, GraphicsPipelineBlendFactor dstBlendFactor, NovelRT::Utilities::Misc::Span inputs, NovelRT::Utilities::Misc::Span resources) { - return std::static_pointer_cast(std::make_shared( - std::dynamic_pointer_cast(shared_from_this()), srcBlendFactor, dstBlendFactor, inputs, - resources)); + return std::make_shared(shared_from_this(), srcBlendFactor, dstBlendFactor, + inputs, resources); } VkRenderPass VulkanGraphicsDevice::CreateRenderPass() @@ -468,32 +457,6 @@ namespace NovelRT::Graphics::Vulkan return _contextIndex; } - std::shared_ptr VulkanGraphicsDevice::CreatePrimitive( - std::shared_ptr pipeline, - GraphicsMemoryRegion& vertexBufferRegion, - uint32_t vertexBufferStride, - GraphicsMemoryRegion& indexBufferRegion, - uint32_t indexBufferStride, - NovelRT::Utilities::Misc::Span> inputResourceRegions) - { - return std::static_pointer_cast( - CreateVulkanPrimitive(std::dynamic_pointer_cast(pipeline), vertexBufferRegion, - vertexBufferStride, indexBufferRegion, indexBufferStride, inputResourceRegions)); - } - - std::shared_ptr VulkanGraphicsDevice::CreateVulkanPrimitive( - std::shared_ptr pipeline, - GraphicsMemoryRegion& vertexBufferRegion, - uint32_t vertexBufferStride, - GraphicsMemoryRegion& indexBufferRegion, - uint32_t indexBufferStride, - NovelRT::Utilities::Misc::Span> inputResourceRegions) - { - return std::make_shared( - std::dynamic_pointer_cast(shared_from_this()), pipeline, vertexBufferRegion, - vertexBufferStride, indexBufferRegion, indexBufferStride, inputResourceRegions); - } - void VulkanGraphicsDevice::PresentFrame() { auto presentCompletionGraphicsFence = GetPresentCompletionFence(); @@ -532,9 +495,14 @@ namespace NovelRT::Graphics::Vulkan _contextIndex = contextIndex; } - void VulkanGraphicsDevice::Signal(std::shared_ptr fence) + void VulkanGraphicsDevice::Signal(std::shared_ptr fence) const { - SignalVulkan(std::dynamic_pointer_cast(fence)); + VkResult result = vkQueueSubmit(GetVulkanGraphicsQueue(), 0, nullptr, fence->GetVulkanFence()); + + if (result != VK_SUCCESS) + { + throw std::runtime_error("Failed to signal VkQueue PresentQueue! Reason: " + std::to_string(result)); + } } void VulkanGraphicsDevice::WaitForIdle() @@ -548,9 +516,24 @@ namespace NovelRT::Graphics::Vulkan } } - VulkanGraphicsMemoryAllocator* VulkanGraphicsDevice::GetMemoryAllocatorInternal() + std::shared_ptr VulkanGraphicsDevice::GetCurrentContext() { - return _memoryAllocator.getActual().get(); + return GetContexts()[GetContextIndex()]; + } + + std::shared_ptr VulkanGraphicsDevice::GetAdapter() const noexcept + { + return _adapter; + } + + std::shared_ptr VulkanGraphicsDevice::GetSurfaceContext() const noexcept + { + return _surfaceContext; + } + + std::shared_ptr VulkanGraphicsDevice::GetSurface() const noexcept + { + return _surfaceContext->GetSurface(); } void VulkanGraphicsDevice::OnGraphicsSurfaceSizeChanged(NovelRT::Maths::GeoVector2F newSize) @@ -576,16 +559,6 @@ namespace NovelRT::Graphics::Vulkan } } - void VulkanGraphicsDevice::SignalVulkan(const std::shared_ptr& fence) const - { - VkResult result = vkQueueSubmit(GetVulkanGraphicsQueue(), 0, nullptr, fence->GetVulkanFence()); - - if (result != VK_SUCCESS) - { - throw std::runtime_error("Failed to signal VkQueue PresentQueue! Reason: " + std::to_string(result)); - } - } - void VulkanGraphicsDevice::ResizeGraphicsContexts(uint32_t newContextCount) { _contextCount = newContextCount; @@ -600,8 +573,7 @@ namespace NovelRT::Graphics::Vulkan for (size_t i = oldSize; i < newContextCount; i++) { - contexts[i] = std::make_shared( - std::dynamic_pointer_cast(shared_from_this()), i); + contexts[i] = std::make_shared(shared_from_this(), i); } _contextPtrs.reset(); diff --git a/graphics/Vulkan/VulkanGraphicsFence.cpp b/Graphics/Vulkan/VulkanGraphicsFence.cpp similarity index 93% rename from graphics/Vulkan/VulkanGraphicsFence.cpp rename to Graphics/Vulkan/VulkanGraphicsFence.cpp index 8a966d891..04e8ea514 100644 --- a/graphics/Vulkan/VulkanGraphicsFence.cpp +++ b/Graphics/Vulkan/VulkanGraphicsFence.cpp @@ -1,7 +1,8 @@ // Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root // for more information. -#include +#include +#include namespace NovelRT::Graphics::Vulkan { @@ -59,11 +60,11 @@ namespace NovelRT::Graphics::Vulkan } VulkanGraphicsFence::VulkanGraphicsFence(std::shared_ptr device, bool isSignaled) noexcept - : GraphicsFence(device->weak_from_this()), + : _device(device), _vulkanFence([=]() { return isSignaled ? CreateVulkanFenceSignaled() : CreateVulkanFenceUnsignaled(); }), _state() { - static_cast(_state.Transition(Threading::VolatileState::Initialised)); + unused(_state.Transition(Threading::VolatileState::Initialised)); } bool VulkanGraphicsFence::GetIsSignalled() diff --git a/Graphics/Vulkan/VulkanGraphicsMemoryAllocator.cpp b/Graphics/Vulkan/VulkanGraphicsMemoryAllocator.cpp new file mode 100644 index 000000000..251726d62 --- /dev/null +++ b/Graphics/Vulkan/VulkanGraphicsMemoryAllocator.cpp @@ -0,0 +1,158 @@ +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace NovelRT::Graphics::Vulkan +{ + VulkanGraphicsMemoryAllocator::VulkanGraphicsMemoryAllocator(std::shared_ptr provider, + std::shared_ptr device) + : _allocator(VK_NULL_HANDLE), _provider(provider), _device(device) + { + auto vulkanDevice = GetDevice(); + auto vulkanAdapter = vulkanDevice->GetAdapter(); + auto vulkanProvider = GetProvider(); + + VmaAllocatorCreateInfo createInfo{}; + createInfo.vulkanApiVersion = vulkanProvider->GetApiVersion(); + createInfo.physicalDevice = vulkanAdapter->GetVulkanPhysicalDevice(); + createInfo.device = vulkanDevice->GetVulkanDevice(); + createInfo.instance = vulkanProvider->GetVulkanInstance(); + + VkResult result = vmaCreateAllocator(&createInfo, &_allocator); + + if (result != VK_SUCCESS) + { + Exceptions::InitialisationFailureException("Failed to create the VulkanMemoryAllocator.", result); + } + } + + std::shared_ptr VulkanGraphicsMemoryAllocator::GetDevice() const noexcept + { + return _device; + } + + std::shared_ptr VulkanGraphicsMemoryAllocator::GetProvider() const noexcept + { + return _provider; + } + + std::shared_ptr VulkanGraphicsMemoryAllocator::CreateBuffer( + const GraphicsBufferCreateInfo& createInfo) + { + return CreateVulkanBuffer(createInfo); + } + + std::shared_ptr VulkanGraphicsMemoryAllocator::CreateTexture( + const GraphicsTextureCreateInfo& createInfo) + { + return CreateVulkanTexture(createInfo); + } + + std::shared_ptr VulkanGraphicsMemoryAllocator::CreateVulkanBuffer( + const GraphicsBufferCreateInfo& createInfo) + { + VkBufferCreateInfo bufferCreateInfo{}; + bufferCreateInfo.size = createInfo.size; + bufferCreateInfo.usage = Utilities::GetVulkanBufferUsageKind(createInfo.bufferKind, createInfo.gpuAccessKind); + + VmaAllocationCreateInfo allocationCreateInfo{}; + allocationCreateInfo.flags = Utilities::GetVmaAllocationKind(createInfo.cpuAccessKind); + allocationCreateInfo.usage = VMA_MEMORY_USAGE_AUTO; + + VkBuffer outBuffer = VK_NULL_HANDLE; + VmaAllocation outAllocation = VK_NULL_HANDLE; + VmaAllocationInfo outAllocationInfo{}; // TODO: I haven't figured out what I am doing with this yet, but I'm + // fairly sure we need it. Lol. + + VkResult result = vmaCreateBuffer(GetVmaAllocator(), &bufferCreateInfo, &allocationCreateInfo, &outBuffer, + &outAllocation, &outAllocationInfo); + + if (result != VK_SUCCESS) + { + throw Exceptions::InitialisationFailureException("Failed to correctly initialise the newly requested " + "Vulkan Buffer based on the supplied createInfo object.", + result); + } + + return std::make_shared(GetDevice(), shared_from_this(), createInfo.cpuAccessKind, + createInfo.bufferKind, outAllocation, outAllocationInfo, 0, + outBuffer); + } + + std::shared_ptr VulkanGraphicsMemoryAllocator::CreateVulkanTexture( + const GraphicsTextureCreateInfo& createInfo) + { + VkImageType imageType{}; + + switch (createInfo.textureKind) + { + case GraphicsTextureKind::OneDimensional: + imageType = VK_IMAGE_TYPE_1D; + break; + case GraphicsTextureKind::TwoDimensional: + imageType = VK_IMAGE_TYPE_2D; + break; + case GraphicsTextureKind::ThreeDimensional: + imageType = VK_IMAGE_TYPE_3D; + break; + default: + case GraphicsTextureKind::Unknown: + throw Exceptions::NotSupportedException( + "The specified texture kind is not supported in the default Vulkan pipeline."); + } + + VkExtent3D extent{}; + extent.width = createInfo.width; + extent.height = createInfo.height; + extent.depth = createInfo.depth; + + VkImageCreateInfo imageCreateInfo{}; + imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; + imageCreateInfo.imageType = imageType; + imageCreateInfo.format = Utilities::Map(createInfo.texelFormat); + imageCreateInfo.extent = extent; + imageCreateInfo.mipLevels = 1; + imageCreateInfo.arrayLayers = 1; + imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT; + imageCreateInfo.usage = Utilities::GetVulkanImageUsageKind(createInfo.textureKind, createInfo.gpuAccessKind); + + VkImage vulkanImage = VK_NULL_HANDLE; + VmaAllocation outAllocation = VK_NULL_HANDLE; + VmaAllocationInfo outAllocationInfo{}; // TODO: I haven't figured out what I am doing with this yet, but I'm + // fairly sure we need it. Lol. + + VmaAllocationCreateInfo allocationCreateInfo{}; + allocationCreateInfo.flags = Utilities::GetVmaAllocationKind(createInfo.cpuAccessKind); + allocationCreateInfo.usage = VMA_MEMORY_USAGE_AUTO; + // allocationCreateInfo.priority = 1; //TODO: do I need this? + + VkResult result = vmaCreateImage(GetVmaAllocator(), &imageCreateInfo, &allocationCreateInfo, &vulkanImage, + &outAllocation, &outAllocationInfo); + + if (result != VK_SUCCESS) + { + throw Exceptions::InitialisationFailureException("Failed to correctly initialise the newly requested " + "Vulkan Image based on the supplied createInfo object.", + result); + } + + return std::make_shared( + GetDevice(), shared_from_this(), createInfo.cpuAccessKind, createInfo.addressMode, createInfo.textureKind, + createInfo.width, createInfo.height, createInfo.depth, outAllocation, outAllocationInfo, 0, vulkanImage); + } + + VmaAllocator VulkanGraphicsMemoryAllocator::GetVmaAllocator() const noexcept + { + return _allocator; + } +} diff --git a/graphics/Vulkan/VulkanGraphicsPipeline.cpp b/Graphics/Vulkan/VulkanGraphicsPipeline.cpp similarity index 97% rename from graphics/Vulkan/VulkanGraphicsPipeline.cpp rename to Graphics/Vulkan/VulkanGraphicsPipeline.cpp index 4181a4f9a..c862059ec 100644 --- a/graphics/Vulkan/VulkanGraphicsPipeline.cpp +++ b/Graphics/Vulkan/VulkanGraphicsPipeline.cpp @@ -1,7 +1,10 @@ // Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root // for more information. -#include +#include +#include +#include +#include namespace NovelRT::Graphics::Vulkan { @@ -10,7 +13,7 @@ namespace NovelRT::Graphics::Vulkan std::shared_ptr signature, std::shared_ptr vertexShader, std::shared_ptr pixelShader) noexcept - : GraphicsPipeline(device, signature, vertexShader, pixelShader), + : _device(device), _vertexShader(vertexShader), _pixelShader(pixelShader), _signature(signature), _vulkanPipeline([&]() { return CreateVulkanPipeline(); }) { } diff --git a/graphics/Vulkan/VulkanGraphicsPipelineSignature.cpp b/Graphics/Vulkan/VulkanGraphicsPipelineSignature.cpp similarity index 96% rename from graphics/Vulkan/VulkanGraphicsPipelineSignature.cpp rename to Graphics/Vulkan/VulkanGraphicsPipelineSignature.cpp index 9ad436e31..3635fc80f 100644 --- a/graphics/Vulkan/VulkanGraphicsPipelineSignature.cpp +++ b/Graphics/Vulkan/VulkanGraphicsPipelineSignature.cpp @@ -1,7 +1,9 @@ // Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root // for more information. -#include +#include +#include +#include namespace NovelRT::Graphics::Vulkan { @@ -282,7 +284,11 @@ namespace NovelRT::Graphics::Vulkan GraphicsPipelineBlendFactor dstBlendFactor, NovelRT::Utilities::Misc::Span inputs, NovelRT::Utilities::Misc::Span resources) noexcept - : GraphicsPipelineSignature(std::move(device), srcBlendFactor, dstBlendFactor, inputs, resources), + : _device(device), + _srcBlendFactor(srcBlendFactor), + _dstBlendFactor(dstBlendFactor), + _inputs(std::vector(inputs.begin(), inputs.end())), + _resources(std::vector(resources.begin(), resources.end())), _vulkanDescriptorPool([&]() { return CreateDescriptorPool(); }), _vulkanDescriptorSetLayout([&]() { return CreateDescriptorSetLayout(); }), _vulkanPipelineLayout([&]() { return CreatePipelineLayout(); }) diff --git a/Graphics/Vulkan/VulkanGraphicsPluginProvider.cpp b/Graphics/Vulkan/VulkanGraphicsPluginProvider.cpp new file mode 100644 index 000000000..eebb28344 --- /dev/null +++ b/Graphics/Vulkan/VulkanGraphicsPluginProvider.cpp @@ -0,0 +1,46 @@ +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#include +#include +#include +#include +#include +#include +#include + +// this is such a hack +using namespace NovelRT::PluginManagement; +using namespace NovelRT::Graphics::Vulkan; +using namespace NovelRT::Graphics; + +template<> +IGraphicsPluginProvider::IGraphicsPluginProvider() noexcept + : _graphicsProvider([]() { return std::make_shared(); }) +{ +} + +template<> +[[nodiscard]] std::shared_ptr> IGraphicsPluginProvider< + VulkanGraphicsBackend>::GetGraphicsProvider() +{ + //TODO: unfuck this + return std::make_shared>(_graphicsProvider.getActual()); +} + +template<> +std::shared_ptr> IGraphicsPluginProvider< + VulkanGraphicsBackend>::CreateSurfaceContext(std::shared_ptr surface) +{ + //TODO: unfuck this + return std::make_shared>(nullptr, surface, GetGraphicsProvider()); +} + +template<> +std::shared_ptr> IGraphicsPluginProvider:: + GetDefaultSelectedGraphicsAdapterForContext(std::shared_ptr> context) +{ + auto x = VulkanGraphicsAdapterSelector().GetDefaultRecommendedAdapter(_graphicsProvider.getActual(), + context->_implementation); + return std::make_shared>(x, GetGraphicsProvider()); +} \ No newline at end of file diff --git a/graphics/Vulkan/VulkanGraphicsProvider.cpp b/Graphics/Vulkan/VulkanGraphicsProvider.cpp similarity index 94% rename from graphics/Vulkan/VulkanGraphicsProvider.cpp rename to Graphics/Vulkan/VulkanGraphicsProvider.cpp index 09d29d346..41656564c 100644 --- a/graphics/Vulkan/VulkanGraphicsProvider.cpp +++ b/Graphics/Vulkan/VulkanGraphicsProvider.cpp @@ -1,8 +1,9 @@ // Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root // for more information. -#include #include +#include +#include namespace NovelRT::Graphics::Vulkan { @@ -222,7 +223,7 @@ namespace NovelRT::Graphics::Vulkan appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0); appInfo.pEngineName = EngineConfig::EngineName().c_str(); appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0); - appInfo.apiVersion = VK_API_VERSION_1_2; + appInfo.apiVersion = GetApiVersion(); _finalExtensionSet = GetFinalInstanceExtensionSet(); std::vector allExtensionullptrs = @@ -270,7 +271,7 @@ namespace NovelRT::Graphics::Vulkan return returnInstance; } - std::vector> VulkanGraphicsProvider::GetGraphicsAdapters() + std::vector> VulkanGraphicsProvider::GetGraphicsAdapters() { VkInstance instance = GetVulkanInstance(); @@ -290,13 +291,12 @@ namespace NovelRT::Graphics::Vulkan std::vector devices(deviceCount); vkEnumeratePhysicalDevices(instance, &deviceCount, devices.data()); - std::vector> adapters{}; + std::vector> adapters{}; adapters.reserve(devices.size()); for (auto&& physicalDevice : devices) { - adapters.emplace_back(std::make_shared( - std::dynamic_pointer_cast(shared_from_this()), physicalDevice)); + adapters.emplace_back(std::make_shared(shared_from_this(), physicalDevice)); } return adapters; @@ -310,7 +310,8 @@ namespace NovelRT::Graphics::Vulkan _engineName(EngineConfig::EngineName()), _state(Threading::VolatileState()), _debugLogger(VK_NULL_HANDLE), - _logger(LoggingService(NovelRT::Utilities::Misc::CONSOLE_LOG_GFX)) + _logger(LoggingService(NovelRT::Utilities::Misc::CONSOLE_LOG_GFX)), + _debugModeEnabled(EngineConfig::EnableDebugOutputFromEngineInternals()) { if (GetDebugModeEnabled()) { @@ -338,12 +339,23 @@ namespace NovelRT::Graphics::Vulkan vkDestroyInstance(_vulkanInstance, nullptr); } - std::vector>::iterator VulkanGraphicsProvider::begin() noexcept + + uint32_t VulkanGraphicsProvider::GetApiVersion() const noexcept + { + return VK_API_VERSION_1_2; + } + + bool VulkanGraphicsProvider::GetDebugModeEnabled() const noexcept + { + return _debugModeEnabled; + } + + std::vector>::iterator VulkanGraphicsProvider::begin() noexcept { return _adapters.getActual().begin(); } - std::vector>::iterator VulkanGraphicsProvider::end() noexcept + std::vector>::iterator VulkanGraphicsProvider::end() noexcept { return _adapters.getActual().end(); } diff --git a/Graphics/Vulkan/VulkanGraphicsResource.cpp b/Graphics/Vulkan/VulkanGraphicsResource.cpp new file mode 100644 index 000000000..620d6afa8 --- /dev/null +++ b/Graphics/Vulkan/VulkanGraphicsResource.cpp @@ -0,0 +1,97 @@ +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#include +#include +#include +#include +#include + +namespace NovelRT::Graphics::Vulkan +{ + std::tuple VulkanGraphicsResource::GetVirtualAllocation(size_t size, size_t alignment) + { + VmaVirtualAllocationCreateInfo allocInfo{}; + allocInfo.size = size; + allocInfo.alignment = alignment; + + VmaVirtualAllocation allocHandle = VK_NULL_HANDLE; + VkDeviceSize offset{}; + + VkResult allocResult = vmaVirtualAllocate(_virtualBlock, &allocInfo, &allocHandle, &offset); + + if (allocResult != VK_SUCCESS) + { + throw Exceptions::OutOfMemoryException("Unable to allocate additional memory in the Vulkan graphics resource."); + } + + return std::make_tuple(allocHandle, offset); + } + + VulkanGraphicsResource::VulkanGraphicsResource(std::shared_ptr graphicsDevice, + std::shared_ptr allocator, + GraphicsResourceAccess cpuAccess, + VmaAllocation allocation, + VmaAllocationInfo allocationInfo) + : _allocator(allocator), + _graphicsDevice(graphicsDevice), + _allocation(allocation), + _allocationInfo(allocationInfo), + _virtualBlock(VK_NULL_HANDLE) + { + unused(cpuAccess); + + VmaVirtualBlockCreateInfo createInfo{}; + createInfo.size = GetSize(); + + VkResult result = vmaCreateVirtualBlock(&createInfo, &_virtualBlock); + + if (result != VK_SUCCESS) + { + throw Exceptions::InitialisationFailureException("Failed to create virtual memory block for VkBuffer", + std::to_string(result)); + } + } + + std::shared_ptr VulkanGraphicsResource::GetAllocator() const noexcept + { + return _allocator; + } + + std::shared_ptr VulkanGraphicsResource::GetDevice() const noexcept + { + return _graphicsDevice; + } + + size_t VulkanGraphicsResource::GetDeviceMemoryOffset() const noexcept + { + return _allocationInfo.offset; + } + + size_t VulkanGraphicsResource::GetSize() const noexcept + { + return _allocationInfo.size; + } + + std::shared_ptr VulkanGraphicsResource::Allocate(size_t size, size_t alignment) + { + auto [allocation, offset] = GetVirtualAllocation(size, alignment); + return AllocateInternal(allocation, offset); + } + + VmaAllocation VulkanGraphicsResource::GetAllocation() const noexcept + { + return _allocation; + } + + const VmaAllocationInfo& VulkanGraphicsResource::GetAllocationInfo() const noexcept + { + return _allocationInfo; + } + + VmaVirtualBlock VulkanGraphicsResource::GetVirtualBlock() const noexcept + { + return _virtualBlock; + } +} + diff --git a/Graphics/Vulkan/VulkanGraphicsResourceMemoryRegion.cpp b/Graphics/Vulkan/VulkanGraphicsResourceMemoryRegion.cpp new file mode 100644 index 000000000..35231e200 --- /dev/null +++ b/Graphics/Vulkan/VulkanGraphicsResourceMemoryRegion.cpp @@ -0,0 +1,57 @@ +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#include +#include +#include +#include + +namespace NovelRT::Graphics::Vulkan +{ + VulkanGraphicsResourceMemoryRegionBase::VulkanGraphicsResourceMemoryRegionBase( + std::shared_ptr graphicsDevice, + std::shared_ptr owningResource, + VmaVirtualAllocation virtualAllocation, + VmaVirtualAllocationInfo virtualAllocationInfo) + : _device(graphicsDevice), + _owningResource(owningResource), + _virtualAllocation(virtualAllocation), + _virtualAllocationInfo(virtualAllocationInfo) + { + if (_virtualAllocation == VK_NULL_HANDLE || _virtualAllocationInfo.size == 0) + { + throw Exceptions::InitialisationFailureException( + "An invalid memory region of a Vulkan graphics resource was created."); + } + } + + std::shared_ptr VulkanGraphicsResourceMemoryRegionBase::GetDevice() const noexcept + { + return _device; + } + + std::shared_ptr VulkanGraphicsResourceMemoryRegionBase::GetOwningResource() const noexcept + { + return _owningResource; + } + + size_t VulkanGraphicsResourceMemoryRegionBase::GetRelativeOffset() const noexcept + { + return _virtualAllocationInfo.offset; + } + + size_t VulkanGraphicsResourceMemoryRegionBase::GetSize() const noexcept + { + return _virtualAllocationInfo.size; + } + + VmaVirtualAllocation VulkanGraphicsResourceMemoryRegionBase::GetVirtualAllocation() const noexcept + { + return _virtualAllocation; + } + + VmaVirtualAllocationInfo VulkanGraphicsResourceMemoryRegionBase::GetVirtualAllocationInfo() const noexcept + { + return _virtualAllocationInfo; + } +} \ No newline at end of file diff --git a/graphics/Vulkan/VulkanGraphicsSurfaceContext.cpp b/Graphics/Vulkan/VulkanGraphicsSurfaceContext.cpp similarity index 77% rename from graphics/Vulkan/VulkanGraphicsSurfaceContext.cpp rename to Graphics/Vulkan/VulkanGraphicsSurfaceContext.cpp index 16b68b351..e5f836543 100644 --- a/graphics/Vulkan/VulkanGraphicsSurfaceContext.cpp +++ b/Graphics/Vulkan/VulkanGraphicsSurfaceContext.cpp @@ -1,17 +1,29 @@ // Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root // for more information. -#include +#include +#include namespace NovelRT::Graphics::Vulkan { VulkanGraphicsSurfaceContext::VulkanGraphicsSurfaceContext(std::shared_ptr surface, - const std::shared_ptr& provider) - : GraphicsSurfaceContext(std::move(surface), std::static_pointer_cast(provider)), + std::shared_ptr provider) + : _surface(surface), + _provider(provider), _logger(LoggingService(NovelRT::Utilities::Misc::CONSOLE_LOG_GFX)), _vulkanSurface(VK_NULL_HANDLE) { + if (_surface == nullptr) + { + throw Exceptions::NullPointerException("The supplied IGraphicsSurface is nullptr."); + } + + if (_provider == nullptr) + { + throw Exceptions::NullPointerException("The supplied GraphicsProvider is nullptr."); + } + std::shared_ptr targetSurface = GetSurface(); switch (targetSurface->GetKind()) { diff --git a/Graphics/Vulkan/VulkanGraphicsTexture.cpp b/Graphics/Vulkan/VulkanGraphicsTexture.cpp new file mode 100644 index 000000000..9471de577 --- /dev/null +++ b/Graphics/Vulkan/VulkanGraphicsTexture.cpp @@ -0,0 +1,300 @@ +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#include +#include +#include +#include +#include + +namespace NovelRT::Graphics::Vulkan +{ + VkImageView VulkanGraphicsTexture::CreateVulkanImageView() + { + VkImageView vulkanImageView = VK_NULL_HANDLE; + + std::shared_ptr device = VulkanGraphicsResource::GetAllocator()->GetDevice(); + + VkDevice vulkanDevice = device->GetVulkanDevice(); + + VkImageViewType viewType; + switch (GetKind()) + { + case GraphicsTextureKind::OneDimensional: + viewType = VK_IMAGE_VIEW_TYPE_1D; + break; + case GraphicsTextureKind::TwoDimensional: + viewType = VK_IMAGE_VIEW_TYPE_2D; + break; + case GraphicsTextureKind::ThreeDimensional: + viewType = VK_IMAGE_VIEW_TYPE_3D; + break; + default: + case GraphicsTextureKind::Unknown: + throw Exceptions::InvalidOperationException("Invalid or unknown graphics texture kind type specified."); + break; + } + + VkComponentMapping components{}; + components.r = VK_COMPONENT_SWIZZLE_R; + components.g = VK_COMPONENT_SWIZZLE_G; + components.b = VK_COMPONENT_SWIZZLE_B; + components.a = VK_COMPONENT_SWIZZLE_A; + + VkImageSubresourceRange subresourceRange{}; + subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + subresourceRange.levelCount = 1; + subresourceRange.layerCount = 1; + + VkImageViewCreateInfo imageViewCreateInfo{}; + imageViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + imageViewCreateInfo.image = GetVulkanImage(); + imageViewCreateInfo.viewType = viewType; + imageViewCreateInfo.format = VK_FORMAT_R8G8B8A8_UNORM; + imageViewCreateInfo.components = components; + imageViewCreateInfo.subresourceRange = subresourceRange; + + VkResult imageViewResult = vkCreateImageView(vulkanDevice, &imageViewCreateInfo, nullptr, &vulkanImageView); + + if (imageViewResult != VK_SUCCESS) + { + throw Exceptions::InitialisationFailureException("Failed to create VkImageView for texture!", + imageViewResult); + } + + return vulkanImageView; + } + + VkSampler VulkanGraphicsTexture::CreateVulkanSampler() + { + VkSampler vulkanSampler = VK_NULL_HANDLE; + + std::shared_ptr device = VulkanGraphicsResource::GetAllocator()->GetDevice(); + + VkDevice vulkanDevice = device->GetVulkanDevice(); + + VkSamplerAddressMode addressMode = Utilities::GetVulkanAddressMode(GetAddressMode()); + + VkSamplerCreateInfo samplerCreateInfo{}; + samplerCreateInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; + samplerCreateInfo.magFilter = VK_FILTER_LINEAR; + samplerCreateInfo.minFilter = VK_FILTER_LINEAR; + samplerCreateInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; + samplerCreateInfo.maxLod = 1.0f; + samplerCreateInfo.borderColor = VK_BORDER_COLOR_INT_OPAQUE_WHITE; + samplerCreateInfo.addressModeU = addressMode; + samplerCreateInfo.addressModeV = addressMode; + samplerCreateInfo.addressModeW = addressMode; + + VkResult result = vkCreateSampler(vulkanDevice, &samplerCreateInfo, nullptr, &vulkanSampler); + + if (result != VK_SUCCESS) + { + throw Exceptions::InitialisationFailureException("Failed to create VkSampler!", result); + } + + return vulkanSampler; + } + + std::shared_ptr VulkanGraphicsTexture::AllocateInternal( + VmaVirtualAllocation allocation, + VkDeviceSize offset) + { + unused(offset); // TODO: figure out if we need offset + + VmaVirtualAllocationInfo allocInfo{}; + vmaGetVirtualAllocationInfo(GetVirtualBlock(), allocation, &allocInfo); + return std::make_shared>( + GetDevice(), shared_from_this(), allocation, allocInfo); + } + + VulkanGraphicsTexture::VulkanGraphicsTexture(std::shared_ptr device, + std::shared_ptr allocator, + GraphicsResourceAccess cpuAccess, + GraphicsTextureAddressMode addressMode, + GraphicsTextureKind kind, + uint32_t width, + uint32_t height, + uint16_t depth, + VmaAllocation allocation, + VmaAllocationInfo allocationInfo, + size_t subAllocations, + VkImage vulkanImage) + : VulkanGraphicsResource(device, allocator, cpuAccess, allocation, allocationInfo), + // GraphicsTexture(device, allocator, cpuAccess, addressMode, kind, width, height, depth), + _vulkanImage(vulkanImage), + _subAllocations(0), + _addressMode(addressMode), + _kind(kind), + _vulkanImageView([&]() { return CreateVulkanImageView(); }), + _vulkanSampler([&]() { return CreateVulkanSampler(); }), + _width(width), + _height(height), + _depth(depth) + { + // TODO: Still need this? + unused(subAllocations); + + VkResult result = vkBindImageMemory(GetDevice()->GetVulkanDevice(), GetVulkanImage(), GetAllocationInfo().deviceMemory, GetAllocationInfo().offset); + + if (result != VK_SUCCESS) + { + throw Exceptions::InitialisationFailureException("Failed to bind VkImage to VkImageMemory correctly.", + result); + } + } + + VulkanGraphicsTexture::~VulkanGraphicsTexture() noexcept + { + auto vulkanDevice = VulkanGraphicsResource::GetDevice()->GetVulkanDevice(); + auto allocator = VulkanGraphicsResource::GetAllocator()->GetVmaAllocator(); + auto allocation = GetAllocation(); + + assert_message(_subAllocations != 0, "Attempted to destroy a VkImage containing mapped regions."); + + if (_vulkanImageView.isCreated()) + { + vkDestroyImageView(vulkanDevice, _vulkanImageView.getActual(), nullptr); + _vulkanImageView.reset(); + } + + if (_vulkanSampler.isCreated()) + { + vkDestroyImageView(vulkanDevice, _vulkanImageView.getActual(), nullptr); + _vulkanSampler.reset(); + } + + vmaDestroyImage(allocator, GetVulkanImage(), allocation); + } + + GraphicsTextureAddressMode VulkanGraphicsTexture::GetAddressMode() const noexcept + { + return _addressMode; + } + + GraphicsTextureKind VulkanGraphicsTexture::GetKind() const noexcept + { + return _kind; + } + + NovelRT::Utilities::Misc::Span VulkanGraphicsTexture::MapBytes(size_t rangeOffset, size_t rangeLength) + { + size_t sizeOfBuffer = GetAllocationInfo().size; + size_t rangeValidationValue = sizeOfBuffer - rangeOffset; + + if (rangeValidationValue < rangeLength) + { + throw Exceptions::InvalidOperationException( + "Attempted to map a subrange of a VkTexture that exceeded the VkBuffer's size."); + } + + void* data = nullptr; + VkResult result = + vmaMapMemory(VulkanGraphicsResource::GetAllocator()->GetVmaAllocator(), GetAllocation(), &data); + + if (result != VK_SUCCESS) + { + // TODO: Make this a real exception + throw std::runtime_error("Failed to map Vulkan memory to the CPU. Reason: " + std::to_string(result)); + } + + _subAllocations++; + + return NovelRT::Utilities::Misc::Span(reinterpret_cast(data) + rangeOffset, rangeLength); + } + + NovelRT::Utilities::Misc::Span VulkanGraphicsTexture::MapBytesForRead(size_t rangeOffset, + size_t rangeLength) + { + size_t sizeOfBuffer = GetAllocationInfo().size; + size_t rangeValidationValue = sizeOfBuffer - rangeOffset; + + if (rangeValidationValue < rangeLength) + { + throw Exceptions::InvalidOperationException( + "Attempted to map a subrange of a VkBuffer that exceeded the VkBuffer's size."); + } + + VmaAllocator allocator = VulkanGraphicsResource::GetAllocator()->GetVmaAllocator(); + VmaAllocation allocation = GetAllocation(); + + void* data = nullptr; + VkResult mapResult = vmaMapMemory(allocator, allocation, &data); + + if (mapResult != VK_SUCCESS) + { + // TODO: Make this a real exception + throw std::runtime_error("Failed to map Vulkan memory to the CPU. Reason: " + std::to_string(mapResult)); + } + + VkResult invalidateResult = vmaInvalidateAllocation(allocator, allocation, rangeOffset, rangeLength); + + if (invalidateResult != VK_SUCCESS) + { + // TODO: Make this a real exception + throw std::runtime_error("Failed to invalidate mapped memory. Reason: " + std::to_string(mapResult)); + } + + return NovelRT::Utilities::Misc::Span(reinterpret_cast(data), rangeLength); + } + + void VulkanGraphicsTexture::UnmapBytes() + { + vmaUnmapMemory(VulkanGraphicsResource::GetAllocator()->GetVmaAllocator(), GetAllocation()); + } + + void VulkanGraphicsTexture::UnmapBytesAndWrite(size_t writtenRangeOffset, size_t writtenRangeLength) + { + size_t sizeOfBuffer = GetAllocationInfo().size; + size_t rangeValidationValue = sizeOfBuffer - writtenRangeOffset; + + if (rangeValidationValue < writtenRangeLength) + { + throw Exceptions::InvalidOperationException( + "Attempted to write a subrange of a VkImage that exceeded the VkBuffer's size."); + } + + auto allocator = VulkanGraphicsResource::GetAllocator()->GetVmaAllocator(); + auto allocation = GetAllocation(); + + VkResult result = vmaFlushAllocation(allocator, allocation, writtenRangeOffset, writtenRangeLength); + + if (result != VK_SUCCESS) + { + throw std::runtime_error("Failed to write VkBuffer subrange to GPU memory. Reason: " + + std::to_string(result)); + } + + vmaUnmapMemory(allocator, allocation); + } + + VkImage VulkanGraphicsTexture::GetVulkanImage() const noexcept + { + return _vulkanImage; + } + + VkImageView VulkanGraphicsTexture::GetOrCreateVulkanImageView() + { + return _vulkanImageView.getActual(); + } + + VkSampler VulkanGraphicsTexture::GetOrCreateVulkanSampler() + { + return _vulkanSampler.getActual(); + } + + uint32_t VulkanGraphicsTexture::GetWidth() const noexcept + { + return _width; + } + + uint32_t VulkanGraphicsTexture::GetHeight() const noexcept + { + return _height; + } + + uint32_t VulkanGraphicsTexture::GetDepth() const noexcept + { + return _depth; + } +} \ No newline at end of file diff --git a/graphics/Vulkan/VulkanShaderProgram.cpp b/Graphics/Vulkan/VulkanShaderProgram.cpp similarity index 80% rename from graphics/Vulkan/VulkanShaderProgram.cpp rename to Graphics/Vulkan/VulkanShaderProgram.cpp index 7946073f5..728704aec 100644 --- a/graphics/Vulkan/VulkanShaderProgram.cpp +++ b/Graphics/Vulkan/VulkanShaderProgram.cpp @@ -1,7 +1,8 @@ // Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root // for more information. -#include +#include +#include namespace NovelRT::Graphics::Vulkan { @@ -9,7 +10,9 @@ namespace NovelRT::Graphics::Vulkan std::string entryPointName, ShaderProgramKind kind, NovelRT::Utilities::Misc::Span bytecode) noexcept - : ShaderProgram(device, std::move(entryPointName), kind), + : _device(device), + _entryPointName(entryPointName), + _kind(kind), _shaderModule(NovelRT::Utilities::Lazy( std::function([this]() { return CreateShaderModule(); }))), _bytecode(std::vector(bytecode.begin(), bytecode.end())), @@ -44,6 +47,21 @@ namespace NovelRT::Graphics::Vulkan _shaderModule.getActual(), nullptr); } + std::shared_ptr VulkanShaderProgram::GetDevice() const noexcept + { + return _device; + } + + std::string VulkanShaderProgram::GetEntryPointName() const noexcept + { + return _entryPointName; + } + + ShaderProgramKind VulkanShaderProgram::GetKind() const noexcept + { + return _kind; + } + NovelRT::Utilities::Misc::Span VulkanShaderProgram::GetBytecode() const noexcept { return NovelRT::Utilities::Misc::Span(&(*_bytecode.begin()), _bytecode.size()); diff --git a/graphics/include/NovelRT/Graphics/D3D12/Utilities/PipelineBlendFactor.hpp b/Graphics/include/NovelRT/Graphics/D3D12/Utilities/PipelineBlendFactor.hpp similarity index 82% rename from graphics/include/NovelRT/Graphics/D3D12/Utilities/PipelineBlendFactor.hpp rename to Graphics/include/NovelRT/Graphics/D3D12/Utilities/PipelineBlendFactor.hpp index 5ad1b3f44..13e431238 100644 --- a/graphics/include/NovelRT/Graphics/D3D12/Utilities/PipelineBlendFactor.hpp +++ b/Graphics/include/NovelRT/Graphics/D3D12/Utilities/PipelineBlendFactor.hpp @@ -1,12 +1,11 @@ +#pragma once + // Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root // for more information. -#ifndef NOVELRT_GRAPHICS_D3D12_UTILITIES_PIPELINEBLENDFACTOR_H -#define NOVELRT_GRAPHICS_D3D12_UTILITIES_PIPELINEBLENDFACTOR_H - -#ifndef NOVELRT_GRAPHICS_D3D12_UTILITIES_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.D3D12.Utilities.h instead for the Graphics::D3D12::Utilities namespace subset. -#endif +#include +#include +#include namespace NovelRT::Graphics::D3D12::Utilities { @@ -44,5 +43,3 @@ namespace NovelRT::Graphics::D3D12::Utilities return NovelRTToD3D12Blend[static_cast(blendFactor)]; } } - -#endif // !NOVELRT_GRAPHICS_D3D12_UTILITIES_PIPELINEBLENDFACTOR_H diff --git a/Graphics/include/NovelRT/Graphics/GraphicsAdapter.hpp b/Graphics/include/NovelRT/Graphics/GraphicsAdapter.hpp new file mode 100644 index 000000000..9d5344a90 --- /dev/null +++ b/Graphics/include/NovelRT/Graphics/GraphicsAdapter.hpp @@ -0,0 +1,72 @@ +#pragma once + +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#include +#include +#include +#include + +namespace NovelRT::Graphics +{ + template class GraphicsDevice; + template class GraphicsProvider; + template class GraphicsSurfaceContext; + + template struct GraphicsBackendTraits; + + template class GraphicsAdapter : public std::enable_shared_from_this> + { + public: + using BackendAdapterType = typename GraphicsBackendTraits::AdapterType; + + private: + std::shared_ptr _implementation; + std::shared_ptr> _provider; + + public: + GraphicsAdapter(std::shared_ptr implementation, + std::shared_ptr> provider) + : _implementation(implementation), _provider(provider) + { + if (!_provider) + { + throw Exceptions::NullPointerException( + "The provided GraphicsProvider pointer is nullptr or an invalid pointer."); + } + } + + ~GraphicsAdapter() noexcept = default; + + [[nodiscard]] uint32_t GetDeviceId() + { + return _implementation->GetDeviceId(); + } + + [[nodiscard]] const std::string& GetName() + { + return _implementation->GetName(); + } + + [[nodiscard]] inline std::shared_ptr> GetProvider() const + { + return _provider; + } + + [[nodiscard]] uint32_t GetVendorId() + { + return _implementation->GetVendorId(); + } + + [[nodiscard]] std::shared_ptr> CreateDevice( + std::shared_ptr> surfaceContext, + int32_t contextCount) + { + return std::make_shared>( + _implementation->CreateDevice(surfaceContext->GetImplementation(), contextCount), + this->shared_from_this(), + surfaceContext); + } + }; +} diff --git a/Graphics/include/NovelRT/Graphics/GraphicsBackendTraits.hpp b/Graphics/include/NovelRT/Graphics/GraphicsBackendTraits.hpp new file mode 100644 index 000000000..b0d5f7f14 --- /dev/null +++ b/Graphics/include/NovelRT/Graphics/GraphicsBackendTraits.hpp @@ -0,0 +1,13 @@ +#pragma once + +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +namespace NovelRT::Graphics +{ + template + struct GraphicsBackendTraits; + //{ + // static_assert(false, "Backends need to specialise this type."); + //}; +} \ No newline at end of file diff --git a/Graphics/include/NovelRT/Graphics/GraphicsBuffer.hpp b/Graphics/include/NovelRT/Graphics/GraphicsBuffer.hpp new file mode 100644 index 000000000..68ae3c63f --- /dev/null +++ b/Graphics/include/NovelRT/Graphics/GraphicsBuffer.hpp @@ -0,0 +1,45 @@ +#pragma once + +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#include +#include + +namespace NovelRT::Graphics +{ + template class GraphicsResourceMemoryRegion; + + template struct GraphicsBackendTraits; + + template class GraphicsBuffer : public GraphicsResource + { + public: + using BackendBufferType = typename GraphicsBackendTraits::BufferType; + using BackendResourceMemoryRegionType = typename GraphicsBackendTraits::ResourceMemoryRegionType; + + private: + GraphicsBufferKind _kind; + + public: + GraphicsBuffer(std::shared_ptr implementation, + std::shared_ptr> allocator, + GraphicsResourceAccess cpuAccess, + GraphicsBufferKind kind) noexcept + : GraphicsResource(implementation, allocator, cpuAccess), _kind(kind) + { + } + + virtual ~GraphicsBuffer() noexcept override = default; + + [[nodiscard]] std::shared_ptr, TBackend>> Allocate(size_t size, size_t alignment) + { + return GraphicsResource::_implementation->Allocate(size, alignment); + } + + [[nodiscard]] GraphicsBufferKind GetKind() const noexcept + { + return _kind; + } + }; +} diff --git a/Graphics/include/NovelRT/Graphics/GraphicsBufferCreateInfo.hpp b/Graphics/include/NovelRT/Graphics/GraphicsBufferCreateInfo.hpp new file mode 100644 index 000000000..e3e7ba026 --- /dev/null +++ b/Graphics/include/NovelRT/Graphics/GraphicsBufferCreateInfo.hpp @@ -0,0 +1,23 @@ +#pragma once + +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#include +#include +#include +#include +#include + + +namespace NovelRT::Graphics +{ + struct GraphicsBufferCreateInfo + { + GraphicsBufferKind bufferKind; + GraphicsResourceAccess cpuAccessKind; + GraphicsResourceAccess gpuAccessKind; + size_t size; + GraphicsMemoryRegionAllocationFlags allocationFlags; + }; +} \ No newline at end of file diff --git a/graphics/include/NovelRT/Graphics/GraphicsBufferKind.hpp b/Graphics/include/NovelRT/Graphics/GraphicsBufferKind.hpp similarity index 52% rename from graphics/include/NovelRT/Graphics/GraphicsBufferKind.hpp rename to Graphics/include/NovelRT/Graphics/GraphicsBufferKind.hpp index 31065444c..bf433aaaa 100644 --- a/graphics/include/NovelRT/Graphics/GraphicsBufferKind.hpp +++ b/Graphics/include/NovelRT/Graphics/GraphicsBufferKind.hpp @@ -1,12 +1,9 @@ +#pragma once + // Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root // for more information. -#ifndef NOVELRT_GRAPHICS_GRAPHICSBUFFERKIND_H -#define NOVELRT_GRAPHICS_GRAPHICSBUFFERKIND_H - -#ifndef NOVELRT_GRAPHICS_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.h instead for the Graphics namespace subset. -#endif +#include namespace NovelRT::Graphics { @@ -19,5 +16,3 @@ namespace NovelRT::Graphics Uniform = Constant }; } - -#endif // !NOVELRT_GRAPHICS_GRAPHICSBUFFERKIND_H diff --git a/Graphics/include/NovelRT/Graphics/GraphicsCmdList.hpp b/Graphics/include/NovelRT/Graphics/GraphicsCmdList.hpp new file mode 100644 index 000000000..9cf0d0985 --- /dev/null +++ b/Graphics/include/NovelRT/Graphics/GraphicsCmdList.hpp @@ -0,0 +1,124 @@ +#pragma once + +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#include +#include +#include +#include + +namespace NovelRT::Graphics +{ + template class GraphicsContext; + template class GraphicsBuffer; + template class GraphicsTexture; + template class GraphicsDescriptorSet; + template class GraphicsRenderPass; + + // TODO: MOVE THIS + struct ViewportInfo + { + float x; + float y; + float width; + float height; + float minDepth; + float maxDepth; + }; + + template struct GraphicsBackendTraits; + + template class GraphicsCmdList : public GraphicsDeviceObject + { + public: + using BackendCmdListType = typename GraphicsBackendTraits::CmdListType; + using BackendDescriptorType = typename GraphicsBackendTraits::DescriptorSetType; + using BackendBufferType = typename GraphicsBackendTraits::BufferType; + + private: + std::shared_ptr _implementation; + std::shared_ptr> _context; + + public: + GraphicsCmdList(std::shared_ptr implementation, + std::shared_ptr> context) noexcept + : _implementation(implementation), _context(context) + { + } + + virtual ~GraphicsCmdList() override = default; + + [[nodiscard]] std::shared_ptr> GetContext() const noexcept + { + return _context; + } + + void CmdBeginRenderPass(std::shared_ptr> targetPass) + { + _implementation->CmdBeginRenderPass(targetPass->GetImplementation()); + } + + void CmdBindDescriptorSets(NovelRT::Utilities::Misc::Span>> sets) + { + std::vector> transformedArgs{}; + transformedArgs.resize(sets.size()); + std::transform(sets.begin(), sets.end(), transformedArgs.begin(), [&](auto x){ return x->GetImplementation(); }); + _implementation->CmdBindDescriptorSets(sets); + } + + void CmdBindVertexBuffers(uint32_t firstBinding, + uint32_t bindingCount, + NovelRT::Utilities::Misc::Span>> buffers, + NovelRT::Utilities::Misc::Span offsets) + { + std::vector> transformedArgs{}; + transformedArgs.resize(buffers.size()); + std::transform(buffers.begin(), buffers.end(), transformedArgs.begin(), [&](auto x) { return x->GetImplementation(); }); + _implementation->CmdBindVertexBuffers(firstBinding, bindingCount, transformedArgs, offsets); + } + + void CmdBindIndexBuffers(NovelRT::Utilities::Misc::Span>> buffers) + { + std::vector> transformedArgs{}; + transformedArgs.resize(buffers.size()); + std::transform(buffers.begin(), buffers.end(), transformedArgs.begin(), [&](auto x) { return x->GetImplementation(); }); + _implementation->CmdBindIndexbuffers(transformedArgs); + } + + void CmdCopy(std::shared_ptr> destination, std::shared_ptr> source) + { + _implementation->CmdCopy(destination->GetImplementation(), source->GetImplementation()); + } + + void CmdCopy(std::shared_ptr> destination, std::shared_ptr> source) + { + _implementation->CmdCopy(destination->GetImplementation(), source->GetImplementation()); + } + + void CmdDrawIndexed(uint32_t instanceCount) + { + _implementation->CmdDrawIndexed(instanceCount); + } + + void CmdDraw(uint32_t instanceCount, uint32_t bufferStride) + { + _implementation->CmdDraw(instanceCount, bufferStride); + } + + void CmdSetScissor(Maths::GeoVector2F extent) + { + _implementation->CmdSetScissor(extent); + } + + void CmdSetScissor(float xExtent, float yExtent) + { + _implementation->CmdSetScissor(xExtent, yExtent); + } + + void CmdSetViewport(uint32_t firstViewport, uint32_t viewportCount, ViewportInfo viewportInfo) + { + _implementation->CmdSetViewport(firstViewport, viewportCount, viewportInfo); + } + }; +} \ No newline at end of file diff --git a/Graphics/include/NovelRT/Graphics/GraphicsContext.hpp b/Graphics/include/NovelRT/Graphics/GraphicsContext.hpp new file mode 100644 index 000000000..9d097c425 --- /dev/null +++ b/Graphics/include/NovelRT/Graphics/GraphicsContext.hpp @@ -0,0 +1,62 @@ +#pragma once + +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#include +#include + +namespace NovelRT::Graphics +{ + template struct GraphicsBackendTraits; + + template class GraphicsContext : public GraphicsDeviceObject + { + public: + using BackendContextType = typename GraphicsBackendTraits::ContextType; + + private: + std::shared_ptr _implementation; + size_t _index; + + public: + GraphicsContext(std::shared_ptr implemenetation, + std::shared_ptr> device, + size_t index) noexcept + : GraphicsDeviceObject(device), _implementation(implemenetation), _index(index) + { + } + + virtual ~GraphicsContext() override = default; + + [[nodiscard]] std::shared_ptr> GetFence() const noexcept + { + return _implementation->GetFence(); + } + + [[nodiscard]] inline size_t GetIndex() const noexcept + { + return _index; + } + + void BeginDrawing(RGBAColour backgroundColour) + { + _implementation->BeginDrawing(backgroundColour); + } + + void BeginFrame() + { + _implementation->BeginFrame(); + } + + void EndDrawing() + { + _implementation->EndDrawing(); + } + + void EndFrame() + { + _implementation->EndFrame(); + } + }; +} diff --git a/Graphics/include/NovelRT/Graphics/GraphicsDescriptorSet.hpp b/Graphics/include/NovelRT/Graphics/GraphicsDescriptorSet.hpp new file mode 100644 index 000000000..647c5c80f --- /dev/null +++ b/Graphics/include/NovelRT/Graphics/GraphicsDescriptorSet.hpp @@ -0,0 +1,50 @@ +#pragma once + +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#include +#include +#include + +namespace NovelRT::Graphics +{ + template class GraphicsBuffer; + template class GraphicsPipeline; + template class GraphicsTexture; + template struct GraphicsBackendTraits; + + //TODO: FIX BASE TYPING + template class GraphicsDescriptorSet + { + public: + using BackendDescriptorSetType = typename GraphicsBackendTraits::DescriptorSetType; + + private: + std::shared_ptr _implementation; + std::shared_ptr> _pipeline; + + using BackendMemoryRegionBaseType = typename GraphicsBackendTraits::ResourceMemoryRegionBaseType; + + public: + explicit GraphicsDescriptorSet(std::shared_ptr implementation, + std::shared_ptr> targetPipeline) noexcept + : _implementation(implementation), _pipeline(targetPipeline) + { + } + + void AddMemoryRegionToInputs(std::shared_ptr, TBackend>> region) + { + _implementation->AddMemoryRegionToInputs(region->GetImplementation()); + } + + void AddMemoryRegionsToInputs(NovelRT::Utilities::Misc::Span, TBackend>>> regions) + { + std::vector> args{}; + args.resize(regions.size()); + std::transform(regions.begin(), regions.end(), args.begin(), [&](auto x){ return x->GetImplementation(); }); + + _implementation->AddMemoryRegionsToInputs(args); + } + }; +} \ No newline at end of file diff --git a/Graphics/include/NovelRT/Graphics/GraphicsDevice.hpp b/Graphics/include/NovelRT/Graphics/GraphicsDevice.hpp new file mode 100644 index 000000000..2d7ac535f --- /dev/null +++ b/Graphics/include/NovelRT/Graphics/GraphicsDevice.hpp @@ -0,0 +1,136 @@ +#pragma once + +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace NovelRT::Graphics +{ + template class GraphicsAdapter; + template class GraphicsFence; + template class GraphicsSurfaceContext; + template class GraphicsContext; + template class GraphicsPipeline; + class GraphicsPipelineInput; + class GraphicsPipelineResource; + template class GraphicsPipelineSignature; + template class ShaderProgram; + + template struct GraphicsBackendTraits; + + template class GraphicsDevice : public std::enable_shared_from_this> + { + public: + using BackendDeviceType = typename GraphicsBackendTraits::DeviceType; + + private: + std::shared_ptr _implementation; + std::weak_ptr> _adapter; + std::shared_ptr> _surfaceContext; + + public: + GraphicsDevice(std::shared_ptr implementation, + std::weak_ptr> adapter, + std::shared_ptr> surfaceContext) + : _implementation(implementation), _adapter(adapter), _surfaceContext(surfaceContext) + { + if (_adapter.expired()) + { + throw Exceptions::NullPointerException("The supplied GraphicsAdapter is nullptr."); + } + + if (_surfaceContext == nullptr) + { + throw Exceptions::NullPointerException("The supplied GraphicsSurfaceContext is nullptr."); + } + } + + void TearDown() + { + _implementation->TearDown(); + } + + [[nodiscard]] std::shared_ptr> GetAdapter() const + { + if (_adapter.expired()) + { + throw std::runtime_error("Adapter has expired!"); + } + + return _adapter.lock(); + } + + [[nodiscard]] size_t GetContextIndex() const noexcept + { + return _implementation->GetContextIndex(); + } + + [[nodiscard]] NovelRT::Utilities::Misc::Span>> GetContexts() + { + return _implementation->GetContexts(); + } + + [[nodiscard]] inline std::shared_ptr> GetCurrentContext() + { + return GetContexts()[GetContextIndex()]; + } + + [[nodiscard]] inline std::shared_ptr GetSurface() const noexcept + { + return _surfaceContext->GetSurface(); + } + + [[nodiscard]] inline std::shared_ptr> GetSurfaceContext() const noexcept + { + return _surfaceContext; + } + + [[nodiscard]] std::shared_ptr> CreatePipeline( + std::shared_ptr> signature, + std::shared_ptr> vertexShader, + std::shared_ptr> pixelShader) + { + return _implementation->CreatePipeline(signature, vertexShader, pixelShader); + } + + [[nodiscard]] std::shared_ptr> CreatePipelineSignature( + GraphicsPipelineBlendFactor srcBlendFactor, + GraphicsPipelineBlendFactor dstBlendFactor, + NovelRT::Utilities::Misc::Span inputs, + NovelRT::Utilities::Misc::Span resources) + { + return _implementation->CreatePipelineSignature(srcBlendFactor, dstBlendFactor, inputs, resources); + } + + [[nodiscard]] std::shared_ptr> CreateShaderProgram( + std::string entryPointName, + ShaderProgramKind kind, + NovelRT::Utilities::Misc::Span byteData) + { + return _implementation->CreateShaderProgram(entryPointName, kind, byteData); + } + + void PresentFrame() + { + _implementation->PresentFrame(); + } + + void Signal(std::shared_ptr> fence) + { + _implementation->Signal(fence); + } + + void WaitForIdle() + { + _implementation->WaitForIdle(); + } + }; +} diff --git a/Graphics/include/NovelRT/Graphics/GraphicsDeviceObject.hpp b/Graphics/include/NovelRT/Graphics/GraphicsDeviceObject.hpp new file mode 100644 index 000000000..0caa299a5 --- /dev/null +++ b/Graphics/include/NovelRT/Graphics/GraphicsDeviceObject.hpp @@ -0,0 +1,38 @@ +#pragma once + +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#include +#include +#include + +namespace NovelRT::Graphics +{ + template struct GraphicsBackendTraits; + + template + class GraphicsDeviceObject : public std::enable_shared_from_this> + { + private: + std::weak_ptr> _graphicsDevice; + + public: + explicit GraphicsDeviceObject(std::shared_ptr> graphicsDevice) noexcept + : _graphicsDevice(graphicsDevice) + { + } + + virtual ~GraphicsDeviceObject() noexcept = default; + + [[nodiscard]] inline std::shared_ptr> GetDevice() const + { + if (_graphicsDevice.expired()) + { + throw std::runtime_error("The graphics device has expired!"); + } + + return _graphicsDevice.lock(); + } + }; +} diff --git a/Graphics/include/NovelRT/Graphics/GraphicsFence.hpp b/Graphics/include/NovelRT/Graphics/GraphicsFence.hpp new file mode 100644 index 000000000..da852def6 --- /dev/null +++ b/Graphics/include/NovelRT/Graphics/GraphicsFence.hpp @@ -0,0 +1,58 @@ +#pragma once + +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#include + +namespace NovelRT::Graphics +{ + template struct GraphicsBackendTraits; + + template class GraphicsFence : public GraphicsDeviceObject + { + public: + using BackendFenceType = typename GraphicsBackendTraits::FenceType; + + private: + std::shared_ptr _implementation; + + public: + GraphicsFence(std::shared_ptr implementation, std::shared_ptr> device) noexcept + : GraphicsDeviceObject(device), _implementation(implementation) + { + } + + virtual ~GraphicsFence() override = default; + + [[nodiscard]] bool GetIsSignalled() + { + return _implementation->GetIsSignalled(); + } + + void Reset() + { + _implementation->Reset(); + } + + [[nodiscard]] inline bool TryWait() + { + return TryWait(std::numeric_limits::max()); + } + + [[nodiscard]] bool TryWait(uint64_t millisecondsTimeout) + { + return _implementation->TryWait(millisecondsTimeout); + } + + [[nodiscard]] bool TryWait(std::chrono::duration timeout) + { + return _implementation->TryWait(timeout); + } + + inline void Wait() + { + Wait(std::numeric_limits::max()); + } + }; +} diff --git a/Graphics/include/NovelRT/Graphics/GraphicsMemoryAllocator.hpp b/Graphics/include/NovelRT/Graphics/GraphicsMemoryAllocator.hpp new file mode 100644 index 000000000..56eed30ca --- /dev/null +++ b/Graphics/include/NovelRT/Graphics/GraphicsMemoryAllocator.hpp @@ -0,0 +1,78 @@ +#pragma once + +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace NovelRT::Graphics +{ + template class GraphicsAdapter; + template class GraphicsDevice; + template class GraphicsProvider; + template class GraphicsBuffer; + struct GraphicsBufferCreateInfo; + template class GraphicsTexture; + struct GraphicsTextureCreateInfo; + + template struct GraphicsBackendTraits; + + template class GraphicsMemoryAllocator : public GraphicsDeviceObject + { + public: + using BackendMemoryAllocatorType = typename GraphicsBackendTraits::MemoryAllocator; + + private: + std::shared_ptr _implementation; + std::shared_ptr> _provider; + + public: + GraphicsMemoryAllocator(std::shared_ptr implementation, + std::shared_ptr> device, + std::shared_ptr> provider) + : GraphicsDeviceObject(device), _implementation(implementation), _provider(provider) + { + } + + [[nodiscard]] std::shared_ptr> GetProvider() const noexcept + { + return _provider; + } + + [[nodiscard]] std::shared_ptr> CreateBuffer(const GraphicsBufferCreateInfo& createInfo) + { + return _implementation->CreateBuffer(createInfo); + } + + [[nodiscard]] std::shared_ptr> CreateBuffer(GraphicsBufferKind bufferKind, + GraphicsResourceAccess cpuAccessKind, + GraphicsResourceAccess gpuAccessKind, + size_t size) + { + CreateBuffer(GraphicsBufferCreateInfo{bufferKind, cpuAccessKind, gpuAccessKind, size, + GraphicsMemoryRegionAllocationFlags::None}); + } + + [[nodiscard]] std::shared_ptr> CreateTexture( + const GraphicsTextureCreateInfo& createInfo) + { + return _implementation->CreateTexture(createInfo); + } + + [[nodiscard]] std::shared_ptr> CreateTexture2DRepeatGpuWriteOnly(uint32_t width, + uint32_t height = 1) + { + CreateTexture( + GraphicsTextureCreateInfo{GraphicsTextureAddressMode::Repeat, GraphicsTextureKind::TwoDimensional, + GraphicsResourceAccess::None, GraphicsResourceAccess::Write, width, height, 1, + GraphicsMemoryRegionAllocationFlags::None, TexelFormat::R8G8B8A8_UNORM}); + } + }; +} diff --git a/graphics/include/NovelRT/Graphics/GraphicsMemoryRegionAllocationFlags.hpp b/Graphics/include/NovelRT/Graphics/GraphicsMemoryRegionAllocationFlags.hpp similarity index 50% rename from graphics/include/NovelRT/Graphics/GraphicsMemoryRegionAllocationFlags.hpp rename to Graphics/include/NovelRT/Graphics/GraphicsMemoryRegionAllocationFlags.hpp index 250e94681..0572bb3d9 100644 --- a/graphics/include/NovelRT/Graphics/GraphicsMemoryRegionAllocationFlags.hpp +++ b/Graphics/include/NovelRT/Graphics/GraphicsMemoryRegionAllocationFlags.hpp @@ -1,12 +1,9 @@ +#pragma once + // Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root // for more information. -#ifndef NOVELRT_GRAPHICS_GRAPHICSMEMORYREGIONALLOCATIONFLAGS_H -#define NOVELRT_GRAPHICS_GRAPHICSMEMORYREGIONALLOCATIONFLAGS_H - -#ifndef NOVELRT_GRAPHICS_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.h instead for the Graphics namespace subset. -#endif +#include namespace NovelRT::Graphics { @@ -18,5 +15,3 @@ namespace NovelRT::Graphics WithinBudget = 1 << 2 }; } - -#endif // !NOVELRT_GRAPHICS_GRAPHICSMEMORYREGIONALLOCATIONFLAGS_H diff --git a/Graphics/include/NovelRT/Graphics/GraphicsPipeline.hpp b/Graphics/include/NovelRT/Graphics/GraphicsPipeline.hpp new file mode 100644 index 000000000..b4cdb233b --- /dev/null +++ b/Graphics/include/NovelRT/Graphics/GraphicsPipeline.hpp @@ -0,0 +1,58 @@ +#pragma once + +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#include + +namespace NovelRT::Graphics +{ + template struct GraphicsBackendTraits; + + template class GraphicsPipeline : public GraphicsDeviceObject + { + private: + std::shared_ptr> _signature; + std::shared_ptr> _vertexShader; + std::shared_ptr> _pixelShader; + + public: + GraphicsPipeline(std::shared_ptr> device, + std::shared_ptr> signature, + std::shared_ptr> vertexShader, + std::shared_ptr> pixelShader) noexcept + : GraphicsDeviceObject(device), + _signature(signature), + _vertexShader(vertexShader), + _pixelShader(pixelShader) + { + } + + virtual ~GraphicsPipeline() override = default; + + bool HasVertexShader() const noexcept + { + return _vertexShader != nullptr; + } + + bool HasPixelShader() const noexcept + { + return _pixelShader != nullptr; + } + + std::shared_ptr> GetVertexShader() const noexcept + { + return _vertexShader; + } + + std::shared_ptr> GetPixelShader() const noexcept + { + return _pixelShader; + } + + std::shared_ptr> GetSignature() const noexcept + { + return _signature; + } + }; +} diff --git a/graphics/include/NovelRT/Graphics/GraphicsPipelineBlendFactor.hpp b/Graphics/include/NovelRT/Graphics/GraphicsPipelineBlendFactor.hpp similarity index 69% rename from graphics/include/NovelRT/Graphics/GraphicsPipelineBlendFactor.hpp rename to Graphics/include/NovelRT/Graphics/GraphicsPipelineBlendFactor.hpp index 51d05cc2b..dd89747f5 100644 --- a/graphics/include/NovelRT/Graphics/GraphicsPipelineBlendFactor.hpp +++ b/Graphics/include/NovelRT/Graphics/GraphicsPipelineBlendFactor.hpp @@ -1,12 +1,9 @@ +#pragma once + // Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root // for more information. -#ifndef NOVELRT_GRAPHICS_GRAPHICSPIPELINEBLENDFACTOR_H -#define NOVELRT_GRAPHICS_GRAPHICSPIPELINEBLENDFACTOR_H - -#ifndef NOVELRT_GRAPHICS_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.h instead for the Graphics namespace subset. -#endif +#include namespace NovelRT::Graphics { @@ -34,5 +31,3 @@ namespace NovelRT::Graphics __COUNT }; } - -#endif // NOVELRT_GRAPHICS_GRAPHICSPIPELINEBLENDFACTOR_H diff --git a/graphics/include/NovelRT/Graphics/GraphicsPipelineInput.hpp b/Graphics/include/NovelRT/Graphics/GraphicsPipelineInput.hpp similarity index 63% rename from graphics/include/NovelRT/Graphics/GraphicsPipelineInput.hpp rename to Graphics/include/NovelRT/Graphics/GraphicsPipelineInput.hpp index 812c37ccc..5d5ed254d 100644 --- a/graphics/include/NovelRT/Graphics/GraphicsPipelineInput.hpp +++ b/Graphics/include/NovelRT/Graphics/GraphicsPipelineInput.hpp @@ -1,12 +1,11 @@ +#pragma once + // Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root // for more information. -#ifndef NOVELRT_GRAPHICS_GRAPHICSPIPELINEINPUT_H -#define NOVELRT_GRAPHICS_GRAPHICSPIPELINEINPUT_H - -#ifndef NOVELRT_GRAPHICS_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.h instead for the Graphics namespace subset. -#endif +#include +#include +#include namespace NovelRT::Graphics { @@ -22,5 +21,3 @@ namespace NovelRT::Graphics [[nodiscard]] NovelRT::Utilities::Misc::Span GetElements() const noexcept; }; } - -#endif // !NOVELRT_GRAPHICS_GRAPHICSPIPELINEINPUT_H diff --git a/graphics/include/NovelRT/Graphics/GraphicsPipelineInputElement.hpp b/Graphics/include/NovelRT/Graphics/GraphicsPipelineInputElement.hpp similarity index 66% rename from graphics/include/NovelRT/Graphics/GraphicsPipelineInputElement.hpp rename to Graphics/include/NovelRT/Graphics/GraphicsPipelineInputElement.hpp index 01869df82..b3d2b0cfa 100644 --- a/graphics/include/NovelRT/Graphics/GraphicsPipelineInputElement.hpp +++ b/Graphics/include/NovelRT/Graphics/GraphicsPipelineInputElement.hpp @@ -1,12 +1,11 @@ +#pragma once + // Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root // for more information. -#ifndef NOVELRT_GRAPHICS_GRAPHICSPIPELINEINPUTELEMENT_H -#define NOVELRT_GRAPHICS_GRAPHICSPIPELINEINPUTELEMENT_H - -#ifndef NOVELRT_GRAPHICS_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.h instead for the Graphics namespace subset. -#endif +#include +#include +#include namespace NovelRT::Graphics { @@ -24,5 +23,3 @@ namespace NovelRT::Graphics [[nodiscard]] size_t GetSize() const noexcept; }; } - -#endif // !NOVELRT_GRAPHICS_GRAPHICSPIPELINEINPUTELEMENT_H diff --git a/graphics/include/NovelRT/Graphics/GraphicsPipelineInputElementKind.hpp b/Graphics/include/NovelRT/Graphics/GraphicsPipelineInputElementKind.hpp similarity index 50% rename from graphics/include/NovelRT/Graphics/GraphicsPipelineInputElementKind.hpp rename to Graphics/include/NovelRT/Graphics/GraphicsPipelineInputElementKind.hpp index c7cd0efbc..b0727cd6a 100644 --- a/graphics/include/NovelRT/Graphics/GraphicsPipelineInputElementKind.hpp +++ b/Graphics/include/NovelRT/Graphics/GraphicsPipelineInputElementKind.hpp @@ -1,12 +1,9 @@ +#pragma once + // Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root // for more information. -#ifndef NOVELRT_GRAPHICS_GRAPHICSPIPELINEINPUTELEMENTKIND_H -#define NOVELRT_GRAPHICS_GRAPHICSPIPELINEINPUTELEMENTKIND_H - -#ifndef NOVELRT_GRAPHICS_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.h instead for the Graphics namespace subset. -#endif +#include namespace NovelRT::Graphics { @@ -19,5 +16,3 @@ namespace NovelRT::Graphics TextureCoordinate = 4 }; } - -#endif // !NOVELRT_GRAPHICS_GRAPHICSPIPELINEINPUTELEMENTKIND_H diff --git a/graphics/include/NovelRT/Graphics/GraphicsPipelineResource.hpp b/Graphics/include/NovelRT/Graphics/GraphicsPipelineResource.hpp similarity index 67% rename from graphics/include/NovelRT/Graphics/GraphicsPipelineResource.hpp rename to Graphics/include/NovelRT/Graphics/GraphicsPipelineResource.hpp index 0949cd298..8db38edc4 100644 --- a/graphics/include/NovelRT/Graphics/GraphicsPipelineResource.hpp +++ b/Graphics/include/NovelRT/Graphics/GraphicsPipelineResource.hpp @@ -1,12 +1,10 @@ +#pragma once + // Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root // for more information. -#ifndef NOVELRT_GRAPHICS_GRAPHICSPIPELINERESOURCE_H -#define NOVELRT_GRAPHICS_GRAPHICSPIPELINERESOURCE_H - -#ifndef NOVELRT_GRAPHICS_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.h instead for the Graphics namespace subset. -#endif +#include +#include namespace NovelRT::Graphics { @@ -26,5 +24,3 @@ namespace NovelRT::Graphics [[nodiscard]] ShaderProgramVisibility GetShaderProgramVisibility() const noexcept; }; } - -#endif // !NOVELRT_GRAPHICS_GRAPHICSPIPELINERESOURCE_H diff --git a/Graphics/include/NovelRT/Graphics/GraphicsPipelineResourceKind.hpp b/Graphics/include/NovelRT/Graphics/GraphicsPipelineResourceKind.hpp new file mode 100644 index 000000000..705d2b5d5 --- /dev/null +++ b/Graphics/include/NovelRT/Graphics/GraphicsPipelineResourceKind.hpp @@ -0,0 +1,16 @@ +#pragma once + +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#include + +namespace NovelRT::Graphics +{ + enum class GraphicsPipelineResourceKind : uint32_t + { + Unknown = 0, + ConstantBuffer = 1, + Texture = 2 + }; +} diff --git a/Graphics/include/NovelRT/Graphics/GraphicsPipelineSignature.hpp b/Graphics/include/NovelRT/Graphics/GraphicsPipelineSignature.hpp new file mode 100644 index 000000000..3af1a840c --- /dev/null +++ b/Graphics/include/NovelRT/Graphics/GraphicsPipelineSignature.hpp @@ -0,0 +1,74 @@ +#pragma once + +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#include +#include +#include + +namespace NovelRT::Graphics +{ + template class GraphicsDescriptorSet; + + template struct GraphicsBackendTraits; + + template class GraphicsPipelineSignature : public GraphicsDeviceObject + { + public: + using BackendPipelineSignatureType = typename GraphicsBackendTraits::PipelineSignatureType; + + private: + std::shared_ptr _implementation; + GraphicsPipelineBlendFactor _srcBlendFactor; + GraphicsPipelineBlendFactor _dstBlendFactor; + std::vector _inputs; + std::vector _resources; + + public: + GraphicsPipelineSignature(std::shared_ptr implementation, + std::shared_ptr> device, + GraphicsPipelineBlendFactor srcBlendFactor, + GraphicsPipelineBlendFactor dstBlendFactor, + NovelRT::Utilities::Misc::Span inputs, + NovelRT::Utilities::Misc::Span resources) noexcept + : GraphicsDeviceObject(device), + _implementation(implementation), + _srcBlendFactor(srcBlendFactor), + _dstBlendFactor(dstBlendFactor), + _inputs(std::vector(inputs.begin(), inputs.end())), + _resources(std::vector(resources.begin(), resources.end())) + { + } + + virtual ~GraphicsPipelineSignature() = default; + + [[nodiscard]] GraphicsPipelineBlendFactor GetSrcBlendFactor() const noexcept + { + return _srcBlendFactor; + } + + [[nodiscard]] GraphicsPipelineBlendFactor GetDstBlendFactor() const noexcept + { + return _dstBlendFactor; + } + + [[nodiscard]] std::shared_ptr> CreateDescriptorSet() + { + return _implementation->CreateDescriptorSet(); + } + + [[nodiscard]] NovelRT::Utilities::Misc::Span GetInputs() + const noexcept + { + return NovelRT::Utilities::Misc::Span(&(*_inputs.begin()), _inputs.size()); + } + + [[nodiscard]] NovelRT::Utilities::Misc::Span GetResources() + const noexcept + { + return NovelRT::Utilities::Misc::Span(&(*_resources.begin()), + _resources.size()); + } + }; +} diff --git a/Graphics/include/NovelRT/Graphics/GraphicsProvider.hpp b/Graphics/include/NovelRT/Graphics/GraphicsProvider.hpp new file mode 100644 index 000000000..c9b7bfa5f --- /dev/null +++ b/Graphics/include/NovelRT/Graphics/GraphicsProvider.hpp @@ -0,0 +1,116 @@ +#pragma once + +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#include +#include +#include + +namespace NovelRT::Graphics +{ + template class GraphicsAdapter; + template struct GraphicsBackendTraits; + template class GraphicsProvider; +} + +namespace NovelRT::Graphics::details +{ + template struct GraphicsAdapterIterator + { + private: + using BackendProviderType = typename GraphicsBackendTraits::ProviderType; + using BackendIteratorType = decltype(std::declval().begin()); + + BackendIteratorType _iterator; + std::shared_ptr> _provider; + + public: + GraphicsAdapterIterator(BackendIteratorType const& it, std::shared_ptr> provider) + : _iterator(it), _provider(provider) + { } + + using difference_type = typename std::iterator_traits::difference_type; + using value_type = std::shared_ptr>; + using pointer = void; + using reference = void; + using iterator_category = std::input_iterator_tag; + + inline bool operator==(GraphicsAdapterIterator const& other) + { + return _provider == other._provider + && _iterator == other._iterator; + } + + inline bool operator!=(GraphicsAdapterIterator const& other) + { + return _provider != other._provider + || _iterator != other._iterator; + } + + inline auto operator*() const + { + return std::make_shared>(*_iterator, _provider); + } + + inline auto operator++() + { + ++_iterator; + return *this; + } + + inline auto operator++(int) + { + auto prev = *this; + ++_iterator; + return prev; + } + }; +} + + +namespace NovelRT::Graphics +{ + template class GraphicsProvider : public std::enable_shared_from_this> + { + public: + using BackendProviderType = typename GraphicsBackendTraits::ProviderType; + + using iterator = typename details::GraphicsAdapterIterator; + + private: + std::shared_ptr _implementation; + bool _debugModeEnabled; + + public: + static inline const std::string EnableDebugModeSwitchName = + "NovelRT::Graphics::GraphicsProvider::EnableDebugMode"; + + GraphicsProvider(std::shared_ptr implementation) noexcept + : _implementation(implementation), _debugModeEnabled(EngineConfig::EnableDebugOutputFromEngineInternals()) + { + } + + virtual ~GraphicsProvider() = default; + + [[nodiscard]] bool GetDebugModeEnabled() const noexcept + { + return _debugModeEnabled; + } + + [[nodiscard]] iterator begin() noexcept + { + return iterator{_implementation->begin(), this->shared_from_this()}; + } + + [[nodiscard]] iterator end() noexcept + { + return iterator{_implementation->end(), this->shared_from_this()}; + } + + [[nodiscard]] uint32_t GetApiVersion() const noexcept + { + return _implementation->GetApiVersion(); + } + }; +} diff --git a/Graphics/include/NovelRT/Graphics/GraphicsResource.hpp b/Graphics/include/NovelRT/Graphics/GraphicsResource.hpp new file mode 100644 index 000000000..7c48c0b8e --- /dev/null +++ b/Graphics/include/NovelRT/Graphics/GraphicsResource.hpp @@ -0,0 +1,129 @@ +#pragma once + +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#include +#include +#include +#include +#include + +namespace NovelRT::Graphics +{ + template class GraphicsMemoryAllocator; + + template class GraphicsResourceMemoryRegion; + + template struct GraphicsBackendTraits; + + template class GraphicsResource : public GraphicsDeviceObject + { + public: + using BackendResourceType = typename GraphicsBackendTraits::ResourceType; + + protected: + std::shared_ptr _implementation; + + private: + std::shared_ptr> _allocator; + GraphicsResourceAccess _cpuAccess; + + public: + explicit GraphicsResource(std::shared_ptr implementation, + std::shared_ptr> allocator, + GraphicsResourceAccess cpuAccess) noexcept + : GraphicsDeviceObject(implementation->GetDevice()), + _implementation(implementation), + _allocator(allocator), + _cpuAccess(cpuAccess) + { + } + + virtual ~GraphicsResource() noexcept override = default; + + //[[nodiscard]] virtual size_t GetAlignment() const noexcept = 0; //TODO: Do we still need this? + [[nodiscard]] std::shared_ptr> GetAllocator() const noexcept + { + return _implementation->GetAllocator(); + } + + [[nodiscard]] GraphicsResourceAccess GetCpuAccess() const noexcept + { + return _implementation->GetCpuAccess(); + } + + [[nodiscard]] size_t GetDeviceMemoryOffset() const noexcept + { + return _implementation->GetDeviceMemoryOffset(); + } + + [[nodiscard]] size_t GetSize() const noexcept + { + return _implementation->GetSize(); + } + + [[nodiscard]] std::shared_ptr> Allocate( + size_t size, + size_t alignment) + { + return _implementation->Allocate(size, alignment); + } + + [[nodiscard]] Utilities::Misc::Span MapBytes() + { + return MapBytes(0, GetSize()); + } + + [[nodiscard]] virtual Utilities::Misc::Span MapBytes(size_t rangeOffset, size_t rangeLength) + { + return _implementation->MapBytes(rangeOffset, rangeLength); + } + + [[nodiscard]] Utilities::Misc::Span MapBytesForRead() + { + return MapBytesForRead(0, GetSize()); + } + + [[nodiscard]] Utilities::Misc::Span MapBytesForRead(size_t rangeOffset, size_t rangeLength) + { + return _implementation->MapBytesForRead(rangeOffset, rangeLength); + } + + void UnmapBytes() + { + return _implementation->UnmapBytes(); + } + + void UnmapBytesAndWrite() + { + UnmapBytesAndWrite(0, GetSize()); + } + + void UnmapBytesAndWrite(size_t writtenRangeOffset, size_t writtenRangeLength) + { + return _implementation->UnmapBytesAndWrite(writtenRangeOffset, writtenRangeLength); + } + + template [[nodiscard]] Utilities::Misc::Span Map() + { + return Utilities::Misc::SpanCast(MapBytes()); + } + + template [[nodiscard]] Utilities::Misc::Span Map(size_t rangeOffset, size_t rangeLength) + { + return Utilities::Misc::SpanCast(MapBytes(rangeOffset, rangeLength)); + } + + template [[nodiscard]] Utilities::Misc::Span MapForRead() + { + return Utilities::Misc::SpanCast(MapBytesForRead()); + } + + template + [[nodiscard]] Utilities::Misc::Span MapForRead(size_t rangeOffset, size_t rangeLength) + { + return Utilities::Misc::SpanCast(MapBytesForRead(rangeOffset, rangeLength)); + } + }; +} diff --git a/graphics/include/NovelRT/Graphics/GraphicsResourceAccess.hpp b/Graphics/include/NovelRT/Graphics/GraphicsResourceAccess.hpp similarity index 51% rename from graphics/include/NovelRT/Graphics/GraphicsResourceAccess.hpp rename to Graphics/include/NovelRT/Graphics/GraphicsResourceAccess.hpp index 4c6b747e8..ed48f4737 100644 --- a/graphics/include/NovelRT/Graphics/GraphicsResourceAccess.hpp +++ b/Graphics/include/NovelRT/Graphics/GraphicsResourceAccess.hpp @@ -1,12 +1,9 @@ +#pragma once + // Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root // for more information. -#ifndef NOVELRT_GRAPHICS_GRAPHICSRESOURCEACCESS_H -#define NOVELRT_GRAPHICS_GRAPHICSRESOURCEACCESS_H - -#ifndef NOVELRT_GRAPHICS_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.h instead for the Graphics namespace subset. -#endif +#include namespace NovelRT::Graphics { @@ -18,5 +15,3 @@ namespace NovelRT::Graphics ReadWrite = Read | Write, }; } - -#endif // !NOVELRT_GRAPHICS_GRAPHICSRESOURCEACCESS_H diff --git a/Graphics/include/NovelRT/Graphics/GraphicsResourceMemoryRegion.hpp b/Graphics/include/NovelRT/Graphics/GraphicsResourceMemoryRegion.hpp new file mode 100644 index 000000000..b34aa2e00 --- /dev/null +++ b/Graphics/include/NovelRT/Graphics/GraphicsResourceMemoryRegion.hpp @@ -0,0 +1,83 @@ +#pragma once + +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#include +#include +#include + +namespace NovelRT::Graphics +{ + template class GraphicsResource; + + template struct GraphicsBackendTraits; + + template + class GraphicsResourceMemoryRegion : public GraphicsDeviceObject + { + static_assert(std::is_base_of_v, TResource>, + "Incompatible type specified as the resource type."); + + public: + using BackendResourceMemoryRegionType = typename GraphicsBackendTraits::ResourceMemoryRegionType; + + private: + std::shared_ptr _implementation; + std::shared_ptr _owningResource; + + public: + GraphicsResourceMemoryRegion(std::shared_ptr implementation, + std::shared_ptr owningResource) + : GraphicsDeviceObject(implementation->GetDevice()), + _implementation(implementation), + _owningResource(owningResource) + { + } + + [[nodiscard]] std::shared_ptr GetOwningResource() const noexcept + { + return _owningResource; + } + + [[nodiscard]] size_t GetRelativeOffset() const noexcept + { + return _implementation->GetRelativeOffset(); + } + + [[nodiscard]] virtual size_t GetSize() const noexcept + { + return _implementation->GetSize(); + } + + [[nodiscard]] Utilities::Misc::Span MapBytes() + { + return _implementation->MapBytes(GetRelativeOffset(), GetSize()); + } + + [[nodiscard]] Utilities::Misc::Span MapBytesForRead() + { + return _implementation->MapBytesForRead(GetRelativeOffset(), GetSize()); + } + + void UnmapBytes() + { + _implementation->UnmapBytes(); + } + + void UnmapBytesAndWrite() + { + _implementation->UnmapBytesAndWrite(GetRelativeOffset(), GetSize()); + } + + template [[nodiscard]] Utilities::Misc::Span Map() + { + return Utilities::Misc::SpanCast(MapBytes()); + } + + template [[nodiscard]] Utilities::Misc::Span MapForRead() + { + return Utilities::Misc::SpanCast(MapBytesForRead()); + } + }; +} diff --git a/Graphics/include/NovelRT/Graphics/GraphicsSurfaceContext.hpp b/Graphics/include/NovelRT/Graphics/GraphicsSurfaceContext.hpp new file mode 100644 index 000000000..043dd8b0f --- /dev/null +++ b/Graphics/include/NovelRT/Graphics/GraphicsSurfaceContext.hpp @@ -0,0 +1,71 @@ +#pragma once + +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#include +#include + +namespace NovelRT::PluginManagement +{ + template class IGraphicsPluginProvider; +} + +namespace NovelRT::Graphics +{ + template struct GraphicsBackendTraits; + + template class GraphicsSurfaceContext + { + public: + using BackendSurfaceContextType = typename GraphicsBackendTraits::SurfaceContextType; + + private: + std::shared_ptr _implementation; + std::shared_ptr _surface; + std::shared_ptr> _provider; + + friend class NovelRT::PluginManagement::IGraphicsPluginProvider; + + public: + GraphicsSurfaceContext(std::shared_ptr implementation, + std::shared_ptr surface, + std::shared_ptr> provider) + : _implementation(implementation), _surface(surface), _provider(provider) + { + if (_surface == nullptr) + { + throw Exceptions::NullPointerException("The supplied IGraphicsSurface is nullptr."); + } + + if (_provider == nullptr) + { + throw Exceptions::NullPointerException("The supplied GraphicsProvider is nullptr."); + } + } + + [[nodiscard]] std::shared_ptr GetImplementation() const noexcept + { + return _implementation; + } + + [[nodiscard]] std::shared_ptr GetSurface() const noexcept + { + return _surface; + } + [[nodiscard]] std::shared_ptr> GetProvider() const noexcept + { + return _provider; + } + + [[nodiscard]] void* GetSurfaceContextHandleUntyped() + { + return _implementation->GetSurfaceContextHandleUntyped(); + } + + template [[nodiscard]] THandleType GetSurfaceContextHandleAs() + { + return *reinterpret_cast(GetSurfaceContextHandleUntyped()); + } + }; +} diff --git a/graphics/include/NovelRT/Graphics/GraphicsSurfaceKind.hpp b/Graphics/include/NovelRT/Graphics/GraphicsSurfaceKind.hpp similarity index 53% rename from graphics/include/NovelRT/Graphics/GraphicsSurfaceKind.hpp rename to Graphics/include/NovelRT/Graphics/GraphicsSurfaceKind.hpp index ed2f47915..40269893a 100644 --- a/graphics/include/NovelRT/Graphics/GraphicsSurfaceKind.hpp +++ b/Graphics/include/NovelRT/Graphics/GraphicsSurfaceKind.hpp @@ -1,12 +1,9 @@ +#pragma once + // Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root // for more information. -#ifndef NOVELRT_GRAPHICS_GRAPHICSSURFACEKIND_H -#define NOVELRT_GRAPHICS_GRAPHICSSURFACEKIND_H - -#ifndef NOVELRT_GRAPHICS_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.h instead for the Graphics namespace subset. -#endif +#include namespace NovelRT::Graphics { @@ -21,5 +18,3 @@ namespace NovelRT::Graphics Glfw = 6 }; } - -#endif // !NOVELRT_GRAPHICS_GRAPHICSSURFACEKIND_H diff --git a/Graphics/include/NovelRT/Graphics/GraphicsTexture.hpp b/Graphics/include/NovelRT/Graphics/GraphicsTexture.hpp new file mode 100644 index 000000000..fda10801c --- /dev/null +++ b/Graphics/include/NovelRT/Graphics/GraphicsTexture.hpp @@ -0,0 +1,84 @@ +#pragma once + +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#include +#include +#include +#include +#include +#include + +namespace NovelRT::Graphics +{ + template class GraphicsResourceMemoryRegion; + + template struct GraphicsBackendTraits; + + template class GraphicsTexture : public GraphicsResource + { + public: + using BackendTextureType = typename GraphicsBackendTraits::TextureType; + using BackendResourceMemoryRegionType = typename GraphicsBackendTraits::ResourceMemoryRegionType; + + private: + GraphicsTextureAddressMode _addressMode; + GraphicsTextureKind _kind; + uint32_t _width; + uint32_t _height; + uint16_t _depth; + + public: + GraphicsTexture(std::shared_ptr implementation, + std::shared_ptr> allocator, + GraphicsResourceAccess cpuAccess, + GraphicsTextureAddressMode addressMode, + GraphicsTextureKind kind, + uint32_t width, + uint32_t height, + uint16_t depth) noexcept + : GraphicsResource(implementation, allocator, cpuAccess), + _addressMode(addressMode), + _kind(kind), + _width(width), + _height(height), + _depth(depth) + { + } + + virtual ~GraphicsTexture() noexcept override = default; + + [[nodiscard]] std::shared_ptr> Allocate( + size_t size, + size_t alignment) + { + return GraphicsResource::_implementation->Allocate(size, alignment); + } + + [[nodiscard]] GraphicsTextureAddressMode GetAddressMode() const noexcept + { + return _addressMode; + } + + [[nodiscard]] GraphicsTextureKind GetKind() const noexcept + { + return _kind; + } + + [[nodiscard]] uint32_t GetWidth() const noexcept + { + return _width; + } + + [[nodiscard]] uint32_t GetHeight() const noexcept + { + return _height; + } + + [[nodiscard]] uint16_t GetDepth() const noexcept + { + return _depth; + } + }; +} diff --git a/graphics/include/NovelRT/Graphics/GraphicsTextureAddressMode.hpp b/Graphics/include/NovelRT/Graphics/GraphicsTextureAddressMode.hpp similarity index 54% rename from graphics/include/NovelRT/Graphics/GraphicsTextureAddressMode.hpp rename to Graphics/include/NovelRT/Graphics/GraphicsTextureAddressMode.hpp index 4d01185a2..8b4f7a8c6 100644 --- a/graphics/include/NovelRT/Graphics/GraphicsTextureAddressMode.hpp +++ b/Graphics/include/NovelRT/Graphics/GraphicsTextureAddressMode.hpp @@ -1,12 +1,9 @@ +#pragma once + // Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root // for more information. -#ifndef NOVELRT_GRAPHICS_GRAPHICSTEXTUREADDRESSMODE_H -#define NOVELRT_GRAPHICS_GRAPHICSTEXTUREADDRESSMODE_H - -#ifndef NOVELRT_GRAPHICS_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.h instead for the Graphics namespace subset. -#endif +#include namespace NovelRT::Graphics { @@ -20,5 +17,3 @@ namespace NovelRT::Graphics MirrorClampToEdge = 4 }; } - -#endif // NOVELRT_GRAPHICS_GRAPHICSTEXTUREADDRESSMODE_H diff --git a/Graphics/include/NovelRT/Graphics/GraphicsTextureCreateInfo.hpp b/Graphics/include/NovelRT/Graphics/GraphicsTextureCreateInfo.hpp new file mode 100644 index 000000000..62db64445 --- /dev/null +++ b/Graphics/include/NovelRT/Graphics/GraphicsTextureCreateInfo.hpp @@ -0,0 +1,27 @@ +#pragma once + +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#include +#include +#include +#include +#include +#include + +namespace NovelRT::Graphics +{ + struct GraphicsTextureCreateInfo + { + GraphicsTextureAddressMode addressMode; + GraphicsTextureKind textureKind; + GraphicsResourceAccess cpuAccessKind; + GraphicsResourceAccess gpuAccessKind; + uint32_t width; + uint32_t height; + uint32_t depth; + GraphicsMemoryRegionAllocationFlags allocationFlags; + TexelFormat texelFormat; + }; +} \ No newline at end of file diff --git a/graphics/include/NovelRT/Graphics/GraphicsTextureKind.hpp b/Graphics/include/NovelRT/Graphics/GraphicsTextureKind.hpp similarity index 52% rename from graphics/include/NovelRT/Graphics/GraphicsTextureKind.hpp rename to Graphics/include/NovelRT/Graphics/GraphicsTextureKind.hpp index dedd6427d..6fba786e6 100644 --- a/graphics/include/NovelRT/Graphics/GraphicsTextureKind.hpp +++ b/Graphics/include/NovelRT/Graphics/GraphicsTextureKind.hpp @@ -1,12 +1,9 @@ +#pragma once + // Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root // for more information. -#ifndef NOVELRT_GRAPHICS_GRAPHICSTEXTUREKIND_H -#define NOVELRT_GRAPHICS_GRAPHICSTEXTUREKIND_H - -#ifndef NOVELRT_GRAPHICS_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.h instead for the Graphics namespace subset. -#endif +#include namespace NovelRT::Graphics { @@ -18,5 +15,3 @@ namespace NovelRT::Graphics ThreeDimensional = 3 }; } - -#endif // !NOVELRT_GRAPHICS_GRAPHICSTEXTUREKIND_H diff --git a/Graphics/include/NovelRT/Graphics/IGraphicsAdapterSelector.hpp b/Graphics/include/NovelRT/Graphics/IGraphicsAdapterSelector.hpp new file mode 100644 index 000000000..256d807b8 --- /dev/null +++ b/Graphics/include/NovelRT/Graphics/IGraphicsAdapterSelector.hpp @@ -0,0 +1,33 @@ +#pragma once + +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#include + +namespace NovelRT::Graphics +{ + template class GraphicsAdapter; + template class GraphicsProvider; + template class GraphicsSurfaceContext; + + template struct GraphicsBackendTraits; + + template class IGraphicsAdapterSelector + { + public: + using BackendAdapterSelectorType = typename GraphicsBackendTraits::AdapterSelectorType; + + private: + std::shared_ptr _implementation; + + + public: + [[nodiscard]] virtual std::shared_ptr> GetDefaultRecommendedAdapter( + std::shared_ptr> provider, + std::shared_ptr> surfaceContext) const + { + return _implementation->GetDefaultRecommendedAdapter(provider, surfaceContext); + } + }; +} diff --git a/graphics/include/NovelRT/Graphics/IGraphicsSurface.hpp b/Graphics/include/NovelRT/Graphics/IGraphicsSurface.hpp similarity index 72% rename from graphics/include/NovelRT/Graphics/IGraphicsSurface.hpp rename to Graphics/include/NovelRT/Graphics/IGraphicsSurface.hpp index c9e2b4c4d..fe8e8d1ea 100644 --- a/graphics/include/NovelRT/Graphics/IGraphicsSurface.hpp +++ b/Graphics/include/NovelRT/Graphics/IGraphicsSurface.hpp @@ -1,12 +1,11 @@ +#pragma once + // Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root // for more information. -#ifndef NOVELRT_GRAPHICS_IGRAPHICSSURFACE_H -#define NOVELRT_GRAPHICS_IGRAPHICSSURFACE_H - -#ifndef NOVELRT_GRAPHICS_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.h instead for the Graphics namespace subset. -#endif +#include +#include +#include namespace NovelRT::Graphics { @@ -32,5 +31,3 @@ namespace NovelRT::Graphics [[nodiscard]] virtual GraphicsSurfaceKind GetKind() const noexcept = 0; }; } - -#endif // !NOVELRT_GRAPHICS_IGRAPHICSSURFACE_H diff --git a/graphics/include/NovelRT/Graphics/Metal/Utilities/PipelineBlendFactor.hpp b/Graphics/include/NovelRT/Graphics/Metal/Utilities/PipelineBlendFactor.hpp similarity index 83% rename from graphics/include/NovelRT/Graphics/Metal/Utilities/PipelineBlendFactor.hpp rename to Graphics/include/NovelRT/Graphics/Metal/Utilities/PipelineBlendFactor.hpp index 2a4256fda..70656ef7c 100644 --- a/graphics/include/NovelRT/Graphics/Metal/Utilities/PipelineBlendFactor.hpp +++ b/Graphics/include/NovelRT/Graphics/Metal/Utilities/PipelineBlendFactor.hpp @@ -1,12 +1,10 @@ +#pragma once + // Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root // for more information. -#ifndef NOVELRT_GRAPHICS_METAL_UTILITIES_PIPELINEBLENDFACTOR_H -#define NOVELRT_GRAPHICS_METAL_UTILITIES_PIPELINEBLENDFACTOR_H - -#ifndef NOVELRT_GRAPHICS_METAL_UTILITIES_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.Metal.Utilities.h instead for the Graphics::Metal::Utilities namespace subset. -#endif +#include +#include namespace NovelRT::Graphics::Metal::Utilities { @@ -44,5 +42,3 @@ namespace NovelRT::Graphics::Metal::Utilities return NovelRTToMetalBlend[static_cast(blendFactor)]; } } - -#endif // !NOVELRT_GRAPHICS_METAL_UTILITIES_PIPELINEBLENDFACTOR_H diff --git a/graphics/include/NovelRT/Graphics/RGBAColour.hpp b/Graphics/include/NovelRT/Graphics/RGBAColour.hpp similarity index 89% rename from graphics/include/NovelRT/Graphics/RGBAColour.hpp rename to Graphics/include/NovelRT/Graphics/RGBAColour.hpp index 67d730ef6..c28d7ea83 100644 --- a/graphics/include/NovelRT/Graphics/RGBAColour.hpp +++ b/Graphics/include/NovelRT/Graphics/RGBAColour.hpp @@ -1,9 +1,8 @@ +#pragma once + // Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root // for more information. -#ifndef NOVELRT_GRAPHICS_RGBACOLOUR_H -#define NOVELRT_GRAPHICS_RGBACOLOUR_H - #include namespace NovelRT::Graphics @@ -42,5 +41,3 @@ namespace NovelRT::Graphics } }; } - -#endif // NOVELRT_GRAPHICS_RGBACOLOUR_H diff --git a/Graphics/include/NovelRT/Graphics/ShaderProgram.hpp b/Graphics/include/NovelRT/Graphics/ShaderProgram.hpp new file mode 100644 index 000000000..a3975640c --- /dev/null +++ b/Graphics/include/NovelRT/Graphics/ShaderProgram.hpp @@ -0,0 +1,52 @@ +#pragma once + +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#include +#include + +namespace NovelRT::Graphics +{ + template struct GraphicsBackendTraits; + + template class ShaderProgram : public GraphicsDeviceObject + { + public: + using BackendShaderProgramType = typename GraphicsBackendTraits::ShaderProgramType; + + private: + std::shared_ptr _implementation; + std::string _entryPointName; + ShaderProgramKind _kind; + + public: + ShaderProgram(std::shared_ptr implementation, + std::shared_ptr> device, + std::string entryPointName, + ShaderProgramKind kind) noexcept + : GraphicsDeviceObject(std::move(device)), + _implementation(implementation), + _entryPointName(entryPointName), + _kind(kind) + { + } + + virtual ~ShaderProgram() override = default; + + [[nodiscard]] const std::string& GetEntryPointName() const noexcept + { + return _entryPointName; + } + + [[nodiscard]] ShaderProgramKind GetKind() const noexcept + { + return _kind; + } + + [[nodiscard]] NovelRT::Utilities::Misc::Span GetBytecode() const noexcept + { + return _implementation->GetBytecode(); + } + }; +} diff --git a/graphics/include/NovelRT/Graphics/ShaderProgramKind.hpp b/Graphics/include/NovelRT/Graphics/ShaderProgramKind.hpp similarity index 50% rename from graphics/include/NovelRT/Graphics/ShaderProgramKind.hpp rename to Graphics/include/NovelRT/Graphics/ShaderProgramKind.hpp index ae3a8c5db..c3dfddb23 100644 --- a/graphics/include/NovelRT/Graphics/ShaderProgramKind.hpp +++ b/Graphics/include/NovelRT/Graphics/ShaderProgramKind.hpp @@ -1,12 +1,9 @@ +#pragma once + // Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root // for more information. -#ifndef NOVELRT_GRAPHICS_SHADERPROGRAMKIND_H -#define NOVELRT_GRAPHICS_SHADERPROGRAMKIND_H - -#ifndef NOVELRT_GRAPHICS_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.h instead for the Graphics namespace subset. -#endif +#include namespace NovelRT::Graphics { @@ -18,5 +15,3 @@ namespace NovelRT::Graphics Fragment = Pixel }; } - -#endif // !NOVELRT_GRAPHICS_SHADERPROGRAMKIND_H diff --git a/graphics/include/NovelRT/Graphics/ShaderProgramVisibility.hpp b/Graphics/include/NovelRT/Graphics/ShaderProgramVisibility.hpp similarity index 53% rename from graphics/include/NovelRT/Graphics/ShaderProgramVisibility.hpp rename to Graphics/include/NovelRT/Graphics/ShaderProgramVisibility.hpp index d46dd1707..324bd9a94 100644 --- a/graphics/include/NovelRT/Graphics/ShaderProgramVisibility.hpp +++ b/Graphics/include/NovelRT/Graphics/ShaderProgramVisibility.hpp @@ -1,12 +1,9 @@ +#pragma once + // Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root // for more information. -#ifndef NOVELRT_GRAPHICS_SHADERPROGRAMVISIBILITY_H -#define NOVELRT_GRAPHICS_SHADERPROGRAMVISIBILITY_H - -#ifndef NOVELRT_GRAPHICS_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.h instead for the Graphics namespace subset. -#endif +#include namespace NovelRT::Graphics { @@ -19,5 +16,3 @@ namespace NovelRT::Graphics All = Vertex | Pixel }; } - -#endif // !NOVELRT_GRAPHICS_SHADERPROGRAMVISIBILITY_H diff --git a/graphics/include/NovelRT/Graphics/TexelFormat.hpp b/Graphics/include/NovelRT/Graphics/TexelFormat.hpp similarity index 50% rename from graphics/include/NovelRT/Graphics/TexelFormat.hpp rename to Graphics/include/NovelRT/Graphics/TexelFormat.hpp index 63788825d..fd8041696 100644 --- a/graphics/include/NovelRT/Graphics/TexelFormat.hpp +++ b/Graphics/include/NovelRT/Graphics/TexelFormat.hpp @@ -1,12 +1,9 @@ +#pragma once + // Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root // for more information. -#ifndef NOVELRT_GRAPHICS_TEXELFORMAT_H -#define NOVELRT_GRAPHICS_TEXELFORMAT_H - -#ifndef NOVELRT_GRAPHICS_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.h instead for the Graphics namespace subset. -#endif +#include namespace NovelRT::Graphics { @@ -17,5 +14,3 @@ namespace NovelRT::Graphics R16G16UINT, }; } - -#endif // NOVELRT_GRAPHICS_TEXELFORMAT_H diff --git a/graphics/include/NovelRT/Graphics/Vulkan/QueueFamilyIndices.hpp b/Graphics/include/NovelRT/Graphics/Vulkan/QueueFamilyIndices.hpp similarity index 57% rename from graphics/include/NovelRT/Graphics/Vulkan/QueueFamilyIndices.hpp rename to Graphics/include/NovelRT/Graphics/Vulkan/QueueFamilyIndices.hpp index f4e02a7ed..fc0af4137 100644 --- a/graphics/include/NovelRT/Graphics/Vulkan/QueueFamilyIndices.hpp +++ b/Graphics/include/NovelRT/Graphics/Vulkan/QueueFamilyIndices.hpp @@ -1,12 +1,9 @@ +#pragma once + // Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root // for more information. -#ifndef NOVELRT_GRAPHICS_VULKAN_QUEUEFAMILYINDICES_H -#define NOVELRT_GRAPHICS_VULKAN_QUEUEFAMILYINDICES_H - -#ifndef NOVELRT_GRAPHICS_VULKAN_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.Vulkan.h instead for the Graphics::Vulkan namespace subset. -#endif +#include namespace NovelRT::Graphics::Vulkan { @@ -21,5 +18,3 @@ namespace NovelRT::Graphics::Vulkan } }; } - -#endif // NOVELRT_GRAPHICS_VULKAN_QUEUEFAMILYINDICES_H diff --git a/graphics/include/NovelRT/Graphics/Vulkan/SwapChainSupportDetails.hpp b/Graphics/include/NovelRT/Graphics/Vulkan/SwapChainSupportDetails.hpp similarity index 50% rename from graphics/include/NovelRT/Graphics/Vulkan/SwapChainSupportDetails.hpp rename to Graphics/include/NovelRT/Graphics/Vulkan/SwapChainSupportDetails.hpp index 53515bada..8085911a4 100644 --- a/graphics/include/NovelRT/Graphics/Vulkan/SwapChainSupportDetails.hpp +++ b/Graphics/include/NovelRT/Graphics/Vulkan/SwapChainSupportDetails.hpp @@ -1,12 +1,10 @@ +#pragma once + // Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root // for more information. -#ifndef NOVELRT_GRAPHICS_VULKAN_SWAPCHAINSUPPORTDETAILS_H -#define NOVELRT_GRAPHICS_VULKAN_SWAPCHAINSUPPORTDETAILS_H - -#ifndef NOVELRT_GRAPHICS_VULKAN_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.Vulkan.h instead for the Graphics::Vulkan namespace subset. -#endif +#include +#include namespace NovelRT::Graphics::Vulkan { @@ -17,5 +15,3 @@ namespace NovelRT::Graphics::Vulkan std::vector presentModes; }; } - -#endif // NOVELRT_GRAPHICS_VULKAN_SWAPCHAINSUPPORTDETAILS_H diff --git a/graphics/include/NovelRT/Graphics/Vulkan/Utilities/BufferUsageKind.hpp b/Graphics/include/NovelRT/Graphics/Vulkan/Utilities/BufferUsageKind.hpp similarity index 81% rename from graphics/include/NovelRT/Graphics/Vulkan/Utilities/BufferUsageKind.hpp rename to Graphics/include/NovelRT/Graphics/Vulkan/Utilities/BufferUsageKind.hpp index 8d225ae72..acbf94b50 100644 --- a/graphics/include/NovelRT/Graphics/Vulkan/Utilities/BufferUsageKind.hpp +++ b/Graphics/include/NovelRT/Graphics/Vulkan/Utilities/BufferUsageKind.hpp @@ -1,17 +1,20 @@ +#pragma once + // Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root // for more information. -#ifndef NOVELRT_GRAPHICS_VULKAN_UTILITIES_BUFFERUSAGEKIND_H -#define NOVELRT_GRAPHICS_VULKAN_UTILITIES_BUFFERUSAGEKIND_H - -#ifndef NOVELRT_GRAPHICS_VULKAN_UTILITIES_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.Vulkan.Utilities.h instead for the Graphics::Vulkan::Utilities namespace subset. -#endif +#include +#include +#include +#include +#include +#include // we need this for the bitwise logic +#include namespace NovelRT::Graphics::Vulkan::Utilities { [[nodiscard]] inline uint32_t GetVulkanBufferUsageKind(GraphicsBufferKind kind, - GraphicsResourceAccess gpuAccess) noexcept + GraphicsResourceAccess resourceAccessType) noexcept { VkBufferUsageFlagBits vulkanBufferUsageKind = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; @@ -34,7 +37,7 @@ namespace NovelRT::Graphics::Vulkan::Utilities VkBufferUsageFlagBits cpuAccessBit = VK_BUFFER_USAGE_TRANSFER_DST_BIT; - switch (gpuAccess) + switch (resourceAccessType) { case GraphicsResourceAccess::Read: cpuAccessBit = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; @@ -56,11 +59,11 @@ namespace NovelRT::Graphics::Vulkan::Utilities } [[nodiscard]] inline uint32_t GetVulkanImageUsageKind(GraphicsTextureKind /*kind*/, - GraphicsResourceAccess gpuAccess) noexcept + GraphicsResourceAccess resourceAccessType) noexcept { VkImageUsageFlagBits cpuAccessBit = VK_IMAGE_USAGE_TRANSFER_DST_BIT; - switch (gpuAccess) + switch (resourceAccessType) { case GraphicsResourceAccess::Read: cpuAccessBit = VK_IMAGE_USAGE_TRANSFER_SRC_BIT; @@ -80,6 +83,11 @@ namespace NovelRT::Graphics::Vulkan::Utilities cpuAccessBit |= static_cast(VK_IMAGE_USAGE_SAMPLED_BIT); return static_cast(cpuAccessBit); } -} -#endif // NOVELRT_GRAPHICS_VULKAN_UTILITIES_BUFFERUSAGEKIND_H + [[nodiscard]] inline uint32_t GetVmaAllocationKind(GraphicsResourceAccess resourceAccessType) noexcept + { + unused(resourceAccessType); + // TODO: this + return 0; + } +} diff --git a/graphics/include/NovelRT/Graphics/Vulkan/Utilities/PipelineBlendFactor.hpp b/Graphics/include/NovelRT/Graphics/Vulkan/Utilities/PipelineBlendFactor.hpp similarity index 83% rename from graphics/include/NovelRT/Graphics/Vulkan/Utilities/PipelineBlendFactor.hpp rename to Graphics/include/NovelRT/Graphics/Vulkan/Utilities/PipelineBlendFactor.hpp index 14b7ff989..4eafc22f6 100644 --- a/graphics/include/NovelRT/Graphics/Vulkan/Utilities/PipelineBlendFactor.hpp +++ b/Graphics/include/NovelRT/Graphics/Vulkan/Utilities/PipelineBlendFactor.hpp @@ -1,12 +1,11 @@ +#pragma once + // Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root // for more information. -#ifndef NOVELRT_GRAPHICS_VULKAN_UTILITIES_PIPELINEBLENDFACTOR_H -#define NOVELRT_GRAPHICS_VULKAN_UTILITIES_PIPELINEBLENDFACTOR_H - -#ifndef NOVELRT_GRAPHICS_VULKAN_UTILITIES_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.Vulkan.Utilities.h instead for the Graphics::Vulkan::Utilities namespace subset. -#endif +#include +#include +#include namespace NovelRT::Graphics::Vulkan::Utilities { @@ -44,5 +43,3 @@ namespace NovelRT::Graphics::Vulkan::Utilities return NovelRTToVulkanBlend[static_cast(blendFactor)]; } } - -#endif // !NOVELRT_GRAPHICS_VULKAN_UTILITIES_PIPELINEBLENDFACTOR_H diff --git a/graphics/include/NovelRT/Graphics/Vulkan/Utilities/Support.hpp b/Graphics/include/NovelRT/Graphics/Vulkan/Utilities/Support.hpp similarity index 87% rename from graphics/include/NovelRT/Graphics/Vulkan/Utilities/Support.hpp rename to Graphics/include/NovelRT/Graphics/Vulkan/Utilities/Support.hpp index a89cc1ebc..2991d2867 100644 --- a/graphics/include/NovelRT/Graphics/Vulkan/Utilities/Support.hpp +++ b/Graphics/include/NovelRT/Graphics/Vulkan/Utilities/Support.hpp @@ -1,12 +1,12 @@ +#pragma once + // Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root // for more information. -#ifndef NOVELRT_GRAPHICS_VULKAN_UTILITIES_SUPPORT_H -#define NOVELRT_GRAPHICS_VULKAN_UTILITIES_SUPPORT_H - -#ifndef NOVELRT_GRAPHICS_VULKAN_UTILITIES_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.Vulkan.Utilities.h instead for the Graphics::Vulkan::Utilities namespace subset. -#endif +#include +#include +#include +#include namespace NovelRT::Graphics::Vulkan::Utilities { @@ -76,5 +76,3 @@ namespace NovelRT::Graphics::Vulkan::Utilities return returnDetails; } } - -#endif // NOVELRT_GRAPHICS_VULKAN_UTILITIES_SUPPORT_H diff --git a/graphics/include/NovelRT/Graphics/Vulkan/Utilities/Texel.hpp b/Graphics/include/NovelRT/Graphics/Vulkan/Utilities/Texel.hpp similarity index 68% rename from graphics/include/NovelRT/Graphics/Vulkan/Utilities/Texel.hpp rename to Graphics/include/NovelRT/Graphics/Vulkan/Utilities/Texel.hpp index 4e3390122..da06b8ca0 100644 --- a/graphics/include/NovelRT/Graphics/Vulkan/Utilities/Texel.hpp +++ b/Graphics/include/NovelRT/Graphics/Vulkan/Utilities/Texel.hpp @@ -1,12 +1,10 @@ +#pragma once + // Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root // for more information. -#ifndef NOVELRT_GRAPHICS_VULKAN_UTILITIES_TEXELUTILITIES_H -#define NOVELRT_GRAPHICS_VULKAN_UTILITIES_TEXELUTILITIES_H - -#ifndef NOVELRT_GRAPHICS_VULKAN_UTILITIES_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.Vulkan.Utilities.h instead for the Graphics::Vulkan::Utilities namespace subset. -#endif +#include +#include namespace NovelRT::Graphics::Vulkan::Utilities { @@ -33,5 +31,3 @@ namespace NovelRT::Graphics::Vulkan::Utilities return returnFormat; } } - -#endif // !NOVELRT_GRAPHICS_VULKAN_UTILITIES_TEXELUTILITIES_H diff --git a/graphics/include/NovelRT/Graphics/Vulkan/Utilities/TextureAddressMode.hpp b/Graphics/include/NovelRT/Graphics/Vulkan/Utilities/TextureAddressMode.hpp similarity index 75% rename from graphics/include/NovelRT/Graphics/Vulkan/Utilities/TextureAddressMode.hpp rename to Graphics/include/NovelRT/Graphics/Vulkan/Utilities/TextureAddressMode.hpp index f950c0e65..26362d1e2 100644 --- a/graphics/include/NovelRT/Graphics/Vulkan/Utilities/TextureAddressMode.hpp +++ b/Graphics/include/NovelRT/Graphics/Vulkan/Utilities/TextureAddressMode.hpp @@ -1,12 +1,11 @@ +#pragma once + // Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root // for more information. -#ifndef NOVELRT_GRAPHICS_VULKAN_UTILITIES_TEXTUREADDRESSMODE_H -#define NOVELRT_GRAPHICS_VULKAN_UTILITIES_TEXTUREADDRESSMODE_H - -#ifndef NOVELRT_GRAPHICS_VULKAN_UTILITIES_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.Vulkan.Utilities.h instead for the Graphics::Vulkan::Utilities namespace subset. -#endif +#include +#include +#include namespace NovelRT::Graphics::Vulkan::Utilities { @@ -36,5 +35,3 @@ namespace NovelRT::Graphics::Vulkan::Utilities } } } - -#endif // !NOVELRT_GRAPHICS_VULKAN_UTILITIES_TEXTUREADDRESSMODE_H diff --git a/graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsAdapter.hpp b/Graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsAdapter.hpp similarity index 57% rename from graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsAdapter.hpp rename to Graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsAdapter.hpp index 01f3c63c1..8bfdae38c 100644 --- a/graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsAdapter.hpp +++ b/Graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsAdapter.hpp @@ -1,31 +1,38 @@ +#pragma once + // Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root // for more information. -#ifndef NOVELRT_GRAPHICS_VULKAN_VULKANGRAPHICSADAPTER_H -#define NOVELRT_GRAPHICS_VULKAN_VULKANGRAPHICSADAPTER_H - -#ifndef NOVELRT_GRAPHICS_VULKAN_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.Vulkan.h instead for the Graphics::Vulkan namespace subset. -#endif +#include +#include +#include +#include +#include +#include +#include namespace NovelRT::Graphics::Vulkan { - class VulkanGraphicsAdapter final : public GraphicsAdapter + class VulkanGraphicsProvider; + class VulkanGraphicsDevice; + + class VulkanGraphicsAdapter : public std::enable_shared_from_this { private: + std::weak_ptr _provider; VkPhysicalDevice _vulkanPhysicalDevice; NovelRT::Utilities::Lazy _vulkanPhysicalDeviceProperties; NovelRT::Utilities::Lazy _vulkanPhysicalDeviceMemoryProperties; NovelRT::Utilities::Lazy _name; - Threading::VolatileState _state; - [[nodiscard]] std::string GetNameInternal(); [[nodiscard]] VkPhysicalDeviceProperties GetVulkanPhysicalDevicePropertiesInternal(); [[nodiscard]] VkPhysicalDeviceMemoryProperties GetVulkanPhysicalDeviceMemoryPropertiesInternal(); public: - VulkanGraphicsAdapter(const std::shared_ptr& provider, VkPhysicalDevice physicalDevice); + VulkanGraphicsAdapter(std::shared_ptr provider, VkPhysicalDevice physicalDevice); + + ~VulkanGraphicsAdapter() = default; [[nodiscard]] inline VkPhysicalDevice GetVulkanPhysicalDevice() const noexcept { @@ -42,40 +49,33 @@ namespace NovelRT::Graphics::Vulkan return _vulkanPhysicalDeviceMemoryProperties.getActual(); } - [[nodiscard]] uint32_t GetDeviceId() final + [[nodiscard]] uint32_t GetDeviceId() { return GetVulkanPhysicalDeviceProperties().deviceID; } - [[nodiscard]] const std::string& GetName() final + [[nodiscard]] const std::string& GetName() { return _name.getActual(); } - [[nodiscard]] inline uint32_t GetVendorId() final + [[nodiscard]] inline uint32_t GetVendorId() { return GetVulkanPhysicalDeviceProperties().vendorID; } - [[nodiscard]] std::shared_ptr CreateDevice( - std::shared_ptr surfaceContext, - int32_t contextCount) final - { - return std::static_pointer_cast(CreateVulkanGraphicsDevice( - std::dynamic_pointer_cast(surfaceContext), contextCount)); - } - - [[nodiscard]] inline std::shared_ptr GetProvider() const - { - return std::dynamic_pointer_cast(GraphicsAdapter::GetProvider()); - } - - [[nodiscard]] std::shared_ptr CreateVulkanGraphicsDevice( + [[nodiscard]] std::shared_ptr CreateDevice( std::shared_ptr surfaceContext, int32_t contextCount); - ~VulkanGraphicsAdapter() final = default; + [[nodiscard]] inline std::shared_ptr GetProvider() const + { + if (_provider.expired()) + { + throw std::runtime_error("Provider has expired."); + } + + return _provider.lock(); + } }; } - -#endif // !NOVELRT_GRAPHICS_VULKAN_VULKANGRAPHICSADAPTER_H diff --git a/Graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsAdapterSelector.hpp b/Graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsAdapterSelector.hpp new file mode 100644 index 000000000..5905c97c7 --- /dev/null +++ b/Graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsAdapterSelector.hpp @@ -0,0 +1,31 @@ +#pragma once + +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#include +#include + +namespace NovelRT::Graphics::Vulkan +{ + class VulkanGraphicsAdapter; + class VulkanGraphicsProvider; + class VulkanGraphicsSurfaceContext; + + class VulkanGraphicsAdapterSelector + { + private: + [[nodiscard]] int32_t GetPhysicalDeviceOptionalExtensionSupportScore( + VkPhysicalDevice physicalDevice) const noexcept; + + [[nodiscard]] int32_t RateDeviceSuitability(VkPhysicalDevice physicalDevice, + VkSurfaceKHR surfaceContext) const noexcept; + + [[nodiscard]] bool CheckPhysicalDeviceRequiredExtensionSupport(VkPhysicalDevice physicalDevice) const noexcept; + + public: + [[nodiscard]] std::shared_ptr GetDefaultRecommendedAdapter( + std::shared_ptr provider, + std::shared_ptr surfaceContext) const; + }; +} diff --git a/Graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsBackendTraits.hpp b/Graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsBackendTraits.hpp new file mode 100644 index 000000000..22deaad99 --- /dev/null +++ b/Graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsBackendTraits.hpp @@ -0,0 +1,51 @@ +#pragma once + +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#include + +namespace NovelRT::Graphics::Vulkan +{ + struct VulkanGraphicsBackend; + + class VulkanGraphicsProvider; + class VulkanGraphicsAdapter; + class VulkanGraphicsDevice; + class VulkanGraphicsSurfaceContext; + class VulkanGraphicsResource; + class VulkanGraphicsResourceMemoryRegionBase; + + template + class VulkanGraphicsResourceMemoryRegion; + + class VulkanGraphicsMemoryAllocator; + class VulkanGraphicsBuffer; + class VulkanGraphicsTexture; + class VulkanGraphicsDescriptorSet; + class VulkanGraphicsCmdList; +} + +namespace NovelRT::Graphics +{ + template<> + struct GraphicsBackendTraits + { + using ProviderType = Vulkan::VulkanGraphicsProvider; + using AdapterType = Vulkan::VulkanGraphicsAdapter; + using DeviceType = Vulkan::VulkanGraphicsDevice; + using SurfaceContextType = Vulkan::VulkanGraphicsSurfaceContext; + using ContextType = Vulkan::VulkanGraphicsSurfaceContext; + using ResourceType = Vulkan::VulkanGraphicsResource; + using ResourceMemoryRegionBaseType = Vulkan::VulkanGraphicsResourceMemoryRegionBase; + + template + using ResourceMemoryRegionType = Vulkan::VulkanGraphicsResourceMemoryRegion; + + using MemoryAllocatorType = Vulkan::VulkanGraphicsMemoryAllocator; + using BufferType = Vulkan::VulkanGraphicsBuffer; + using TextureType = Vulkan::VulkanGraphicsTexture; + using DescriptorSetType = Vulkan::VulkanGraphicsDescriptorSet; + using CmdListType = Vulkan::VulkanGraphicsCmdList; + }; +} \ No newline at end of file diff --git a/Graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsBuffer.hpp b/Graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsBuffer.hpp new file mode 100644 index 000000000..52917060c --- /dev/null +++ b/Graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsBuffer.hpp @@ -0,0 +1,61 @@ +#pragma once + +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#include +#include +#include +#include + +namespace NovelRT::Graphics::Vulkan +{ + class VulkanGraphicsDevice; + class VulkanGraphicsMemoryAllocator; + template class VulkanGraphicsResourceMemoryRegion; + + class VulkanGraphicsBuffer final : public VulkanGraphicsResource + { + private: + VkBuffer _vulkanBuffer; + size_t _subAllocations; + GraphicsResourceAccess _cpuAccess; + GraphicsBufferKind _kind; + + protected: + [[nodiscard]] std::shared_ptr AllocateInternal(VmaVirtualAllocation allocation, VkDeviceSize offset) final; + + public: + VulkanGraphicsBuffer(std::shared_ptr graphicsDevice, + std::shared_ptr allocator, + GraphicsResourceAccess cpuAccess, + GraphicsBufferKind kind, + VmaAllocation allocation, + VmaAllocationInfo allocationInfo, + size_t subAllocations, + VkBuffer vulkanBuffer); + + ~VulkanGraphicsBuffer() noexcept; + + [[nodiscard]] GraphicsResourceAccess GetAccess() const noexcept + { + return _cpuAccess; + } + + [[nodiscard]] GraphicsBufferKind GetKind() const noexcept + { + return _kind; + } + + [[nodiscard]] NovelRT::Utilities::Misc::Span MapBytes(size_t rangeOffset, size_t rangeLength); + + [[nodiscard]] NovelRT::Utilities::Misc::Span MapBytesForRead(size_t rangeOffset, + size_t rangeLength); + + void UnmapBytes(); + + void UnmapBytesAndWrite(size_t writtenRangeOffset, size_t writtenRangeLength); + + [[nodiscard]] VkBuffer GetVulkanBuffer() const noexcept; + }; +} \ No newline at end of file diff --git a/Graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsCmdList.hpp b/Graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsCmdList.hpp new file mode 100644 index 000000000..f5c6f10fd --- /dev/null +++ b/Graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsCmdList.hpp @@ -0,0 +1,55 @@ +#pragma once + +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#include +#include + +namespace NovelRT::Graphics::Vulkan +{ + class VulkanGraphicsRenderPass; + class VulkanGraphicsContext; + class VulkanGraphicsDescriptorSet; + class VulkanGraphicsBuffer; + class VulkanGraphicsTexture; + + class VulkanGraphicsCmdList final + { + private: + std::shared_ptr _context; + + public: + explicit VulkanGraphicsCmdList(std::shared_ptr context) noexcept; + + ~VulkanGraphicsCmdList() = default; + + [[nodiscard]] std::shared_ptr GetContext() const noexcept; + + void CmdBeginRenderPass(std::shared_ptr targetPass); + + void CmdBindDescriptorSets( + NovelRT::Utilities::Misc::Span> sets); + + void CmdBindVertexBuffers(uint32_t firstBinding, + uint32_t bindingCount, + NovelRT::Utilities::Misc::Span> buffers, + NovelRT::Utilities::Misc::Span offsets); + + void CmdBindIndexBuffers(NovelRT::Utilities::Misc::Span> buffers); + + void CmdCopy(std::shared_ptr destination, std::shared_ptr source); + + void CmdCopy(std::shared_ptr destination, std::shared_ptr source); + + void CmdDrawIndexed(uint32_t instanceCount); + + void CmdDraw(uint32_t instanceCount, uint32_t bufferStride); + + void CmdSetScissor(Maths::GeoVector2F extent); + + void CmdSetScissor(float xExtent, float yExtent); + + void CmdSetViewport(uint32_t firstViewport, uint32_t viewportCount, ViewportInfo viewportInfo); + }; +} \ No newline at end of file diff --git a/graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsContext.hpp b/Graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsContext.hpp similarity index 56% rename from graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsContext.hpp rename to Graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsContext.hpp index f7c714f13..615e9d872 100644 --- a/graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsContext.hpp +++ b/Graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsContext.hpp @@ -1,18 +1,27 @@ +#pragma once + // Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root // for more information. -#ifndef NOVELRT_GRAPHICS_VULKAN_VULKANGRAPHICSCONTEXT_H -#define NOVELRT_GRAPHICS_VULKAN_VULKANGRAPHICSCONTEXT_H - -#ifndef NOVELRT_GRAPHICS_VULKAN_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.Vulkan.h instead for the Graphics::Vulkan namespace subset. -#endif +#include +#include +#include +#include +#include +#include +#include namespace NovelRT::Graphics::Vulkan { - class VulkanGraphicsContext final : public GraphicsContext + class VulkanGraphicsPipelineSignature; + class VulkanGraphicsDevice; + + class VulkanGraphicsContext : public std::enable_shared_from_this { private: + std::shared_ptr _device; + size_t _index; + std::unordered_map, std::vector> _vulkanDescriptorSets; std::shared_ptr _fence; @@ -33,8 +42,8 @@ namespace NovelRT::Graphics::Vulkan void DisposeVulkanCommandPool(VkCommandPool vulkanCommandPool) noexcept; void DisposeVulkanFramebuffer(VkFramebuffer vulkanFramebuffer) noexcept; void DisposeVulkanSwapChainImageView(VkImageView vulkanSwapChainImageView) noexcept; - void BeginCopy(VkImage vulkanImage) noexcept; - void EndCopy(VkImage vulkanImage) noexcept; + //void BeginCopy(VkImage vulkanImage) noexcept; + //void EndCopy(VkImage vulkanImage) noexcept; void DestroyDescriptorSets(); public: @@ -44,15 +53,15 @@ namespace NovelRT::Graphics::Vulkan [[nodiscard]] std::shared_ptr GetDevice() const noexcept { - return std::static_pointer_cast(GraphicsContext::GetDevice()); + return _device; } - [[nodiscard]] inline std::shared_ptr GetFence() const noexcept final + [[nodiscard]] inline size_t GetIndex() const noexcept { - return _fence; + return _index; } - [[nodiscard]] inline std::shared_ptr GetVulkanFence() const noexcept + [[nodiscard]] inline std::shared_ptr GetFence() const noexcept { return _fence; } @@ -82,37 +91,14 @@ namespace NovelRT::Graphics::Vulkan return _waitForExecuteCompletionFence; } - void BeginDrawing(NovelRT::Graphics::RGBAColour backgroundColour) final; - void BeginFrame() final; - - inline void Copy(std::shared_ptr destination, std::shared_ptr source) final - { - Copy(std::static_pointer_cast(destination), - std::static_pointer_cast(source)); - } - - inline void Copy(std::shared_ptr destination, std::shared_ptr source) final - { - Copy(std::static_pointer_cast(destination), - std::static_pointer_cast(source)); - } - - void Copy(std::shared_ptr destination, std::shared_ptr source); - void Copy(std::shared_ptr destination, std::shared_ptr source); + void BeginDrawing(NovelRT::Graphics::RGBAColour backgroundColour); + void BeginFrame(); - inline void Draw(std::shared_ptr primitive, uint32_t instanceCount) final - { - Draw(std::static_pointer_cast(primitive), instanceCount); - } - - void Draw(const std::shared_ptr& primitive, int32_t instanceCount); - void EndDrawing() final; - void EndFrame() final; + void EndDrawing(); + void EndFrame(); void ResetContext(); - ~VulkanGraphicsContext() final; + ~VulkanGraphicsContext(); }; } - -#endif // !NOVELRT_GRAPHICS_VULKAN_VULKANGRAPHICSCONTEXT_H diff --git a/Graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsDescriptorSet.hpp b/Graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsDescriptorSet.hpp new file mode 100644 index 000000000..ebaace124 --- /dev/null +++ b/Graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsDescriptorSet.hpp @@ -0,0 +1,38 @@ +#pragma once + +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#include +#include +#include + +namespace NovelRT::Graphics::Vulkan +{ + class VulkanGraphicsPipeline; + class VulkanGraphicsResource; + + class VulkanGraphicsDescriptorSet + { + private: + VkDescriptorSet _descriptorSetHandle; + std::shared_ptr _pipeline; + std::vector>> _inputResourceRegions; + + + public: + explicit VulkanGraphicsDescriptorSet(std::shared_ptr targetPipeline) noexcept; + + ~VulkanGraphicsDescriptorSet(); + + [[nodiscard]] VkDescriptorSet GetVulkanDescriptorSet() const noexcept; + + [[nodiscard]] std::shared_ptr GetPipeline() const noexcept; + + void AddMemoryRegionToInputs(std::shared_ptr> region); + + void AddMemoryRegionsToInputs(NovelRT::Utilities::Misc::Span>> regions); + + void UpdateDescriptorSetData(); + }; +} \ No newline at end of file diff --git a/graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsDevice.hpp b/Graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsDevice.hpp similarity index 53% rename from graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsDevice.hpp rename to Graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsDevice.hpp index 7228202b8..7bf985476 100644 --- a/graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsDevice.hpp +++ b/Graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsDevice.hpp @@ -1,22 +1,34 @@ +#pragma once + // Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root // for more information. -#ifndef NOVELRT_GRAPHICS_VULKAN_VULKANGRAPHICSDEVICE_H -#define NOVELRT_GRAPHICS_VULKAN_VULKANGRAPHICSDEVICE_H - -#ifndef NOVELRT_GRAPHICS_VULKAN_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.Vulkan.h instead for the Graphics::Vulkan namespace subset. -#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include namespace NovelRT::Graphics::Vulkan { - class VulkanGraphicsDevice final : public GraphicsDevice + class VulkanGraphicsAdapter; + class VulkanShaderProgram; + class VulkanGraphicsPipeline; + class VulkanGraphicsPipelineSignature; + + class VulkanGraphicsDevice : public std::enable_shared_from_this { private: + std::shared_ptr _adapter; + std::shared_ptr _surfaceContext; NovelRT::Utilities::Lazy> _presentCompletionFence; uint32_t _contextCount; NovelRT::Utilities::Lazy>> _contexts; - NovelRT::Utilities::Lazy>> _contextPtrs; + NovelRT::Utilities::Lazy>> _contextPtrs; LoggingService _logger; @@ -36,14 +48,12 @@ namespace NovelRT::Graphics::Vulkan NovelRT::Utilities::Lazy _vulkanSwapchain; NovelRT::Utilities::Lazy> _swapChainImages; NovelRT::Utilities::Lazy _renderPass; - NovelRT::Utilities::Lazy> _memoryAllocator; QueueFamilyIndices _indicesData; Threading::VolatileState _state; [[nodiscard]] std::vector> CreateGraphicsContexts(uint32_t contextCount); - [[nodiscard]] std::shared_ptr CreateMemoryAllocator(); void OnGraphicsSurfaceSizeChanged(Maths::GeoVector2F newSize); [[nodiscard]] std::vector GetFinalPhysicalDeviceExtensionSet() const; @@ -62,76 +72,48 @@ namespace NovelRT::Graphics::Vulkan VkRenderPass CreateRenderPass(); - protected: - VulkanGraphicsMemoryAllocator* GetMemoryAllocatorInternal() final; - public: - VulkanGraphicsDevice(const std::shared_ptr& adapter, - const std::shared_ptr& surfaceContext, + VulkanGraphicsDevice(std::shared_ptr adapter, + std::shared_ptr surfaceContext, int32_t contextCount); - void TearDown() final; - size_t GetContextIndex() const noexcept override; + void TearDown(); + size_t GetContextIndex() const noexcept; - std::shared_ptr CreatePrimitive( - std::shared_ptr pipeline, - GraphicsMemoryRegion& vertexBufferRegion, - uint32_t vertexBufferStride, - GraphicsMemoryRegion& indexBufferRegion, - uint32_t indexBufferStride, - NovelRT::Utilities::Misc::Span> inputResourceRegions) final; + void PresentFrame(); - [[nodiscard]] std::shared_ptr CreateVulkanPrimitive( - std::shared_ptr pipeline, - GraphicsMemoryRegion& vertexBufferRegion, - uint32_t vertexBufferStride, - GraphicsMemoryRegion& indexBufferRegion, - uint32_t indexBufferStride, - NovelRT::Utilities::Misc::Span> inputResourceRegions); + void Signal(std::shared_ptr fence) const; - void PresentFrame() final; + void WaitForIdle(); - void Signal(std::shared_ptr fence) final; - void SignalVulkan(const std::shared_ptr& fence) const; - - void WaitForIdle() final; - - [[nodiscard]] inline NovelRT::Utilities::Misc::Span> GetContexts() final + [[nodiscard]] inline NovelRT::Utilities::Misc::Span> GetContexts() { - return NovelRT::Utilities::Misc::Span>( + return NovelRT::Utilities::Misc::Span>( &(*_contextPtrs.getActual().begin()), _contextPtrs.getActual().size()); } - [[nodiscard]] std::shared_ptr GetCurrentContext() - { - return std::dynamic_pointer_cast(GetContexts()[GetContextIndex()]); - } + [[nodiscard]] std::shared_ptr GetCurrentContext(); + [[nodiscard]] std::shared_ptr GetSurfaceContext() const noexcept; - [[nodiscard]] inline std::shared_ptr GetAdapter() const noexcept - { - return std::dynamic_pointer_cast(GraphicsDevice::GetAdapter()); - } + [[nodiscard]] std::shared_ptr GetSurface() const noexcept; - [[nodiscard]] inline std::shared_ptr GetSurfaceContext() const noexcept - { - return std::dynamic_pointer_cast(GraphicsDevice::GetSurfaceContext()); - } + [[nodiscard]] std::shared_ptr GetAdapter() const noexcept; - [[nodiscard]] std::shared_ptr CreateShaderProgram( + [[nodiscard]] std::shared_ptr CreateShaderProgram( std::string entryPointName, ShaderProgramKind kind, - NovelRT::Utilities::Misc::Span byteData) final; + NovelRT::Utilities::Misc::Span byteData); - [[nodiscard]] std::shared_ptr CreatePipeline( - std::shared_ptr signature, - std::shared_ptr vertexShader, - std::shared_ptr pixelShader) final; + [[nodiscard]] std::shared_ptr CreatePipeline( + std::shared_ptr signature, + std::shared_ptr vertexShader, + std::shared_ptr pixelShader); - [[nodiscard]] std::shared_ptr CreatePipelineSignature( + [[nodiscard]] std::shared_ptr CreatePipelineSignature( GraphicsPipelineBlendFactor srcBlendFactor, GraphicsPipelineBlendFactor dstBlendFactor, NovelRT::Utilities::Misc::Span inputs, - NovelRT::Utilities::Misc::Span resources) final; + NovelRT::Utilities::Misc::Span resources); [[nodiscard]] inline VkSwapchainKHR GetVulkanSwapchain() { @@ -183,11 +165,9 @@ namespace NovelRT::Graphics::Vulkan return _presentCompletionFence.getActual(); } - std::vector> CreateGraphicsContextPointers(); + std::vector> CreateGraphicsContextPointers(); void ResizeGraphicsContexts(uint32_t newContextCount); - ~VulkanGraphicsDevice() final; + ~VulkanGraphicsDevice(); }; } - -#endif // NOVELRT_GRAPHICS_VULKAN_VULKANGRAPHICSDEVICE_H diff --git a/graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsFence.hpp b/Graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsFence.hpp similarity index 52% rename from graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsFence.hpp rename to Graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsFence.hpp index 890247aa4..61f3d0460 100644 --- a/graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsFence.hpp +++ b/Graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsFence.hpp @@ -1,18 +1,21 @@ +#pragma once + // Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root // for more information. -#ifndef NOVELRT_GRAPHICS_VULKAN_VULKANGRAPHICSFENCE_H -#define NOVELRT_GRAPHICS_VULKAN_VULKANGRAPHICSFENCE_H - -#ifndef NOVELRT_GRAPHICS_VULKAN_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.Vulkan.h instead for the Graphics::Vulkan namespace subset. -#endif +#include +#include +#include +#include namespace NovelRT::Graphics::Vulkan { - class VulkanGraphicsFence final : public GraphicsFence + class VulkanGraphicsDevice; + + class VulkanGraphicsFence { private: + std::shared_ptr _device; NovelRT::Utilities::Lazy _vulkanFence; Threading::VolatileState _state; @@ -29,11 +32,12 @@ namespace NovelRT::Graphics::Vulkan [[nodiscard]] bool TryWaitInternal(uint64_t millisecondsTimeout); public: - explicit VulkanGraphicsFence(std::shared_ptr device, bool isSignaled) noexcept; + VulkanGraphicsFence(std::shared_ptr device, bool isSignaled) noexcept; + ~VulkanGraphicsFence(); [[nodiscard]] inline std::shared_ptr GetDevice() const noexcept { - return std::static_pointer_cast(GraphicsFence::GetDevice()); + return _device; } [[nodiscard]] inline VkFence GetVulkanFence() @@ -41,15 +45,32 @@ namespace NovelRT::Graphics::Vulkan return _vulkanFence.getActual(); } - [[nodiscard]] bool GetIsSignalled() final; + [[nodiscard]] bool GetIsSignalled(); - void Reset() final; + void Reset(); - [[nodiscard]] bool TryWait(uint64_t millisecondsTimeout) final; - [[nodiscard]] bool TryWait(std::chrono::duration timeout) final; + [[nodiscard]] bool TryWait(uint64_t millisecondsTimeout); + [[nodiscard]] bool TryWait(std::chrono::duration timeout); + + inline void Wait(uint64_t millisecondsTimeout) + { + if (!TryWait(millisecondsTimeout)) + { + throw Exceptions::TimeoutException(millisecondsTimeout); + } + } - ~VulkanGraphicsFence() final; + inline void Wait(std::chrono::duration timeout) + { + if (!TryWait(timeout)) + { + throw Exceptions::TimeoutException(timeout.count()); + } + } + + inline void Wait() + { + Wait(std::numeric_limits::max()); + } }; } - -#endif // !NOVELRT_GRAPHICS_VULKAN_VULKANGRAPHICSFENCE_H diff --git a/Graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsMemoryAllocator.hpp b/Graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsMemoryAllocator.hpp new file mode 100644 index 000000000..9fdf240db --- /dev/null +++ b/Graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsMemoryAllocator.hpp @@ -0,0 +1,42 @@ +#pragma once + +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#include +#include +#include + +namespace NovelRT::Graphics::Vulkan +{ + class VulkanGraphicsTexture; + class VulkanGraphicsBuffer; + + class VulkanGraphicsMemoryAllocator : public std::enable_shared_from_this + { + private: + VmaAllocator _allocator; + std::shared_ptr _provider; + std::shared_ptr _device; + + public: + VulkanGraphicsMemoryAllocator(std::shared_ptr provider, + std::shared_ptr device); + + [[nodiscard]] std::shared_ptr GetDevice() const noexcept; + + [[nodiscard]] std::shared_ptr GetProvider() const noexcept; + + [[nodiscard]] std::shared_ptr CreateBuffer(const GraphicsBufferCreateInfo& createInfo); + + [[nodiscard]] std::shared_ptr CreateTexture(const GraphicsTextureCreateInfo& createInfo); + + [[nodiscard]] std::shared_ptr CreateVulkanBuffer( + const GraphicsBufferCreateInfo& createInfo); + + [[nodiscard]] std::shared_ptr CreateVulkanTexture( + const GraphicsTextureCreateInfo& createInfo); + + [[nodiscard]] VmaAllocator GetVmaAllocator() const noexcept; + }; +} \ No newline at end of file diff --git a/graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsPipeline.hpp b/Graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsPipeline.hpp similarity index 59% rename from graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsPipeline.hpp rename to Graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsPipeline.hpp index e2ed02d8d..e9324eb3f 100644 --- a/graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsPipeline.hpp +++ b/Graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsPipeline.hpp @@ -1,18 +1,27 @@ +#pragma once + // Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root // for more information. -#ifndef NOVELRT_GRAPHICS_VULKAN_VULKANGRAPHICSPIPELINE_H -#define NOVELRT_GRAPHICS_VULKAN_VULKANGRAPHICSPIPELINE_H - -#ifndef NOVELRT_GRAPHICS_VULKAN_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.Vulkan.h instead for the Graphics::Vulkan namespace subset. -#endif +#include +#include +#include +#include +#include +#include +#include +#include namespace NovelRT::Graphics::Vulkan { - class VulkanGraphicsPipeline : public GraphicsPipeline + class VulkanGraphicsPipeline { private: + std::shared_ptr _device; + std::shared_ptr _vertexShader; + std::shared_ptr _pixelShader; + std::shared_ptr _signature; + NovelRT::Utilities::Lazy _vulkanPipeline; [[nodiscard]] VkPipeline CreateVulkanPipeline(); [[nodiscard]] size_t GetInputElementsCount( @@ -25,31 +34,39 @@ namespace NovelRT::Graphics::Vulkan std::shared_ptr vertexShader, std::shared_ptr pixelShader) noexcept; - [[nodiscard]] inline std::shared_ptr GetDevice() const + [[nodiscard]] inline std::shared_ptr GetDevice() const noexcept { - return std::dynamic_pointer_cast(GraphicsPipeline::GetDevice()); + return _device; } [[nodiscard]] inline std::shared_ptr GetPixelShader() const noexcept { - return std::dynamic_pointer_cast(GraphicsPipeline::GetPixelShader()); + return _vertexShader; } [[nodiscard]] inline std::shared_ptr GetVertexShader() const noexcept { - return std::dynamic_pointer_cast(GraphicsPipeline::GetVertexShader()); + return _pixelShader; } [[nodiscard]] inline std::shared_ptr GetSignature() const noexcept { - return std::dynamic_pointer_cast(GraphicsPipeline::GetSignature()); + return _signature; } [[nodiscard]] inline VkPipeline GetVulkanPipeline() { return _vulkanPipeline.getActual(); } + + bool HasVertexShader() const noexcept + { + return _vertexShader != nullptr; + } + + bool HasPixelShader() const noexcept + { + return _pixelShader != nullptr; + } }; } - -#endif // NOVELRT_GRAPHICS_VULKAN_VULKANGRAPHICSPIPELINE_H diff --git a/graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsPipelineSignature.hpp b/Graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsPipelineSignature.hpp similarity index 60% rename from graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsPipelineSignature.hpp rename to Graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsPipelineSignature.hpp index 9f0d6489b..0b532cd7e 100644 --- a/graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsPipelineSignature.hpp +++ b/Graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsPipelineSignature.hpp @@ -1,18 +1,25 @@ +#pragma once + // Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root // for more information. -#ifndef NOVELRT_GRAPHICS_VULKAN_VULKANGRAPHICSPIPELINESIGNATURE_H -#define NOVELRT_GRAPHICS_VULKAN_VULKANGRAPHICSPIPELINESIGNATURE_H - -#ifndef NOVELRT_GRAPHICS_VULKAN_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.Vulkan.h instead for the Graphics::Vulkan namespace subset. -#endif +#include +#include +#include +#include +#include namespace NovelRT::Graphics::Vulkan { - class VulkanGraphicsPipelineSignature final : public GraphicsPipelineSignature - { + class VulkanGraphicsDevice; + class VulkanGraphicsPipelineSignature + { + std::shared_ptr _device; + GraphicsPipelineBlendFactor _srcBlendFactor; + GraphicsPipelineBlendFactor _dstBlendFactor; + std::vector _inputs; + std::vector _resources; NovelRT::Utilities::Lazy _vulkanDescriptorPool; NovelRT::Utilities::Lazy _vulkanDescriptorSetLayout; NovelRT::Utilities::Lazy _vulkanPipelineLayout; @@ -36,10 +43,27 @@ namespace NovelRT::Graphics::Vulkan GraphicsPipelineBlendFactor dstBlendFactor, NovelRT::Utilities::Misc::Span inputs, NovelRT::Utilities::Misc::Span resources) noexcept; + + ~VulkanGraphicsPipelineSignature(); [[nodiscard]] inline std::shared_ptr GetDevice() const { - return std::dynamic_pointer_cast(GraphicsPipelineSignature::GetDevice()); + return _device; + } + + [[nodiscard]] inline GraphicsPipelineBlendFactor GetSrcBlendFactor() const noexcept + { + return _srcBlendFactor; + } + + [[nodiscard]] inline GraphicsPipelineBlendFactor GetDstBlendFactor() const noexcept + { + return _dstBlendFactor; + } + + [[nodiscard]] inline std::vector GetInputs() const noexcept + { + return _inputs; } [[nodiscard]] inline VkDescriptorPool GetVulkanDescriptorPool() @@ -61,11 +85,14 @@ namespace NovelRT::Graphics::Vulkan { return _vulkanPipelineLayout.getActual(); } + + NovelRT::Utilities::Misc::Span GetResources() + const noexcept + { + return NovelRT::Utilities::Misc::Span(&(*_resources.begin()), + _resources.size()); + } void DestroyDescriptorSets(NovelRT::Utilities::Misc::Span vulkanDescriptorSets); - - ~VulkanGraphicsPipelineSignature() final; }; } - -#endif // NOVELRT_GRAPHICS_VULKAN_VULKANGRAPHICSPIPELINESIGNATURE_H diff --git a/graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsProvider.hpp b/Graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsProvider.hpp similarity index 74% rename from graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsProvider.hpp rename to Graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsProvider.hpp index 9dd1b36f6..2b1251778 100644 --- a/graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsProvider.hpp +++ b/Graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsProvider.hpp @@ -1,16 +1,18 @@ +#pragma once + // Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root // for more information. -#ifndef NOVELRT_GRAPHICS_VULKAN_VULKANGRAPHICSPROVIDER_H -#define NOVELRT_GRAPHICS_VULKAN_VULKANGRAPHICSPROVIDER_H - -#ifndef NOVELRT_GRAPHICS_VULKAN_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.Vulkan.h instead for the Graphics::Vulkan namespace subset. -#endif +#include +#include +#include +#include namespace NovelRT::Graphics::Vulkan { - class VulkanGraphicsProvider final : public GraphicsProvider + class VulkanGraphicsAdapter; + + class VulkanGraphicsProvider : public std::enable_shared_from_this { private: static inline std::string _defaultFailureMessage = "Failed to initialise Vulkan version 1.2. Reason: "; @@ -18,11 +20,12 @@ namespace NovelRT::Graphics::Vulkan VkInstance _vulkanInstance; std::vector _finalExtensionSet; std::vector _finalValidationLayerSet; - NovelRT::Utilities::Lazy>> _adapters; + NovelRT::Utilities::Lazy>> _adapters; std::string _engineName; Threading::VolatileState _state; VkDebugUtilsMessengerEXT _debugLogger; LoggingService _logger; + bool _debugModeEnabled; static VKAPI_ATTR VkBool32 VKAPI_CALL DebugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageType, @@ -45,7 +48,7 @@ namespace NovelRT::Graphics::Vulkan void ConfigureDebugLogger(); VkInstance CreateInstance(); - std::vector> GetGraphicsAdapters(); + std::vector> GetGraphicsAdapters(); public: VulkanGraphicsProvider(); @@ -61,11 +64,13 @@ namespace NovelRT::Graphics::Vulkan _finalValidationLayerSet.size()); } - std::vector>::iterator begin() noexcept final; - std::vector>::iterator end() noexcept final; + [[nodiscard]] uint32_t GetApiVersion() const noexcept; - ~VulkanGraphicsProvider() final; + [[nodiscard]] bool GetDebugModeEnabled() const noexcept; + + std::vector>::iterator begin() noexcept; + std::vector>::iterator end() noexcept; + + ~VulkanGraphicsProvider(); }; } - -#endif // !NOVELRT_GRAPHICS_VULKAN_VULKANGRAPHICSPROVIDER_H diff --git a/Graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsResource.hpp b/Graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsResource.hpp new file mode 100644 index 000000000..bfdb3156f --- /dev/null +++ b/Graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsResource.hpp @@ -0,0 +1,52 @@ +#pragma once + +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#include +#include +#include +#include + +namespace NovelRT::Graphics::Vulkan +{ + class VulkanGraphicsDevice; + class VulkanGraphicsMemoryAllocator; + + class VulkanGraphicsResource : public std::enable_shared_from_this + { + private: + std::shared_ptr _allocator; + std::shared_ptr _graphicsDevice; + VmaAllocation _allocation; + VmaAllocationInfo _allocationInfo; + VmaVirtualBlock _virtualBlock; + [[nodiscard]] std::tuple GetVirtualAllocation(size_t size, size_t alignment); + + protected: + [[nodiscard]] virtual std::shared_ptr AllocateInternal(VmaVirtualAllocation allocation, VkDeviceSize offset) = 0; + + public: + VulkanGraphicsResource(std::shared_ptr graphicsDevice, + std::shared_ptr allocator, + GraphicsResourceAccess cpuAccess, + VmaAllocation allocation, + VmaAllocationInfo allocationInfo); + + [[nodiscard]] std::shared_ptr GetAllocator() const noexcept; + + [[nodiscard]] std::shared_ptr GetDevice() const noexcept; + + [[nodiscard]] size_t GetDeviceMemoryOffset() const noexcept; + + [[nodiscard]] size_t GetSize() const noexcept; + + [[nodiscard]] std::shared_ptr Allocate(size_t size, size_t alignment); + + [[nodiscard]] VmaAllocation GetAllocation() const noexcept; + + [[nodiscard]] const VmaAllocationInfo& GetAllocationInfo() const noexcept; + + [[nodiscard]] VmaVirtualBlock GetVirtualBlock() const noexcept; + }; +} diff --git a/Graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsResourceMemoryRegion.hpp b/Graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsResourceMemoryRegion.hpp new file mode 100644 index 000000000..78826d2fc --- /dev/null +++ b/Graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsResourceMemoryRegion.hpp @@ -0,0 +1,57 @@ +#pragma once + +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#include +#include + +namespace NovelRT::Graphics::Vulkan +{ + class VulkanGraphicsDevice; + class VulkanGraphicsResource; + + class VulkanGraphicsResourceMemoryRegionBase : public std::enable_shared_from_this + { + private: + std::shared_ptr _device; + std::shared_ptr _owningResource; + VmaVirtualAllocation _virtualAllocation; + VmaVirtualAllocationInfo _virtualAllocationInfo; + + public: + VulkanGraphicsResourceMemoryRegionBase(std::shared_ptr graphicsDevice, + std::shared_ptr owningResource, + VmaVirtualAllocation virtualAllocation, + VmaVirtualAllocationInfo virtualAllocationInfo); + + ~VulkanGraphicsResourceMemoryRegionBase() = default; + + [[nodiscard]] inline std::shared_ptr GetOwningResource() const noexcept; + + [[nodiscard]] inline std::shared_ptr GetDevice() const noexcept; + + [[nodiscard]] size_t GetRelativeOffset() const noexcept; + + [[nodiscard]] size_t GetSize() const noexcept; + + [[nodiscard]] VmaVirtualAllocation GetVirtualAllocation() const noexcept; + + [[nodiscard]] VmaVirtualAllocationInfo GetVirtualAllocationInfo() const noexcept; + }; + + template + class VulkanGraphicsResourceMemoryRegion : public VulkanGraphicsResourceMemoryRegionBase + { + public: + VulkanGraphicsResourceMemoryRegion(std::shared_ptr graphicsDevice, + std::shared_ptr owningResource, + VmaVirtualAllocation virtualAllocation, + VmaVirtualAllocationInfo virtualAllocationInfo) + : VulkanGraphicsResourceMemoryRegionBase(graphicsDevice, owningResource, virtualAllocation, virtualAllocationInfo) + { + } + + ~VulkanGraphicsResourceMemoryRegion() = default; + }; +} diff --git a/Graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsSurfaceContext.hpp b/Graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsSurfaceContext.hpp new file mode 100644 index 000000000..99959a6cf --- /dev/null +++ b/Graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsSurfaceContext.hpp @@ -0,0 +1,52 @@ +#pragma once + +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#include +#include +#include +#include + +namespace NovelRT::Graphics::Vulkan +{ + class VulkanGraphicsSurfaceContext + { + private: + std::shared_ptr _surface; + std::shared_ptr _provider; + LoggingService _logger; + VkSurfaceKHR _vulkanSurface; + + public: + VulkanGraphicsSurfaceContext(std::shared_ptr surface, + std::shared_ptr provider); + + ~VulkanGraphicsSurfaceContext(); + + [[nodiscard]] inline void* GetSurfaceContextHandleUntyped() + { + return &_vulkanSurface; + } + + [[nodiscard]] inline VkSurfaceKHR GetVulkanSurfaceContextHandle() const noexcept + { + return _vulkanSurface; + } + + [[nodiscard]] inline std::shared_ptr GetSurface() const noexcept + { + return _surface; + } + + [[nodiscard]] inline std::shared_ptr GetProvider() const noexcept + { + return _provider; + } + + template[[nodiscard]] THandleType GetSurfaceContextHandleAs() + { + return *reinterpret_cast(GetSurfaceContextHandleUntyped()); + } + }; +} diff --git a/Graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsTexture.hpp b/Graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsTexture.hpp new file mode 100644 index 000000000..7a4cada9d --- /dev/null +++ b/Graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsTexture.hpp @@ -0,0 +1,78 @@ +#pragma once + +// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root +// for more information. + +#include +#include +#include +#include +#include +#include + +namespace NovelRT::Graphics::Vulkan +{ + class VulkanGraphicsTexture : public VulkanGraphicsResource + { + private: + VkImage _vulkanImage; + size_t _subAllocations; + GraphicsTextureAddressMode _addressMode; + GraphicsTextureKind _kind; + + NovelRT::Utilities::Lazy _vulkanImageView; + NovelRT::Utilities::Lazy _vulkanSampler; + + uint32_t _width; + uint32_t _height; + uint32_t _depth; + + [[nodiscard]] VkImageView CreateVulkanImageView(); + [[nodiscard]] VkSampler CreateVulkanSampler(); + + protected: + [[nodiscard]] std::shared_ptr AllocateInternal( + VmaVirtualAllocation allocation, + VkDeviceSize offset) final; + + public: + VulkanGraphicsTexture(std::shared_ptr device, + std::shared_ptr allocator, + GraphicsResourceAccess cpuAccess, + GraphicsTextureAddressMode addressMode, + GraphicsTextureKind kind, + uint32_t width, + uint32_t height, + uint16_t depth, + VmaAllocation allocation, + VmaAllocationInfo allocationInfo, + size_t subAllocations, + VkImage vulkanImage); + + ~VulkanGraphicsTexture() noexcept; + + [[nodiscard]] GraphicsTextureAddressMode GetAddressMode() const noexcept; + [[nodiscard]] GraphicsTextureKind GetKind() const noexcept; + + [[nodiscard]] NovelRT::Utilities::Misc::Span MapBytes(size_t rangeOffset, size_t rangeLength); + + [[nodiscard]] NovelRT::Utilities::Misc::Span MapBytesForRead(size_t rangeOffset, + size_t rangeLength); + + void UnmapBytes(); + + void UnmapBytesAndWrite(size_t writtenRangeOffset, size_t writtenRangeLength); + + [[nodiscard]] VkImage GetVulkanImage() const noexcept; + + [[nodiscard]] VkImageView GetOrCreateVulkanImageView(); + + [[nodiscard]] VkSampler GetOrCreateVulkanSampler(); + + [[nodiscard]] uint32_t GetWidth() const noexcept; + + [[nodiscard]] uint32_t GetHeight() const noexcept; + + [[nodiscard]] uint32_t GetDepth() const noexcept; + }; +} diff --git a/graphics/include/NovelRT/Graphics/Vulkan/VulkanShaderProgram.hpp b/Graphics/include/NovelRT/Graphics/Vulkan/VulkanShaderProgram.hpp similarity index 56% rename from graphics/include/NovelRT/Graphics/Vulkan/VulkanShaderProgram.hpp rename to Graphics/include/NovelRT/Graphics/Vulkan/VulkanShaderProgram.hpp index 343d5438c..e5fd6e0a5 100644 --- a/graphics/include/NovelRT/Graphics/Vulkan/VulkanShaderProgram.hpp +++ b/Graphics/include/NovelRT/Graphics/Vulkan/VulkanShaderProgram.hpp @@ -1,18 +1,23 @@ +#pragma once + // Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root // for more information. -#ifndef NOVELRT_GRAPHICS_VULKAN_VULKANSHADERPROGRAM_H -#define NOVELRT_GRAPHICS_VULKAN_VULKANSHADERPROGRAM_H - -#ifndef NOVELRT_GRAPHICS_VULKAN_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.Vulkan.h instead for the Graphics::Vulkan namespace subset. -#endif +#include +#include +#include +#include namespace NovelRT::Graphics::Vulkan { - class VulkanShaderProgram : public ShaderProgram + class VulkanGraphicsDevice; + + class VulkanShaderProgram { private: + std::shared_ptr _device; + std::string _entryPointName; + ShaderProgramKind _kind; NovelRT::Utilities::Lazy _shaderModule; std::vector _bytecode; VkShaderModuleCreateInfo _shaderModuleCreateInfo; @@ -24,12 +29,14 @@ namespace NovelRT::Graphics::Vulkan std::string entryPointName, ShaderProgramKind kind, NovelRT::Utilities::Misc::Span bytecode) noexcept; - - [[nodiscard]] NovelRT::Utilities::Misc::Span GetBytecode() const noexcept final; + + ~VulkanShaderProgram(); + + [[nodiscard]] std::shared_ptr GetDevice() const noexcept; + [[nodiscard]] std::string GetEntryPointName() const noexcept; + [[nodiscard]] ShaderProgramKind GetKind() const noexcept; + [[nodiscard]] NovelRT::Utilities::Misc::Span GetBytecode() const noexcept; [[nodiscard]] VkShaderModule GetShaderModule(); - ~VulkanShaderProgram() override; }; } - -#endif // NOVELRT_GRAPHICS_VULKAN_VULKANSHADERPROGRAM_H diff --git a/graphics/GraphicsMemoryBlock.cpp b/graphics/GraphicsMemoryBlock.cpp deleted file mode 100644 index 80ee3643e..000000000 --- a/graphics/GraphicsMemoryBlock.cpp +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#include - -namespace NovelRT::Graphics -{ - GraphicsMemoryBlock::GraphicsMemoryBlock(std::shared_ptr device, - std::shared_ptr collection) - : GraphicsDeviceObject(std::move(device)), _collection(std::move(collection)) - { - if (_collection == nullptr) - { - throw Exceptions::NullPointerException("Parameter: collection."); - } - - // directly calling the base GetDevice here to avoid trouble with the virtual override. - if (_collection->GetDevice() != GraphicsDeviceObject::GetDevice()) - { - throw std::out_of_range("The same graphics device is not being used for this memory block. It is out " - "of range of one of the devices."); - } - } -} // namespace NovelRT::Graphics diff --git a/graphics/GraphicsMemoryBlockCollection.cpp b/graphics/GraphicsMemoryBlockCollection.cpp deleted file mode 100644 index da040cc34..000000000 --- a/graphics/GraphicsMemoryBlockCollection.cpp +++ /dev/null @@ -1,482 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#include - -namespace NovelRT::Graphics -{ - std::shared_ptr GraphicsMemoryBlockCollection::AddBlock(size_t size) - { - std::shared_ptr block = std::shared_ptr(CreateBlock(size)); - - _blocks.push_back(block); - _size += size; - - return block; - } - - size_t GraphicsMemoryBlockCollection::GetAdjustedBlockSize(size_t size) const noexcept - { - size_t maximumSharedBlockSize = GetMaximumSharedBlockSize(); - size_t blockSize = size; - - if (blockSize < maximumSharedBlockSize) - { - size_t minimumBlockSize = GetMinimumBlockSize(); - blockSize = GetMaximumSharedBlockSize(); - - if (minimumBlockSize != maximumSharedBlockSize) - { - // Allocate 1/8, 1/4, 1/2 as first blocks, ensuring we don't go smaller than the minimum. - size_t largestBlockSize = GetLargestSharedBlockSize(); - - for (size_t i = 0; i < 3; ++i) - { - size_t smallerBlockSize = blockSize / 2; - - if ((smallerBlockSize > largestBlockSize) && (smallerBlockSize >= (size * 2))) - { - blockSize = std::max(smallerBlockSize, minimumBlockSize); - } - else - { - break; - } - } - } - } - else - { - blockSize = size; - } - - return blockSize; - } - - size_t GraphicsMemoryBlockCollection::GetLargestSharedBlockSize() const noexcept - { - size_t result = 0; - NovelRT::Utilities::Misc::Span> blocks(_blocks.data(), - _blocks.size()); - size_t maximumSharedBlockSize = GetMaximumSharedBlockSize(); - - for (size_t i = blocks.size(); i-- != 0;) - { - size_t blockSize = blocks[i]->GetSize(); - - if (blockSize < maximumSharedBlockSize) - { - result = std::max(result, blockSize); - } - else if (blockSize == maximumSharedBlockSize) - { - result = maximumSharedBlockSize; - break; - } - } - - return result; - } - - void GraphicsMemoryBlockCollection::IncrementallySortBlocks() noexcept - { - // Bubble sort only until first swap. This is called after - // freeing a region and will result in eventual consistency. - - NovelRT::Utilities::Misc::Span> blocks(&(*_blocks.begin()), - _blocks.size()); - - if (blocks.size() >= 2) - { - std::shared_ptr previousBlock = blocks[0]; - - for (size_t i = 1; i < blocks.size(); ++i) - { - std::shared_ptr block = blocks[i]; - - if (previousBlock->GetTotalFreeRegionSize() <= block->GetTotalFreeRegionSize()) - { - previousBlock = block; - } - else - { - blocks[i - 1] = block; - blocks[i] = previousBlock; - return; - } - } - } - } - - void GraphicsMemoryBlockCollection::RemoveBlock(const std::shared_ptr& block) - { - auto blockIndex = std::find(_blocks.begin(), _blocks.end(), block); - RemoveBlockAt(blockIndex); - } - - void GraphicsMemoryBlockCollection::RemoveBlockAt( - std::vector>::iterator iterator) - { - std::shared_ptr block = *iterator; - _blocks.erase(iterator); - _size -= block->GetSize(); - } - - void GraphicsMemoryBlockCollection::RemoveBlockAt(size_t index) - { - RemoveBlockAt(std::next(_blocks.begin(), static_cast(index))); - } - - bool GraphicsMemoryBlockCollection::TryAllocateRegion(size_t size, - size_t alignment, - GraphicsMemoryRegionAllocationFlags flags, - GraphicsMemoryRegion& region) - { - bool useDedicatedBlock = (flags & GraphicsMemoryRegionAllocationFlags::DedicatedCollection) == - GraphicsMemoryRegionAllocationFlags::DedicatedCollection; - - bool useExistingBlock = (flags & GraphicsMemoryRegionAllocationFlags::ExistingCollection) == - GraphicsMemoryRegionAllocationFlags::ExistingCollection; - - if (useDedicatedBlock && useExistingBlock) - { - throw std::out_of_range( - "A region allocation request defined as requiring both a dedicated and existing block."); - } - - GraphicsMemoryBudget budget = - _allocator->GetBudget(std::dynamic_pointer_cast(shared_from_this())); - - size_t maximumSharedBlockSize = GetMaximumSharedBlockSize(); - size_t sizeWithMargins = size + (2 * _allocator->GetSettings().MinimumAllocatedRegionMarginSize.value_or(0)); - - NovelRT::Utilities::Misc::Span> blocks(_blocks.data(), _blocks.size()); - size_t blocksLength = blocks.size(); - - size_t availableMemory = (budget.GetEstimatedUsage() < budget.GetEstimatedBudget()) - ? (budget.GetEstimatedBudget() - budget.GetEstimatedUsage()) - : 0; - - bool canCreateNewBlock = !useExistingBlock && (blocksLength < static_cast(GetMaximumBlockCount())) && - (availableMemory >= sizeWithMargins); - - // 1. Search existing blocks. - - if (!useDedicatedBlock && (size <= maximumSharedBlockSize)) - { - for (size_t blockIndex = 0; blockIndex < blocksLength; ++blockIndex) - { - std::shared_ptr currentBlock = blocks[blockIndex]; - - if (currentBlock == nullptr) - { - throw Exceptions::NullPointerException("The memory block is set to nullptr."); - } - - if (currentBlock->TryAllocate(size, alignment, region)) - { - if (currentBlock == _emptyBlock) - { - _emptyBlock = nullptr; - } - return true; - } - } - } - - // 2. Try to create a new block. - - if (!canCreateNewBlock) - { - return false; - } - - size_t blockSize = GetAdjustedBlockSize(sizeWithMargins); - - if (blockSize >= availableMemory) - { - return false; - } - - std::shared_ptr block = AddBlock(blockSize); - return block->TryAllocate(size, alignment, region); - } - - GraphicsMemoryBlockCollection::GraphicsMemoryBlockCollection(std::shared_ptr device, - std::shared_ptr allocator) - : GraphicsDeviceObject(std::move(device)), - _allocator(std::move(allocator)), - _blocks{}, - _mutex(), - _emptyBlock(nullptr), - _minimumSize(0), - _size(0LL), - _state() - { - if (_allocator == nullptr) - { - throw Exceptions::NullPointerException("Parameter name: allocator."); - } - - if (_allocator->GetDevice() != GraphicsDeviceObject::GetDevice()) - { - throw std::out_of_range( - "The same graphics device is not being used for this memory block collection. It is out " - "of range of one of the devices."); - } - - const GraphicsMemoryAllocatorSettings& settings = _allocator->GetSettings(); - - int32_t minimumBlockCount = settings.MinimumBlockCountPerCollection; - size_t maximumSharedBlockSize = settings.MaximumSharedBlockSize.value_or(0); - - for (int32_t i = 0; i < minimumBlockCount; ++i) - { - size_t blockSize = GetAdjustedBlockSize(maximumSharedBlockSize); - static_cast(AddBlock(blockSize)); - } - - static_cast(_state.Transition(Threading::VolatileState::Initialised)); - } - - GraphicsMemoryRegion GraphicsMemoryBlockCollection::Allocate( - size_t size, - size_t alignment, - GraphicsMemoryRegionAllocationFlags flags) - { - GraphicsMemoryRegion outRegion(0, nullptr, nullptr, false, 0, 0); - bool succeeded = TryAllocate(size, alignment, flags, outRegion); - - if (!succeeded) - { - throw Exceptions::OutOfMemoryException("Attempted to allocate memory region of size: " + - std::to_string(size)); - } - - return outRegion; - } - - void GraphicsMemoryBlockCollection::Free(const GraphicsMemoryRegion& region) - { - std::shared_ptr block = region.GetCollection(); - - if (block == nullptr) - { - throw Exceptions::NullPointerException("The supplied memory region's collection is nullptr."); - } - - std::lock_guard guard(_mutex); - - auto blockIndex = std::find(_blocks.begin(), _blocks.end(), block); - - if (blockIndex == _blocks.end()) - { - throw Exceptions::KeyNotFoundException( - "The memory block associated with the supplied region was not found in the block collection."); - } - - block->Free(region); - - if (block->GetIsEmpty()) - { - size_t blocksCount = _blocks.size(); - - if (_emptyBlock != nullptr) - { - if (blocksCount > static_cast(GetMinimumBlockCount())) - { - size_t size = GetSize(); - size_t minimumSize = GetMinimumSize(); - - // We have two empty blocks, we want to prefer removing the larger of the two. - - if (block->GetSize() > _emptyBlock->GetSize()) - { - if ((size - block->GetSize()) >= minimumSize) - { - RemoveBlockAt(blockIndex); - } - else if ((size - _emptyBlock->GetSize()) >= minimumSize) - { - RemoveBlock(_emptyBlock); - } - } - else if ((size - _emptyBlock->GetSize()) >= minimumSize) - { - RemoveBlockAt(blockIndex); - } - else if ((size - block->GetSize()) >= minimumSize) - { - RemoveBlock(_emptyBlock); - } - - // Removing either would put us below the minimum size if none of the above is met, so we can't - // remove. - } - else if (block->GetSize() > _emptyBlock->GetSize()) - { - _emptyBlock = block; - } - } - else - { - // We have no existing empty blocks, so we want to set the index to this block unless - // we are currently exceeding our memory budget, in which case we want to free the block - // instead. However, we still need to maintain the minimum block count and minimum size - // placed on the collection, so we will only respect the budget if those can be maintained. - - GraphicsMemoryBudget budget = - _allocator->GetBudget(std::static_pointer_cast(shared_from_this())); - - if ((budget.GetEstimatedUsage() >= budget.GetEstimatedBudget()) && - (blocksCount > static_cast(GetMinimumBlockCount())) && - ((GetSize() - block->GetSize()) >= GetMinimumSize())) - { - RemoveBlockAt(blockIndex); - } - else - { - _emptyBlock = block; - } - } - } - - IncrementallySortBlocks(); - } - - bool GraphicsMemoryBlockCollection::TryAllocate(size_t size, - size_t alignment, - GraphicsMemoryRegionAllocationFlags flags, - GraphicsMemoryRegion& outRegion) - { - std::lock_guard guard(_mutex); - return TryAllocateRegion(size, alignment, flags, outRegion); - } - - bool GraphicsMemoryBlockCollection::TryAllocate(size_t size, GraphicsMemoryRegion& outRegion) - { - return TryAllocate(size, 1, GraphicsMemoryRegionAllocationFlags::None, outRegion); - } - - bool GraphicsMemoryBlockCollection::TryAllocate( - size_t size, - size_t alignment, - GraphicsMemoryRegionAllocationFlags flags, - NovelRT::Utilities::Misc::Span> regions) - { - bool succeeded = true; - size_t index; - - // This scope is needed for the lock guard. - { - std::lock_guard guard(_mutex); - - for (index = 0; index < regions.size(); ++index) - { - succeeded = TryAllocateRegion(size, alignment, flags, regions[index]); - - if (!succeeded) - { - break; - } - } - } - - if (!succeeded) - { - while (index-- != 0) - { - Free(regions[index]); - regions[index] = GraphicsMemoryRegion(); - } - } - - return succeeded; - } - - bool GraphicsMemoryBlockCollection::TryAllocate( - size_t size, - NovelRT::Utilities::Misc::Span> regions) - { - return TryAllocate(size, 1, GraphicsMemoryRegionAllocationFlags::None, regions); - } - - bool GraphicsMemoryBlockCollection::TrySetMinimumSize(size_t minimumSize) - { - std::lock_guard guard(_mutex); - - size_t currentMinimumSize = GetMinimumSize(); - - if (minimumSize == currentMinimumSize) - { - return true; - } - - size_t size = GetSize(); - size_t blockCount = _blocks.size(); - - if (minimumSize < currentMinimumSize) - { - std::shared_ptr emptyBlock = nullptr; - size_t minimumBlockCount = GetMinimumBlockCount(); - - for (size_t blockIndex = blockCount; blockIndex-- != 0;) - { - std::shared_ptr block = _blocks[blockIndex]; - - size_t blockSize = block->GetSize(); - bool blockIsEmpty = block->GetIsEmpty(); - - if (blockIsEmpty) - { - if (((size - blockSize) >= minimumSize) && ((blockCount - 1) >= minimumBlockCount)) - { - RemoveBlockAt(blockIndex); - size -= blockSize; - --blockCount; - } - else - { - emptyBlock = (emptyBlock == nullptr) ? block : emptyBlock; - } - } - } - _emptyBlock = emptyBlock; - } - else - { - std::shared_ptr emptyBlock = nullptr; - size_t maximumBlockCount = GetMaximumBlockCount(); - size_t maximumSharedBlockSize = GetMaximumSharedBlockSize(); - size_t minimumBlockSize = GetMinimumBlockSize(); - - while (size < minimumSize) - { - if (blockCount < maximumBlockCount) - { - size_t blockSize = GetAdjustedBlockSize(maximumSharedBlockSize); - - if (((size + blockSize) > minimumSize) && (blockSize != minimumBlockSize)) - { - blockSize = minimumSize - size; - } - - emptyBlock = (emptyBlock == nullptr) ? AddBlock(blockSize) : emptyBlock; - size += blockSize; - } - else - { - _emptyBlock = (_emptyBlock == nullptr) ? emptyBlock : _emptyBlock; - return false; - } - } - - _emptyBlock = (_emptyBlock == nullptr) ? emptyBlock : _emptyBlock; - } - - _minimumSize = minimumSize; - - assert(_size == size && "Sizes don't match!"); - return true; - } -} // namespace NovelRT::Graphics diff --git a/graphics/GraphicsPipeline.cpp b/graphics/GraphicsPipeline.cpp deleted file mode 100644 index 22cc64a4b..000000000 --- a/graphics/GraphicsPipeline.cpp +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#include - -namespace NovelRT::Graphics -{ - GraphicsPipeline::GraphicsPipeline(const std::shared_ptr& device, - std::shared_ptr signature, - std::shared_ptr vertexShader, - std::shared_ptr pixelShader) noexcept - : GraphicsDeviceObject(std::weak_ptr(device)), - _signature(signature), - _vertexShader(vertexShader), - _pixelShader(pixelShader) - { - } - - bool GraphicsPipeline::HasVertexShader() const noexcept - { - return _vertexShader != nullptr; - } - - bool GraphicsPipeline::HasPixelShader() const noexcept - { - return _pixelShader != nullptr; - } - - std::shared_ptr GraphicsPipeline::GetVertexShader() const noexcept - { - return _vertexShader; - } - - std::shared_ptr GraphicsPipeline::GetPixelShader() const noexcept - { - return _pixelShader; - } - - std::shared_ptr GraphicsPipeline::GetSignature() const noexcept - { - return _signature; - } -} // namespace NovelRT::Graphics diff --git a/graphics/GraphicsPipelineSignature.cpp b/graphics/GraphicsPipelineSignature.cpp deleted file mode 100644 index 9fde9071e..000000000 --- a/graphics/GraphicsPipelineSignature.cpp +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#include - -namespace NovelRT::Graphics -{ - - GraphicsPipelineSignature::GraphicsPipelineSignature( - std::shared_ptr device, - GraphicsPipelineBlendFactor srcBlendFactor, - GraphicsPipelineBlendFactor dstBlendFactor, - NovelRT::Utilities::Misc::Span inputs, - NovelRT::Utilities::Misc::Span resources) noexcept - : GraphicsDeviceObject(std::move(device)), - _srcBlendFactor(srcBlendFactor), - _dstBlendFactor(dstBlendFactor), - _inputs(std::vector(inputs.begin(), inputs.end())), - _resources(std::vector(resources.begin(), resources.end())) - { - } - - NovelRT::Utilities::Misc::Span GraphicsPipelineSignature::GetInputs() const noexcept - { - return NovelRT::Utilities::Misc::Span(&(*_inputs.begin()), _inputs.size()); - } - NovelRT::Utilities::Misc::Span GraphicsPipelineSignature::GetResources() - const noexcept - { - return NovelRT::Utilities::Misc::Span(&(*_resources.begin()), - _resources.size()); - } -} // namespace NovelRT::Graphics diff --git a/graphics/GraphicsResourceManager.cpp b/graphics/GraphicsResourceManager.cpp deleted file mode 100644 index a33db8d56..000000000 --- a/graphics/GraphicsResourceManager.cpp +++ /dev/null @@ -1,481 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#include - -namespace NovelRT::Graphics -{ - GraphicsResourceManager::GraphicsResourceManager(std::shared_ptr graphicsDevice, - size_t startingStagingBufferSize) - : _defaultBuffers{}, - _vertexBuffers{}, - _indexBuffers{}, - _constantBuffers{}, - _textures{}, - _graphicsDevice(std::move(graphicsDevice)), - _stagingBufferSize(startingStagingBufferSize), - _contextIndex(0) - { - if (_stagingBufferSize == 0) - { - _stagingBufferSize = _graphicsDevice->GetMemoryAllocator()->GetSettings().MinimumBlockSize; - } - } - - GraphicsResourceManager::GraphicsResourceManager(const GraphicsResourceManager& other) - : _defaultBuffers{}, - _vertexBuffers{}, - _indexBuffers{}, - _constantBuffers{}, - _textures{}, - _graphicsDevice(nullptr), - _stagingBufferSize(0), - _contextIndex(0) - { - *this = other; - } - - GraphicsResourceManager::GraphicsResourceManager(GraphicsResourceManager&& other) noexcept - : _defaultBuffers{}, - _vertexBuffers{}, - _indexBuffers{}, - _constantBuffers{}, - _textures{}, - _graphicsDevice(nullptr), - _stagingBufferSize(0), - _contextIndex(0) - { - *this = std::move(other); - } - - GraphicsResourceManager& GraphicsResourceManager::operator=(const GraphicsResourceManager& other) - { - if (this == &other) - { - return *this; - } - - _graphicsDevice = other._graphicsDevice; - _stagingBufferSize = other._stagingBufferSize; - _contextIndex = other._contextIndex; - _stagingBuffers = {}; - _defaultBuffers = {}; - _vertexBuffers = {}; - _indexBuffers = {}; - _constantBuffers = {}; - _textures = {}; - - return *this; - } - - GraphicsResourceManager& GraphicsResourceManager::operator=(GraphicsResourceManager&& other) noexcept - { - _graphicsDevice = std::move(other._graphicsDevice); - _stagingBuffers = std::move(other._stagingBuffers); - _defaultBuffers = std::move(other._defaultBuffers); - _vertexBuffers = std::move(other._vertexBuffers); - _indexBuffers = std::move(other._indexBuffers); - _constantBuffers = std::move(other._constantBuffers); - _textures = std::move(other._textures); - _stagingBufferSize = other._stagingBufferSize; - other._stagingBufferSize = 0; - _contextIndex = other._contextIndex; - other._contextIndex = 0; - - return *this; - } - - void GraphicsResourceManager::PrepForFrameWithContextIndex(size_t newContextIndex) - { - size_t finalContextCount = _contextIndex < newContextIndex ? newContextIndex : _contextIndex; - - size_t currentStagingBufferContextSize = _stagingBuffers.size(); - while (currentStagingBufferContextSize <= finalContextCount) - { - _stagingBuffers.emplace_back(std::vector>{}); - ++currentStagingBufferContextSize; - } - - if (_stagingBuffers[_contextIndex].size() == 0) - { - _stagingBufferSize = _graphicsDevice->GetMemoryAllocator()->GetSettings().MinimumBlockSize; - } - else - { - size_t totalSize = 0; - - for (auto&& buffer : _stagingBuffers[_contextIndex]) - { - totalSize += buffer->GetSize(); - } - - totalSize /= _stagingBuffers.size(); - _stagingBufferSize = totalSize; - } - - _stagingBuffers[newContextIndex].clear(); - } - - GraphicsMemoryRegion GraphicsResourceManager::LoadVertexDataUntyped(void* data, - size_t dataTypeSize, - size_t dataLength, - size_t alignment) - { - assert(data != nullptr && - "data is a nullptr, make sure that you are passing in a valid pointer into the method."); - assert(dataTypeSize != 0 && "dataTypeSize is zero, make sure the correct size of the type has been passed in."); - assert(dataLength != 0 && - "dataLength is zero, make sure that the length of the buffer is properly calculated and passed in."); - - size_t sizeToStage = dataTypeSize * dataLength; - auto currentContext = _graphicsDevice->GetCurrentContext(); - - std::shared_ptr stagingBuffer = - GetStagingBufferWithProperSizeHandling(sizeToStage, currentContext); - - std::shared_ptr vertexBuffer = - GetOrCreateGraphicsBufferForAllocationSize(sizeToStage, GraphicsBufferKind::Vertex); - auto vertexRegion = vertexBuffer->Allocate(sizeToStage, alignment); - auto writeArea = stagingBuffer->Map(vertexRegion); - - NovelRT::Utilities::Memory::Copy(writeArea, sizeToStage, data, sizeToStage); - - stagingBuffer->UnmapAndWrite(vertexRegion); - currentContext->Copy(vertexBuffer, stagingBuffer); - - return vertexRegion; - } - - GraphicsMemoryRegion GraphicsResourceManager::LoadIndexDataUntyped(void* data, - size_t dataTypeSize, - size_t dataLength, - size_t alignment) - { - assert(data != nullptr && - "data is a nullptr, make sure that you are passing in a valid pointer into the method."); - assert(dataTypeSize != 0 && "dataTypeSize is zero, make sure the correct size of the type has been passed in."); - assert(dataLength != 0 && - "dataLength is zero, make sure that the length of the buffer is properly calculated and passed in."); - - size_t sizeToStage = dataTypeSize * dataLength; - auto currentContext = _graphicsDevice->GetCurrentContext(); - - std::shared_ptr stagingBuffer = - GetStagingBufferWithProperSizeHandling(sizeToStage, currentContext); - - std::shared_ptr indexBuffer = - GetOrCreateGraphicsBufferForAllocationSize(sizeToStage, GraphicsBufferKind::Index); - auto indexRegion = indexBuffer->Allocate(sizeToStage, alignment); - auto writeArea = stagingBuffer->Map(indexRegion); - - NovelRT::Utilities::Memory::Copy(writeArea, sizeToStage, data, sizeToStage); - - stagingBuffer->UnmapAndWrite(indexRegion); - currentContext->Copy(indexBuffer, stagingBuffer); - - return indexRegion; - } - - std::shared_ptr GraphicsResourceManager::GetStagingBufferWithProperSizeHandling( - size_t sizeToStage, - std::shared_ptr& /*currentContext*/) - { - _stagingBufferSize = _stagingBufferSize < sizeToStage ? sizeToStage : _stagingBufferSize; - - for (auto&& buffer : _stagingBuffers[_contextIndex]) - { - if (buffer->GetLargestFreeRegionSize() >= sizeToStage) - { - return buffer; - } - } - - return CreateStagingBuffer(); - } - - std::shared_ptr GraphicsResourceManager::CreateStagingBuffer() - { - return _stagingBuffers[_contextIndex].emplace_back( - _graphicsDevice->GetMemoryAllocator()->CreateBufferWithDefaultArguments( - Graphics::GraphicsBufferKind::Default, Graphics::GraphicsResourceAccess::Write, - Graphics::GraphicsResourceAccess::Read, _stagingBufferSize)); - } - - std::shared_ptr GraphicsResourceManager::GetOrCreateGraphicsBufferForAllocationSize( - size_t allocationSize, - GraphicsBufferKind bufferKind) - { - const std::vector>& buffers = [&]() { - switch (bufferKind) - { - case GraphicsBufferKind::Default: - return _defaultBuffers; - case GraphicsBufferKind::Vertex: - return _vertexBuffers; - case GraphicsBufferKind::Index: - return _indexBuffers; - case GraphicsBufferKind::Constant: - return _constantBuffers; - default: - throw Exceptions::InvalidOperationException(); - } - }(); - - for (auto&& buffer : buffers) - { - if (buffer->GetLargestFreeRegionSize() >= allocationSize) - { - return buffer; - } - } - - const auto newBuffer = [&]() { - if (bufferKind == GraphicsBufferKind::Constant) - { - return _graphicsDevice->GetMemoryAllocator()->CreateBufferWithDefaultArguments( - GraphicsBufferKind::Constant, GraphicsResourceAccess::Write, GraphicsResourceAccess::Read, - ((allocationSize > _tenMegabytesAsBytes) ? allocationSize : _tenMegabytesAsBytes)); - } - else - { - size_t minimumBlockSize = _graphicsDevice->GetMemoryAllocator()->GetSettings().MinimumBlockSize; - size_t sizeToAllocate = _graphicsDevice->GetMemoryAllocator()->GetSettings().MinimumBlockSize; - while (sizeToAllocate < allocationSize) - { - sizeToAllocate += minimumBlockSize; - } - - return _graphicsDevice->GetMemoryAllocator()->CreateBufferWithDefaultArguments( - bufferKind, GraphicsResourceAccess::None, GraphicsResourceAccess::Write, - ((allocationSize > _tenMegabytesAsBytes) ? allocationSize : _tenMegabytesAsBytes)); - } - }(); - - switch (bufferKind) - { - case GraphicsBufferKind::Default: - return _defaultBuffers.emplace_back(newBuffer); - case GraphicsBufferKind::Vertex: - return _vertexBuffers.emplace_back(newBuffer); - case GraphicsBufferKind::Index: - return _indexBuffers.emplace_back(newBuffer); - case GraphicsBufferKind::Constant: - return _constantBuffers.emplace_back(newBuffer); - } - - throw Exceptions::InvalidOperationException(); // we should never reach here - } - - GraphicsMemoryRegion GraphicsResourceManager::LoadTextureData( - const ResourceManagement::TextureMetadata& metadata, - GraphicsTextureAddressMode addressMode, - GraphicsTextureKind textureKind) - { - assert(metadata.data.size() != 0 && - "metadata.data.size is zero, make sure you are passing in metadata that has a valid size on the data."); - assert(metadata.data.data() != nullptr && - "metadata.data.data() returns a nullptr, make sure it returns a valid pointer."); - - auto currentContext = _graphicsDevice->GetCurrentContext(); - - std::shared_ptr texture2d = - _graphicsDevice->GetMemoryAllocator()->CreateTextureWithDefaultArguments( - addressMode, textureKind, GraphicsResourceAccess::None, GraphicsResourceAccess::Write, metadata.width, - metadata.height); - - std::shared_ptr stagingBuffer = - GetStagingBufferWithProperSizeHandling(texture2d->GetSize(), currentContext); - - auto texture2dRegion = texture2d->Allocate(texture2d->GetSize(), 4); - auto pTextureData = stagingBuffer->Map(texture2dRegion); - - NovelRT::Utilities::Memory::Copy(pTextureData, metadata.data.size(), metadata.data.data(), - metadata.data.size()); - - stagingBuffer->UnmapAndWrite(texture2dRegion); - currentContext->Copy(texture2d, stagingBuffer); - - return texture2dRegion; - } - - void GraphicsResourceManager::FreeVertexData(GraphicsMemoryRegion& vertexResource) - { - auto collection = vertexResource.GetCollection(); - auto bufferPtr = std::dynamic_pointer_cast(collection); - - if (bufferPtr == nullptr) - { - throw Exceptions::InvalidOperationException("An invalid graphics resource was passed into FreeVertexData."); - } - - collection->Free(vertexResource); - - if (bufferPtr->GetSize() == bufferPtr->GetLargestFreeRegionSize()) - { - unused(std::remove(_vertexBuffers.begin(), _vertexBuffers.end(), bufferPtr)); - } - } - - void GraphicsResourceManager::FreeIndexData(GraphicsMemoryRegion& indexResource) - { - auto collection = indexResource.GetCollection(); - auto bufferPtr = std::dynamic_pointer_cast(collection); - - if (bufferPtr == nullptr) - { - throw Exceptions::InvalidOperationException("An invalid graphics resource was passed into FreeIndexData."); - } - - collection->Free(indexResource); - - if (bufferPtr->GetSize() == bufferPtr->GetLargestFreeRegionSize()) - { - unused(std::remove(_indexBuffers.begin(), _indexBuffers.end(), bufferPtr)); - } - } - - void GraphicsResourceManager::FreeTextureData(GraphicsMemoryRegion& textureResource) - { - auto collection = textureResource.GetCollection(); - auto texturePtr = std::dynamic_pointer_cast(collection); - - if (texturePtr == nullptr) - { - throw Exceptions::InvalidOperationException( - "An invalid graphics resource was passed into FreeTextureData."); - } - - collection->Free(textureResource); - - // For now, a single region is a single texture pointer, so we can just remove it. - unused(std::remove(_textures.begin(), _textures.end(), texturePtr)); - } - - GraphicsMemoryRegion GraphicsResourceManager::LoadConstantBufferDataToNewRegion(void* data, - size_t size, - size_t alignment) - { - assert(data != nullptr && - "data is a nullptr, make sure that you are passing in a valid pointer into the method."); - assert(size != 0 && "size is zero, make sure the correct size has been passed in."); - - auto bufferPtr = GetOrCreateGraphicsBufferForAllocationSize(size, GraphicsBufferKind::Constant); - auto allocation = bufferPtr->Allocate(size, alignment); - uint8_t* destination = bufferPtr->Map(allocation); - - NovelRT::Utilities::Memory::Copy(destination, size, data, size); - - bufferPtr->UnmapAndWrite(allocation); - return allocation; - } - - void GraphicsResourceManager::LoadConstantBufferDataToExistingRegion( - GraphicsMemoryRegion& targetMemoryResource, - void* data, - size_t size) - { - assert(data != nullptr && - "data is a nullptr, make sure that you are passing in a valid pointer into the method."); - assert(size != 0 && "dataTypeSize is zero, make sure the correct size has been passed in."); - - auto bufferPtr = std::dynamic_pointer_cast(targetMemoryResource.GetCollection()); - - if (bufferPtr == nullptr) - { - throw Exceptions::InvalidOperationException("The provided region was not provided by a constant buffer"); - } - - if (std::find(_constantBuffers.begin(), _constantBuffers.end(), bufferPtr) == _constantBuffers.end()) - { - throw Exceptions::InvalidOperationException( - "The provided region is not managed by this instance of GraphicsResourceManager."); - } - - if (targetMemoryResource.GetSize() < size) - { - throw std::out_of_range("The size of the data is too large for the specified memory region."); - } - - uint8_t* destination = bufferPtr->Map(targetMemoryResource); - - NovelRT::Utilities::Memory::Copy(destination, size, data, size); - - bufferPtr->UnmapAndWrite(targetMemoryResource); - } - - void GraphicsResourceManager::FreeConstantBufferData(GraphicsMemoryRegion& region) - { - auto collection = region.GetCollection(); - auto bufferPtr = std::dynamic_pointer_cast(collection); - - if (bufferPtr == nullptr) - { - throw Exceptions::InvalidOperationException( - "An invalid graphics resource was passed into FreeConstantBufferRegion"); - } - - auto iterator = std::find(_constantBuffers.begin(), _constantBuffers.end(), bufferPtr); - - if (iterator == _constantBuffers.end()) - { - throw Exceptions::InvalidOperationException("The constant buffer this region belongs to is not managed by " - "this instance of GraphicsResourceManager."); - } - - bufferPtr->Free(region); - - if (bufferPtr->GetSize() == bufferPtr->GetLargestFreeRegionSize()) - { - _constantBuffers.erase(iterator); - } - } - - uint8_t* GraphicsResourceManager::MapConstantBufferRegionForWritingUntyped( - GraphicsMemoryRegion& targetMemoryResource) - { - auto bufferPtr = std::dynamic_pointer_cast(targetMemoryResource.GetCollection()); - - if (bufferPtr == nullptr) - { - throw Exceptions::InvalidOperationException( - "An invalid graphics resource was passed into FreeConstantBufferRegion"); - } - - size_t oldLength = _constantBuffersToUnmapAndWrite.size(); - for (size_t i = 0; i < _constantBuffers.size(); i++) - { - if (bufferPtr != _constantBuffers[i]) - { - continue; - } - - _constantBuffersToUnmapAndWrite.emplace(i); - break; - } - - if (oldLength >= _constantBuffersToUnmapAndWrite.size()) - { - throw Exceptions::InvalidOperationException("The constant buffer this region belongs to is not managed by " - "this instance of GraphicsResourceManager."); - } - - return bufferPtr->Map(targetMemoryResource); - } - - void GraphicsResourceManager::UnmapAndWriteAllConstantBuffers() noexcept - { - for (size_t index : _constantBuffersToUnmapAndWrite) - { - _constantBuffers[index]->UnmapAndWrite(); - } - - _constantBuffersToUnmapAndWrite.clear(); - } - - GraphicsMemoryRegion GraphicsResourceManager::AllocateConstantBufferRegion(size_t size, - size_t alignment) - { - auto bufferPtr = GetOrCreateGraphicsBufferForAllocationSize(size, GraphicsBufferKind::Constant); - return bufferPtr->Allocate(size, alignment); - } -} diff --git a/graphics/ShaderProgram.cpp b/graphics/ShaderProgram.cpp deleted file mode 100644 index 929a50986..000000000 --- a/graphics/ShaderProgram.cpp +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#include - -namespace NovelRT::Graphics -{ - - ShaderProgram::ShaderProgram(std::shared_ptr device, - std::string entryPointName, - ShaderProgramKind kind) noexcept - : GraphicsDeviceObject(std::move(device)), _entryPointName(std::move(entryPointName)), _kind(kind) - { - } -} // namespace NovelRT::Graphics diff --git a/graphics/Vulkan/VulkanGraphicsBuffer.cpp b/graphics/Vulkan/VulkanGraphicsBuffer.cpp deleted file mode 100644 index 77183eccf..000000000 --- a/graphics/Vulkan/VulkanGraphicsBuffer.cpp +++ /dev/null @@ -1,236 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#include - -namespace NovelRT::Graphics::Vulkan -{ - VulkanGraphicsDevice* VulkanGraphicsBuffer::GetDeviceInternal() const noexcept - { - // TODO: This feels like it might be a perf issue later. - return dynamic_cast(GraphicsDeviceObject::GetDevice().get()); - } - - VulkanGraphicsBuffer::VulkanGraphicsBuffer(std::shared_ptr device, - GraphicsBufferKind kind, - GraphicsMemoryRegion blockRegion, - GraphicsResourceAccess cpuAccess, - VkBuffer buffer) - : GraphicsBuffer(std::move(device), kind, std::move(blockRegion), cpuAccess), _vulkanBuffer(buffer) - { - VkResult bindResult = vkBindBufferMemory(GetAllocator()->GetDevice()->GetVulkanDevice(), _vulkanBuffer, - GetBlock()->GetVulkanDeviceMemory(), GetBlockRegion().GetOffset()); - - if (bindResult != VK_SUCCESS) - { - throw Exceptions::InitialisationFailureException("Failed to bind the VkBuffer!", bindResult); - } - } - - void* VulkanGraphicsBuffer::MapUntyped() - { - std::shared_ptr device = GetDevice(); - - VkDevice vulkanDevice = device->GetVulkanDevice(); - VkDeviceMemory vulkanDeviceMemory = GetBlock()->GetVulkanDeviceMemory(); - - void* pDestination = nullptr; - - VkResult mapMemoryResult = - vkMapMemory(vulkanDevice, vulkanDeviceMemory, GetOffset(), GetSize(), 0, &pDestination); - - if (mapMemoryResult != VK_SUCCESS) - { - // TODO: Make a real exception. - throw std::runtime_error("Failed to map Vulkan memory to the CPU!"); - } - - return pDestination; - } - - void* VulkanGraphicsBuffer::MapUntyped(size_t rangeOffset, size_t /*rangeLength*/) - { - std::shared_ptr device = GetDevice(); - - VkDevice vulkanDevice = device->GetVulkanDevice(); - VkDeviceMemory vulkanDeviceMemory = GetBlock()->GetVulkanDeviceMemory(); - - void* pDestination = nullptr; - - VkResult mapMemoryResult = - vkMapMemory(vulkanDevice, vulkanDeviceMemory, GetOffset(), GetSize(), 0, &pDestination); - - if (mapMemoryResult != VK_SUCCESS) - { - // TODO: Make a real exception. - throw std::runtime_error("Failed to map Vulkan memory to the CPU! Reason: " + - std::to_string(mapMemoryResult)); - } - - return reinterpret_cast(pDestination) + rangeOffset; - } - - const void* VulkanGraphicsBuffer::MapForReadUntyped() - { - std::shared_ptr device = GetDevice(); - - VkDevice vulkanDevice = device->GetVulkanDevice(); - VkDeviceMemory vulkanDeviceMemory = GetBlock()->GetVulkanDeviceMemory(); - - void* pDestination = nullptr; - - VkResult mapMemoryResult = - vkMapMemory(vulkanDevice, vulkanDeviceMemory, GetOffset(), GetSize(), 0, &pDestination); - - if (mapMemoryResult != VK_SUCCESS) - { - // TODO: Make a real exception. - throw std::runtime_error("Failed to map Vulkan memory to the CPU! Reason: " + - std::to_string(mapMemoryResult)); - } - - uint64_t nonCoherentAtomSize = - device->GetAdapter()->GetVulkanPhysicalDeviceProperties().limits.nonCoherentAtomSize; - - size_t offset = GetOffset(); - size_t size = (GetSize() + nonCoherentAtomSize - 1) & ~(nonCoherentAtomSize - 1); - - VkMappedMemoryRange mappedMemoryRange{}; - mappedMemoryRange.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; - mappedMemoryRange.memory = vulkanDeviceMemory; - mappedMemoryRange.offset = offset; - mappedMemoryRange.size = size; - - VkResult invalidateMappedMemoryRangesResult = - vkInvalidateMappedMemoryRanges(device->GetVulkanDevice(), 1, &mappedMemoryRange); - - if (invalidateMappedMemoryRangesResult != VK_SUCCESS) - { - // TODO: Make a real exception. - throw std::runtime_error("Failed to map the Vulkan memory for read only!"); - } - - return pDestination; - } - - const void* VulkanGraphicsBuffer::MapForReadUntyped(size_t readRangeOffset, size_t readRangeLength) - { - std::shared_ptr device = GetDevice(); - - VkDevice vulkanDevice = device->GetVulkanDevice(); - VkDeviceMemory vulkanDeviceMemory = GetBlock()->GetVulkanDeviceMemory(); - - void* pDestination = nullptr; - - VkResult mapMemoryResult = - vkMapMemory(vulkanDevice, vulkanDeviceMemory, GetOffset(), GetSize(), 0, &pDestination); - - if (mapMemoryResult != VK_SUCCESS) - { - // TODO: Make a real exception. - throw std::runtime_error("Failed to map Vulkan memory to the CPU!"); - } - - uint64_t nonCoherentAtomSize = - device->GetAdapter()->GetVulkanPhysicalDeviceProperties().limits.nonCoherentAtomSize; - - size_t offset = GetOffset() + readRangeOffset; - size_t size = (readRangeLength + nonCoherentAtomSize - 1) & ~(nonCoherentAtomSize - 1); - - VkMappedMemoryRange mappedMemoryRange{}; - mappedMemoryRange.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; - mappedMemoryRange.memory = vulkanDeviceMemory; - mappedMemoryRange.offset = offset; - mappedMemoryRange.size = size; - - VkResult invalidateMappedMemoryRangesResult = - vkInvalidateMappedMemoryRanges(device->GetVulkanDevice(), 1, &mappedMemoryRange); - - if (invalidateMappedMemoryRangesResult != VK_SUCCESS) - { - // TODO: Make a real exception. - throw std::runtime_error("Failed to map the Vulkan memory for read only!"); - } - - return (reinterpret_cast(pDestination) + readRangeOffset); - } - - void VulkanGraphicsBuffer::Unmap() - { - std::shared_ptr device = GetDevice(); - - VkDevice vulkanDevice = device->GetVulkanDevice(); - VkDeviceMemory vulkanDeviceMemory = GetBlock()->GetVulkanDeviceMemory(); - - vkUnmapMemory(vulkanDevice, vulkanDeviceMemory); - } - - void VulkanGraphicsBuffer::UnmapAndWrite() - { - std::shared_ptr device = GetDevice(); - - VkDevice vulkanDevice = device->GetVulkanDevice(); - VkDeviceMemory vulkanDeviceMemory = GetBlock()->GetVulkanDeviceMemory(); - - uint64_t nonCoherentAtomSize = - device->GetAdapter()->GetVulkanPhysicalDeviceProperties().limits.nonCoherentAtomSize; - - size_t offset = GetOffset(); - size_t size = (GetSize() + nonCoherentAtomSize - 1) & ~(nonCoherentAtomSize - 1); - - VkMappedMemoryRange mappedMemoryRange{}; - mappedMemoryRange.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; - mappedMemoryRange.memory = vulkanDeviceMemory; - mappedMemoryRange.offset = offset; - mappedMemoryRange.size = size; - - VkResult flushMappedMemoryRangesResult = vkFlushMappedMemoryRanges(vulkanDevice, 1, &mappedMemoryRange); - - if (flushMappedMemoryRangesResult != VK_SUCCESS) - { - // TODO: Make a real exception. - throw std::runtime_error("Failed to flush the written changes to the Vulkan memory!"); - } - - vkUnmapMemory(vulkanDevice, vulkanDeviceMemory); - } - - void VulkanGraphicsBuffer::UnmapAndWrite(size_t writtenRangeOffset, size_t writtenRangeLength) - { - std::shared_ptr device = GetDevice(); - - VkDevice vulkanDevice = device->GetVulkanDevice(); - VkDeviceMemory vulkanDeviceMemory = GetBlock()->GetVulkanDeviceMemory(); - - uint64_t nonCoherentAtomSize = - device->GetAdapter()->GetVulkanPhysicalDeviceProperties().limits.nonCoherentAtomSize; - - size_t offset = GetOffset() + writtenRangeOffset; - size_t size = (writtenRangeLength + nonCoherentAtomSize - 1) & ~(nonCoherentAtomSize - 1); - - VkMappedMemoryRange mappedMemoryRange{}; - mappedMemoryRange.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; - mappedMemoryRange.memory = vulkanDeviceMemory; - mappedMemoryRange.offset = offset; - mappedMemoryRange.size = size; - - VkResult flushMappedMemoryRangesResult = vkFlushMappedMemoryRanges(vulkanDevice, 1, &mappedMemoryRange); - - if (flushMappedMemoryRangesResult != VK_SUCCESS) - { - // TODO: Make a real exception. - throw std::runtime_error("Failed to flush the written changes to the Vulkan memory!"); - } - - vkUnmapMemory(vulkanDevice, vulkanDeviceMemory); - } - - VulkanGraphicsBuffer::~VulkanGraphicsBuffer() - { - if (_vulkanBuffer != VK_NULL_HANDLE) - { - vkDestroyBuffer(GetDevice()->GetVulkanDevice(), GetVulkanBuffer(), nullptr); - } - GetBlockRegion().GetCollection()->Free(GetBlockRegion()); - } -} // namespace NovelRT::Graphics::Vulkan diff --git a/graphics/Vulkan/VulkanGraphicsMemoryAllocator.cpp b/graphics/Vulkan/VulkanGraphicsMemoryAllocator.cpp deleted file mode 100644 index 3f28d7fb2..000000000 --- a/graphics/Vulkan/VulkanGraphicsMemoryAllocator.cpp +++ /dev/null @@ -1,261 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#include - -namespace NovelRT::Graphics::Vulkan -{ - // TODO: I have no idea if this works. Lol. -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable : 4996) -#elif defined(__clang__) -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" -#endif - size_t VulkanGraphicsMemoryAllocator::GetBlockCollectionIndex(GraphicsResourceAccess cpuAccess, - uint32_t memoryTypeBits) - { - bool isIntegratedGpu = GetDevice()->GetAdapter()->GetVulkanPhysicalDeviceProperties().deviceType == - VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU; - - VkMemoryPropertyFlagBits requiredMemoryPropertyFlags = static_cast(0); - VkMemoryPropertyFlagBits preferredMemoryPropertyFlags = static_cast(0); - VkMemoryPropertyFlagBits unpreferredMemoryPropertyFlags = static_cast(0); - - switch (cpuAccess) - { - case GraphicsResourceAccess::Read: - requiredMemoryPropertyFlags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; - preferredMemoryPropertyFlags |= VK_MEMORY_PROPERTY_HOST_CACHED_BIT; - break; - case GraphicsResourceAccess::Write: - requiredMemoryPropertyFlags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; - preferredMemoryPropertyFlags |= - isIntegratedGpu ? static_cast(0) : VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; - break; - case GraphicsResourceAccess::ReadWrite: - requiredMemoryPropertyFlags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; - preferredMemoryPropertyFlags |= VK_MEMORY_PROPERTY_HOST_CACHED_BIT; - preferredMemoryPropertyFlags |= - isIntegratedGpu ? static_cast(0) : VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; - break; - default: - case GraphicsResourceAccess::None: - preferredMemoryPropertyFlags |= - isIntegratedGpu ? static_cast(0) : VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; - break; - } - - int32_t index = -1; - int32_t lowestCost = std::numeric_limits::max(); - - const VkPhysicalDeviceMemoryProperties& memoryProperties = - GetDevice()->GetAdapter()->GetVulkanPhysicalDeviceMemoryProperties(); - - for (int32_t i = 0; i < static_cast(_blockCollections.getActual().size()); i++) - { - if ((memoryTypeBits & (1 << i)) == 0) - { - continue; - } - - VkMemoryPropertyFlags memoryPropertyFlags = memoryProperties.memoryTypes[i].propertyFlags; - - if ((requiredMemoryPropertyFlags & memoryPropertyFlags) != - static_cast(requiredMemoryPropertyFlags)) - { - continue; - } - - if (memoryProperties.memoryHeaps[memoryProperties.memoryTypes[i].heapIndex].flags & - VK_MEMORY_HEAP_MULTI_INSTANCE_BIT) - { - continue; - } - - int32_t cost = - Maths::Utilities::PopCount(static_cast(preferredMemoryPropertyFlags) & ~memoryPropertyFlags) + - Maths::Utilities::PopCount(static_cast(unpreferredMemoryPropertyFlags) & - ~memoryPropertyFlags); - - if (cost >= lowestCost) - { - continue; - } - - index = i; - - if (cost == 0) - { - break; - } - - lowestCost = cost; - } - - if (index == -1) - { - throw std::out_of_range("Requested memory type unavailable on this physical device."); - } - - return index; - } -#ifdef _MSC_VER -#pragma warning(pop) -#elif defined(__clang__) -#pragma clang diagnostic pop -#endif - - VulkanGraphicsMemoryAllocator::VulkanGraphicsMemoryAllocator(std::shared_ptr device, - GraphicsMemoryAllocatorSettings settings) - : GraphicsMemoryAllocatorImpl::DefaultMetadata>( - std::move(device), - std::move(settings)), - _blockCollections([&]() { - std::vector> returnVec{}; - uint32_t memoryTypeCount = - GetDevice()->GetAdapter()->GetVulkanPhysicalDeviceMemoryProperties().memoryTypeCount; - returnVec.reserve(memoryTypeCount); - - for (uint32_t memoryTypeIndex = 0; memoryTypeIndex < memoryTypeCount; memoryTypeIndex++) - { - returnVec.emplace_back(std::static_pointer_cast( - std::make_shared( - GetDevice(), std::dynamic_pointer_cast(shared_from_this()), - memoryTypeIndex))); - } - - return returnVec; - }) - { - if (!_settings.BlockCreationLogicDelegate.has_value()) - { - _settings.BlockCreationLogicDelegate = std::function, std::shared_ptr, size_t)>( - [](auto device, auto collection, auto size) { - return new VulkanGraphicsMemoryBlockImpl< - IGraphicsMemoryRegionCollection::DefaultMetadata>( - std::dynamic_pointer_cast(device), - std::dynamic_pointer_cast(collection), size); - }); - } - } - - std::shared_ptr VulkanGraphicsMemoryAllocator::CreateBuffer( - GraphicsBufferKind bufferKind, - GraphicsResourceAccess cpuAccessKind, - GraphicsResourceAccess gpuAccessKind, - size_t size, - GraphicsMemoryRegionAllocationFlags allocationFlags) - { - VkDevice vulkanDevice = GetDevice()->GetVulkanDevice(); - - VkBufferCreateInfo bufferCreateInfo{}; - bufferCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; - bufferCreateInfo.size = size; - bufferCreateInfo.usage = Utilities::GetVulkanBufferUsageKind(bufferKind, gpuAccessKind); - - VkBuffer vulkanBuffer = VK_NULL_HANDLE; - - VkResult bufferCreationResult = vkCreateBuffer(vulkanDevice, &bufferCreateInfo, nullptr, &vulkanBuffer); - if (bufferCreationResult != VK_SUCCESS) - { - throw Exceptions::InitialisationFailureException("Failed to create requested VkBuffer instance.", - bufferCreationResult); - } - - VkMemoryRequirements memoryRequirements{}; - vkGetBufferMemoryRequirements(vulkanDevice, vulkanBuffer, &memoryRequirements); - - size_t index = GetBlockCollectionIndex(cpuAccessKind, memoryRequirements.memoryTypeBits); - std::shared_ptr blockCollection = - std::dynamic_pointer_cast(_blockCollections.getActual().at(index)); - - GraphicsMemoryRegion blockRegion = - blockCollection->Allocate(memoryRequirements.size, memoryRequirements.alignment, allocationFlags); - - return std::static_pointer_cast(std::make_shared>( - GetDevice(), bufferKind, std::move(blockRegion), cpuAccessKind, vulkanBuffer)); - } - - std::shared_ptr VulkanGraphicsMemoryAllocator::CreateTexture( - GraphicsTextureAddressMode addressMode, - GraphicsTextureKind textureKind, - GraphicsResourceAccess cpuAccessKind, - GraphicsResourceAccess gpuAccessKind, - uint32_t width, - uint32_t height, - uint32_t depth, - GraphicsMemoryRegionAllocationFlags allocationFlags, - TexelFormat texelFormat) - { - VkDevice vulkanDevice = GetDevice()->GetVulkanDevice(); - VkImageType imageType; - - switch (textureKind) - { - case GraphicsTextureKind::OneDimensional: - imageType = VK_IMAGE_TYPE_1D; - break; - case GraphicsTextureKind::TwoDimensional: - imageType = VK_IMAGE_TYPE_2D; - break; - case GraphicsTextureKind::ThreeDimensional: - imageType = VK_IMAGE_TYPE_3D; - break; - default: - case GraphicsTextureKind::Unknown: - throw Exceptions::NotSupportedException( - "The specified texture kind is not supported in the default Vulkan pipeline."); - } - - VkExtent3D extent{}; - extent.width = width; - extent.height = height; - extent.depth = depth; - - VkImageCreateInfo imageCreateInfo{}; - imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; - imageCreateInfo.imageType = imageType; - imageCreateInfo.format = Utilities::Map(texelFormat); - imageCreateInfo.extent = extent; - imageCreateInfo.mipLevels = 1; - imageCreateInfo.arrayLayers = 1; - imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT; - imageCreateInfo.usage = Utilities::GetVulkanImageUsageKind(textureKind, gpuAccessKind); - - VkImage vulkanImage = VK_NULL_HANDLE; - - VkResult createImageResult = vkCreateImage(vulkanDevice, &imageCreateInfo, nullptr, &vulkanImage); - if (createImageResult != VK_SUCCESS) - { - throw Exceptions::InitialisationFailureException("Failed to create VkImage with the specified parameters.", - createImageResult); - } - - VkMemoryRequirements memoryRequirements{}; - vkGetImageMemoryRequirements(vulkanDevice, vulkanImage, &memoryRequirements); - - size_t index = GetBlockCollectionIndex(cpuAccessKind, memoryRequirements.memoryTypeBits); - std::shared_ptr blockCollection = - std::dynamic_pointer_cast(_blockCollections.getActual().at(index)); - - GraphicsMemoryRegion blockRegion = - blockCollection->Allocate(memoryRequirements.size, memoryRequirements.alignment, allocationFlags); - - return std::static_pointer_cast(std::make_shared>( - GetDevice(), addressMode, textureKind, std::move(blockRegion), cpuAccessKind, width, height, - static_cast(depth), vulkanImage)); - } - - std::vector>::iterator VulkanGraphicsMemoryAllocator::begin() - { - return _blockCollections.getActual().begin(); - } - - std::vector>::iterator VulkanGraphicsMemoryAllocator::end() - { - return _blockCollections.getActual().end(); - } -} // namespace NovelRT::Graphics::Vulkan diff --git a/graphics/Vulkan/VulkanGraphicsMemoryBlock.cpp b/graphics/Vulkan/VulkanGraphicsMemoryBlock.cpp deleted file mode 100644 index 9a3327db2..000000000 --- a/graphics/Vulkan/VulkanGraphicsMemoryBlock.cpp +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#include - -namespace NovelRT::Graphics::Vulkan -{ - VkDeviceMemory VulkanGraphicsMemoryBlock::CreateVulkanDeviceMemory() - { - VkDeviceMemory vulkanDeviceMemory = VK_NULL_HANDLE; - - std::shared_ptr collection = GetCollection(); - VkDevice vulkanDevice = collection->GetAllocator()->GetDevice()->GetVulkanDevice(); - - VkMemoryAllocateInfo memoryAllocateInfo{}; - memoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; - memoryAllocateInfo.allocationSize = GetSize(); - memoryAllocateInfo.memoryTypeIndex = collection->GetVulkanMemoryTypeIndex(); - - VkResult result = vkAllocateMemory(vulkanDevice, &memoryAllocateInfo, nullptr, &vulkanDeviceMemory); - - if (result != VK_SUCCESS) - { - throw Exceptions::InitialisationFailureException("Failed to initialise VkDeviceMemory instance.", result); - } - - return vulkanDeviceMemory; - } - - void VulkanGraphicsMemoryBlock::DisposeVulkanDeviceMemory() noexcept - { - if (_vulkanDeviceMemory.isCreated()) - { - vkFreeMemory(GetCollection()->GetAllocator()->GetDevice()->GetVulkanDevice(), - _vulkanDeviceMemory.getActual(), nullptr); - } - } - - VulkanGraphicsDevice* VulkanGraphicsMemoryBlock::GetDeviceInternal() const noexcept - { - return dynamic_cast(GraphicsDeviceObject::GetDevice().get()); - } - - VulkanGraphicsMemoryBlock::VulkanGraphicsMemoryBlock( - const std::shared_ptr& device, - const std::shared_ptr& collection) - : GraphicsMemoryBlock(std::static_pointer_cast(device), - std::static_pointer_cast(collection)), - _vulkanDeviceMemory([&]() { return CreateVulkanDeviceMemory(); }) - { - } - - VulkanGraphicsMemoryBlock::~VulkanGraphicsMemoryBlock() - { - DisposeVulkanDeviceMemory(); - } -} // namespace NovelRT::Graphics::Vulkan diff --git a/graphics/Vulkan/VulkanGraphicsMemoryBlockCollection.cpp b/graphics/Vulkan/VulkanGraphicsMemoryBlockCollection.cpp deleted file mode 100644 index 7798fc1e5..000000000 --- a/graphics/Vulkan/VulkanGraphicsMemoryBlockCollection.cpp +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#include - -namespace NovelRT::Graphics::Vulkan -{ - VulkanGraphicsMemoryBlock* VulkanGraphicsMemoryBlockCollection::CreateBlock(size_t size) - { - const GraphicsMemoryAllocatorSettings& settings = GetAllocator()->GetSettings(); - - if (!settings.BlockCreationLogicDelegate.has_value()) - { - throw Exceptions::NotSupportedException( - "No memory block creation method has been specified for the default Vulkan render pipeline."); - } - - return reinterpret_cast(settings.BlockCreationLogicDelegate.value()( - GetDevice(), std::static_pointer_cast(shared_from_this()), size)); - } - - VulkanGraphicsMemoryBlockCollection::VulkanGraphicsMemoryBlockCollection( - std::shared_ptr device, - std::shared_ptr allocator, - uint32_t memoryTypeIndex) - : GraphicsMemoryBlockCollection(std::move(device), std::move(allocator)), - _vulkanMemoryTypeIndex(memoryTypeIndex) - { - } -} // namespace NovelRT::Graphics::Vulkan diff --git a/graphics/Vulkan/VulkanGraphicsPluginProvider.cpp b/graphics/Vulkan/VulkanGraphicsPluginProvider.cpp deleted file mode 100644 index 18765683b..000000000 --- a/graphics/Vulkan/VulkanGraphicsPluginProvider.cpp +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#include - -namespace NovelRT::Graphics::Vulkan -{ - VulkanGraphicsPluginProvider::VulkanGraphicsPluginProvider() noexcept - : _graphicsProvider([&]() { return CreateVulkanGraphicsProviderInternal(); }) - { - } - - std::shared_ptr VulkanGraphicsPluginProvider::CreateVulkanGraphicsProviderInternal() - { - return std::make_shared(); - } - - VulkanGraphicsProvider* VulkanGraphicsPluginProvider::GetGraphicsProviderInternal() - { - return _graphicsProvider.getActual().get(); - } - - std::shared_ptr VulkanGraphicsPluginProvider::CreateSurfaceContext( - std::shared_ptr surface) - { - return std::static_pointer_cast(CreateSurfaceContextVulkan(surface)); - } - - std::shared_ptr VulkanGraphicsPluginProvider::CreateSurfaceContextVulkan( - std::shared_ptr surface) - { - return std::make_shared(surface, GetGraphicsProvider()); - } - - std::shared_ptr VulkanGraphicsPluginProvider::GetDefaultSelectedGraphicsAdapterForContext( - std::shared_ptr context) - { - return std::static_pointer_cast(GetDefaultSelectedGraphicsAdapterForContextVulkan( - std::dynamic_pointer_cast(context))); - } - - std::shared_ptr VulkanGraphicsPluginProvider:: - GetDefaultSelectedGraphicsAdapterForContextVulkan(std::shared_ptr context) - { - return VulkanGraphicsAdapterSelector().GetDefaultRecommendedAdapterVulkan(GetGraphicsProvider(), context); - } -} diff --git a/graphics/Vulkan/VulkanGraphicsTexture.cpp b/graphics/Vulkan/VulkanGraphicsTexture.cpp deleted file mode 100644 index 1ae04bdf4..000000000 --- a/graphics/Vulkan/VulkanGraphicsTexture.cpp +++ /dev/null @@ -1,358 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#include - -namespace NovelRT::Graphics::Vulkan -{ - VulkanGraphicsTexture::VulkanGraphicsTexture(std::shared_ptr device, - GraphicsTextureAddressMode addressMode, - GraphicsTextureKind kind, - GraphicsMemoryRegion blockRegion, - GraphicsResourceAccess cpuAccess, - uint32_t width, - uint32_t height, - uint16_t depth, - VkImage vulkanImage) - : GraphicsTexture(std::move(device), - addressMode, - kind, - std::move(blockRegion), - cpuAccess, - width, - height, - depth), - _vulkanImage(vulkanImage), - _vulkanImageView([&]() { return CreateVulkanImageView(); }), - _vulkanSampler([&]() { return CreateVulkanSampler(); }) - { - VkResult result = vkBindImageMemory(GetAllocator()->GetDevice()->GetVulkanDevice(), vulkanImage, - GetBlock()->GetVulkanDeviceMemory(), GetBlockRegion().GetOffset()); - - if (result != VK_SUCCESS) - { - throw Exceptions::InitialisationFailureException("Failed to bind VkImage to VkImageMemory correctly.", - result); - } - } - - void* Vulkan::VulkanGraphicsTexture::MapUntyped() - { - std::shared_ptr device = GetAllocator()->GetDevice(); - - VkDevice vulkanDevice = device->GetVulkanDevice(); - VkDeviceMemory vulkanDeviceMemory = GetBlock()->GetVulkanDeviceMemory(); - - void* pDestination = nullptr; - VkResult mapMemoryResult = - vkMapMemory(vulkanDevice, vulkanDeviceMemory, GetOffset(), GetSize(), 0, &pDestination); - - if (mapMemoryResult != VK_SUCCESS) - { - throw std::runtime_error("Failed to map VkMemory to T*! Reason: " + std::to_string(mapMemoryResult)); - } - - return pDestination; - } - - void* VulkanGraphicsTexture::MapUntyped(size_t rangeOffset, size_t /*rangeLength*/) - { - std::shared_ptr device = GetAllocator()->GetDevice(); - - VkDevice vulkanDevice = device->GetVulkanDevice(); - VkDeviceMemory vulkanDeviceMemory = GetBlock()->GetVulkanDeviceMemory(); - - void* pDestination = nullptr; - - VkResult result = vkMapMemory(vulkanDevice, vulkanDeviceMemory, GetOffset(), GetSize(), 0, &pDestination); - - if (result != VK_SUCCESS) - { - throw std::runtime_error("Failed to map VkDeviceMemory! Reason: " + std::to_string(result)); - } - - return reinterpret_cast(pDestination) + rangeOffset; - } - - const void* VulkanGraphicsTexture::MapForReadUntyped() - { - std::shared_ptr device = GetAllocator()->GetDevice(); - - VkDevice vulkanDevice = device->GetVulkanDevice(); - VkDeviceMemory vulkanDeviceMemory = GetBlock()->GetVulkanDeviceMemory(); - - void* pDestination = nullptr; - VkResult mapMemoryResult = - vkMapMemory(vulkanDevice, vulkanDeviceMemory, GetOffset(), GetSize(), 0, &pDestination); - - if (mapMemoryResult != VK_SUCCESS) - { - // TODO: Add real exception. - throw std::runtime_error("Failed to map VkMemory to T*! Reason: " + std::to_string(mapMemoryResult)); - } - - size_t nonCoherentAtomSize = - device->GetAdapter()->GetVulkanPhysicalDeviceProperties().limits.nonCoherentAtomSize; - size_t offset = GetOffset(); - size_t size = (GetSize() + nonCoherentAtomSize - 1) & ~(nonCoherentAtomSize - 1); - - VkMappedMemoryRange mappedMemoryRange{}; - mappedMemoryRange.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; - mappedMemoryRange.memory = vulkanDeviceMemory; - mappedMemoryRange.offset = offset; - mappedMemoryRange.size = size; - - VkResult invalidateResult = vkInvalidateMappedMemoryRanges(vulkanDevice, 1, &mappedMemoryRange); - - if (invalidateResult != VK_SUCCESS) - { - // TODO: Add real exception. - throw std::runtime_error("Failed to invalidate memory ranges to prevent writing! Reason: " + - std::to_string(invalidateResult)); - } - - return pDestination; - } - - const void* VulkanGraphicsTexture::MapForReadUntyped(size_t readRangeOffset, size_t readRangeLength) - { - std::shared_ptr device = GetAllocator()->GetDevice(); - - VkDevice vulkanDevice = device->GetVulkanDevice(); - VkDeviceMemory vulkanDeviceMemory = GetBlock()->GetVulkanDeviceMemory(); - - void* pDestination = nullptr; - VkResult mapMemoryResult = - vkMapMemory(vulkanDevice, vulkanDeviceMemory, GetOffset(), GetSize(), 0, &pDestination); - - if (mapMemoryResult != VK_SUCCESS) - { - // TODO: Add real exception. - throw std::runtime_error("Failed to map VkMemory to T*! Reason: " + std::to_string(mapMemoryResult)); - } - - if (readRangeLength != 0) - { - size_t nonCoherentAtomSize = - device->GetAdapter()->GetVulkanPhysicalDeviceProperties().limits.nonCoherentAtomSize; - size_t offset = GetOffset() + readRangeOffset; - size_t size = (readRangeLength + nonCoherentAtomSize - 1) & ~(nonCoherentAtomSize - 1); - - VkMappedMemoryRange mappedMemoryRange{}; - mappedMemoryRange.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; - mappedMemoryRange.memory = vulkanDeviceMemory; - mappedMemoryRange.offset = offset; - mappedMemoryRange.size = size; - - VkResult invalidateResult = vkInvalidateMappedMemoryRanges(vulkanDevice, 1, &mappedMemoryRange); - - if (invalidateResult != VK_SUCCESS) - { - // TODO: Add real exception. - throw std::runtime_error("Failed to invalidate memory ranges to prevent writing! Reason: " + - std::to_string(invalidateResult)); - } - } - - return reinterpret_cast(pDestination) + readRangeOffset; - } - - void VulkanGraphicsTexture::Unmap() - { - std::shared_ptr device = GetAllocator()->GetDevice(); - - VkDevice vulkanDevice = device->GetVulkanDevice(); - VkDeviceMemory vulkanDeviceMemory = GetBlock()->GetVulkanDeviceMemory(); - - vkUnmapMemory(vulkanDevice, vulkanDeviceMemory); - } - - void VulkanGraphicsTexture::UnmapAndWrite() - { - std::shared_ptr device = GetAllocator()->GetDevice(); - - VkDevice vulkanDevice = device->GetVulkanDevice(); - VkDeviceMemory vulkanDeviceMemory = GetBlock()->GetVulkanDeviceMemory(); - - size_t nonCoherentAtomSize = - device->GetAdapter()->GetVulkanPhysicalDeviceProperties().limits.nonCoherentAtomSize; - size_t offset = GetOffset(); - size_t size = (GetSize() + nonCoherentAtomSize - 1) & ~(nonCoherentAtomSize - 1); - - VkMappedMemoryRange mappedMemoryRange{}; - mappedMemoryRange.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; - mappedMemoryRange.memory = vulkanDeviceMemory; - mappedMemoryRange.offset = offset; - mappedMemoryRange.size = size; - - VkResult flushResult = vkFlushMappedMemoryRanges(vulkanDevice, 1, &mappedMemoryRange); - - if (flushResult != VK_SUCCESS) - { - // TODO: Add real exception. - throw std::runtime_error("Failed to flush memory ranges after writing! Reason: " + - std::to_string(flushResult)); - } - - vkUnmapMemory(vulkanDevice, vulkanDeviceMemory); - } - - void VulkanGraphicsTexture::UnmapAndWrite(size_t writtenRangeOffset, size_t writtenRangeLength) - { - std::shared_ptr device = GetAllocator()->GetDevice(); - - VkDevice vulkanDevice = device->GetVulkanDevice(); - VkDeviceMemory vulkanDeviceMemory = GetBlock()->GetVulkanDeviceMemory(); - - if (writtenRangeLength != 0) - { - size_t nonCoherentAtomSize = - device->GetAdapter()->GetVulkanPhysicalDeviceProperties().limits.nonCoherentAtomSize; - size_t offset = GetOffset() + writtenRangeOffset; - size_t size = (writtenRangeLength + nonCoherentAtomSize - 1) & ~(nonCoherentAtomSize - 1); - - VkMappedMemoryRange mappedMemoryRange{}; - mappedMemoryRange.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; - mappedMemoryRange.memory = vulkanDeviceMemory; - mappedMemoryRange.offset = offset; - mappedMemoryRange.size = size; - - VkResult flushResult = vkFlushMappedMemoryRanges(vulkanDevice, 1, &mappedMemoryRange); - - if (flushResult != VK_SUCCESS) - { - // TODO: Add real exception. - throw std::runtime_error("Failed to flush memory ranges after writing! Reason: " + - std::to_string(flushResult)); - } - } - vkUnmapMemory(vulkanDevice, vulkanDeviceMemory); - } - - VulkanGraphicsTexture::~VulkanGraphicsTexture() - { - DisposeVulkanSampler(); - DisposeVulkanImage(); - DisposeVulkanImageView(); - GetBlockRegion().GetCollection()->Free(GetBlockRegion()); - } - - VulkanGraphicsDevice* VulkanGraphicsTexture::GetDeviceInternal() const noexcept - { - // TODO: This feels like it might be a perf issue later. - return dynamic_cast(GraphicsDeviceObject::GetDevice().get()); - } - - VkImageView VulkanGraphicsTexture::CreateVulkanImageView() - { - VkImageView vulkanImageView = VK_NULL_HANDLE; - - std::shared_ptr device = GetAllocator()->GetDevice(); - - VkDevice vulkanDevice = device->GetVulkanDevice(); - - VkImageViewType viewType; - switch (GetKind()) - { - case GraphicsTextureKind::OneDimensional: - viewType = VK_IMAGE_VIEW_TYPE_1D; - break; - case GraphicsTextureKind::TwoDimensional: - viewType = VK_IMAGE_VIEW_TYPE_2D; - break; - case GraphicsTextureKind::ThreeDimensional: - viewType = VK_IMAGE_VIEW_TYPE_3D; - break; - default: - case GraphicsTextureKind::Unknown: - throw Exceptions::InvalidOperationException("Invalid or unknown graphics texture kind type specified."); - break; - } - - VkComponentMapping components{}; - components.r = VK_COMPONENT_SWIZZLE_R; - components.g = VK_COMPONENT_SWIZZLE_G; - components.b = VK_COMPONENT_SWIZZLE_B; - components.a = VK_COMPONENT_SWIZZLE_A; - - VkImageSubresourceRange subresourceRange{}; - subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - subresourceRange.levelCount = 1; - subresourceRange.layerCount = 1; - - VkImageViewCreateInfo imageViewCreateInfo{}; - imageViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; - imageViewCreateInfo.image = GetVulkanImage(); - imageViewCreateInfo.viewType = viewType; - imageViewCreateInfo.format = VK_FORMAT_R8G8B8A8_UNORM; - imageViewCreateInfo.components = components; - imageViewCreateInfo.subresourceRange = subresourceRange; - - VkResult imageViewResult = vkCreateImageView(vulkanDevice, &imageViewCreateInfo, nullptr, &vulkanImageView); - - if (imageViewResult != VK_SUCCESS) - { - throw Exceptions::InitialisationFailureException("Failed to create VkImageView for texture!", - imageViewResult); - } - - return vulkanImageView; - } - - VkSampler VulkanGraphicsTexture::CreateVulkanSampler() - { - VkSampler vulkanSampler = VK_NULL_HANDLE; - - std::shared_ptr device = GetAllocator()->GetDevice(); - - VkDevice vulkanDevice = device->GetVulkanDevice(); - - VkSamplerAddressMode addressMode = Utilities::GetVulkanAddressMode(GetAddressMode()); - - VkSamplerCreateInfo samplerCreateInfo{}; - samplerCreateInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; - samplerCreateInfo.magFilter = VK_FILTER_LINEAR; - samplerCreateInfo.minFilter = VK_FILTER_LINEAR; - samplerCreateInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; - samplerCreateInfo.maxLod = 1.0f; - samplerCreateInfo.borderColor = VK_BORDER_COLOR_INT_OPAQUE_WHITE; - samplerCreateInfo.addressModeU = addressMode; - samplerCreateInfo.addressModeV = addressMode; - samplerCreateInfo.addressModeW = addressMode; - - VkResult result = vkCreateSampler(vulkanDevice, &samplerCreateInfo, nullptr, &vulkanSampler); - - if (result != VK_SUCCESS) - { - throw Exceptions::InitialisationFailureException("Failed to create VkSampler!", result); - } - - return vulkanSampler; - } - - void VulkanGraphicsTexture::DisposeVulkanImage() noexcept - { - if (_vulkanImage != VK_NULL_HANDLE) - { - vkDestroyImage(GetAllocator()->GetDevice()->GetVulkanDevice(), _vulkanImage, nullptr); - } - } - - void VulkanGraphicsTexture::DisposeVulkanImageView() noexcept - { - if (_vulkanImageView.isCreated()) - { - vkDestroyImageView(GetAllocator()->GetDevice()->GetVulkanDevice(), _vulkanImageView.getActual(), nullptr); - _vulkanImageView.reset(); - } - } - - void VulkanGraphicsTexture::DisposeVulkanSampler() noexcept - { - if (_vulkanSampler.isCreated()) - { - vkDestroySampler(GetAllocator()->GetDevice()->GetVulkanDevice(), _vulkanSampler.getActual(), nullptr); - _vulkanSampler.reset(); - } - } -} // namespace NovelRT::Graphics::Vulkan diff --git a/graphics/include/NovelRT/Graphics/D3D12/Graphics.D3D12.hpp b/graphics/include/NovelRT/Graphics/D3D12/Graphics.D3D12.hpp deleted file mode 100644 index 5aa33f7e4..000000000 --- a/graphics/include/NovelRT/Graphics/D3D12/Graphics.D3D12.hpp +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_GRAPHICS_D3D12_H -#define NOVELRT_GRAPHICS_D3D12_H - -// Graphics.D3D12 dependencies -#include -#include -#include -#include - -/** - * @brief The default D3D12 implementation for the Graphics plugin API. - */ -namespace NovelRT::Graphics::D3D12 -{ - -} - -// Graphics.D3D12 types - -// clang-format off - -#include - -// clang-format on - -#endif // NOVELRT_GRAPHICS_D3D12_H diff --git a/graphics/include/NovelRT/Graphics/D3D12/Utilities/Graphics.D3D12.Utilities.hpp b/graphics/include/NovelRT/Graphics/D3D12/Utilities/Graphics.D3D12.Utilities.hpp deleted file mode 100644 index 9ac8f725f..000000000 --- a/graphics/include/NovelRT/Graphics/D3D12/Utilities/Graphics.D3D12.Utilities.hpp +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_GRAPHICS_D3D12_UTILITIES_H -#define NOVELRT_GRAPHICS_D3D12_UTILITIES_H - -#ifndef NOVELRT_GRAPHICS_D3D12_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.D3D12.h instead for the Graphics::D3D12 namespace subset. -#endif - -#include - -#endif // !NOVELRT_GRAPHICS_D3D12_UTILITIES_H diff --git a/graphics/include/NovelRT/Graphics/Graphics.hpp b/graphics/include/NovelRT/Graphics/Graphics.hpp deleted file mode 100644 index 3d46f713a..000000000 --- a/graphics/include/NovelRT/Graphics/Graphics.hpp +++ /dev/null @@ -1,120 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_GRAPHICS_H -#define NOVELRT_GRAPHICS_H - -// Graphics dependencies -#include "NovelRT/EngineConfig.h" -#include "NovelRT/Maths/Maths.h" -#include "NovelRT/ResourceManagement/ResourceManagement.h" -#include "NovelRT/SceneGraph/SceneGraph.h" -#include "NovelRT/Threading/Threading.h" -#include "NovelRT/Utilities/Event.h" -#include "NovelRT/Utilities/Lazy.h" -#include "NovelRT/Utilities/Memory.h" -#include "NovelRT/Utilities/Misc.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/** - * @brief The experimental Graphics plugin API. Comes with built-in support for the ECS. - */ -namespace NovelRT::Graphics -{ - enum class ShaderProgramKind : uint32_t; - enum class GraphicsResourceAccess : uint32_t; - enum class GraphicsSurfaceKind : uint32_t; - enum class GraphicsTextureAddressMode : uint32_t; - enum class GraphicsPipelineBlendFactor : uint32_t; - enum class GraphicsPipelineInputElementKind : uint32_t; - enum class GraphicsPipelineResourceKind : uint32_t; - enum class ShaderProgramVisibility : uint32_t; - enum class GraphicsTextureKind : uint32_t; - enum class GraphicsMemoryRegionAllocationFlags : uint32_t; - enum class GraphicsMemoryRegionAllocationFlags : uint32_t; - enum class GraphicsBufferKind : uint32_t; - enum class TexelFormat : uint32_t; - struct GraphicsMemoryAllocatorSettings; - class GraphicsDeviceObject; - class IGraphicsSurface; - class GraphicsAdapter; - class GraphicsDevice; - class GraphicsResource; - class GraphicsBuffer; - class GraphicsTexture; - class ShaderProgram; - class GraphicsPipeline; - class GraphicsPipelineSignature; - class GraphicsPipelineInput; - class GraphicsPipelineResource; - class GraphicsPipelineInputElement; - class GraphicsContext; - class GraphicsFence; - class GraphicsPrimitive; - class GraphicsProvider; - class GraphicsMemoryAllocator; - class IGraphicsAdapterSelector; - class GraphicsMemoryBlockCollection; - class GraphicsMemoryBlock; - class GraphicsMemoryBudget; - class GraphicsSurfaceContext; - class GraphicsResourceManager; -} - -// Graphics types -// clang-format off - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// clang-format on - -#endif // !NOVELRT_GRAPHICS_H diff --git a/graphics/include/NovelRT/Graphics/GraphicsAdapter.hpp b/graphics/include/NovelRT/Graphics/GraphicsAdapter.hpp deleted file mode 100644 index f9a6c8e76..000000000 --- a/graphics/include/NovelRT/Graphics/GraphicsAdapter.hpp +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_GRAPHICS_GRAPHICSADAPTER_H -#define NOVELRT_GRAPHICS_GRAPHICSADAPTER_H - -#ifndef NOVELRT_GRAPHICS_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.h instead for the Graphics namespace subset. -#endif - -namespace NovelRT::Graphics -{ - class GraphicsAdapter : public std::enable_shared_from_this - { - private: - std::weak_ptr _provider; - - public: - explicit GraphicsAdapter(std::weak_ptr provider) : _provider(std::move(provider)) - { - if (_provider.expired()) - { - throw Exceptions::NullPointerException( - "The provided GraphicsProvider pointer is nullptr or an invalid pointer."); - } - } - - [[nodiscard]] virtual uint32_t GetDeviceId() = 0; - - [[nodiscard]] virtual const std::string& GetName() = 0; - - [[nodiscard]] inline std::shared_ptr GetProvider() const - { - if (_provider.expired()) - { - throw std::runtime_error("Provider has expired."); - } - - return _provider.lock(); - } - - [[nodiscard]] virtual uint32_t GetVendorId() = 0; - - [[nodiscard]] virtual std::shared_ptr CreateDevice( - std::shared_ptr surfaceContext, - int32_t contextCount) = 0; - - virtual ~GraphicsAdapter() = default; - }; -} - -#endif // !NOVELRT_GRAPHICS_GRAPHICSADAPTER_H diff --git a/graphics/include/NovelRT/Graphics/GraphicsBuffer.hpp b/graphics/include/NovelRT/Graphics/GraphicsBuffer.hpp deleted file mode 100644 index aaa89bb4f..000000000 --- a/graphics/include/NovelRT/Graphics/GraphicsBuffer.hpp +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_GRAPHICS_GRAPHICSBUFFER_H -#define NOVELRT_GRAPHICS_GRAPHICSBUFFER_H - -#ifndef NOVELRT_GRAPHICS_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.h instead for the Graphics namespace subset. -#endif - -namespace NovelRT::Graphics -{ - class GraphicsBuffer : public GraphicsResource - { - private: - GraphicsBufferKind _kind; - - public: - GraphicsBuffer(std::shared_ptr device, - GraphicsBufferKind kind, - GraphicsMemoryRegion blockRegion, - GraphicsResourceAccess cpuAccess) - : GraphicsResource(std::move(device), std::move(blockRegion), cpuAccess), _kind(kind) - { - } - - [[nodiscard]] inline GraphicsBufferKind GetKind() const noexcept - { - return _kind; - } - }; -} - -#endif // !NOVELRT_GRAPHICS_GRAPHICSBUFFER_H diff --git a/graphics/include/NovelRT/Graphics/GraphicsContext.hpp b/graphics/include/NovelRT/Graphics/GraphicsContext.hpp deleted file mode 100644 index 72dd4a3c7..000000000 --- a/graphics/include/NovelRT/Graphics/GraphicsContext.hpp +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_GRAPHICS_GRAPHICSCONTEXT_H -#define NOVELRT_GRAPHICS_GRAPHICSCONTEXT_H - -#ifndef NOVELRT_GRAPHICS_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.h instead for the Graphics namespace subset. -#endif - -namespace NovelRT::Graphics -{ - class GraphicsContext : public GraphicsDeviceObject - { - private: - size_t _index; - - public: - GraphicsContext(const std::shared_ptr& device, size_t index) noexcept - : GraphicsDeviceObject(std::weak_ptr(device)), _index(index) - { - } - - [[nodiscard]] virtual std::shared_ptr GetFence() const noexcept = 0; - - [[nodiscard]] inline size_t GetIndex() const noexcept - { - return _index; - } - - virtual void BeginDrawing(NovelRT::Graphics::RGBAColour backgroundColour) = 0; - virtual void BeginFrame() = 0; - virtual void Copy(std::shared_ptr destination, std::shared_ptr source) = 0; - virtual void Copy(std::shared_ptr destination, std::shared_ptr source) = 0; - - inline void Draw(std::shared_ptr primitive) - { - Draw(std::move(primitive), 1); - } - - virtual void Draw(std::shared_ptr primitive, uint32_t instanceCount) = 0; - virtual void EndDrawing() = 0; - virtual void EndFrame() = 0; - }; -} - -#endif // !NOVELRT_GRAPHICS_GRAPHICSCONTEXT_H diff --git a/graphics/include/NovelRT/Graphics/GraphicsDevice.hpp b/graphics/include/NovelRT/Graphics/GraphicsDevice.hpp deleted file mode 100644 index 6f5057560..000000000 --- a/graphics/include/NovelRT/Graphics/GraphicsDevice.hpp +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_GRAPHICS_GRAPHICSDEVICE_H -#define NOVELRT_GRAPHICS_GRAPHICSDEVICE_H - -#ifndef NOVELRT_GRAPHICS_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.h instead for the Graphics namespace subset. -#endif - -namespace NovelRT::Graphics -{ - class GraphicsDevice : public std::enable_shared_from_this - { - private: - std::weak_ptr _adapter; - std::shared_ptr _surfaceContext; - - protected: - [[nodiscard]] virtual GraphicsMemoryAllocator* GetMemoryAllocatorInternal() = 0; - - public: - GraphicsDevice(std::weak_ptr adapter, std::shared_ptr surfaceContext) - : _adapter(std::move(adapter)), _surfaceContext(std::move(surfaceContext)) - { - if (_adapter.expired()) - { - throw Exceptions::NullPointerException("The supplied GraphicsAdapter is nullptr."); - } - - if (_surfaceContext == nullptr) - { - throw Exceptions::NullPointerException("The supplied GraphicsSurfaceContext is nullptr."); - } - } - - virtual void TearDown() = 0; - - [[nodiscard]] inline std::shared_ptr GetAdapter() const - { - if (_adapter.expired()) - { - throw std::runtime_error("Adapter has expired!"); - } - - return _adapter.lock(); - } - - [[nodiscard]] virtual size_t GetContextIndex() const noexcept = 0; - - [[nodiscard]] virtual NovelRT::Utilities::Misc::Span> GetContexts() = 0; - - [[nodiscard]] inline std::shared_ptr GetCurrentContext() - { - return GetContexts()[GetContextIndex()]; - } - - [[nodiscard]] inline std::shared_ptr GetMemoryAllocator() - { - return std::dynamic_pointer_cast(GetMemoryAllocatorInternal()->shared_from_this()); - } - - [[nodiscard]] inline std::shared_ptr GetSurface() const noexcept - { - return _surfaceContext->GetSurface(); - } - - [[nodiscard]] inline std::shared_ptr GetSurfaceContext() const noexcept - { - return _surfaceContext; - } - - [[nodiscard]] virtual std::shared_ptr CreatePipeline( - std::shared_ptr signature, - std::shared_ptr vertexShader, - std::shared_ptr pixelShader) = 0; - - [[nodiscard]] virtual std::shared_ptr CreatePipelineSignature( - GraphicsPipelineBlendFactor srcBlendFactor, - GraphicsPipelineBlendFactor dstBlendFactor, - NovelRT::Utilities::Misc::Span inputs, - NovelRT::Utilities::Misc::Span resources) = 0; - - [[nodiscard]] virtual std::shared_ptr CreatePrimitive( - std::shared_ptr pipeline, - GraphicsMemoryRegion& vertexBufferRegion, - uint32_t vertexBufferStride, - GraphicsMemoryRegion& indexBufferRegion, - uint32_t indexBufferStride, - NovelRT::Utilities::Misc::Span> inputResourceRegions) = 0; - - [[nodiscard]] virtual std::shared_ptr CreateShaderProgram( - std::string entryPointName, - ShaderProgramKind kind, - NovelRT::Utilities::Misc::Span byteData) = 0; - - virtual void PresentFrame() = 0; - virtual void Signal(std::shared_ptr fence) = 0; - virtual void WaitForIdle() = 0; - - virtual ~GraphicsDevice() = default; - }; -} - -#endif // !NOVELRT_GRAPHICS_GRAPHICSDEVICE_H diff --git a/graphics/include/NovelRT/Graphics/GraphicsDeviceObject.hpp b/graphics/include/NovelRT/Graphics/GraphicsDeviceObject.hpp deleted file mode 100644 index 6410adf0d..000000000 --- a/graphics/include/NovelRT/Graphics/GraphicsDeviceObject.hpp +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_GRAPHICS_GRAPHICSDEVICEOBJECT_H -#define NOVELRT_GRAPHICS_GRAPHICSDEVICEOBJECT_H - -#ifndef NOVELRT_GRAPHICS_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.h instead for the Graphics namespace subset. -#endif - -namespace NovelRT::Graphics -{ - class GraphicsDeviceObject : public std::enable_shared_from_this - { - private: - std::weak_ptr _graphicsDevice; - - public: - explicit GraphicsDeviceObject(std::weak_ptr graphicsDevice) noexcept - : _graphicsDevice(std::move(graphicsDevice)) - { - } - - [[nodiscard]] inline std::shared_ptr GetDevice() const - { - if (_graphicsDevice.expired()) - { - throw std::runtime_error("The graphics device has expired!"); - } - - return _graphicsDevice.lock(); - } - - virtual ~GraphicsDeviceObject() = default; - }; -} - -#endif // !NOVELRT_GRAPHICS_GRAPHICSDEVICEOBJECT_H diff --git a/graphics/include/NovelRT/Graphics/GraphicsFence.hpp b/graphics/include/NovelRT/Graphics/GraphicsFence.hpp deleted file mode 100644 index 06673ad8d..000000000 --- a/graphics/include/NovelRT/Graphics/GraphicsFence.hpp +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_GRAPHICS_GRAPHICSFENCE_H -#define NOVELRT_GRAPHICS_GRAPHICSFENCE_H - -#ifndef NOVELRT_GRAPHICS_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.h instead for the Graphics namespace subset. -#endif - -namespace NovelRT::Graphics -{ - class GraphicsFence : public GraphicsDeviceObject - { - public: - explicit GraphicsFence(std::weak_ptr device) noexcept : GraphicsDeviceObject(std::move(device)) - { - } - - [[nodiscard]] virtual bool GetIsSignalled() = 0; - virtual void Reset() = 0; - - [[nodiscard]] inline bool TryWait() - { - return TryWait(std::numeric_limits::max()); - } - - [[nodiscard]] virtual bool TryWait(uint64_t millisecondsTimeout) = 0; - [[nodiscard]] virtual bool TryWait(std::chrono::duration timeout) = 0; - - inline void Wait() - { - Wait(std::numeric_limits::max()); - } - - inline void Wait(uint64_t millisecondsTimeout) - { - if (!TryWait(millisecondsTimeout)) - { - throw Exceptions::TimeoutException(millisecondsTimeout); - } - } - - inline void Wait(std::chrono::duration timeout) - { - if (!TryWait(timeout)) - { - throw Exceptions::TimeoutException(timeout.count()); - } - } - }; -} - -#endif // !NOVELRT_GRAPHICS_GRAPHICSFENCE_H diff --git a/graphics/include/NovelRT/Graphics/GraphicsMemoryAllocator.hpp b/graphics/include/NovelRT/Graphics/GraphicsMemoryAllocator.hpp deleted file mode 100644 index d8b7a7d35..000000000 --- a/graphics/include/NovelRT/Graphics/GraphicsMemoryAllocator.hpp +++ /dev/null @@ -1,134 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_GRAPHICS_GRAPHICSMEMORYALLOCATOR_H -#define NOVELRT_GRAPHICS_GRAPHICSMEMORYALLOCATOR_H - -#ifndef NOVELRT_GRAPHICS_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.h instead for the Graphics namespace subset. -#endif - -namespace NovelRT::Graphics -{ - class GraphicsMemoryAllocator : public GraphicsDeviceObject - { - protected: - GraphicsMemoryAllocatorSettings _settings; - - public: - GraphicsMemoryAllocator(std::shared_ptr device, - GraphicsMemoryAllocatorSettings settings) noexcept - : GraphicsDeviceObject(std::move(device)), _settings(settings) - { - bool isExternallySynchronised = - _settings.IsExternallySynchronised.has_value() && _settings.IsExternallySynchronised.value(); - - int32_t maximumBlockCountPerCollection = _settings.MaximumBlockCountPerCollection > 0 - ? _settings.MaximumBlockCountPerCollection - : std::numeric_limits::max(); - - size_t maximumSharedBlockSize = _settings.MaximumSharedBlockSize.value_or(256 * 1024 * 1024); - - int32_t minimumBlockCountPerCollection = - _settings.MinimumBlockCountPerCollection >= 0 ? _settings.MinimumBlockCountPerCollection : 0; - - size_t minimumBlockSize = _settings.MinimumBlockSize != 0 - ? _settings.MinimumBlockSize - : std::max(static_cast(4096), maximumSharedBlockSize / 8); - - size_t minimumAllocatedRegionMarginSize = _settings.MinimumAllocatedRegionMarginSize.value_or(0); - - size_t minimumFreeRegionSizeToRegister = - _settings.MinimumFreeRegionSizeToRegister != 0 ? _settings.MinimumFreeRegionSizeToRegister : 4096; - - _settings = GraphicsMemoryAllocatorSettings(); - _settings.IsExternallySynchronised = isExternallySynchronised; - _settings.MaximumBlockCountPerCollection = maximumBlockCountPerCollection; - _settings.MaximumSharedBlockSize = maximumSharedBlockSize; - _settings.MinimumBlockCountPerCollection = minimumBlockCountPerCollection; - _settings.MinimumBlockSize = minimumBlockSize; - _settings.MinimumAllocatedRegionMarginSize = minimumAllocatedRegionMarginSize; - _settings.MinimumFreeRegionSizeToRegister = minimumFreeRegionSizeToRegister; - } - - [[nodiscard]] inline virtual size_t GetCount() = 0; - - [[nodiscard]] inline const GraphicsMemoryAllocatorSettings& GetSettings() const noexcept - { - return _settings; - } - - [[nodiscard]] virtual std::shared_ptr CreateBuffer( - GraphicsBufferKind bufferKind, - GraphicsResourceAccess cpuAccessKind, - GraphicsResourceAccess gpuAccessKind, - size_t size, - GraphicsMemoryRegionAllocationFlags allocationFlags) = 0; - - [[nodiscard]] std::shared_ptr CreateBufferWithDefaultArguments( - GraphicsBufferKind bufferKind, - GraphicsResourceAccess cpuAccessKind, - GraphicsResourceAccess gpuAccessKind, - size_t size) - { - return CreateBuffer(bufferKind, cpuAccessKind, gpuAccessKind, size, - GraphicsMemoryRegionAllocationFlags::None); - } - - [[nodiscard]] virtual std::shared_ptr CreateTexture( - GraphicsTextureAddressMode addressMode, - GraphicsTextureKind textureKind, - GraphicsResourceAccess cpuAccessKind, - GraphicsResourceAccess gpuAccessKind, - uint32_t width, - uint32_t height, - uint32_t depth, - GraphicsMemoryRegionAllocationFlags allocationFlags, - TexelFormat texelFormat) = 0; - - [[nodiscard]] std::shared_ptr CreateTextureWithDefaultArguments( - GraphicsTextureAddressMode addressMode, - GraphicsTextureKind textureKind, - GraphicsResourceAccess cpuAccessKind, - GraphicsResourceAccess gpuAccessKind, - uint32_t width) - { - return CreateTextureWithDefaultArguments(addressMode, textureKind, cpuAccessKind, gpuAccessKind, width, 1); - } - - [[nodiscard]] std::shared_ptr CreateTextureWithDefaultArguments( - GraphicsTextureAddressMode addressMode, - GraphicsTextureKind textureKind, - GraphicsResourceAccess cpuAccessKind, - GraphicsResourceAccess gpuAccessKind, - uint32_t width, - uint32_t height) - { - return CreateTexture(addressMode, textureKind, cpuAccessKind, gpuAccessKind, width, height, 1, - GraphicsMemoryRegionAllocationFlags::None, TexelFormat::R8G8B8A8_UNORM); - } - - [[nodiscard]] virtual GraphicsMemoryBudget GetBudget( - std::shared_ptr blockCollection) = 0; - - // TODO: maybe this should be std::list instead? - [[nodiscard]] virtual std::vector>::iterator begin() = 0; - [[nodiscard]] virtual std::vector>::iterator end() = 0; - }; - - template class GraphicsMemoryAllocatorImpl : public GraphicsMemoryAllocator - { - public: - using Metadata = TMetadata; - - GraphicsMemoryAllocatorImpl(std::shared_ptr device, - GraphicsMemoryAllocatorSettings settings) noexcept - : GraphicsMemoryAllocator(std::move(device), std::move(settings)) - { - static_assert(std::is_base_of_v::IMetadata, TMetadata>); - } - }; - -} - -#endif // !NOVELRT_GRAPHICS_GRAPHICSMEMORYALLOCATOR_H diff --git a/graphics/include/NovelRT/Graphics/GraphicsMemoryAllocatorSettings.hpp b/graphics/include/NovelRT/Graphics/GraphicsMemoryAllocatorSettings.hpp deleted file mode 100644 index 8cd5ac5ab..000000000 --- a/graphics/include/NovelRT/Graphics/GraphicsMemoryAllocatorSettings.hpp +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_GRAPHICS_GRAPHICSMEMORYALLOCATORSETTINGS_H -#define NOVELRT_GRAPHICS_GRAPHICSMEMORYALLOCATORSETTINGS_H - -#ifndef NOVELRT_GRAPHICS_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.h instead for the Graphics namespace subset. -#endif - -namespace NovelRT::Graphics -{ - struct GraphicsMemoryAllocatorSettings - { - int32_t MaximumBlockCountPerCollection = 0; - int32_t MinimumBlockCountPerCollection = 0; - size_t MinimumBlockSize = 0; - size_t MinimumFreeRegionSizeToRegister = 0; - std::optional, - std::shared_ptr, - size_t)>> - BlockCreationLogicDelegate; - std::optional IsExternallySynchronised; - std::optional MaximumSharedBlockSize; - std::optional MinimumAllocatedRegionMarginSize; - }; -} - -#endif // !NOVELRT_GRAPHICS_GRAPHICSMEMORYALLOCATORSETTINGS_H diff --git a/graphics/include/NovelRT/Graphics/GraphicsMemoryBlock.hpp b/graphics/include/NovelRT/Graphics/GraphicsMemoryBlock.hpp deleted file mode 100644 index c5c803f9c..000000000 --- a/graphics/include/NovelRT/Graphics/GraphicsMemoryBlock.hpp +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_GRAPHICS_GRAPHICSMEMORYBLOCK_H -#define NOVELRT_GRAPHICS_GRAPHICSMEMORYBLOCK_H - -#ifndef NOVELRT_GRAPHICS_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.h instead for the Graphics namespace subset. -#endif - -namespace NovelRT::Graphics -{ - class GraphicsMemoryBlock : public GraphicsDeviceObject, public IGraphicsMemoryRegionCollection - { - private: - std::shared_ptr _collection; - - public: - GraphicsMemoryBlock(std::shared_ptr device, - std::shared_ptr collection); - - [[nodiscard]] inline std::shared_ptr GetCollection() const noexcept - { - return _collection; - } - - ~GraphicsMemoryBlock() override = default; - }; -} - -#endif // !NOVELRT_GRAPHICS_GRAPHICSMEMORYBLOCK_H diff --git a/graphics/include/NovelRT/Graphics/GraphicsMemoryBlockCollection.hpp b/graphics/include/NovelRT/Graphics/GraphicsMemoryBlockCollection.hpp deleted file mode 100644 index 82ae9b73b..000000000 --- a/graphics/include/NovelRT/Graphics/GraphicsMemoryBlockCollection.hpp +++ /dev/null @@ -1,137 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_GRAPHICS_GRAPHICSMEMORYBLOCKCOLLECTION_H -#define NOVELRT_GRAPHICS_GRAPHICSMEMORYBLOCKCOLLECTION_H - -#ifndef NOVELRT_GRAPHICS_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.h instead for the Graphics namespace subset. -#endif - -namespace NovelRT::Graphics -{ - class GraphicsMemoryBlockCollection : public GraphicsDeviceObject - { - private: - std::shared_ptr _allocator; - std::vector> _blocks; - std::mutex _mutex; - std::shared_ptr _emptyBlock; - size_t _minimumSize; - size_t _size; - Threading::VolatileState _state; - - [[nodiscard]] std::shared_ptr AddBlock(size_t size); - [[nodiscard]] size_t GetAdjustedBlockSize(size_t size) const noexcept; - [[nodiscard]] size_t GetLargestSharedBlockSize() const noexcept; - void IncrementallySortBlocks() noexcept; - void RemoveBlock(const std::shared_ptr& block); - void RemoveBlockAt(std::vector>::iterator iterator); - void RemoveBlockAt(size_t index); - - bool TryAllocateRegion(size_t size, - size_t alignment, - GraphicsMemoryRegionAllocationFlags flags, - GraphicsMemoryRegion& region); - - protected: - [[nodiscard]] virtual GraphicsMemoryBlock* CreateBlock(size_t size) = 0; - - public: - GraphicsMemoryBlockCollection(std::shared_ptr device, - std::shared_ptr allocator); - - [[nodiscard]] inline std::shared_ptr GetAllocator() const noexcept - { - return _allocator; - } - - [[nodiscard]] inline int32_t GetMaximumBlockCount() const noexcept - { - return _allocator->GetSettings().MaximumBlockCountPerCollection; - } - - [[nodiscard]] inline size_t GetMaximumSharedBlockSize() const noexcept - { - return _allocator->GetSettings().MaximumSharedBlockSize.value_or(256 * 1024 * 1024); - } - - [[nodiscard]] inline int32_t GetMinimumBlockCount() const noexcept - { - return _allocator->GetSettings().MinimumBlockCountPerCollection; - } - - [[nodiscard]] inline size_t GetMinimumBlockSize() const noexcept - { - return _allocator->GetSettings().MinimumBlockSize; - } - - [[nodiscard]] inline size_t GetMinimumSize() const noexcept - { - return _minimumSize; - } - - [[nodiscard]] inline size_t GetSize() const noexcept - { - return _size; - } - - [[nodiscard]] GraphicsMemoryRegion Allocate( - size_t size, - size_t alignment = 1, - GraphicsMemoryRegionAllocationFlags flags = GraphicsMemoryRegionAllocationFlags::None); - - [[nodiscard]] bool TryAllocate(size_t size, - size_t alignment, - GraphicsMemoryRegionAllocationFlags flags, - GraphicsMemoryRegion& outRegion); - - [[nodiscard]] bool TryAllocate(size_t size, GraphicsMemoryRegion& outRegion); - - [[nodiscard]] bool TryAllocate( - size_t size, - size_t alignment, - GraphicsMemoryRegionAllocationFlags flags, - NovelRT::Utilities::Misc::Span> regions); - - [[nodiscard]] bool TryAllocate( - size_t size, - NovelRT::Utilities::Misc::Span> regions); - - void Free(const GraphicsMemoryRegion& region); - - [[nodiscard]] inline std::vector>::iterator begin() noexcept - { - return _blocks.begin(); - } - - [[nodiscard]] inline std::vector>::iterator end() noexcept - { - return _blocks.end(); - } - - [[nodiscard]] inline std::vector>::const_iterator begin() const noexcept - { - return _blocks.begin(); - } - - [[nodiscard]] inline std::vector>::const_iterator end() const noexcept - { - return _blocks.end(); - } - - [[nodiscard]] inline std::vector>::const_iterator cbegin() const noexcept - { - return _blocks.cbegin(); - } - - [[nodiscard]] inline std::vector>::const_iterator cend() const noexcept - { - return _blocks.cend(); - } - - [[nodiscard]] bool TrySetMinimumSize(size_t minimumSize); - }; -} - -#endif // !NOVELRT_GRAPHICS_GRAPHICSMEMORYBLOCKCOLLECTION_H diff --git a/graphics/include/NovelRT/Graphics/GraphicsMemoryBudget.hpp b/graphics/include/NovelRT/Graphics/GraphicsMemoryBudget.hpp deleted file mode 100644 index 401f5a311..000000000 --- a/graphics/include/NovelRT/Graphics/GraphicsMemoryBudget.hpp +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_GRAPHICS_GRAPHICSMEMORYBUDGET_H -#define NOVELRT_GRAPHICS_GRAPHICSMEMORYBUDGET_H - -#ifndef NOVELRT_GRAPHICS_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.h instead for the Graphics namespace subset. -#endif - -namespace NovelRT::Graphics -{ - class GraphicsMemoryBudget - { - private: - size_t _estimatedBudget; - size_t _estimatedUsage; - size_t _totalAllocatedRegionSize; - size_t _totalBlocksSize; - - public: - GraphicsMemoryBudget(size_t estimatedBudget, - size_t estimatedUsage, - size_t totalAllocatedRegionSize, - size_t totalBlocksSize) noexcept - : _estimatedBudget(estimatedBudget), - _estimatedUsage(estimatedUsage), - _totalAllocatedRegionSize(totalAllocatedRegionSize), - _totalBlocksSize(totalBlocksSize) - { - } - - [[nodiscard]] inline size_t GetEstimatedBudget() const noexcept - { - return _estimatedBudget; - } - - [[nodiscard]] inline size_t GetEstimatedUsage() const noexcept - { - return _estimatedUsage; - } - - [[nodiscard]] inline size_t GetTotalAllocatedRegionSize() const noexcept - { - return _totalAllocatedRegionSize; - } - - [[nodiscard]] inline size_t GetTotalBlocksSize() const noexcept - { - return _totalBlocksSize; - } - }; -} - -#endif // !NOVELRT_GRAPHICS_GRAPHICSMEMORYBUDGET_H diff --git a/graphics/include/NovelRT/Graphics/GraphicsMemoryRegion.hpp b/graphics/include/NovelRT/Graphics/GraphicsMemoryRegion.hpp deleted file mode 100644 index f00c17c50..000000000 --- a/graphics/include/NovelRT/Graphics/GraphicsMemoryRegion.hpp +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_GRAPHICS_GRAPHICSMEMORYREGION_H -#define NOVELRT_GRAPHICS_GRAPHICSMEMORYREGION_H - -#ifndef NOVELRT_GRAPHICS_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.h instead for the Graphics namespace subset. -#endif - -namespace NovelRT::Graphics -{ - template class GraphicsMemoryRegion - { - private: - size_t _alignment; - std::shared_ptr _collection; - std::shared_ptr _device; - bool _isAllocated; - size_t _offset; - size_t _size; - - public: - GraphicsMemoryRegion(size_t alignment, - std::shared_ptr collection, - std::shared_ptr device, - bool isAllocated, - size_t offset, - size_t size) noexcept - : _alignment(alignment), - _collection(std::move(collection)), - _device(std::move(device)), - _isAllocated(isAllocated), - _offset(offset), - _size(size) - { - } - - GraphicsMemoryRegion() noexcept - : _alignment(0), _collection(nullptr), _device(nullptr), _isAllocated(false), _offset(0), _size(0) - { - } - - [[nodiscard]] size_t GetAlignment() const noexcept - { - return _alignment; - } - - [[nodiscard]] std::shared_ptr GetCollection() const noexcept - { - return _collection; - } - - [[nodiscard]] std::shared_ptr GetDevice() const noexcept - { - return _device; - } - - [[nodiscard]] bool GetIsAllocated() const noexcept - { - return _isAllocated; - } - - [[nodiscard]] size_t GetOffset() const noexcept - { - return _offset; - } - - [[nodiscard]] size_t GetSize() const noexcept - { - return _size; - } - - [[nodiscard]] bool operator==(const GraphicsMemoryRegion& rhs) const noexcept - { - return (GetCollection() == rhs.GetCollection()) && (GetIsAllocated() == rhs.GetIsAllocated()) && - (GetOffset() == rhs.GetOffset()) && (GetSize() == rhs.GetSize()) && - (GetAlignment() == rhs.GetAlignment()); - } - - [[nodiscard]] bool operator!=(const GraphicsMemoryRegion& rhs) const noexcept - { - return !(*this == rhs); - } - }; -} - -#endif // !NOVELRT_GRAPHICS_GRAPHICSMEMORYREGION_H diff --git a/graphics/include/NovelRT/Graphics/GraphicsPipeline.hpp b/graphics/include/NovelRT/Graphics/GraphicsPipeline.hpp deleted file mode 100644 index 930355aa4..000000000 --- a/graphics/include/NovelRT/Graphics/GraphicsPipeline.hpp +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_GRAPHICS_GRAPHICSPIPELINE_H -#define NOVELRT_GRAPHICS_GRAPHICSPIPELINE_H - -#ifndef NOVELRT_GRAPHICS_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.h instead for the Graphics namespace subset. -#endif - -namespace NovelRT::Graphics -{ - class GraphicsPipeline : public GraphicsDeviceObject - { - private: - std::shared_ptr _signature; - std::shared_ptr _vertexShader; - std::shared_ptr _pixelShader; - - public: - GraphicsPipeline(const std::shared_ptr& device, - std::shared_ptr signature, - std::shared_ptr vertexShader, - std::shared_ptr pixelShader) noexcept; - - [[nodiscard]] bool HasVertexShader() const noexcept; - [[nodiscard]] bool HasPixelShader() const noexcept; - [[nodiscard]] std::shared_ptr GetVertexShader() const noexcept; - [[nodiscard]] std::shared_ptr GetPixelShader() const noexcept; - [[nodiscard]] std::shared_ptr GetSignature() const noexcept; - }; -} - -#endif // !NOVELRT_GRAPHICS_GRAPHICSPIPELINE_H diff --git a/graphics/include/NovelRT/Graphics/GraphicsPipelineResourceKind.hpp b/graphics/include/NovelRT/Graphics/GraphicsPipelineResourceKind.hpp deleted file mode 100644 index 52938bece..000000000 --- a/graphics/include/NovelRT/Graphics/GraphicsPipelineResourceKind.hpp +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_GRAPHICS_GRAPHICSPIPELINERESOURCEKIND_H -#define NOVELRT_GRAPHICS_GRAPHICSPIPELINERESOURCEKIND_H - -#ifndef NOVELRT_GRAPHICS_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.h instead for the Graphics namespace subset. -#endif - -namespace NovelRT::Graphics -{ - enum class GraphicsPipelineResourceKind : uint32_t - { - Unknown = 0, - ConstantBuffer = 1, - Texture = 2 - }; -} - -#endif // !NOVELRT_GRAPHICS_GRAPHICSPIPELINERESOURCEKIND_H diff --git a/graphics/include/NovelRT/Graphics/GraphicsPipelineSignature.hpp b/graphics/include/NovelRT/Graphics/GraphicsPipelineSignature.hpp deleted file mode 100644 index db8faee26..000000000 --- a/graphics/include/NovelRT/Graphics/GraphicsPipelineSignature.hpp +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_GRAPHICS_GRAPHICSPIPELINESIGNATURE_H -#define NOVELRT_GRAPHICS_GRAPHICSPIPELINESIGNATURE_H - -#ifndef NOVELRT_GRAPHICS_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.h instead for the Graphics namespace subset. -#endif - -namespace NovelRT::Graphics -{ - class GraphicsPipelineSignature : public GraphicsDeviceObject - { - private: - GraphicsPipelineBlendFactor _srcBlendFactor; - GraphicsPipelineBlendFactor _dstBlendFactor; - std::vector _inputs; - std::vector _resources; - - public: - GraphicsPipelineSignature(std::shared_ptr device, - GraphicsPipelineBlendFactor srcBlendFactor, - GraphicsPipelineBlendFactor dstBlendFactor, - NovelRT::Utilities::Misc::Span inputs, - NovelRT::Utilities::Misc::Span resources) noexcept; - - [[nodiscard]] NovelRT::Utilities::Misc::Span GetInputs() const noexcept; - [[nodiscard]] NovelRT::Utilities::Misc::Span GetResources() const noexcept; - - [[nodiscard]] inline GraphicsPipelineBlendFactor GetSrcBlendFactor() const noexcept - { - return _srcBlendFactor; - } - - [[nodiscard]] inline GraphicsPipelineBlendFactor GetDstBlendFactor() const noexcept - { - return _dstBlendFactor; - } - }; -} - -#endif // !NOVELRT_GRAPHICS_GRAPHICSPIPELINESIGNATURE_H diff --git a/graphics/include/NovelRT/Graphics/GraphicsPrimitive.hpp b/graphics/include/NovelRT/Graphics/GraphicsPrimitive.hpp deleted file mode 100644 index cfa7756c1..000000000 --- a/graphics/include/NovelRT/Graphics/GraphicsPrimitive.hpp +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_GRAPHICS_GRAPHICSPRIMITIVE_H -#define NOVELRT_GRAPHICS_GRAPHICSPRIMITIVE_H - -#ifndef NOVELRT_GRAPHICS_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.h instead for the Graphics namespace subset. -#endif - -namespace NovelRT::Graphics -{ - class GraphicsPrimitive : public GraphicsDeviceObject - { - private: - std::shared_ptr _pipeline; - GraphicsMemoryRegion _vertexBufferRegion; - GraphicsMemoryRegion _indexBufferRegion; - std::vector> _inputResourceRegions; - uint32_t _vertexBufferStride; - uint32_t _indexBufferStride; - - public: - GraphicsPrimitive( - const std::shared_ptr& device, - std::shared_ptr pipeline, - GraphicsMemoryRegion vertexBufferRegion, - uint32_t vertexBufferStride, - GraphicsMemoryRegion indexBufferRegion, - uint32_t indexBufferStride, - NovelRT::Utilities::Misc::Span> inputResourceRegions) - : GraphicsDeviceObject(std::weak_ptr(device)), - _pipeline(std::move(pipeline)), - _vertexBufferRegion(std::move(vertexBufferRegion)), - _indexBufferRegion(std::move(indexBufferRegion)), - _inputResourceRegions(), - _vertexBufferStride(vertexBufferStride), - _indexBufferStride(indexBufferStride) - { - if (_pipeline == nullptr) - { - throw Exceptions::NullPointerException("Parameter name: pipeline."); - } - - if (GetVertexBufferRegion().GetCollection() == nullptr) - { - throw Exceptions::NullPointerException( - "The vertex buffer region's memory resource collection is nullptr."); - } - - if (GetPipeline()->GetDevice() != GetDevice()) - { - throw Exceptions::InvalidOperationException( - "The supplied graphics devices for the primitive and the pipeline do not match."); - } - - if (GetVertexBufferRegion().GetDevice() != GetDevice()) - { - throw Exceptions::InvalidOperationException( - "The supplied graphics devices for the primitive and the vertex buffer region do not match."); - } - - if (GetIndexBufferRegion().GetCollection() != nullptr && GetIndexBufferRegion().GetDevice() != GetDevice()) - { - throw Exceptions::InvalidOperationException( - "The supplied graphics devices for the primitive and the index buffer region do not match."); - } - - _inputResourceRegions = std::vector>(inputResourceRegions.begin(), - inputResourceRegions.end()); - } - - [[nodiscard]] inline const GraphicsMemoryRegion& GetIndexBufferRegion() const noexcept - { - return _indexBufferRegion; - } - - [[nodiscard]] inline uint32_t GetIndexBufferStride() const noexcept - { - return _indexBufferStride; - } - - [[nodiscard]] inline NovelRT::Utilities::Misc::Span> - GetInputResourceRegions() const noexcept - { - return NovelRT::Utilities::Misc::Span>( - &(*_inputResourceRegions.begin()), _inputResourceRegions.size()); - } - - [[nodiscard]] inline std::shared_ptr GetPipeline() const noexcept - { - return _pipeline; - } - - [[nodiscard]] inline const GraphicsMemoryRegion& GetVertexBufferRegion() const noexcept - { - return _vertexBufferRegion; - } - - [[nodiscard]] inline uint32_t GetVertexBufferStride() const noexcept - { - return _vertexBufferStride; - } - - virtual ~GraphicsPrimitive() = default; - }; -} - -#endif // !NOVELRT_GRAPHICS_GRAPHICSPRIMITIVE_H diff --git a/graphics/include/NovelRT/Graphics/GraphicsProvider.hpp b/graphics/include/NovelRT/Graphics/GraphicsProvider.hpp deleted file mode 100644 index 89e866f15..000000000 --- a/graphics/include/NovelRT/Graphics/GraphicsProvider.hpp +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_GRAPHICS_GRAPHICSPROVIDER_H -#define NOVELRT_GRAPHICS_GRAPHICSPROVIDER_H - -#ifndef NOVELRT_GRAPHICS_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.h instead for the Graphics namespace subset. -#endif - -namespace NovelRT::Graphics -{ - class GraphicsProvider : public std::enable_shared_from_this - { - private: - bool _debugModeEnabled; - - public: - static inline const std::string EnableDebugModeSwitchName = - "NovelRT::Graphics::GraphicsProvider::EnableDebugMode"; - - GraphicsProvider() noexcept : _debugModeEnabled(EngineConfig::EnableDebugOutputFromEngineInternals()) - { - } - - [[nodiscard]] inline bool GetDebugModeEnabled() const noexcept - { - return _debugModeEnabled; - } - - [[nodiscard]] virtual std::vector>::iterator begin() noexcept = 0; - [[nodiscard]] virtual std::vector>::iterator end() noexcept = 0; - - virtual ~GraphicsProvider() = default; - }; -} - -#endif // !NOVELRT_GRAPHICS_GRAPHICSPROVIDER_H diff --git a/graphics/include/NovelRT/Graphics/GraphicsResource.hpp b/graphics/include/NovelRT/Graphics/GraphicsResource.hpp deleted file mode 100644 index 3547287f0..000000000 --- a/graphics/include/NovelRT/Graphics/GraphicsResource.hpp +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_GRAPHICS_GRAPHICSRESOURCE_H -#define NOVELRT_GRAPHICS_GRAPHICSRESOURCE_H - -#ifndef NOVELRT_GRAPHICS_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.h instead for the Graphics namespace subset. -#endif - -namespace NovelRT::Graphics -{ - class GraphicsResource : public GraphicsDeviceObject, public IGraphicsMemoryRegionCollection - { - private: - GraphicsMemoryRegion _blockRegion; - std::shared_ptr _allocator; - GraphicsResourceAccess _cpuAccess; - - public: - GraphicsResource(const std::shared_ptr& device, - GraphicsMemoryRegion blockRegion, - GraphicsResourceAccess cpuAccess) - : GraphicsDeviceObject(std::weak_ptr(device)), - _blockRegion(std::move(blockRegion)), - _cpuAccess(cpuAccess) - { - if (_blockRegion.GetCollection() == nullptr) - { - throw Exceptions::NullPointerException("The collection in the provided block region is null."); - } - - // Explicit call to base GetDevice() to avoid ambiguity in the ctor. - if (_blockRegion.GetDevice() != GraphicsDeviceObject::GetDevice()) - { - throw std::out_of_range("The device of the block region does not match that of the provided device. " - "This resource will be out of range and therefore invalid."); - } - - _allocator = _blockRegion.GetCollection()->GetCollection()->GetAllocator(); - } - - [[nodiscard]] inline size_t GetAlignment() const noexcept - { - return GetBlockRegion().GetAlignment(); - } - - [[nodiscard]] inline std::shared_ptr GetAllocator() const noexcept - { - return _allocator; - } - - [[nodiscard]] inline std::shared_ptr GetBlock() const noexcept - { - return GetBlockRegion().GetCollection(); - } - - [[nodiscard]] inline const GraphicsMemoryRegion& GetBlockRegion() const noexcept - { - return _blockRegion; - } - - [[nodiscard]] virtual size_t GetCount() = 0; - - [[nodiscard]] inline GraphicsResourceAccess GetCpuAccess() const noexcept - { - return _cpuAccess; - } - - [[nodiscard]] inline size_t GetOffset() const noexcept - { - return GetBlockRegion().GetOffset(); - } - - [[nodiscard]] inline size_t GetSize() final - { - return GetBlockRegion().GetSize(); - } - - [[nodiscard]] virtual void* MapUntyped() = 0; - - [[nodiscard]] virtual void* MapUntyped(size_t rangeOffset, size_t rangeLength) = 0; - - template[[nodiscard]] T* Map() - { - return reinterpret_cast(MapUntyped()); - } - - template[[nodiscard]] T* Map(const GraphicsMemoryRegion& region) - { - return Map(region.GetOffset(), region.GetSize()); - } - - template[[nodiscard]] T* Map(size_t rangeOffset, size_t rangeLength) - { - return reinterpret_cast(MapUntyped(rangeOffset, rangeLength)); - } - - [[nodiscard]] virtual const void* MapForReadUntyped() = 0; - [[nodiscard]] virtual const void* MapForReadUntyped(size_t readRangeOffset, size_t readRangeLength) = 0; - - template[[nodiscard]] const T* MapForRead() - { - return reinterpret_cast(MapForReadUntyped()); - } - - template[[nodiscard]] const T* MapForRead(const GraphicsMemoryRegion& readRegion) - { - return MapForRead(readRegion.GetOffset(), readRegion.GetSize()); - } - - template[[nodiscard]] const T* MapForRead(size_t readRangeOffset, size_t readRangeLength) - { - return reinterpret_cast(MapForReadUntyped(readRangeOffset, readRangeLength)); - } - - virtual void Unmap() = 0; - virtual void UnmapAndWrite() = 0; - virtual void UnmapAndWrite(size_t writtenRangeOffset, size_t writtenRangeLength) = 0; - - inline void UnmapAndWrite(const GraphicsMemoryRegion& writtenRegion) - { - UnmapAndWrite(writtenRegion.GetOffset(), writtenRegion.GetSize()); - } - - ~GraphicsResource() override = default; - }; -} - -#endif // !NOVELRT_GRAPHICS_GRAPHICSRESOURCE_H diff --git a/graphics/include/NovelRT/Graphics/GraphicsResourceManager.hpp b/graphics/include/NovelRT/Graphics/GraphicsResourceManager.hpp deleted file mode 100644 index 9cc93bfd9..000000000 --- a/graphics/include/NovelRT/Graphics/GraphicsResourceManager.hpp +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_GRAPHICS_GRAPHICSRESOURCEMANAGER_H -#define NOVELRT_GRAPHICS_GRAPHICSRESOURCEMANAGER_H - -#ifndef NOVELRT_GRAPHICS_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.h instead for the Graphics namespace subset. -#endif - -namespace NovelRT::Graphics -{ - class GraphicsResourceManager - { - private: - std::vector>> _stagingBuffers; - std::vector> _defaultBuffers; - std::vector> _vertexBuffers; - std::vector> _indexBuffers; - std::vector> _constantBuffers; - std::vector> _textures; - std::set _constantBuffersToUnmapAndWrite; - std::shared_ptr _graphicsDevice; - size_t _stagingBufferSize; - size_t _contextIndex; - static constexpr size_t _tenMegabytesAsBytes = 10 * 1024 * 1024; - - [[nodiscard]] std::shared_ptr CreateStagingBuffer(); - [[nodiscard]] std::shared_ptr GetOrCreateGraphicsBufferForAllocationSize( - size_t allocationSize, - GraphicsBufferKind bufferKind); - [[nodiscard]] std::shared_ptr GetStagingBufferWithProperSizeHandling( - size_t sizeToStage, - std::shared_ptr& currentContext); - - public: - explicit GraphicsResourceManager(std::shared_ptr graphicsDevice, - size_t startingStagingBufferSize = 0); - GraphicsResourceManager(const GraphicsResourceManager& other); - GraphicsResourceManager(GraphicsResourceManager&& other) noexcept; - - GraphicsResourceManager& operator=(const GraphicsResourceManager& other); - GraphicsResourceManager& operator=(GraphicsResourceManager&& other) noexcept; - - ~GraphicsResourceManager() = default; - - void PrepForFrameWithContextIndex(size_t newContextIndex); - - template - [[nodiscard]] GraphicsMemoryRegion LoadVertexData(NovelRT::Utilities::Misc::Span data, - size_t alignment = 0) - { - return LoadVertexDataUntyped(&(*data.begin()), sizeof(TData), data.size(), alignment); - } - - [[nodiscard]] GraphicsMemoryRegion LoadVertexDataUntyped(void* data, - size_t dataTypeSize, - size_t dataLength, - size_t alignment = 16); - - template - [[nodiscard]] GraphicsMemoryRegion LoadIndexData(NovelRT::Utilities::Misc::Span data, - size_t alignment = 0) - { - return LoadIndexDataUntyped(&(*data.begin()), sizeof(TData), data.size(), alignment); - } - - [[nodiscard]] GraphicsMemoryRegion LoadIndexDataUntyped(void* data, - size_t dataTypeSize, - size_t dataLength, - size_t alignment = 64); - - [[nodiscard]] GraphicsMemoryRegion LoadTextureData( - const ResourceManagement::TextureMetadata& metadata, - GraphicsTextureAddressMode addressMode, - GraphicsTextureKind textureKind); - - [[nodiscard]] GraphicsMemoryRegion AllocateConstantBufferRegion(size_t size, - size_t alignment = 256); - - [[nodiscard]] GraphicsMemoryRegion LoadConstantBufferDataToNewRegion(void* data, - size_t size, - size_t alignment = 256); - - void LoadConstantBufferDataToExistingRegion(GraphicsMemoryRegion& targetMemoryResource, - void* data, - size_t size); - [[nodiscard]] uint8_t* MapConstantBufferRegionForWritingUntyped( - GraphicsMemoryRegion& targetMemoryResource); - - template - [[nodiscard]] TPointerType* MapConstantBufferRegionForWriting( - GraphicsMemoryRegion& targetMemoryResource) - { - return reinterpret_cast(MapConstantBufferRegionForWritingUntyped(targetMemoryResource)); - } - void UnmapAndWriteAllConstantBuffers() noexcept; - - void FreeConstantBufferData(GraphicsMemoryRegion& regionToFree); - void FreeVertexData(GraphicsMemoryRegion& vertexResource); - void FreeIndexData(GraphicsMemoryRegion& indexResource); - void FreeTextureData(GraphicsMemoryRegion& textureResource); - }; -} - -#endif // !NOVELRT_GRAPHICS_GRAPHICSRESOURCEMANAGER_H diff --git a/graphics/include/NovelRT/Graphics/GraphicsSurfaceContext.hpp b/graphics/include/NovelRT/Graphics/GraphicsSurfaceContext.hpp deleted file mode 100644 index 90e053c17..000000000 --- a/graphics/include/NovelRT/Graphics/GraphicsSurfaceContext.hpp +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_GRAPHICS_GRAPHICSSURFACECONTEXT_H -#define NOVELRT_GRAPHICS_GRAPHICSSURFACECONTEXT_H - -#ifndef NOVELRT_GRAPHICS_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.h instead for the Graphics namespace subset. -#endif - -namespace NovelRT::Graphics -{ - class GraphicsSurfaceContext - { - private: - std::shared_ptr _surface; - std::shared_ptr _provider; - - public: - GraphicsSurfaceContext(std::shared_ptr surface, std::shared_ptr provider) - : _surface(std::move(surface)), _provider(std::move(provider)) - { - if (_surface == nullptr) - { - throw Exceptions::NullPointerException("The supplied IGraphicsSurface is nullptr."); - } - - if (_provider == nullptr) - { - throw Exceptions::NullPointerException("The supplied GraphicsProvider is nullptr."); - } - } - - [[nodiscard]] inline std::shared_ptr GetSurface() const noexcept - { - return _surface; - } - - [[nodiscard]] inline std::shared_ptr GetProvider() const noexcept - { - return _provider; - } - - [[nodiscard]] virtual void* GetSurfaceContextHandleUntyped() = 0; - - template[[nodiscard]] THandleType GetSurfaceContextHandleAs() - { - return *reinterpret_cast(GetSurfaceContextHandleUntyped()); - } - - virtual ~GraphicsSurfaceContext() = default; - }; -} - -#endif // !NOVELRT_GRAPHICS_GRAPHICSSURFACECONTEXT_H diff --git a/graphics/include/NovelRT/Graphics/GraphicsTexture.hpp b/graphics/include/NovelRT/Graphics/GraphicsTexture.hpp deleted file mode 100644 index 2f1cadae0..000000000 --- a/graphics/include/NovelRT/Graphics/GraphicsTexture.hpp +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_GRAPHICS_GRAPHICSTEXTURE_H -#define NOVELRT_GRAPHICS_GRAPHICSTEXTURE_H - -#ifndef NOVELRT_GRAPHICS_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.h instead for the Graphics namespace subset. -#endif - -namespace NovelRT::Graphics -{ - class GraphicsTexture : public GraphicsResource - { - private: - GraphicsTextureAddressMode _addressMode; - GraphicsTextureKind _kind; - uint32_t _width; - uint32_t _height; - uint16_t _depth; - - public: - GraphicsTexture(std::shared_ptr device, - GraphicsTextureAddressMode addressMode, - GraphicsTextureKind kind, - GraphicsMemoryRegion blockRegion, - GraphicsResourceAccess cpuAccess, - uint32_t width, - uint32_t height, - uint16_t depth) - : GraphicsResource(std::move(device), std::move(blockRegion), cpuAccess), - _addressMode(addressMode), - _kind(kind), - _width(width), - _height(height), - _depth(depth) - { - } - - [[nodiscard]] inline uint16_t GetDepth() const noexcept - { - return _depth; - } - - [[nodiscard]] inline uint32_t GetHeight() const noexcept - { - return _height; - } - - [[nodiscard]] inline GraphicsTextureKind GetKind() const noexcept - { - return _kind; - } - - [[nodiscard]] inline GraphicsTextureAddressMode GetAddressMode() const noexcept - { - return _addressMode; - } - - [[nodiscard]] inline uint32_t GetWidth() const noexcept - { - return _width; - } - }; -} - -#endif // !NOVELRT_GRAPHICS_GRAPHICSTEXTURE_H diff --git a/graphics/include/NovelRT/Graphics/IGraphicsAdapterSelector.hpp b/graphics/include/NovelRT/Graphics/IGraphicsAdapterSelector.hpp deleted file mode 100644 index f560002b8..000000000 --- a/graphics/include/NovelRT/Graphics/IGraphicsAdapterSelector.hpp +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_GRAPHICS_GRAPHICSADAPTERSELECTOR_H -#define NOVELRT_GRAPHICS_GRAPHICSADAPTERSELECTOR_H - -#ifndef NOVELRT_GRAPHICS_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.h instead for the Graphics namespace subset. -#endif - -namespace NovelRT::Graphics -{ - class IGraphicsAdapterSelector - { - public: - [[nodiscard]] virtual std::shared_ptr GetDefaultRecommendedAdapter( - const std::shared_ptr& provider, - const std::shared_ptr& surfaceContext) const = 0; - - virtual ~IGraphicsAdapterSelector() = default; - }; -} - -#endif // !NOVELRT_GRAPHICS_GRAPHICSADAPTERSELECTOR_H diff --git a/graphics/include/NovelRT/Graphics/IGraphicsMemoryRegionCollection.hpp b/graphics/include/NovelRT/Graphics/IGraphicsMemoryRegionCollection.hpp deleted file mode 100644 index 912f377b5..000000000 --- a/graphics/include/NovelRT/Graphics/IGraphicsMemoryRegionCollection.hpp +++ /dev/null @@ -1,677 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_GRAPHICS_IGRAPHICSMEMORYREGIONCOLLECTION_H -#define NOVELRT_GRAPHICS_IGRAPHICSMEMORYREGIONCOLLECTION_H - -#ifndef NOVELRT_GRAPHICS_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.h instead for the Graphics namespace subset. -#endif - -namespace NovelRT::Graphics -{ - template>::iterator> - class IGraphicsMemoryRegionCollection - { - protected: - [[nodiscard]] virtual GraphicsDevice* GetDeviceInternal() const noexcept = 0; - - public: - IGraphicsMemoryRegionCollection() noexcept = default; - IGraphicsMemoryRegionCollection(const IGraphicsMemoryRegionCollection&) noexcept = delete; - IGraphicsMemoryRegionCollection(IGraphicsMemoryRegionCollection&&) noexcept = delete; - IGraphicsMemoryRegionCollection& operator=( - const IGraphicsMemoryRegionCollection&) noexcept = delete; - IGraphicsMemoryRegionCollection& operator=( - IGraphicsMemoryRegionCollection&&) noexcept = delete; - virtual ~IGraphicsMemoryRegionCollection() = default; - - [[nodiscard]] virtual int32_t GetAllocatedRegionCount() = 0; - - [[nodiscard]] inline std::shared_ptr GetDevice() const noexcept - { - return GetDeviceInternal()->shared_from_this(); - } - - [[nodiscard]] virtual bool GetIsEmpty() = 0; - [[nodiscard]] virtual size_t GetLargestFreeRegionSize() = 0; - [[nodiscard]] virtual size_t GetMinimumAllocatedRegionMarginSize() = 0; - [[nodiscard]] virtual size_t GetMinimumFreeRegionSizeToRegister() = 0; - [[nodiscard]] virtual size_t GetSize() = 0; - [[nodiscard]] virtual size_t GetTotalFreeRegionSize() = 0; - [[nodiscard]] virtual GraphicsMemoryRegion Allocate(size_t size, size_t alignment) = 0; - virtual void Clear() = 0; - - virtual void Free(const GraphicsMemoryRegion& region) = 0; - - [[nodiscard]] virtual bool TryAllocate(size_t size, - size_t alignment, - GraphicsMemoryRegion& outRegion) = 0; - - [[nodiscard]] GraphicsMemoryRegion Allocate(size_t size) - { - return Allocate(size, 1); - } - - [[nodiscard]] bool TryAllocate(size_t size, GraphicsMemoryRegion& outRegion) - { - return TryAllocate(size, 1, outRegion); - } - - [[nodiscard]] virtual TIterator begin() = 0; - [[nodiscard]] virtual TIterator end() = 0; - - class IMetadata : public IGraphicsMemoryRegionCollection - { - public: - virtual void Initialise(std::shared_ptr collection, - size_t size, - size_t minimumAllocatedRegionMarginSize, - size_t minimumFreeRegionSizeToRegister) = 0; - - IMetadata() noexcept = default; - IMetadata(const IMetadata&) noexcept = delete; - IMetadata(IMetadata&&) noexcept = delete; - IMetadata& operator=(const IMetadata&) noexcept = delete; - IMetadata& operator=(IMetadata&&) noexcept = delete; - virtual ~IMetadata() = default; - }; - - class DefaultMetadata final : public IMetadata - { - private: - std::shared_ptr _collection; - std::shared_ptr>::iterator>> _freeRegionsBySize; - std::shared_ptr>> _regions; - size_t _minimumFreeRegionSizeToRegister; - size_t _minimumAllocatedRegionMarginSize; - size_t _size; - size_t _totalFreeRegionSize; - int32_t _freeRegionCount; - std::shared_ptr _device; - - protected: - [[nodiscard]] GraphicsDevice* GetDeviceInternal() const noexcept final - { - return _device.get(); - } - - public: - explicit DefaultMetadata(std::shared_ptr device) noexcept - : _collection(nullptr), - _freeRegionsBySize( - std::make_shared>::iterator>>()), - _regions(std::make_shared>>()), - _minimumFreeRegionSizeToRegister(static_cast(-1)), - _minimumAllocatedRegionMarginSize(static_cast(-1)), - _size(static_cast(-1)), - _totalFreeRegionSize(static_cast(-1)), - _freeRegionCount(-1), - _device(std::move(device)) - { - } - - DefaultMetadata(const DefaultMetadata& other) noexcept - : _collection(other._collection), - _freeRegionsBySize(other._freeRegionsBySize), - _regions(other._regions), - _minimumFreeRegionSizeToRegister(other._minimumFreeRegionSizeToRegister), - _minimumAllocatedRegionMarginSize(other._minimumAllocatedRegionMarginSize), - _size(other._size), - _totalFreeRegionSize(other._totalFreeRegionSize), - _freeRegionCount(other._freeRegionCount), - _device(other._device) - { - } - - DefaultMetadata(DefaultMetadata&& other) noexcept - : _collection(std::move(other._collection)), - _freeRegionsBySize(std::move(other._freeRegionsBySize)), - _regions(std::move(other._regions)), - _minimumFreeRegionSizeToRegister(other._minimumFreeRegionSizeToRegister), - _minimumAllocatedRegionMarginSize(other._minimumAllocatedRegionMarginSize), - _size(other._size), - _totalFreeRegionSize(other._totalFreeRegionSize), - _freeRegionCount(other._freeRegionCount), - _device(std::move(other._device)) - { - other._minimumFreeRegionSizeToRegister = static_cast(-1); - other._minimumAllocatedRegionMarginSize = static_cast(-1); - other._size = static_cast(-1); - other._totalFreeRegionSize = static_cast(-1); - other._freeRegionCount = -1; - } - - DefaultMetadata& operator=(DefaultMetadata other) noexcept - { - std::swap(_collection, other._collection); - std::swap(_freeRegionsBySize, other._freeRegionsBySize); - std::swap(_regions, other._regions); - std::swap(_minimumFreeRegionSizeToRegister, other._minimumFreeRegionSizeToRegister); - std::swap(_minimumAllocatedRegionMarginSize, other._minimumAllocatedRegionMarginSize); - std::swap(_size, other._size); - std::swap(_totalFreeRegionSize, other._totalFreeRegionSize); - std::swap(_freeRegionCount, other._freeRegionCount); - std::swap(_device, other._device); - - return *this; - } - - DefaultMetadata& operator=(DefaultMetadata&& other) noexcept - { - *this = std::move(other); - } - - ~DefaultMetadata() final = default; - - [[nodiscard]] int32_t GetAllocatedRegionCount() final - { - return static_cast(_regions->size() - _freeRegionCount); - } - - [[nodiscard]] size_t GetCount() const noexcept - { - return _regions->size(); - } - - [[nodiscard]] bool GetIsEmpty() final - { - return _regions->size() == 1 && _freeRegionCount == 1; - } - - [[nodiscard]] size_t GetLargestFreeRegionSize() final - { - return _freeRegionsBySize->size() != 0 ? _freeRegionsBySize->back()->GetSize() : 0; - } - - [[nodiscard]] size_t GetMinimumAllocatedRegionMarginSize() final - { - return _minimumAllocatedRegionMarginSize; - } - - [[nodiscard]] size_t GetMinimumFreeRegionSizeToRegister() final - { - return _minimumFreeRegionSizeToRegister; - } - - [[nodiscard]] size_t GetSize() final - { - return _size; - } - - [[nodiscard]] size_t GetTotalFreeRegionSize() final - { - return _totalFreeRegionSize; - } - - [[nodiscard]] GraphicsMemoryRegion Allocate(size_t size, size_t alignment) final - { - GraphicsMemoryRegion region(0, nullptr, nullptr, false, 0, 0); - auto result = TryAllocate(size, alignment, region); - - if (!result) - { - throw Exceptions::OutOfMemoryException("A size of " + std::to_string(result) + - " bytes was requested, but this size is too large."); - } - - return region; - } - - void Clear() final - { - size_t size = GetSize(); - - _freeRegionCount = 1; - _totalFreeRegionSize = size; - - _regions->clear(); - - GraphicsMemoryRegion region(1, _collection, this->GetDevice(), false, 0, size); - _regions->emplace_front(region); - auto iterator = _regions->begin(); - _freeRegionsBySize->clear(); - _freeRegionsBySize->emplace_back(iterator); - - assert(Validate()); - } - - void Free(const GraphicsMemoryRegion& region) final - { - bool freedRegion = false; - - for (auto it = _regions->begin(); it != _regions->end(); std::advance(it, 1)) - { - if (*it != region) - { - continue; - } - - static_cast(FreeRegionInternal(it)); - freedRegion = true; - break; - } - - if (!freedRegion) - { - throw Exceptions::KeyNotFoundException(); - } - - assert(Validate()); - } - - void Initialise(std::shared_ptr collection, - size_t size, - size_t minimumAllocatedRegionMarginSize, - size_t minimumFreeRegionSizeToRegister) final - { - if (collection == nullptr) - { - throw Exceptions::NullPointerException("Parameter name: collection."); - } - - if (size == 0) - { - throw std::out_of_range( - "The size parameter was set to 0. This is not a valid size and is out of range."); - } - - _collection = collection; - _minimumAllocatedRegionMarginSize = minimumAllocatedRegionMarginSize; - _minimumFreeRegionSizeToRegister = minimumFreeRegionSizeToRegister; - _size = size; - Clear(); - } - - [[nodiscard]] bool TryAllocate(size_t size, size_t alignment, GraphicsMemoryRegion& outRegion) final - { - if (size == 0) - { - throw std::out_of_range( - "The size parameter was set to 0. This is not a valid size and is out of range."); - } - - if (!Maths::Utilities::IsPow2(alignment)) - { - throw std::out_of_range("The provided alignment is invalid, as it is not to a power of two."); - } - - size_t sizeWithMargins = size + (2 * GetMinimumAllocatedRegionMarginSize()); - bool allocatedRegion = false; - - if (GetTotalFreeRegionSize() >= sizeWithMargins) - { - NovelRT::Utilities::Misc::Span>::iterator> - freeRegionsBySizeSpan(*_freeRegionsBySize); - size_t freeRegionsBySizeLength = freeRegionsBySizeSpan.size(); - - if (freeRegionsBySizeLength > 0) - { - for (auto index = BinarySearchFirstRegionNodeWithSizeNotLessThan(sizeWithMargins); - index < freeRegionsBySizeLength; ++index) - { - auto regionNode = freeRegionsBySizeSpan[index]; - - if (TryAllocateInternal(size, alignment, regionNode)) - { - outRegion = *regionNode; - allocatedRegion = true; - break; - } - } - } - } - - if (!allocatedRegion) - { - outRegion = GraphicsMemoryRegion(); - } - - assert(Validate()); - - return allocatedRegion; - } - - [[nodiscard]] typename std::list>::iterator begin() override - { - return _regions->begin(); - } - - [[nodiscard]] typename std::list>::iterator end() override - { - return _regions->end(); - } - - /** - * THIS IS ONLY USED BY DEBUG BUILDS - */ - [[nodiscard]] bool Validate() - { - if (_regions->size() == 0) - { - return false; - } - - size_t calculatedSize = 0ULL; - size_t calculatedTotalFreeRegionSize = 0ULL; - - int32_t calculatedFreeRegionCount = 0; - size_t calculatedFreeRegionsToRegisterCount = 0; - - bool isPreviousRegionFree = false; - - for (auto&& region : *_regions) - { - if (region.GetOffset() != calculatedSize) - { - return false; - } - - bool isCurrentRegionFree = !region.GetIsAllocated(); - - if (isPreviousRegionFree && isCurrentRegionFree) - { - return false; - } - - if (isCurrentRegionFree) - { - calculatedTotalFreeRegionSize += region.GetSize(); - ++calculatedFreeRegionCount; - - if (region.GetSize() >= GetMinimumFreeRegionSizeToRegister()) - { - ++calculatedFreeRegionsToRegisterCount; - } - - if (region.GetSize() < GetMinimumAllocatedRegionMarginSize()) - { - return false; - } - } - else if (GetMinimumAllocatedRegionMarginSize() != 0 && !isPreviousRegionFree) - { - return false; - } - - calculatedSize += region.GetSize(); - isPreviousRegionFree = isCurrentRegionFree; - } - - if (!ValidateFreeRegionsBySizeList()) - { - return false; - } - - return calculatedSize == GetSize() && calculatedTotalFreeRegionSize == _totalFreeRegionSize && - calculatedFreeRegionCount == _freeRegionCount && - calculatedFreeRegionsToRegisterCount == _freeRegionsBySize->size(); - } - - private: - [[nodiscard]] bool ValidateFreeRegionsBySizeList() - { - size_t lastRegionSize = 0ULL; - - for (auto&& region : *_freeRegionsBySize) - { - if (region->GetIsAllocated() || region->GetSize() < GetMinimumFreeRegionSizeToRegister() || - region->GetSize() < lastRegionSize) - { - return false; - } - - lastRegionSize = region->GetSize(); - } - - return true; - } - - [[nodiscard]] size_t BinarySearchFirstRegionNodeWithSizeNotLessThan(size_t size) const noexcept - { - NovelRT::Utilities::Misc::Span>::iterator> - freeRegionsBySizeSpan(&(*_freeRegionsBySize->begin()), _freeRegionsBySize->size()); - - size_t index = 0; - size_t endIndex = freeRegionsBySizeSpan.size(); - - while (index < endIndex) - { - size_t midIndex = (index + endIndex) / 2; - - if (freeRegionsBySizeSpan[midIndex]->GetSize() < size) - { - index = midIndex + 1; - } - else - { - endIndex = midIndex; - } - } - - return index; - } - - [[nodiscard]] typename std::list>::iterator FreeRegionInternal( - typename std::list>::iterator regionNode) - { - GraphicsMemoryRegion& region = *regionNode; - - if (!region.GetIsAllocated()) - { - return regionNode; - } - - region = GraphicsMemoryRegion(region.GetAlignment(), region.GetCollection(), region.GetDevice(), - false, region.GetOffset(), region.GetSize()); - - ++_freeRegionCount; - _totalFreeRegionSize += region.GetSize(); - - auto nextRegionNode = regionNode; - std::advance(nextRegionNode, 1); - bool mergeWithNext = nextRegionNode != _regions->end() && !nextRegionNode->GetIsAllocated(); - - auto previousRegionNode = regionNode; - std::advance(previousRegionNode, -1); - bool mergeWithPrevious = previousRegionNode != _regions->end() && !previousRegionNode->GetIsAllocated(); - - if (mergeWithNext) - { - UnregisterFreeRegion(nextRegionNode); - MergeFreeRegionWithNext(regionNode); - } - - if (mergeWithPrevious) - { - UnregisterFreeRegion(previousRegionNode); - MergeFreeRegionWithNext(previousRegionNode); - RegisterFreeRegion(previousRegionNode); - return previousRegionNode; - } - else - { - RegisterFreeRegion(regionNode); - return regionNode; - } - } - - void MergeFreeRegionWithNext(typename std::list>::iterator regionNode) - { - auto nextRegionNode = regionNode; - ++nextRegionNode; - - if (nextRegionNode->GetIsAllocated()) - { - throw Exceptions::InvalidOperationException( - "An allocated memory region was designated to be merged with an unallocated one."); - } - - GraphicsMemoryRegion& region = *regionNode; - const GraphicsMemoryRegion& nextRegion = *nextRegionNode; - - region = GraphicsMemoryRegion(region.GetAlignment(), region.GetCollection(), region.GetDevice(), - region.GetIsAllocated(), region.GetOffset(), - region.GetSize() + nextRegion.GetSize()); - - --_freeRegionCount; - - _regions->erase(nextRegionNode); - } - - void RegisterFreeRegion(typename std::list>::iterator regionNode) - { - if (regionNode->GetIsAllocated()) - { - throw Exceptions::InvalidOperationException( - "An allocated memory region was designated to be registered as free."); - } - - if (regionNode->GetSize() == 0) - { - throw Exceptions::InvalidOperationException( - "A memory region of size 0 was provided as a free region to register."); - } - - assert(ValidateFreeRegionsBySizeList()); - - if (regionNode->GetSize() >= GetMinimumFreeRegionSizeToRegister()) - { - if (_freeRegionsBySize->size() == 0) - { - _freeRegionsBySize->emplace_back(regionNode); - } - else - { - size_t index = BinarySearchFirstRegionNodeWithSizeNotLessThan(regionNode->GetSize()); - _freeRegionsBySize->insert(_freeRegionsBySize->begin() + index, regionNode); - } - } - - assert(ValidateFreeRegionsBySizeList()); - } - - [[nodiscard]] bool TryAllocateInternal(size_t size, - size_t alignment, - typename std::list>::iterator regionNode) - { - if (size <= 0) - { - throw Exceptions::InvalidOperationException( - "An attempt to allocate a memory region of size 0 (or less) was made."); - } - - if (regionNode == _collection->end()) - { - throw std::out_of_range("Parameter name: regionNode"); - } - - GraphicsMemoryRegion& region = *regionNode; - - if (region.GetIsAllocated()) - { - throw Exceptions::InvalidOperationException( - "An attempt to allocate a memory region that was already allocated was made."); - } - - if (region.GetSize() < size) - { - return false; - } - - size_t offset = region.GetOffset(); - - if (GetMinimumAllocatedRegionMarginSize() > 0) - { - offset += GetMinimumAllocatedRegionMarginSize(); - } - - offset = Maths::Utilities::AlignUp(offset, alignment); - size_t paddingBegin = offset - region.GetOffset(); - size_t requiredEndMargin = GetMinimumAllocatedRegionMarginSize(); - - if ((paddingBegin + size + requiredEndMargin) > region.GetSize()) - { - return false; - } - - size_t paddingEnd = region.GetSize() - paddingBegin - size; - - UnregisterFreeRegion(regionNode); - - region = GraphicsMemoryRegion(alignment, _collection, this->GetDevice(), true, offset, size); - - if (paddingEnd != 0) - { - auto iterator = _regions->insert(std::next(regionNode), - GraphicsMemoryRegion(1, _collection, this->GetDevice(), - false, offset + size, paddingEnd)); - RegisterFreeRegion(iterator); - } - - if (paddingBegin != 0) - { - auto iterator = _regions->insert( - regionNode, GraphicsMemoryRegion(1, _collection, this->GetDevice(), false, - offset - paddingBegin, paddingBegin)); - RegisterFreeRegion(iterator); - } - - --_freeRegionCount; - - if (paddingBegin > 0) - { - ++_freeRegionCount; - } - - if (paddingEnd > 0) - { - ++_freeRegionCount; - } - - _totalFreeRegionSize -= size; - return true; - } - - void UnregisterFreeRegion(typename std::list>::iterator regionNode) - { - if (regionNode->GetIsAllocated()) - { - throw Exceptions::InvalidOperationException("An attempt was made to unregister a free region, but " - "the target region is currently allocated."); - } - - if (regionNode->GetSize() <= 0) - { - throw Exceptions::InvalidOperationException( - "An attempt was made to unregister an invalid region that has a size of 0 (or less)."); - } - - assert(ValidateFreeRegionsBySizeList()); - - if (regionNode->GetSize() >= GetMinimumFreeRegionSizeToRegister()) - { - for (auto index = BinarySearchFirstRegionNodeWithSizeNotLessThan(regionNode->GetSize()); - index < _freeRegionsBySize->size(); ++index) - { - if ((*_freeRegionsBySize)[index] == regionNode) - { - _freeRegionsBySize->erase(_freeRegionsBySize->begin() + index); - return; - } - - if ((*_freeRegionsBySize)[index]->GetSize() != regionNode->GetSize()) - { - // TODO: Fix exception message - throw std::runtime_error("Something broke lol"); - } - } - } - - assert(ValidateFreeRegionsBySizeList()); - } - }; - }; -} - -#endif // NOVELRT_GRAPHICS_IGRAPHICSMEMORYREGIONCOLLECTION_H diff --git a/graphics/include/NovelRT/Graphics/Metal/Graphics.Metal.hpp b/graphics/include/NovelRT/Graphics/Metal/Graphics.Metal.hpp deleted file mode 100644 index 452073378..000000000 --- a/graphics/include/NovelRT/Graphics/Metal/Graphics.Metal.hpp +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_GRAPHICS_METAL_H -#define NOVELRT_GRAPHICS_METAL_H - -// Graphics.Metal dependencies -#include "../../Exceptions/Exceptions.h" -#include "../../LoggingService.h" -#include "../Graphics.h" -#include - -/** - * @brief The default Metal implementation for the Graphics plugin API. - */ -namespace NovelRT::Graphics::Metal -{ - -} - -// Graphics.Metal types - -// clang-format off - -#include "NovelRT/Graphics/Metal/Utilities/Graphics.Metal.Utilities.h" - -// clang-format on - -#endif // NOVELRT_GRAPHICS_METAL_H diff --git a/graphics/include/NovelRT/Graphics/Metal/Utilities/Graphics.Metal.Utilities.hpp b/graphics/include/NovelRT/Graphics/Metal/Utilities/Graphics.Metal.Utilities.hpp deleted file mode 100644 index 35d41ad00..000000000 --- a/graphics/include/NovelRT/Graphics/Metal/Utilities/Graphics.Metal.Utilities.hpp +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_GRAPHICS_METAL_UTILITIES_H -#define NOVELRT_GRAPHICS_METAL_UTILITIES_H - -#ifndef NOVELRT_GRAPHICS_METAL_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.Metal.h instead for the Graphics::Metal namespace subset. -#endif - -#include "PipelineBlendFactor.h" - -#endif // !NOVELRT_GRAPHICS_METAL_UTILITIES_H diff --git a/graphics/include/NovelRT/Graphics/ShaderProgram.hpp b/graphics/include/NovelRT/Graphics/ShaderProgram.hpp deleted file mode 100644 index 64c1d57f2..000000000 --- a/graphics/include/NovelRT/Graphics/ShaderProgram.hpp +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_GRAPHICS_SHADERPROGRAM_H -#define NOVELRT_GRAPHICS_SHADERPROGRAM_H - -#ifndef NOVELRT_GRAPHICS_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.h instead for the Graphics namespace subset. -#endif - -namespace NovelRT::Graphics -{ - class ShaderProgram : public GraphicsDeviceObject - { - private: - std::string _entryPointName; - ShaderProgramKind _kind; - - public: - ShaderProgram(std::shared_ptr device, - std::string entryPointName, - ShaderProgramKind kind) noexcept; - - [[nodiscard]] inline const std::string& GetEntryPointName() const noexcept - { - return _entryPointName; - } - - [[nodiscard]] inline ShaderProgramKind GetKind() const noexcept - { - return _kind; - } - - [[nodiscard]] virtual NovelRT::Utilities::Misc::Span GetBytecode() const noexcept = 0; - }; -} - -#endif // !NOVELRT_GRAPHICS_SHADERPROGRAM_H diff --git a/graphics/include/NovelRT/Graphics/Vulkan/Graphics.Vulkan.hpp b/graphics/include/NovelRT/Graphics/Vulkan/Graphics.Vulkan.hpp deleted file mode 100644 index 255c7b5d6..000000000 --- a/graphics/include/NovelRT/Graphics/Vulkan/Graphics.Vulkan.hpp +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_GRAPHICS_VULKAN_H -#define NOVELRT_GRAPHICS_VULKAN_H - -// Graphics.Vulkan dependencies -// clang-format off - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// clang-format on - -/** - * @brief The default Vulkan implementation for the Graphics plugin API. - */ -namespace NovelRT::Graphics::Vulkan -{ - struct QueueFamilyIndices; - struct SwapChainSupportDetails; - class VulkanGraphicsDevice; - class VulkanGraphicsPipeline; - class VulkanShaderProgram; - class VulkanGraphicsPipeline; - class VulkanGraphicsPipelineSignature; - class VulkanGraphicsContext; - class VulkanGraphicsFence; - class VulkanGraphicsBuffer; - class VulkanGraphicsTexture; - class VulkanGraphicsPrimitive; - class VulkanGraphicsProvider; - class VulkanGraphicsMemoryAllocator; - class VulkanGraphicsMemoryBlockCollection; - class VulkanGraphicsMemoryBlock; - class VulkanGraphicsAdapter; - class VulkanGraphicsAdapterSelector; - class VulkanGraphicsSurfaceContext; - class VulkanGraphicsPluginProvider; -} - -// Graphics.Vulkan types - -// clang-format off - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// clang-format on - -#endif // NOVELRT_GRAPHICS_VULKAN_H diff --git a/graphics/include/NovelRT/Graphics/Vulkan/Utilities/Graphics.Vulkan.Utilities.hpp b/graphics/include/NovelRT/Graphics/Vulkan/Utilities/Graphics.Vulkan.Utilities.hpp deleted file mode 100644 index 6e37dfe97..000000000 --- a/graphics/include/NovelRT/Graphics/Vulkan/Utilities/Graphics.Vulkan.Utilities.hpp +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_GRAPHICS_VULKAN_UTILITIES_H -#define NOVELRT_GRAPHICS_VULKAN_UTILITIES_H - -#ifndef NOVELRT_GRAPHICS_VULKAN_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.Vulkan.h instead for the Graphics::Vulkan namespace subset. -#endif - -#include -#include -#include -#include -#include - -#endif // !NOVELRT_GRAPHICS_VULKAN_UTILITIES_H diff --git a/graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsAdapterSelector.hpp b/graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsAdapterSelector.hpp deleted file mode 100644 index c86ea64b4..000000000 --- a/graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsAdapterSelector.hpp +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_GRAPHICS_VULKAN_VULKANGRAPHICSADAPTERSELECTOR_H -#define NOVELRT_GRAPHICS_VULKAN_VULKANGRAPHICSADAPTERSELECTOR_H - -#ifndef NOVELRT_GRAPHICS_VULKAN_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.Vulkan.h instead for the Graphics::Vulkan namespace subset. -#endif - -namespace NovelRT::Graphics::Vulkan -{ - class VulkanGraphicsAdapterSelector final : public IGraphicsAdapterSelector - { - private: - [[nodiscard]] int32_t GetPhysicalDeviceOptionalExtensionSupportScore( - VkPhysicalDevice physicalDevice) const noexcept; - - [[nodiscard]] int32_t RateDeviceSuitability(VkPhysicalDevice physicalDevice, - VkSurfaceKHR surfaceContext) const noexcept; - - [[nodiscard]] bool CheckPhysicalDeviceRequiredExtensionSupport(VkPhysicalDevice physicalDevice) const noexcept; - - public: - [[nodiscard]] std::shared_ptr GetDefaultRecommendedAdapter( - const std::shared_ptr& provider, - const std::shared_ptr& surfaceContext) const final; - - [[nodiscard]] std::shared_ptr GetDefaultRecommendedAdapterVulkan( - const std::shared_ptr& provider, - const std::shared_ptr& surfaceContext) const; - - ~VulkanGraphicsAdapterSelector() final = default; - }; -} - -#endif // !NOVELRT_GRAPHICS_VULKAN_VULKANGRAPHICSADAPTERSELECTOR_H diff --git a/graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsBuffer.hpp b/graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsBuffer.hpp deleted file mode 100644 index e1c422b5a..000000000 --- a/graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsBuffer.hpp +++ /dev/null @@ -1,159 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_GRAPHICS_VULKAN_VULKANGRAPHICSBUFFER_H -#define NOVELRT_GRAPHICS_VULKAN_VULKANGRAPHICSBUFFER_H - -#ifndef NOVELRT_GRAPHICS_VULKAN_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.Vulkan.h instead for the Graphics::Vulkan namespace subset. -#endif - -namespace NovelRT::Graphics::Vulkan -{ - class VulkanGraphicsBuffer : public GraphicsBuffer - { - private: - VkBuffer _vulkanBuffer; - - protected: - Threading::VolatileState _state; - [[nodiscard]] VulkanGraphicsDevice* GetDeviceInternal() const noexcept final; - - public: - VulkanGraphicsBuffer(std::shared_ptr device, - GraphicsBufferKind kind, - GraphicsMemoryRegion blockRegion, - GraphicsResourceAccess cpuAccess, - VkBuffer buffer); - - [[nodiscard]] inline std::shared_ptr GetAllocator() const noexcept - { - return std::dynamic_pointer_cast(GraphicsBuffer::GetAllocator()); - } - - [[nodiscard]] inline std::shared_ptr GetBlock() const noexcept - { - return std::dynamic_pointer_cast(GraphicsBuffer::GetBlock()); - } - - [[nodiscard]] inline std::shared_ptr GetDevice() const noexcept - { - return std::dynamic_pointer_cast(GetDeviceInternal()->shared_from_this()); - } - - [[nodiscard]] inline VkBuffer GetVulkanBuffer() const noexcept - { - return _vulkanBuffer; - } - - [[nodiscard]] void* MapUntyped() final; - [[nodiscard]] void* MapUntyped(size_t rangeOffset, size_t rangeLength) final; - [[nodiscard]] const void* MapForReadUntyped() final; - [[nodiscard]] const void* MapForReadUntyped(size_t readRangeOffset, size_t readRangeLength) final; - void Unmap() final; - void UnmapAndWrite() final; - void UnmapAndWrite(size_t writtenRangeOffset, size_t writtenRangeLength) final; - ~VulkanGraphicsBuffer() override; - }; - - template class VulkanGraphicsBufferImpl final : public VulkanGraphicsBuffer - { - private: - NovelRT::Utilities::Lazy _metadata; - - public: - VulkanGraphicsBufferImpl(std::shared_ptr device, - GraphicsBufferKind kind, - GraphicsMemoryRegion blockRegion, - GraphicsResourceAccess cpuAccess, - VkBuffer vulkanBuffer) - : VulkanGraphicsBuffer(std::move(device), kind, std::move(blockRegion), cpuAccess, vulkanBuffer), - _metadata([&]() { - TMetadata metadata(GraphicsDeviceObject::GetDevice()); - GraphicsMemoryRegion blockRegionInternal = GetBlockRegion(); - std::shared_ptr block = blockRegionInternal.GetCollection(); - - size_t minimumAllocatedRegionMarginSize = block->GetMinimumAllocatedRegionMarginSize(); - size_t minimumFreeRegionSizeToRegister = block->GetMinimumFreeRegionSizeToRegister(); - - metadata.Initialise(std::static_pointer_cast(shared_from_this()), - blockRegionInternal.GetSize(), minimumAllocatedRegionMarginSize, - minimumFreeRegionSizeToRegister); - return metadata; - }) - { - static_assert(std::is_base_of_v::IMetadata, TMetadata>); - - static_cast(_state.Transition(Threading::VolatileState::Initialised)); - } - - [[nodiscard]] int32_t GetAllocatedRegionCount() final - { - return _metadata.getActual().GetAllocatedRegionCount(); - } - - [[nodiscard]] size_t GetCount() final - { - return _metadata.getActual().GetCount(); - } - - [[nodiscard]] bool GetIsEmpty() final - { - return _metadata.getActual().GetIsEmpty(); - } - - [[nodiscard]] size_t GetLargestFreeRegionSize() final - { - return _metadata.getActual().GetLargestFreeRegionSize(); - } - - [[nodiscard]] size_t GetMinimumAllocatedRegionMarginSize() final - { - return _metadata.getActual().GetMinimumAllocatedRegionMarginSize(); - } - - [[nodiscard]] size_t GetMinimumFreeRegionSizeToRegister() final - { - return _metadata.getActual().GetMinimumFreeRegionSizeToRegister(); - } - - [[nodiscard]] size_t GetTotalFreeRegionSize() final - { - return _metadata.getActual().GetTotalFreeRegionSize(); - } - - GraphicsMemoryRegion Allocate(size_t size, size_t alignment) final - { - return _metadata.getActual().Allocate(size, alignment); - } - - void Clear() final - { - _metadata.getActual().Clear(); - } - - void Free(const GraphicsMemoryRegion& region) final - { - _metadata.getActual().Free(region); - } - - bool TryAllocate(size_t size, size_t alignment, GraphicsMemoryRegion& outRegion) final - { - return _metadata.getActual().TryAllocate(size, alignment, outRegion); - } - - [[nodiscard]] std::list>::iterator begin() final - { - return _metadata.getActual().begin(); - } - - [[nodiscard]] std::list>::iterator end() override - { - return _metadata.getActual().end(); - } - - ~VulkanGraphicsBufferImpl() final = default; - }; -} - -#endif // !NOVELRT_GRAPHICS_VULKAN_VULKANGRAPHICSBUFFER_H diff --git a/graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsMemoryAllocator.hpp b/graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsMemoryAllocator.hpp deleted file mode 100644 index 4661a9a7d..000000000 --- a/graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsMemoryAllocator.hpp +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_GRAPHICS_VULKAN_VULKANGRAPHICSMEMORYALLOCATOR_H -#define NOVELRT_GRAPHICS_VULKAN_VULKANGRAPHICSMEMORYALLOCATOR_H - -#ifndef NOVELRT_GRAPHICS_VULKAN_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.Vulkan.h instead for the Graphics::Vulkan namespace subset. -#endif - -namespace NovelRT::Graphics::Vulkan -{ - class VulkanGraphicsMemoryAllocator final - : public GraphicsMemoryAllocatorImpl::DefaultMetadata> - { - private: - NovelRT::Utilities::Lazy>> _blockCollections; - Threading::VolatileState _state; - - [[nodiscard]] size_t GetBlockCollectionIndex(GraphicsResourceAccess cpuAccess, uint32_t memoryTypeBits); - - public: - VulkanGraphicsMemoryAllocator(std::shared_ptr device, - GraphicsMemoryAllocatorSettings settings); - - [[nodiscard]] inline size_t GetCount() final - { - return _blockCollections.getActual().size(); - } - - [[nodiscard]] inline std::shared_ptr GetDevice() const noexcept - { - return std::dynamic_pointer_cast(GraphicsDeviceObject::GetDevice()); - } - - std::shared_ptr CreateBuffer(GraphicsBufferKind bufferKind, - GraphicsResourceAccess cpuAccessKind, - GraphicsResourceAccess gpuAccessKind, - size_t size, - GraphicsMemoryRegionAllocationFlags allocationFlags) final; - - [[nodiscard]] std::shared_ptr CreateTexture( - GraphicsTextureAddressMode addressMode, - GraphicsTextureKind textureKind, - GraphicsResourceAccess cpuAccessKind, - GraphicsResourceAccess gpuAccessKind, - uint32_t width, - uint32_t height, - uint32_t depth, - GraphicsMemoryRegionAllocationFlags allocationFlags, - TexelFormat texelFormat) final; - - [[nodiscard]] inline GraphicsMemoryBudget GetBudget( - std::shared_ptr /*collection*/) - { - return GraphicsMemoryBudget(std::numeric_limits::max(), 0, 0, 0); - } - - [[nodiscard]] inline GraphicsMemoryBudget GetBudget( - std::shared_ptr blockCollection) final - { - return GetBudget(std::dynamic_pointer_cast(blockCollection)); - } - - [[nodiscard]] std::vector>::iterator begin() final; - [[nodiscard]] std::vector>::iterator end() final; - - ~VulkanGraphicsMemoryAllocator() final = default; - }; -} - -#endif // NOVELRT_GRAPHICS_VULKAN_VULKANGRAPHICSMEMORYALLOCATOR_H diff --git a/graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsMemoryBlock.hpp b/graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsMemoryBlock.hpp deleted file mode 100644 index 95794fbc1..000000000 --- a/graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsMemoryBlock.hpp +++ /dev/null @@ -1,151 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_GRAPHICS_VULKAN_VULKANGRAPHICSMEMORYBLOCK_H -#define NOVELRT_GRAPHICS_VULKAN_VULKANGRAPHICSMEMORYBLOCK_H - -#ifndef NOVELRT_GRAPHICS_VULKAN_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.Vulkan.h instead for the Graphics::Vulkan namespace subset. -#endif - -namespace NovelRT::Graphics::Vulkan -{ - class VulkanGraphicsMemoryBlock : public GraphicsMemoryBlock - { - private: - NovelRT::Utilities::Lazy _vulkanDeviceMemory; - - VkDeviceMemory CreateVulkanDeviceMemory(); - void DisposeVulkanDeviceMemory() noexcept; - - protected: - Threading::VolatileState _state; - - VulkanGraphicsDevice* GetDeviceInternal() const noexcept final; - - public: - VulkanGraphicsMemoryBlock(const std::shared_ptr& device, - const std::shared_ptr& collection); - - ~VulkanGraphicsMemoryBlock() override; - - [[nodiscard]] inline std::shared_ptr GetCollection() - { - return std::static_pointer_cast(GraphicsMemoryBlock::GetCollection()); - } - - [[nodiscard]] inline std::shared_ptr GetDevice() - { - return std::dynamic_pointer_cast(GetDeviceInternal()->shared_from_this()); - } - - [[nodiscard]] inline VkDeviceMemory GetVulkanDeviceMemory() - { - return _vulkanDeviceMemory.getActual(); - } - }; - - template class VulkanGraphicsMemoryBlockImpl final : public VulkanGraphicsMemoryBlock - { - private: - NovelRT::Utilities::Lazy _metadata; - - public: - VulkanGraphicsMemoryBlockImpl(std::shared_ptr device, - std::shared_ptr collection, - size_t size) - : VulkanGraphicsMemoryBlock(std::move(device), std::move(collection)), _metadata([&, size]() { - TMetadata metadata(GetDevice()); - const GraphicsMemoryAllocatorSettings& allocatorSettings = - GetCollection()->GetAllocator()->GetSettings(); - - size_t minimumAllocatedRegionSize = allocatorSettings.MinimumAllocatedRegionMarginSize.value_or(0); - size_t minimumFreeRegionSizeToRegister = allocatorSettings.MinimumFreeRegionSizeToRegister; - metadata.Initialise(std::static_pointer_cast(shared_from_this()), size, - minimumAllocatedRegionSize, minimumFreeRegionSizeToRegister); - return metadata; - }) - { - static_assert( - std::is_base_of_v::IMetadata, TMetadata>); - - static_cast(_state.Transition(Threading::VolatileState::Initialised)); - } - - [[nodiscard]] int32_t GetAllocatedRegionCount() final - { - return _metadata.getActual().GetAllocatedRegionCount(); - } - - [[nodiscard]] size_t GetCount() - { - return _metadata.getActual().GetCount(); - } - - [[nodiscard]] bool GetIsEmpty() final - { - return _metadata.getActual().GetIsEmpty(); - } - - [[nodiscard]] size_t GetLargestFreeRegionSize() final - { - return _metadata.getActual().GetLargestFreeRegionSize(); - } - - [[nodiscard]] size_t GetMinimumAllocatedRegionMarginSize() final - { - return _metadata.getActual().GetMinimumAllocatedRegionMarginSize(); - } - - [[nodiscard]] size_t GetMinimumFreeRegionSizeToRegister() final - { - return _metadata.getActual().GetMinimumFreeRegionSizeToRegister(); - } - - [[nodiscard]] size_t GetSize() final - { - return _metadata.getActual().GetSize(); - } - - [[nodiscard]] size_t GetTotalFreeRegionSize() final - { - return _metadata.getActual().GetTotalFreeRegionSize(); - } - - GraphicsMemoryRegion Allocate(size_t size, size_t alignment) final - { - return _metadata.getActual().Allocate(size, alignment); - } - - void Clear() final - { - _metadata.getActual().Clear(); - } - - void Free(const GraphicsMemoryRegion& region) final - { - _metadata.getActual().Free(region); - } - - [[nodiscard]] bool TryAllocate(size_t size, - size_t alignment, - GraphicsMemoryRegion& outRegion) final - { - return _metadata.getActual().TryAllocate(size, alignment, outRegion); - } - - [[nodiscard]] std::list>::iterator begin() final - { - return _metadata.getActual().begin(); - } - - [[nodiscard]] std::list>::iterator end() final - { - return _metadata.getActual().end(); - } - - ~VulkanGraphicsMemoryBlockImpl() final = default; - }; -} - -#endif // NOVELRT_GRAPHICS_VULKAN_VULKANGRAPHICSMEMORYBLOCK_H diff --git a/graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsMemoryBlockCollection.hpp b/graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsMemoryBlockCollection.hpp deleted file mode 100644 index ed411ad5b..000000000 --- a/graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsMemoryBlockCollection.hpp +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_GRAPHICS_VULKAN_VULKANGRAPHICSMEMORYBLOCKCOLLECTION_H -#define NOVELRT_GRAPHICS_VULKAN_VULKANGRAPHICSMEMORYBLOCKCOLLECTION_H - -#ifndef NOVELRT_GRAPHICS_VULKAN_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.Vulkan.h instead for the Graphics::Vulkan namespace subset. -#endif - -namespace NovelRT::Graphics::Vulkan -{ - class VulkanGraphicsMemoryBlockCollection final : public GraphicsMemoryBlockCollection - { - private: - uint32_t _vulkanMemoryTypeIndex; - - protected: - VulkanGraphicsMemoryBlock* CreateBlock(size_t size) final; - - public: - VulkanGraphicsMemoryBlockCollection(std::shared_ptr device, - std::shared_ptr allocator, - uint32_t memoryTypeIndex); - - [[nodiscard]] inline std::shared_ptr GetAllocator() const noexcept - { - return std::dynamic_pointer_cast( - GraphicsMemoryBlockCollection::GetAllocator()); - } - - [[nodiscard]] inline std::shared_ptr GetDevice() const noexcept - { - return std::dynamic_pointer_cast(GraphicsMemoryBlockCollection::GetDevice()); - } - - [[nodiscard]] inline uint32_t GetVulkanMemoryTypeIndex() const noexcept - { - return _vulkanMemoryTypeIndex; - } - - ~VulkanGraphicsMemoryBlockCollection() final = default; - }; -} - -#endif // NOVELRT_GRAPHICS_VULKAN_VULKANGRAPHICSMEMORYBLOCKCOLLECTION_H diff --git a/graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsPluginProvider.hpp b/graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsPluginProvider.hpp deleted file mode 100644 index 00e26a548..000000000 --- a/graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsPluginProvider.hpp +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_GRAPHICS_VULKAN_VULKANGRAPHICSPLUGINPROVIDER_H -#define NOVELRT_GRAPHICS_VULKAN_VULKANGRAPHICSPLUGINPROVIDER_H - -namespace NovelRT::Graphics::Vulkan -{ - class VulkanGraphicsPluginProvider final : public PluginManagement::IGraphicsPluginProvider - { - protected: - NovelRT::Utilities::Lazy> _graphicsProvider; - - [[nodiscard]] std::shared_ptr CreateVulkanGraphicsProviderInternal(); - - [[nodiscard]] VulkanGraphicsProvider* GetGraphicsProviderInternal() override; - - public: - VulkanGraphicsPluginProvider() noexcept; - ~VulkanGraphicsPluginProvider() final = default; - - [[nodiscard]] std::shared_ptr GetDefaultSelectedGraphicsAdapterForContext( - std::shared_ptr context) override; - - [[nodiscard]] std::shared_ptr GetDefaultSelectedGraphicsAdapterForContextVulkan( - std::shared_ptr context); - - [[nodiscard]] inline std::shared_ptr GetGraphicsProvider() - { - return std::dynamic_pointer_cast(GetGraphicsProviderInternal()->shared_from_this()); - } - - [[nodiscard]] std::shared_ptr CreateSurfaceContext( - std::shared_ptr surface) override; - - [[nodiscard]] std::shared_ptr CreateSurfaceContextVulkan( - std::shared_ptr surface); - }; -} - -#endif // NOVELRT_GRAPHICS_VULKAN_VULKANGRAPHICSPLUGINPROVIDER_H diff --git a/graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsPrimitive.hpp b/graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsPrimitive.hpp deleted file mode 100644 index 53623e603..000000000 --- a/graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsPrimitive.hpp +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_GRAPHICS_VULKAN_VULKANGRAPHICSPRIMITIVE_H -#define NOVELRT_GRAPHICS_VULKAN_VULKANGRAPHICSPRIMITIVE_H - -#ifndef NOVELRT_GRAPHICS_VULKAN_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.Vulkan.h instead for the Graphics::Vulkan namespace subset. -#endif - -namespace NovelRT::Graphics::Vulkan -{ - class VulkanGraphicsPrimitive final : public GraphicsPrimitive - { - private: - Threading::VolatileState _state; - - public: - VulkanGraphicsPrimitive( - std::shared_ptr device, - std::shared_ptr pipeline, - GraphicsMemoryRegion vertexBufferView, - uint32_t vertexBufferStride, - GraphicsMemoryRegion indexBufferView, - uint32_t indexBufferStride, - NovelRT::Utilities::Misc::Span> inputResourceRegions = {}) - : GraphicsPrimitive(std::move(device), - std::move(pipeline), - std::move(vertexBufferView), - vertexBufferStride, - std::move(indexBufferView), - indexBufferStride, - inputResourceRegions), - _state() - { - static_cast(_state.Transition(Threading::VolatileState::Initialised)); - } - - [[nodiscard]] inline std::shared_ptr GetDevice() const - { - return std::dynamic_pointer_cast(GraphicsPrimitive::GetDevice()); - } - - [[nodiscard]] inline std::shared_ptr GetPipeline() const noexcept - { - return std::dynamic_pointer_cast(GraphicsPrimitive::GetPipeline()); - } - - ~VulkanGraphicsPrimitive() final = default; - }; -} - -#endif // NOVELRT_GRAPHICS_VULKAN_VULKANGRAPHICSPRIMITIVE_H diff --git a/graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsSurfaceContext.hpp b/graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsSurfaceContext.hpp deleted file mode 100644 index 2ac6fe9dd..000000000 --- a/graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsSurfaceContext.hpp +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_GRAPHICS_VULKAN_VULKANGRAPHICSSURFACECONTEXT_H -#define NOVELRT_GRAPHICS_VULKAN_VULKANGRAPHICSSURFACECONTEXT_H - -#ifndef NOVELRT_GRAPHICS_VULKAN_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.Vulkan.h instead for the Graphics::Vulkan namespace subset. -#endif - -namespace NovelRT::Graphics::Vulkan -{ - class VulkanGraphicsSurfaceContext final : public GraphicsSurfaceContext - { - private: - LoggingService _logger; - VkSurfaceKHR _vulkanSurface; - - public: - VulkanGraphicsSurfaceContext(std::shared_ptr surface, - const std::shared_ptr& provider); - - [[nodiscard]] inline void* GetSurfaceContextHandleUntyped() final - { - return &_vulkanSurface; - } - - [[nodiscard]] inline VkSurfaceKHR GetVulkanSurfaceContextHandle() const noexcept - { - return _vulkanSurface; - } - - [[nodiscard]] inline std::shared_ptr GetProvider() const noexcept - { - return std::dynamic_pointer_cast(GraphicsSurfaceContext::GetProvider()); - } - - ~VulkanGraphicsSurfaceContext() final; - }; -} - -#endif // !NOVELRT_GRAPHICS_VULKAN_VULKANGRAPHICSSURFACECONTEXT_H diff --git a/graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsTexture.hpp b/graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsTexture.hpp deleted file mode 100644 index 68042b839..000000000 --- a/graphics/include/NovelRT/Graphics/Vulkan/VulkanGraphicsTexture.hpp +++ /dev/null @@ -1,197 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_GRAPHICS_VULKAN_VULKANGRAPHICSTEXTURE_H -#define NOVELRT_GRAPHICS_VULKAN_VULKANGRAPHICSTEXTURE_H - -#ifndef NOVELRT_GRAPHICS_VULKAN_H -#error NovelRT does not support including types explicitly by default. Please include Graphics.Vulkan.h instead for the Graphics::Vulkan namespace subset. -#endif - -namespace NovelRT::Graphics::Vulkan -{ - class VulkanGraphicsTexture : public GraphicsTexture - { - private: - // TODO: These don't seem to be used anywhere? why? What is the point of these? - static inline const int32_t Binding = 2; - static inline const int32_t Bound = 3; - - VkImage _vulkanImage; - - NovelRT::Utilities::Lazy _vulkanImageView; - NovelRT::Utilities::Lazy _vulkanSampler; - - [[nodiscard]] VkImageView CreateVulkanImageView(); - [[nodiscard]] VkSampler CreateVulkanSampler(); - void DisposeVulkanImage() noexcept; - void DisposeVulkanImageView() noexcept; - void DisposeVulkanSampler() noexcept; - - protected: - Threading::VolatileState _state; - [[nodiscard]] VulkanGraphicsDevice* GetDeviceInternal() const noexcept final; - - public: - VulkanGraphicsTexture(std::shared_ptr device, - GraphicsTextureAddressMode addressMode, - GraphicsTextureKind kind, - GraphicsMemoryRegion blockRegion, - GraphicsResourceAccess cpuAccess, - uint32_t width, - uint32_t height, - uint16_t depth, - VkImage vulkanImage); - - [[nodiscard]] inline std::shared_ptr GetAllocator() const noexcept - { - return std::dynamic_pointer_cast(GraphicsTexture::GetAllocator()); - } - - [[nodiscard]] inline VkImage GetVulkanImage() const noexcept - { - return _vulkanImage; - } - - [[nodiscard]] inline VkImageView GetVulkanImageView() - { - return _vulkanImageView.getActual(); - } - - [[nodiscard]] inline VkSampler GetVulkanSampler() - { - return _vulkanSampler.getActual(); - } - - [[nodiscard]] inline std::shared_ptr GetBlock() const noexcept - { - return std::dynamic_pointer_cast(GraphicsTexture::GetBlock()); - } - - [[nodiscard]] void* MapUntyped() final; - [[nodiscard]] void* MapUntyped(size_t rangeOffset, size_t rangeLength) final; - [[nodiscard]] const void* MapForReadUntyped() final; - [[nodiscard]] const void* MapForReadUntyped(size_t readRangeOffset, size_t readRangeLength) final; - void Unmap() final; - void UnmapAndWrite() final; - void UnmapAndWrite(size_t writtenRangeOffset, size_t writtenRangeLength) final; - - ~VulkanGraphicsTexture() override; - }; - - template class VulkanGraphicsTextureImpl final : public VulkanGraphicsTexture - { - private: - NovelRT::Utilities::Lazy _metadata; - - public: - VulkanGraphicsTextureImpl(std::shared_ptr device, - GraphicsTextureAddressMode addressMode, - GraphicsTextureKind kind, - GraphicsMemoryRegion blockRegion, - GraphicsResourceAccess cpuAccess, - uint32_t width, - uint32_t height, - uint16_t depth, - VkImage vulkanImage) - : VulkanGraphicsTexture(std::move(device), - addressMode, - kind, - std::move(blockRegion), - cpuAccess, - width, - height, - depth, - vulkanImage), - _metadata([&]() { - TMetadata metadata(GraphicsDeviceObject::GetDevice()); - GraphicsMemoryRegion blockRegionInternal = GetBlockRegion(); - std::shared_ptr block = blockRegionInternal.GetCollection(); - - size_t minimumAllocatedRegionMarginSize = block->GetMinimumAllocatedRegionMarginSize(); - size_t minimumFreeRegionSizeToRegister = block->GetMinimumFreeRegionSizeToRegister(); - - metadata.Initialise( - std::static_pointer_cast>(shared_from_this()), - blockRegionInternal.GetSize(), minimumAllocatedRegionMarginSize, minimumFreeRegionSizeToRegister); - - return metadata; - }) - { - static_assert(std::is_base_of_v::IMetadata, TMetadata>); - - static_cast(_state.Transition(Threading::VolatileState::Initialised)); - } - - [[nodiscard]] int32_t GetAllocatedRegionCount() final - { - return _metadata.getActual().GetAllocatedRegionCount(); - } - - [[nodiscard]] size_t GetCount() final - { - return _metadata.getActual().GetCount(); - } - - [[nodiscard]] bool GetIsEmpty() final - { - return _metadata.getActual().GetIsEmpty(); - } - - [[nodiscard]] size_t GetLargestFreeRegionSize() final - { - return _metadata.getActual().GetLargestFreeRegionSize(); - } - - [[nodiscard]] size_t GetMinimumAllocatedRegionMarginSize() final - { - return _metadata.getActual().GetMinimumAllocatedRegionMarginSize(); - } - - [[nodiscard]] size_t GetMinimumFreeRegionSizeToRegister() final - { - return _metadata.getActual().GetMinimumFreeRegionSizeToRegister(); - } - - [[nodiscard]] size_t GetTotalFreeRegionSize() final - { - return _metadata.getActual().GetTotalFreeRegionSize(); - } - - GraphicsMemoryRegion Allocate(size_t size, size_t alignment) final - { - return _metadata.getActual().Allocate(size, alignment); - } - - void Clear() final - { - _metadata.getActual().Clear(); - } - - void Free(const GraphicsMemoryRegion& region) final - { - _metadata.getActual().Free(region); - } - - [[nodiscard]] bool TryAllocate(size_t size, - size_t alignment, - GraphicsMemoryRegion& outRegion) final - { - return _metadata.getActual().TryAllocate(size, alignment, outRegion); - } - - [[nodiscard]] std::list>::iterator begin() final - { - return _metadata.getActual().begin(); - } - - [[nodiscard]] std::list>::iterator end() final - { - return _metadata.getActual().end(); - } - - ~VulkanGraphicsTextureImpl() final = default; - }; -} - -#endif // !NOVELRT_GRAPHICS_VULKAN_VULKANGRAPHICSTEXTURE_H diff --git a/include/NovelRT/Ecs/Configurator.h b/include/NovelRT/Ecs/Configurator.h index 9d86501bb..b7d0e7497 100644 --- a/include/NovelRT/Ecs/Configurator.h +++ b/include/NovelRT/Ecs/Configurator.h @@ -4,15 +4,12 @@ #ifndef NOVELRT_ECS_CONFIGURATOR_H #define NOVELRT_ECS_CONFIGURATOR_H -#ifndef NOVELRT_ECS_H -#error NovelRT does not support including types explicitly by default. Please include Ecs.h instead for the Ecs namespace subset. -#endif - namespace NovelRT::Ecs { /** * @brief A convenience type to help with the creation of an ECS instance. */ + template class Configurator { private: @@ -20,16 +17,13 @@ namespace NovelRT::Ecs std::optional _threadCount; std::vector> _systems; std::vector> _iecsSystems; - std::shared_ptr _graphicsPluginProvider; + std::shared_ptr> _graphicsPluginProvider; std::shared_ptr _windowingPluginProvider; std::shared_ptr _resourceManagementPluginProvider; std::shared_ptr _inputPluginProvider; inline void AddDefaultComponentsAndSystems(SystemScheduler& target) { - target.GetComponentCache().RegisterComponentType(Graphics::RenderComponent{0, 0, 0, 0, true}, - "NovelRT::Ecs::Graphics::RenderComponent"); - target.GetComponentCache().RegisterComponentType( EntityGraphComponent{false, std::numeric_limits::max(), std::numeric_limits::max()}, "NovelRT::Ecs::EntityGraphComponent"); @@ -43,9 +37,6 @@ namespace NovelRT::Ecs TransformComponent{Maths::GeoVector3F::Uniform(NAN), Maths::GeoVector2F::Uniform(NAN), NAN}, "NovelRT::Ecs::TransformComponent"); - target.RegisterSystem(std::make_shared( - _graphicsPluginProvider, _windowingPluginProvider, _resourceManagementPluginProvider)); - target.GetComponentCache().RegisterComponentType( Input::InputEventComponent{0, NovelRT::Input::KeyState::Idle, 0, 0}, "NovelRT::Ecs::Input::InputEventComponent"); @@ -146,25 +137,9 @@ namespace NovelRT::Ecs * @exception Exceptions::NotSupportedException if the plugin provider type is currently not used or supported * by default systems. */ - template - [[nodiscard]] Configurator& WithPluginProvider(std::shared_ptr /*pluginInstance*/) - { - throw Exceptions::NotSupportedException( - "This plugin provider type is invalid or not supported at this time."); - } - - /** - * @brief Specifies a plugin provider object to use for creating the default systems. - * - * @tparam TPluginProvider The type of PluginProvider interface this provider implements. - * @return A reference to this to allow method chaining. - * - * @exception Exceptions::NotSupportedException if the plugin provider type is currently not used or supported - * by default systems. - */ - template<> - [[nodiscard]] Configurator& WithPluginProvider( - std::shared_ptr pluginInstance) + template + [[nodiscard]] Configurator WithPluginProvider( + std::shared_ptr> pluginInstance) { _graphicsPluginProvider = std::move(pluginInstance); return *this; @@ -179,8 +154,7 @@ namespace NovelRT::Ecs * @exception Exceptions::NotSupportedException if the plugin provider type is currently not used or supported * by default systems. */ - template<> - [[nodiscard]] Configurator& WithPluginProvider( + [[nodiscard]] Configurator& WithPluginProvider( std::shared_ptr pluginInstance) { _windowingPluginProvider = std::move(pluginInstance); @@ -196,8 +170,7 @@ namespace NovelRT::Ecs * @exception Exceptions::NotSupportedException if the plugin provider type is currently not used or supported * by default systems. */ - template<> - [[nodiscard]] Configurator& WithPluginProvider( + [[nodiscard]] Configurator& WithPluginProvider( std::shared_ptr pluginInstance) { _resourceManagementPluginProvider = std::move(pluginInstance); @@ -213,8 +186,7 @@ namespace NovelRT::Ecs * @exception Exceptions::NotSupportedException if the plugin provider type is currently not used or supported * by default systems. */ - template<> - [[nodiscard]] Configurator& WithPluginProvider( + [[nodiscard]] Configurator& WithPluginProvider( std::shared_ptr pluginInstance) { _inputPluginProvider = std::move(pluginInstance); @@ -266,7 +238,7 @@ namespace NovelRT::Ecs * * @returns An instance of the ECS SystemScheduler based on the provided configuration. */ - template<>[[nodiscard]] SystemScheduler InitialiseAndRegisterComponents() + [[nodiscard]] SystemScheduler InitialiseAndRegisterComponents() { SystemScheduler scheduler(_threadCount.value_or(0)); diff --git a/include/NovelRT/Ecs/Ecs.h b/include/NovelRT/Ecs/Ecs.h index dce79d63d..b16f55916 100644 --- a/include/NovelRT/Ecs/Ecs.h +++ b/include/NovelRT/Ecs/Ecs.h @@ -49,6 +49,7 @@ */ namespace NovelRT::Ecs { + template class Configurator; class Catalogue; class ComponentBufferMemoryContainer; @@ -82,7 +83,6 @@ namespace NovelRT::Ecs #include "SystemScheduler.h" #include "UnsafeComponentView.h" #include "Audio/Ecs.Audio.h" -#include "Graphics/Ecs.Graphics.h" #include "Input/Ecs.Input.h" #include "Narrative/Ecs.Narrative.h" #include "Configurator.h" diff --git a/include/NovelRT/Ecs/Graphics/AttachRenderToExistingEntityRequestInfo.h b/include/NovelRT/Ecs/Graphics/AttachRenderToExistingEntityRequestInfo.h deleted file mode 100644 index 4664d280d..000000000 --- a/include/NovelRT/Ecs/Graphics/AttachRenderToExistingEntityRequestInfo.h +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_ATTACHRENDERTOEXISTINGENTITYREQUESTINFO_H -#define NOVELRT_ATTACHRENDERTOEXISTINGENTITYREQUESTINFO_H - -#ifndef NOVELRT_ECS_H -#error NovelRT does not support including types explicitly by default. Please include Ecs.h instead for the Ecs namespace subset. -#endif - -namespace NovelRT::Ecs::Graphics -{ - struct AttachRenderToExistingEntityRequestInfo - { - EntityId entityId = 0; - Threading::ConcurrentSharedPtr texturePtr = nullptr; - Threading::ConcurrentSharedPtr meshPtr = nullptr; - Threading::ConcurrentSharedPtr pipelinePtr = nullptr; - }; -} - -#endif // NOVELRT_ATTACHRENDERTOEXISTINGENTITYREQUESTINFO_H diff --git a/include/NovelRT/Ecs/Graphics/ConstantBufferInfo.h b/include/NovelRT/Ecs/Graphics/ConstantBufferInfo.h deleted file mode 100644 index 8ef06870a..000000000 --- a/include/NovelRT/Ecs/Graphics/ConstantBufferInfo.h +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_CONSTANTBUFFERINFO_H -#define NOVELRT_CONSTANTBUFFERINFO_H - -#ifndef NOVELRT_ECS_H -#error NovelRT does not support including types explicitly by default. Please include Ecs.h instead for the Ecs namespace subset. -#endif - -namespace NovelRT::Ecs::Graphics -{ - struct ConstantBufferInfo - { - NovelRT::Graphics::GraphicsMemoryRegion gpuConstantBufferRegion = {}; - }; -} - -#endif // NOVELRT_CONSTANTBUFFERINFO_H diff --git a/include/NovelRT/Ecs/Graphics/CreateRenderEntityRequestInfo.h b/include/NovelRT/Ecs/Graphics/CreateRenderEntityRequestInfo.h deleted file mode 100644 index 0cc2fd1f2..000000000 --- a/include/NovelRT/Ecs/Graphics/CreateRenderEntityRequestInfo.h +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_CREATERENDERENTITYREQUESTINFO_H -#define NOVELRT_CREATERENDERENTITYREQUESTINFO_H - -#ifndef NOVELRT_ECS_H -#error NovelRT does not support including types explicitly by default. Please include Ecs.h instead for the Ecs namespace subset. -#endif - -namespace NovelRT::Ecs::Graphics -{ - struct CreateRenderEntityRequestInfo - { - Threading::ConcurrentSharedPtr entityId = nullptr; - Threading::ConcurrentSharedPtr texturePtr = nullptr; - Threading::ConcurrentSharedPtr meshPtr = nullptr; - Threading::ConcurrentSharedPtr pipelinePtr = nullptr; - }; -} - -#endif // NOVELRT_CREATERENDERENTITYREQUESTINFO_H diff --git a/include/NovelRT/Ecs/Graphics/DefaultRenderingComponentTypes.h b/include/NovelRT/Ecs/Graphics/DefaultRenderingComponentTypes.h deleted file mode 100644 index 8c9657393..000000000 --- a/include/NovelRT/Ecs/Graphics/DefaultRenderingComponentTypes.h +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_ECS_GRAPHICS_ECSDEFAULTRENDERINGCOMPONENTTYPES_H -#define NOVELRT_ECS_GRAPHICS_ECSDEFAULTRENDERINGCOMPONENTTYPES_H - -#ifndef NOVELRT_ECS_H -#error NovelRT does not support including types explicitly by default. Please include Ecs.h instead for the Ecs namespace subset. -#endif - -namespace NovelRT::Ecs::Graphics -{ - using BindingIndex = uint32_t; - - struct RenderComponent - { - Atom vertexDataId = 0; - Atom textureId = 0; - Atom pipelineId = 0; - Atom primitiveInfoId = 0; - bool requiresCustomRendering = false; - bool markedForDeletion = false; - - inline RenderComponent& operator+=(const RenderComponent& other) - { - vertexDataId = other.vertexDataId; - textureId = other.textureId; - pipelineId = other.pipelineId; - primitiveInfoId = other.primitiveInfoId; - markedForDeletion = other.markedForDeletion; - return *this; - } - - inline bool operator==(const RenderComponent& other) const noexcept - { - return ((vertexDataId == other.vertexDataId) && (textureId == other.textureId) && - (pipelineId == other.pipelineId)) && - (markedForDeletion == other.markedForDeletion); - } - - inline bool operator!=(const RenderComponent& other) const noexcept - { - return !(*this == other); - } - }; - - // TODO: I don't know how to use these given how GraphicsPrimitive currently works quite yet. - /* - struct RGBAColourShaderDescriptorComponent - { - NovelRT::Graphics::RGBAColour value = NovelRT::Graphics::RGBAColour(0, 0, 0, 0); - }; - - struct BoolShaderDescriptorComponent - { - bool value = false; - }; - - struct IntShaderDescriptorComponent - { - int32_t value = 0; - }; - - struct UIntShaderDescriptorComponent - { - uint32_t value = 0; - }; - - struct FloatShaderDescriptorComponent - { - float value = 0.0f; - }; - - struct DoubleShaderDescriptorComponent - { - double value = 0.0f; - }; - - struct Vector2FShaderDescriptorComponent - { - Maths::GeoVector2F value = Maths::GeoVector2F::zero(); - }; - - struct Vector3FShaderDescriptorComponent - { - Maths::GeoVector3F value = Maths::GeoVector2F::zero(); - }; - - struct Vector4FShaderDescriptorComponent - { - Maths::GeoVector4F value = Maths::GeoVector2F::zero(); - }; - - struct GeoMatrix4x4FShaderDescriptorComponent - { - Maths::GeoMatrix4x4F value = Maths::GeoMatrix4x4F::getDefaultIdentity(); - }; - */ - -} - -#endif // !NOVELRT_ECS_GRAPHICS_ECSDEFAULTRENDERINGCOMPONENTTYPES_H diff --git a/include/NovelRT/Ecs/Graphics/DefaultRenderingSystem.h b/include/NovelRT/Ecs/Graphics/DefaultRenderingSystem.h deleted file mode 100644 index 53d40fcae..000000000 --- a/include/NovelRT/Ecs/Graphics/DefaultRenderingSystem.h +++ /dev/null @@ -1,222 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_ECS_GRAPHICS_DEFAULTRENDERINGSYSTEM_H -#define NOVELRT_ECS_GRAPHICS_DEFAULTRENDERINGSYSTEM_H - -#ifndef NOVELRT_ECS_H -#error NovelRT does not support including types explicitly by default. Please include Ecs.h instead for the Ecs namespace subset. -#endif - -namespace NovelRT::Ecs::Graphics -{ - struct TexturedVertex - { - NovelRT::Maths::GeoVector3F Position; - NovelRT::Maths::GeoVector2F UV; - }; - - class DefaultRenderingSystem : public IEcsSystem - { - private: - inline static AtomFactory& _textureIdFactory = AtomFactoryDatabase::GetFactory("TextureId"); - inline static AtomFactory& _ecsPrimitiveInfoConfigurationIdFactory = - AtomFactoryDatabase::GetFactory("EcsPrimitiveInfoConfigurationId"); - - Utilities::Lazy _resourceManager; - std::shared_ptr _graphicsPluginProvider; - std::shared_ptr _windowingPluginProvider; - std::shared_ptr _resourceManagementPluginProvider; - std::shared_ptr _surfaceContext; - std::shared_ptr _graphicsAdapter; - std::shared_ptr _graphicsDevice; - std::shared_ptr _windowingDevice; - - NovelRT::Graphics::GraphicsMemoryRegion _frameMatrixConstantBufferRegion; - - tbb::mutex _textureQueueMapMutex; - std::map> _namedTextureInfoObjects; - std::queue> _texturesToInitialise; - std::queue _texturesToDelete; - - tbb::mutex _vertexQueueMapMutex; - std::map> _namedVertexInfoObjects; - std::queue> _vertexDataToInitialise; - std::queue _vertexDataToDelete; - - Threading::ConcurrentSharedPtr _defaultSpriteMeshPtr; - - tbb::mutex _graphicsPipelineMapMutex; - std::map> _namedGraphicsPipelineInfoObjects; - - Threading::ConcurrentSharedPtr _defaultGraphicsPipelinePtr; - - std::map _primitiveConfigurations; - - SceneGraph::Scene _renderScene; - - NovelRT::Graphics::RGBAColour _backgroundColour; - - void ResolveGpuResourceCleanup(); - void ResolveVertexInfoGpuCleanup(); - void ResolveTextureInfoGpuCleanup(); - - void ResolveGpuFutures(); - void ResolveVertexInfoFutureResults(); - void ResolveTextureFutureResults(); - - public: - struct UIRenderEventArgs - { - Timing::Timestamp delta; - Catalogue& catalogue; - std::shared_ptr graphicsSurfaceContext; - std::shared_ptr graphicsAdapter; - std::shared_ptr graphicsDevice; - std::shared_ptr graphicsContext; - NovelRT::Graphics::GraphicsResourceManager& resourceManager; - NovelRT::Graphics::GraphicsMemoryRegion - frameMatrixConstantBufferRegion; - }; - - Utilities::Event, UIRenderEventArgs> UIRenderEvent; - - DefaultRenderingSystem( - std::shared_ptr graphicsPluginProvider, - std::shared_ptr windowingPluginProvider, - std::shared_ptr resourceManagementPluginProvider); - - void Update(Timing::Timestamp delta, Catalogue catalogue) final; - - [[nodiscard]] Threading::FutureResult GetOrLoadTexture(const std::string& spriteName); - - template - [[nodiscard]] Threading::FutureResult LoadTextureDataRaw( - const std::string& textureDataName, - NovelRT::Utilities::Misc::Span textureDataSpan, - uint32_t width, - uint32_t height, - uuids::uuid textureAssetDataHandle) - { - static_assert(std::is_trivially_copyable_v && - "The specified vertex struct must be trivially copyable."); - - return LoadTextureDataRawUntyped(textureDataName, textureDataSpan.data(), sizeof(TSpanType), - textureDataSpan.size(), width, height, textureAssetDataHandle); - } - - [[nodiscard]] Threading::FutureResult LoadTextureDataRawUntyped( - const std::string& textureDataName, - void* data, - size_t dataTypeSize, - size_t dataLength, - uint32_t width, - uint32_t height, - uuids::uuid textureAssetDataHandle); - - [[nodiscard]] Threading::ConcurrentSharedPtr GetExistingTexture(Atom ecsId); - - [[nodiscard]] Threading::ConcurrentSharedPtr GetExistingTexture(const std::string& name); - - void DeleteTexture(Threading::ConcurrentSharedPtr texture); - - void DeleteTexture(Atom ecsId); - - void DeleteTexture(const std::string& name); - - // TODO: I don't know if we want to have an untyped version of this. we could use the C++ new mechanism with a - // type for complete safety but then C might have a harder time. Unsure. - // TODO: in the future when we have mesh loading capabilities these will be replaced with similar mechanisms to - // texture loading. End-users shouldn't need to manually hard-code the data. - template - [[nodiscard]] Threading::FutureResult LoadVertexDataRaw( - const std::string& vertexDataName, - NovelRT::Utilities::Misc::Span vertexDataSpan) - { - static_assert(std::is_trivially_copyable_v && - "The specified vertex struct must be trivially copyable."); - - return LoadVertexDataRawUntyped(vertexDataName, vertexDataSpan.data(), sizeof(TSpanType), - vertexDataSpan.size()); - } - - [[nodiscard]] Threading::FutureResult LoadVertexDataRawUntyped(const std::string& vertexDataName, - void* data, - size_t dataTypeSize, - size_t dataLength); - - [[nodiscard]] Threading::ConcurrentSharedPtr GetExistingVertexData( - const std::string& vertexDataName); - - [[nodiscard]] Threading::ConcurrentSharedPtr GetExistingVertexData(Atom ecsId); - - void DeleteVertexData(Threading::ConcurrentSharedPtr vertexData); - - void DeleteVertexData(Atom ecsId); - - void DeleteVertexData(const std::string& name); - - [[nodiscard]] Threading::ConcurrentSharedPtr GetExistingPipelineInfo( - const std::string& name); - - [[nodiscard]] Threading::ConcurrentSharedPtr GetExistingPipelineInfo(Atom ecsId); - - [[nodiscard]] Threading::ConcurrentSharedPtr RegisterPipeline( - const std::string& pipelineName, - std::shared_ptr pipeline, - uuids::uuid vertexShaderAssetHandle, - uuids::uuid pixelShaderAssetHandle, - std::vector> - customConstantBufferRegions = {}, - bool useEcsTransforms = true); - - void UnregisterPipeline(Threading::ConcurrentSharedPtr pipelineInfo); - - void UnregisterPipeline(Atom ecsId); - - void UnregisterPipeline(const std::string& name); - - void AttachSpriteRenderingToEntity(EntityId entity, - Threading::ConcurrentSharedPtr texture, - Catalogue& catalogue); - - [[nodiscard]] EntityId CreateSpriteEntity(Threading::ConcurrentSharedPtr texture, - Catalogue& catalogue); - - [[nodiscard]] EntityId CreateSpriteEntityOutsideOfSystem(Threading::ConcurrentSharedPtr texture, - SystemScheduler& scheduler); - - void ForceVertexTextureFutureResolution(); - - [[nodiscard]] inline NovelRT::Graphics::RGBAColour& BackgroundColour() noexcept - { - return _backgroundColour; - } - - [[nodiscard]] inline const NovelRT::Graphics::RGBAColour& BackgroundColour() const noexcept - { - return _backgroundColour; - } - - [[nodiscard]] uuids::uuid GetVertexShaderGuidForPrimitiveInfo(Atom primitiveInfoId) const; - - [[nodiscard]] uuids::uuid GetPixelShaderGuidForPrimitiveInfo(Atom primitiveInfoId) const; - - [[nodiscard]] uuids::uuid GetGuidForTexture(Atom textureId) const; - - [[nodiscard]] inline Atom GetDefaultVertexDataId() const noexcept - { - return _defaultSpriteMeshPtr->ecsId; - } - - [[nodiscard]] Atom GetTextureIdFromGuid(uuids::uuid assetGuid) const; - - [[nodiscard]] Atom GetPrimitiveInfoFromAssetGuids(uuids::uuid textureAssetGuid, - uuids::uuid vertexShaderAssetGuid, - uuids::uuid pixelShaderAssetGuid) const; - - [[nodiscard]] Atom GetPipelineFromAssetGuids(uuids::uuid vertexShaderAssetGuid, - uuids::uuid pixelShaderAssetGuid) const; - }; -} -#endif // !NOVELRT_ECS_GRAPHICS_DEFAULTRENDERINGSYSTEM_H diff --git a/include/NovelRT/Ecs/Graphics/Ecs.Graphics.h b/include/NovelRT/Ecs/Graphics/Ecs.Graphics.h deleted file mode 100644 index 593560a94..000000000 --- a/include/NovelRT/Ecs/Graphics/Ecs.Graphics.h +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_ECS_GRAPHICS_H -#define NOVELRT_ECS_GRAPHICS_H - -#ifndef NOVELRT_ECS_H -#error NovelRT does not support including types explicitly by default. Please include Ecs.h instead for the Ecs namespace subset. -#endif - -// Ecs.Graphics Dependencies -#include - -namespace NovelRT::Ecs::Graphics -{ - class DefaultRenderingSystem; - struct RenderComponent; - struct GraphicsPipelineComponent; - struct TextureInfo; - struct GraphicsPrimitiveInfo; - struct VertexInfo; - struct AttachRenderToExistingEntityRequestInfo; - struct GraphicsPipelineInfo; - struct CreateRenderEntityRequestInfo; - struct ConstantBufferInfo; - struct TexturedVertex; -} - -// clang-format off -#include "AttachRenderToExistingEntityRequestInfo.h" -#include "CreateRenderEntityRequestInfo.h" -#include "TextureInfo.h" -#include "VertexInfo.h" -#include "DefaultRenderingComponentTypes.h" -#include "DefaultRenderingSystem.h" -#include "GraphicsPrimitiveInfo.h" -#include "GraphicsPrimitiveInfo.h" -#include "GraphicsPipelineInfo.h" -#include "ConstantBufferInfo.h" -// clang-format on - -#endif // NOVELRT_ECS_GRAPHICS_H diff --git a/include/NovelRT/Ecs/Graphics/GraphicsPipelineInfo.h b/include/NovelRT/Ecs/Graphics/GraphicsPipelineInfo.h deleted file mode 100644 index d4ce87e8d..000000000 --- a/include/NovelRT/Ecs/Graphics/GraphicsPipelineInfo.h +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_GRAPHICSPIPELINEINFO_H -#define NOVELRT_GRAPHICSPIPELINEINFO_H - -#ifndef NOVELRT_ECS_H -#error NovelRT does not support including types explicitly by default. Please include Ecs.h instead for the Ecs namespace subset. -#endif - -namespace NovelRT::Ecs::Graphics -{ - struct GraphicsPipelineInfo - { - Threading::ConcurrentSharedPtr gpuPipeline = nullptr; - Threading::ConcurrentSharedPtr< - std::vector>> - gpuCustomConstantBuffers = nullptr; - bool useEcsTransforms = false; - std::string pipelineName = ""; - Atom ecsId = 0; - uuids::uuid vertexShaderAssetHandle; - uuids::uuid pixelShaderAssetHandle; - }; -} - -#endif // NOVELRT_GRAPHICSPIPELINEINFO_H diff --git a/include/NovelRT/Ecs/Graphics/GraphicsPrimitiveInfo.h b/include/NovelRT/Ecs/Graphics/GraphicsPrimitiveInfo.h deleted file mode 100644 index c1adeb8c4..000000000 --- a/include/NovelRT/Ecs/Graphics/GraphicsPrimitiveInfo.h +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_GRAPHICSPRIMITIVEINFO_H -#define NOVELRT_GRAPHICSPRIMITIVEINFO_H - -#ifndef NOVELRT_ECS_H -#error NovelRT does not support including types explicitly by default. Please include Ecs.h instead for the Ecs namespace subset. -#endif - -namespace NovelRT::Ecs::Graphics -{ - struct GraphicsPrimitiveInfo - { - Atom ecsVertexDataId = 0; - Atom ecsTextureId = 0; - Atom ecsPipelineId = 0; - std::map> - gpuTransformConstantBufferRegions = {}; - - inline bool operator==(const GraphicsPrimitiveInfo& other) const noexcept - { - return (ecsVertexDataId == other.ecsVertexDataId) && (ecsTextureId == other.ecsTextureId) && - (ecsPipelineId == other.ecsPipelineId); - } - - inline bool operator==(const RenderComponent& other) const noexcept - { - return (ecsVertexDataId == other.vertexDataId) && (ecsTextureId == other.textureId) && - (ecsPipelineId == other.pipelineId); - } - - inline bool operator!=(const GraphicsPrimitiveInfo& other) const noexcept - { - return !(*this == other); - } - }; -} - -#endif // NOVELRT_GRAPHICSPRIMITIVEINFO_H diff --git a/include/NovelRT/Ecs/Graphics/TextureInfo.h b/include/NovelRT/Ecs/Graphics/TextureInfo.h deleted file mode 100644 index 61bd7955a..000000000 --- a/include/NovelRT/Ecs/Graphics/TextureInfo.h +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_ECS_GRAPHICS_TEXTUREINFO_H -#define NOVELRT_ECS_GRAPHICS_TEXTUREINFO_H - -#ifndef NOVELRT_ECS_H -#error NovelRT does not support including types explicitly by default. Please include Ecs.h instead for the Ecs namespace subset. -#endif - -namespace NovelRT::Ecs::Graphics -{ - struct TextureInfo - { - NovelRT::Graphics::GraphicsMemoryRegion gpuTextureRegion = {}; - std::string textureName; - uint32_t width = 0; - uint32_t height = 0; - Atom ecsId = 0; - std::vector textureData; - uuids::uuid textureAssetDataHandle; - - bool operator==(const TextureInfo& other) const noexcept - { - return (gpuTextureRegion == other.gpuTextureRegion) && (textureName == other.textureName) && - (ecsId == other.ecsId) && (textureAssetDataHandle == other.textureAssetDataHandle); - } - }; -} - -#endif // NOVELRT_ECS_GRAPHICS_TEXTUREINFO_H diff --git a/include/NovelRT/Ecs/Graphics/VertexInfo.h b/include/NovelRT/Ecs/Graphics/VertexInfo.h deleted file mode 100644 index 95d00dd15..000000000 --- a/include/NovelRT/Ecs/Graphics/VertexInfo.h +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_ECS_GRAPHICS_VERTEXINFO_H -#define NOVELRT_ECS_GRAPHICS_VERTEXINFO_H - -#ifndef NOVELRT_ECS_H -#error NovelRT does not support including types explicitly by default. Please include Ecs.h instead for the Ecs namespace subset. -#endif - -namespace NovelRT::Ecs::Graphics -{ - struct VertexInfo - { - NovelRT::Graphics::GraphicsMemoryRegion gpuVertexRegion = {}; - std::string vertexInfoName; - Atom ecsId = 0; - void* stagingPtr = nullptr; - size_t sizeOfVert = 0; - size_t stagingPtrLength = 0; - uint32_t stride = 0; - - bool operator==(const VertexInfo& other) const noexcept - { - return (gpuVertexRegion == other.gpuVertexRegion) && (vertexInfoName == other.vertexInfoName) && - (ecsId == other.ecsId); - } - }; -} - -#endif // NOVELRT_ECS_GRAPHICS_VERTEXINFO_H diff --git a/include/NovelRT/NovelRT.h b/include/NovelRT/NovelRT.h index e0f4156e3..6e2a726e9 100644 --- a/include/NovelRT/NovelRT.h +++ b/include/NovelRT/NovelRT.h @@ -103,14 +103,6 @@ // Exception types #include - #include - #include -#ifdef WIN32 - #include -#endif -#ifdef TARGET_OS_MAC - #include -#endif #include #include #include @@ -124,8 +116,6 @@ #include #include - // Scene Graph types - #include #endif // __cplusplus #if defined(NOVELRT_C_API) diff --git a/include/NovelRT/Persistence/Graphics/Persistence.Graphics.h b/include/NovelRT/Persistence/Graphics/Persistence.Graphics.h deleted file mode 100644 index ba88eb397..000000000 --- a/include/NovelRT/Persistence/Graphics/Persistence.Graphics.h +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_PERSISTENCE_GRAPHICS_H -#define NOVELRT_PERSISTENCE_GRAPHICS_H - -#ifndef NOVELRT_PERSISTENCE_H -#error NovelRT does not support including types explicitly by default. Please include Persistence.h instead for the Persistence namespace subset. -#endif - -// Persistence.Graphics Dependencies -#include - -namespace NovelRT::Persistence::Graphics -{ - class RenderingComponentPersistenceRule; -} - -// clang-format off -#include "RenderingComponentPersistenceRule.h" -// clang-format on - -#endif // NOVELRT_PERSISTENCE_GRAPHICS_H diff --git a/include/NovelRT/Persistence/Graphics/RenderingComponentPersistenceRule.h b/include/NovelRT/Persistence/Graphics/RenderingComponentPersistenceRule.h deleted file mode 100644 index 46e529075..000000000 --- a/include/NovelRT/Persistence/Graphics/RenderingComponentPersistenceRule.h +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_PERSISTENCE_GRAPHICS_RENDERINGCOMPONENTPERSISTENCERULE_H -#define NOVELRT_PERSISTENCE_GRAPHICS_RENDERINGCOMPONENTPERSISTENCERULE_H - -#ifndef NOVELRT_PERSISTENCE_H -#error NovelRT does not support including types explicitly by default. Please include Persistence.h instead for the Persistence namespace subset. -#endif - -namespace NovelRT::Persistence::Graphics -{ - class RenderingComponentPersistenceRule final : public ICustomSerialisationRule - { - private: - std::shared_ptr _renderingSystem; - - public: - explicit RenderingComponentPersistenceRule( - std::shared_ptr renderingSystem) noexcept; - - [[nodiscard]] inline size_t GetSerialisedSize() const noexcept final - { - return sizeof(uuids::uuid) * 3; - } - - [[nodiscard]] std::vector ExecuteSerialiseModification( - NovelRT::Utilities::Misc::Span component) const noexcept final; - - [[nodiscard]] std::vector ExecuteDeserialiseModification( - NovelRT::Utilities::Misc::Span component) const noexcept final; - }; -} - -#endif // NOVELRT_PERSISTENCE_GRAPHICS_RENDERINGCOMPONENTPERSISTENCERULE_H diff --git a/include/NovelRT/Persistence/Persistable.h b/include/NovelRT/Persistence/Persistable.h index 1f9ae4e2c..6eca15c4d 100644 --- a/include/NovelRT/Persistence/Persistable.h +++ b/include/NovelRT/Persistence/Persistable.h @@ -28,8 +28,6 @@ namespace NovelRT::Persistence [[nodiscard]] static std::unordered_map>& GetComponentLoadRules() noexcept; - static void LoadDefaultRules(std::shared_ptr renderingSystem) noexcept; - [[nodiscard]] virtual ResourceManagement::BinaryPackage ToFileData() const noexcept = 0; virtual void LoadFileData(const ResourceManagement::BinaryPackage& data) = 0; }; diff --git a/include/NovelRT/Persistence/Persistence.h b/include/NovelRT/Persistence/Persistence.h index b61c0f4a0..e5c9c2387 100644 --- a/include/NovelRT/Persistence/Persistence.h +++ b/include/NovelRT/Persistence/Persistence.h @@ -27,8 +27,6 @@ namespace NovelRT::Persistence #include "Persistable.h" #include "Chapter.h" -#include "Graphics/Persistence.Graphics.h" - // clang-format on #endif // NOVELRT_PERSISTENCE_H diff --git a/include/NovelRT/PluginManagement/DefaultPluginSelector.h b/include/NovelRT/PluginManagement/DefaultPluginSelector.h index e93190841..b3b47b622 100644 --- a/include/NovelRT/PluginManagement/DefaultPluginSelector.h +++ b/include/NovelRT/PluginManagement/DefaultPluginSelector.h @@ -8,6 +8,11 @@ #error #endif +namespace NovelRT::Graphics::Vulkan +{ + struct VulkanGraphicsBackend; +} + namespace NovelRT::PluginManagement { class DefaultPluginSelector @@ -20,10 +25,10 @@ namespace NovelRT::PluginManagement } template<> - [[nodiscard]] std::shared_ptr GetDefaultPluginTypeOnCurrentPlatformFor< - IGraphicsPluginProvider>() + [[nodiscard]] std::shared_ptr> GetDefaultPluginTypeOnCurrentPlatformFor< + IGraphicsPluginProvider>() { - return std::static_pointer_cast(GetVulkanPluginProvider()); + return std::static_pointer_cast>(GetVulkanPluginProvider()); } template<> diff --git a/include/NovelRT/PluginManagement/IGraphicsPluginProvider.h b/include/NovelRT/PluginManagement/IGraphicsPluginProvider.h index 0efc97781..1d64471fc 100644 --- a/include/NovelRT/PluginManagement/IGraphicsPluginProvider.h +++ b/include/NovelRT/PluginManagement/IGraphicsPluginProvider.h @@ -4,30 +4,37 @@ #ifndef NOVELRT_GRAPHICS_IGRAPHICSPLUGINPROVIDER_H #define NOVELRT_GRAPHICS_IGRAPHICSPLUGINPROVIDER_H -#ifndef NOVELRT_PLUGINMANAGEMENT_H -#error NovelRT does not support including types explicitly by default. Please include PluginManagement.h instead for the PluginManagement namespace subset. -#endif +#include + +namespace NovelRT::Graphics +{ + template + struct GraphicsBackendTraits; +} namespace NovelRT::PluginManagement { - class IGraphicsPluginProvider : public std::enable_shared_from_this + template + class IGraphicsPluginProvider : public std::enable_shared_from_this> { - protected: - [[nodiscard]] virtual Graphics::GraphicsProvider* GetGraphicsProviderInternal() = 0; + public: + using BackendGraphicsProvider = typename Graphics::GraphicsBackendTraits::ProviderType; + + private: + Utilities::Lazy> _graphicsProvider; public: - [[nodiscard]] inline std::shared_ptr GetGraphicsProvider() - { - return GetGraphicsProviderInternal()->shared_from_this(); - } + IGraphicsPluginProvider() noexcept; + virtual ~IGraphicsPluginProvider() = default; - [[nodiscard]] virtual std::shared_ptr GetDefaultSelectedGraphicsAdapterForContext( - std::shared_ptr context) = 0; + [[nodiscard]] std::shared_ptr> GetGraphicsProvider(); - [[nodiscard]] virtual std::shared_ptr CreateSurfaceContext( - std::shared_ptr windowingDevice) = 0; + [[nodiscard]] std::shared_ptr> GetDefaultSelectedGraphicsAdapterForContext( + std::shared_ptr> context); + + [[nodiscard]] std::shared_ptr> CreateSurfaceContext( + std::shared_ptr windowingDevice); - virtual ~IGraphicsPluginProvider() = default; }; } diff --git a/include/NovelRT/PluginManagement/PluginManagement.h b/include/NovelRT/PluginManagement/PluginManagement.h index 1362b2839..f01d35d95 100644 --- a/include/NovelRT/PluginManagement/PluginManagement.h +++ b/include/NovelRT/PluginManagement/PluginManagement.h @@ -8,7 +8,8 @@ #include "../Input/Input.h" #include "../ResourceManagement/ResourceManagement.h" #include "../Windowing/Windowing.h" -#include +#include +#include /** * @brief The NovelRT engine plugin system for loading modules such as Vulkan, GLFW3, OpenAL, and more. @@ -17,6 +18,7 @@ namespace NovelRT::PluginManagement { class DefaultPluginSelector; class IResourceManagementPluginProvider; + template class IGraphicsPluginProvider; class IWindowingPluginProvider; class IInputPluginProvider; diff --git a/include/NovelRT/PluginManagement/TemporaryFnPtrs.h b/include/NovelRT/PluginManagement/TemporaryFnPtrs.h index 76dfbf2d9..b219347cd 100644 --- a/include/NovelRT/PluginManagement/TemporaryFnPtrs.h +++ b/include/NovelRT/PluginManagement/TemporaryFnPtrs.h @@ -4,16 +4,17 @@ #ifndef NOVELRT_PLUGINMANAGEMENT_TEMPORARYFNPTRS_H #define NOVELRT_PLUGINMANAGEMENT_TEMPORARYFNPTRS_H -#ifndef NOVELRT_PLUGINMANAGEMENT_H -#error NovelRT does not support including types explicitly by default. Please include PluginManagement.h instead for the PluginManagement namespace subset. -#endif +namespace NovelRT::Graphics::Vulkan +{ + struct VulkanGraphicsBackend; +} /** * @brief This whole header is a hack. It won't be here post-MVP. */ namespace NovelRT::PluginManagement { - [[nodiscard]] std::shared_ptr GetVulkanPluginProvider() noexcept; + [[nodiscard]] std::shared_ptr> GetVulkanPluginProvider() noexcept; [[nodiscard]] std::shared_ptr GetGlfwWindowPluginProvider() noexcept; [[nodiscard]] std::shared_ptr GetGlfwInputPluginProvider() noexcept; [[nodiscard]] std::shared_ptr diff --git a/include/NovelRT/SceneGraph/QuadTreeNode.h b/include/NovelRT/SceneGraph/QuadTreeNode.h deleted file mode 100644 index 0d1d6bae9..000000000 --- a/include/NovelRT/SceneGraph/QuadTreeNode.h +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_SCENEGRAPH_QUADTREENODE_H -#define NOVELRT_SCENEGRAPH_QUADTREENODE_H - -#ifndef NOVELRT_SCENEGRAPH_H -#error NovelRT does not support including types explicitly by default. Please include SceneGraph.h instead for the Graphics namespace subset. -#endif - -namespace NovelRT::SceneGraph -{ - class QuadTreeNode : public SceneNode - { - private: - static const int32_t TOP_LEFT = 0; - static const int32_t TOP_RIGHT = 1; - static const int32_t BOTTOM_LEFT = 2; - static const int32_t BOTTOM_RIGHT = 3; - - std::array, 4> _quadTreePoints; - - public: - QuadTreeNode(std::array, 4> quadTreePoints) noexcept - : _quadTreePoints(quadTreePoints) - { - } - - const std::shared_ptr& getTopLeft() const noexcept - { - return _quadTreePoints[TOP_LEFT]; - } - - const std::shared_ptr& getTopRight() const noexcept - { - return _quadTreePoints[TOP_RIGHT]; - } - - const std::shared_ptr& getBottomLeft() const noexcept - { - return _quadTreePoints[BOTTOM_LEFT]; - } - - const std::shared_ptr& getBottomRight() const noexcept - { - return _quadTreePoints[BOTTOM_RIGHT]; - } - }; -} - -#endif diff --git a/include/NovelRT/SceneGraph/QuadTreeScenePoint.h b/include/NovelRT/SceneGraph/QuadTreeScenePoint.h deleted file mode 100644 index 26c231af9..000000000 --- a/include/NovelRT/SceneGraph/QuadTreeScenePoint.h +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_SCENEGRAPH_QUADTREESCENEPOINT_H -#define NOVELRT_SCENEGRAPH_QUADTREESCENEPOINT_H - -#ifndef NOVELRT_SCENEGRAPH_H -#error NovelRT does not support including types explicitly by default. Please include SceneGraph.h instead for the Graphics namespace subset. -#endif - -namespace NovelRT::SceneGraph -{ - class QuadTreeScenePoint : public Maths::QuadTreePoint - { - private: - std::shared_ptr _sceneNode; - - public: - QuadTreeScenePoint(Maths::GeoVector2F position, std::shared_ptr sceneNode) noexcept - : Maths::QuadTreePoint(position), _sceneNode(sceneNode) - { - } - - QuadTreeScenePoint(float x, float y, std::shared_ptr sceneNode) noexcept - : Maths::QuadTreePoint(x, y), _sceneNode(sceneNode) - { - } - - const std::shared_ptr& getSceneNode() const noexcept - { - return _sceneNode; - } - }; -} - -#endif diff --git a/include/NovelRT/SceneGraph/Scene.h b/include/NovelRT/SceneGraph/Scene.h deleted file mode 100644 index 8bf1097ad..000000000 --- a/include/NovelRT/SceneGraph/Scene.h +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_SCENE_H -#define NOVELRT_SCENE_H - -#ifndef NOVELRT_SCENEGRAPH_H -#error NovelRT does not support including types explicitly by default. Please include SceneGraph.h instead for the Graphics namespace subset. -#endif - -namespace NovelRT::SceneGraph -{ - class Scene - { - private: - std::set> _nodes; - - public: - const std::set>& getNodes() noexcept - { - return _nodes; - } - - bool insert(const std::shared_ptr& node) - { - return _nodes.insert(node).second; - } - - bool remove(const std::shared_ptr& node) noexcept - { - auto numErased = _nodes.erase(node); - assert((numErased == 0) || (numErased == 1)); - return numErased != 0; - } - }; -} - -#endif diff --git a/include/NovelRT/SceneGraph/SceneGraph.h b/include/NovelRT/SceneGraph/SceneGraph.h deleted file mode 100644 index 7bb7b3a71..000000000 --- a/include/NovelRT/SceneGraph/SceneGraph.h +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_SCENEGRAPH_H -#define NOVELRT_SCENEGRAPH_H - -// dependencies -#include "../Maths/Maths.h" -#include -#include -#include -#include -#include -#include - -/** - * @brief Provides Scene Graph features for a variety of purposes, such as rendering or input. - */ -namespace NovelRT::SceneGraph -{ - class QuadTreeNode; - class QuadTreeScenePoint; - class Scene; - class SceneNode; -} - -// clang-format off - -#include "SceneNode.h" -#include "QuadTreeNode.h" -#include "QuadTreeScenePoint.h" -#include "Scene.h" - -// clang-format on - -#endif // !NOVELRT_SCENEGRAPH_H diff --git a/include/NovelRT/SceneGraph/SceneNode.h b/include/NovelRT/SceneGraph/SceneNode.h deleted file mode 100644 index f50136a90..000000000 --- a/include/NovelRT/SceneGraph/SceneNode.h +++ /dev/null @@ -1,299 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#ifndef NOVELRT_SCENEGRAPH_SCENENODE_H -#define NOVELRT_SCENEGRAPH_SCENENODE_H - -#ifndef NOVELRT_SCENEGRAPH_H -#error NovelRT does not support including types explicitly by default. Please include SceneGraph.h instead for the SceneGraph.h namespace subset. -#endif - -namespace NovelRT::SceneGraph -{ - class SceneNode : public std::enable_shared_from_this - { - public: - template class breadth_first_traversal_result_iterator; - template class depth_first_traversal_result_iterator; - - private: - std::set> _parents; - std::set> _children; - - public: - const std::set>& getChildren() const noexcept - { - return _children; - } - - const std::set>& getParents() const noexcept - { - return _parents; - } - - bool insert(const std::shared_ptr& node) - { - node->_parents.insert(shared_from_this()); - return _children.insert(node).second; - } - - bool remove(const std::shared_ptr& node) - { - auto numErased = _children.erase(node); - numErased += node->_parents.erase(shared_from_this()); - - assert((numErased == 0) || (numErased == 2)); - return numErased != 0; - } - - bool isAdjacent(const std::shared_ptr& node) - { - return _children.find(node) != _children.cend() || _parents.find(node) != _parents.cend(); - } - - void traverseBreadthFirst(std::function&)> action) - { - // We do a breadth-first traversal of the nodes using a queue-based algorithm - // to track pending nodes, rather than using recursion, so that we can - // process much more complex graphs. - - auto visitedNodes = std::set>(); - auto pendingNodes = std::queue>(); - - visitedNodes.insert(shared_from_this()); - pendingNodes.push(shared_from_this()); - - do - { - auto node = pendingNodes.front(); - action(node); - pendingNodes.pop(); - - for (auto child : node->getChildren()) - { - if (visitedNodes.find(child) == visitedNodes.cend()) - { - visitedNodes.insert(child); - pendingNodes.push(child); - } - } - - } while (!pendingNodes.empty()); - } - - void traverseDepthFirst(std::function&)> action) - { - // We do a depth-first traversal of the nodes using a stack-based algorithm - // to track pending nodes, rather than using recursion, so that we can - // process much more complex graphs - - auto visitedNodes = std::set>(); - auto pendingNodes = std::stack>(); - - visitedNodes.insert(shared_from_this()); - pendingNodes.push(shared_from_this()); - - do - { - auto node = pendingNodes.top(); - action(node); - pendingNodes.pop(); - - for (auto child : node->getChildren()) - { - if (visitedNodes.find(child) == visitedNodes.cend()) - { - visitedNodes.insert(child); - pendingNodes.push(child); - } - } - - } while (!pendingNodes.empty()); - } - - template - breadth_first_traversal_result_iterator traverseBreadthFirst( - std::function&)> function) - { - return breadth_first_traversal_result_iterator(shared_from_this(), function); - } - - template - depth_first_traversal_result_iterator traverseDepthFirst( - std::function&)> function) - { - return depth_first_traversal_result_iterator(shared_from_this(), function); - } - - bool canReach(const std::shared_ptr& node) - { - auto result = traverseDepthFirst( - [&](const std::shared_ptr& traversedNode) { return traversedNode == node; }); - - while ((*result != true) && !result.isEnd()) - { - ++result; - } - - return *result; - } - - template class breadth_first_traversal_result_iterator - { - private: - std::function&)> _function; - std::queue> _pendingNodes; - std::set> _visitedNodes; - - T _value; - - public: - using iterator_category = std::output_iterator_tag; - using value_type = T; - using pointer = value_type*; - using const_pointer = const value_type*; - using reference = value_type&; - using const_reference = const value_type&; - - breadth_first_traversal_result_iterator(const std::shared_ptr& node, - std::function&)> function) - : _function(function) - { - _pendingNodes.push(node); - _visitedNodes.insert(node); - ++*this; - } - - const_reference operator*() const noexcept - { - return _value; - } - - const_pointer operator->() const noexcept - { - return std::pointer_traits::pointer_to(**this); - } - - breadth_first_traversal_result_iterator& operator++() - { - auto node = _pendingNodes.front(); - _value = _function(node); - _pendingNodes.pop(); - - for (auto child : node->getChildren()) - { - if (_visitedNodes.find(child) == _visitedNodes.cend()) - { - _visitedNodes.insert(child); - _pendingNodes.push(child); - } - } - - return *this; - } - - breadth_first_traversal_result_iterator operator++(int32_t) noexcept - { - auto tmp = *this; - ++*this; - return tmp; - } - - bool operator==(const breadth_first_traversal_result_iterator& other) const noexcept - { - return _value == other._value && (_pendingNodes.empty() == other._pendingNodes.empty() || - _pendingNodes.front() == other._pendingNodes.front()); - } - - bool operator!=(const breadth_first_traversal_result_iterator& other) const noexcept - { - return !(*this == other); - } - - bool isEnd() const noexcept - { - return _pendingNodes.empty(); - } - }; - - template class depth_first_traversal_result_iterator - { - private: - std::function&)> _function; - std::stack> _pendingNodes; - std::set> _visitedNodes; - - T _value; - - public: - using iterator_category = std::output_iterator_tag; - using value_type = T; - using pointer = value_type*; - using const_pointer = const value_type*; - using reference = value_type&; - using const_reference = const value_type&; - - depth_first_traversal_result_iterator(const std::shared_ptr& node, - std::function&)> function) - : _function(function) - { - _pendingNodes.push(node); - _visitedNodes.insert(node); - ++*this; - } - - const_reference operator*() const noexcept - { - return _value; - } - - const_pointer operator->() const noexcept - { - return std::pointer_traits::pointer_to(**this); - } - - depth_first_traversal_result_iterator& operator++() - { - auto node = _pendingNodes.top(); - _value = _function(node); - _pendingNodes.pop(); - - for (auto child : node->getChildren()) - { - if (_visitedNodes.find(child) == _visitedNodes.cend()) - { - _visitedNodes.insert(child); - _pendingNodes.push(child); - } - } - - return *this; - } - - depth_first_traversal_result_iterator operator++(int32_t) noexcept - { - auto tmp = *this; - ++*this; - return tmp; - } - - bool operator==(const depth_first_traversal_result_iterator& other) const noexcept - { - return _value == other._value && (_pendingNodes.empty() == other._pendingNodes.empty() || - _pendingNodes.top() == other._pendingNodes.top()); - } - - bool operator!=(const depth_first_traversal_result_iterator& other) const noexcept - { - return !(*this == other); - } - - bool isEnd() const noexcept - { - return _pendingNodes.empty(); - } - }; - }; -} - -#endif diff --git a/include/NovelRT/Utilities/Misc.h b/include/NovelRT/Utilities/Misc.h index ce4b25d64..cee4d717d 100644 --- a/include/NovelRT/Utilities/Misc.h +++ b/include/NovelRT/Utilities/Misc.h @@ -1,3 +1,5 @@ +#pragma once + // Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root // for more information. @@ -30,6 +32,8 @@ #define unused(x) (void)(x) +#define assert_message(exp, msg) assert((static_cast(msg), exp)); + namespace NovelRT::Utilities { class Misc @@ -44,13 +48,33 @@ namespace NovelRT::Utilities static inline const char* CONSOLE_LOG_INPUT = "Input"; static inline const char* CONSOLE_LOG_WINDOWING = "WindowManager"; - template #ifdef NOVELRT_USE_STD_SPAN - using Span = std::span; + static const size_t DynamicExtent = std::dynamic_extent; #else - using Span = gsl::span; + static const size_t DynamicExtent = gsl::dynamic_extent; #endif + template +#ifdef NOVELRT_USE_STD_SPAN + using Span = std::span; +#else + using Span = gsl::span; +#endif + + + template + auto SpanCast(Span s) noexcept -> Span + { + return {reinterpret_cast(s.data()), s.size_bytes() / sizeof(TTo)}; + } + + + template + auto SpanCast(Span s) noexcept -> Span + { + return {reinterpret_cast(s.data()), s.size_bytes() / sizeof(TTo)}; + } + /** * @brief Gets the path to the executable. * diff --git a/include/NovelRT/Windowing/Windowing.h b/include/NovelRT/Windowing/Windowing.h index ebeca88f7..7defcd43b 100644 --- a/include/NovelRT/Windowing/Windowing.h +++ b/include/NovelRT/Windowing/Windowing.h @@ -15,7 +15,7 @@ namespace NovelRT::Windowing // Windowing dependencies #include "NovelRT/Maths/Maths.h" #include "WindowMode.h" -#include +#include // Windowing types #include "IWindowingDevice.h" diff --git a/samples/AudioEcsSample/main.cpp b/samples/AudioEcsSample/main.cpp index 37eecd0d3..946805b9a 100644 --- a/samples/AudioEcsSample/main.cpp +++ b/samples/AudioEcsSample/main.cpp @@ -4,6 +4,8 @@ #include #include +#include + using namespace NovelRT::Ecs; using namespace NovelRT::Ecs::Audio; using namespace NovelRT::Input; @@ -20,9 +22,9 @@ int main() auto windowingProvider = selector.GetDefaultPluginTypeOnCurrentPlatformFor(); auto inputProvider = selector.GetDefaultPluginTypeOnCurrentPlatformFor(); auto scheduler = - Configurator() + Configurator() .WithDefaultSystemsAndComponents() - .WithPluginProvider(selector.GetDefaultPluginTypeOnCurrentPlatformFor()) + .WithPluginProvider(selector.GetDefaultPluginTypeOnCurrentPlatformFor>()) .WithPluginProvider(windowingProvider) .WithPluginProvider(inputProvider) .WithPluginProvider(selector.GetDefaultPluginTypeOnCurrentPlatformFor()) diff --git a/samples/EcsPipeline/main.cpp b/samples/EcsPipeline/main.cpp index 5ea7dd43e..731b22dc9 100644 --- a/samples/EcsPipeline/main.cpp +++ b/samples/EcsPipeline/main.cpp @@ -3,6 +3,8 @@ #include +#include + using namespace NovelRT::Ecs; using namespace NovelRT::Input; using namespace NovelRT::PluginManagement; @@ -18,9 +20,9 @@ int main() auto windowingProvider = selector.GetDefaultPluginTypeOnCurrentPlatformFor(); auto inputProvider = selector.GetDefaultPluginTypeOnCurrentPlatformFor(); auto scheduler = - Configurator() + Configurator() .WithDefaultSystemsAndComponents() - .WithPluginProvider(selector.GetDefaultPluginTypeOnCurrentPlatformFor()) + .WithPluginProvider(selector.GetDefaultPluginTypeOnCurrentPlatformFor>()) .WithPluginProvider(windowingProvider) .WithPluginProvider(inputProvider) .WithPluginProvider(selector.GetDefaultPluginTypeOnCurrentPlatformFor()) diff --git a/samples/FabulistTest/main.cpp b/samples/FabulistTest/main.cpp index 7f3aa2cff..064341ffa 100644 --- a/samples/FabulistTest/main.cpp +++ b/samples/FabulistTest/main.cpp @@ -2,6 +2,7 @@ // for more information. #include +#include using namespace NovelRT::Ecs; using namespace NovelRT::PluginManagement; @@ -19,9 +20,9 @@ int main() logger.setLogLevel(NovelRT::LogLevel::Info); auto scheduler = - Configurator() + Configurator() .WithDefaultSystemsAndComponents() - .WithPluginProvider(selector.GetDefaultPluginTypeOnCurrentPlatformFor()) + .WithPluginProvider(selector.GetDefaultPluginTypeOnCurrentPlatformFor>()) .WithPluginProvider(windowingProvider) .WithPluginProvider(resourceManagementProvider) .WithPluginProvider(selector.GetDefaultPluginTypeOnCurrentPlatformFor()) diff --git a/samples/InputEcsSample/main.cpp b/samples/InputEcsSample/main.cpp index 4db4deca6..d66597c25 100644 --- a/samples/InputEcsSample/main.cpp +++ b/samples/InputEcsSample/main.cpp @@ -4,6 +4,8 @@ #include #include +#include + using namespace NovelRT::Ecs; using namespace NovelRT::Input; using namespace NovelRT::PluginManagement; @@ -19,9 +21,9 @@ int main() auto windowingProvider = selector.GetDefaultPluginTypeOnCurrentPlatformFor(); auto inputProvider = selector.GetDefaultPluginTypeOnCurrentPlatformFor(); auto scheduler = - Configurator() + Configurator() .WithDefaultSystemsAndComponents() - .WithPluginProvider(selector.GetDefaultPluginTypeOnCurrentPlatformFor()) + .WithPluginProvider(selector.GetDefaultPluginTypeOnCurrentPlatformFor>()) .WithPluginProvider(windowingProvider) .WithPluginProvider(inputProvider) .WithPluginProvider(selector.GetDefaultPluginTypeOnCurrentPlatformFor()) diff --git a/samples/PersistenceSample/main.cpp b/samples/PersistenceSample/main.cpp index 9aa13d49c..595aafa17 100644 --- a/samples/PersistenceSample/main.cpp +++ b/samples/PersistenceSample/main.cpp @@ -3,6 +3,8 @@ #include +#include + using namespace NovelRT::Ecs; using namespace NovelRT::Input; using namespace NovelRT::PluginManagement; @@ -116,9 +118,9 @@ int main() selector.GetDefaultPluginTypeOnCurrentPlatformFor(); auto scheduler = - Configurator() + Configurator() .WithDefaultSystemsAndComponents() - .WithPluginProvider(selector.GetDefaultPluginTypeOnCurrentPlatformFor()) + .WithPluginProvider(selector.GetDefaultPluginTypeOnCurrentPlatformFor>()) .WithPluginProvider(windowingProvider) .WithPluginProvider(inputProvider) .WithPluginProvider(resourceManagementProvider) diff --git a/samples/UIEventExample/main.cpp b/samples/UIEventExample/main.cpp index 68d841e78..a936a1551 100644 --- a/samples/UIEventExample/main.cpp +++ b/samples/UIEventExample/main.cpp @@ -4,6 +4,8 @@ #include #include +#include + using namespace NovelRT::Ecs; using namespace NovelRT::Input; using namespace NovelRT::PluginManagement; @@ -19,9 +21,9 @@ int main() auto windowingProvider = selector.GetDefaultPluginTypeOnCurrentPlatformFor(); auto inputProvider = selector.GetDefaultPluginTypeOnCurrentPlatformFor(); auto scheduler = - Configurator() + Configurator() .WithDefaultSystemsAndComponents() - .WithPluginProvider(selector.GetDefaultPluginTypeOnCurrentPlatformFor()) + .WithPluginProvider(selector.GetDefaultPluginTypeOnCurrentPlatformFor>()) .WithPluginProvider(windowingProvider) .WithPluginProvider(inputProvider) .WithPluginProvider(selector.GetDefaultPluginTypeOnCurrentPlatformFor()) diff --git a/src/NovelRT/CMakeLists.txt b/src/NovelRT/CMakeLists.txt index 5b1fd6d73..f5f100e7a 100644 --- a/src/NovelRT/CMakeLists.txt +++ b/src/NovelRT/CMakeLists.txt @@ -14,7 +14,6 @@ set(CORE_SOURCES Ecs/SparseSetMemoryContainer.cpp Ecs/SystemScheduler.cpp Ecs/UnsafeComponentView.cpp - Ecs/Graphics/DefaultRenderingSystem.cpp Ecs/Audio/AudioSystem.cpp Ecs/Input/InputSystem.cpp Ecs/Narrative/NarrativePlayerSystem.cpp @@ -28,7 +27,6 @@ set(CORE_SOURCES Persistence/Chapter.cpp Persistence/Persistable.cpp - Persistence/Graphics/RenderingComponentPersistenceRule.cpp PluginManagement/TemporaryFnPtrs.cpp diff --git a/src/NovelRT/Ecs/Graphics/DefaultRenderingSystem.cpp b/src/NovelRT/Ecs/Graphics/DefaultRenderingSystem.cpp deleted file mode 100644 index 48cfa788e..000000000 --- a/src/NovelRT/Ecs/Graphics/DefaultRenderingSystem.cpp +++ /dev/null @@ -1,970 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#include - -namespace NovelRT::Ecs::Graphics -{ - void DefaultRenderingSystem::ResolveGpuResourceCleanup() - { - ResolveVertexInfoGpuCleanup(); - ResolveTextureInfoGpuCleanup(); - } - - void DefaultRenderingSystem::ResolveVertexInfoGpuCleanup() - { - std::scoped_lock guard(_vertexQueueMapMutex); - - while (!_vertexDataToDelete.empty()) - { - Atom ecsId = _vertexDataToDelete.front(); - _vertexDataToDelete.pop(); - - _resourceManager.getActual().FreeVertexData(_namedVertexInfoObjects.at(ecsId)->gpuVertexRegion); - _namedVertexInfoObjects.erase(ecsId); - } - } - - void DefaultRenderingSystem::ResolveTextureInfoGpuCleanup() - { - std::scoped_lock guard(_textureQueueMapMutex); - - while (!_texturesToDelete.empty()) - { - Atom ecsId = _texturesToDelete.front(); - _texturesToDelete.pop(); - - _resourceManager.getActual().FreeTextureData(_namedTextureInfoObjects.at(ecsId)->gpuTextureRegion); - _namedVertexInfoObjects.erase(ecsId); - } - } - - void DefaultRenderingSystem::ResolveGpuFutures() - { - ResolveVertexInfoFutureResults(); - ResolveTextureFutureResults(); - } - - void DefaultRenderingSystem::ResolveVertexInfoFutureResults() - { - static AtomFactory& vertexDataIdFactory = AtomFactoryDatabase::GetFactory("VertexDataId"); - - std::scoped_lock guard(_vertexQueueMapMutex); - - while (!_vertexDataToInitialise.empty()) - { - Threading::ConcurrentSharedPtr ptr = _vertexDataToInitialise.front(); - _vertexDataToInitialise.pop(); - - std::scoped_lock innerGuard(ptr); - - auto& resourceManager = _resourceManager.getActual(); - - ptr->gpuVertexRegion = - resourceManager.LoadVertexDataUntyped(ptr->stagingPtr, ptr->sizeOfVert, ptr->stagingPtrLength); - ptr->ecsId = vertexDataIdFactory.GetNext(); - free(ptr->stagingPtr); - ptr->stagingPtr = nullptr; - _namedVertexInfoObjects.emplace(ptr->ecsId, ptr); - } - } - - void DefaultRenderingSystem::ResolveTextureFutureResults() - { - std::scoped_lock guard(_textureQueueMapMutex); - - while (!_texturesToInitialise.empty()) - { - Threading::ConcurrentSharedPtr ptr = _texturesToInitialise.front(); - _texturesToInitialise.pop(); - - std::scoped_lock innerGuard(ptr); - - auto& resourceManager = _resourceManager.getActual(); - auto resourceLoader = _resourceManagementPluginProvider->GetResourceLoader(); - ResourceManagement::TextureMetadata texture; - - if (!ptr->textureData.empty()) - { - texture.width = ptr->width; - texture.height = ptr->height; - texture.pixelCount = ptr->width * ptr->height; - texture.data = ptr->textureData; - } - else - { - texture = resourceLoader->LoadTexture(ptr->textureName + ".png"); - } - - auto texture2DRegion = - resourceManager.LoadTextureData(texture, NovelRT::Graphics::GraphicsTextureAddressMode::ClampToEdge, - NovelRT::Graphics::GraphicsTextureKind::TwoDimensional); - - *ptr = TextureInfo{texture2DRegion, ptr->textureName, texture.width, texture.height, - ptr->ecsId, std::vector{}, texture.databaseHandle}; - _namedTextureInfoObjects.emplace(ptr->ecsId, ptr); - } - } - - DefaultRenderingSystem::DefaultRenderingSystem( - std::shared_ptr graphicsPluginProvider, - std::shared_ptr windowingPluginProvider, - std::shared_ptr resourceManagementPluginProvider) - : _resourceManager([&]() { return NovelRT::Graphics::GraphicsResourceManager(_graphicsDevice); }), - _graphicsPluginProvider(std::move(graphicsPluginProvider)), - _windowingPluginProvider(std::move(windowingPluginProvider)), - _resourceManagementPluginProvider(std::move(resourceManagementPluginProvider)), - _surfaceContext(nullptr), - _graphicsAdapter(nullptr), - _graphicsDevice(nullptr), - _windowingDevice(nullptr), - _frameMatrixConstantBufferRegion(), - _textureQueueMapMutex(), - _namedTextureInfoObjects{}, - _texturesToInitialise(), - _vertexQueueMapMutex(), - _namedVertexInfoObjects{}, - _vertexDataToInitialise(), - _defaultSpriteMeshPtr(nullptr), - _namedGraphicsPipelineInfoObjects{}, - _defaultGraphicsPipelinePtr(nullptr), - _renderScene(), - _backgroundColour(NovelRT::Graphics::RGBAColour(0, 0, 255, 255)) - { - _windowingDevice = _windowingPluginProvider->GetWindowingDevice(); - _windowingDevice->Initialise(Windowing::WindowMode::Windowed, Maths::GeoVector2F(1920, 1080)); - - _surfaceContext = _graphicsPluginProvider->CreateSurfaceContext(_windowingPluginProvider->GetWindowingDevice()); - _graphicsAdapter = _graphicsPluginProvider->GetDefaultSelectedGraphicsAdapterForContext(_surfaceContext); - _graphicsDevice = _graphicsAdapter->CreateDevice(_surfaceContext, 2); - - auto resourceLoader = _resourceManagementPluginProvider->GetResourceLoader(); - auto vertShaderData = resourceLoader->LoadShaderSource("vert.spv"); - auto pixelShaderData = resourceLoader->LoadShaderSource("frag.spv"); - - std::vector elements = { - NovelRT::Graphics::GraphicsPipelineInputElement( - typeid(NovelRT::Maths::GeoVector3F), NovelRT::Graphics::GraphicsPipelineInputElementKind::Position, 12), - - NovelRT::Graphics::GraphicsPipelineInputElement( - typeid(NovelRT::Maths::GeoVector2F), - NovelRT::Graphics::GraphicsPipelineInputElementKind::TextureCoordinate, 8)}; - - std::vector inputs = { - NovelRT::Graphics::GraphicsPipelineInput(elements)}; - - std::vector resources = { - NovelRT::Graphics::GraphicsPipelineResource(NovelRT::Graphics::GraphicsPipelineResourceKind::ConstantBuffer, - NovelRT::Graphics::ShaderProgramVisibility::Vertex), - - NovelRT::Graphics::GraphicsPipelineResource(NovelRT::Graphics::GraphicsPipelineResourceKind::ConstantBuffer, - NovelRT::Graphics::ShaderProgramVisibility::Vertex), - - NovelRT::Graphics::GraphicsPipelineResource(NovelRT::Graphics::GraphicsPipelineResourceKind::Texture, - NovelRT::Graphics::ShaderProgramVisibility::Pixel), - }; - - auto vertexShaderProgram = _graphicsDevice->CreateShaderProgram( - "main", NovelRT::Graphics::ShaderProgramKind::Vertex, vertShaderData.shaderCode); - auto pixelShaderProgram = _graphicsDevice->CreateShaderProgram( - "main", NovelRT::Graphics::ShaderProgramKind::Pixel, pixelShaderData.shaderCode); - auto signature = _graphicsDevice->CreatePipelineSignature( - NovelRT::Graphics::GraphicsPipelineBlendFactor::SrcAlpha, - NovelRT::Graphics::GraphicsPipelineBlendFactor::OneMinusSrcAlpha, inputs, resources); - auto pipeline = _graphicsDevice->CreatePipeline(signature, vertexShaderProgram, pixelShaderProgram); - - _defaultGraphicsPipelinePtr = - RegisterPipeline("default", pipeline, vertShaderData.databaseHandle, pixelShaderData.databaseHandle); - - auto graphicsContext = _graphicsDevice->GetCurrentContext(); - _resourceManager.getActual().PrepForFrameWithContextIndex(graphicsContext->GetIndex()); - - graphicsContext->BeginFrame(); - auto pVertexBuffer = std::vector{ - TexturedVertex{Maths::GeoVector3F(-0.5, +0.5, 0), Maths::GeoVector2F(0.0f, 0.0f)}, - TexturedVertex{Maths::GeoVector3F(+0.5, +0.5, 0), Maths::GeoVector2F(1.0f, 0.0f)}, - TexturedVertex{Maths::GeoVector3F(+0.5, -0.5, 0), Maths::GeoVector2F(1.0f, 1.0f)}, - TexturedVertex{Maths::GeoVector3F(+0.5, -0.5, 0), Maths::GeoVector2F(1.0f, 1.0f)}, - TexturedVertex{Maths::GeoVector3F(-0.5, -0.5, 0), Maths::GeoVector2F(0.0f, 1.0f)}, - TexturedVertex{Maths::GeoVector3F(-0.5, +0.5, 0), Maths::GeoVector2F(0.0f, 0.0f)}}; - - auto spriteMeshFuture = LoadVertexDataRaw("default", pVertexBuffer); - - ResolveGpuFutures(); - - _defaultSpriteMeshPtr = spriteMeshFuture.GetBackingConcurrentSharedPtr(); - - auto windowingDevice = _windowingPluginProvider->GetWindowingDevice(); - - auto size = windowingDevice->GetSize(); - float width = size.x; - float height = size.y; - float halfWidth = width / 2.0f; - float halfHeight = height / 2.0f; - float left = -halfWidth; - float right = +halfWidth; - float top = -halfHeight; - float bottom = +halfHeight; - - auto position = Maths::GeoVector2F::Zero(); - auto projectionMatrix = Maths::GeoMatrix4x4F::CreateOrthographic(left, right, bottom, top, 0.1f, 65535.0f); - auto viewMatrix = Maths::GeoMatrix4x4F::CreateFromLookAt(Maths::GeoVector3F(position.x, position.y, -1.0f), - Maths::GeoVector3F(position.x, position.y, 0.0f), - Maths::GeoVector3F(0, -1, 0)); - - // This is correct for row-major. :] - auto frameTransform = viewMatrix * projectionMatrix; - - _frameMatrixConstantBufferRegion = _resourceManager.getActual().LoadConstantBufferDataToNewRegion( - &frameTransform, sizeof(Maths::GeoMatrix4x4F)); - - graphicsContext->EndFrame(); - _graphicsDevice->Signal(graphicsContext->GetFence()); - _graphicsDevice->WaitForIdle(); - - windowingDevice->SizeChanged += [&](Maths::GeoVector2F newSize) { - float width = newSize.x; - float height = newSize.y; - float halfWidth = width / 2.0f; - float halfHeight = height / 2.0f; - float left = -halfWidth; - float right = +halfWidth; - float top = -halfHeight; - float bottom = +halfHeight; - - auto position = Maths::GeoVector2F::Zero(); - auto projectionMatrix = Maths::GeoMatrix4x4F::CreateOrthographic(left, right, bottom, top, 0.1f, 65535.0f); - auto viewMatrix = Maths::GeoMatrix4x4F::CreateFromLookAt(Maths::GeoVector3F(position.x, position.y, -1.0f), - Maths::GeoVector3F(position.x, position.y, 0.0f), - Maths::GeoVector3F(0, -1, 0)); - - auto frameTransform = viewMatrix * projectionMatrix; // This is correct for row-major. :] - - _frameMatrixConstantBufferRegion = _resourceManager.getActual().LoadConstantBufferDataToNewRegion( - &frameTransform, sizeof(Maths::GeoMatrix4x4F)); - ; - }; - } - - void DefaultRenderingSystem::Update(Timing::Timestamp delta, Ecs::Catalogue catalogue) - { - auto dummyRegion = NovelRT::Graphics::GraphicsMemoryRegion( - 0, nullptr, _graphicsDevice, false, 0, 0); - auto& gpuResourceManager = _resourceManager.getActual(); - - auto context = _graphicsDevice->GetCurrentContext(); - gpuResourceManager.PrepForFrameWithContextIndex(context->GetIndex()); - context->BeginFrame(); - - ResolveGpuResourceCleanup(); - ResolveGpuFutures(); - - context->BeginDrawing(_backgroundColour); - - auto [renderComponents, transformComponents, entityGraphComponents] = - catalogue.GetComponentViews(); - - std::map> transformLayerMap{}; - - for (auto [entity, transformComponent] : transformComponents) - { - RenderComponent renderComponent{}; - - if (!renderComponents.TryGetComponent(entity, renderComponent)) - { - continue; - } - - int32_t layer = static_cast(transformComponent.positionAndLayer.z); - - if (transformLayerMap.find(layer) == transformLayerMap.end()) - { - transformLayerMap[layer] = std::vector{}; - transformLayerMap[layer].reserve(1000); - } - - transformLayerMap[layer].emplace_back(entity); - } - - struct GpuSpanCounter - { - Maths::GeoMatrix4x4F* gpuData = nullptr; - size_t currentIndex = 0; - }; - - std::unordered_map> gpuSpanCounterMap{}; - - for (auto reverseIt = transformLayerMap.rbegin(); reverseIt != transformLayerMap.rend(); reverseIt++) - { - auto&& [layer, entityVector] = *reverseIt; - - for (EntityId entity : entityVector) - { - RenderComponent renderComponent = renderComponents.GetComponentUnsafe(entity); - TransformComponent transformComponent = transformComponents.GetComponentUnsafe(entity); - - if (gpuSpanCounterMap.find(renderComponent.primitiveInfoId) == gpuSpanCounterMap.end()) - { - gpuSpanCounterMap[renderComponent.primitiveInfoId] = std::map{}; - gpuSpanCounterMap[renderComponent.primitiveInfoId][layer] = - GpuSpanCounter{gpuResourceManager.MapConstantBufferRegionForWriting( - _primitiveConfigurations[renderComponent.primitiveInfoId] - .gpuTransformConstantBufferRegions[layer]), - 0}; - } - - auto textureInfo = GetExistingTexture(renderComponent.textureId); - GpuSpanCounter& tempSpanCounter = gpuSpanCounterMap[renderComponent.primitiveInfoId][layer]; - auto scaleValue = Maths::GeoVector2F::Uniform(500); - float aspect = static_cast(textureInfo->height) / static_cast(textureInfo->width); - scaleValue.y *= aspect; - Maths::GeoMatrix4x4F matrixToInsert = Maths::GeoMatrix4x4F::GetDefaultIdentity(); - - std::vector parentTransforms{}; - - auto graphComponent = entityGraphComponents.GetComponentUnsafe(entity); - - while (graphComponent.parent != std::numeric_limits::max()) - { - TransformComponent transform = transformComponents.GetComponentUnsafe(graphComponent.parent); - parentTransforms.emplace_back(transform); - graphComponent = entityGraphComponents.GetComponentUnsafe(graphComponent.parent); - } - - scaleValue *= transformComponent.scale; - - // TODO: There is definitely a better way to handle this but I'm being stupid. - for (auto it = parentTransforms.rbegin(); it != parentTransforms.rend(); it++) - { - matrixToInsert.Translate(it->positionAndLayer); - matrixToInsert.Rotate(it->rotationInRadians); - scaleValue *= it->scale; - } - - matrixToInsert.Translate(transformComponent.positionAndLayer); - matrixToInsert.Rotate(transformComponent.rotationInRadians); - matrixToInsert.Scale(scaleValue); // scale based on aspect. :] - - tempSpanCounter.gpuData[tempSpanCounter.currentIndex++] = matrixToInsert; - } - } - - gpuResourceManager.UnmapAndWriteAllConstantBuffers(); - - int32_t farthestLayer = transformLayerMap.rbegin()->first; - int32_t closestLayer = transformLayerMap.begin()->first; - - std::vector> primitiveCache{}; - primitiveCache.reserve(1000); - - for (int32_t layer = farthestLayer; layer >= closestLayer; layer--) - { - for (auto&& [primitiveInfoId, spanCounterMap] : gpuSpanCounterMap) - { - auto& primitiveInfo = _primitiveConfigurations[primitiveInfoId]; - auto pipelineInfo = GetExistingPipelineInfo(primitiveInfo.ecsPipelineId); - auto texture = GetExistingTexture(primitiveInfo.ecsTextureId); - auto mesh = GetExistingVertexData(primitiveInfo.ecsVertexDataId); - - std::vector> - inputResourceRegions{}; - - if (pipelineInfo->useEcsTransforms) - { - size_t customConstantBuffersCount = (pipelineInfo->gpuCustomConstantBuffers != nullptr) - ? pipelineInfo->gpuCustomConstantBuffers->size() - : 0; - inputResourceRegions.reserve( - 2 + customConstantBuffersCount); // 2 for the frame transform and the ecs transform data - inputResourceRegions.emplace_back(_frameMatrixConstantBufferRegion); - inputResourceRegions.emplace_back(primitiveInfo.gpuTransformConstantBufferRegions[layer]); - } - else - { - size_t customConstantBuffersCount = (pipelineInfo->gpuCustomConstantBuffers != nullptr) - ? pipelineInfo->gpuCustomConstantBuffers->size() - : 0; - inputResourceRegions.reserve(customConstantBuffersCount); - } - - inputResourceRegions.emplace_back(texture->gpuTextureRegion); - - if (pipelineInfo->gpuCustomConstantBuffers != nullptr) - { - for (auto&& region : *pipelineInfo->gpuCustomConstantBuffers) - { - inputResourceRegions.emplace_back(region); - } - } - - size_t amountToDraw = spanCounterMap[layer].currentIndex; - - auto primitive = _graphicsDevice->CreatePrimitive(pipelineInfo->gpuPipeline.GetUnderlyingSharedPtr(), - mesh->gpuVertexRegion, sizeof(TexturedVertex), - dummyRegion, 0, inputResourceRegions); - context->Draw(primitive, static_cast(amountToDraw)); - primitiveCache.emplace_back(primitive); - } - } - - UIRenderEvent(*this, UIRenderEventArgs{delta, catalogue, _surfaceContext, _graphicsAdapter, _graphicsDevice, - context, gpuResourceManager, _frameMatrixConstantBufferRegion}); - - context->EndDrawing(); - context->EndFrame(); - _graphicsDevice->PresentFrame(); - _graphicsDevice->WaitForIdle(); - } - - Threading::FutureResult DefaultRenderingSystem::GetOrLoadTexture(const std::string& textureName) - { - std::scoped_lock guard(_textureQueueMapMutex); - - auto resultIterator = - std::find_if(_namedTextureInfoObjects.begin(), _namedTextureInfoObjects.end(), - [textureName](const auto& pair) { return textureName == pair.second->textureName; }); - - if (resultIterator == _namedTextureInfoObjects.end()) - { - auto concurrentPtr = Threading::MakeConcurrentShared(); - concurrentPtr->textureName = textureName; - concurrentPtr->ecsId = _textureIdFactory.GetNext(); - - _texturesToInitialise.push(concurrentPtr); - return Threading::FutureResult(concurrentPtr, *concurrentPtr); - } - - return Threading::FutureResult(resultIterator->second, TextureInfo{}); - } - - Threading::FutureResult DefaultRenderingSystem::LoadTextureDataRawUntyped( - const std::string& textureDataName, - void* data, - size_t dataTypeSize, - size_t dataLength, - uint32_t width, - uint32_t height, - uuids::uuid textureAssetDataHandle) - { - std::scoped_lock guard(_textureQueueMapMutex); - - auto ptr = Threading::MakeConcurrentShared(); - std::vector textureData{}; - const size_t size = dataTypeSize * dataLength; - textureData.resize(size); - - NovelRT::Utilities::Memory::Copy(textureData.data(), size, data, size); - - ptr->textureName = textureDataName; - ptr->textureData = textureData; - ptr->width = width; - ptr->height = height; - ptr->ecsId = _textureIdFactory.GetNext(); - ptr->textureAssetDataHandle = textureAssetDataHandle; - _texturesToInitialise.push(ptr); - - return Threading::FutureResult(ptr, *ptr); - } - - Threading::ConcurrentSharedPtr DefaultRenderingSystem::GetExistingTexture(Atom ecsId) - { - std::scoped_lock guard(_textureQueueMapMutex); - return _namedTextureInfoObjects.at(ecsId); - } - - Threading::ConcurrentSharedPtr DefaultRenderingSystem::GetExistingTexture(const std::string& name) - { - std::scoped_lock guard(_textureQueueMapMutex); - - for (auto&& pair : _namedTextureInfoObjects) - { - if (pair.second->textureName != name) - { - continue; - } - - return pair.second; - } - - throw Exceptions::KeyNotFoundException(); - } - - void DefaultRenderingSystem::DeleteTexture(Threading::ConcurrentSharedPtr texture) - { - std::scoped_lock guard(_textureQueueMapMutex); - - std::optional ecsId; - - for (auto&& pair : _namedTextureInfoObjects) - { - if (pair.second != texture) - { - continue; - } - - ecsId = pair.first; - break; - } - - _texturesToDelete.push(ecsId.value()); - } - - void DefaultRenderingSystem::DeleteTexture(Atom ecsId) - { - std::scoped_lock guard(_textureQueueMapMutex); - - auto it = _namedTextureInfoObjects.find(ecsId); - - if (it == _namedTextureInfoObjects.end()) - { - throw Exceptions::KeyNotFoundException(); - } - - _texturesToDelete.push(ecsId); - } - - void DefaultRenderingSystem::DeleteTexture(const std::string& name) - { - std::scoped_lock guard(_textureQueueMapMutex); - - std::optional ecsId; - for (auto&& pair : _namedTextureInfoObjects) - { - if (pair.second->textureName != name) - { - continue; - } - - ecsId = pair.first; - break; - } - - if (!ecsId.has_value()) - { - throw Exceptions::KeyNotFoundException(); - } - - _texturesToDelete.push(ecsId.value()); - } - - Threading::FutureResult DefaultRenderingSystem::LoadVertexDataRawUntyped( - const std::string& vertexDataName, - void* data, - size_t dataTypeSize, - size_t dataLength) - { - std::scoped_lock guard(_vertexQueueMapMutex); - - auto ptr = Threading::MakeConcurrentShared(); - size_t size = dataTypeSize * dataLength; - ptr->vertexInfoName = vertexDataName; - ptr->stagingPtr = malloc(size); - if (ptr->stagingPtr == nullptr) - { - throw NovelRT::Exceptions::OutOfMemoryException(); - } - ptr->sizeOfVert = dataTypeSize; - ptr->stagingPtrLength = dataLength; - - NovelRT::Utilities::Memory::Copy(ptr->stagingPtr, size, data, size); - _vertexDataToInitialise.push(ptr); - - return Threading::FutureResult(ptr, VertexInfo{}); - } - - Threading::ConcurrentSharedPtr DefaultRenderingSystem::GetExistingVertexData( - const std::string& vertexDataName) - { - std::scoped_lock guard(_vertexQueueMapMutex); - - for (auto&& pair : _namedVertexInfoObjects) - { - if (pair.second->vertexInfoName != vertexDataName) - { - continue; - } - - return pair.second; - } - - throw Exceptions::KeyNotFoundException(); - } - - Threading::ConcurrentSharedPtr DefaultRenderingSystem::GetExistingVertexData(Atom ecsId) - { - std::scoped_lock guard(_vertexQueueMapMutex); - return _namedVertexInfoObjects.at(ecsId); - } - - void DefaultRenderingSystem::DeleteVertexData(Threading::ConcurrentSharedPtr vertexData) - { - std::scoped_lock guard(_vertexQueueMapMutex); - - std::optional ecsId; - for (auto&& pair : _namedVertexInfoObjects) - { - if (pair.second != vertexData) - { - continue; - } - - ecsId = pair.first; - } - - if (!ecsId.has_value()) - { - throw Exceptions::KeyNotFoundException(); - } - - _vertexDataToDelete.push(ecsId.value()); - } - - void DefaultRenderingSystem::DeleteVertexData(Atom ecsId) - { - std::scoped_lock guard(_vertexQueueMapMutex); - - auto it = _namedVertexInfoObjects.find(ecsId); - - if (it == _namedVertexInfoObjects.end()) - { - throw Exceptions::KeyNotFoundException(); - } - - _vertexDataToDelete.push(ecsId); - } - - void DefaultRenderingSystem::DeleteVertexData(const std::string& name) - { - std::scoped_lock guard(_vertexQueueMapMutex); - - std::optional ecsId; - for (auto&& pair : _namedVertexInfoObjects) - { - if (pair.second->vertexInfoName != name) - { - continue; - } - - ecsId = pair.first; - break; - } - - if (!ecsId.has_value()) - { - throw Exceptions::KeyNotFoundException(); - } - - _vertexDataToDelete.push(ecsId.value()); - } - - Threading::ConcurrentSharedPtr DefaultRenderingSystem::GetExistingPipelineInfo( - const std::string& name) - { - std::scoped_lock guard(_graphicsPipelineMapMutex); - - for (auto&& pair : _namedGraphicsPipelineInfoObjects) - { - if (pair.second->pipelineName != name) - { - continue; - } - - return pair.second; - } - - throw Exceptions::KeyNotFoundException(); - } - - Threading::ConcurrentSharedPtr DefaultRenderingSystem::GetExistingPipelineInfo(Atom ecsId) - { - std::scoped_lock guard(_graphicsPipelineMapMutex); - return _namedGraphicsPipelineInfoObjects.at(ecsId); - } - - Threading::ConcurrentSharedPtr DefaultRenderingSystem::RegisterPipeline( - const std::string& pipelineName, - std::shared_ptr pipeline, - uuids::uuid vertexShaderAssetHandle, - uuids::uuid pixelShaderAssetHandle, - std::vector> - customConstantBufferRegions, - bool useEcsTransforms) - { - static AtomFactory& ecsGraphicsPipelineIdFactory = AtomFactoryDatabase::GetFactory("EcsGraphicsPipelineId"); - - std::scoped_lock guard(_graphicsPipelineMapMutex); - - auto ptr = Threading::MakeConcurrentShared(); - ptr->gpuPipeline = Threading::ConcurrentSharedPtr(std::move(pipeline)); - ptr->pipelineName = pipelineName; - ptr->ecsId = ecsGraphicsPipelineIdFactory.GetNext(); - ptr->useEcsTransforms = useEcsTransforms; - ptr->vertexShaderAssetHandle = vertexShaderAssetHandle; - ptr->pixelShaderAssetHandle = pixelShaderAssetHandle; - - if (!customConstantBufferRegions.empty()) - { - auto rawShared = std::make_shared< - std::vector>>(); - *rawShared = std::move(customConstantBufferRegions); - ptr->gpuCustomConstantBuffers = Threading::ConcurrentSharedPtr< - std::vector>>( - std::move(rawShared)); - } - - _namedGraphicsPipelineInfoObjects.emplace(ptr->ecsId, ptr); - - return ptr; - } - - void DefaultRenderingSystem::UnregisterPipeline(Threading::ConcurrentSharedPtr pipelineInfo) - { - std::lock_guard guard(_graphicsPipelineMapMutex); - - std::optional ecsId; - for (auto&& pair : _namedGraphicsPipelineInfoObjects) - { - if (pair.second != pipelineInfo) - { - continue; - } - - ecsId = pair.first; - break; - } - - if (!ecsId.has_value()) - { - throw Exceptions::KeyNotFoundException(); - } - - _namedGraphicsPipelineInfoObjects.erase(ecsId.value()); - } - - void DefaultRenderingSystem::UnregisterPipeline(Atom ecsId) - { - std::lock_guard guard(_graphicsPipelineMapMutex); - auto it = _namedGraphicsPipelineInfoObjects.find(ecsId); - - if (it == _namedGraphicsPipelineInfoObjects.end()) - { - throw Exceptions::KeyNotFoundException(); - } - - _namedGraphicsPipelineInfoObjects.erase(ecsId); - } - - void DefaultRenderingSystem::UnregisterPipeline(const std::string& name) - { - std::lock_guard guard(_graphicsPipelineMapMutex); - - std::optional ecsId; - for (auto&& pair : _namedGraphicsPipelineInfoObjects) - { - if (pair.second->pipelineName != name) - { - continue; - } - - ecsId = pair.first; - break; - } - - if (!ecsId.has_value()) - { - throw Exceptions::KeyNotFoundException(); - } - - _namedGraphicsPipelineInfoObjects.erase(ecsId.value()); - } - - void DefaultRenderingSystem::AttachSpriteRenderingToEntity(EntityId entity, - Threading::ConcurrentSharedPtr texture, - Catalogue& catalogue) - { - auto [renderComponentView, transformComponentView, entityGraphComponentView] = - catalogue.GetComponentViews(); - - auto newRenderComponent = - RenderComponent{_defaultSpriteMeshPtr->ecsId, texture->ecsId, _defaultGraphicsPipelinePtr->ecsId}; - - bool assigned = false; - for (auto&& [primitiveInfoId, primitiveInfo] : _primitiveConfigurations) - { - if (primitiveInfo == newRenderComponent) - { - newRenderComponent.primitiveInfoId = primitiveInfoId; - assigned = true; - break; - } - } - - if (!assigned) - { - Atom newId = _ecsPrimitiveInfoConfigurationIdFactory.GetNext(); - GraphicsPrimitiveInfo newPrimitiveInfo{_defaultSpriteMeshPtr->ecsId, texture->ecsId, - _defaultGraphicsPipelinePtr->ecsId}; - newPrimitiveInfo.gpuTransformConstantBufferRegions[0] = - _resourceManager.getActual().AllocateConstantBufferRegion(sizeof(Maths::GeoMatrix4x4F) * 1000); - - _primitiveConfigurations.emplace(newId, newPrimitiveInfo); - newRenderComponent.primitiveInfoId = newId; - } - - renderComponentView.AddComponent(entity, newRenderComponent); - - if (!transformComponentView.HasComponent(entity)) - { - transformComponentView.AddComponent(entity); - } - - if (!entityGraphComponentView.HasComponent(entity)) - { - entityGraphComponentView.AddComponent(entity); - } - } - - EntityId DefaultRenderingSystem::CreateSpriteEntity(Threading::ConcurrentSharedPtr texture, - Catalogue& catalogue) - { - EntityId entity = catalogue.CreateEntity(); - AttachSpriteRenderingToEntity(entity, std::move(texture), catalogue); - return entity; - } - - EntityId DefaultRenderingSystem::CreateSpriteEntityOutsideOfSystem( - Threading::ConcurrentSharedPtr texture, - SystemScheduler& scheduler) - { - static AtomFactory& _entityIdFactory = AtomFactoryDatabase::GetFactory("EntityId"); - - EntityId entity = _entityIdFactory.GetNext(); - auto& registeredEntities = scheduler.GetEntityCache().GetRegisteredEntities(); - - while (std::find(registeredEntities.begin(), registeredEntities.end(), entity) != registeredEntities.end()) - { - entity = _entityIdFactory.GetNext(); - } - - scheduler.GetEntityCache().AddEntity(0, entity); - - auto newRenderComponent = - RenderComponent{_defaultSpriteMeshPtr->ecsId, texture->ecsId, _defaultGraphicsPipelinePtr->ecsId}; - - bool assigned = false; - for (auto&& [primitiveInfoId, primitiveInfo] : _primitiveConfigurations) - { - if (primitiveInfo == newRenderComponent) - { - newRenderComponent.primitiveInfoId = primitiveInfoId; - assigned = true; - break; - } - } - - if (!assigned) - { - Atom newId = _ecsPrimitiveInfoConfigurationIdFactory.GetNext(); - GraphicsPrimitiveInfo newPrimitiveInfo{_defaultSpriteMeshPtr->ecsId, texture->ecsId, - _defaultGraphicsPipelinePtr->ecsId}; - newPrimitiveInfo.gpuTransformConstantBufferRegions[0] = - _resourceManager.getActual().AllocateConstantBufferRegion(sizeof(Maths::GeoMatrix4x4F) * 1000); - - _primitiveConfigurations.emplace(newId, newPrimitiveInfo); - newRenderComponent.primitiveInfoId = newId; - } - - scheduler.GetComponentCache().GetComponentBuffer().PushComponentUpdateInstruction( - 0, entity, newRenderComponent); - - scheduler.GetComponentCache().GetComponentBuffer().PushComponentUpdateInstruction( - 0, entity, TransformComponent{}); - - scheduler.GetComponentCache().GetComponentBuffer().PushComponentUpdateInstruction( - 0, entity, EntityGraphComponent{}); - - scheduler.GetEntityCache().ProcessEntityRegistrationRequestsFromThreads(); - scheduler.GetComponentCache().PrepAllBuffersForNextFrame(std::vector{}); - return entity; - } - - void DefaultRenderingSystem::ForceVertexTextureFutureResolution() - { - auto currentContext = _graphicsDevice->GetCurrentContext(); - currentContext->BeginFrame(); - ResolveGpuFutures(); - currentContext->EndFrame(); - _graphicsDevice->Signal(currentContext->GetFence()); - _graphicsDevice->WaitForIdle(); - } - - uuids::uuid DefaultRenderingSystem::GetVertexShaderGuidForPrimitiveInfo(Atom primitiveInfoId) const - { - return _namedGraphicsPipelineInfoObjects.at(_primitiveConfigurations.at(primitiveInfoId).ecsPipelineId) - ->vertexShaderAssetHandle; - } - - uuids::uuid DefaultRenderingSystem::GetPixelShaderGuidForPrimitiveInfo(Atom primitiveInfoId) const - { - return _namedGraphicsPipelineInfoObjects.at(_primitiveConfigurations.at(primitiveInfoId).ecsPipelineId) - ->pixelShaderAssetHandle; - } - - uuids::uuid DefaultRenderingSystem::GetGuidForTexture(Atom textureId) const - { - return _namedTextureInfoObjects.at(textureId)->textureAssetDataHandle; - } - - Atom DefaultRenderingSystem::GetTextureIdFromGuid(uuids::uuid assetGuid) const - { - for (auto&& [atomHandle, textureInfo] : _namedTextureInfoObjects) - { - if (textureInfo->textureAssetDataHandle != assetGuid) - { - continue; - } - - return atomHandle; - } - - throw Exceptions::KeyNotFoundException(); - } - - Atom DefaultRenderingSystem::GetPrimitiveInfoFromAssetGuids(uuids::uuid textureAssetGuid, - uuids::uuid vertexShaderAssetGuid, - uuids::uuid pixelShaderAssetGuid) const - { - for (auto&& [atomHandle, primitiveInfo] : _primitiveConfigurations) - { - auto pipeline = _namedGraphicsPipelineInfoObjects.at(primitiveInfo.ecsPipelineId); - - if (_namedTextureInfoObjects.at(primitiveInfo.ecsTextureId)->textureAssetDataHandle != textureAssetGuid || - pipeline->vertexShaderAssetHandle != vertexShaderAssetGuid || - pipeline->pixelShaderAssetHandle != pixelShaderAssetGuid) - { - continue; - } - - return atomHandle; - } - - throw Exceptions::KeyNotFoundException(); - } - - Atom DefaultRenderingSystem::GetPipelineFromAssetGuids(uuids::uuid vertexShaderAssetGuid, - uuids::uuid pixelShaderAssetGuid) const - { - for (auto&& [atomHandle, pipelineInfo] : _namedGraphicsPipelineInfoObjects) - { - if (pipelineInfo->vertexShaderAssetHandle != vertexShaderAssetGuid || - pipelineInfo->pixelShaderAssetHandle != pixelShaderAssetGuid) - { - continue; - } - - return atomHandle; - } - - throw Exceptions::KeyNotFoundException(); - } -} diff --git a/src/NovelRT/Persistence/Graphics/RenderingComponentPersistenceRule.cpp b/src/NovelRT/Persistence/Graphics/RenderingComponentPersistenceRule.cpp deleted file mode 100644 index 9235bf38c..000000000 --- a/src/NovelRT/Persistence/Graphics/RenderingComponentPersistenceRule.cpp +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root -// for more information. - -#include - -namespace NovelRT::Persistence::Graphics -{ - RenderingComponentPersistenceRule::RenderingComponentPersistenceRule( - std::shared_ptr renderingSystem) noexcept - : _renderingSystem(std::move(renderingSystem)) - { - } - - std::vector RenderingComponentPersistenceRule::ExecuteSerialiseModification( - NovelRT::Utilities::Misc::Span component) const noexcept - { - const Ecs::Graphics::RenderComponent* ptr = - reinterpret_cast(component.data()); - - uuids::uuid vertexShaderId = _renderingSystem->GetVertexShaderGuidForPrimitiveInfo(ptr->primitiveInfoId); - uuids::uuid pixelShaderId = _renderingSystem->GetPixelShaderGuidForPrimitiveInfo(ptr->primitiveInfoId); - - std::vector packedData(GetSerialisedSize()); - - auto uuidPtr = reinterpret_cast(packedData.data()); - - uuidPtr[0] = _renderingSystem->GetGuidForTexture(ptr->textureId); - uuidPtr[1] = vertexShaderId; - uuidPtr[2] = pixelShaderId; - - return packedData; - } - - std::vector RenderingComponentPersistenceRule::ExecuteDeserialiseModification( - NovelRT::Utilities::Misc::Span component) const noexcept - { - const uuids::uuid* guids = reinterpret_cast(component.data()); - - std::vector unpackedData(sizeof(Ecs::Graphics::RenderComponent)); - Ecs::Graphics::RenderComponent* ptr = reinterpret_cast(unpackedData.data()); - ptr->vertexDataId = _renderingSystem->GetDefaultVertexDataId(); - ptr->textureId = _renderingSystem->GetTextureIdFromGuid(guids[0]); - ptr->primitiveInfoId = _renderingSystem->GetPrimitiveInfoFromAssetGuids(guids[0], guids[1], guids[2]); - ptr->pipelineId = _renderingSystem->GetPipelineFromAssetGuids(guids[1], guids[2]); - - return unpackedData; - } -} \ No newline at end of file diff --git a/src/NovelRT/Persistence/Persistable.cpp b/src/NovelRT/Persistence/Persistable.cpp index 3523d81d8..4a5239c23 100644 --- a/src/NovelRT/Persistence/Persistable.cpp +++ b/src/NovelRT/Persistence/Persistable.cpp @@ -50,14 +50,4 @@ namespace NovelRT::Persistence auto newData = it->second->ExecuteDeserialiseModification(serialisedData); NovelRT::Utilities::Memory::Copy(writeToData.data(), writeToData.size(), newData.data(), writeToData.size()); } - - // TODO: Rework this at a later date. - void Persistable::LoadDefaultRules(std::shared_ptr renderingSystem) noexcept - { - auto& serialisationRules = GetSerialisationRules(); - - serialisationRules.emplace("NovelRT::Ecs::Graphics::RenderComponent", - std::unique_ptr( - new Graphics::RenderingComponentPersistenceRule(std::move(renderingSystem)))); - } } diff --git a/src/NovelRT/PluginManagement/TemporaryFnPtrs.cpp b/src/NovelRT/PluginManagement/TemporaryFnPtrs.cpp index 64802f1ad..13a9f8e21 100644 --- a/src/NovelRT/PluginManagement/TemporaryFnPtrs.cpp +++ b/src/NovelRT/PluginManagement/TemporaryFnPtrs.cpp @@ -1,18 +1,19 @@ // Copyright © Matt Jones and Contributors. Licensed under the MIT Licence (MIT). See LICENCE.md in the repository root // for more information. -#include #include #include #include #include #include +#include + namespace NovelRT::PluginManagement { - std::shared_ptr GetVulkanPluginProvider() noexcept + std::shared_ptr> GetVulkanPluginProvider() noexcept { - return std::make_shared(); + return std::make_shared>(); } std::shared_ptr GetGlfwWindowPluginProvider() noexcept { diff --git a/tests/NovelRT.Tests/CMakeLists.txt b/tests/NovelRT.Tests/CMakeLists.txt index 04b754cac..d3c91958a 100644 --- a/tests/NovelRT.Tests/CMakeLists.txt +++ b/tests/NovelRT.Tests/CMakeLists.txt @@ -7,7 +7,6 @@ set(SOURCES Ecs/ComponentBufferTest.cpp Ecs/ComponentCacheTest.cpp Ecs/ComponentViewTest.cpp - Ecs/ConfiguratorTest.cpp Ecs/EntityCacheTest.cpp Ecs/EntityGraphViewTest.cpp Ecs/LinkedEntityListViewTest.cpp diff --git a/tests/NovelRT.Tests/Ecs/ConfiguratorTest.cpp b/tests/NovelRT.Tests/Ecs/ConfiguratorTest.cpp index c414c7cd0..d9262e8ff 100644 --- a/tests/NovelRT.Tests/Ecs/ConfiguratorTest.cpp +++ b/tests/NovelRT.Tests/Ecs/ConfiguratorTest.cpp @@ -4,6 +4,8 @@ #include #include +#include + using namespace NovelRT::Ecs; using namespace NovelRT::Timing; diff --git a/thirdparty/CMakeLists.txt b/thirdparty/CMakeLists.txt index 53d5c6ed8..667fca012 100644 --- a/thirdparty/CMakeLists.txt +++ b/thirdparty/CMakeLists.txt @@ -71,8 +71,8 @@ thirdparty_module(SndFile URL_HASH SHA512=7e650af94068277246e4ccaf3b5dc20d0f93d2a2e0ecdf0f24f0be79196f879c21ec692ad48d39454f22dd01d9a4864d21458daa8d7b8f5ea4568c9551b345c1 ) thirdparty_module(spdlog - URL https://github.com/gabime/spdlog/archive/refs/tags/v1.10.0.zip - URL_HASH SHA512=9f1c778482446f52fb6e35f752226715412011f608bdcbfc87be5ae4a246d6733179a910fce09c2609e4dc1ba50664a6b0c3421749a7a12d8648dcf2b61c0b99 + URL https://github.com/gabime/spdlog/archive/refs/tags/v1.15.1.zip + URL_HASH SHA512=67b82452e046cb8d77082edeaf163460f2b171b3555c7feb32f5e0296921de2f3ebf279224509a8f0821947b274dd0b7f40ef01f1b8f612c80ba93cbc3e156cc ) thirdparty_module(stduuid URL https://github.com/mariusbancila/stduuid/archive/3afe7193facd5d674de709fccc44d5055e144d7a.zip