15# pragma warning(disable : 4251 4275)
17#include <OpenColorIO/OpenColorIO.h>
28using namespace OCIO_NAMESPACE;
77 GPUTexture *texture =
nullptr;
82 GpuShaderDesc::UniformData
data;
88 std::vector<OCIO_GPULutTexture>
luts;
116 GPUTexture *texture =
nullptr;
156 const std::string &needle,
157 const std::string &other)
160 while ((index = haystack.find(needle, i)) != std::string::npos) {
161 haystack.replace(index, needle.size(), other);
162 i = index + other.size();
168 const GpuShaderDescRcPtr &shaderdesc_to_scene_linear,
169 const GpuShaderDescRcPtr &shaderdesc_to_display,
170 const bool use_curve_mapping)
175 source += shaderdesc_to_scene_linear->getShaderText();
177 source += shaderdesc_to_display->getShaderText();
185 index = source.find(
"uniform ", index);
189 source.replace(index, 2,
"//");
203 source,
"if ( gamma != vec3(1., 1., 1.) )",
"if (! all(equal(gamma, vec3(1., 1., 1.))) )");
206 iface.
smooth(Type::VEC2,
"texCoord_interp");
210 info.
define(
"texture1D",
"texture");
211 info.
define(
"texture2D",
"texture");
212 info.
define(
"texture3D",
"texture");
223 info.
vertex_in(1, Type::VEC2,
"texCoord");
226 info.
vertex_source(
"gpu_shader_display_transform_vert.glsl");
235 if (use_curve_mapping) {
236 info.
define(
"USE_CURVE_MAPPING");
245 ImageType type = (dimensions == 1) ? ImageType::FLOAT_1D :
246 (dimensions == 2) ? ImageType::FLOAT_2D :
249 info.
sampler(slot++, type, texture.sampler_name.c_str());
256 size_t ubo_size = textures.
uniforms.size() *
sizeof(
float) * 4;
257 void *ubo_data_buf = malloc(ubo_size);
261 std::stringstream ss;
262 ss <<
"struct OCIO_GPULutParameters {\n";
267 const GpuShaderDesc::UniformData &data = uniform.data;
268 const char *name = uniform.name.c_str();
271 switch (data.m_type) {
272 case UNIFORM_DOUBLE: {
274 float value =
float(data.m_getDouble());
275 memcpy(ubo_data, &value,
sizeof(
float));
281 int value =
int(data.m_getBool());
282 memcpy(ubo_data, &value,
sizeof(
int));
287 memcpy(ubo_data, data.m_getFloat3().data(),
sizeof(
float) * 3);
289 case UNIFORM_VECTOR_FLOAT:
290 vec_len = data.m_vectorFloat.m_getSize();
291 memcpy(ubo_data, data.m_vectorFloat.m_getVector(),
sizeof(
float) * vec_len);
293 case UNIFORM_VECTOR_INT:
295 vec_len = data.m_vectorInt.m_getSize();
296 memcpy(ubo_data, data.m_vectorInt.m_getVector(),
sizeof(
int) * vec_len);
305 ss <<
" " << prefix <<
"vec4 var" << index <<
";\n";
308 ss <<
"#define " << name <<
" lut_parameters.var" << index <<
"." << suffix <<
"\n";
316 ubo_size, ubo_data_buf,
"OCIO_LutParameters");
323 return (shader.shader !=
nullptr);
333 const GpuShaderDescRcPtr &shader_desc,
337 uniform.
name = shader_desc->getUniform(index, uniform.
data);
338 if (uniform.
data.m_type == UNIFORM_UNKNOWN) {
342 textures.
uniforms.push_back(uniform);
347 const GpuShaderDescRcPtr &shader_desc,
350 const char *texture_name =
nullptr;
351 const char *sampler_name =
nullptr;
352 unsigned int width = 0;
353 unsigned int height = 0;
354 GpuShaderCreator::TextureType channel = GpuShaderCreator::TEXTURE_RGB_CHANNEL;
356#if OCIO_VERSION_HEX >= 0x02030000
358 GpuShaderDesc::TextureDimensions dimensions = GpuShaderDesc::TEXTURE_2D;
359 shader_desc->getTexture(
360 index, texture_name, sampler_name, width, height, channel, dimensions, interpolation);
362 shader_desc->getTexture(
363 index, texture_name, sampler_name, width, height, channel, interpolation);
367 shader_desc->getTextureValues(index, values);
368 if (texture_name ==
nullptr || sampler_name ==
nullptr || width == 0 || height == 0 ||
378#if OCIO_VERSION_HEX < 0x02030000
381 std::string sampler1D_name = std::string(
"sampler1D ") + sampler_name;
382 if (strstr(shader_desc->getShaderText(), sampler1D_name.c_str()) !=
nullptr) {
401 textures.
luts.push_back(lut);
406 const GpuShaderDescRcPtr &shader_desc,
409 const char *texture_name =
nullptr;
410 const char *sampler_name =
nullptr;
411 unsigned int edgelen = 0;
413 shader_desc->get3DTexture(index, texture_name, sampler_name, edgelen, interpolation);
416 shader_desc->get3DTextureValues(index, values);
417 if (texture_name ==
nullptr || sampler_name ==
nullptr || edgelen == 0 || values ==
nullptr) {
439 textures.
luts.push_back(lut);
444 const GpuShaderDescRcPtr &shaderdesc_to_scene_linear,
445 const GpuShaderDescRcPtr &shaderdesc_to_display)
449 textures.
luts.clear();
452 for (
int index = 0; index < shaderdesc_to_scene_linear->getNumUniforms(); index++) {
453 if (!
addGPUUniform(textures, shaderdesc_to_scene_linear, index)) {
457 for (
int index = 0; index < shaderdesc_to_scene_linear->getNumTextures(); index++) {
458 if (!
addGPULut1D2D(textures, shaderdesc_to_scene_linear, index)) {
462 for (
int index = 0; index < shaderdesc_to_scene_linear->getNum3DTextures(); index++) {
463 if (!
addGPULut3D(textures, shaderdesc_to_scene_linear, index)) {
467 for (
int index = 0; index < shaderdesc_to_display->getNumUniforms(); index++) {
468 if (!
addGPUUniform(textures, shaderdesc_to_display, index)) {
472 for (
int index = 0; index < shaderdesc_to_display->getNumTextures(); index++) {
473 if (!
addGPULut1D2D(textures, shaderdesc_to_display, index)) {
477 for (
int index = 0; index < shaderdesc_to_display->getNum3DTextures(); index++) {
478 if (!
addGPULut3D(textures, shaderdesc_to_display, index)) {
495 if (curve_mapping_settings) {
496 int lut_size = curve_mapping_settings->
lut_size;
505 if (curvemap.
texture ==
nullptr || curvemap.
buffer ==
nullptr) {
518 if (curve_mapping_settings ==
nullptr || curvemap.
cache_id == curve_mapping_settings->
cache_id) {
525 const int offset[3] = {0, 0, 0};
526 const int extent[3] = {curve_mapping_settings->
lut_size, 0, 0};
527 const float *pixels = curve_mapping_settings->
lut;
533 for (
int i = 0; i < 4; i++) {
534 data.
range[i] = curve_mapping_settings->
range[i];
535 data.mintable[i] = curve_mapping_settings->
mintable[i];
536 data.ext_in_x[i] = curve_mapping_settings->
ext_in_x[i];
537 data.ext_in_y[i] = curve_mapping_settings->
ext_in_y[i];
538 data.ext_out_x[i] = curve_mapping_settings->
ext_out_x[i];
539 data.ext_out_y[i] = curve_mapping_settings->
ext_out_y[i];
540 data.first_x[i] = curve_mapping_settings->
first_x[i];
541 data.first_y[i] = curve_mapping_settings->
first_y[i];
542 data.last_x[i] = curve_mapping_settings->
last_x[i];
543 data.last_y[i] = curve_mapping_settings->
last_y[i];
545 for (
int i = 0; i < 3; i++) {
546 data.black[i] = curve_mapping_settings->
black[i];
547 data.bwmul[i] = curve_mapping_settings->
bwmul[i];
549 data.lut_size = curve_mapping_settings->
lut_size;
563 bool do_update =
false;
564 if (shader.parameters_buffer ==
nullptr) {
569 if (data.scene_linear_matrix != scene_linear_matrix) {
573 if (data.exponent != exponent) {
574 data.exponent = exponent;
577 if (data.dither != dither) {
578 data.dither = dither;
581 if (
bool(data.use_predivide) != use_predivide) {
582 data.use_predivide = use_predivide;
585 if (
bool(data.use_overlay) != use_overlay) {
586 data.use_overlay = use_overlay;
589 if (
bool(data.use_hdr) != use_hdr) {
590 data.use_hdr = use_hdr;
604bool OCIOImpl::supportGPUShader()
611 OCIO_ConstConfigRcPtr *config,
619 const bool use_curve_mapping = (curve_mapping_settings !=
nullptr);
620 for (std::list<OCIO_GPUDisplayShader>::iterator it =
SHADER_CACHE.begin();
624 if (it->input == input && it->view == view && it->display == display && it->look == look &&
625 it->use_curve_mapping == use_curve_mapping)
645 display_shader.
input = input;
647 display_shader.
display = display;
648 display_shader.
look = look;
650 display_shader.
valid =
false;
667 config, input, ROLE_SCENE_LINEAR);
669 config, ROLE_SCENE_LINEAR, view, display, look, 1.0f, 1.0f, 0.0f, 0.0f,
false,
false);
672 if (processor_to_scene_linear && processor_to_display) {
673 GpuShaderDescRcPtr shaderdesc_to_scene_linear = GpuShaderDesc::CreateShaderDesc();
674 shaderdesc_to_scene_linear->setLanguage(GPU_LANGUAGE_GLSL_1_3);
675 shaderdesc_to_scene_linear->setFunctionName(
"OCIO_to_scene_linear");
676 shaderdesc_to_scene_linear->setResourcePrefix(
"to_scene");
677 (*(ConstProcessorRcPtr *)processor_to_scene_linear)
678 ->getDefaultGPUProcessor()
679 ->extractGpuShaderInfo(shaderdesc_to_scene_linear);
680 shaderdesc_to_scene_linear->finalize();
682 GpuShaderDescRcPtr shaderdesc_to_display = GpuShaderDesc::CreateShaderDesc();
683 shaderdesc_to_display->setLanguage(GPU_LANGUAGE_GLSL_1_3);
684 shaderdesc_to_display->setFunctionName(
"OCIO_to_display");
685 shaderdesc_to_display->setResourcePrefix(
"to_display");
686 (*(ConstProcessorRcPtr *)processor_to_display)
687 ->getDefaultGPUProcessor()
688 ->extractGpuShaderInfo(shaderdesc_to_display);
689 shaderdesc_to_display->finalize();
693 display_shader.
textures, shaderdesc_to_scene_linear, shaderdesc_to_display) &&
697 shaderdesc_to_scene_linear,
698 shaderdesc_to_display,
701 display_shader.
valid =
true;
706 if (processor_to_scene_linear) {
709 if (processor_to_display) {
713 return display_shader;
726bool OCIOImpl::gpuDisplayShaderBind(OCIO_ConstConfigRcPtr *config,
733 const float exponent,
735 const float temperature,
737 const bool use_predivide,
738 const bool use_overlay,
740 const bool use_white_balance)
744 config, input, view, display, look, curve_mapping_settings);
745 if (!display_shader.
valid) {
755 if (curve_mapping_settings) {
767 for (
int i = 0; i < textures.
luts.size(); i++) {
775 float3x3 matrix = float3x3::identity() * scale;
776 if (use_white_balance) {
779 configGetXYZtoSceneLinear(config, xyz_to_scene.
ptr());
786 matrix *= xyz_to_scene;
789 matrix *= scene_to_xyz;
792 shader, exponent,
float4x4(matrix), dither, use_predivide, use_overlay, use_hdr);
801void OCIOImpl::gpuDisplayShaderUnbind()
806void OCIOImpl::gpuCacheFree()
void BLI_kdtree_nd_ free(KDTree *tree)
GPUShader * GPU_shader_create_from_info(const GPUShaderCreateInfo *_info)
void GPU_shader_free(GPUShader *shader)
void GPU_texture_bind(GPUTexture *texture, int unit)
GPUTexture * GPU_texture_create_2d(const char *name, int width, int height, int mip_len, eGPUTextureFormat format, eGPUTextureUsage usage, const float *data)
GPUTexture * GPU_texture_create_1d(const char *name, int width, int mip_len, eGPUTextureFormat format, eGPUTextureUsage usage, const float *data)
void GPU_texture_free(GPUTexture *texture)
int GPU_texture_dimensions(const GPUTexture *texture)
GPUTexture * GPU_texture_create_error(int dimension, bool array)
void GPU_texture_extend_mode(GPUTexture *texture, GPUSamplerExtendMode extend_mode)
@ GPU_TEXTURE_USAGE_SHADER_READ
@ GPU_SAMPLER_EXTEND_MODE_EXTEND
void GPU_texture_update_sub(GPUTexture *texture, eGPUDataFormat data_format, const void *pixels, int offset_x, int offset_y, int offset_z, int width, int height, int depth)
GPUTexture * GPU_texture_create_3d(const char *name, int width, int height, int depth, int mip_len, eGPUTextureFormat format, eGPUTextureUsage usage, const void *data)
void GPU_texture_filter_mode(GPUTexture *texture, bool use_filter)
Read Guarded memory(de)allocation.
struct GPUShader GPUShader
constexpr StringRef substr(int64_t start, int64_t size) const
draw_view in_light_buf[] float
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
float3 whitepoint_from_temp_tint(float temperature, float tint)
CartesianBasis invert(const CartesianBasis &basis)
float3x3 chromatic_adaption_matrix(const float3 &from_XYZ, const float3 &to_XYZ)
OCIO_ConstProcessorRcPtr * OCIO_createDisplayProcessor(OCIO_ConstConfigRcPtr *config, const char *input, const char *view, const char *display, const char *look, const float scale, const float exponent, const float temperature, const float tint, const bool use_white_balance, const bool inverse)
OCIO_ConstProcessorRcPtr * OCIO_configGetProcessorWithNames(OCIO_ConstConfigRcPtr *config, const char *srcName, const char *dstName)
void OCIO_processorRelease(OCIO_ConstProcessorRcPtr *processor)
static bool addGPULut3D(OCIO_GPUTextures &textures, const GpuShaderDescRcPtr &shader_desc, int index)
static bool createGPUCurveMapping(OCIO_GPUCurveMappping &curvemap, OCIO_CurveMappingSettings *curve_mapping_settings)
static void updateGPUDisplayParameters(OCIO_GPUShader &shader, float exponent, float4x4 scene_linear_matrix, float dither, bool use_predivide, bool use_overlay, bool use_hdr)
static bool addGPUUniform(OCIO_GPUTextures &textures, const GpuShaderDescRcPtr &shader_desc, int index)
@ UNIFORMBUF_SLOT_CURVEMAP
@ UNIFORMBUF_SLOT_DISPLAY
static bool createGPUShader(OCIO_GPUShader &shader, OCIO_GPUTextures &textures, const GpuShaderDescRcPtr &shaderdesc_to_scene_linear, const GpuShaderDescRcPtr &shaderdesc_to_display, const bool use_curve_mapping)
@ TEXTURE_SLOT_CURVE_MAPPING
@ TEXTURE_SLOT_LUTS_OFFSET
static const int SHADER_CACHE_MAX_SIZE
static bool createGPUTextures(OCIO_GPUTextures &textures, const GpuShaderDescRcPtr &shaderdesc_to_scene_linear, const GpuShaderDescRcPtr &shaderdesc_to_display)
static void updateGPUCurveMapping(OCIO_GPUCurveMappping &curvemap, OCIO_CurveMappingSettings *curve_mapping_settings)
static bool addGPULut1D2D(OCIO_GPUTextures &textures, const GpuShaderDescRcPtr &shader_desc, int index)
std::list< OCIO_GPUDisplayShader > SHADER_CACHE
static void string_replace_all(std::string &haystack, const std::string &needle, const std::string &other)
static OCIO_GPUDisplayShader & getGPUDisplayShader(OCIO_ConstConfigRcPtr *config, const char *input, const char *view, const char *display, const char *look, OCIO_CurveMappingSettings *curve_mapping_settings)
int use_extend_extrapolate
OCIO_GPUCurveMappping curvemap
OCIO_GPUTextures textures
float4x4 scene_linear_matrix
GPUUniformBuf * parameters_buffer
OCIO_GPUParameters parameters
std::vector< OCIO_GPUUniform > uniforms
GPUUniformBuf * uniforms_buffer
std::vector< OCIO_GPULutTexture > luts
const c_style_mat & ptr() const
Describe inputs & outputs, stage interfaces, resources and sources of a shader. If all data is correc...
Self & fragment_source(StringRefNull filename)
std::string fragment_source_generated
Self & vertex_in(int slot, Type type, StringRefNull name)
Self & push_constant(Type type, StringRefNull name, int array_size=0)
Self & typedef_source(StringRefNull filename)
Self & fragment_out(int slot, Type type, StringRefNull name, DualBlend blend=DualBlend::NONE, int raster_order_group=-1)
Self & vertex_out(StageInterfaceInfo &interface)
std::string typedef_source_generated
Self & vertex_source(StringRefNull filename)
Self & sampler(int slot, ImageType type, StringRefNull name, Frequency freq=Frequency::PASS, GPUSamplerState sampler=GPUSamplerState::internal_sampler())
Self & uniform_buf(int slot, StringRefNull type_name, StringRefNull name, Frequency freq=Frequency::PASS)
Self & define(StringRefNull name, StringRefNull value="")
Self & smooth(Type type, StringRefNull _name)