[WIP] Texture support
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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(); }
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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, ®ion);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
56
openVulkanoCpp/Vulkan/Scene/VulkanTexture.hpp
Normal file
56
openVulkanoCpp/Vulkan/Scene/VulkanTexture.hpp
Normal 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);
|
||||
}
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user