[WIP] Texture support

This commit is contained in:
2023-08-02 16:17:18 +02:00
parent cf91c9c67e
commit d340d91f52
8 changed files with 175 additions and 2 deletions

View File

@@ -13,7 +13,7 @@
#include <assimp/scene.h>
#include <assimp/mesh.h>
#include <assimp/postprocess.h>
#define ASSIMP_AVAILABLE
//#define ASSIMP_AVAILABLE
#endif
#include <stdexcept>

View File

@@ -0,0 +1,24 @@
/*
* 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 "UpdateFrequency.hpp"
#include "Base/ICloseable.hpp"
namespace openVulkanoCpp::Scene
{
struct Texture
{
ICloseable* renderTexture = nullptr;
void* textureBuffer;
Math::Vector3ui resolution;
size_t size;
bool updated = true;
UpdateFrequency updateFrequency = UpdateFrequency::Never;
ICloseable* vulkanTexture = nullptr;
};
}

View File

@@ -34,6 +34,52 @@ namespace openVulkanoCpp::Vulkan
{}, nullptr, nullptr, imgMemBarrier);
}
void Image::Init(const Device* device, const vk::Extent3D& resolution)
{
this->device = device->device;
vk::ImageCreateInfo imgCreateInfo;
imgCreateInfo.imageType = vk::ImageType::e2D;
imgCreateInfo.extent = resolution;
imgCreateInfo.mipLevels = 1;
imgCreateInfo.arrayLayers = 1;
imgCreateInfo.format = vk::Format::eR8G8B8Srgb;
imgCreateInfo.tiling = vk::ImageTiling::eOptimal;
imgCreateInfo.initialLayout = vk::ImageLayout::eUndefined;
imgCreateInfo.usage = vk::ImageUsageFlagBits::eTransferDst | vk::ImageUsageFlagBits::eSampled;
imgCreateInfo.sharingMode = vk::SharingMode::eExclusive;
imgCreateInfo.samples = vk::SampleCountFlagBits::e1;
vk::ImageViewCreateInfo imgViewCreateInfo;
imgViewCreateInfo.image = image;
imgViewCreateInfo.format = imgCreateInfo.format;
imgViewCreateInfo.viewType = vk::ImageViewType::e2D;
imgViewCreateInfo.subresourceRange.aspectMask = vk::ImageAspectFlagBits::eColor;
imgViewCreateInfo.subresourceRange.baseMipLevel = 0;
imgViewCreateInfo.subresourceRange.levelCount = 1;
imgViewCreateInfo.subresourceRange.baseArrayLayer = 0;
imgViewCreateInfo.subresourceRange.levelCount = 1;
Init(device, imgCreateInfo, imgViewCreateInfo);
CreateSampler();
}
void Image::CreateSampler()
{
vk::SamplerCreateInfo samplerCreateInfo;
samplerCreateInfo.magFilter = vk::Filter::eLinear;
samplerCreateInfo.minFilter = vk::Filter::eLinear;
samplerCreateInfo.mipmapMode = vk::SamplerMipmapMode::eLinear;
samplerCreateInfo.addressModeU = vk::SamplerAddressMode::eClampToEdge;
samplerCreateInfo.addressModeV = vk::SamplerAddressMode::eClampToEdge;
samplerCreateInfo.addressModeW = vk::SamplerAddressMode::eClampToEdge;
samplerCreateInfo.borderColor = vk::BorderColor::eFloatTransparentBlack;
samplerCreateInfo.unnormalizedCoordinates = false;
samplerCreateInfo.compareEnable = false;
sampler = this->device.createSampler(samplerCreateInfo);
}
void Image::Close()
{
if(sampler)

View File

@@ -38,6 +38,8 @@ namespace openVulkanoCpp::Vulkan
*/
void Init(const Device* device, const vk::ImageCreateInfo& imageCreateInfo, vk::ImageViewCreateInfo imageViewCreateInfo, const vk::MemoryPropertyFlags& memoryPropertyFlags = vk::MemoryPropertyFlagBits::eDeviceLocal);
void Init(const Device* device, const vk::Extent3D& resolution);
void SetLayout(vk::CommandBuffer& cmdBuffer, vk::ImageSubresourceRange subResourceRange, vk::ImageLayout newLayout, vk::ImageLayout oldLayout = vk::ImageLayout::eUndefined) const;
void SetLayout(vk::CommandBuffer& cmdBuffer, vk::ImageAspectFlags aspectMask, vk::ImageLayout newLayout, vk::ImageLayout oldLayout = vk::ImageLayout::eUndefined) const
@@ -45,6 +47,8 @@ namespace openVulkanoCpp::Vulkan
SetLayout(cmdBuffer, vk::ImageSubresourceRange(aspectMask, 0, 1, 0, 1), newLayout, oldLayout);
}
void CreateSampler();
void Close() override;
operator bool() const { return image.operator bool(); }
@@ -53,5 +57,7 @@ namespace openVulkanoCpp::Vulkan
vk::Image GetImage() override { return image; }
vk::ImageView GetView() override { return view; }
~Image() override { Close(); }
};
}

View File

@@ -38,6 +38,7 @@ namespace openVulkanoCpp::Vulkan
vk::PushConstantRange camPushConstantDescFrag = { vk::ShaderStageFlagBits::eFragment, camPushConstantDesc.size, camPushConstantDesc.size };
std::array<vk::PushConstantRange, 2> camPushConstantDescs = { camPushConstantDesc, camPushConstantDescFrag };
vk::DescriptorSetLayoutBinding nodeLayoutBinding = { 0, vk::DescriptorType::eUniformBufferDynamic, 1, vk::ShaderStageFlagBits::eVertex };
//vk::DescriptorSetLayoutBinding textureLayoutBinding = { 0, vk::DescriptorType::image };
std::array<vk::DescriptorSetLayoutBinding, 1> layoutBindings = { nodeLayoutBinding };
vk::DescriptorSetLayoutCreateInfo dslci = { {}, layoutBindings.size(), layoutBindings.data() };
descriptorSetLayout = device.createDescriptorSetLayout(dslci);

View File

@@ -6,10 +6,14 @@
#include "ResourceManager.hpp"
#include "Scene/Vertex.hpp"
#include "Scene/Geometry.hpp"
#include "Scene/Material.hpp"
#include "Vulkan/Context.hpp"
#include "Vulkan/Scene/VulkanShader.hpp"
#include "Vulkan/Scene/VulkanGeometry.hpp"
#include "Vulkan/Scene/VulkanNode.hpp"
#include "Vulkan/Scene/VulkanTexture.hpp"
#include "Vulkan/Image.hpp"
namespace openVulkanoCpp::Vulkan
{
@@ -115,6 +119,10 @@ namespace openVulkanoCpp::Vulkan
{
material->shader->renderShader = CreateShader(material->shader);
}
if (material->texture && !material->texture->renderTexture)
{
material->texture->renderTexture = PrepareTexture(material->texture);
}
}
void ResourceManager::PrepareNode(Scene::Node* node)
@@ -159,7 +167,7 @@ namespace openVulkanoCpp::Vulkan
}
}
}
ManagedBuffer* buffer = CreateBuffer(size, vk::BufferUsageFlagBits::eVertexBuffer, vk::MemoryPropertyFlagBits::eHostCoherent);
ManagedBuffer* buffer = CreateBuffer(size, vk::BufferUsageFlagBits::eVertexBuffer, vk::MemoryPropertyFlagBits::eHostCoherent/* | vk::MemoryPropertyFlagBits::eDeviceLocal*/);
return buffer;
}
@@ -196,6 +204,17 @@ namespace openVulkanoCpp::Vulkan
toFree[currentBuffer].clear();
}
void ResourceManager::CopyDataToImage(vk::DeviceSize size, void* data, Image* image)
{
ManagedBuffer* uploadBuffer = CreateBuffer(size, vk::BufferUsageFlagBits::eTransferSrc, vk::MemoryPropertyFlagBits::eHostCoherent | vk::MemoryPropertyFlagBits::eHostVisible);
uploadBuffer->Copy(data, size, 0);
vk::BufferImageCopy region(0, 0, 0, { vk::ImageAspectFlagBits::eColor, 0, 0, 1 }, { 0, 0, 0 }, image->extent);
cmdBuffers[currentBuffer].copyBufferToImage(uploadBuffer->buffer, image->image, vk::ImageLayout::eTransferDstOptimal, 1, &region);
FreeBuffer(uploadBuffer);
}
ManagedBuffer* ResourceManager::CreateDeviceOnlyBufferWithData(vk::DeviceSize size, vk::BufferUsageFlagBits usage, void* data)
{
ManagedBuffer* target = CreateBuffer(size, usage | vk::BufferUsageFlagBits::eTransferDst, vk::MemoryPropertyFlagBits::eDeviceLocal);
@@ -253,4 +272,14 @@ namespace openVulkanoCpp::Vulkan
shaders.push_back(vkShader);
return vkShader;
}
VulkanTexture* ResourceManager::PrepareTexture(Scene::Texture* texture)
{
VulkanTexture* vkTexture = new VulkanTexture();
vkTexture->Init(this, texture);
//vkTexture->
return vkTexture;
}
}

View File

@@ -10,6 +10,7 @@
#include "Base/ICloseable.hpp"
#include "IShaderOwner.hpp"
#include "ManagedResource.hpp"
#include "Vulkan/Image.hpp"
#include <mutex>
#include <functional>
@@ -20,11 +21,13 @@ namespace openVulkanoCpp
class Node;
class Geometry;
class Material;
class Texture;
}
namespace Vulkan
{
class VulkanGeometry;
class VulkanTexture;
class ResourceManager : virtual public ICloseable, virtual public IShaderOwner
{
@@ -68,12 +71,20 @@ namespace openVulkanoCpp
void PrepareNode(Scene::Node* node);
VulkanTexture* PrepareTexture(Scene::Texture* texture);
void RemoveShader(VulkanShader* shader) override;
void CopyDataToImage(vk::DeviceSize size, void* data, openVulkanoCpp::Vulkan::Image* image);
ManagedBuffer* CreateSharedMemoryBuffer(size_t size);
void FreeBuffer(ManagedBuffer* buffer);
[[nodiscard]] Context* GetContext() const { return context; }
[[nodiscard]] vk::Device GetDevice() const { return device; }
protected: // Allocation management
void DoFreeBuffer(ManagedBuffer* buffer);

View File

@@ -0,0 +1,56 @@
/*
* 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/.
*/
#include "IRecordable.hpp"
#include "Vulkan/Image.hpp"
#include "Vulkan/Context.hpp"
#include "Vulkan/Resources/ResourceManager.hpp"
#include "Scene/Texture.hpp"
namespace openVulkanoCpp::Vulkan
{
struct VulkanTexture : IRecordable, Image
{
Scene::Texture* m_texture = nullptr;
virtual void Init(ResourceManager* resManager, Scene::Texture* texture)
{
this->m_texture = texture;
Image::Init(resManager->GetContext()->device.get(), { texture->resolution.x, texture->resolution.y, texture->resolution.z });
resManager->CopyDataToImage(m_texture->size, m_texture->textureBuffer, this);
texture->updated = false;
}
void Record(vk::CommandBuffer& cmdBuffer, uint32_t bufferId) override
{
//cmdBuffer.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, )
}
};
struct VulkanTextureDynamic : VulkanTexture
{
uint32_t lastUpdate = -1;
ResourceManager* resourceManager;
void Init(ResourceManager* resManager, Scene::Texture* texture) override
{
resourceManager = resManager;
VulkanTexture::Init(resourceManager, texture);
lastUpdate = -1;
}
void Record(vk::CommandBuffer& cmdBuffer, uint32_t bufferId) override
{
if(bufferId != lastUpdate && m_texture->updated)
{
lastUpdate = bufferId;
resourceManager->CopyDataToImage(m_texture->size, m_texture->textureBuffer, this);
m_texture->updated = false;
}
VulkanTexture::Record(cmdBuffer, bufferId);
}
};
}