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);
408 printf(
"Compiling all static GPU shaders. This process takes a while.\n");
428 "Shader requires specialization constants but none was passed");
434 shader->bind(constants_state);
439 if (constants_state) {
440 shader->bind(constants_state);
449#if GPU_SHADER_PRINTF_ENABLE
459 if (ctx ==
nullptr) {
520 return *
unwrap(sh)->constants;
531 constants = std::make_unique<const shader::SpecializationConstants>(std::move(constants_tmp));
560 return uniform ? uniform->location : -1;
567 return constant ? constant->location : -1;
586 return ssbo ? ssbo->location : -1;
593 return ubo ? ubo->location : -1;
600 return ubo ? ubo->binding : -1;
607 return tex ? tex->binding : -1;
626 return attr ? attr->location : -1;
642 *r_type = attr->location != -1 ?
interface->attr_types_[attr->location] : -1;
666 GPUShader *
shader,
int loc,
int len,
int array_size,
const float *value)
672 GPUShader *
shader,
int loc,
int len,
int array_size,
const int *value)
690 const float data[2] = {
x,
y};
696 const float data[3] = {
x,
y,
z};
775namespace blender::gpu {
814 using Clock = std::chrono::steady_clock;
815 using TimePoint = Clock::time_point;
820 TimePoint start_time;
827 else if (
G.profile_gpu) {
828 start_time = Clock::now();
832 if (!
error.empty()) {
833 std::cerr <<
error <<
"\n";
840 shader->specialization_constants_init(info);
841 shader->init(info, is_batch_compilation);
843 shader->fragment_output_bits = 0;
845 shader->fragment_output_bits |= 1u << frag_out.
index;
848 std::string defines =
shader->defines_declare(info);
849 std::string resources =
shader->resources_declare(info);
851 defines +=
"#define USE_GPU_SHADER_CREATE_INFO\n";
866 std::string
interface =
shader->vertex_interface_declare(info);
870 sources.append(
"#define GPU_VERTEX_SHADER\n");
871 if (!info.geometry_source_.is_empty()) {
872 sources.append(
"#define USE_GEOMETRY_SHADER\n");
874 sources.append(defines);
875 sources.extend(typedefs);
876 sources.append(resources);
878 sources.extend(code);
879 sources.extend(info.dependencies_generated);
880 sources.append(info.vertex_source_generated);
882 shader->vertex_shader_from_glsl(sources);
887 std::string
interface =
shader->fragment_interface_declare(info);
891 sources.append(
"#define GPU_FRAGMENT_SHADER\n");
892 if (!info.geometry_source_.is_empty()) {
893 sources.append(
"#define USE_GEOMETRY_SHADER\n");
895 sources.append(defines);
896 sources.extend(typedefs);
897 sources.append(resources);
899 sources.extend(code);
900 sources.extend(info.dependencies_generated);
901 sources.append(info.fragment_source_generated);
903 shader->fragment_shader_from_glsl(sources);
908 std::string layout =
shader->geometry_layout_declare(info);
909 std::string
interface =
shader->geometry_interface_declare(info);
913 sources.append(
"#define GPU_GEOMETRY_SHADER\n");
914 sources.append(defines);
915 sources.extend(typedefs);
916 sources.append(resources);
917 sources.append(layout);
919 sources.append(info.geometry_source_generated);
920 sources.extend(code);
922 shader->geometry_shader_from_glsl(sources);
927 std::string layout =
shader->compute_layout_declare(info);
931 sources.
append(
"#define GPU_COMPUTE_SHADER\n");
934 sources.
append(resources);
940 shader->compute_shader_from_glsl(sources);
943 if (!
shader->finalize(&info)) {
953 else if (
G.profile_gpu) {
954 TimePoint end_time = Clock::now();
957 start_time.time_since_epoch().count(),
958 end_time.time_since_epoch().count());
960 start_time.time_since_epoch().count(),
961 end_time.time_since_epoch().count());
969 bool support_specializations)
971 support_specializations_ = support_specializations;
974 compilation_worker_ = std::make_unique<GPUWorker>(
978 [
this]() ->
void * {
return this->pop_work(); },
979 [
this](
void *work) { this->do_work(work); });
985 compilation_worker_.reset();
999 std::unique_lock
lock(mutex_);
1001 Batch *
batch = MEM_new<Batch>(__func__);
1002 batch->infos = infos;
1006 batches_.add(handle,
batch);
1008 if (compilation_worker_) {
1009 batch->shaders.resize(infos.
size(),
nullptr);
1010 batch->pending_compilations = infos.
size();
1012 compilation_queue_.push({
batch,
i}, priority);
1013 compilation_worker_->wake_up();
1027 std::unique_lock
lock(mutex_);
1029 Batch *
batch = batches_.pop(handle);
1030 compilation_queue_.remove_batch(
batch);
1032 if (
batch->is_specialization_batch()) {
1035 compilation_finished_notification_.wait(
lock, [&]() {
return batch->is_ready(); });
1038 if (
batch->is_ready()) {
1039 batch->free_shaders();
1044 batch->is_cancelled =
true;
1052 std::lock_guard
lock(mutex_);
1054 return batches_.lookup(handle)->is_ready();
1059 std::unique_lock
lock(mutex_);
1061 compilation_finished_notification_.wait(
lock,
1062 [&]() {
return batches_.lookup(handle)->is_ready(); });
1064 Batch *
batch = batches_.pop(handle);
1075 if (!compilation_worker_ || !support_specializations_) {
1079 std::lock_guard
lock(mutex_);
1081 Batch *
batch = MEM_new<Batch>(__func__);
1082 batch->specializations = specializations;
1085 batches_.add(handle,
batch);
1087 batch->pending_compilations = specializations.
size();
1089 compilation_queue_.push({
batch,
i}, priority);
1090 compilation_worker_->wake_up();
1099 std::lock_guard
lock(mutex_);
1101 Batch *
batch = batches_.pop(handle);
1109void *ShaderCompiler::pop_work()
1113 if (compilation_queue_.is_empty()) {
1117 ParallelWork work = compilation_queue_.pop();
1118 return MEM_new<ParallelWork>(__func__, work);
1121void ShaderCompiler::do_work(
void *work_payload)
1123 ParallelWork *work =
reinterpret_cast<ParallelWork *
>(work_payload);
1124 Batch *
batch = work->batch;
1125 int shader_index = work->shader_index;
1129 if (!
batch->is_specialization_batch()) {
1130 batch->shaders[shader_index] = compile_shader(*
batch->infos[shader_index]);
1133 specialize_shader(
batch->specializations[shader_index]);
1137 std::lock_guard
lock(mutex_);
1138 batch->pending_compilations--;
1139 if (
batch->is_ready() &&
batch->is_cancelled) {
1140 batch->free_shaders();
1145 compilation_finished_notification_.notify_all();
1148bool ShaderCompiler::is_compiling_impl()
1153 if (!compilation_queue_.is_empty()) {
1157 for (Batch *
batch : batches_.values()) {
1158 if (!
batch->is_ready()) {
1168 std::unique_lock
lock(mutex_);
1169 return is_compiling_impl();
1174 std::unique_lock
lock(mutex_);
1175 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
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)
bool GPU_shader_batch_is_compiling()
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 @064345207361167251075330302113175271221317160336::@113254110077376341056327177062323111323010325277 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