Fix non-srgb texture loads and unnecessary dedicated memory.
This commit is contained in:
parent
44121f1930
commit
b9ee037216
|
|
@ -44,7 +44,7 @@ Texture::Init(const Device *device, const vk::Extent2D extent, vk::Format imageF
|
||||||
.initialLayout = vk::ImageLayout::eUndefined,
|
.initialLayout = vk::ImageLayout::eUndefined,
|
||||||
};
|
};
|
||||||
constexpr VmaAllocationCreateInfo allocationCreateInfo = {
|
constexpr VmaAllocationCreateInfo allocationCreateInfo = {
|
||||||
.flags = VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT,
|
.flags = {},
|
||||||
.usage = VMA_MEMORY_USAGE_AUTO,
|
.usage = VMA_MEMORY_USAGE_AUTO,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
|
|
||||||
#include <EASTL/array.h>
|
#include <EASTL/array.h>
|
||||||
|
#include <EASTL/hash_map.h>
|
||||||
#include <glm/gtc/type_ptr.hpp>
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
|
|
||||||
vec4
|
vec4
|
||||||
|
|
@ -46,15 +47,17 @@ VectorToVec3(const std::vector<double> &vec)
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureHandle
|
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);
|
assert(image->component == 4);
|
||||||
|
|
||||||
|
vk::Format imageFormat = isSrgb ? vk::Format::eR8G8B8A8Srgb : vk::Format::eR8G8B8A8Unorm;
|
||||||
|
|
||||||
Texture texture;
|
Texture texture;
|
||||||
|
|
||||||
usize byteSize = image->image.size();
|
usize byteSize = image->image.size();
|
||||||
texture.Init(m_ResourceManager->m_Device, {.width = Cast<u32>(image->width), .height = Cast<u32>(image->height)},
|
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->Init(m_ResourceManager->m_Device, byteSize);
|
||||||
stagingBuffer->Write(m_ResourceManager->m_Device, 0, byteSize, image->image.data());
|
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,
|
.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);
|
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);
|
&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);
|
nullptr, 0, nullptr, 1, &nextMipBarrier);
|
||||||
|
|
||||||
auto calcNextMip = [](i32 prev) { return eastl::max(prev / 2, 1); };
|
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;
|
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);
|
vk::ImageLayout::eTransferDstOptimal, 1, &blitRegion, vk::Filter::eLinear);
|
||||||
commandBuffer.pipelineBarrier(vk::PipelineStageFlagBits::eTransfer, vk::PipelineStageFlagBits::eTransfer, {}, 0,
|
m_CommandBuffer.pipelineBarrier(vk::PipelineStageFlagBits::eTransfer, vk::PipelineStageFlagBits::eTransfer, {},
|
||||||
nullptr, 0, nullptr, 1, &nextMipBarrier);
|
0, nullptr, 0, nullptr, 1, &nextMipBarrier);
|
||||||
|
|
||||||
prevMipHeight = currentMipHeight;
|
prevMipHeight = currentMipHeight;
|
||||||
prevMipWidth = currentMipWidth;
|
prevMipWidth = currentMipWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
commandBuffer.pipelineBarrier(vk::PipelineStageFlagBits::eTransfer, vk::PipelineStageFlagBits::eFragmentShader, {},
|
m_CommandBuffer.pipelineBarrier(vk::PipelineStageFlagBits::eTransfer, vk::PipelineStageFlagBits::eFragmentShader,
|
||||||
0, nullptr, 0, nullptr, 1, &imageReadyBarrier);
|
{}, 0, nullptr, 0, nullptr, 1, &imageReadyBarrier);
|
||||||
|
|
||||||
return m_ResourceManager->Commit(&texture);
|
return m_ResourceManager->Commit(&texture);
|
||||||
}
|
}
|
||||||
|
|
@ -227,23 +230,8 @@ ModelLoader::LoadModel(cstr path, cstr name, bool batched)
|
||||||
}
|
}
|
||||||
|
|
||||||
eastl::vector<StagingBuffer> stagingBuffers;
|
eastl::vector<StagingBuffer> stagingBuffers;
|
||||||
eastl::vector<TextureHandle> textureHandles;
|
|
||||||
|
|
||||||
// TODO: MetalRough and Occlusion Textures are non-sRGB
|
eastl::hash_map<i32, TextureHandle> textureHandleMap;
|
||||||
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::vector<Material> materials;
|
eastl::vector<Material> materials;
|
||||||
StorageBuffer materialsBuffer;
|
StorageBuffer materialsBuffer;
|
||||||
|
|
@ -251,12 +239,22 @@ ModelLoader::LoadModel(cstr path, cstr name, bool batched)
|
||||||
|
|
||||||
if (!model.materials.empty())
|
if (!model.materials.empty())
|
||||||
{
|
{
|
||||||
auto getTextureHandle = [&textureHandles](i32 index) -> TextureHandle {
|
auto getTextureHandle = [this, &textureHandleMap, &stagingBuffers, &model](i32 index,
|
||||||
if (index >= 0)
|
bool isSrgb) -> TextureHandle {
|
||||||
|
if (index < 0)
|
||||||
{
|
{
|
||||||
return textureHandles[index];
|
|
||||||
}
|
|
||||||
return {};
|
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());
|
materials.reserve(model.materials.size());
|
||||||
|
|
@ -267,11 +265,12 @@ ModelLoader::LoadModel(cstr path, cstr name, bool batched)
|
||||||
.m_EmissionFactor = VectorToVec3(material.emissiveFactor),
|
.m_EmissionFactor = VectorToVec3(material.emissiveFactor),
|
||||||
.m_MetalFactor = Cast<f32>(material.pbrMetallicRoughness.metallicFactor),
|
.m_MetalFactor = Cast<f32>(material.pbrMetallicRoughness.metallicFactor),
|
||||||
.m_RoughFactor = Cast<f32>(material.pbrMetallicRoughness.roughnessFactor),
|
.m_RoughFactor = Cast<f32>(material.pbrMetallicRoughness.roughnessFactor),
|
||||||
.m_AlbedoTex = getTextureHandle(material.pbrMetallicRoughness.baseColorTexture.index),
|
.m_AlbedoTex = getTextureHandle(material.pbrMetallicRoughness.baseColorTexture.index, true),
|
||||||
.m_NormalTex = getTextureHandle(material.normalTexture.index),
|
.m_NormalTex = getTextureHandle(material.normalTexture.index, false),
|
||||||
.m_MetalRoughTex = getTextureHandle(material.pbrMetallicRoughness.metallicRoughnessTexture.index),
|
.m_MetalRoughTex =
|
||||||
.m_OcclusionTex = getTextureHandle(material.occlusionTexture.index),
|
getTextureHandle(material.pbrMetallicRoughness.metallicRoughnessTexture.index, false),
|
||||||
.m_EmissionTex = getTextureHandle(material.emissiveTexture.index),
|
.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,
|
.m_NodeHandle = nodeHandle,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
eastl::vector<TextureHandle> textureHandles;
|
||||||
|
textureHandles.reserve(textureHandleMap.size());
|
||||||
|
|
||||||
|
for (auto &[key, val] : textureHandleMap)
|
||||||
|
{
|
||||||
|
textureHandles.emplace_back(val);
|
||||||
|
}
|
||||||
|
|
||||||
return Model{
|
return Model{
|
||||||
m_ResourceManager, std::move(textureHandles), std::move(nodes), handles, indexBuffer, meshPrimitives,
|
m_ResourceManager, std::move(textureHandles), std::move(nodes), handles, indexBuffer, meshPrimitives,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -92,8 +92,7 @@ struct ModelLoader
|
||||||
u32 m_TransferQueueIndex;
|
u32 m_TransferQueueIndex;
|
||||||
u32 m_GraphicsQueueIndex;
|
u32 m_GraphicsQueueIndex;
|
||||||
|
|
||||||
TextureHandle
|
TextureHandle LoadImage(StagingBuffer *stagingBuffer, tinygltf::Image *image, bool isSrgb) const;
|
||||||
LoadImage(vk::CommandBuffer commandBuffer, StagingBuffer *stagingBuffer, tinygltf::Image *image) const;
|
|
||||||
Model LoadModel(cstr path, cstr name = nullptr, bool batched = false);
|
Model LoadModel(cstr path, cstr name = nullptr, bool batched = false);
|
||||||
|
|
||||||
constexpr static auto ANormal = "NORMAL";
|
constexpr static auto ANormal = "NORMAL";
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue