3#include <glm/gtc/type_ptr.hpp>
17 const uint8_t *p =
static_cast<const uint8_t *
>(data);
18 uint64_t h = 1469598103934665603ull;
19 for (
size_t i = 0; i < n; ++i) {
21 h *= 1099511628211ull;
29 std::ifstream f(filepath, std::ios::binary);
33 uint64_t h = 1469598103934665603ull;
36 while (f.read(buf,
sizeof(buf)) || f.gcount()) {
37 std::streamsize n = f.gcount();
38 for (std::streamsize i = 0; i < n; ++i) {
39 h ^=
static_cast<uint8_t
>(buf[i]);
40 h *= 1099511628211ull;
46 static uint64_t
mix64(uint64_t a, uint64_t b) {
47 uint64_t x = a ^ (b + 0x9e3779b97f4a7c15ull + (a << 6) + (a >> 2));
49 x *= 0xff51afd7ed558ccdull;
51 x *= 0xc4ceb9fe1a85ec53ull;
56 static std::string
glStr(GLenum e) {
57 const GLubyte *p = glGetString(e);
60 return std::string(
reinterpret_cast<const char *
>(p));
72 static constexpr uint32_t
kMagic = 0x53434143u;
75 static bool readWholeFile(
const std::string &path, std::vector<uint8_t> &out) {
76 std::ifstream f(path, std::ios::binary);
79 f.seekg(0, std::ios::end);
80 std::streamoff sz = f.tellg();
83 f.seekg(0, std::ios::beg);
84 out.resize(
static_cast<size_t>(sz));
85 f.read(
reinterpret_cast<char *
>(out.data()),
static_cast<std::streamsize
>(out.size()));
89 static bool writeFileAtomic(
const std::string &path,
const void *data,
size_t size) {
90 std::filesystem::path p(path);
91 std::filesystem::create_directories(p.parent_path());
93 std::string tmp = path +
".tmp";
95 std::ofstream out(tmp, std::ios::binary | std::ios::trunc);
98 out.write(
static_cast<const char *
>(data),
static_cast<std::streamsize
>(size));
104 std::filesystem::rename(tmp, path, ec);
106 std::filesystem::remove(path, ec);
108 std::filesystem::rename(tmp, path, ec);
110 std::filesystem::remove(tmp, ec);
121 std::snprintf(name,
sizeof(name),
"%016llx.bin",
static_cast<unsigned long long>(key));
131 uint64_t h =
mix64(hv, hf);
133 std::string vendor =
glStr(GL_VENDOR);
134 std::string renderer =
glStr(GL_RENDERER);
135 std::string version =
glStr(GL_VERSION);
149 uint64_t h =
mix64(hv, hf);
151 std::string vendor =
glStr(GL_VENDOR);
152 std::string renderer =
glStr(GL_RENDERER);
153 std::string version =
glStr(GL_VERSION);
173 std::vector<uint8_t> data;
181 std::memcpy(&hdr, data.data(),
sizeof(
CacheHeader));
192 if (data.size() != need)
195 GLuint prog = glCreateProgram();
199 glGetProgramiv(prog, GL_LINK_STATUS, &ok);
201 glDeleteProgram(prog);
211 glGetProgramiv(prog, GL_PROGRAM_BINARY_LENGTH, &binLen);
215 std::vector<uint8_t> blob;
216 blob.resize(
sizeof(
CacheHeader) +
static_cast<size_t>(binLen));
225 glGetProgramBinary(prog,
static_cast<GLsizei
>(binLen), &got, &fmt, blob.data() +
sizeof(
CacheHeader));
232 std::memcpy(blob.data(), &hdr,
sizeof(
CacheHeader));
246 uint64_t key = computeProgramKeyFromFiles(v, f);
248 if (tryLoadProgramBinary(key, cached)) {
249 static_cast<gl::ShaderProgram &
>(*this) = gl::ShaderProgram(cached);
252 if (!gl::ShaderProgram::loadProgram(v, f))
254 saveProgramBinary(key,
id());
259 uint64_t key = computeProgramKeyFromText(v, f);
261 if (tryLoadProgramBinary(key, cached)) {
262 static_cast<gl::ShaderProgram &
>(*this) = gl::ShaderProgram(cached);
265 if (!gl::ShaderProgram::loadProgramFromText(v, f))
267 saveProgramBinary(key,
id());
bool loadProgram(const std::string &v, const std::string &f)
bool loadProgramFromText(const std::string &v, const std::string &f)
bool loadComputeProgramBinaryFromCache(const std::string &source, GLuint &program)
Restore a compute-only program binary keyed by source and GL driver.
bool saveComputeProgramBinaryToCache(const std::string &source, GLuint program)
Save a linked compute-only program to its stage-specific cache key.
static uint64_t computeProgramKeyFromFiles(const std::string &vsPath, const std::string &fsPath)
static std::string cacheFilePath(uint64_t key)
static uint64_t fnv1a64_file(const std::string &filepath)
static constexpr uint16_t kVersion
static std::string cacheDirDefault()
static uint64_t fnv1a64_str(const std::string &s)
static constexpr uint32_t kMagic
static std::string glStr(GLenum e)
static bool writeFileAtomic(const std::string &path, const void *data, size_t size)
static bool saveProgramBinary(uint64_t key, GLuint prog)
static uint64_t fnv1a64_bytes(const void *data, size_t n)
static bool tryLoadProgramBinary(uint64_t key, GLuint &outProg)
static uint64_t computeProgramKeyFromText(const std::string &vs, const std::string &fs)
static bool readWholeFile(const std::string &path, std::vector< uint8_t > &out)
static uint64_t computeComputeProgramKeyFromText(const std::string &source)
static uint64_t mix64(uint64_t a, uint64_t b)