From f1bbe515bcc04d3edb1bbc74b43bd7ca9b95e25b Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Tue, 5 Mar 2024 00:16:44 +0100 Subject: [PATCH] Create a dummy texture as the lightmapper assumes we have textures --- src/lightmapper/vk_renderdevice.cpp | 67 +++++++++++++++++++++++++++++ src/lightmapper/vk_renderdevice.h | 25 ++++++++++- 2 files changed, 91 insertions(+), 1 deletion(-) diff --git a/src/lightmapper/vk_renderdevice.cpp b/src/lightmapper/vk_renderdevice.cpp index 94e9008..ecd2462 100644 --- a/src/lightmapper/vk_renderdevice.cpp +++ b/src/lightmapper/vk_renderdevice.cpp @@ -36,9 +36,14 @@ VulkanRenderDevice::VulkanRenderDevice() commands = std::make_unique(this); descriptors = std::make_unique(this); + samplers = std::make_unique(this); textures = std::make_unique(this); levelmesh = std::make_unique(this); lightmapper = std::make_unique(this); + + descriptors->AddBindlessTextureIndex(GetTextureManager()->GetNullTextureView(), GetSamplerManager()->Get()); + descriptors->AddBindlessTextureIndex(GetTextureManager()->GetNullTextureView(), GetSamplerManager()->Get()); + descriptors->UpdateBindlessDescriptorSet(); } VulkanRenderDevice::~VulkanRenderDevice() @@ -89,6 +94,51 @@ VulkanCommandBuffer* VkCommandBufferManager::GetTransferCommands() VkTextureManager::VkTextureManager(VulkanRenderDevice* fb) : fb(fb) { + CreateNullTexture(); +} + +void VkTextureManager::CreateNullTexture() +{ + NullTexture = ImageBuilder() + .Format(VK_FORMAT_R8G8B8A8_UNORM) + .Size(1, 1) + .Usage(VK_IMAGE_USAGE_SAMPLED_BIT) + .DebugName("VkTextureManager.NullTexture") + .Create(fb->GetDevice()); + + NullTextureView = ImageViewBuilder() + .Image(NullTexture.get(), VK_FORMAT_R8G8B8A8_UNORM) + .DebugName("VkTextureManager.NullTextureView") + .Create(fb->GetDevice()); + + auto stagingBuffer = BufferBuilder() + .Size(4) + .Usage(VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_CPU_ONLY) + .DebugName("VkTextureManager.NullTextureStaging") + .Create(fb->GetDevice()); + + // Put white in the texture + uint32_t* data = (uint32_t*)stagingBuffer->Map(0, 4); + *data = 0xffffffff; + stagingBuffer->Unmap(); + + PipelineBarrier() + .AddImage(NullTexture.get(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_ASPECT_COLOR_BIT) + .Execute(fb->GetCommands()->GetTransferCommands(), VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); + + VkBufferImageCopy region = {}; + region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + region.imageSubresource.layerCount = 1; + region.imageExtent.depth = 1; + region.imageExtent.width = 1; + region.imageExtent.height = 1; + fb->GetCommands()->GetTransferCommands()->copyBufferToImage(stagingBuffer->buffer, NullTexture->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); + + fb->GetCommands()->TransferDeleteList->Add(std::move(stagingBuffer)); + + PipelineBarrier() + .AddImage(NullTexture.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_ASPECT_COLOR_BIT) + .Execute(fb->GetCommands()->GetTransferCommands(), VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); } void VkTextureManager::CreateLightmap(int newLMTextureSize, int newLMTextureCount) @@ -157,6 +207,20 @@ void VkTextureManager::DownloadLightmap(int arrayIndex, uint16_t* buffer) ///////////////////////////////////////////////////////////////////////////// +VkSamplerManager::VkSamplerManager(VulkanRenderDevice* fb) : fb(fb) +{ + Sampler = SamplerBuilder() + .MagFilter(VK_FILTER_NEAREST) + .MinFilter(VK_FILTER_NEAREST) + .AddressMode(VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, VK_SAMPLER_ADDRESS_MODE_REPEAT) + .MipmapMode(VK_SAMPLER_MIPMAP_MODE_NEAREST) + .MaxLod(0.25f) + .DebugName("VkSamplerManager.Sampler") + .Create(fb->GetDevice()); +} + +///////////////////////////////////////////////////////////////////////////// + VkDescriptorSetManager::VkDescriptorSetManager(VulkanRenderDevice* fb) : fb(fb) { CreateBindlessDescriptorSet(); @@ -196,3 +260,6 @@ int VkDescriptorSetManager::AddBindlessTextureIndex(VulkanImageView* imageview, WriteBindless.AddCombinedImageSampler(BindlessDescriptorSet.get(), 0, index, imageview, sampler, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); return index; } + +///////////////////////////////////////////////////////////////////////////// + diff --git a/src/lightmapper/vk_renderdevice.h b/src/lightmapper/vk_renderdevice.h index 080d3bc..1b5ecd2 100644 --- a/src/lightmapper/vk_renderdevice.h +++ b/src/lightmapper/vk_renderdevice.h @@ -11,6 +11,7 @@ class VkLightmapper; class VkCommandBufferManager; class VkDescriptorSetManager; class VkTextureManager; +class VkSamplerManager; class VulkanRenderDevice { @@ -22,10 +23,11 @@ public: VkCommandBufferManager* GetCommands() { return commands.get(); } VkDescriptorSetManager* GetDescriptorSetManager() { return descriptors.get(); } VkTextureManager* GetTextureManager() { return textures.get(); } + VkSamplerManager* GetSamplerManager() { return samplers.get(); } VkLevelMesh* GetLevelMesh() { return levelmesh.get(); } VkLightmapper* GetLightmapper() { return lightmapper.get(); } - int GetBindlessTextureIndex(FTextureID texture) { return 0; } + int GetBindlessTextureIndex(FTextureID texture) { return texture.isValid() ? 1 : 0; } bool IsRayQueryEnabled() const { return useRayQuery; } @@ -36,6 +38,7 @@ private: std::unique_ptr commands; std::unique_ptr descriptors; std::unique_ptr textures; + std::unique_ptr samplers; std::unique_ptr levelmesh; std::unique_ptr lightmapper; }; @@ -117,12 +120,32 @@ public: void CreateLightmap(int newLMTextureSize, int newLMTextureCount); void DownloadLightmap(int arrayIndex, uint16_t* buffer); + VulkanImage* GetNullTexture() { return NullTexture.get(); } + VulkanImageView* GetNullTextureView() { return NullTextureView.get(); } + VkTextureImage Lightmap; int LMTextureSize = 0; int LMTextureCount = 0; private: + void CreateNullTexture(); + VulkanRenderDevice* fb = nullptr; + + std::unique_ptr NullTexture; + std::unique_ptr NullTextureView; +}; + +class VkSamplerManager +{ +public: + VkSamplerManager(VulkanRenderDevice* fb); + + VulkanSampler* Get() { return Sampler.get(); } + +private: + VulkanRenderDevice* fb = nullptr; + std::unique_ptr Sampler; }; class VkDescriptorSetManager