38 for (
const auto &def : info.
defines_) {
39 defines +=
"#define ";
65 "Shader must be unbound from context before being freed");
75 sources.
append(
"/* specialization_constants */");
77 sources.
append(
"#define GPU_SHADER\n");
80 sources.
append(
"#define GPU_ATI\n");
83 sources.
append(
"#define GPU_NVIDIA\n");
86 sources.
append(
"#define GPU_INTEL\n");
89 sources.
append(
"#define GPU_APPLE\n");
93 sources.
append(
"#define OS_WIN\n");
96 sources.
append(
"#define OS_MAC\n");
99 sources.
append(
"#define OS_UNIX\n");
105 sources.
append(
"#define GPU_OPENGL\n");
108 sources.
append(
"#define GPU_METAL\n");
111 sources.
append(
"#define GPU_VULKAN\n");
140 if (
error.length() == 0) {
154 std::cerr <<
"Warning: Trying to compile \"" << info.
name_
155 <<
"\" which was not marked for static compilation.\n";
173 return processor.
process(original);
239 printf(
"Compiling all static GPU shaders. This process takes a while.\n");
260 "Shader requires specialization constants but none was passed");
266 shader->bind(constants_state);
274 if (constants_state) {
275 shader->bind(constants_state);
284#if GPU_SHADER_PRINTF_ENABLE
294 if (ctx ==
nullptr) {
322 return shader->name_get().c_str();
337 Shader *shd_parent = parent;
344 shader->warm_cache(limit);
367 constants = std::make_unique<const shader::SpecializationConstants>(std::move(constants_tmp));
396 return uniform ? uniform->location : -1;
403 return constant ? constant->location : -1;
416 return ssbo ? ssbo->location : -1;
423 return ubo ? ubo->location : -1;
430 return ubo ? ubo->binding : -1;
437 return tex ? tex->binding : -1;
456 return attr ? attr->location : -1;
472 *r_type = attr->location != -1 ?
interface->attr_types_[attr->location] : -1;
500 shader->uniform_float(loc,
len, array_size, value);
506 shader->uniform_int(loc,
len, array_size, value);
522 const float data[2] = {
x,
y};
528 const float data[3] = {
x,
y,
z};
583 const float data[3][3])
602 const float (*val)[2])
611 const float (*val)[4])
619namespace blender::gpu {
667 using Clock = std::chrono::steady_clock;
668 using TimePoint = Clock::time_point;
674 TimePoint start_time;
681 else if (
G.profile_gpu) {
682 start_time = Clock::now();
686 if (!
error.empty()) {
687 std::cerr <<
error <<
"\n";
694 shader->specialization_constants_init(info);
695 shader->init(info, is_batch_compilation);
697 shader->fragment_output_bits = 0;
699 shader->fragment_output_bits |= 1u << frag_out.
index;
702 std::string defines =
shader->defines_declare(info);
703 std::string resources =
shader->resources_declare(info);
707 defines +=
"#define USE_GPU_SHADER_CREATE_INFO\n";
724 std::string
interface =
shader->vertex_interface_declare(info);
728 sources.append(
"#define GPU_VERTEX_SHADER\n");
729 if (!info.geometry_source_.is_empty()) {
730 sources.append(
"#define USE_GEOMETRY_SHADER\n");
732 sources.append(defines);
733 sources.extend(typedefs);
734 sources.append(resources);
736 sources.extend(code);
737 sources.append(info.vertex_source_generated);
739 if (info.vertex_entry_fn_ !=
"main") {
740 sources.append(
"void main() { ");
741 sources.append(info.vertex_entry_fn_);
742 sources.append(
"(); }\n");
745 shader->vertex_shader_from_glsl(sources);
751 std::string
interface =
shader->fragment_interface_declare(info);
755 sources.append(
"#define GPU_FRAGMENT_SHADER\n");
756 if (!info.geometry_source_.is_empty()) {
757 sources.append(
"#define USE_GEOMETRY_SHADER\n");
759 sources.append(defines);
760 sources.extend(typedefs);
761 sources.append(resources);
763 sources.extend(code);
764 sources.append(info.fragment_source_generated);
766 if (info.fragment_entry_fn_ !=
"main") {
767 sources.append(
"void main() { ");
768 sources.append(info.fragment_entry_fn_);
769 sources.append(
"(); }\n");
772 shader->fragment_shader_from_glsl(sources);
778 std::string layout =
shader->geometry_layout_declare(info);
779 std::string
interface =
shader->geometry_interface_declare(info);
783 sources.append(
"#define GPU_GEOMETRY_SHADER\n");
784 sources.append(defines);
785 sources.extend(typedefs);
786 sources.append(resources);
787 sources.append(layout);
789 sources.append(info.geometry_source_generated);
790 sources.extend(code);
792 if (info.geometry_entry_fn_ !=
"main") {
793 sources.append(
"void main() { ");
794 sources.append(info.geometry_entry_fn_);
795 sources.append(
"(); }\n");
798 shader->geometry_shader_from_glsl(sources);
804 std::string layout =
shader->compute_layout_declare(info);
808 sources.
append(
"#define GPU_COMPUTE_SHADER\n");
811 sources.
append(resources);
817 sources.
append(
"void main() { ");
819 sources.
append(
"(); }\n");
822 shader->compute_shader_from_glsl(sources);
825 if (!
shader->finalize(&info)) {
835 else if (
G.profile_gpu) {
836 TimePoint end_time = Clock::now();
839 start_time.time_since_epoch().count(),
840 end_time.time_since_epoch().count());
842 start_time.time_since_epoch().count(),
843 end_time.time_since_epoch().count());
851 bool support_specializations)
853 support_specializations_ = support_specializations;
856 compilation_worker_ = std::make_unique<GPUWorker>(
860 [
this]() ->
void * {
return this->pop_work(); },
861 [
this](
void *work) { this->do_work(work); });
867 compilation_worker_.reset();
881 std::unique_lock
lock(mutex_);
883 Batch *
batch = MEM_new<Batch>(__func__);
884 batch->infos = infos;
888 batches_.add(handle,
batch);
890 if (compilation_worker_) {
891 batch->shaders.resize(infos.
size(),
nullptr);
892 batch->pending_compilations = infos.
size();
894 compilation_queue_.push({
batch,
i}, priority);
895 compilation_worker_->wake_up();
909 std::unique_lock
lock(mutex_);
911 Batch *
batch = batches_.pop(handle);
912 compilation_queue_.remove_batch(
batch);
916 compilation_finished_notification_.wait(
lock, [&]() {
return batch->is_ready(); });
917 batch->free_shaders();
925 std::lock_guard
lock(mutex_);
927 return batches_.lookup(handle)->is_ready();
932 std::unique_lock
lock(mutex_);
934 compilation_finished_notification_.wait(
lock,
935 [&]() {
return batches_.lookup(handle)->is_ready(); });
937 Batch *
batch = batches_.pop(handle);
948 if (!compilation_worker_ || !support_specializations_) {
952 std::lock_guard
lock(mutex_);
954 Batch *
batch = MEM_new<Batch>(__func__);
955 batch->specializations = specializations;
958 batches_.add(handle,
batch);
960 batch->pending_compilations = specializations.
size();
962 compilation_queue_.push({
batch,
i}, priority);
963 compilation_worker_->wake_up();
972 std::lock_guard
lock(mutex_);
974 Batch *
batch = batches_.pop(handle);
982void *ShaderCompiler::pop_work()
986 if (compilation_queue_.is_empty()) {
990 ParallelWork work = compilation_queue_.pop();
991 return MEM_new<ParallelWork>(__func__, work);
994void ShaderCompiler::do_work(
void *work_payload)
996 ParallelWork *work =
reinterpret_cast<ParallelWork *
>(work_payload);
997 Batch *
batch = work->batch;
998 int shader_index = work->shader_index;
1002 if (!
batch->is_specialization_batch()) {
1003 batch->shaders[shader_index] = compile_shader(*
batch->infos[shader_index]);
1006 specialize_shader(
batch->specializations[shader_index]);
1010 std::unique_lock
lock(mutex_);
1011 batch->pending_compilations--;
1014 compilation_finished_notification_.notify_all();
1017bool ShaderCompiler::is_compiling_impl()
1022 if (!compilation_queue_.is_empty()) {
1026 for (Batch *
batch : batches_.values()) {
1027 if (!
batch->is_ready()) {
1037 std::unique_lock
lock(mutex_);
1038 return is_compiling_impl();
1043 std::unique_lock
lock(mutex_);
1044 compilation_finished_notification_.wait(
lock, [&]() {
return !is_compiling_impl(); });
#define BLI_assert_msg(a, msg)
void copy_m4_m3(float m1[4][4], const float m2[3][3])
char * STRNCPY(char(&dst)[N], const char *src)
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
bool GPU_use_main_context_workaround()
GPUBackendType GPU_backend_get_type()
void GPU_debug_group_end()
void GPU_debug_group_begin(const char *name)
#define GPU_DEBUG_SHADER_COMPILATION_GROUP
void GPU_matrix_bind(blender::gpu::Shader *shader)
bool GPU_matrix_dirty_get()
blender::gpu::Shader * GPU_shader_create_from_info_python(const GPUShaderCreateInfo *_info)
int GPU_shader_get_ubo_binding(blender::gpu::Shader *shader, const char *name)
void GPU_shader_uniform_2fv_array(blender::gpu::Shader *sh, const char *name, int len, const float(*val)[2])
int GPU_shader_get_constant(blender::gpu::Shader *shader, const char *name)
void GPU_shader_uniform_1b(blender::gpu::Shader *sh, const char *name, bool value)
const blender::gpu::shader::SpecializationConstants & GPU_shader_get_default_constant_state(blender::gpu::Shader *sh)
int GPU_shader_get_uniform_block(blender::gpu::Shader *shader, const char *name)
void GPU_shader_uniform_4fv_array(blender::gpu::Shader *sh, const char *name, int len, const float(*val)[4])
void GPU_shader_uniform_1f(blender::gpu::Shader *sh, const char *name, float value)
void GPU_shader_cache_dir_clear_old()
void GPU_shader_free(blender::gpu::Shader *shader)
bool GPU_shader_get_attribute_info(const blender::gpu::Shader *shader, int attr_location, char r_name[256], int *r_type)
bool GPU_shader_get_ssbo_input_info(const blender::gpu::Shader *shader, int ssbo_location, char r_name[256])
blender::gpu::Shader * GPU_shader_create_from_info(const GPUShaderCreateInfo *_info)
void GPU_shader_uniform_4fv(blender::gpu::Shader *sh, const char *name, const float data[4])
void GPU_shader_uniform_mat3_as_mat4(blender::gpu::Shader *sh, const char *name, const float data[3][3])
int GPU_shader_get_sampler_binding(blender::gpu::Shader *shader, const char *name)
void GPU_shader_uniform_3fv(blender::gpu::Shader *sh, const char *name, const float data[3])
bool GPU_shader_batch_is_compiling()
void GPU_shader_batch_wait_for_all()
uint GPU_shader_get_attribute_len(const blender::gpu::Shader *shader)
uint GPU_shader_get_ssbo_input_len(const blender::gpu::Shader *shader)
void GPU_shader_bind(blender::gpu::Shader *shader, const blender::gpu::shader::SpecializationConstants *constants_state=nullptr)
blender::Vector< blender::gpu::Shader * > GPU_shader_batch_finalize(BatchHandle &handle)
bool GPU_shader_batch_is_ready(BatchHandle handle)
int GPU_shader_get_ssbo_binding(blender::gpu::Shader *shader, const char *name)
std::string GPU_shader_preprocess_source(blender::StringRefNull original)
blender::gpu::Shader * GPU_shader_get_bound()
SpecializationBatchHandle GPU_shader_batch_specializations(blender::Span< ShaderSpecialization > specializations, CompilationPriority priority=CompilationPriority::High)
const GPUShaderCreateInfo * GPU_shader_create_info_get(const char *info_name)
void GPU_shader_uniform_int_ex(blender::gpu::Shader *shader, int location, int length, int array_size, const int *value)
void GPU_shader_uniform_1i(blender::gpu::Shader *sh, const char *name, int value)
void GPU_shader_batch_specializations_cancel(SpecializationBatchHandle &handle)
@ GPU_UNIFORM_SRGB_TRANSFORM
@ GPU_UNIFORM_SCENE_LINEAR_XFORM
void GPU_shader_uniform_mat4(blender::gpu::Shader *sh, const char *name, const float data[4][4])
void GPU_shader_uniform_4f(blender::gpu::Shader *sh, const char *name, float x, float y, float z, float w)
int64_t SpecializationBatchHandle
const char * GPU_shader_get_name(blender::gpu::Shader *shader)
int GPU_shader_get_attribute(const blender::gpu::Shader *shader, const char *name)
void GPU_shader_uniform_2f(blender::gpu::Shader *sh, const char *name, float x, float y)
void GPU_shader_set_parent(blender::gpu::Shader *shader, blender::gpu::Shader *parent)
blender::gpu::Shader * GPU_shader_create_from_info_name(const char *info_name)
void GPU_shader_uniform_2fv(blender::gpu::Shader *sh, const char *name, const float data[2])
int GPU_shader_get_uniform(blender::gpu::Shader *shader, const char *name)
void GPU_shader_batch_cancel(BatchHandle &handle)
void GPU_shader_uniform_1f_array(blender::gpu::Shader *sh, const char *name, int len, const float *val)
bool GPU_shader_create_info_check_error(const GPUShaderCreateInfo *_info, char r_error[128])
void GPU_shader_warm_cache(blender::gpu::Shader *shader, int limit)
void GPU_shader_uniform_3f(blender::gpu::Shader *sh, const char *name, float x, float y, float z)
BatchHandle GPU_shader_batch_create_from_infos(blender::Span< const GPUShaderCreateInfo * > infos, CompilationPriority priority=CompilationPriority::High)
int GPU_shader_get_builtin_uniform(blender::gpu::Shader *shader, int builtin)
void GPU_shader_uniform_float_ex(blender::gpu::Shader *shader, int location, int length, int array_size, const float *value)
bool GPU_shader_batch_specializations_is_ready(SpecializationBatchHandle &handle)
void GPU_shader_compile_static()
void GPU_shader_uniform_2iv(blender::gpu::Shader *sh, const char *name, const int data[2])
void GPU_shader_uniform_3iv(blender::gpu::Shader *sh, const char *name, const int data[3])
void GPU_storagebuf_bind(blender::gpu::StorageBuf *ssbo, int slot)
BMesh const char void * data
SIMD_FORCE_INLINE const btScalar & z() const
Return the z value.
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
void append(const T &value)
constexpr int64_t size() const
constexpr IndexRange index_range() const
constexpr bool is_empty() const
constexpr const char * c_str() const
void append(const T &value)
void extend(Span< T > array)
void extend_non_duplicates(Span< T > array)
Vector< StorageBuf * > printf_buf
int shader_builtin_srgb_transform
bool shader_builtin_srgb_is_dirty
static GPUBackend * get()
ShaderCompiler * get_compiler()
virtual void shader_cache_dir_clear_old()=0
virtual Shader * shader_alloc(const char *name)=0
static ProfileReport & get()
void add_group_cpu(StringRefNull name, uint64_t cpu_start, uint64_t cpu_end)
void batch_cancel(BatchHandle &handle)
BatchHandle batch_compile(Span< const shader::ShaderCreateInfo * > &infos, CompilationPriority priority)
bool specialization_batch_is_ready(SpecializationBatchHandle &handle)
Vector< Shader * > batch_finalize(BatchHandle &handle)
Shader * compile(const shader::ShaderCreateInfo &info, bool is_batch_compilation)
bool batch_is_ready(BatchHandle handle)
ShaderCompiler(uint32_t threads_count=1, GPUWorker::ContextType context_type=GPUWorker::ContextType::PerThread, bool support_specializations=false)
virtual ~ShaderCompiler()
SpecializationBatchHandle precompile_specializations(Span< ShaderSpecialization > specializations, CompilationPriority priority)
virtual Shader * compile_shader(const shader::ShaderCreateInfo &info)
std::string defines_declare(const shader::ShaderCreateInfo &info) const
std::unique_ptr< const shader::SpecializationConstants > constants
ShaderInterface * interface
void specialization_constants_init(const shader::ShaderCreateInfo &info)
void parent_set(Shader *parent)
static void set_scene_linear_to_xyz_uniform(gpu::Shader *shader)
static void set_framebuffer_srgb_target(int use_srgb_to_linear)
static void set_srgb_uniform(Context *ctx, gpu::Shader *shader)
std::string process(SourceLanguage language, std::string str, const std::string &filename, bool do_parse_function, bool do_small_type_linting, report_callback report_error, metadata::Source &r_metadata)
struct @021025263243242147216143265077100330027142264337::@225245033123204053237120173316075113304004012000 batch
static void standard_defines(Vector< StringRefNull > &sources)
char datatoc_gpu_shader_colorspace_lib_glsl[]
const GPUShaderCreateInfo * gpu_shader_create_info_get(const char *info_name)
bool gpu_shader_create_info_compile(const char *name_starts_with_filter)
#define GPU_SHADER_PRINTF_SLOT
static void error(const char *str)
float3x3 scene_linear_to_rec709
Vector< StringRefNull > gpu_shader_dependency_get_resolved_source(const StringRefNull shader_source_name, const shader::GeneratedSourceList &generated_sources, const StringRefNull shader_name)
StringRefNull gpu_shader_dependency_get_source(const StringRefNull shader_source_name)
Describe inputs & outputs, stage interfaces, resources and sources of a shader. If all data is correc...
std::string fragment_source_generated
std::string check_error() const
std::string vertex_source_generated
bool do_static_compilation_
std::string compute_source_generated
std::string geometry_source_generated
Describe inputs & outputs, stage interfaces, resources and sources of a shader. If all data is correc...
StringRefNull vertex_source_
StringRefNull compute_source_
StringRefNull compute_entry_fn_
Vector< std::array< StringRefNull, 2 > > defines_
GeneratedSourceList generated_sources
std::string check_error() const
StringRefNull geometry_source_
std::string typedef_source_generated
StringRefNull fragment_source_
bool do_static_compilation_
std::string compute_source_generated
void resource_guard_defines(std::string &defines) const
Vector< SpecializationConstant > specialization_constants_
Vector< StringRefNull > typedef_sources_
Vector< FragOut > fragment_outputs_
Vector< SpecializationConstant::Value, 8 > values
Vector< gpu::shader::Type, 8 > types