46 static std::optional<std::string>
result;
47 if (!result.has_value()) {
48 static char tmp_dir_buffer[
FILE_MAX];
54 std::string cache_dir = std::string(tmp_dir_buffer) +
"vk-spirv-cache" +
SEP_STR;
69 if (!cache_dir.has_value()) {
74 std::string sidecar_path = (*cache_dir) +
SEP_STR + shader_module.
sources_hash +
".sidecar.bin";
84 fstream sidecar_file(sidecar_path, std::ios::binary | std::ios::in | std::ios::ate);
85 std::streamsize sidecar_size_on_disk = sidecar_file.tellg();
87 if (sidecar_size_on_disk !=
sizeof(sidecar)) {
90 sidecar_file.seekg(0, std::ios::beg);
91 sidecar_file.read(
reinterpret_cast<char *
>(&sidecar),
sizeof(sidecar));
94 fstream spirv_file(spirv_path, std::ios::binary | std::ios::in | std::ios::ate);
95 std::streamsize size = spirv_file.tellg();
99 spirv_file.seekg(0, std::ios::beg);
101 spirv_file.read(
reinterpret_cast<char *
>(shader_module.
spirv_binary.
data()), size);
111 if (!cache_dir.has_value()) {
120 fstream spirv_file(spirv_path, std::ios::binary | std::ios::out);
121 spirv_file.write(
reinterpret_cast<const char *
>(shader_module.
compilation_result.begin()), size);
125 std::string sidecar_path = (*cache_dir) +
SEP_STR + shader_module.
sources_hash +
".sidecar.bin";
126 fstream sidecar_file(sidecar_path, std::ios::binary | std::ios::out);
127 sidecar_file.write(
reinterpret_cast<const char *
>(&sidecar),
sizeof(
SPIRVSidecar));
133 if (!cache_dir.has_value()) {
144 const time_t ts_now =
time(
nullptr);
145 const time_t delete_threshold = 60 * 60 * 24 * 30 ;
146 if (entry.
s.st_mtime + delete_threshold < ts_now) {
161 std::scoped_lock
lock(mutex_);
167 batch.shaders.append(shader);
178 case shaderc_vertex_shader:
179 return std::string(
"vertex");
180 case shaderc_geometry_shader:
181 return std::string(
"geometry");
182 case shaderc_fragment_shader:
183 return std::string(
"fragment");
184 case shaderc_compute_shader:
185 return std::string(
"compute");
188 BLI_assert_msg(
false,
"Do not know how to convert shaderc_shader_kind to stage name.");
191 return std::string(
"unknown stage");
196 shaderc_shader_kind
stage,
203 shaderc::CompileOptions
options;
204 options.SetOptimizationLevel(shaderc_optimization_level_performance);
205 options.SetTargetEnvironment(shaderc_target_env_vulkan, shaderc_env_version_vulkan_1_2);
207 options.SetOptimizationLevel(shaderc_optimization_level_zero);
208 options.SetGenerateDebugInfo();
213 options.SetOptimizationLevel(shaderc_optimization_level_zero);
219 bool compilation_succeeded = shader_module.
compilation_result.GetCompilationStatus() ==
220 shaderc_compilation_status_success;
221 if (compilation_succeeded) {
224 return compilation_succeeded;
228 shaderc_shader_kind
stage,
231 shaderc::Compiler compiler;
235void VKShaderCompiler::run(
TaskPool *__restrict ,
void *task_data)
238 shaderc::Compiler compiler;
240 bool has_not_succeeded =
false;
241 if (!shader.vertex_module.is_ready) {
243 compiler, shader, shaderc_vertex_shader, shader.vertex_module);
244 has_not_succeeded |= !compilation_succeeded;
245 shader.vertex_module.is_ready =
true;
247 if (!shader.geometry_module.is_ready) {
249 compiler, shader, shaderc_geometry_shader, shader.geometry_module);
250 has_not_succeeded |= !compilation_succeeded;
251 shader.geometry_module.is_ready =
true;
253 if (!shader.fragment_module.is_ready) {
255 compiler, shader, shaderc_fragment_shader, shader.fragment_module);
256 has_not_succeeded |= !compilation_succeeded;
257 shader.fragment_module.is_ready =
true;
259 if (!shader.compute_module.is_ready) {
261 compiler, shader, shaderc_compute_shader, shader.compute_module);
262 has_not_succeeded |= !compilation_succeeded;
263 shader.compute_module.is_ready =
true;
265 if (has_not_succeeded) {
266 shader.compilation_failed =
true;
268 shader.compilation_finished =
true;
269 shader.finalize_post();
274 std::scoped_lock
lock(mutex_);
279 if (!shader.is_ready()) {
291 std::scoped_lock
lock(mutex_);
294 VKBatch
batch = batches_.
pop(handle);
296 return batch.shaders;
bool BKE_appdir_folder_caches(char *path, size_t path_maxncpy) ATTR_NONNULL(1)
#define BLI_assert_msg(a, msg)
bool BLI_file_touch(const char *filepath) ATTR_NONNULL(1)
int BLI_exists(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
bool BLI_dir_create_recursive(const char *dirname) ATTR_NONNULL()
unsigned int BLI_filelist_dir_contents(const char *dirname, struct direntry **r_filelist)
int BLI_delete(const char *path, bool dir, bool recursive) ATTR_NONNULL()
void BLI_filelist_free(struct direntry *filelist, unsigned int nrentries)
File and directory operations.
void BLI_task_pool_work_and_wait(TaskPool *pool)
TaskPool * BLI_task_pool_create(void *userdata, eTaskPriority priority)
void BLI_task_pool_free(TaskPool *pool)
void BLI_task_pool_push(TaskPool *pool, TaskRunFunction run, void *taskdata, bool free_taskdata, TaskFreeFunction freedata)
Platform independent time functions.
void BLI_time_sleep_ms(int ms)
Compatibility-like things for windows.
Value pop(const Key &key)
Value & lookup_or_add_default(const Key &key)
const Value & lookup(const Key &key) const
bool contains(const Key &key) const
constexpr int64_t size() const
void resize(const int64_t new_size)
Shader * compile(const shader::ShaderCreateInfo &info, bool is_batch_compilation)
BatchHandle batch_compile(Span< const shader::ShaderCreateInfo * > &infos) override
Vector< Shader * > batch_finalize(BatchHandle &handle) override
static bool compile_module(VKShader &shader, shaderc_shader_kind stage, VKShaderModule &shader_module)
bool batch_is_ready(BatchHandle handle) override
static void cache_dir_clear_old()
virtual ~VKShaderCompiler()
shaderc::SpvCompilationResult compilation_result
std::string combined_sources
void build_sources_hash()
Vector< uint32_t > spirv_binary
CCL_NAMESPACE_BEGIN struct Options options
static bool compile_ex(shaderc::Compiler &compiler, VKShader &shader, shaderc_shader_kind stage, VKShaderModule &shader_module)
static Context * unwrap(GPUContext *ctx)
static void write_spirv_to_disk(VKShaderModule &shader_module)
static std::optional< std::string > cache_dir_get()
static bool read_spirv_from_disk(VKShaderModule &shader_module)
static const std::string to_stage_name(shaderc_shader_kind stage)
unsigned __int64 uint64_t
Describe inputs & outputs, stage interfaces, resources and sources of a shader. If all data is correc...