35#define SHADER_SOURCE(filename_underscore, filename, filepath) \
36 extern char datatoc_##filename_underscore[];
37#include "glsl_compositor_source_list.h"
38#include "glsl_draw_source_list.h"
39#include "glsl_gpu_source_list.h"
40#include "glsl_ocio_source_list.h"
42# include "glsl_osd_source_list.h"
49using GPUPrintFormatMap = Map<uint32_t, shader::PrintfFormat>;
50using GPUSourceDictionnary = Map<StringRef, struct GPUSource *>;
51using GPUFunctionDictionnary = Map<StringRef, GPUFunction *>;
54 StringRefNull fullpath;
55 StringRefNull filename;
57 std::string patched_source;
60 bool dependencies_init =
false;
61 shader::BuiltinBits builtins = shader::BuiltinBits::NONE;
67 shader::BuiltinBits convert_builtin_bit(shader::metadata::Builtin builtin)
70 using namespace blender::gpu::shader::metadata;
72 case Builtin::FragCoord:
73 return BuiltinBits::FRAG_COORD;
74 case Builtin::FrontFacing:
75 return BuiltinBits::FRONT_FACING;
76 case Builtin::GlobalInvocationID:
77 return BuiltinBits::GLOBAL_INVOCATION_ID;
78 case Builtin::InstanceID:
79 return BuiltinBits::INSTANCE_ID;
80 case Builtin::LocalInvocationID:
81 return BuiltinBits::LOCAL_INVOCATION_ID;
82 case Builtin::LocalInvocationIndex:
83 return BuiltinBits::LOCAL_INVOCATION_INDEX;
84 case Builtin::NumWorkGroup:
85 return BuiltinBits::NUM_WORK_GROUP;
86 case Builtin::PointCoord:
87 return BuiltinBits::POINT_COORD;
88 case Builtin::PointSize:
89 return BuiltinBits::POINT_SIZE;
90 case Builtin::PrimitiveID:
91 return BuiltinBits::PRIMITIVE_ID;
92 case Builtin::VertexID:
93 return BuiltinBits::VERTEX_ID;
94 case Builtin::WorkGroupID:
95 return BuiltinBits::WORK_GROUP_ID;
96 case Builtin::WorkGroupSize:
97 return BuiltinBits::WORK_GROUP_SIZE;
98 case Builtin::drw_debug:
100 return BuiltinBits::USE_DEBUG_DRAW;
102 return BuiltinBits::NONE;
104 case Builtin::assert:
105 case Builtin::printf:
106#if GPU_SHADER_PRINTF_ENABLE
107 return BuiltinBits::USE_PRINTF;
109 return BuiltinBits::NONE;
113 return BuiltinBits::NONE;
116 GPUFunctionQual convert_qualifier(shader::metadata::Qualifier qualifier)
120 case metadata::Qualifier::in:
122 case metadata::Qualifier::out:
124 case metadata::Qualifier::inout:
131 eGPUType convert_type(shader::metadata::Type type)
135 case metadata::Type::float1:
137 case metadata::Type::float2:
139 case metadata::Type::float3:
141 case metadata::Type::float4:
143 case metadata::Type::float3x3:
145 case metadata::Type::float4x4:
147 case metadata::Type::sampler1DArray:
149 case metadata::Type::sampler2DArray:
151 case metadata::Type::sampler2D:
153 case metadata::Type::sampler3D:
155 case metadata::Type::Closure:
166 GPUFunctionDictionnary *g_functions,
167 GPUPrintFormatMap *g_formats,
168 std::function<
void(GPUSource &, GPUFunctionDictionnary *, GPUPrintFormatMap *)> metadata_fn)
169 : fullpath(path), filename(
file), source(datatoc)
171 metadata_fn(*
this, g_functions, g_formats);
174 void add_builtin(shader::metadata::Builtin builtin)
176 builtins |= convert_builtin_bit(builtin);
181 dependencies_names.append(line);
184 void add_printf_format(
uint32_t format_hash, std::string
format, GPUPrintFormatMap *format_map)
187 if (format_map->contains(format_hash)) {
188 if (format_map->lookup(format_hash).format_str !=
format) {
201 format = std::regex_replace(
format, std::regex(R
"(\\n)"), "\n");
202 format = std::regex_replace(
format, std::regex(R
"(\\v)"), "\v");
203 format = std::regex_replace(
format, std::regex(R
"(\\t)"), "\t");
204 format = std::regex_replace(
format, std::regex(R
"(\\')"), "\'");
205 format = std::regex_replace(
format, std::regex(R
"(\\")"), "\"");
206 format = std::regex_replace(
format, std::regex(R
"(\\\\)"), "\\");
209 shader::PrintfFormat::Block::ArgumentType::NONE;
211 while ((end =
format.find_first_of(
'%', start + 1)) != -1) {
216 switch (
format[end + 1]) {
219 type = shader::PrintfFormat::Block::ArgumentType::UINT;
222 type = shader::PrintfFormat::Block::ArgumentType::INT;
225 type = shader::PrintfFormat::Block::ArgumentType::FLOAT;
236 format_map->add(format_hash, fmt);
242 GPUFunctionDictionnary *g_functions)
244 GPUFunction *func = MEM_new<GPUFunction>(__func__);
245 name.copy_utf8_truncated(func->
name,
sizeof(func->
name));
246 func->
source =
reinterpret_cast<void *
>(
this);
248 for (
auto arg : arguments) {
250 print_error(source, source.find(
name),
"Too many parameters in function");
258 bool insert = g_functions->add(func->
name, func);
262 GPUSource *other_source =
reinterpret_cast<GPUSource *
>(g_functions->lookup(
name)->source);
263 if (other_source !=
this) {
264 const char *msg =
"Function redefinition or overload in two different files ...";
267 other_source->source.find(
name),
268 "... previous definition was here");
283 int64_t char_number = offset - line_start + 1;
287 std::cerr << fullpath <<
":" << line_number <<
":" << char_number;
289 std::cerr <<
" error: " << message <<
"\n";
290 std::cerr << std::setw(5) << line_number <<
" | "
291 <<
input.
substr(line_start, line_end - line_start) <<
"\n";
293 for (
int64_t i = 0; i < char_number - 1; i++) {
300 int init_dependencies(
const GPUSourceDictionnary &dict,
301 const GPUFunctionDictionnary &g_functions)
303 if (this->dependencies_init) {
306 this->dependencies_init =
true;
308 using namespace shader;
310 if ((builtins & BuiltinBits::USE_PRINTF) == BuiltinBits::USE_PRINTF) {
311 dependencies.append_non_duplicates(dict.lookup(
"gpu_shader_print_lib.glsl"));
313 if ((builtins & BuiltinBits::USE_DEBUG_DRAW) == BuiltinBits::USE_DEBUG_DRAW) {
314 dependencies.append_non_duplicates(dict.lookup(
"draw_debug_draw_lib.glsl"));
317 for (
auto dependency_name : dependencies_names) {
318 GPUSource *dependency_source = dict.lookup_default(dependency_name,
nullptr);
319 if (dependency_source ==
nullptr) {
320 std::string
error = std::string(
"Dependency not found : ") + dependency_name;
326 int result = dependency_source->init_dependencies(dict, g_functions);
331 for (
auto *dep : dependency_source->dependencies) {
332 dependencies.append_non_duplicates(dep);
334 dependencies.append_non_duplicates(dependency_source);
336 dependencies_names.clear();
343 for (
auto *dep : dependencies) {
344 result.append(dep->source);
352 for (
auto *dep : dependencies) {
353 out_builtins |= dep->builtins;
358 bool is_from_material_library()
const
360 return (filename.startswith(
"gpu_shader_material_") ||
361 filename.startswith(
"gpu_shader_common_") ||
362 filename.startswith(
"gpu_shader_compositor_")) &&
363 filename.endswith(
".glsl");
369#include "glsl_compositor_metadata_list.hh"
370#include "glsl_draw_metadata_list.hh"
371#include "glsl_gpu_metadata_list.hh"
372#include "glsl_ocio_metadata_list.hh"
373#ifdef WITH_OPENSUBDIV
374# include "glsl_osd_metadata_list.hh"
383static GPUPrintFormatMap *g_formats =
nullptr;
384static GPUSourceDictionnary *g_sources =
nullptr;
385static GPUFunctionDictionnary *g_functions =
nullptr;
386static bool force_printf_injection =
false;
390 g_formats =
new GPUPrintFormatMap();
391 g_sources =
new GPUSourceDictionnary();
392 g_functions =
new GPUFunctionDictionnary();
394#define SHADER_SOURCE(filename_underscore, filename, filepath) \
395 g_sources->add_new(filename, \
396 new GPUSource(filepath, \
398 datatoc_##filename_underscore, \
401 blender::gpu::shader::metadata_##filename_underscore));
403#include "glsl_compositor_source_list.h"
404#include "glsl_draw_source_list.h"
405#include "glsl_gpu_source_list.h"
406#include "glsl_ocio_source_list.h"
407#ifdef WITH_OPENSUBDIV
408# include "glsl_osd_source_list.h"
411#ifdef WITH_OPENSUBDIV
414 "osd_patch_basis.glsl",
415 new GPUSource(
"osd_patch_basis.glsl",
416 "osd_patch_basis.glsl",
417 patch_basis_source.
c_str(),
420 [](GPUSource &, GPUFunctionDictionnary *, GPUPrintFormatMap *) {}));
424 for (
auto *
value : g_sources->values()) {
425 errors +=
value->init_dependencies(*g_sources, *g_functions);
427 BLI_assert_msg(errors == 0,
"Dependency errors detected: Aborting");
430#if GPU_SHADER_PRINTF_ENABLE
431 if (!g_formats->is_empty()) {
434 for (
auto *
value : g_sources->values()) {
435 if (
bool(
value->builtins & shader::BuiltinBits::USE_PRINTF)) {
436 if (
value->filename.startswith(
"gpu_shader_material_")) {
437 force_printf_injection =
true;
446 for (
auto *
value : g_sources->values()) {
448 value->source =
value->patched_source.c_str();
449 size_t start_pos = 0;
450 while ((start_pos =
value->patched_source.find(
"#line ", start_pos)) != std::string::npos) {
451 value->patched_source[start_pos] =
'/';
452 value->patched_source[start_pos + 1] =
'/';
460 for (
auto *
value : g_sources->values()) {
463 for (
auto *
value : g_functions->values()) {
471 g_functions =
nullptr;
477 BLI_assert_msg(function !=
nullptr,
"Requested function not in the function library");
478 GPUSource *source =
reinterpret_cast<GPUSource *
>(function->
source);
479 BLI_gset_add(used_libraries,
const_cast<char *
>(source->filename.c_str()));
489 return force_printf_injection;
494 return (g_formats !=
nullptr) && !g_formats->is_empty();
499 return g_formats->lookup(format_hash);
504 if (shader_source_name.
is_empty()) {
507 if (g_sources->contains(shader_source_name) ==
false) {
508 std::cerr <<
"Error: Could not find \"" << shader_source_name
509 <<
"\" in the list of registered source.\n";
513 GPUSource *source = g_sources->lookup(shader_source_name);
514 return source->builtins_get();
521 GPUSource *src = g_sources->lookup_default(shader_source_name,
nullptr);
522 if (src ==
nullptr) {
523 std::cerr <<
"Error source not found : " << shader_source_name << std::endl;
531 GPUSource *src = g_sources->lookup_default(shader_source_name,
nullptr);
532 if (src ==
nullptr) {
533 std::cerr <<
"Error source not found : " << shader_source_name << std::endl;
540 for (
auto &source : g_sources->values()) {
541 if (source->source == source_string) {
542 return source->filename;
#define BLI_assert_unreachable()
#define BLI_assert_msg(a, msg)
bool BLI_gset_add(GSet *gs, void *key)
void BLI_kdtree_nd_ insert(KDTree *tree, int index, const float co[KD_DIMS]) ATTR_NONNULL(1
#define UNUSED_VARS_NDEBUG(...)
void build(btStridingMeshInterface *triangles, bool useQuantizedAabbCompression, const btVector3 &bvhAabbMin, const btVector3 &bvhAabbMax)
constexpr int64_t find(char c, int64_t pos=0) const
constexpr const char * begin() const
constexpr const char * end() const
constexpr bool is_empty() const
constexpr StringRef substr(int64_t start, int64_t size) const
constexpr const char * c_str() const
const char * openSubdiv_getGLSLPatchBasisSource()
GPUFunction * gpu_material_library_use_function(GSet *used_libraries, const char *name)
void gpu_shader_dependency_init()
void gpu_shader_dependency_exit()
static void print_error(const char *message, va_list str_format_args)
static void error(const char *str)
Vector< StringRefNull > gpu_shader_dependency_get_resolved_source(StringRefNull source_name)
const PrintfFormat & gpu_shader_dependency_get_printf_format(uint32_t format_hash)
StringRefNull gpu_shader_dependency_get_source(StringRefNull source_name)
BuiltinBits gpu_shader_dependency_get_builtins(const StringRefNull source_name)
bool gpu_shader_dependency_has_printf()
bool gpu_shader_dependency_force_gpu_print_injection()
StringRefNull gpu_shader_dependency_get_filename_from_source_string(StringRef source_string)
Find the name of the file from which the given string was generated.
eGPUType paramtype[MAX_PARAMETER]
char name[MAX_FUNCTION_NAME]
GPUFunctionQual paramqual[MAX_PARAMETER]
bool line_directive_workaround