Experimental shared memory texture handling

This commit is contained in:
Georg Hagen
2024-07-23 01:21:27 +02:00
parent d64bb7a530
commit 75aa36c024
9 changed files with 76 additions and 7 deletions

View File

@@ -6,6 +6,7 @@
#pragma once
#include "IResourceManager.hpp"
#include "Base/ITickable.hpp"
#include "Base/ICloseable.hpp"
#include "Scene/Scene.hpp"
@@ -32,5 +33,7 @@ namespace OpenVulkano
virtual void SetActiveUi(Scene::UI::Ui* ui) = 0;
virtual Scene::UI::Ui* GetActiveUi() = 0;
virtual IResourceManager* GetIResourceManager() = 0;
};
}

View File

@@ -0,0 +1,25 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once
#include "Base/Wrapper.hpp"
#include "Math/Math.hpp"
#include "Scene/DataFormat.hpp"
namespace OpenVulkano
{
namespace Scene
{
class Texture;
}
class IResourceManager
{
public:
[[nodiscard]] virtual Unique<Scene::Texture> CreateSharedMemoryTexture(const Math::Vector3ui& resolution, DataFormat format) = 0;
};
}

View File

@@ -202,7 +202,7 @@ namespace OpenVulkano::Vulkan
bool Device::GetMemoryType(uint32_t typeBits, const vk::MemoryPropertyFlags& properties, uint32_t* typeIndex) const
{
for (uint32_t i = 0; i < 32; i++)
for (uint32_t i = 0; i < 32 && typeBits; i++)
{
if ((typeBits & 1) == 1)
{

View File

@@ -35,14 +35,22 @@ namespace OpenVulkano::Vulkan
cmdBuffer.pipelineBarrier(/*VulkanUtils::GetPipelineStageForLayout(oldLayout)*/vk::PipelineStageFlagBits::eTopOfPipe, /*VulkanUtils::GetPipelineStageForLayout(newLayout)*/ vk::PipelineStageFlagBits::eTransfer, {}, nullptr, nullptr, imgMemBarrier);
}
void Image::Init(const Device* device, const DataFormat& format, const vk::Extent3D& resolution)
void Image::Init(const Device* device, const DataFormat& format, const vk::Extent3D& resolution, const vk::MemoryPropertyFlags& memoryPropertyFlags)
{
vk::ImageCreateInfo imgCreateInfo { {}, vk::ImageType::e2D, format, resolution, 1, 1 };
imgCreateInfo.usage = vk::ImageUsageFlagBits::eTransferDst | vk::ImageUsageFlagBits::eSampled;
imgCreateInfo.tiling = vk::ImageTiling::eOptimal;
if (memoryPropertyFlags & vk::MemoryPropertyFlagBits::eHostVisible)
{
imgCreateInfo.tiling = vk::ImageTiling::eLinear;
imgCreateInfo.initialLayout = vk::ImageLayout::ePreinitialized;
}
else
{
imgCreateInfo.tiling = vk::ImageTiling::eOptimal;
imgCreateInfo.initialLayout = vk::ImageLayout::eUndefined;
}
imgCreateInfo.sharingMode = vk::SharingMode::eExclusive;
imgCreateInfo.initialLayout = vk::ImageLayout::eUndefined;
vk::ImageViewCreateInfo imgViewCreateInfo { {}, image, vk::ImageViewType::e2D, imgCreateInfo.format };
imgViewCreateInfo.subresourceRange.aspectMask = vk::ImageAspectFlagBits::eColor;
@@ -51,7 +59,7 @@ namespace OpenVulkano::Vulkan
imgViewCreateInfo.subresourceRange.baseArrayLayer = 0;
imgViewCreateInfo.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS;
Init(device, imgCreateInfo, imgViewCreateInfo);
Init(device, imgCreateInfo, imgViewCreateInfo, true, memoryPropertyFlags);
}
void Image::Close()

View File

@@ -38,7 +38,7 @@ namespace OpenVulkano::Vulkan
*/
void Init(const Device* device, const vk::ImageCreateInfo& imageCreateInfo, vk::ImageViewCreateInfo imageViewCreateInfo, bool allocateMem = true, const vk::MemoryPropertyFlags& memoryPropertyFlags = vk::MemoryPropertyFlagBits::eDeviceLocal);
void Init(const Device* device, const DataFormat& format, const vk::Extent3D& resolution);
void Init(const Device* device, const DataFormat& format, const vk::Extent3D& resolution, const vk::MemoryPropertyFlags& memoryPropertyFlags = vk::MemoryPropertyFlagBits::eDeviceLocal);
void SetLayout(vk::CommandBuffer& cmdBuffer, const vk::ImageSubresourceRange& subResourceRange, vk::ImageLayout newLayout, vk::ImageLayout oldLayout = vk::ImageLayout::eUndefined) const;

View File

@@ -84,5 +84,7 @@ namespace OpenVulkano::Vulkan
void RegisterCloseable(ICloseable* closeable) { closeables.push_back(closeable); }
void UnregisterCloseable(ICloseable* closeable) { Utils::Remove(closeables, closeable); }
IResourceManager* GetIResourceManager() override { return &resourceManager; }
};
}

View File

@@ -365,4 +365,19 @@ namespace OpenVulkano::Vulkan
if (!sampler) sampler = device.createSampler(samplerConfig);
return sampler;
}
Unique<Scene::Texture> ResourceManager::CreateSharedMemoryTexture(const Math::Vector3ui& resolution, DataFormat format)
{
const std::unique_lock lock(mutex);
Unique<Scene::Texture> texture = std::make_unique<Scene::Texture>();
texture->resolution = resolution;
texture->format = format;
texture->size = resolution.x * resolution.y * resolution.z * format.GetBytesPerPixel();
VulkanTexture* vkTexture = new VulkanTexture();
vkTexture->InitSharedMem(this, texture.get(), GetDescriptorLayoutSet(Scene::Texture::DESCRIPTOR_SET_LAYOUT_BINDING), Scene::Texture::DESCRIPTOR_SET_LAYOUT_BINDING);
textures.emplace_back(vkTexture);
return texture;
}
}

View File

@@ -14,6 +14,7 @@
#include "IShaderOwner.hpp"
#include "MemoryPool.hpp"
#include "Base/Wrapper.hpp"
#include "Base/Render/IResourceManager.hpp"
#include "Vulkan/Image.hpp"
#include "Scene/Shader/DescriptorInputDescription.hpp"
#include <vulkan/vulkan.hpp>
@@ -47,7 +48,7 @@ namespace OpenVulkano
class ManagedBuffer;
class MemoryAllocation;
class ResourceManager : public IShaderOwner
class ResourceManager : public IShaderOwner, public IResourceManager
{
friend UniformBuffer;
friend VulkanTexture;
@@ -118,6 +119,8 @@ namespace OpenVulkano
vk::Sampler CreateSampler(const vk::SamplerCreateInfo& samplerConfig);
[[nodiscard]] Unique<Scene::Texture> CreateSharedMemoryTexture(const Math::Vector3ui& resolution, DataFormat format) override;
protected: // Allocation management
MemoryPool::ManagedBufferPtr CreateDeviceOnlyBufferWithData(vk::DeviceSize size, vk::BufferUsageFlagBits usage, const void* data);

View File

@@ -37,6 +37,19 @@ namespace OpenVulkano::Vulkan
texture->renderTexture = this;
}
void InitSharedMem(ResourceManager* resManager, Scene::Texture* texture, vk::DescriptorSetLayout* descriptorSetLayout, const DescriptorSetLayoutBinding& binding)
{
m_texture = texture;
Image::Init(resManager->GetContext()->device.get(), texture->format, { texture->resolution.x, texture->resolution.y, texture->resolution.z }, vk::MemoryPropertyFlagBits::eDeviceLocal | vk::MemoryPropertyFlagBits::eHostVisible);
texture->updated = false;
texture->textureBuffer = Map();
m_sampler = resManager->CreateSampler(DEFAULT_SAMPLER_CONFIG);
SetDescriptorSet(resManager, descriptorSetLayout, binding);
texture->renderTexture = this;
}
virtual ~VulkanTexture() override
{
if (m_texture) Close();