Blender V4.3
gpu_shader_private.hh
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#pragma once
10
11#include "BLI_span.hh"
12#include "BLI_string_ref.hh"
13
14#include "GPU_shader.hh"
17
18#include "BLI_map.hh"
19
20#include <mutex>
21#include <string>
22
23namespace blender {
24namespace gpu {
25
26class GPULogParser;
27class Context;
28
29/* Set to 1 to log the full source of shaders that fail to compile. */
30#define DEBUG_LOG_SHADER_SRC_ON_ERROR 0
31
37#define SOURCES_INDEX_VERSION 0
38#define SOURCES_INDEX_SPECIALIZATION_CONSTANTS 1
39
44class Shader {
45 public:
47 ShaderInterface *interface = nullptr;
48
53 struct Constants {
56 /* Current values set by `GPU_shader_constant_*()` call. The backend can choose to interpret
57 * that however it wants (i.e: bind another shader instead). */
59
67
68 protected:
70 char name[64];
71
72 /* Parent shader can be used for shaders which are derived from the same source material.
73 * The child shader can pull information from its parent to prepare additional resources
74 * such as PSOs upfront. This enables asynchronous PSO compilation which mitigates stuttering
75 * when updating new materials. */
77
78 public:
79 Shader(const char *name);
80 virtual ~Shader();
81
82 /* `is_batch_compilation` is true when the shader is being compiled as part of a
83 * `GPU_shader_batch`. Backends that use the `ShaderCompilerGeneric` can ignore it. */
84 virtual void init(const shader::ShaderCreateInfo &info, bool is_batch_compilation) = 0;
85
90 virtual bool finalize(const shader::ShaderCreateInfo *info = nullptr) = 0;
91 /* Pre-warms PSOs using parent shader's cached PSO descriptors. Limit specifies maximum PSOs to
92 * warm. If -1, compiles all PSO permutations in parent shader.
93 *
94 * See `GPU_shader_warm_cache(..)` in `GPU_shader.hh` for more information. */
95 virtual void warm_cache(int limit) = 0;
96
98 eGPUShaderTFBType geom_type) = 0;
100 virtual void transform_feedback_disable() = 0;
101
102 virtual void bind() = 0;
103 virtual void unbind() = 0;
104
105 virtual void uniform_float(int location, int comp_len, int array_size, const float *data) = 0;
106 virtual void uniform_int(int location, int comp_len, int array_size, const int *data) = 0;
107
108 /* Add specialization constant declarations to shader instance. */
110
111 std::string defines_declare(const shader::ShaderCreateInfo &info) const;
112 virtual std::string resources_declare(const shader::ShaderCreateInfo &info) const = 0;
113 virtual std::string vertex_interface_declare(const shader::ShaderCreateInfo &info) const = 0;
114 virtual std::string fragment_interface_declare(const shader::ShaderCreateInfo &info) const = 0;
115 virtual std::string geometry_interface_declare(const shader::ShaderCreateInfo &info) const = 0;
116 virtual std::string geometry_layout_declare(const shader::ShaderCreateInfo &info) const = 0;
117 virtual std::string compute_layout_declare(const shader::ShaderCreateInfo &info) const = 0;
118
119 /* DEPRECATED: Kept only because of BGL API. */
120 virtual int program_handle_get() const = 0;
121
122 /* Only used by SSBO Vertex fetch. */
123 virtual bool get_uses_ssbo_vertex_fetch() const = 0;
125
126 inline const char *const name_get() const
127 {
128 return name;
129 }
130
131 inline void parent_set(Shader *parent)
132 {
133 parent_shader_ = parent;
134 }
135
136 inline Shader *parent_get() const
137 {
138 return parent_shader_;
139 }
140
141 static bool srgb_uniform_dirty_get();
142 static void set_srgb_uniform(GPUShader *shader);
143 static void set_framebuffer_srgb_target(int use_srgb_to_linear);
144
145 protected:
146 void print_log(Span<const char *> sources,
147 const char *log,
148 const char *stage,
149 bool error,
150 GPULogParser *parser);
151};
152
153/* Syntactic sugar. */
154static inline GPUShader *wrap(Shader *vert)
155{
156 return reinterpret_cast<GPUShader *>(vert);
157}
158static inline Shader *unwrap(GPUShader *vert)
159{
160 return reinterpret_cast<Shader *>(vert);
161}
162static inline const Shader *unwrap(const GPUShader *vert)
163{
164 return reinterpret_cast<const Shader *>(vert);
165}
166
168 protected:
169 struct Sources {
170 std::string vert;
171 std::string geom;
172 std::string frag;
173 std::string comp;
174 };
175
176 public:
177 virtual ~ShaderCompiler(){};
178
179 Shader *compile(const shader::ShaderCreateInfo &info, bool is_batch_compilation);
180
182 virtual bool batch_is_ready(BatchHandle handle) = 0;
184
186 Span<ShaderSpecialization> /*specializations*/)
187 {
188 /* No-op.*/
189 return 0;
190 };
191
193 {
194 handle = 0;
195 return true;
196 };
197};
198
199/* Generic (fully synchronous) implementation for backends that don't implement their own
200 * ShaderCompiler. Used by Vulkan and Metal. */
202 private:
203 struct Batch {
204 Vector<Shader *> shaders;
206 bool is_ready = false;
207 };
208 BatchHandle next_batch_handle = 1;
210
211 public:
212 virtual ~ShaderCompilerGeneric() override;
213
215 virtual bool batch_is_ready(BatchHandle handle) override;
216 virtual Vector<Shader *> batch_finalize(BatchHandle &handle) override;
217};
218
219enum class Severity {
220 Unknown,
221 Warning,
222 Error,
223 Note,
224};
225
226struct LogCursor {
227 int source = -1;
228 int row = -1;
229 int column = -1;
231};
232
238
240 public:
241 virtual const char *parse_line(const char *source_combined,
242 const char *log_line,
243 GPULogItem &log_item) = 0;
244
245 protected:
246 const char *skip_severity(const char *log_line,
247 GPULogItem &log_item,
248 const char *error_msg,
249 const char *warning_msg,
250 const char *note_msg) const;
251 const char *skip_separators(const char *log_line, const StringRef separators) const;
252 const char *skip_until(const char *log_line, char stop_char) const;
253 bool at_number(const char *log_line) const;
254 bool at_any(const char *log_line, const StringRef chars) const;
255 int parse_number(const char *log_line, const char **r_new_position) const;
256
258};
259
260void printf_begin(Context *ctx);
261void printf_end(Context *ctx);
262
263} // namespace gpu
264} // namespace blender
265
266/* XXX do not use it. Special hack to use OCIO with batch API. */
int64_t BatchHandle
Definition GPU_shader.hh:68
eGPUShaderTFBType
int64_t SpecializationBatchHandle
struct GPUShader GPUShader
int parse_number(const char *log_line, const char **r_new_position) const
const char * skip_separators(const char *log_line, const StringRef separators) const
bool at_number(const char *log_line) const
bool at_any(const char *log_line, const StringRef chars) const
virtual const char * parse_line(const char *source_combined, const char *log_line, GPULogItem &log_item)=0
const char * skip_until(const char *log_line, char stop_char) const
MEM_CXX_CLASS_ALLOC_FUNCS("GPULogParser")
const char * skip_severity(const char *log_line, GPULogItem &log_item, const char *error_msg, const char *warning_msg, const char *note_msg) const
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 >)
virtual void unbind()=0
virtual bool transform_feedback_enable(VertBuf *)=0
virtual std::string fragment_interface_declare(const shader::ShaderCreateInfo &info) const =0
virtual void transform_feedback_names_set(Span< const char * > name_list, eGPUShaderTFBType geom_type)=0
virtual void uniform_int(int location, int comp_len, int array_size, const int *data)=0
std::string defines_declare(const shader::ShaderCreateInfo &info) const
Definition gpu_shader.cc:33
virtual bool get_uses_ssbo_vertex_fetch() const =0
virtual void init(const shader::ShaderCreateInfo &info, bool is_batch_compilation)=0
virtual void fragment_shader_from_glsl(MutableSpan< const char * > sources)=0
virtual void transform_feedback_disable()=0
virtual std::string compute_layout_declare(const shader::ShaderCreateInfo &info) const =0
Shader * parent_get() const
virtual bool finalize(const shader::ShaderCreateInfo *info=nullptr)=0
virtual std::string resources_declare(const shader::ShaderCreateInfo &info) const =0
const char *const name_get() const
virtual std::string geometry_interface_declare(const shader::ShaderCreateInfo &info) const =0
virtual void vertex_shader_from_glsl(MutableSpan< const char * > sources)=0
void specialization_constants_init(const shader::ShaderCreateInfo &info)
virtual void warm_cache(int limit)=0
void parent_set(Shader *parent)
static bool srgb_uniform_dirty_get()
virtual void compute_shader_from_glsl(MutableSpan< const char * > sources)=0
struct blender::gpu::Shader::Constants constants
virtual std::string vertex_interface_declare(const shader::ShaderCreateInfo &info) const =0
void print_log(Span< const char * > sources, const char *log, const char *stage, bool error, GPULogParser *parser)
virtual void geometry_shader_from_glsl(MutableSpan< const char * > sources)=0
virtual int program_handle_get() const =0
virtual void uniform_float(int location, int comp_len, int array_size, const float *data)=0
static void set_framebuffer_srgb_target(int use_srgb_to_linear)
virtual void bind()=0
virtual std::string geometry_layout_declare(const shader::ShaderCreateInfo &info) const =0
Shader(const char *name)
Definition gpu_shader.cc:55
static void set_srgb_uniform(GPUShader *shader)
virtual int get_ssbo_vertex_fetch_output_num_verts() const =0
EvaluationStage stage
Definition deg_eval.cc:83
GPUShader * immGetShader()
ccl_device_inline float3 log(float3 v)
static void error(const char *str)
static Context * unwrap(GPUContext *ctx)
static GPUContext * wrap(Context *ctx)
void printf_begin(Context *ctx)
void printf_end(Context *ctx)
Vector< gpu::shader::Type > types
Describe inputs & outputs, stage interfaces, resources and sources of a shader. If all data is correc...