16#if !defined(GPU_SHADER)
28#if defined(GPU_SHADER)
35#define GPU_FORCE_ENABLE_SHADER_PRINTF 0
37#if !defined(NDEBUG) || GPU_FORCE_ENABLE_SHADER_PRINTF
38# define GPU_SHADER_PRINTF_ENABLE 1
40# define GPU_SHADER_PRINTF_ENABLE 0
42#define GPU_SHADER_PRINTF_SLOT 13
43#define GPU_SHADER_PRINTF_MAX_CAPACITY (1024 * 4)
46#define GPU_SSBO_INDEX_BUF_SLOT 7
48#define GPU_SSBO_POLYLINE_POS_BUF_SLOT 0
49#define GPU_SSBO_POLYLINE_COL_BUF_SLOT 1
51#if defined(GLSL_CPP_STUBS)
52# define GPU_SHADER_NAMED_INTERFACE_INFO(_interface, _inst_name) \
53 namespace interface::_interface { \
55# define GPU_SHADER_NAMED_INTERFACE_END(_inst_name) \
60# define GPU_SHADER_INTERFACE_INFO(_interface) namespace interface::_interface {
61# define GPU_SHADER_INTERFACE_END() }
63# define GPU_SHADER_CREATE_INFO(_info) \
65 namespace gl_VertexShader { \
67 namespace gl_FragmentShader { \
69 namespace gl_ComputeShader { \
71# define GPU_SHADER_CREATE_END() }
73# define SHADER_LIBRARY_CREATE_INFO(_info) using namespace _info;
74# define VERTEX_SHADER_CREATE_INFO(_info) \
75 using namespace ::gl_VertexShader; \
76 using namespace _info::gl_VertexShader; \
77 using namespace _info;
78# define FRAGMENT_SHADER_CREATE_INFO(_info) \
79 using namespace ::gl_FragmentShader; \
80 using namespace _info::gl_FragmentShader; \
81 using namespace _info;
82# define COMPUTE_SHADER_CREATE_INFO(_info) \
83 using namespace ::gl_ComputeShader; \
84 using namespace _info::gl_ComputeShader; \
85 using namespace _info;
87#elif !defined(GPU_SHADER_CREATE_INFO)
89# define GPU_SHADER_NAMED_INTERFACE_INFO(_interface, _inst_name) \
90 static inline void autocomplete_helper_interface_##_interface() \
92 StageInterfaceInfo _interface(#_interface, _inst_name); \
94# define GPU_SHADER_INTERFACE_INFO(_interface) \
95 static inline void autocomplete_helper_interface_##_interface() \
97 StageInterfaceInfo _interface(#_interface); \
99# define GPU_SHADER_CREATE_INFO(_info) \
100 static inline void autocomplete_helper_info_##_info() \
102 ShaderCreateInfo _info(#_info); \
105# define GPU_SHADER_NAMED_INTERFACE_END(_inst_name) \
108# define GPU_SHADER_INTERFACE_END() \
111# define GPU_SHADER_CREATE_END() \
117#ifndef GLSL_CPP_STUBS
118# define SMOOTH(type, name) .smooth(Type::type##_t, #name)
119# define FLAT(type, name) .flat(Type::type##_t, #name)
120# define NO_PERSPECTIVE(type, name) .no_perspective(Type::type##_t, #name)
123# define LOCAL_GROUP_SIZE(...) .local_group_size(__VA_ARGS__)
125# define VERTEX_IN(slot, type, name) .vertex_in(slot, Type::type##_t, #name)
126# define VERTEX_IN_SRD(srd) .shared_resource_descriptor(srd::populate)
127# define VERTEX_OUT(stage_interface) .vertex_out(stage_interface)
128# define VERTEX_OUT_SRD(srd) .vertex_out(srd)
130# define GEOMETRY_LAYOUT(...) .geometry_layout(__VA_ARGS__)
131# define GEOMETRY_OUT(stage_interface) .geometry_out(stage_interface)
133# define SUBPASS_IN(slot, type, img_type, name, rog) \
134 .subpass_in(slot, Type::type##_t, ImageType::img_type, #name, rog)
136# define FRAGMENT_OUT(slot, type, name) .fragment_out(slot, Type::type##_t, #name)
137# define FRAGMENT_OUT_SRD(srd) .shared_resource_descriptor(srd::populate)
138# define FRAGMENT_OUT_DUAL(slot, type, name, blend) \
139 .fragment_out(slot, Type::type##_t, #name, DualBlend::blend)
140# define FRAGMENT_OUT_ROG(slot, type, name, rog) \
141 .fragment_out(slot, Type::type##_t, #name, DualBlend::NONE, rog)
143# define RESOURCE_SRD(srd) .shared_resource_descriptor(srd::populate)
145# define EARLY_FRAGMENT_TEST(enable) .early_fragment_test(enable)
146# define DEPTH_WRITE(value) .depth_write(value)
148# define SPECIALIZATION_CONSTANT(type, name, default_value) \
149 .specialization_constant(Type::type##_t, #name, default_value)
151# define COMPILATION_CONSTANT(type, name, value) \
152 .compilation_constant(Type::type##_t, #name, value)
154# define PUSH_CONSTANT(type, name) .push_constant(Type::type##_t, #name)
155# define PUSH_CONSTANT_ARRAY(type, name, array_size) \
156 .push_constant(Type::type##_t, #name, array_size)
158# define UNIFORM_BUF(slot, type_name, name) .uniform_buf(slot, #type_name, #name)
159# define UNIFORM_BUF_FREQ(slot, type_name, name, freq) \
160 .uniform_buf(slot, #type_name, #name, Frequency::freq)
162# define STORAGE_BUF(slot, qualifiers, type_name, name) \
163 .storage_buf(slot, Qualifier::qualifiers, STRINGIFY(type_name), #name)
164# define STORAGE_BUF_FREQ(slot, qualifiers, type_name, name, freq) \
165 .storage_buf(slot, Qualifier::qualifiers, STRINGIFY(type_name), #name, Frequency::freq)
167# define SAMPLER(slot, type, name) .sampler(slot, ImageType::type, #name)
168# define SAMPLER_FREQ(slot, type, name, freq) \
169 .sampler(slot, ImageType::type, #name, Frequency::freq)
171# define IMAGE(slot, format, qualifiers, type, name) \
173 blender::gpu::TextureFormat::format, \
174 Qualifier::qualifiers, \
175 ImageReadWriteType::type, \
177# define IMAGE_FREQ(slot, format, qualifiers, type, name, freq) \
179 blender::gpu::TextureFormat::format, \
180 Qualifier::qualifiers, \
181 ImageReadWriteType::type, \
185# define GROUP_SHARED(type, name) .shared_variable(Type::type##_t, #name)
187# define BUILTINS(builtin) .builtins(builtin)
189# define VERTEX_SOURCE(filename) .vertex_source(filename)
190# define FRAGMENT_SOURCE(filename) .fragment_source(filename)
191# define COMPUTE_SOURCE(filename) .compute_source(filename)
193# define VERTEX_FUNCTION(function) .vertex_function(function)
194# define FRAGMENT_FUNCTION(function) .fragment_function(function)
195# define COMPUTE_FUNCTION(function) .compute_function(function)
197# define DEFINE(name) .define(name)
198# define DEFINE_VALUE(name, value) .define(name, value)
200# define DO_STATIC_COMPILATION() .do_static_compilation(true)
201# define AUTO_RESOURCE_LOCATION() .auto_resource_location(true)
204# define METAL_BACKEND_ONLY() .metal_backend_only(true)
206# define ADDITIONAL_INFO(info_name) .additional_info(#info_name)
207# define TYPEDEF_SOURCE(filename) .typedef_source(filename)
209# define MTL_MAX_TOTAL_THREADS_PER_THREADGROUP(value) \
210 .mtl_max_total_threads_per_threadgroup(value)
218# define SMOOTH(type, name) type name = {};
219# define FLAT(type, name) type name = {};
220# define NO_PERSPECTIVE(type, name) type name = {};
223# define LOCAL_GROUP_SIZE(...)
225# define VERTEX_IN(slot, type, name) \
226 namespace gl_VertexShader { \
227 const type name = {}; \
229# define VERTEX_IN_SRD(srd) \
230 namespace gl_VertexShader { \
231 using namespace srd; \
233# define VERTEX_OUT(stage_interface) using namespace interface::stage_interface;
234# define VERTEX_OUT_SRD(srd) using namespace interface::srd;
236# define GEOMETRY_LAYOUT(...)
237# define GEOMETRY_OUT(stage_interface) using namespace interface::stage_interface;
239# define SUBPASS_IN(slot, type, img_type, name, rog) const type name = {};
241# define FRAGMENT_OUT(slot, type, name) \
242 namespace gl_FragmentShader { \
245# define FRAGMENT_OUT_DUAL(slot, type, name, blend) \
246 namespace gl_FragmentShader { \
249# define FRAGMENT_OUT_ROG(slot, type, name, rog) \
250 namespace gl_FragmentShader { \
253# define FRAGMENT_OUT_SRD(srd) \
254 namespace gl_FragmentShader { \
255 using namespace srd; \
258# define RESOURCE_SRD(srd) using namespace srd;
260# define EARLY_FRAGMENT_TEST(enable)
261# define DEPTH_WRITE(value)
263# define SPECIALIZATION_CONSTANT(type, name, default_value) \
264 constexpr type name = type(default_value);
266# define COMPILATION_CONSTANT(type, name, value) constexpr type name = type(value);
268# define PUSH_CONSTANT(type, name) extern const type name;
269# define PUSH_CONSTANT_ARRAY(type, name, array_size) extern const type name[array_size];
271# define UNIFORM_BUF(slot, type_name, name) extern const type_name name;
272# define UNIFORM_BUF_FREQ(slot, type_name, name, freq) extern const type_name name;
274# define STORAGE_BUF(slot, qualifiers, type_name, name) extern _##qualifiers type_name name;
275# define STORAGE_BUF_FREQ(slot, qualifiers, type_name, name, freq) \
276 extern _##qualifiers type_name name;
278# define SAMPLER(slot, type, name) type name;
279# define SAMPLER_FREQ(slot, type, name, freq) type name;
281# define IMAGE(slot, format, qualifiers, type, name) _##qualifiers type name;
282# define IMAGE_FREQ(slot, format, qualifiers, type, name, freq) _##qualifiers type name;
284# define GROUP_SHARED(type, name) type name;
286# define BUILTINS(builtin)
288# define VERTEX_SOURCE(filename)
289# define FRAGMENT_SOURCE(filename)
290# define COMPUTE_SOURCE(filename)
292# define VERTEX_FUNCTION(filename)
293# define FRAGMENT_FUNCTION(filename)
294# define COMPUTE_FUNCTION(filename)
297# define DEFINE_VALUE(name, value)
299# define DO_STATIC_COMPILATION()
300# define AUTO_RESOURCE_LOCATION()
303# define METAL_BACKEND_ONLY()
305# define ADDITIONAL_INFO(info_name) \
306 using namespace info_name; \
307 using namespace info_name::gl_FragmentShader; \
308 using namespace info_name::gl_VertexShader;
310# define TYPEDEF_SOURCE(filename)
312# define MTL_MAX_TOTAL_THREADS_PER_THREADGROUP(value)
315#define _INFO_EXPAND2(a, b) ADDITIONAL_INFO(a) ADDITIONAL_INFO(b)
316#define _INFO_EXPAND3(a, b, c) _INFO_EXPAND2(a, b) ADDITIONAL_INFO(c)
317#define _INFO_EXPAND4(a, b, c, d) _INFO_EXPAND3(a, b, c) ADDITIONAL_INFO(d)
318#define _INFO_EXPAND5(a, b, c, d, e) _INFO_EXPAND4(a, b, c, d) ADDITIONAL_INFO(e)
319#define _INFO_EXPAND6(a, b, c, d, e, f) _INFO_EXPAND5(a, b, c, d, e) ADDITIONAL_INFO(f)
321#define ADDITIONAL_INFO_EXPAND(...) VA_NARGS_CALL_OVERLOAD(_INFO_EXPAND, __VA_ARGS__)
323#define CREATE_INFO_VARIANT(name, ...) \
324 GPU_SHADER_CREATE_INFO(name) \
325 DO_STATIC_COMPILATION() \
326 ADDITIONAL_INFO_EXPAND(__VA_ARGS__) \
327 GPU_SHADER_CREATE_END()
329#if !defined(GLSL_CPP_STUBS)
354 BLI_assert_msg(0,
"Error: Cannot convert GPUType to shader::Type.");
363 return stream <<
"float";
365 return stream <<
"vec2";
367 return stream <<
"vec3";
369 return stream <<
"vec4";
371 return stream <<
"mat3";
373 return stream <<
"mat4";
375 return stream <<
"vec3_1010102_Inorm";
377 return stream <<
"uchar";
379 return stream <<
"uchar2";
381 return stream <<
"uchar3";
383 return stream <<
"uchar4";
385 return stream <<
"char";
387 return stream <<
"char2";
389 return stream <<
"char3";
391 return stream <<
"char4";
393 return stream <<
"int";
395 return stream <<
"ivec2";
397 return stream <<
"ivec3";
399 return stream <<
"ivec4";
401 return stream <<
"uint";
403 return stream <<
"uvec2";
405 return stream <<
"uvec3";
407 return stream <<
"uvec4";
409 return stream <<
"ushort";
411 return stream <<
"ushort2";
413 return stream <<
"ushort3";
415 return stream <<
"ushort4";
417 return stream <<
"short";
419 return stream <<
"short2";
421 return stream <<
"short3";
423 return stream <<
"short4";
425 return stream <<
"bool";
436 return stream <<
"Closure";
438 return stream <<
to_type(type);
505# define TYPES_EXPAND(s) \
506 Float##s, Uint##s, Int##s, sampler##s = Float##s, usampler##s = Uint##s, isampler##s = Int##s
518# define TYPES_EXPAND(s) \
519 Shadow##s, Depth##s, sampler##s##Shadow = Shadow##s, sampler##s##Depth = Depth##s
527# define TYPES_EXPAND(s) \
528 AtomicUint##s, AtomicInt##s, usampler##s##Atomic = AtomicUint##s, \
529 isampler##s##Atomic = AtomicInt##s
547# define TYPES_EXPAND(s) \
548 Float##s = int(ImageType::Float##s), Uint##s = int(ImageType::Uint##s), \
549 Int##s = int(ImageType::Int##s), image##s = Float##s, uimage##s = Uint##s, iimage##s = Int##s
558# define TYPES_EXPAND(s) \
559 AtomicUint##s = int(ImageType::AtomicUint##s), AtomicInt##s = int(ImageType::AtomicInt##s), \
560 uimage##s##Atomic = AtomicUint##s, iimage##s##Atomic = AtomicInt##s
652 return *(
Self *)
this;
658 return *(
Self *)
this;
664 return *(
Self *)
this;
752# define TEST_EQUAL(a, b, _member) \
753 if (!((a)._member == (b)._member)) { \
757# define TEST_VECTOR_EQUAL(a, b, _vector) \
758 TEST_EQUAL(a, b, _vector.size()); \
759 for (auto i : _vector.index_range()) { \
760 TEST_EQUAL(a, b, _vector[i]); \
963 return all_resources;
1000# ifdef WITH_METAL_BACKEND
1001 ushort mtl_max_threads_per_threadgroup_ = 0;
1018 return *(
Self *)
this;
1024 return *(
Self *)
this;
1030 int invocations = -1)
1036 return *(
Self *)
this;
1044 return *(
Self *)
this;
1054 return *(
Self *)
this;
1066 return *(
Self *)
this;
1073 int raster_order_group = -1)
1076 return *(
Self *)
this;
1097 return *(
Self *)
this;
1103 return *(
Self *)
this;
1119 constant.
type = type;
1123 constant.
value.
i = int(default_value);
1130 BLI_assert_msg(0,
"Only scalar integer and bool types can be used as constants");
1135 return *(
Self *)
this;
1169 constant.
type = type;
1173 constant.
value.
i = int(default_value);
1188 return *(
Self *)
this;
1204 return *(
Self *)
this;
1223 return *(
Self *)
this;
1238 return *(
Self *)
this;
1255 return *(
Self *)
this;
1272 return *(
Self *)
this;
1284 return *(
Self *)
this;
1290 return *(
Self *)
this;
1296 return *(
Self *)
this;
1302 return *(
Self *)
this;
1308 return *(
Self *)
this;
1314 return *(
Self *)
this;
1331 "Array syntax is forbidden for push constants."
1332 "Use the array_size parameter instead.");
1335 return *(
Self *)
this;
1347 return *(
Self *)
this;
1359 return *(
Self *)
this;
1365 return *(
Self *)
this;
1372 return *(
Self *)
this;
1378 return *(
Self *)
this;
1384 return *(
Self *)
this;
1398 return *(
Self *)
this;
1405 return *(
Self *)
this;
1421 return *(
Self *)
this;
1441# ifdef WITH_METAL_BACKEND
1442 mtl_max_threads_per_threadgroup_ = max_total_threads_per_threadgroup;
1446 return *(
Self *)
this;
1461 void finalize(
const bool recursive =
false);
1515 switch (res.bind_type) {
1517 stream <<
"UNIFORM_BUFFER(" << res.slot <<
", " << res.uniformbuf.name <<
")"
1521 stream <<
"STORAGE_BUFFER(" << res.slot <<
", " << res.storagebuf.name <<
")"
1525 stream <<
"SAMPLER(" << res.slot <<
", " << res.sampler.name <<
")" << std::endl;
1528 stream <<
"IMAGE(" << res.slot <<
", " << res.image.name <<
")" << std::endl;
1549 if (res.bind_type == bind_type) {
1554 if (res.bind_type == bind_type) {
1559 if (res.bind_type == bind_type) {
1574# undef TEST_VECTOR_EQUAL
#define BLI_assert_unreachable()
#define BLI_assert_msg(a, msg)
#define ENUM_OPERATORS(_type, _max)
unsigned long long int uint64_t
static T Cube(const T &x)
constexpr StringRef substr(int64_t start, int64_t size) const
constexpr int64_t find_first_of(StringRef chars, int64_t pos=0) const
constexpr int64_t size() const
constexpr const char * c_str() const
constexpr StringRefNull()
void extend(Span< T > array)
#define SMOOTH(type, name)
#define TEST_VECTOR_EQUAL(a, b, _vector)
#define NO_PERSPECTIVE(type, name)
#define TEST_EQUAL(a, b, _member)
Vector< shader::GeneratedSource, 0 > GeneratedSourceList
static Type to_type(const GPUType type)
static std::ostream & operator<<(std::ostream &stream, const Type type)
static void print_resource(std::ostream &os, const ShaderCreateInfo::Resource &res)
static constexpr GPUSamplerState internal_sampler()
uint64_t operator()(const Vector< blender::gpu::shader::SpecializationConstant::Value > &key) const
SpecializationConstant::Value value
Vector< StringRefNull > dependencies
bool operator==(const ComputeStageLayout &b) const
bool operator==(const FragOut &b) const
bool operator==(const GeometryStageLayout &b) const
PrimitiveOut primitive_out
bool operator==(const PushConst &b) const
constexpr ResourceString()
constexpr ResourceString(const char *str, int64_t size)
int64_t array_offset() const
StringRef str_no_array() const
ResourceString(std::nullptr_t)=delete
StringRef str_only_array() const
ResourceString(const StringRefNull &str)
ResourceString(const std::string &str)
constexpr ResourceString(const char *str)
bool operator==(const Resource &b) const
Resource(BindType type, int _slot)
bool operator==(const SubpassIn &b) const
bool operator==(const VertIn &b) const
Describe inputs & outputs, stage interfaces, resources and sources of a shader. If all data is correc...
StringRefNull vertex_source_
Vector< StageInterfaceInfo * > vertex_out_interfaces_
StringRefNull compute_source_
Vector< SubpassIn > subpass_inputs_
ShaderCreateInfo(const char *name)
StringRefNull compute_entry_fn_
Self & mtl_max_total_threads_per_threadgroup(ushort max_total_threads_per_threadgroup)
Self & compute_source(StringRefNull filename)
Vector< Resource > geometry_resources_
Self & compilation_constant(Type type, StringRefNull name, double default_value)
bool has_resource_image() const
Self & do_static_compilation(bool value)
Self & geometry_layout(PrimitiveIn prim_in, PrimitiveOut prim_out, int max_vertices, int invocations=-1)
Self & fragment_source(StringRefNull filename)
std::string fragment_source_generated
Self & depth_write(DepthWrite value)
Vector< std::array< StringRefNull, 2 > > defines_
Vector< CompilationConstant, 0 > compilation_constants_
GeneratedSourceList generated_sources
void validate_vertex_attributes(const ShaderCreateInfo *other_info=nullptr)
Self & metal_backend_only(bool flag)
Vector< Resource > & resources_get_(Frequency freq)
Self & vertex_in(int slot, Type type, StringRefNull name)
Self & builtins(BuiltinBits builtin)
std::string check_error() const
Vector< VertIn > vertex_inputs_
bool early_fragment_test_
bool auto_resource_location_
Self & auto_resource_location(bool value)
void finalize(const bool recursive=false)
Vector< Resource > batch_resources_
Self & push_constant(Type type, StringRefNull name, int array_size=0)
bool is_vulkan_compatible() const
StringRefNull geometry_entry_fn_
Self & geometry_out(StageInterfaceInfo &interface)
size_t interface_names_size_
Self & shared_variable(Type type, StringRefNull name)
Vector< StringRefNull, 0 > dependencies_generated
bool operator==(const ShaderCreateInfo &b) const
Self & vertex_function(StringRefNull function_name)
Vector< StringRefNull > additional_infos_
Self & additional_info(StringRefNull info_name)
Self & typedef_source(StringRefNull filename)
Self & fragment_out(int slot, Type type, StringRefNull name, DualBlend blend=DualBlend::NONE, int raster_order_group=-1)
StringRefNull geometry_source_
std::string vertex_source_generated
Self & vertex_out(StageInterfaceInfo &interface)
Vector< StageInterfaceInfo * > geometry_out_interfaces_
Self & storage_buf(int slot, Qualifier qualifiers, StringRefNull type_name, StringRefNull name, Frequency freq=Frequency::PASS)
Vector< Resource > pass_resources_
StringRefNull vertex_entry_fn_
std::string typedef_source_generated
bool has_resource_type(Resource::BindType bind_type) const
Self & shared_resource_descriptor(void(*fn)(ShaderCreateInfo &))
Vector< Resource > resources_get_all_() const
Self & vertex_source(StringRefNull filename)
GeometryStageLayout geometry_layout_
StringRefNull fragment_source_
Vector< SharedVariable, 0 > shared_variables_
Self & sampler(int slot, ImageType type, StringRefNull name, Frequency freq=Frequency::PASS, GPUSamplerState sampler=GPUSamplerState::internal_sampler())
bool do_static_compilation_
ComputeStageLayout compute_layout_
Self & compute_function(StringRefNull function_name)
Self & image(int slot, TextureFormat format, Qualifier qualifiers, ImageReadWriteType type, StringRefNull name, Frequency freq=Frequency::PASS)
Self & additional_info(StringRefNull info_name, Args... args)
Self & uniform_buf(int slot, StringRefNull type_name, StringRefNull name, Frequency freq=Frequency::PASS)
Self & subpass_in(int slot, Type type, ImageType img_type, StringRefNull name, int raster_order_group=-1)
std::string compute_source_generated
Self & specialization_constant(Type type, StringRefNull name, double default_value)
~ShaderCreateInfo()=default
Self & fragment_function(StringRefNull function_name)
friend std::ostream & operator<<(std::ostream &stream, const ShaderCreateInfo &info)
std::string geometry_source_generated
StringRefNull fragment_entry_fn_
Self & local_group_size(int local_size_x, int local_size_y=1, int local_size_z=1)
void validate_merge(const ShaderCreateInfo &other_info)
Self & early_fragment_test(bool enable)
Self & define(StringRefNull name, StringRefNull value="")
void resource_guard_defines(std::string &defines) const
Vector< SpecializationConstant > specialization_constants_
Vector< StringRefNull > typedef_sources_
Vector< PushConst > push_constants_
Vector< FragOut > fragment_outputs_
Self & smooth(Type type, StringRefNull _name)
StageInterfaceInfo(const char *name_, const char *instance_name_="")
~StageInterfaceInfo()=default
Self & no_perspective(Type type, StringRefNull _name)
StringRefNull instance_name
Self & flat(Type type, StringRefNull _name)
static int blend(const Tex *tex, const float texvec[3], TexResult *texres)