Fix non-srgb texture loads and unnecessary dedicated memory.

This commit is contained in:
Anish Bhobe 2024-07-23 15:34:20 +02:00
parent 44121f1930
commit b9ee037216
3 changed files with 48 additions and 42 deletions

View File

@ -44,7 +44,7 @@ Texture::Init(const Device *device, const vk::Extent2D extent, vk::Format imageF
.initialLayout = vk::ImageLayout::eUndefined,
};
constexpr VmaAllocationCreateInfo allocationCreateInfo = {
.flags = VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT,
.flags = {},
.usage = VMA_MEMORY_USAGE_AUTO,
};

View File

@ -19,6 +19,7 @@
#include "image.h"
#include <EASTL/array.h>
#include <EASTL/hash_map.h>
#include <glm/gtc/type_ptr.hpp>
vec4
@ -46,15 +47,17 @@ VectorToVec3(const std::vector<double> &vec)
}
TextureHandle
ModelLoader::LoadImage(vk::CommandBuffer commandBuffer, StagingBuffer *stagingBuffer, tinygltf::Image *image) const
ModelLoader::LoadImage(StagingBuffer *stagingBuffer, tinygltf::Image *image, bool isSrgb) const
{
assert(image->component == 4);
vk::Format imageFormat = isSrgb ? vk::Format::eR8G8B8A8Srgb : vk::Format::eR8G8B8A8Unorm;
Texture texture;
usize byteSize = image->image.size();
texture.Init(m_ResourceManager->m_Device, {.width = Cast<u32>(image->width), .height = Cast<u32>(image->height)},
vk::Format::eR8G8B8A8Srgb, true, image->name.data());
imageFormat, true, image->name.data());
stagingBuffer->Init(m_ResourceManager->m_Device, byteSize);
stagingBuffer->Write(m_ResourceManager->m_Device, 0, byteSize, image->image.data());
@ -127,11 +130,11 @@ ModelLoader::LoadImage(vk::CommandBuffer commandBuffer, StagingBuffer *stagingBu
.imageExtent = texture.m_Extent,
};
commandBuffer.pipelineBarrier(vk::PipelineStageFlagBits::eTopOfPipe, vk::PipelineStageFlagBits::eTransfer, {}, 0,
m_CommandBuffer.pipelineBarrier(vk::PipelineStageFlagBits::eTopOfPipe, vk::PipelineStageFlagBits::eTransfer, {}, 0,
nullptr, 0, nullptr, 1, &imageStartBarrier);
commandBuffer.copyBufferToImage(stagingBuffer->m_Buffer, texture.m_Image, vk::ImageLayout::eTransferDstOptimal, 1,
m_CommandBuffer.copyBufferToImage(stagingBuffer->m_Buffer, texture.m_Image, vk::ImageLayout::eTransferDstOptimal, 1,
&imageCopy);
commandBuffer.pipelineBarrier(vk::PipelineStageFlagBits::eTransfer, vk::PipelineStageFlagBits::eTransfer, {}, 0,
m_CommandBuffer.pipelineBarrier(vk::PipelineStageFlagBits::eTransfer, vk::PipelineStageFlagBits::eTransfer, {}, 0,
nullptr, 0, nullptr, 1, &nextMipBarrier);
auto calcNextMip = [](i32 prev) { return eastl::max(prev / 2, 1); };
@ -174,17 +177,17 @@ ModelLoader::LoadImage(vk::CommandBuffer commandBuffer, StagingBuffer *stagingBu
};
nextMipBarrier.subresourceRange.baseMipLevel = currentMipLevel;
commandBuffer.blitImage(texture.m_Image, vk::ImageLayout::eTransferSrcOptimal, texture.m_Image,
m_CommandBuffer.blitImage(texture.m_Image, vk::ImageLayout::eTransferSrcOptimal, texture.m_Image,
vk::ImageLayout::eTransferDstOptimal, 1, &blitRegion, vk::Filter::eLinear);
commandBuffer.pipelineBarrier(vk::PipelineStageFlagBits::eTransfer, vk::PipelineStageFlagBits::eTransfer, {}, 0,
nullptr, 0, nullptr, 1, &nextMipBarrier);
m_CommandBuffer.pipelineBarrier(vk::PipelineStageFlagBits::eTransfer, vk::PipelineStageFlagBits::eTransfer, {},
0, nullptr, 0, nullptr, 1, &nextMipBarrier);
prevMipHeight = currentMipHeight;
prevMipWidth = currentMipWidth;
}
commandBuffer.pipelineBarrier(vk::PipelineStageFlagBits::eTransfer, vk::PipelineStageFlagBits::eFragmentShader, {},
0, nullptr, 0, nullptr, 1, &imageReadyBarrier);
m_CommandBuffer.pipelineBarrier(vk::PipelineStageFlagBits::eTransfer, vk::PipelineStageFlagBits::eFragmentShader,
{}, 0, nullptr, 0, nullptr, 1, &imageReadyBarrier);
return m_ResourceManager->Commit(&texture);
}
@ -227,23 +230,8 @@ ModelLoader::LoadModel(cstr path, cstr name, bool batched)
}
eastl::vector<StagingBuffer> stagingBuffers;
eastl::vector<TextureHandle> textureHandles;
// TODO: MetalRough and Occlusion Textures are non-sRGB
if (!model.images.empty())
{
u32 numImages = Cast<u32>(model.images.size());
stagingBuffers.resize(numImages);
textureHandles.resize(numImages);
auto stagingPtr = stagingBuffers.data();
auto imagePtr = model.images.data();
for (TextureHandle &handle : textureHandles)
{
handle = LoadImage(m_CommandBuffer, stagingPtr++, imagePtr++);
}
}
eastl::hash_map<i32, TextureHandle> textureHandleMap;
eastl::vector<Material> materials;
StorageBuffer materialsBuffer;
@ -251,12 +239,22 @@ ModelLoader::LoadModel(cstr path, cstr name, bool batched)
if (!model.materials.empty())
{
auto getTextureHandle = [&textureHandles](i32 index) -> TextureHandle {
if (index >= 0)
auto getTextureHandle = [this, &textureHandleMap, &stagingBuffers, &model](i32 index,
bool isSrgb) -> TextureHandle {
if (index < 0)
{
return textureHandles[index];
}
return {};
}
const auto iter = textureHandleMap.find(index);
if (iter != textureHandleMap.end())
{
return iter->second;
}
auto *image = &model.images[index];
TextureHandle handle = LoadImage(&stagingBuffers.push_back(), image, isSrgb);
textureHandleMap.emplace(index, handle);
return handle;
};
materials.reserve(model.materials.size());
@ -267,11 +265,12 @@ ModelLoader::LoadModel(cstr path, cstr name, bool batched)
.m_EmissionFactor = VectorToVec3(material.emissiveFactor),
.m_MetalFactor = Cast<f32>(material.pbrMetallicRoughness.metallicFactor),
.m_RoughFactor = Cast<f32>(material.pbrMetallicRoughness.roughnessFactor),
.m_AlbedoTex = getTextureHandle(material.pbrMetallicRoughness.baseColorTexture.index),
.m_NormalTex = getTextureHandle(material.normalTexture.index),
.m_MetalRoughTex = getTextureHandle(material.pbrMetallicRoughness.metallicRoughnessTexture.index),
.m_OcclusionTex = getTextureHandle(material.occlusionTexture.index),
.m_EmissionTex = getTextureHandle(material.emissiveTexture.index),
.m_AlbedoTex = getTextureHandle(material.pbrMetallicRoughness.baseColorTexture.index, true),
.m_NormalTex = getTextureHandle(material.normalTexture.index, false),
.m_MetalRoughTex =
getTextureHandle(material.pbrMetallicRoughness.metallicRoughnessTexture.index, false),
.m_OcclusionTex = getTextureHandle(material.occlusionTexture.index, false),
.m_EmissionTex = getTextureHandle(material.emissiveTexture.index, true),
});
}
@ -634,6 +633,14 @@ ModelLoader::LoadModel(cstr path, cstr name, bool batched)
.m_NodeHandle = nodeHandle,
};
eastl::vector<TextureHandle> textureHandles;
textureHandles.reserve(textureHandleMap.size());
for (auto &[key, val] : textureHandleMap)
{
textureHandles.emplace_back(val);
}
return Model{
m_ResourceManager, std::move(textureHandles), std::move(nodes), handles, indexBuffer, meshPrimitives,
};

View File

@ -92,8 +92,7 @@ struct ModelLoader
u32 m_TransferQueueIndex;
u32 m_GraphicsQueueIndex;
TextureHandle
LoadImage(vk::CommandBuffer commandBuffer, StagingBuffer *stagingBuffer, tinygltf::Image *image) const;
TextureHandle LoadImage(StagingBuffer *stagingBuffer, tinygltf::Image *image, bool isSrgb) const;
Model LoadModel(cstr path, cstr name = nullptr, bool batched = false);
constexpr static auto ANormal = "NORMAL";