diff --git a/libs/filaflat/src/BlobDictionary.h b/libs/filaflat/src/BlobDictionary.h index c71935e290..4d2de3353b 100644 --- a/libs/filaflat/src/BlobDictionary.h +++ b/libs/filaflat/src/BlobDictionary.h @@ -29,8 +29,14 @@ public: BlobDictionary() = default; ~BlobDictionary() = default; + using Blob = std::vector; + inline void addBlob(const char* blob, size_t len) noexcept { - mBlobs.push_back({ blob, len }); + mBlobs.emplace_back(Blob(blob, blob + len)); + } + + inline void addBlob(Blob&& blob) noexcept { + mBlobs.emplace_back(blob); } inline bool isEmpty() const noexcept { @@ -42,8 +48,8 @@ public: } inline const char* getBlob(size_t index, size_t* size) const noexcept { - *size = mBlobs[index].size; - return mBlobs[index].data; + *size = mBlobs[index].size(); + return (const char*) mBlobs[index].data(); } inline const char* getString(size_t index) const noexcept { @@ -53,10 +59,6 @@ public: private: - struct Blob { - const char* data; - size_t size; - }; std::vector mBlobs; }; diff --git a/libs/filaflat/src/SpirvDictionaryReader.cpp b/libs/filaflat/src/SpirvDictionaryReader.cpp index ace9144e01..97b2bd5bc5 100644 --- a/libs/filaflat/src/SpirvDictionaryReader.cpp +++ b/libs/filaflat/src/SpirvDictionaryReader.cpp @@ -16,6 +16,11 @@ #include "SpirvDictionaryReader.h" +#if defined (FILAMENT_DRIVER_SUPPORTS_VULKAN) +#include +#include +#endif + #include namespace filaflat { @@ -26,8 +31,8 @@ bool SpirvDictionaryReader::unflatten(Unflattener& f, BlobDictionary& dictionary return false; } - // TODO: support compression - assert(compressionScheme == 0); + // For now, 1 is the only acceptable compression scheme. + assert(compressionScheme == 1); uint32_t numBlobs; if (!f.read(&numBlobs)) { @@ -36,12 +41,28 @@ bool SpirvDictionaryReader::unflatten(Unflattener& f, BlobDictionary& dictionary dictionary.reserve(numBlobs); for (uint32_t i = 0; i < numBlobs; i++) { - const char* blob; - size_t size; - if (!f.read(&blob, &size)) { + const char* compressed; + size_t compressedSize; + if (!f.read(&compressed, &compressedSize)) { return false; } - dictionary.addBlob(blob, size); + +#if defined (FILAMENT_DRIVER_SUPPORTS_VULKAN) + size_t spirvSize = smolv::GetDecodedBufferSize(compressed, compressedSize); + if (spirvSize == 0) { + utils::slog.e << "Error with SPIRV decompression" << utils::io::endl; + return false; + } + BlobDictionary::Blob spirv(spirvSize); + if (!smolv::Decode(compressed, compressedSize, spirv.data(), spirvSize)) { + utils::slog.e << "Error with SPIRV decompression" << utils::io::endl; + return false; + } + dictionary.addBlob(std::move(spirv)); +#else + return false; +#endif + } return true; } diff --git a/libs/filamat/src/eiff/DictionarySpirvChunk.cpp b/libs/filamat/src/eiff/DictionarySpirvChunk.cpp index 9b4b1e45d0..587a7a8914 100644 --- a/libs/filamat/src/eiff/DictionarySpirvChunk.cpp +++ b/libs/filamat/src/eiff/DictionarySpirvChunk.cpp @@ -16,6 +16,8 @@ #include "DictionarySpirvChunk.h" +#include + namespace filamat { DictionarySpirvChunk::DictionarySpirvChunk(BlobDictionary& dictionary) : @@ -23,12 +25,21 @@ DictionarySpirvChunk::DictionarySpirvChunk(BlobDictionary& dictionary) : } void DictionarySpirvChunk::flatten(Flattener& f) { - // TODO: for now the compression option is always 0, fix this. - f.writeUint32(0); + + // For now, 1 is the only acceptable compression scheme. + f.writeUint32(1); + f.writeUint32(mDictionary.getBlobCount()); for (size_t i = 0 ; i < mDictionary.getBlobCount() ; i++) { - const std::string& blob = mDictionary.getBlob(i); - f.writeBlob(blob.data(), blob.size()); + const std::string& spirv = mDictionary.getBlob(i); + + smolv::ByteArray compressed; + const uint32_t flags = smolv::kEncodeFlagStripDebugInfo; + if (!smolv::Encode(spirv.data(), spirv.size(), compressed, flags)) { + utils::slog.e << "Error with SPIRV compression" << utils::io::endl; + } + + f.writeBlob((const char*) compressed.data(), compressed.size()); } }