16#if !defined(GPU_SHADER)
29#define GPU_FORCE_ENABLE_SHADER_PRINTF 0
31#if !defined(NDEBUG) || GPU_FORCE_ENABLE_SHADER_PRINTF
32# define GPU_SHADER_PRINTF_ENABLE 1
34# define GPU_SHADER_PRINTF_ENABLE 0
36#define GPU_SHADER_PRINTF_SLOT 13
37#define GPU_SHADER_PRINTF_MAX_CAPACITY (1024 * 4)
40#define GPU_SSBO_INDEX_BUF_SLOT 7
42#define GPU_SSBO_POLYLINE_POS_BUF_SLOT 0
43#define GPU_SSBO_POLYLINE_COL_BUF_SLOT 1
45#if defined(GLSL_CPP_STUBS)
46# define GPU_SHADER_NAMED_INTERFACE_INFO(_interface, _inst_name) \
47 namespace interface::_interface { \
49# define GPU_SHADER_NAMED_INTERFACE_END(_inst_name) \
54# define GPU_SHADER_INTERFACE_INFO(_interface) namespace interface::_interface {
55# define GPU_SHADER_INTERFACE_END() }
57# define GPU_SHADER_CREATE_INFO(_info) \
59 namespace gl_VertexShader { \
61 namespace gl_FragmentShader { \
63 namespace gl_ComputeShader { \
65# define GPU_SHADER_CREATE_END() }
67# define SHADER_LIBRARY_CREATE_INFO(_info) using namespace _info;
68# define VERTEX_SHADER_CREATE_INFO(_info) \
69 using namespace ::gl_VertexShader; \
70 using namespace _info::gl_VertexShader; \
71 using namespace _info;
72# define FRAGMENT_SHADER_CREATE_INFO(_info) \
73 using namespace ::gl_FragmentShader; \
74 using namespace _info::gl_FragmentShader; \
75 using namespace _info;
76# define COMPUTE_SHADER_CREATE_INFO(_info) \
77 using namespace ::gl_ComputeShader; \
78 using namespace _info::gl_ComputeShader; \
79 using namespace _info;
81#elif !defined(GPU_SHADER_CREATE_INFO)
83# define GPU_SHADER_NAMED_INTERFACE_INFO(_interface, _inst_name) \
84 static inline void autocomplete_helper_interface_##_interface() \
86 StageInterfaceInfo _interface(#_interface, _inst_name); \
88# define GPU_SHADER_INTERFACE_INFO(_interface) \
89 static inline void autocomplete_helper_interface_##_interface() \
91 StageInterfaceInfo _interface(#_interface); \
93# define GPU_SHADER_CREATE_INFO(_info) \
94 static inline void autocomplete_helper_info_##_info() \
96 ShaderCreateInfo _info(#_info); \
99# define GPU_SHADER_NAMED_INTERFACE_END(_inst_name) \
102# define GPU_SHADER_INTERFACE_END() \
105# define GPU_SHADER_CREATE_END() \
111#ifndef GLSL_CPP_STUBS
112# define SMOOTH(type, name) .smooth(Type::type##_t, #name)
113# define FLAT(type, name) .flat(Type::type##_t, #name)
114# define NO_PERSPECTIVE(type, name) .no_perspective(Type::type##_t, #name)
117# define LOCAL_GROUP_SIZE(...) .local_group_size(__VA_ARGS__)
119# define VERTEX_IN(slot, type, name) .vertex_in(slot, Type::type##_t, #name)
120# define VERTEX_OUT(stage_interface) .vertex_out(stage_interface)
122# define GEOMETRY_LAYOUT(...) .geometry_layout(__VA_ARGS__)
123# define GEOMETRY_OUT(stage_interface) .geometry_out(stage_interface)
125# define SUBPASS_IN(slot, type, img_type, name, rog) \
126 .subpass_in(slot, Type::type##_t, ImageType::img_type, #name, rog)
128# define FRAGMENT_OUT(slot, type, name) .fragment_out(slot, Type::type##_t, #name)
129# define FRAGMENT_OUT_DUAL(slot, type, name, blend) \
130 .fragment_out(slot, Type::type##_t, #name, DualBlend::blend)
131# define FRAGMENT_OUT_ROG(slot, type, name, rog) \
132 .fragment_out(slot, Type::type##_t, #name, DualBlend::NONE, rog)
134# define EARLY_FRAGMENT_TEST(enable) .early_fragment_test(enable)
135# define DEPTH_WRITE(value) .depth_write(value)
137# define SPECIALIZATION_CONSTANT(type, name, default_value) \
138 .specialization_constant(Type::type##_t, #name, default_value)
140# define COMPILATION_CONSTANT(type, name, value) \
141 .compilation_constant(Type::type##_t, #name, value)
143# define PUSH_CONSTANT(type, name) .push_constant(Type::type##_t, #name)
144# define PUSH_CONSTANT_ARRAY(type, name, array_size) \
145 .push_constant(Type::type##_t, #name, array_size)
147# define UNIFORM_BUF(slot, type_name, name) .uniform_buf(slot, #type_name, #name)
148# define UNIFORM_BUF_FREQ(slot, type_name, name, freq) \
149 .uniform_buf(slot, #type_name, #name, Frequency::freq)
151# define STORAGE_BUF(slot, qualifiers, type_name, name) \
152 .storage_buf(slot, Qualifier::qualifiers, STRINGIFY(type_name), #name)
153# define STORAGE_BUF_FREQ(slot, qualifiers, type_name, name, freq) \
154 .storage_buf(slot, Qualifier::qualifiers, STRINGIFY(type_name), #name, Frequency::freq)
156# define SAMPLER(slot, type, name) .sampler(slot, ImageType::type, #name)
157# define SAMPLER_FREQ(slot, type, name, freq) \
158 .sampler(slot, ImageType::type, #name, Frequency::freq)
160# define IMAGE(slot, format, qualifiers, type, name) \
161 .image(slot, format, Qualifier::qualifiers, ImageReadWriteType::type, #name)
162# define IMAGE_FREQ(slot, format, qualifiers, type, name, freq) \
163 .image(slot, format, Qualifier::qualifiers, ImageReadWriteType::type, #name, Frequency::freq)
165# define BUILTINS(builtin) .builtins(builtin)
167# define VERTEX_SOURCE(filename) .vertex_source(filename)
168# define FRAGMENT_SOURCE(filename) .fragment_source(filename)
169# define COMPUTE_SOURCE(filename) .compute_source(filename)
171# define DEFINE(name) .define(name)
172# define DEFINE_VALUE(name, value) .define(name, value)
174# define DO_STATIC_COMPILATION() .do_static_compilation(true)
175# define AUTO_RESOURCE_LOCATION() .auto_resource_location(true)
178# define METAL_BACKEND_ONLY() .metal_backend_only(true)
180# define ADDITIONAL_INFO(info_name) .additional_info(#info_name)
181# define TYPEDEF_SOURCE(filename) .typedef_source(filename)
183# define MTL_MAX_TOTAL_THREADS_PER_THREADGROUP(value) \
184 .mtl_max_total_threads_per_threadgroup(value)
192# define SMOOTH(type, name) type name = {};
193# define FLAT(type, name) type name = {};
194# define NO_PERSPECTIVE(type, name) type name = {};
197# define LOCAL_GROUP_SIZE(...)
199# define VERTEX_IN(slot, type, name) \
200 namespace gl_VertexShader { \
201 const type name = {}; \
203# define VERTEX_OUT(stage_interface) using namespace interface::stage_interface;
205# define GEOMETRY_LAYOUT(...)
206# define GEOMETRY_OUT(stage_interface) using namespace interface::stage_interface;
208# define SUBPASS_IN(slot, type, img_type, name, rog) const type name = {};
210# define FRAGMENT_OUT(slot, type, name) \
211 namespace gl_FragmentShader { \
214# define FRAGMENT_OUT_DUAL(slot, type, name, blend) \
215 namespace gl_FragmentShader { \
218# define FRAGMENT_OUT_ROG(slot, type, name, rog) \
219 namespace gl_FragmentShader { \
223# define EARLY_FRAGMENT_TEST(enable)
224# define DEPTH_WRITE(value)
226# define SPECIALIZATION_CONSTANT(type, name, default_value) \
227 constexpr type name = type(default_value);
229# define COMPILATION_CONSTANT(type, name, value) constexpr type name = type(value);
231# define PUSH_CONSTANT(type, name) extern const type name;
232# define PUSH_CONSTANT_ARRAY(type, name, array_size) extern const type name[array_size];
234# define UNIFORM_BUF(slot, type_name, name) extern const type_name name;
235# define UNIFORM_BUF_FREQ(slot, type_name, name, freq) extern const type_name name;
237# define STORAGE_BUF(slot, qualifiers, type_name, name) extern _##qualifiers type_name name;
238# define STORAGE_BUF_FREQ(slot, qualifiers, type_name, name, freq) \
239 extern _##qualifiers type_name name;
241# define SAMPLER(slot, type, name) type name;
242# define SAMPLER_FREQ(slot, type, name, freq) type name;
244# define IMAGE(slot, format, qualifiers, type, name) _##qualifiers type name;
245# define IMAGE_FREQ(slot, format, qualifiers, type, name, freq) _##qualifiers type name;
247# define BUILTINS(builtin)
249# define VERTEX_SOURCE(filename)
250# define GEOMETRY_SOURCE(filename)
251# define FRAGMENT_SOURCE(filename)
252# define COMPUTE_SOURCE(filename)
255# define DEFINE_VALUE(name, value)
257# define DO_STATIC_COMPILATION()
258# define AUTO_RESOURCE_LOCATION()
261# define METAL_BACKEND_ONLY()
263# define ADDITIONAL_INFO(info_name) \
264 using namespace info_name; \
265 using namespace info_name::gl_FragmentShader; \
266 using namespace info_name::gl_VertexShader;
268# define TYPEDEF_SOURCE(filename)
270# define MTL_MAX_TOTAL_THREADS_PER_THREADGROUP(value)
273#define _INFO_EXPAND2(a, b) ADDITIONAL_INFO(a) ADDITIONAL_INFO(b)
274#define _INFO_EXPAND3(a, b, c) _INFO_EXPAND2(a, b) ADDITIONAL_INFO(c)
275#define _INFO_EXPAND4(a, b, c, d) _INFO_EXPAND3(a, b, c) ADDITIONAL_INFO(d)
276#define _INFO_EXPAND5(a, b, c, d, e) _INFO_EXPAND4(a, b, c, d) ADDITIONAL_INFO(e)
277#define _INFO_EXPAND6(a, b, c, d, e, f) _INFO_EXPAND5(a, b, c, d, e) ADDITIONAL_INFO(f)
279#define ADDITIONAL_INFO_EXPAND(...) VA_NARGS_CALL_OVERLOAD(_INFO_EXPAND, __VA_ARGS__)
281#define CREATE_INFO_VARIANT(name, ...) \
282 GPU_SHADER_CREATE_INFO(name) \
283 DO_STATIC_COMPILATION() \
284 ADDITIONAL_INFO_EXPAND(__VA_ARGS__) \
285 GPU_SHADER_CREATE_END()
287#if !defined(GLSL_CPP_STUBS)
308 BLI_assert_msg(0,
"Error: Cannot convert eGPUType to shader::Type.");
317 return stream <<
"float";
319 return stream <<
"vec2";
321 return stream <<
"vec3";
323 return stream <<
"vec4";
325 return stream <<
"mat3";
327 return stream <<
"mat4";
329 return stream <<
"vec3_1010102_Inorm";
331 return stream <<
"uchar";
333 return stream <<
"uchar2";
335 return stream <<
"uchar3";
337 return stream <<
"uchar4";
339 return stream <<
"char";
341 return stream <<
"char2";
343 return stream <<
"char3";
345 return stream <<
"char4";
347 return stream <<
"int";
349 return stream <<
"ivec2";
351 return stream <<
"ivec3";
353 return stream <<
"ivec4";
355 return stream <<
"uint";
357 return stream <<
"uvec2";
359 return stream <<
"uvec3";
361 return stream <<
"uvec4";
363 return stream <<
"ushort";
365 return stream <<
"ushort2";
367 return stream <<
"ushort3";
369 return stream <<
"ushort4";
371 return stream <<
"short";
373 return stream <<
"short2";
375 return stream <<
"short3";
377 return stream <<
"short4";
379 return stream <<
"bool";
390 return stream <<
"Closure";
392 return stream <<
to_type(type);
455# define TYPES_EXPAND(s) \
456 Float##s, Uint##s, Int##s, sampler##s = Float##s, usampler##s = Uint##s, isampler##s = Int##s
468# define TYPES_EXPAND(s) \
469 Shadow##s, Depth##s, sampler##s##Shadow = Shadow##s, sampler##s##Depth = Depth##s
477# define TYPES_EXPAND(s) \
478 AtomicUint##s, AtomicInt##s, usampler##s##Atomic = AtomicUint##s, \
479 isampler##s##Atomic = AtomicInt##s
497# define TYPES_EXPAND(s) \
498 Float##s = int(ImageType::Float##s), Uint##s = int(ImageType::Uint##s), \
499 Int##s = int(ImageType::Int##s), image##s = Float##s, uimage##s = Uint##s, iimage##s = Int##s
508# define TYPES_EXPAND(s) \
509 AtomicUint##s = int(ImageType::AtomicUint##s), AtomicInt##s = int(ImageType::AtomicInt##s), \
510 uimage##s##Atomic = AtomicUint##s, iimage##s##Atomic = AtomicInt##s
602 return *(
Self *)
this;
608 return *(
Self *)
this;
614 return *(
Self *)
this;
658# define TEST_EQUAL(a, b, _member) \
659 if (!((a)._member == (b)._member)) { \
663# define TEST_VECTOR_EQUAL(a, b, _vector) \
664 TEST_EQUAL(a, b, _vector.size()); \
665 for (auto i : _vector.index_range()) { \
666 TEST_EQUAL(a, b, _vector[i]); \
862 return all_resources;
897# ifdef WITH_METAL_BACKEND
898 ushort mtl_max_threads_per_threadgroup_ = 0;
915 return *(
Self *)
this;
921 return *(
Self *)
this;
927 int invocations = -1)
933 return *(
Self *)
this;
941 return *(
Self *)
this;
951 return *(
Self *)
this;
963 return *(
Self *)
this;
970 int raster_order_group = -1)
973 return *(
Self *)
this;
993 subpass_inputs_.append({slot, type, img_type, name, raster_order_group});
994 return *(
Self *)
this;
1010 constant.
type = type;
1011 constant.
name = name;
1014 constant.
value.
i = int(default_value);
1021 BLI_assert_msg(0,
"Only scalar integer and bool types can be used as constants");
1026 return *(
Self *)
this;
1060 constant.
type = type;
1061 constant.
name = name;
1064 constant.
value.
i = int(default_value);
1071 constant.
value.
f = float(default_value);
1079 return *(
Self *)
this;
1102 return *(
Self *)
this;
1117 return *(
Self *)
this;
1134 return *(
Self *)
this;
1151 return *(
Self *)
this;
1163 return *(
Self *)
this;
1169 return *(
Self *)
this;
1175 return *(
Self *)
this;
1191 "Array syntax is forbidden for push constants."
1192 "Use the array_size parameter instead.");
1195 return *(
Self *)
this;
1207 return *(
Self *)
this;
1219 return *(
Self *)
this;
1225 return *(
Self *)
this;
1232 return *(
Self *)
this;
1238 return *(
Self *)
this;
1244 return *(
Self *)
this;
1258 return *(
Self *)
this;
1265 return *(
Self *)
this;
1281 return *(
Self *)
this;
1299# ifdef WITH_METAL_BACKEND
1300 mtl_max_threads_per_threadgroup_ = max_total_threads_per_threadgroup;
1304 return *(
Self *)
this;
1319 void finalize(
const bool recursive =
false);
1371 switch (res.bind_type) {
1373 stream <<
"UNIFORM_BUFFER(" << res.slot <<
", " << res.uniformbuf.name <<
")"
1377 stream <<
"STORAGE_BUFFER(" << res.slot <<
", " << res.storagebuf.name <<
")"
1381 stream <<
"SAMPLER(" << res.slot <<
", " << res.sampler.name <<
")" << std::endl;
1384 stream <<
"IMAGE(" << res.slot <<
", " << res.image.name <<
")" << std::endl;
1405 if (res.bind_type == bind_type) {
1410 if (res.bind_type == bind_type) {
1415 if (res.bind_type == bind_type) {
1430# 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 int64_t find(char c, int64_t pos=0) const
constexpr int64_t size() const
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)
static std::ostream & operator<<(std::ostream &stream, const Type type)
static Type to_type(const eGPUType 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
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
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)
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_
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)
Self & image(int slot, eGPUTextureFormat format, Qualifier qualifiers, ImageReadWriteType type, StringRefNull name, Frequency freq=Frequency::PASS)
Vector< Resource > batch_resources_
Self & push_constant(Type type, StringRefNull name, int array_size=0)
bool is_vulkan_compatible() const
Self & geometry_out(StageInterfaceInfo &interface)
size_t interface_names_size_
Vector< StringRefNull, 0 > dependencies_generated
bool operator==(const ShaderCreateInfo &b) const
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_
std::string typedef_source_generated
bool has_resource_type(Resource::BindType bind_type) const
Vector< Resource > resources_get_all_() const
Self & vertex_source(StringRefNull filename)
GeometryStageLayout geometry_layout_
StringRefNull fragment_source_
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 & 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
friend std::ostream & operator<<(std::ostream &stream, const ShaderCreateInfo &info)
std::string geometry_source_generated
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="")
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)