36 for (
const auto &def : info.
defines_) {
37 defines +=
"#define ";
71 sources.
append(
"/* specialization_constants */");
73 sources.
append(
"#define GPU_SHADER\n");
76 sources.
append(
"#define GPU_ATI\n");
79 sources.
append(
"#define GPU_NVIDIA\n");
82 sources.
append(
"#define GPU_INTEL\n");
85 sources.
append(
"#define GPU_APPLE\n");
89 sources.
append(
"#define OS_WIN\n");
92 sources.
append(
"#define OS_MAC\n");
95 sources.
append(
"#define OS_UNIX\n");
101 sources.
append(
"#define GPU_OPENGL\n");
104 sources.
append(
"#define GPU_METAL\n");
107 sources.
append(
"#define GPU_VULKAN\n");
115 sources.
append(
"#define GPU_DEPRECATED_AMD_DRIVER\n");
120 const char *fragcode,
121 const char *geomcode,
122 const char *computecode,
126 const char **tf_names,
131 BLI_assert(((fragcode !=
nullptr) && (vertcode !=
nullptr) && (computecode ==
nullptr)) ||
132 ((fragcode ==
nullptr) && (vertcode ==
nullptr) && (geomcode ==
nullptr) &&
133 (computecode !=
nullptr)));
140 sources.
append(
"#define GPU_VERTEX_SHADER\n");
141 sources.
append(
"#define IN_OUT out\n");
143 sources.
append(
"#define USE_GEOMETRY_SHADER\n");
150 shader->vertex_shader_from_glsl(sources);
156 sources.
append(
"#define GPU_FRAGMENT_SHADER\n");
157 sources.
append(
"#define IN_OUT in\n");
159 sources.
append(
"#define USE_GEOMETRY_SHADER\n");
169 shader->fragment_shader_from_glsl(sources);
175 sources.
append(
"#define GPU_GEOMETRY_SHADER\n");
181 shader->geometry_shader_from_glsl(sources);
187 sources.
append(
"#define GPU_COMPUTE_SHADER\n");
194 sources.
append(computecode);
196 shader->compute_shader_from_glsl(sources);
199 if (tf_names !=
nullptr && tf_count > 0) {
201 shader->transform_feedback_names_set(
Span<const char *>(tf_names, tf_count), tf_type);
204 if (!shader->finalize()) {
224 const char *fragcode,
225 const char *geomcode,
265 GPUShaderCreateInfo &r_info)
275 if (
error.length() == 0) {
289 std::cerr <<
"Warning: Trying to compile \"" << info.
name_.
c_str()
290 <<
"\" which was not marked for static compilation.\n";
303 const char *fragcode,
304 const char *geomcode,
309 char *libcodecat =
nullptr;
311 if (libcode ==
nullptr) {
319 const char *shname = name !=
nullptr ? name :
"pyGPUShader";
357 printf(
"Compiling all static GPU shaders. This process takes a while.\n");
378 if (ctx->
shader != shader) {
382 Shader::set_srgb_uniform(gpu_shader);
383 shader->constants.is_dirty =
false;
386 if (shader->constants.is_dirty) {
388 shader->constants.is_dirty =
false;
390 if (Shader::srgb_uniform_dirty_get()) {
391 Shader::set_srgb_uniform(gpu_shader);
397#if GPU_SHADER_PRINTF_ENABLE
432 return unwrap(shader)->name_get();
445 if (shader != parent) {
454 unwrap(shader)->warm_cache(limit);
467 return unwrap(shader)->transform_feedback_enable(vertbuf);
472 unwrap(shader)->transform_feedback_disable();
483 using namespace shader;
485 constants.types.append(sc.type);
486 constants.values.append(sc.value);
488 constants.is_dirty =
true;
495 shader.constants.is_dirty |=
assign_if_different(shader.constants.values[location].i, value);
501 shader.constants.is_dirty |=
assign_if_different(shader.constants.values[location].u, value);
507 shader.constants.is_dirty |=
assign_if_different(shader.constants.values[location].f, value);
554 const ShaderInput *uniform = interface->uniform_get(name);
555 return uniform ? uniform->
location : -1;
561 const ShaderInput *constant = interface->constant_get(name);
562 return constant ? constant->
location : -1;
580 const ShaderInput *ssbo = interface->ssbo_get(name);
595 return ubo ? ubo->
binding : -1;
602 return tex ?
tex->binding : -1;
614 const ShaderInput *attr = interface->attr_get(name);
625 const ShaderInput *attr = interface->attr_get(attr_location);
630 BLI_strncpy(r_name, interface->input_name_get(attr), 256);
631 *r_type = attr->location != -1 ? interface->attr_types_[attr->location] : -1;
643 return unwrap(shader)->program_handle_get();
648 return unwrap(shader)->get_ssbo_vertex_fetch_output_num_verts();
653 return unwrap(shader)->get_uses_ssbo_vertex_fetch();
663 GPUShader *shader,
int loc,
int len,
int array_size,
const float *value)
665 unwrap(shader)->uniform_float(loc,
len, array_size, value);
669 GPUShader *shader,
int loc,
int len,
int array_size,
const int *value)
671 unwrap(shader)->uniform_int(loc,
len, array_size, value);
687 const float data[2] = {
x, y};
693 const float data[3] = {
x,
y,
z};
699 const float data[4] = {
x,
y,
z,
w};
782bool Shader::srgb_uniform_dirty_get()
796void Shader::set_framebuffer_srgb_target(
int use_srgb_to_linear)
818 if (!
error.empty()) {
819 std::cerr <<
error.c_str() <<
"\n";
824 shader->
init(info, is_batch_compilation);
825 shader->specialization_constants_init(info);
827 std::string defines = shader->defines_declare(info);
828 std::string resources = shader->resources_declare(info);
831 defines +=
"#define USE_GPU_SHADER_CREATE_INFO\n";
836 typedefs.
append(gpu_shader_dependency_get_source(
"GPU_shader_shared_utils.hh").c_str());
842 typedefs.
append(gpu_shader_dependency_get_source(filename).
c_str());
846 auto code = gpu_shader_dependency_get_resolved_source(info.
vertex_source_);
847 std::string
interface = shader->vertex_interface_declare(info);
851 sources.append(
"#define GPU_VERTEX_SHADER\n");
852 if (!info.geometry_source_.is_empty()) {
853 sources.append(
"#define USE_GEOMETRY_SHADER\n");
855 sources.append(defines.c_str());
856 sources.extend(typedefs);
857 sources.append(resources.c_str());
858 sources.append(interface.c_str());
859 sources.extend(code);
860 sources.extend(info.dependencies_generated);
861 sources.append(info.vertex_source_generated.c_str());
863 shader->vertex_shader_from_glsl(sources);
867 auto code = gpu_shader_dependency_get_resolved_source(info.
fragment_source_);
868 std::string
interface = shader->fragment_interface_declare(info);
872 sources.append(
"#define GPU_FRAGMENT_SHADER\n");
873 if (!info.geometry_source_.is_empty()) {
874 sources.append(
"#define USE_GEOMETRY_SHADER\n");
876 sources.append(defines.c_str());
877 sources.extend(typedefs);
878 sources.append(resources.c_str());
879 sources.append(interface.c_str());
880 sources.extend(code);
881 sources.extend(info.dependencies_generated);
882 sources.append(info.fragment_source_generated.c_str());
884 shader->fragment_shader_from_glsl(sources);
888 auto code = gpu_shader_dependency_get_resolved_source(info.
geometry_source_);
889 std::string layout = shader->geometry_layout_declare(info);
890 std::string
interface = shader->geometry_interface_declare(info);
894 sources.append(
"#define GPU_GEOMETRY_SHADER\n");
895 sources.append(defines.c_str());
896 sources.extend(typedefs);
897 sources.append(resources.c_str());
898 sources.append(layout.c_str());
899 sources.append(interface.c_str());
900 sources.append(info.geometry_source_generated.c_str());
901 sources.extend(code);
903 shader->geometry_shader_from_glsl(sources);
907 auto code = gpu_shader_dependency_get_resolved_source(info.
compute_source_);
908 std::string layout = shader->compute_layout_declare(info);
912 sources.
append(
"#define GPU_COMPUTE_SHADER\n");
913 sources.
append(defines.c_str());
915 sources.
append(resources.c_str());
916 sources.
append(layout.c_str());
921 shader->compute_shader_from_glsl(sources);
928 if (!shader->finalize(&info)) {
953 batches.add(handle, {{}, infos,
true});
954 Batch &
batch = batches.lookup(handle);
957 batch.shaders.append(compile(*info,
true));
964 bool is_ready = batches.lookup(handle).is_ready;
#define BLI_assert_msg(a, msg)
void copy_m4_m3(float m1[4][4], const float m2[3][3])
char * BLI_strdupcat(const char *__restrict str1, const char *__restrict str2) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1
#define STRNCPY(dst, src)
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
bool GPU_crappy_amd_driver()
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)
void GPU_shader_constant_int(GPUShader *sh, const char *name, int value)
GPUShader * GPU_shader_create(const char *vertcode, const char *fragcode, const char *geomcode, const char *libcode, const char *defines, const char *shname)
void GPU_shader_uniform_2fv(GPUShader *sh, const char *name, const float data[2])
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)
blender::Vector< GPUShader * > GPU_shader_batch_finalize(BatchHandle &handle)
void GPU_shader_uniform_2f(GPUShader *sh, const char *name, float x, float y)
void GPU_shader_uniform_2fv_array(GPUShader *sh, const char *name, int len, const float(*val)[2])
void GPU_shader_uniform_int_ex(GPUShader *shader, int location, int length, int array_size, const int *value)
SpecializationBatchHandle GPU_shader_batch_specializations(blender::Span< ShaderSpecialization > specializations)
GPUShader * GPU_shader_create_from_info_name(const char *info_name)
int GPU_shader_get_ssbo_vertex_fetch_num_verts_per_prim(GPUShader *shader)
bool GPU_shader_uses_ssbo_vertex_fetch(GPUShader *shader)
void GPU_shader_cache_dir_clear_old()
void GPU_shader_uniform_1f(GPUShader *sh, const char *name, float value)
GPUShader * GPU_shader_create_from_python(const char *vertcode, const char *fragcode, const char *geomcode, const char *libcode, const char *defines, const char *name)
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_constant_uint(GPUShader *sh, const char *name, unsigned int value)
void GPU_shader_uniform_1f_array(GPUShader *sh, const char *name, int len, const float *val)
int GPU_shader_get_ssbo_binding(GPUShader *shader, const char *name)
unsigned int GPU_shader_get_attribute_len(const GPUShader *shader)
int GPU_shader_get_attribute(const GPUShader *shader, const char *name)
bool GPU_shader_transform_feedback_enable(GPUShader *shader, blender::gpu::VertBuf *vertbuf)
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])
void GPU_shader_constant_bool_ex(GPUShader *sh, int location, bool value)
void GPU_shader_constant_int_ex(GPUShader *sh, int location, int value)
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)
const GPUShaderCreateInfo * GPU_shader_create_info_get(const char *info_name)
void GPU_shader_transform_feedback_disable(GPUShader *shader)
int GPU_shader_get_program(GPUShader *shader)
void GPU_shader_bind(GPUShader *shader)
void GPU_shader_constant_float_ex(GPUShader *sh, int location, float value)
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)
void GPU_shader_constant_uint_ex(GPUShader *sh, int location, unsigned int value)
int GPU_shader_get_uniform_block(GPUShader *shader, const char *name)
int64_t SpecializationBatchHandle
BatchHandle GPU_shader_batch_create_from_infos(blender::Span< const GPUShaderCreateInfo * > infos)
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)
void GPU_shader_constant_bool(GPUShader *sh, const char *name, bool value)
int GPU_shader_get_builtin_uniform(GPUShader *shader, int builtin)
void GPU_shader_free(GPUShader *shader)
GPUShader * GPU_shader_create_compute(const char *computecode, const char *libcode, const char *defines, const char *shname)
bool GPU_shader_create_info_check_error(const GPUShaderCreateInfo *_info, char r_error[128])
void GPU_shader_create_info_get_unfinalized_copy(const char *info_name, GPUShaderCreateInfo &r_info)
GPUShader * GPU_shader_create_ex(const char *vertcode, const char *fragcode, const char *geomcode, const char *computecode, const char *libcode, const char *defines, eGPUShaderTFBType tf_type, const char **tf_names, int tf_count, const char *shname)
GPUShader * GPU_shader_get_bound()
void GPU_shader_warm_cache(GPUShader *shader, int limit)
bool GPU_shader_batch_specializations_is_ready(SpecializationBatchHandle &handle)
void GPU_shader_constant_float(GPUShader *sh, const char *name, float value)
void GPU_shader_compile_static()
void GPU_storagebuf_bind(GPUStorageBuf *ssbo, int slot)
Read Guarded memory(de)allocation.
struct GPUShader GPUShader
SIMD_FORCE_INLINE const btScalar & z() const
Return the z value.
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
constexpr int64_t size() const
constexpr bool is_empty() const
constexpr const char * c_str() const
void append(const T &value)
void extend(Span< T > array)
Span< T > as_span() const
GPUStorageBuf * printf_buf
ShaderCompiler * compiler
static GPUBackend * get()
virtual void shader_cache_dir_clear_old()=0
virtual Shader * shader_alloc(const char *name)=0
virtual bool batch_is_ready(BatchHandle handle) override
virtual BatchHandle batch_compile(Span< const shader::ShaderCreateInfo * > &infos) override
virtual ~ShaderCompilerGeneric() override
virtual Vector< Shader * > batch_finalize(BatchHandle &handle) override
Shader * compile(const shader::ShaderCreateInfo &info, bool is_batch_compilation)
virtual Vector< Shader * > batch_finalize(BatchHandle &handle)=0
virtual bool specialization_batch_is_ready(SpecializationBatchHandle &handle)
virtual bool batch_is_ready(BatchHandle handle)=0
virtual BatchHandle batch_compile(Span< const shader::ShaderCreateInfo * > &infos)=0
virtual SpecializationBatchHandle precompile_specializations(Span< ShaderSpecialization >)
int32_t uniform_builtin(const GPUUniformBuiltin builtin) const
int32_t ubo_builtin(const GPUUniformBlockBuiltin builtin) const
std::string defines_declare(const shader::ShaderCreateInfo &info) const
virtual void init(const shader::ShaderCreateInfo &info, bool is_batch_compilation)=0
void parent_set(Shader *parent)
static void standard_defines(Vector< const char * > &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)
void gpu_shader_create_info_get_unfinalized_copy(const char *info_name, GPUShaderCreateInfo &r_info)
#define GPU_SHADER_PRINTF_SLOT
static void error(const char *str)
static Context * unwrap(GPUContext *ctx)
static int g_shader_builtin_srgb_transform
static GPUContext * wrap(Context *ctx)
static bool g_shader_builtin_srgb_is_dirty
bool assign_if_different(T &old_value, T new_value)
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_
Vector< const char * > tf_names_
std::string check_error() const
StringRefNull geometry_source_
std::string typedef_source_generated
Vector< const char *, 0 > dependencies_generated
bool legacy_resource_location_
StringRefNull fragment_source_
bool do_static_compilation_
std::string compute_source_generated
eGPUShaderTFBType tf_type_
Vector< SpecializationConstant > specialization_constants_
Vector< StringRefNull > typedef_sources_