mirror of
https://github.com/johndoe6345789/SDL3CPlusPlus.git
synced 2026-04-27 07:05:03 +00:00
100 lines
2.8 KiB
C++
100 lines
2.8 KiB
C++
//
|
|
// Copyright Contributors to the MaterialX Project
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
//
|
|
|
|
#include <MaterialXRenderSlang/SlangShaderCache.h>
|
|
#include <fstream>
|
|
|
|
MATERIALX_NAMESPACE_BEGIN
|
|
|
|
namespace
|
|
{
|
|
|
|
std::string encodeBase64(const void* data, const size_t size)
|
|
{
|
|
static std::string base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
|
|
|
|
//const uint8_t* input = reinterpret_cast<const uint8_t*>(data);
|
|
std::vector<uint8_t> input(reinterpret_cast<const uint8_t*>(data), reinterpret_cast<const uint8_t*>(data) + size);
|
|
|
|
std::string result;
|
|
|
|
for (size_t i = 0; i < size; i += 3)
|
|
{
|
|
/// Split next 3 characters to 4 groups of 6 bits.
|
|
/// If there is no input character, leave the -1 placeholder.
|
|
int32_t values[4] = {-1,-1,-1,-1};
|
|
values[0] = (input[i] >> 2) & 0b00111111;
|
|
values[1] = (input[i] << 4) & 0b00110000;
|
|
if (i + 1 < size)
|
|
{
|
|
values[1] += (input[i + 1] >> 4) & 0b00001111;
|
|
values[2] += (input[i + 1] << 2) & 0b00111100;
|
|
}
|
|
if (i + 2 < size)
|
|
{
|
|
values[2] += (input[i + 2] >> 6) & 0b00000011;
|
|
values[3] += (input[i + 2]) & 0b00111111;
|
|
}
|
|
|
|
/// Encode valid characters, replace placeholders with =
|
|
for (int j = 0; j < 4; ++j)
|
|
result.push_back(values[j] >= 0 ? base64[values[j]] : '=');
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
} // namespace
|
|
|
|
SlangShaderCache::SlangShaderCache(const FilePath& cachePath) :
|
|
_cachePath(cachePath)
|
|
{
|
|
_cachePath.createDirectory();
|
|
}
|
|
|
|
rhi::Result SlangShaderCache::writeCache(ISlangBlob* key, ISlangBlob* data)
|
|
{
|
|
std::string filename = encodeBase64(key->getBufferPointer(), key->getBufferSize());
|
|
|
|
filename += ".slangcache";
|
|
FilePath path = _cachePath / filename;
|
|
|
|
std::ofstream ofs(path, std::ios::binary);
|
|
if (!ofs)
|
|
return SLANG_E_NOT_FOUND;
|
|
|
|
ofs.write((const char*) data->getBufferPointer(),
|
|
data->getBufferSize());
|
|
return SLANG_OK;
|
|
}
|
|
|
|
rhi::Result SlangShaderCache::queryCache(ISlangBlob* key, ISlangBlob** outData)
|
|
{
|
|
std::string filename = encodeBase64(key->getBufferPointer(), key->getBufferSize());
|
|
|
|
filename += ".slangcache";
|
|
FilePath path = _cachePath / filename;
|
|
|
|
std::ifstream ifs(path, std::ios::binary);
|
|
if (!ifs)
|
|
{
|
|
*outData = nullptr;
|
|
return SLANG_E_NOT_FOUND;
|
|
}
|
|
|
|
ifs.seekg(0, std::ios::end);
|
|
size_t length = ifs.tellg();
|
|
ifs.seekg(0, std::ios::beg);
|
|
|
|
rhi::ComPtr<ISlangBlob> blob = rhi::getRHI()->createBlob(nullptr, length);
|
|
ifs.read((char*)blob->getBufferPointer(), blob->getBufferSize());
|
|
ifs.close();
|
|
|
|
*outData = blob.detach();
|
|
return SLANG_OK;
|
|
}
|
|
|
|
MATERIALX_NAMESPACE_END
|