blob: ddbfa9c820a1f09c045562be95c43afab22d3814 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/ui/lib/escher/shaders/util/spirv_file_util.h"
namespace escher {
namespace {
// Given a path name for a variant shader and its args, generate a new hashed name for that
// shader's spirv code to be saved on disk.
// For example if the shader name was "main.vert" and the hash is "9731555" then the final
// hashed name will be "main_vert9731555.spirv".
std::string GenerateHashedSpirvName(const std::string& path, const ShaderVariantArgs& args) {
uint64_t hash_value = args.hash().val;
std::string result = path + std::to_string(hash_value);
std::replace(result.begin(), result.end(), '.', '_');
std::replace(result.begin(), result.end(), '/', '_');
return result + ".spirv";
}
} // namespace
namespace shader_util {
bool WriteSpirvToDisk(const std::vector<uint32_t>& spirv, const ShaderVariantArgs& args,
const std::string& base_path, const std::string& shader_name) {
auto hash_name = GenerateHashedSpirvName(shader_name, args);
auto full_path = base_path + hash_name;
FILE* fp = fopen(full_path.c_str(), "wb");
if (fp) {
fwrite(spirv.data(), sizeof(uint32_t), spirv.size(), fp);
fclose(fp);
return true;
} else {
FXL_LOG(ERROR) << "Could not write file: " << full_path;
}
return false;
}
bool ReadSpirvFromDisk(const ShaderVariantArgs& args, const std::string& base_path,
const std::string& shader_name, std::vector<uint32_t>* out_spirv) {
FXL_DCHECK(out_spirv);
auto hash_name = GenerateHashedSpirvName(shader_name, args);
auto full_path = base_path + hash_name;
FILE* fp = fopen(full_path.c_str(), "rb");
if (fp) {
std::size_t binary_size;
fseek(fp, 0, SEEK_END);
binary_size = ftell(fp);
rewind(fp);
// File was empty.
if (binary_size == 0) {
return false;
}
uint32_t num_elements = binary_size / sizeof(uint32_t);
out_spirv->resize(num_elements);
uint32_t num_read = fread(out_spirv->data(), sizeof(uint32_t), num_elements, fp);
return num_read == num_elements;
}
return false;
}
} // namespace shader_util
} // namespace escher