Blender V5.0
ocio_color_space_conversion_shader.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include <cstdint>
6#include <memory>
7#include <string>
8
9#include "BLI_assert.h"
10#include "BLI_hash.hh"
11#include "BLI_map.hh"
12#include "BLI_string_ref.hh"
13#include "BLI_vector.hh"
14#include "BLI_vector_set.hh"
15
16#include "GPU_capabilities.hh"
17#include "GPU_shader.hh"
18#include "GPU_texture.hh"
19#include "GPU_uniform_buffer.hh"
20
22
23#include "COM_context.hh"
25#include "COM_result.hh"
26
28
29#include "CLG_log.h"
30
31#if defined(WITH_OPENCOLORIO)
32# include <OpenColorIO/OpenColorIO.h>
33#endif
34
35namespace blender::compositor {
36
37static CLG_LogRef LOG = {"compositor.gpu"};
38
39/* --------------------------------------------------------------------
40 * GPU Shader Creator.
41 */
42
43#if defined(WITH_OPENCOLORIO)
44
45namespace OCIO = OCIO_NAMESPACE;
46using namespace blender::gpu::shader;
47
48/* A subclass of OCIO::GpuShaderCreator that constructs the shader using a ShaderCreateInfo. The
49 * Create method should be used to construct the creator, then the extractGpuShaderInfo() method of
50 * the appropriate OCIO::GPUProcessor should be called passing in the creator. After construction,
51 * the constructed compute shader can be used by calling the bind_shader_and_resources() method,
52 * followed by binding the input texture and output image using their names input_sampler_name()
53 * and output_image_name(), following by dispatching the shader on the domain of the input, and
54 * finally calling the unbind_shader_and_resources() method.
55 *
56 * Upon calling the extractGpuShaderInfo(), all the transforms in the GPU processor will add their
57 * needed resources by calling the respective addUniform() and add[3D]Texture() methods. Then, the
58 * shader code of all transforms will be generated and passed to the createShaderText() method,
59 * generating the full code of the processor. Finally, the finalize() method will be called to
60 * finally create the shader. */
61class GPUShaderCreator : public OCIO::GpuShaderCreator {
62 public:
63 static std::shared_ptr<GPUShaderCreator> Create(ResultPrecision precision)
64 {
65 std::shared_ptr<GPUShaderCreator> instance = std::make_shared<GPUShaderCreator>();
66 instance->setLanguage(OCIO::GPU_LANGUAGE_GLSL_4_0);
67 instance->precision_ = precision;
68 return instance;
69 }
70
71 /* Not used, but needs to be overridden, so return a nullptr. */
72 OCIO::GpuShaderCreatorRcPtr clone() const override
73 {
74 return OCIO::GpuShaderCreatorRcPtr();
75 }
76
77 /* This is ignored since we query using our own GPU capabilities system. */
78 void setTextureMaxWidth(uint /*max_width*/) override {}
79
80 uint getTextureMaxWidth() const noexcept override
81 {
82 return GPU_max_texture_size();
83 }
84
85# if OCIO_VERSION_HEX >= 0x02030000
86 void setAllowTexture1D(bool allowed) override
87 {
88 allow_texture_1D_ = allowed;
89 }
90
91 bool getAllowTexture1D() const override
92 {
93 return allow_texture_1D_;
94 }
95# endif
96
97 bool addUniform(const char *name, const DoubleGetter &get_double) override
98 {
99 /* Check if a resource exists with the same name and assert if it is the case, returning false
100 * indicates failure to add the uniform for the shader creator. */
101 if (!resource_names_.add(std::make_unique<std::string>(name))) {
103 return false;
104 }
105
106 /* Don't use the name argument directly since ShaderCreateInfo only stores references to
107 * resource names, instead, use the name that is stored in resource_names_. */
108 std::string &resource_name = *resource_names_[resource_names_.size() - 1];
109 shader_create_info_.push_constant(Type::float_t, resource_name);
110
111 float_uniforms_.add(resource_name, get_double);
112
113 return true;
114 }
115
116 bool addUniform(const char *name, const BoolGetter &get_bool) override
117 {
118 /* Check if a resource exists with the same name and assert if it is the case, returning false
119 * indicates failure to add the uniform for the shader creator. */
120 if (!resource_names_.add(std::make_unique<std::string>(name))) {
122 return false;
123 }
124
125 /* Don't use the name argument directly since ShaderCreateInfo only stores references to
126 * resource names, instead, use the name that is stored in resource_names_. */
127 const std::string &resource_name = *resource_names_[resource_names_.size() - 1];
128 shader_create_info_.push_constant(Type::bool_t, resource_name);
129
130 boolean_uniforms_.add(name, get_bool);
131
132 return true;
133 }
134
135 bool addUniform(const char *name, const Float3Getter &get_float3) override
136 {
137 /* Check if a resource exists with the same name and assert if it is the case, returning false
138 * indicates failure to add the uniform for the shader creator. */
139 if (!resource_names_.add(std::make_unique<std::string>(name))) {
141 return false;
142 }
143
144 /* Don't use the name argument directly since ShaderCreateInfo only stores references to
145 * resource names, instead, use the name that is stored in resource_names_. */
146 std::string &resource_name = *resource_names_[resource_names_.size() - 1];
147 shader_create_info_.push_constant(Type::float3_t, resource_name);
148
149 vector_uniforms_.add(resource_name, get_float3);
150
151 return true;
152 }
153
154 bool addUniform(const char *name,
155 const SizeGetter &get_size,
156 const VectorFloatGetter &get_vector_float
157# if OCIO_VERSION_HEX >= 0x02050000
158 ,
159 const unsigned /*maxSize*/
160# endif
161 ) override
162 {
163 /* Check if a resource exists with the same name and assert if it is the case, returning false
164 * indicates failure to add the uniform for the shader creator. */
165 if (!resource_names_.add(std::make_unique<std::string>(name))) {
167 return false;
168 }
169
170 /* Don't use the name argument directly since ShaderCreateInfo only stores references to
171 * resource names, instead, use the name that is stored in resource_names_. */
172 std::string &resource_name = *resource_names_[resource_names_.size() - 1];
173 shader_create_info_.uniform_buf(buffers_sizes_.size(), "float", resource_name);
174
175 float_buffers_.add(resource_name, get_vector_float);
176 buffers_sizes_.add(resource_name, get_size);
177
178 return true;
179 }
180
181 bool addUniform(const char *name,
182 const SizeGetter &get_size,
183 const VectorIntGetter &get_vector_int
184# if OCIO_VERSION_HEX >= 0x02050000
185 ,
186 const unsigned /*maxSize*/
187# endif
188 ) override
189 {
190 /* Check if a resource exists with the same name and assert if it is the case, returning false
191 * indicates failure to add the uniform for the shader creator. */
192 if (!resource_names_.add(std::make_unique<std::string>(name))) {
194 return false;
195 }
196
197 /* Don't use the name argument directly since ShaderCreateInfo only stores references to
198 * resource names, instead, use the name that is stored in resource_names_. */
199 std::string &resource_name = *resource_names_[resource_names_.size() - 1];
200 shader_create_info_.uniform_buf(buffers_sizes_.size(), "int", resource_name);
201
202 int_buffers_.add(name, get_vector_int);
203 buffers_sizes_.add(name, get_size);
204
205 return true;
206 }
207
208# if OCIO_VERSION_HEX >= 0x02050000
209 unsigned
210# else
211 void
212# endif
213 addTexture(const char *texture_name,
214 const char *sampler_name,
215 uint width,
216 uint height,
217 TextureType channel,
218# if OCIO_VERSION_HEX >= 0x02030000
219 OCIO::GpuShaderDesc::TextureDimensions dimensions,
220# endif
221 OCIO::Interpolation interpolation,
222 const float *values) override
223 {
224 /* Check if a resource exists with the same name and assert if it is the case. */
225 if (!resource_names_.add(std::make_unique<std::string>(sampler_name))) {
227 }
228
229 /* Don't use the name argument directly since ShaderCreateInfo only stores references to
230 * resource names, instead, use the name that is stored in resource_names_. */
231 const std::string &resource_name = *resource_names_[resource_names_.size() - 1];
232
233 blender::gpu::Texture *texture;
234 const blender::gpu::TextureFormat base_format =
235 (channel == TEXTURE_RGB_CHANNEL) ? blender::gpu::TextureFormat::SFLOAT_32_32_32 :
236 blender::gpu::TextureFormat::SFLOAT_32;
237 const blender::gpu::TextureFormat texture_format = Result::gpu_texture_format(base_format,
238 precision_);
239 /* A height of 1 indicates a 1D texture according to the OCIO API. */
240# if OCIO_VERSION_HEX >= 0x02030000
241 if (dimensions == OCIO::GpuShaderDesc::TEXTURE_1D)
242# else
243 if (height == 1)
244# endif
245 {
247 texture_name, width, 1, texture_format, GPU_TEXTURE_USAGE_SHADER_READ, values);
248 shader_create_info_.sampler(textures_.size() + 1, ImageType::Float1D, resource_name);
249 }
250 else {
252 texture_name, width, height, 1, texture_format, GPU_TEXTURE_USAGE_SHADER_READ, values);
253 shader_create_info_.sampler(textures_.size() + 1, ImageType::Float2D, resource_name);
254 }
255 GPU_texture_filter_mode(texture, interpolation != OCIO::INTERP_NEAREST);
256
257 textures_.add(sampler_name, texture);
258# if OCIO_VERSION_HEX >= 0x02050000
259 return textures_.size() - 1;
260# endif
261 }
262
263# if OCIO_VERSION_HEX >= 0x02050000
264 unsigned
265# else
266 void
267# endif
268 add3DTexture(const char *texture_name,
269 const char *sampler_name,
270 uint size,
271 OCIO::Interpolation interpolation,
272 const float *values) override
273 {
274 /* Check if a resource exists with the same name and assert if it is the case. */
275 if (!resource_names_.add(std::make_unique<std::string>(sampler_name))) {
277 }
278
279 /* Don't use the name argument directly since ShaderCreateInfo only stores references to
280 * resource names, instead, use the name that is stored in resource_names_. */
281 const std::string &resource_name = *resource_names_[resource_names_.size() - 1];
282 shader_create_info_.sampler(textures_.size() + 1, ImageType::Float3D, resource_name);
283
284 blender::gpu::Texture *texture = GPU_texture_create_3d(
285 texture_name,
286 size,
287 size,
288 size,
289 1,
290 Result::gpu_texture_format(blender::gpu::TextureFormat::SFLOAT_32_32_32, precision_),
292 values);
293 GPU_texture_filter_mode(texture, interpolation != OCIO::INTERP_NEAREST);
294
295 textures_.add(sampler_name, texture);
296# if OCIO_VERSION_HEX >= 0x02050000
297 return textures_.size() - 1;
298# endif
299 }
300
301 /* This gets called before the finalize() method to construct the shader code. We just
302 * concatenate the code except for the declarations section. That's because the ShaderCreateInfo
303 * will add the declaration itself. */
304 void createShaderText(const char * /*parameter_declarations*/,
305# if OCIO_VERSION_HEX >= 0x02050000
306 const char * /*texture_declarations*/,
307# endif
308 const char *helper_methods,
309 const char *function_header,
310 const char *function_body,
311 const char *function_footer) override
312 {
313 shader_code_ += helper_methods;
314 shader_code_ += function_header;
315 shader_code_ += function_body;
316 shader_code_ += function_footer;
317 }
318
319 /* This gets called when all resources were added using the respective addUniform() or
320 * add[3D]Texture() methods and the shader code was generated using the createShaderText()
321 * method. That is, we are ready to complete the ShaderCreateInfo and create a shader from it. */
322 void finalize() override
323 {
324 GpuShaderCreator::finalize();
325
326 shader_create_info_.local_group_size(16, 16);
327 shader_create_info_.sampler(0, ImageType::Float2D, input_sampler_name());
328 shader_create_info_.image(0,
330 Qualifier::write,
331 ImageReadWriteType::Float2D,
333 shader_create_info_.compute_source("gpu_shader_compositor_ocio_processor.glsl");
334 shader_create_info_.compute_source_generated += GPU_shader_preprocess_source(shader_code_);
335
336 GPUShaderCreateInfo *info = reinterpret_cast<GPUShaderCreateInfo *>(&shader_create_info_);
337 shader_ = GPU_shader_create_from_info(info);
338 }
339
340 gpu::Shader *bind_shader_and_resources()
341 {
342 if (!shader_) {
343 return nullptr;
344 }
345
346 GPU_shader_bind(shader_);
347
348 for (auto item : float_uniforms_.items()) {
349 GPU_shader_uniform_1f(shader_, item.key.c_str(), item.value());
350 }
351
352 for (auto item : boolean_uniforms_.items()) {
353 GPU_shader_uniform_1b(shader_, item.key.c_str(), item.value());
354 }
355
356 for (auto item : vector_uniforms_.items()) {
357 GPU_shader_uniform_3fv(shader_, item.key.c_str(), item.value().data());
358 }
359
360 for (auto item : float_buffers_.items()) {
361 gpu::UniformBuf *buffer = GPU_uniformbuf_create_ex(
362 buffers_sizes_.lookup(item.key)(), item.value(), item.key.c_str());
363 const int ubo_location = GPU_shader_get_ubo_binding(shader_, item.key.c_str());
364 GPU_uniformbuf_bind(buffer, ubo_location);
365 uniform_buffers_.append(buffer);
366 }
367
368 for (auto item : int_buffers_.items()) {
369 gpu::UniformBuf *buffer = GPU_uniformbuf_create_ex(
370 buffers_sizes_.lookup(item.key)(), item.value(), item.key.c_str());
371 const int ubo_location = GPU_shader_get_ubo_binding(shader_, item.key.c_str());
372 GPU_uniformbuf_bind(buffer, ubo_location);
373 uniform_buffers_.append(buffer);
374 }
375
376 for (auto item : textures_.items()) {
377 const int texture_image_unit = GPU_shader_get_sampler_binding(shader_, item.key.c_str());
378 GPU_texture_bind(item.value, texture_image_unit);
379 }
380
381 return shader_;
382 }
383
385 {
386 for (gpu::UniformBuf *buffer : uniform_buffers_) {
387 GPU_uniformbuf_unbind(buffer);
388 GPU_uniformbuf_free(buffer);
389 }
390
391 for (blender::gpu::Texture *texture : textures_.values()) {
393 }
394
396 }
397
398 const char *input_sampler_name()
399 {
400 return "input_tx";
401 }
402
403 const char *output_image_name()
404 {
405 return "output_img";
406 }
407
408 ~GPUShaderCreator() override
409 {
410 for (blender::gpu::Texture *texture : textures_.values()) {
412 }
413
414 GPU_shader_free(shader_);
415 }
416
417 private:
418 /* The processor shader and the ShaderCreateInfo used to construct it. Constructed and
419 * initialized in the finalize() method. */
420 gpu::Shader *shader_ = nullptr;
421 ShaderCreateInfo shader_create_info_ = ShaderCreateInfo("OCIO Processor");
422
423 /* Stores the generated OCIOMain function as well as a number of helper functions. Initialized in
424 * the createShaderText() method. */
425 std::string shader_code_;
426
427 /* Maps that associates the name of a uniform with a getter function that returns its value.
428 * Initialized in the respective addUniform() methods. */
429 Map<std::string, DoubleGetter> float_uniforms_;
430 Map<std::string, BoolGetter> boolean_uniforms_;
431 Map<std::string, Float3Getter> vector_uniforms_;
432
433 /* Maps that associates the name of uniform buffer objects with a getter function that returns
434 * its values. Initialized in the respective addUniform() methods. */
435 Map<std::string, VectorFloatGetter> float_buffers_;
436 Map<std::string, VectorIntGetter> int_buffers_;
437
438 /* A map that associates the name of uniform buffer objects with a getter functions that returns
439 * its number of elements. Initialized in the respective addUniform() methods. */
440 Map<std::string, SizeGetter> buffers_sizes_;
441
442 /* A map that associates the name of a sampler with its corresponding texture. Initialized in the
443 * addTexture() and add3DTexture() methods. */
444 Map<std::string, blender::gpu::Texture *> textures_;
445
446 /* A vector set that stores the names of all the resources used by the shader. This is used to:
447 * 1. Check for name collisions when adding new resources.
448 * 2. Store the resource names throughout the construction of the shader since the
449 * ShaderCreateInfo class only stores references to resources names. */
450 VectorSet<std::unique_ptr<std::string>> resource_names_;
451
452 /* A vectors that stores the created uniform buffers when bind_shader_and_resources() is called,
453 * so that they can be properly unbound and freed in the unbind_shader_and_resources() method. */
454 Vector<gpu::UniformBuf *> uniform_buffers_;
455
456# if OCIO_VERSION_HEX >= 0x02030000
457 /* Allow creating 1D textures, or only use 2D textures. */
458 bool allow_texture_1D_ = true;
459# endif
460
461 /* The precision of the OCIO resources as well as the output image. */
462 ResultPrecision precision_;
463};
464
465#else
466
467/* A stub implementation in case OCIO is disabled at build time. */
469 public:
470 static std::shared_ptr<GPUShaderCreator> Create(ResultPrecision /*precision*/)
471 {
472 return std::make_shared<GPUShaderCreator>();
473 }
474
476 {
477 return nullptr;
478 }
479
481
482 const char *input_sampler_name()
483 {
484 return nullptr;
485 }
486
487 const char *output_image_name()
488 {
489 return nullptr;
490 }
491};
492
493#endif
494
495/* ------------------------------------------------------------------------------------------------
496 * OCIO Color Space Conversion Shader Key.
497 */
498
504
509
512{
513 return a.source == b.source && a.target == b.target && a.config_cache_id == b.config_cache_id;
514}
515
516/* --------------------------------------------------------------------
517 * OCIO Color Space Conversion Shader.
518 */
519
521 std::string source,
522 std::string target)
523{
524 /* Create a GPU shader creator and construct it based on the transforms in the default GPU
525 * processor. */
526 shader_creator_ = GPUShaderCreator::Create(context.get_precision());
527
528#if defined(WITH_OPENCOLORIO)
529 /* Get a GPU processor that transforms the source color space to the target color space. */
530 try {
531 OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig();
532 OCIO::ConstProcessorRcPtr processor = config->getProcessor(source.c_str(), target.c_str());
533 OCIO::ConstGPUProcessorRcPtr gpu_processor = processor->getDefaultGPUProcessor();
534
535 auto ocio_shader_creator = std::static_pointer_cast<OCIO::GpuShaderCreator>(shader_creator_);
536 gpu_processor->extractGpuShaderInfo(ocio_shader_creator);
537 }
538 catch (const OCIO::Exception &e) {
539 CLOG_ERROR(&LOG, "Failed to create OpenColorIO shader: %s", e.what());
540 }
541#else
542 UNUSED_VARS(source, target);
544#endif
545}
546
548{
549 return shader_creator_->bind_shader_and_resources();
550}
551
553{
554 shader_creator_->unbind_shader_and_resources();
555}
556
558{
559 return shader_creator_->input_sampler_name();
560}
561
563{
564 return shader_creator_->output_image_name();
565}
566
567/* --------------------------------------------------------------------
568 * OCIO Color Space Conversion Shader Container.
569 */
570
572{
573 /* First, delete all resources that are no longer needed. */
574 map_.remove_if([](auto item) { return !item.value->needed; });
575
576 /* Second, reset the needed status of the remaining resources to false to ready them to track
577 * their needed status for the next evaluation. */
578 for (auto &value : map_.values()) {
579 value->needed = false;
580 }
581}
582
584 std::string source,
585 std::string target)
586{
587#if defined(WITH_OPENCOLORIO)
588 /* Use the config cache ID in the cache key in case the configuration changed at runtime. */
589 std::string config_cache_id = OCIO::GetCurrentConfig()->getCacheID();
590#else
591 std::string config_cache_id;
592#endif
593
594 const OCIOColorSpaceConversionShaderKey key(source, target, config_cache_id);
595
596 OCIOColorSpaceConversionShader &shader = *map_.lookup_or_add_cb(key, [&]() {
597 return std::make_unique<OCIOColorSpaceConversionShader>(context, source, target);
598 });
599
600 shader.needed = true;
601 return shader;
602}
603
604/* ------------------------------------------------------------------------------------------------
605 * OCIO To Display Shader Key.
606 */
607
609 const ColorManagedViewSettings &view_settings,
610 const bool inverse,
611 const std::string &config_cache_id)
612 : display_device(display_settings.display_device),
613 view_transform(view_settings.view_transform),
614 look(view_settings.look),
617{
618}
619
626
628{
629 return a.display_device == b.display_device && a.view_transform == b.view_transform &&
630 a.look == b.look && a.inverse == b.inverse && a.config_cache_id == b.config_cache_id;
631}
632
633/* --------------------------------------------------------------------
634 * OCIO To Display Shader.
635 */
636
638 const ColorManagedDisplaySettings &display_settings,
639 const ColorManagedViewSettings &view_settings,
640 const bool inverse)
641{
642 /* Create a GPU shader creator and construct it based on the transforms in the default GPU
643 * processor. */
644 shader_creator_ = GPUShaderCreator::Create(context.get_precision());
645
646#if defined(WITH_OPENCOLORIO)
647 /* Get a GPU processor that transforms the display_device color space to the view_transform color
648 * space. */
649 try {
650 OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig();
651
652 OCIO::TransformRcPtr group = ocio::create_ocio_display_transform(
653 config,
654 display_settings.display_device,
655 view_settings.view_transform,
656 view_settings.look,
657 "scene_linear");
658
659 if (inverse) {
660 group->setDirection(OCIO::TRANSFORM_DIR_INVERSE);
661 }
662
663 OCIO::ConstProcessorRcPtr processor = config->getProcessor(group);
664 OCIO::ConstGPUProcessorRcPtr gpu_processor = processor->getDefaultGPUProcessor();
665
666 auto ocio_shader_creator = std::static_pointer_cast<OCIO::GpuShaderCreator>(shader_creator_);
667 gpu_processor->extractGpuShaderInfo(ocio_shader_creator);
668 }
669 catch (const OCIO::Exception &e) {
670 CLOG_ERROR(&LOG, "Failed to create OpenColorIO shader: %s", e.what());
671 }
672#else
673 UNUSED_VARS(display_settings, view_settings, inverse);
674#endif
675}
676
678{
679 return shader_creator_->bind_shader_and_resources();
680}
681
683{
684 shader_creator_->unbind_shader_and_resources();
685}
686
688{
689 return shader_creator_->input_sampler_name();
690}
691
693{
694 return shader_creator_->output_image_name();
695}
696
697/* --------------------------------------------------------------------
698 * OCIO To Display Shader Container.
699 */
700
702{
703 /* First, delete all resources that are no longer needed. */
704 map_.remove_if([](auto item) { return !item.value->needed; });
705
706 /* Second, reset the needed status of the remaining resources to false to ready them to
707 * track their needed status for the next evaluation. */
708 for (auto &value : map_.values()) {
709 value->needed = false;
710 }
711}
712
714 Context &context,
715 const ColorManagedDisplaySettings &display_settings,
716 const ColorManagedViewSettings &view_settings,
717 const bool inverse)
718{
719#if defined(WITH_OPENCOLORIO)
720 /* Use the config cache ID in the cache key in case the configuration changed at runtime. */
721 std::string config_cache_id = OCIO::GetCurrentConfig()->getCacheID();
722#else
723 std::string config_cache_id;
724#endif
725
726 const OCIOToDisplayShaderKey key(display_settings, view_settings, inverse, config_cache_id);
727
728 OCIOToDisplayShader &shader = *map_.lookup_or_add_cb(key, [&]() {
729 return std::make_unique<OCIOToDisplayShader>(
730 context, display_settings, view_settings, inverse);
731 });
732
733 shader.needed = true;
734 return shader;
735}
736
737} // namespace blender::compositor
#define BLI_assert_unreachable()
Definition BLI_assert.h:93
unsigned int uint
#define UNUSED_VARS(...)
#define CLOG_ERROR(clg_ref,...)
Definition CLG_log.h:188
int GPU_max_texture_size()
int GPU_shader_get_ubo_binding(blender::gpu::Shader *shader, const char *name)
void GPU_shader_uniform_1b(blender::gpu::Shader *sh, const char *name, bool value)
void GPU_shader_uniform_1f(blender::gpu::Shader *sh, const char *name, float value)
void GPU_shader_free(blender::gpu::Shader *shader)
blender::gpu::Shader * GPU_shader_create_from_info(const GPUShaderCreateInfo *_info)
int GPU_shader_get_sampler_binding(blender::gpu::Shader *shader, const char *name)
void GPU_shader_uniform_3fv(blender::gpu::Shader *sh, const char *name, const float data[3])
void GPU_shader_bind(blender::gpu::Shader *shader, const blender::gpu::shader::SpecializationConstants *constants_state=nullptr)
std::string GPU_shader_preprocess_source(blender::StringRefNull original)
void GPU_shader_unbind()
void GPU_texture_unbind(blender::gpu::Texture *texture)
@ GPU_TEXTURE_USAGE_SHADER_READ
blender::gpu::Texture * GPU_texture_create_2d(const char *name, int width, int height, int mip_len, blender::gpu::TextureFormat format, eGPUTextureUsage usage, const float *data)
void GPU_texture_filter_mode(blender::gpu::Texture *texture, bool use_filter)
void GPU_texture_bind(blender::gpu::Texture *texture, int unit)
void GPU_texture_free(blender::gpu::Texture *texture)
blender::gpu::Texture * GPU_texture_create_3d(const char *name, int width, int height, int depth, int mip_len, blender::gpu::TextureFormat format, eGPUTextureUsage usage, const void *data)
blender::gpu::Texture * GPU_texture_create_1d(const char *name, int width, int mip_len, blender::gpu::TextureFormat format, eGPUTextureUsage usage, const float *data)
void GPU_uniformbuf_free(blender::gpu::UniformBuf *ubo)
void GPU_uniformbuf_bind(blender::gpu::UniformBuf *ubo, int slot)
void GPU_uniformbuf_unbind(blender::gpu::UniformBuf *ubo)
blender::gpu::UniformBuf * GPU_uniformbuf_create_ex(size_t size, const void *data, const char *name)
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
unsigned long long int uint64_t
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
static std::shared_ptr< GPUShaderCreator > Create(ResultPrecision)
OCIOColorSpaceConversionShader & get(Context &context, std::string source, std::string target)
OCIOColorSpaceConversionShaderKey(const std::string &source, const std::string &target, const std::string &config_cache_id)
OCIOColorSpaceConversionShader(Context &context, std::string source, std::string target)
OCIOToDisplayShader & get(Context &context, const ColorManagedDisplaySettings &display_settings, const ColorManagedViewSettings &view_settings, const bool inverse)
OCIOToDisplayShaderKey(const ColorManagedDisplaySettings &display_settings, const ColorManagedViewSettings &view_settings, const bool inverse, const std::string &config_cache_id)
OCIOToDisplayShader(Context &context, const ColorManagedDisplaySettings &display_settings, const ColorManagedViewSettings &view_settings, const bool inverse)
static blender::gpu::TextureFormat gpu_texture_format(ResultType type, ResultPrecision precision)
Definition result.cc:65
static float3 get_float3(const BL::Array< float, 2 > &array)
MatBase< C, R > inverse(MatBase< C, R >) RET
TEX_TEMPLATE DataVec texture(T, FltCoord, float=0.0f) RET
bool operator==(const BokehKernelKey &a, const BokehKernelKey &b)
uint64_t get_default_hash(const T &v, const Args &...args)
Definition BLI_hash.hh:233
const char * name