41 std::atomic<GPUShader *>
shader =
nullptr;
56 bool deferred_compilation,
69 GPUShaderCreateInfo *base_info =
reinterpret_cast<GPUShaderCreateInfo *
>(
create_info);
71 if (deferred_compilation) {
109 fprintf(stderr,
"GPUShader: error: too many samplers in shader.\n");
133 GPUShaderCreateInfo *base_info =
reinterpret_cast<GPUShaderCreateInfo *
>(
create_info);
180 int previous_refcount = pass->
refcount++;
187 int previous_refcount = pass->
refcount--;
215 static constexpr float gc_collect_rate_ = 60.0f;
218 static constexpr float optimization_delay_ = 10.0f;
220 double last_base_compilation_timestamp_ = -1.0;
228 bool deferred_compilation,
229 bool is_optimization_pass)
231 std::lock_guard
lock(mutex_);
233 passes_[engine][is_optimization_pass].add(
236 deferred_compilation,
237 is_optimization_pass,
244 bool is_optimization_pass)
246 std::lock_guard
lock(mutex_);
247 std::unique_ptr<GPUPass> *pass = passes_[engine][is_optimization_pass].lookup_ptr(
hash);
248 if (!allow_deferred && pass && pass->get()->status ==
GPU_PASS_QUEUED) {
249 pass->get()->finalize_compilation();
251 return pass ? pass->get() :
nullptr;
256 std::lock_guard
lock(mutex_);
260 bool base_passes_ready =
true;
263 for (
auto &engine_passes : passes_) {
264 for (std::unique_ptr<GPUPass> &pass : engine_passes[
false].values()) {
265 pass->update(timestamp);
267 base_passes_ready =
false;
271 engine_passes[
false].remove_if(
272 [&](
auto item) {
return item.value->should_gc(gc_collect_rate_, timestamp); });
276 for (
auto &engine_passes : passes_) {
277 for (std::unique_ptr<GPUPass> &pass : engine_passes[
true].values()) {
278 pass->update_gc_timestamp(timestamp);
281 engine_passes[
true].remove_if(
283 [&](
auto item) {
return item.value->should_gc(gc_collect_rate_, timestamp); });
286 if (!base_passes_ready) {
287 last_base_compilation_timestamp_ = timestamp;
291 if ((timestamp - last_base_compilation_timestamp_) < optimization_delay_) {
296 for (
auto &engine_passes : passes_) {
297 for (std::unique_ptr<GPUPass> &pass : engine_passes[
true].values()) {
298 pass->update_compilation();
323 g_cache = MEM_new<GPUPassCache>(__func__);
350 int samplers_len = 0;
367 const char *debug_name,
369 bool deferred_compilation,
378 if (optimize_graph) {
386 GPUCodegen codegen(material, graph, debug_name);
392 if (!optimize_graph) {
399 pass =
g_cache->get(engine, codegen.
hash_get(), deferred_compilation, optimize_graph);
412 finalize_source_cb(thunk, material, &codegen.
output);
415 g_cache->add(engine, codegen, deferred_compilation, optimize_graph);
418 return g_cache->get(engine, codegen.
hash_get(), deferred_compilation, optimize_graph);
#define BLI_assert_msg(a, msg)
Platform independent time functions.
double BLI_time_now_seconds(void)
#define UNUSED_VARS_NDEBUG(...)
int GPU_max_textures_frag()
int GPU_max_textures_vert()
eGPUBackendType GPU_backend_get_type()
void(*)(void *thunk, GPUMaterial *mat, struct GPUCodegenOutput *codegen) GPUCodegenCallbackFn
#define GPU_SHADER_FREE_SAFE(shader)
blender::Vector< GPUShader * > GPU_shader_batch_finalize(BatchHandle &handle)
void GPU_shader_batch_wait_for_all()
bool GPU_shader_batch_is_ready(BatchHandle handle)
GPUShader * GPU_shader_create_from_info(const GPUShaderCreateInfo *_info)
void GPU_shader_batch_cancel(BatchHandle &handle)
BatchHandle GPU_shader_batch_create_from_infos(blender::Span< const GPUShaderCreateInfo * > infos, CompilationPriority priority=CompilationPriority::High)
Read Guarded memory(de)allocation.
unsigned long long int uint64_t
GPUPass * get(eGPUMaterialEngine engine, size_t hash, bool allow_deferred, bool is_optimization_pass)
void add(eGPUMaterialEngine engine, GPUCodegen &codegen, bool deferred_compilation, bool is_optimization_pass)
bool should_optimize_heuristic() const
GPUCodegenCreateInfo * create_info
void generate_cryptomatte()
void generate_resources()
uint32_t hash_get() const
void generate_uniform_buffer()
void gpu_node_graph_finalize_uniform_attrs(GPUNodeGraph *graph)
void gpu_node_graph_optimize(GPUNodeGraph *graph)
void gpu_node_graph_prune_unused(GPUNodeGraph *graph)
uint64_t GPU_pass_global_compilation_count()
static bool gpu_pass_validate(GPUCodegenCreateInfo *create_info)
eGPUPassStatus GPU_pass_status(GPUPass *pass)
void GPU_pass_ensure_its_ready(GPUPass *pass)
static GPUPassCache * g_cache
void GPU_pass_cache_wait_for_all()
void GPU_pass_cache_init()
void GPU_pass_release(GPUPass *pass)
void GPU_pass_acquire(GPUPass *pass)
void GPU_pass_cache_update()
GPUPass * GPU_generate_pass(GPUMaterial *material, GPUNodeGraph *graph, const char *debug_name, eGPUMaterialEngine engine, bool deferred_compilation, GPUCodegenCallbackFn finalize_source_cb, void *thunk, bool optimize_graph)
uint64_t GPU_pass_compilation_timestamp(GPUPass *pass)
bool GPU_pass_should_optimize(GPUPass *pass)
void GPU_pass_cache_free()
GPUShader * GPU_pass_shader_get(GPUPass *pass)
std::atomic< GPUShader * > shader
GPUPass(GPUCodegenCreateInfo *info, bool deferred_compilation, bool is_optimization_pass, bool should_optimize)
void finalize_compilation()
bool is_optimization_pass
void update_gc_timestamp(double timestamp)
static std::atomic< uint64_t > compilation_counts
BatchHandle compilation_handle
void update(double timestamp)
std::atomic< eGPUPassStatus > status
bool should_gc(int gc_collect_rate, double timestamp)
void update_compilation()
std::atomic< int > refcount
GPUCodegenCreateInfo * create_info
uint64_t compilation_timestamp
CompilationPriority compilation_priority()
void finalize(const bool recursive=false)
Vector< Resource > resources_get_all_() const