Add lightmap texture support to vulkan backend

Also fix a warning in SetFlatVertex
This commit is contained in:
Magnus Norddahl 2021-09-25 00:13:25 +02:00
commit 63ecb36889
9 changed files with 137 additions and 9 deletions

View file

@ -582,6 +582,81 @@ void VulkanFrameBuffer::BeginFrame()
}
}
void VulkanFrameBuffer::InitLightmap(FLevelLocals* Level)
{
if (Level->LMTextureData.Size() > 0)
{
int w = Level->LMTextureSize;
int h = Level->LMTextureSize;
int count = Level->LMTextureCount;
int pixelsize = 8;
auto& lightmap = mActiveRenderBuffers->Lightmap;
if (lightmap.Image)
{
FrameDeleteList.Images.push_back(std::move(lightmap.Image));
FrameDeleteList.ImageViews.push_back(std::move(lightmap.View));
lightmap.reset();
}
ImageBuilder builder;
builder.setSize(w, h, 1, count);
builder.setFormat(VK_FORMAT_R16G16B16A16_SFLOAT);
builder.setUsage(VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
lightmap.Image = builder.create(device);
lightmap.Image->SetDebugName("VkRenderBuffers.Lightmap");
ImageViewBuilder viewbuilder;
viewbuilder.setType(VK_IMAGE_VIEW_TYPE_2D_ARRAY);
viewbuilder.setImage(lightmap.Image.get(), VK_FORMAT_R16G16B16A16_SFLOAT);
lightmap.View = viewbuilder.create(device);
lightmap.View->SetDebugName("VkRenderBuffers.LightmapView");
auto cmdbuffer = GetTransferCommands();
int totalSize = w * h * count * pixelsize;
BufferBuilder bufbuilder;
bufbuilder.setSize(totalSize);
bufbuilder.setUsage(VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_CPU_ONLY);
std::unique_ptr<VulkanBuffer> stagingBuffer = bufbuilder.create(device);
stagingBuffer->SetDebugName("VkHardwareTexture.mStagingBuffer");
uint16_t one = 0x3c00; // half-float 1.0
uint16_t* src = &Level->LMTextureData[0];
uint16_t* data = (uint16_t*)stagingBuffer->Map(0, totalSize);
for (int i = w * h * count; i > 0; i--)
{
*(data++) = *(src++);
*(data++) = *(src++);
*(data++) = *(src++);
*(data++) = one;
}
stagingBuffer->Unmap();
VkImageTransition imageTransition;
imageTransition.addImage(&lightmap, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, true);
imageTransition.execute(cmdbuffer);
VkBufferImageCopy region = {};
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
region.imageSubresource.layerCount = count;
region.imageExtent.depth = 1;
region.imageExtent.width = w;
region.imageExtent.height = h;
cmdbuffer->copyBufferToImage(stagingBuffer->buffer, lightmap.Image->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
VkImageTransition barrier;
barrier.addImage(&lightmap, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, true);
barrier.execute(cmdbuffer);
FrameTextureUpload.Buffers.push_back(std::move(stagingBuffer));
FrameTextureUpload.TotalSize += totalSize;
Level->LMTextureData.Reset(); // We no longer need this, release the memory
}
}
void VulkanFrameBuffer::PushGroup(const FString &name)
{
if (!gpuStatActive)