37 for (
const auto &def : info.
defines_) {
38 defines +=
"#define ";
64 "Shader must be unbound from context before being freed");
74 sources.
append(
"/* specialization_constants */");
76 sources.
append(
"#define GPU_SHADER\n");
79 sources.
append(
"#define GPU_ATI\n");
82 sources.
append(
"#define GPU_NVIDIA\n");
85 sources.
append(
"#define GPU_INTEL\n");
88 sources.
append(
"#define GPU_APPLE\n");
92 sources.
append(
"#define OS_WIN\n");
95 sources.
append(
"#define OS_MAC\n");
98 sources.
append(
"#define OS_UNIX\n");
104 sources.
append(
"#define GPU_OPENGL\n");
107 sources.
append(
"#define GPU_METAL\n");
110 sources.
append(
"#define GPU_VULKAN\n");
118 sources.
append(
"#define GPU_DEPRECATED_AMD_DRIVER\n");
123 const std::optional<StringRefNull> fragcode,
124 const std::optional<StringRefNull> geomcode,
125 const std::optional<StringRefNull> computecode,
126 const std::optional<StringRefNull> libcode,
127 const std::optional<StringRefNull> defines,
131 BLI_assert((fragcode.has_value() && vertcode.has_value() && !computecode.has_value()) ||
132 (!fragcode.has_value() && !vertcode.has_value() && !geomcode.has_value() &&
133 computecode.has_value()));
138 shader->constants = std::make_unique<const shader::SpecializationConstants>();
144 sources.
append(
"#define GPU_VERTEX_SHADER\n");
145 sources.
append(
"#define IN_OUT out\n");
147 sources.
append(
"#define USE_GEOMETRY_SHADER\n");
152 sources.
append(*vertcode);
154 shader->vertex_shader_from_glsl(sources);
160 sources.
append(
"#define GPU_FRAGMENT_SHADER\n");
161 sources.
append(
"#define IN_OUT in\n");
163 sources.
append(
"#define USE_GEOMETRY_SHADER\n");
171 sources.
append(*fragcode);
173 shader->fragment_shader_from_glsl(sources);
179 sources.
append(
"#define GPU_GEOMETRY_SHADER\n");
183 sources.
append(*geomcode);
185 shader->geometry_shader_from_glsl(sources);
191 sources.
append(
"#define GPU_COMPUTE_SHADER\n");
198 sources.
append(*computecode);
200 shader->compute_shader_from_glsl(sources);
203 if (!
shader->finalize()) {
223 const std::optional<StringRefNull> fragcode,
224 const std::optional<StringRefNull> geomcode,
225 const std::optional<StringRefNull> libcode,
226 const std::optional<StringRefNull> defines,
230 vertcode, fragcode, geomcode, std::nullopt, libcode, defines, shname);
234 const std::optional<StringRefNull> libcode,
235 const std::optional<StringRefNull> defines,
239 std::nullopt, std::nullopt, std::nullopt, computecode, libcode, defines, shname);
252 if (
error.length() == 0) {
266 std::cerr <<
"Warning: Trying to compile \"" << info.
name_
267 <<
"\" which was not marked for static compilation.\n";
285 return processor.
process(original);
315 std::optional<StringRefNull> fragcode,
316 std::optional<StringRefNull> geomcode,
317 std::optional<StringRefNull> libcode,
318 std::optional<StringRefNull> defines,
319 const std::optional<StringRefNull> name)
321 std::string defines_cat =
"#define GPU_RAW_PYTHON_SHADER\n";
323 defines_cat += defines.value();
324 defines = defines_cat;
327 defines = defines_cat;
330 std::string libcodecat;
337 libcode = libcodecat;
340 std::string vertex_source_processed;
341 std::string fragment_source_processed;
342 std::string geometry_source_processed;
343 std::string library_source_processed;
345 if (vertcode.has_value()) {
347 vertcode = vertex_source_processed;
349 if (fragcode.has_value()) {
351 fragcode = fragment_source_processed;
353 if (geomcode.has_value()) {
355 geomcode = geometry_source_processed;
357 if (libcode.has_value()) {
359 libcode = library_source_processed;
366 vertcode, fragcode, geomcode, std::nullopt, libcode, defines, shname);
403 printf(
"Compiling all static GPU shaders. This process takes a while.\n");
423 "Shader requires specialization constants but none was passed");
429 shader->bind(constants_state);
434 if (constants_state) {
435 shader->bind(constants_state);
444#if GPU_SHADER_PRINTF_ENABLE
454 if (ctx ==
nullptr) {
515 return *
unwrap(sh)->constants;
526 constants = std::make_unique<const shader::SpecializationConstants>(std::move(constants_tmp));
555 return uniform ? uniform->location : -1;
562 return constant ? constant->location : -1;
581 return ssbo ? ssbo->location : -1;
588 return ubo ? ubo->location : -1;
595 return ubo ? ubo->binding : -1;
602 return tex ? tex->binding : -1;
621 return attr ? attr->location : -1;
637 *r_type = attr->location != -1 ?
interface->attr_types_[attr->location] : -1;
661 GPUShader *
shader,
int loc,
int len,
int array_size,
const float *value)
667 GPUShader *
shader,
int loc,
int len,
int array_size,
const int *value)
685 const float data[2] = {
x,
y};
691 const float data[3] = {
x,
y,
z};
770namespace blender::gpu {
809 using Clock = std::chrono::steady_clock;
810 using TimePoint = Clock::time_point;
815 TimePoint start_time;
822 else if (
G.profile_gpu) {
823 start_time = Clock::now();
827 if (!
error.empty()) {
828 std::cerr <<
error <<
"\n";
835 shader->specialization_constants_init(info);
836 shader->init(info, is_batch_compilation);
838 shader->fragment_output_bits = 0;
840 shader->fragment_output_bits |= 1u << frag_out.
index;
843 std::string defines =
shader->defines_declare(info);
844 std::string resources =
shader->resources_declare(info);
846 defines +=
"#define USE_GPU_SHADER_CREATE_INFO\n";
861 std::string
interface =
shader->vertex_interface_declare(info);
865 sources.append(
"#define GPU_VERTEX_SHADER\n");
866 if (!info.geometry_source_.is_empty()) {
867 sources.append(
"#define USE_GEOMETRY_SHADER\n");
869 sources.append(defines);
870 sources.extend(typedefs);
871 sources.append(resources);
873 sources.extend(code);
874 sources.extend(info.dependencies_generated);
875 sources.append(info.vertex_source_generated);
877 shader->vertex_shader_from_glsl(sources);
882 std::string
interface =
shader->fragment_interface_declare(info);
886 sources.append(
"#define GPU_FRAGMENT_SHADER\n");
887 if (!info.geometry_source_.is_empty()) {
888 sources.append(
"#define USE_GEOMETRY_SHADER\n");
890 sources.append(defines);
891 sources.extend(typedefs);
892 sources.append(resources);
894 sources.extend(code);
895 sources.extend(info.dependencies_generated);
896 sources.append(info.fragment_source_generated);
898 shader->fragment_shader_from_glsl(sources);
903 std::string layout =
shader->geometry_layout_declare(info);
904 std::string
interface =
shader->geometry_interface_declare(info);
908 sources.append(
"#define GPU_GEOMETRY_SHADER\n");
909 sources.append(defines);
910 sources.extend(typedefs);
911 sources.append(resources);
912 sources.append(layout);
914 sources.append(info.geometry_source_generated);
915 sources.extend(code);
917 shader->geometry_shader_from_glsl(sources);
922 std::string layout =
shader->compute_layout_declare(info);
926 sources.
append(
"#define GPU_COMPUTE_SHADER\n");
929 sources.
append(resources);
935 shader->compute_shader_from_glsl(sources);
938 if (!
shader->finalize(&info)) {
948 else if (
G.profile_gpu) {
949 TimePoint end_time = Clock::now();
952 start_time.time_since_epoch().count(),
953 end_time.time_since_epoch().count());
955 start_time.time_since_epoch().count(),
956 end_time.time_since_epoch().count());
964 bool support_specializations)
966 support_specializations_ = support_specializations;
969 compilation_worker_ = std::make_unique<GPUWorker>(
973 [
this]() ->
void * {
return this->pop_work(); },
974 [
this](
void *work) { this->do_work(work); });
980 compilation_worker_.reset();
994 std::unique_lock
lock(mutex_);
996 Batch *
batch = MEM_new<Batch>(__func__);
997 batch->infos = infos;
1001 batches_.add(handle,
batch);
1003 if (compilation_worker_) {
1004 batch->shaders.resize(infos.
size(),
nullptr);
1005 batch->pending_compilations = infos.
size();
1007 compilation_queue_.push({
batch,
i}, priority);
1008 compilation_worker_->wake_up();
1022 std::unique_lock
lock(mutex_);
1024 Batch *
batch = batches_.pop(handle);
1025 compilation_queue_.remove_batch(
batch);
1027 if (
batch->is_specialization_batch()) {
1030 compilation_finished_notification_.wait(
lock, [&]() {
return batch->is_ready(); });
1033 if (
batch->is_ready()) {
1034 batch->free_shaders();
1039 batch->is_cancelled =
true;
1047 std::lock_guard
lock(mutex_);
1049 return batches_.lookup(handle)->is_ready();
1054 std::unique_lock
lock(mutex_);
1056 compilation_finished_notification_.wait(
lock,
1057 [&]() {
return batches_.lookup(handle)->is_ready(); });
1059 Batch *
batch = batches_.pop(handle);
1070 if (!compilation_worker_ || !support_specializations_) {
1074 std::lock_guard
lock(mutex_);
1076 Batch *
batch = MEM_new<Batch>(__func__);
1077 batch->specializations = specializations;
1080 batches_.add(handle,
batch);
1082 batch->pending_compilations = specializations.
size();
1084 compilation_queue_.push({
batch,
i}, priority);
1085 compilation_worker_->wake_up();
1094 std::lock_guard
lock(mutex_);
1096 Batch *
batch = batches_.pop(handle);
1104void *ShaderCompiler::pop_work()
1108 if (compilation_queue_.is_empty()) {
1112 ParallelWork work = compilation_queue_.pop();
1113 return MEM_new<ParallelWork>(__func__, work);
1116void ShaderCompiler::do_work(
void *work_payload)
1118 ParallelWork *work =
reinterpret_cast<ParallelWork *
>(work_payload);
1119 Batch *
batch = work->batch;
1120 int shader_index = work->shader_index;
1124 if (!
batch->is_specialization_batch()) {
1125 batch->shaders[shader_index] = compile_shader(*
batch->infos[shader_index]);
1128 specialize_shader(
batch->specializations[shader_index]);
1132 std::lock_guard
lock(mutex_);
1133 batch->pending_compilations--;
1134 if (
batch->is_ready() &&
batch->is_cancelled) {
1135 batch->free_shaders();
1140 compilation_finished_notification_.notify_all();
1145 std::unique_lock
lock(mutex_);
1146 compilation_finished_notification_.wait(
lock, [&]() {
1147 if (!compilation_queue_.is_empty()) {
1151 for (Batch *
batch : batches_.values()) {
1152 if (!
batch->is_ready()) {
#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
Platform independent time functions.
bool GPU_crappy_amd_driver()
bool GPU_use_main_context_workaround()
eGPUBackendType 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(GPUShader *shader)
bool GPU_matrix_dirty_get()
int GPU_shader_get_sampler_binding(GPUShader *shader, const char *name)
int GPU_shader_get_uniform(GPUShader *shader, const char *name)
GPUShader * GPU_shader_create_from_info_python(const GPUShaderCreateInfo *_info)
void GPU_shader_uniform_2fv(GPUShader *sh, const char *name, const float data[2])
GPUShader * GPU_shader_create_compute(std::optional< blender::StringRefNull > computecode, std::optional< blender::StringRefNull > libcode, std::optional< blender::StringRefNull > defines, blender::StringRefNull shname)
bool GPU_shader_get_attribute_info(const GPUShader *shader, int attr_location, char r_name[256], int *r_type)
const char * GPU_shader_get_name(GPUShader *shader)
void GPU_shader_uniform_1i(GPUShader *sh, const char *name, int value)
int GPU_shader_get_ubo_binding(GPUShader *shader, const char *name)
void GPU_shader_uniform_3f(GPUShader *sh, const char *name, float x, float y, float z)
void GPU_shader_uniform_3iv(GPUShader *sh, const char *name, const int data[3])
blender::Vector< GPUShader * > GPU_shader_batch_finalize(BatchHandle &handle)
void GPU_shader_uniform_2f(GPUShader *sh, const char *name, float x, float y)
uint GPU_shader_get_ssbo_input_len(const GPUShader *shader)
void GPU_shader_uniform_2fv_array(GPUShader *sh, const char *name, int len, const float(*val)[2])
GPUShader * GPU_shader_create_ex(std::optional< blender::StringRefNull > vertcode, std::optional< blender::StringRefNull > fragcode, std::optional< blender::StringRefNull > geomcode, std::optional< blender::StringRefNull > computecode, std::optional< blender::StringRefNull > libcode, std::optional< blender::StringRefNull > defines, blender::StringRefNull shname)
void GPU_shader_uniform_int_ex(GPUShader *shader, int location, int length, int array_size, const int *value)
GPUShader * GPU_shader_create_from_info_name(const char *info_name)
void GPU_shader_cache_dir_clear_old()
void GPU_shader_uniform_1f(GPUShader *sh, const char *name, float value)
void GPU_shader_bind(GPUShader *shader, const blender::gpu::shader::SpecializationConstants *constants_state=nullptr)
void GPU_shader_uniform_mat3_as_mat4(GPUShader *sh, const char *name, const float data[3][3])
void GPU_shader_uniform_3fv(GPUShader *sh, const char *name, const float data[3])
void GPU_shader_uniform_1f_array(GPUShader *sh, const char *name, int len, const float *val)
uint GPU_shader_get_attribute_len(const GPUShader *shader)
int GPU_shader_get_ssbo_binding(GPUShader *shader, const char *name)
int GPU_shader_get_attribute(const GPUShader *shader, const char *name)
void GPU_shader_batch_wait_for_all()
void GPU_shader_uniform_2iv(GPUShader *sh, const char *name, const int data[2])
void GPU_shader_uniform_4fv_array(GPUShader *sh, const char *name, int len, const float(*val)[4])
GPUShader * GPU_shader_create_from_python(std::optional< blender::StringRefNull > vertcode, std::optional< blender::StringRefNull > fragcode, std::optional< blender::StringRefNull > geomcode, std::optional< blender::StringRefNull > libcode, std::optional< blender::StringRefNull > defines, std::optional< blender::StringRefNull > name)
void GPU_shader_set_parent(GPUShader *shader, GPUShader *parent)
bool GPU_shader_batch_is_ready(BatchHandle handle)
int GPU_shader_get_builtin_block(GPUShader *shader, int builtin)
void GPU_shader_uniform_float_ex(GPUShader *shader, int location, int length, int array_size, const float *value)
std::string GPU_shader_preprocess_source(blender::StringRefNull original)
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_batch_specializations_cancel(SpecializationBatchHandle &handle)
void GPU_shader_uniform_1b(GPUShader *sh, const char *name, bool value)
@ GPU_UNIFORM_SRGB_TRANSFORM
GPUShader * GPU_shader_create_from_info(const GPUShaderCreateInfo *_info)
void GPU_shader_uniform_4fv(GPUShader *sh, const char *name, const float data[4])
void GPU_shader_uniform_4f(GPUShader *sh, const char *name, float x, float y, float z, float w)
int GPU_shader_get_uniform_block(GPUShader *shader, const char *name)
int64_t SpecializationBatchHandle
GPUShader * GPU_shader_create(std::optional< blender::StringRefNull > vertcode, std::optional< blender::StringRefNull > fragcode, std::optional< blender::StringRefNull > geomcode, std::optional< blender::StringRefNull > libcode, std::optional< blender::StringRefNull > defines, blender::StringRefNull shname)
void GPU_shader_uniform_mat4(GPUShader *sh, const char *name, const float data[4][4])
int GPU_shader_get_constant(GPUShader *shader, const char *name)
int GPU_shader_get_builtin_uniform(GPUShader *shader, int builtin)
void GPU_shader_batch_cancel(BatchHandle &handle)
void GPU_shader_free(GPUShader *shader)
bool GPU_shader_create_info_check_error(const GPUShaderCreateInfo *_info, char r_error[128])
GPUShader * GPU_shader_get_bound()
BatchHandle GPU_shader_batch_create_from_infos(blender::Span< const GPUShaderCreateInfo * > infos, CompilationPriority priority=CompilationPriority::High)
void GPU_shader_warm_cache(GPUShader *shader, int limit)
bool GPU_shader_batch_specializations_is_ready(SpecializationBatchHandle &handle)
const blender::gpu::shader::SpecializationConstants & GPU_shader_get_default_constant_state(GPUShader *sh)
void GPU_shader_compile_static()
bool GPU_shader_get_ssbo_input_info(const GPUShader *shader, int ssbo_location, char r_name[256])
void GPU_storagebuf_bind(GPUStorageBuf *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)
const T & last(const int64_t n=0) const
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)
int shader_builtin_srgb_transform
bool shader_builtin_srgb_is_dirty
Vector< GPUStorageBuf * > printf_buf
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)
static void set_srgb_uniform(Context *ctx, GPUShader *shader)
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_framebuffer_srgb_target(int use_srgb_to_linear)
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 @040300273355226347117046032274375156036214075200::@220112075160172005224025156041142162054225111362 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)
Vector< StringRefNull > gpu_shader_dependency_get_resolved_source(const StringRefNull shader_source_name)
StringRefNull gpu_shader_dependency_get_source(const StringRefNull shader_source_name)
static Context * unwrap(GPUContext *ctx)
static GPUContext * wrap(Context *ctx)
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_
Vector< std::array< StringRefNull, 2 > > defines_
std::string check_error() const
Vector< StringRefNull, 0 > dependencies_generated
StringRefNull geometry_source_
std::string typedef_source_generated
StringRefNull fragment_source_
std::string compute_source_generated
Vector< SpecializationConstant > specialization_constants_
Vector< StringRefNull > typedef_sources_
Vector< FragOut > fragment_outputs_
Vector< SpecializationConstant::Value, 8 > values
Vector< gpu::shader::Type, 8 > types