diff options
-rw-r--r-- | intern/opencolorio/CMakeLists.txt | 36 | ||||
-rw-r--r-- | intern/opencolorio/gpu_shader_display_transform_frag.glsl (renamed from intern/opencolorio/gpu_shader_display_transform.glsl) | 109 | ||||
-rw-r--r-- | intern/opencolorio/gpu_shader_display_transform_vert.glsl (renamed from intern/opencolorio/gpu_shader_display_transform_vertex.glsl) | 6 | ||||
-rw-r--r-- | intern/opencolorio/ocio_impl_glsl.cc | 323 | ||||
-rw-r--r-- | intern/opencolorio/ocio_shader_shared.hh | 41 | ||||
-rw-r--r-- | source/blender/gpu/CMakeLists.txt | 9 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_shader_dependency.cc | 6 |
7 files changed, 328 insertions, 202 deletions
diff --git a/intern/opencolorio/CMakeLists.txt b/intern/opencolorio/CMakeLists.txt index dfccb9301ac..be6ccc5c2c5 100644 --- a/intern/opencolorio/CMakeLists.txt +++ b/intern/opencolorio/CMakeLists.txt @@ -7,6 +7,7 @@ set(INC ../guardedalloc ../../source/blender/blenlib ../../source/blender/gpu + ../../source/blender/gpu/intern ../../source/blender/makesdna ) @@ -20,6 +21,7 @@ set(SRC ocio_capi.h ocio_impl.h + ocio_shader_shared.hh ) set(LIB @@ -56,8 +58,38 @@ if(WITH_OPENCOLORIO) ) endif() - data_to_c_simple(gpu_shader_display_transform.glsl SRC) - data_to_c_simple(gpu_shader_display_transform_vertex.glsl SRC) + set(GLSL_SRC + gpu_shader_display_transform_vert.glsl + gpu_shader_display_transform_frag.glsl + + ocio_shader_shared.hh + ) + + set(GLSL_C) + foreach(GLSL_FILE ${GLSL_SRC}) + data_to_c_simple(${GLSL_FILE} GLSL_C) + endforeach() + + blender_add_lib(bf_ocio_shaders "${GLSL_C}" "" "" "") + + list(APPEND LIB + bf_ocio_shaders + ) + + set(GLSL_SOURCE_CONTENT "") + foreach(GLSL_FILE ${GLSL_SRC}) + get_filename_component(GLSL_FILE_NAME ${GLSL_FILE} NAME) + string(REPLACE "." "_" GLSL_FILE_NAME_UNDERSCORES ${GLSL_FILE_NAME}) + string(APPEND GLSL_SOURCE_CONTENT "SHADER_SOURCE\(datatoc_${GLSL_FILE_NAME_UNDERSCORES}, \"${GLSL_FILE_NAME}\", \"${GLSL_FILE}\"\)\n") + endforeach() + + set(glsl_source_list_file "${CMAKE_CURRENT_BINARY_DIR}/glsl_ocio_source_list.h") + file(GENERATE OUTPUT ${glsl_source_list_file} CONTENT "${GLSL_SOURCE_CONTENT}") + list(APPEND SRC ${glsl_source_list_file}) + list(APPEND INC ${CMAKE_CURRENT_BINARY_DIR}) + + target_include_directories(bf_ocio_shaders PUBLIC ${CMAKE_CURRENT_BINARY_DIR}) + endif() diff --git a/intern/opencolorio/gpu_shader_display_transform.glsl b/intern/opencolorio/gpu_shader_display_transform_frag.glsl index f5a7a7bf45d..3c2352c13ba 100644 --- a/intern/opencolorio/gpu_shader_display_transform.glsl +++ b/intern/opencolorio/gpu_shader_display_transform_frag.glsl @@ -1,39 +1,10 @@ /* Blender OpenColorIO implementation */ -uniform sampler2D image_texture; -uniform sampler2D overlay_texture; - -uniform float dither; -uniform float scale; -uniform float exponent; -uniform bool predivide; -uniform bool overlay; +/* -------------------------------------------------------------------- */ +/** \name Curve Mapping Implementation + * \{ */ #ifdef USE_CURVE_MAPPING -uniform sampler1D curve_mapping_texture; - -layout(std140) uniform OCIO_GPUCurveMappingParameters -{ - /* Curve mapping parameters - * - * See documentation for OCIO_CurveMappingSettings to get fields descriptions. - * (this ones pretty much copies stuff from C structure.) - */ - vec4 curve_mapping_mintable; - vec4 curve_mapping_range; - vec4 curve_mapping_ext_in_x; - vec4 curve_mapping_ext_in_y; - vec4 curve_mapping_ext_out_x; - vec4 curve_mapping_ext_out_y; - vec4 curve_mapping_first_x; - vec4 curve_mapping_first_y; - vec4 curve_mapping_last_x; - vec4 curve_mapping_last_y; - vec4 curve_mapping_black; - vec4 curve_mapping_bwmul; - int curve_mapping_lut_size; - int curve_mapping_use_extend_extrapolate; -}; float read_curve_mapping(int table, int index) { @@ -43,27 +14,27 @@ float read_curve_mapping(int table, int index) float curvemap_calc_extend(int table, float x, vec2 first, vec2 last) { if (x <= first[0]) { - if (curve_mapping_use_extend_extrapolate == 0) { + if (curve_mapping.use_extend_extrapolate == 0) { /* horizontal extrapolation */ return first[1]; } else { - float fac = (curve_mapping_ext_in_x[table] != 0.0) ? - ((x - first[0]) / curve_mapping_ext_in_x[table]) : + float fac = (curve_mapping.ext_in_x[table] != 0.0) ? + ((x - first[0]) / curve_mapping.ext_in_x[table]) : 10000.0; - return first[1] + curve_mapping_ext_in_y[table] * fac; + return first[1] + curve_mapping.ext_in_y[table] * fac; } } else if (x >= last[0]) { - if (curve_mapping_use_extend_extrapolate == 0) { + if (curve_mapping.use_extend_extrapolate == 0) { /* horizontal extrapolation */ return last[1]; } else { - float fac = (curve_mapping_ext_out_x[table] != 0.0) ? - ((x - last[0]) / curve_mapping_ext_out_x[table]) : + float fac = (curve_mapping.ext_out_x[table] != 0.0) ? + ((x - last[0]) / curve_mapping.ext_out_x[table]) : -10000.0; - return last[1] + curve_mapping_ext_out_y[table] * fac; + return last[1] + curve_mapping.ext_out_y[table] * fac; } } return 0.0; @@ -71,10 +42,10 @@ float curvemap_calc_extend(int table, float x, vec2 first, vec2 last) float curvemap_evaluateF(int table, float value) { - float mintable_ = curve_mapping_mintable[table]; - float range = curve_mapping_range[table]; + float mintable_ = curve_mapping.mintable[table]; + float range = curve_mapping.range[table]; float mintable = 0.0; - int CM_TABLE = curve_mapping_lut_size - 1; + int CM_TABLE = curve_mapping.lut_size - 1; float fi; int i; @@ -87,8 +58,8 @@ float curvemap_evaluateF(int table, float value) if (fi < 0.0 || fi > float(CM_TABLE)) { return curvemap_calc_extend(table, value, - vec2(curve_mapping_first_x[table], curve_mapping_first_y[table]), - vec2(curve_mapping_last_x[table], curve_mapping_last_y[table])); + vec2(curve_mapping.first_x[table], curve_mapping.first_y[table]), + vec2(curve_mapping.last_x[table], curve_mapping.last_y[table])); } else { if (i < 0) { @@ -106,7 +77,7 @@ float curvemap_evaluateF(int table, float value) vec4 curvemapping_evaluate_premulRGBF(vec4 col) { - col.rgb = (col.rgb - curve_mapping_black.rgb) * curve_mapping_bwmul.rgb; + col.rgb = (col.rgb - curve_mapping.black.rgb) * curve_mapping.bwmul.rgb; vec4 result; result.r = curvemap_evaluateF(0, col.r); @@ -115,8 +86,15 @@ vec4 curvemapping_evaluate_premulRGBF(vec4 col) result.a = col.a; return result; } + #endif /* USE_CURVE_MAPPING */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Dithering + * \{ */ + /* Using a triangle distribution which gives a more final uniform noise. * See Banding in Games:A Noisy Rant(revision 5) Mikkel Gjøl, Playdead (slide 27) */ /* GPUs are rounding before writing to framebuffer so we center the distribution around 0.0. */ @@ -135,23 +113,33 @@ float dither_random_value(vec2 co) vec2 round_to_pixel(sampler2D tex, vec2 uv) { - vec2 size = textureSize(tex, 0); - return vec2(ivec2(uv * size)) / size; + vec2 size = vec2(textureSize(tex, 0)); + return floor(uv * size) / size; } vec4 apply_dither(vec4 col, vec2 uv) { - col.rgb += dither_random_value(uv) * 0.0033 * dither; + col.rgb += dither_random_value(uv) * 0.0033 * parameters.dither; return col; } -vec4 OCIO_ProcessColor(vec4 col, vec4 col_overlay, vec2 noise_uv) +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Main Processing + * \{ */ + +/* Prototypes: Implementation is generaterd and defined after. */ +vec4 OCIO_to_scene_linear(vec4 pixel); +vec4 OCIO_to_display(vec4 pixel); + +vec4 OCIO_ProcessColor(vec4 col, vec4 col_overlay) { #ifdef USE_CURVE_MAPPING col = curvemapping_evaluate_premulRGBF(col); #endif - if (predivide) { + if (parameters.use_predivide) { if (col.a > 0.0 && col.a < 1.0) { col.rgb *= 1.0 / col.a; } @@ -166,7 +154,7 @@ vec4 OCIO_ProcessColor(vec4 col, vec4 col_overlay, vec2 noise_uv) col = OCIO_to_scene_linear(col); /* Apply exposure in scene linear. */ - col.rgb *= scale; + col.rgb *= parameters.scale; /* Convert to display space. */ col = OCIO_to_display(col); @@ -177,34 +165,31 @@ vec4 OCIO_ProcessColor(vec4 col, vec4 col_overlay, vec2 noise_uv) * i.e: The linear color space w.r.t. display chromaticity and radiometry. * We separate the colormanagement process into two steps to be able to * merge UI using alpha blending in the correct color space. */ - if (overlay) { - col.rgb = pow(col.rgb, vec3(exponent * 2.2)); + if (parameters.use_overlay) { + col.rgb = pow(col.rgb, vec3(parameters.exponent * 2.2)); col = clamp(col, 0.0, 1.0); col *= 1.0 - col_overlay.a; col += col_overlay; /* Assumed unassociated alpha. */ col.rgb = pow(col.rgb, vec3(1.0 / 2.2)); } else { - col.rgb = pow(col.rgb, vec3(exponent)); + col.rgb = pow(col.rgb, vec3(parameters.exponent)); } - if (dither > 0.0) { + if (parameters.dither > 0.0) { + vec2 noise_uv = round_to_pixel(image_texture, texCoord_interp.st); col = apply_dither(col, noise_uv); } return col; } -/* ------------------------------------------------------------------------ */ - -in vec2 texCoord_interp; -out vec4 fragColor; +/** \} */ void main() { vec4 col = texture(image_texture, texCoord_interp.st); vec4 col_overlay = texture(overlay_texture, texCoord_interp.st); - vec2 noise_uv = round_to_pixel(image_texture, texCoord_interp.st); - fragColor = OCIO_ProcessColor(col, col_overlay, noise_uv); + fragColor = OCIO_ProcessColor(col, col_overlay); } diff --git a/intern/opencolorio/gpu_shader_display_transform_vertex.glsl b/intern/opencolorio/gpu_shader_display_transform_vert.glsl index 8cf9628b06b..06788be11de 100644 --- a/intern/opencolorio/gpu_shader_display_transform_vertex.glsl +++ b/intern/opencolorio/gpu_shader_display_transform_vert.glsl @@ -1,10 +1,4 @@ -uniform mat4 ModelViewProjectionMatrix; - -in vec2 texCoord; -in vec2 pos; -out vec2 texCoord_interp; - void main() { gl_Position = ModelViewProjectionMatrix * vec4(pos.xy, 0.0f, 1.0f); diff --git a/intern/opencolorio/ocio_impl_glsl.cc b/intern/opencolorio/ocio_impl_glsl.cc index 09803cd8038..47c965dbc8e 100644 --- a/intern/opencolorio/ocio_impl_glsl.cc +++ b/intern/opencolorio/ocio_impl_glsl.cc @@ -21,14 +21,14 @@ #include "GPU_shader.h" #include "GPU_uniform_buffer.h" +#include "gpu_shader_create_info.hh" + using namespace OCIO_NAMESPACE; #include "MEM_guardedalloc.h" #include "ocio_impl.h" - -extern "C" char datatoc_gpu_shader_display_transform_glsl[]; -extern "C" char datatoc_gpu_shader_display_transform_vertex_glsl[]; +#include "ocio_shader_shared.hh" /* **** OpenGL drawing routines using GLSL for color space transform ***** */ @@ -39,41 +39,19 @@ enum OCIO_GPUTextureSlots { TEXTURE_SLOT_LUTS_OFFSET = 3, }; -/* Curve mapping parameters - * - * See documentation for OCIO_CurveMappingSettings to get fields descriptions. - * (this ones pretty much copies stuff from C structure.) - */ -struct OCIO_GPUCurveMappingParameters { - float curve_mapping_mintable[4]; - float curve_mapping_range[4]; - float curve_mapping_ext_in_x[4]; - float curve_mapping_ext_in_y[4]; - float curve_mapping_ext_out_x[4]; - float curve_mapping_ext_out_y[4]; - float curve_mapping_first_x[4]; - float curve_mapping_first_y[4]; - float curve_mapping_last_x[4]; - float curve_mapping_last_y[4]; - float curve_mapping_black[4]; - float curve_mapping_bwmul[4]; - int curve_mapping_lut_size; - int curve_mapping_use_extend_extrapolate; - int _pad[2]; - /** WARNING: Needs to be 16byte aligned. Used as UBO data. */ +enum OCIO_GPUUniformBufSlots { + UNIFORMBUF_SLOT_DISPLAY = 0, + UNIFORMBUF_SLOT_CURVEMAP = 1, + UNIFORMBUF_SLOT_LUTS = 2, }; struct OCIO_GPUShader { /* GPU shader. */ struct GPUShader *shader = nullptr; - /** Uniform locations. */ - int scale_loc = 0; - int exponent_loc = 0; - int dither_loc = 0; - int overlay_loc = 0; - int predivide_loc = 0; - int ubo_bind = 0; + /** Uniform parameters. */ + OCIO_GPUParameters parameters = {}; + GPUUniformBuf *parameters_buffer = nullptr; /* Destructor. */ ~OCIO_GPUShader() @@ -81,6 +59,9 @@ struct OCIO_GPUShader { if (shader) { GPU_shader_free(shader); } + if (parameters_buffer) { + GPU_uniformbuf_free(parameters_buffer); + } } }; @@ -103,6 +84,7 @@ struct OCIO_GPUTextures { /* Uniforms */ std::vector<OCIO_GPUUniform> uniforms; + GPUUniformBuf *uniforms_buffer = nullptr; /* Destructor. */ ~OCIO_GPUTextures() @@ -113,6 +95,9 @@ struct OCIO_GPUTextures { if (dummy) { GPU_texture_free(dummy); } + if (uniforms_buffer) { + GPU_uniformbuf_free(uniforms_buffer); + } } }; @@ -165,97 +150,134 @@ static bool createGPUShader(OCIO_GPUShader &shader, const GpuShaderDescRcPtr &shaderdesc_to_display, const bool use_curve_mapping) { - std::ostringstream os; - { - /* Fragment shader */ + using namespace blender::gpu::shader; - /* Work around OpenColorIO not supporting latest GLSL yet. */ - os << "#define texture2D texture\n"; - os << "#define texture3D texture\n"; + std::string source; + source += shaderdesc_to_scene_linear->getShaderText(); + source += "\n"; + source += shaderdesc_to_display->getShaderText(); + source += "\n"; - if (use_curve_mapping) { - os << "#define USE_CURVE_MAPPING\n"; + { + /* Replace all uniform declarations by a comment. + * This avoids double declarations from the backend. */ + size_t index = 0; + while (true) { + index = source.find("uniform ", index); + if (index == -1) { + break; + } + source.replace(index, 2, "//"); + index += 2; } - - os << shaderdesc_to_scene_linear->getShaderText() << "\n"; - os << shaderdesc_to_display->getShaderText() << "\n"; - - os << datatoc_gpu_shader_display_transform_glsl; } - shader.shader = GPU_shader_create(datatoc_gpu_shader_display_transform_vertex_glsl, - os.str().c_str(), - nullptr, - nullptr, - nullptr, - "OCIOShader"); - - if (shader.shader == nullptr) { - return false; - } - - shader.scale_loc = GPU_shader_get_uniform(shader.shader, "scale"); - shader.exponent_loc = GPU_shader_get_uniform(shader.shader, "exponent"); - shader.dither_loc = GPU_shader_get_uniform(shader.shader, "dither"); - shader.overlay_loc = GPU_shader_get_uniform(shader.shader, "overlay"); - shader.predivide_loc = GPU_shader_get_uniform(shader.shader, "predivide"); - shader.ubo_bind = GPU_shader_get_uniform_block_binding(shader.shader, - "OCIO_GPUCurveMappingParameters"); - - GPU_shader_bind(shader.shader); - - /* Set texture bind point uniform once. This is saved by the shader. */ - GPUShader *sh = shader.shader; - GPU_shader_uniform_int(sh, GPU_shader_get_uniform(sh, "image_texture"), TEXTURE_SLOT_IMAGE); - GPU_shader_uniform_int(sh, GPU_shader_get_uniform(sh, "overlay_texture"), TEXTURE_SLOT_OVERLAY); + StageInterfaceInfo iface("OCIO_Interface", ""); + iface.smooth(Type::VEC2, "texCoord_interp"); + + ShaderCreateInfo info("OCIO_Display"); + /* Work around OpenColorIO not supporting latest GLSL yet. */ + info.define("texture2D", "texture"); + info.define("texture3D", "texture"); + info.typedef_source("ocio_shader_shared.hh"); + info.sampler(TEXTURE_SLOT_IMAGE, ImageType::FLOAT_2D, "image_texture"); + info.sampler(TEXTURE_SLOT_OVERLAY, ImageType::FLOAT_2D, "overlay_texture"); + info.uniform_buf(UNIFORMBUF_SLOT_DISPLAY, "OCIO_GPUParameters", "parameters"); + info.push_constant(Type::MAT4, "ModelViewProjectionMatrix"); + info.vertex_in(0, Type::VEC2, "pos"); + info.vertex_in(1, Type::VEC2, "texCoord"); + info.vertex_out(iface); + info.fragment_out(0, Type::VEC4, "fragColor"); + info.vertex_source("gpu_shader_display_transform_vert.glsl"); + info.fragment_source("gpu_shader_display_transform_frag.glsl"); + info.fragment_source_generated = source; if (use_curve_mapping) { - GPU_shader_uniform_int( - sh, GPU_shader_get_uniform(sh, "curve_mapping_texture"), TEXTURE_SLOT_CURVE_MAPPING); + info.define("USE_CURVE_MAPPING"); + info.uniform_buf(UNIFORMBUF_SLOT_CURVEMAP, "OCIO_GPUCurveMappingParameters", "curve_mapping"); + info.sampler(TEXTURE_SLOT_CURVE_MAPPING, ImageType::FLOAT_1D, "curve_mapping_texture"); } /* Set LUT textures. */ - for (int i = 0; i < textures.luts.size(); i++) { - GPU_shader_uniform_int(sh, - GPU_shader_get_uniform(sh, textures.luts[i].sampler_name.c_str()), - TEXTURE_SLOT_LUTS_OFFSET + i); - } + int slot = TEXTURE_SLOT_LUTS_OFFSET; + for (OCIO_GPULutTexture &texture : textures.luts) { + ImageType type = GPU_texture_dimensions(texture.texture) == 2 ? ImageType::FLOAT_2D : + ImageType::FLOAT_3D; + info.sampler(slot++, type, texture.sampler_name.c_str()); + } + + /* Set LUT uniforms. */ + if (!textures.uniforms.empty()) { + /* NOTE: For simplicity, we pad everything to size of vec4 avoiding sorting and alignment + * issues. It is unlikely that this becomes a real issue. */ + size_t ubo_size = textures.uniforms.size() * sizeof(float) * 4; + void *ubo_data_buf = malloc(ubo_size); + + uint32_t *ubo_data = reinterpret_cast<uint32_t *>(ubo_data_buf); + + std::stringstream ss; + ss << "struct OCIO_GPULutParameters {\n"; + + int index = 0; + for (OCIO_GPUUniform &uniform : textures.uniforms) { + index += 1; + const GpuShaderDesc::UniformData &data = uniform.data; + const char *name = uniform.name.c_str(); + char prefix = ' '; + int vec_len; + switch (data.m_type) { + case UNIFORM_DOUBLE: { + vec_len = 1; + float value = float(data.m_getDouble()); + memcpy(ubo_data, &value, sizeof(float)); + break; + } + case UNIFORM_BOOL: { + prefix = 'b'; + vec_len = 1; + int value = int(data.m_getBool()); + memcpy(ubo_data, &value, sizeof(int)); + break; + } + case UNIFORM_FLOAT3: + vec_len = 3; + memcpy(ubo_data, data.m_getFloat3().data(), sizeof(float) * 3); + break; + case UNIFORM_VECTOR_FLOAT: + vec_len = data.m_vectorFloat.m_getSize(); + memcpy(ubo_data, data.m_vectorFloat.m_getVector(), sizeof(float) * vec_len); + break; + case UNIFORM_VECTOR_INT: + prefix = 'i'; + vec_len = data.m_vectorInt.m_getSize(); + memcpy(ubo_data, data.m_vectorInt.m_getVector(), sizeof(int) * vec_len); + break; + default: + continue; + } + /* Align every member to 16bytes. */ + ubo_data += 4; + /* Use a generic variable name because some GLSL compilers can interpret the preprocessor + * define as recursive. */ + ss << " " << prefix << "vec4 var" << index << ";\n"; + /* Use a define to keep the generated code working. */ + blender::StringRef suffix = blender::StringRefNull("xyzw").substr(0, vec_len); + ss << "#define " << name << " lut_parameters.var" << index << "." << suffix << "\n"; + } + ss << "};\n"; + info.typedef_source_generated = ss.str(); - /* Set uniforms. */ - for (OCIO_GPUUniform &uniform : textures.uniforms) { - const GpuShaderDesc::UniformData &data = uniform.data; - const char *name = uniform.name.c_str(); + info.uniform_buf(UNIFORMBUF_SLOT_LUTS, "OCIO_GPULutParameters", "lut_parameters"); - if (data.m_getDouble) { - GPU_shader_uniform_1f(sh, name, (float)data.m_getDouble()); - } - else if (data.m_getBool) { - GPU_shader_uniform_1f(sh, name, (float)(data.m_getBool() ? 1.0f : 0.0f)); - } - else if (data.m_getFloat3) { - GPU_shader_uniform_3f(sh, - name, - (float)data.m_getFloat3()[0], - (float)data.m_getFloat3()[1], - (float)data.m_getFloat3()[2]); - } - else if (data.m_vectorFloat.m_getSize && data.m_vectorFloat.m_getVector) { - GPU_shader_uniform_vector(sh, - GPU_shader_get_uniform(sh, name), - (int)data.m_vectorFloat.m_getSize(), - 1, - (float *)data.m_vectorFloat.m_getVector()); - } - else if (data.m_vectorInt.m_getSize && data.m_vectorInt.m_getVector) { - GPU_shader_uniform_vector_int(sh, - GPU_shader_get_uniform(sh, name), - (int)data.m_vectorInt.m_getSize(), - 1, - (int *)data.m_vectorInt.m_getVector()); - } + textures.uniforms_buffer = GPU_uniformbuf_create_ex( + ubo_size, ubo_data_buf, "OCIO_LutParameters"); + + free(ubo_data_buf); } - return true; + shader.shader = GPU_shader_create_from_info(reinterpret_cast<GPUShaderCreateInfo *>(&info)); + + return (shader.shader != nullptr); } /** \} */ @@ -438,27 +460,65 @@ static void updateGPUCurveMapping(OCIO_GPUCurveMappping &curvemap, /* Update uniforms. */ OCIO_GPUCurveMappingParameters data; for (int i = 0; i < 4; i++) { - data.curve_mapping_range[i] = curve_mapping_settings->range[i]; - data.curve_mapping_mintable[i] = curve_mapping_settings->mintable[i]; - data.curve_mapping_ext_in_x[i] = curve_mapping_settings->ext_in_x[i]; - data.curve_mapping_ext_in_y[i] = curve_mapping_settings->ext_in_y[i]; - data.curve_mapping_ext_out_x[i] = curve_mapping_settings->ext_out_x[i]; - data.curve_mapping_ext_out_y[i] = curve_mapping_settings->ext_out_y[i]; - data.curve_mapping_first_x[i] = curve_mapping_settings->first_x[i]; - data.curve_mapping_first_y[i] = curve_mapping_settings->first_y[i]; - data.curve_mapping_last_x[i] = curve_mapping_settings->last_x[i]; - data.curve_mapping_last_y[i] = curve_mapping_settings->last_y[i]; + data.range[i] = curve_mapping_settings->range[i]; + data.mintable[i] = curve_mapping_settings->mintable[i]; + data.ext_in_x[i] = curve_mapping_settings->ext_in_x[i]; + data.ext_in_y[i] = curve_mapping_settings->ext_in_y[i]; + data.ext_out_x[i] = curve_mapping_settings->ext_out_x[i]; + data.ext_out_y[i] = curve_mapping_settings->ext_out_y[i]; + data.first_x[i] = curve_mapping_settings->first_x[i]; + data.first_y[i] = curve_mapping_settings->first_y[i]; + data.last_x[i] = curve_mapping_settings->last_x[i]; + data.last_y[i] = curve_mapping_settings->last_y[i]; } for (int i = 0; i < 3; i++) { - data.curve_mapping_black[i] = curve_mapping_settings->black[i]; - data.curve_mapping_bwmul[i] = curve_mapping_settings->bwmul[i]; + data.black[i] = curve_mapping_settings->black[i]; + data.bwmul[i] = curve_mapping_settings->bwmul[i]; } - data.curve_mapping_lut_size = curve_mapping_settings->lut_size; - data.curve_mapping_use_extend_extrapolate = curve_mapping_settings->use_extend_extrapolate; + data.lut_size = curve_mapping_settings->lut_size; + data.use_extend_extrapolate = curve_mapping_settings->use_extend_extrapolate; GPU_uniformbuf_update(curvemap.buffer, &data); } +static void updateGPUDisplayParameters(OCIO_GPUShader &shader, + float scale, + float exponent, + float dither, + bool use_predivide, + bool use_overlay) +{ + bool do_update = false; + if (shader.parameters_buffer == nullptr) { + shader.parameters_buffer = GPU_uniformbuf_create(sizeof(OCIO_GPUParameters)); + do_update = true; + } + OCIO_GPUParameters &data = shader.parameters; + if (data.scale != scale) { + data.scale = scale; + do_update = true; + } + if (data.exponent != exponent) { + data.exponent = exponent; + do_update = true; + } + if (data.dither != dither) { + data.dither = dither; + do_update = true; + } + if (data.use_predivide != use_predivide) { + data.use_predivide = use_predivide; + do_update = true; + } + if (data.use_overlay != use_overlay) { + data.use_overlay = use_overlay; + do_update = true; + } + if (do_update) { + GPU_uniformbuf_update(shader.parameters_buffer, &data); + } +} + /** \} */ /* -------------------------------------------------------------------- */ @@ -609,7 +669,7 @@ bool OCIOImpl::gpuDisplayShaderBind(OCIO_ConstConfigRcPtr *config, /* Update and bind curve mapping data. */ if (curve_mapping_settings) { updateGPUCurveMapping(curvemap, curve_mapping_settings); - GPU_uniformbuf_bind(curvemap.buffer, shader.ubo_bind); + GPU_uniformbuf_bind(curvemap.buffer, UNIFORMBUF_SLOT_CURVEMAP); GPU_texture_bind(curvemap.texture, TEXTURE_SLOT_CURVE_MAPPING); } @@ -623,17 +683,16 @@ bool OCIOImpl::gpuDisplayShaderBind(OCIO_ConstConfigRcPtr *config, GPU_texture_bind(textures.luts[i].texture, TEXTURE_SLOT_LUTS_OFFSET + i); } + if (textures.uniforms_buffer) { + GPU_uniformbuf_bind(textures.uniforms_buffer, UNIFORMBUF_SLOT_LUTS); + } + + updateGPUDisplayParameters(shader, scale, exponent, dither, use_predivide, use_overlay); + GPU_uniformbuf_bind(shader.parameters_buffer, UNIFORMBUF_SLOT_DISPLAY); + /* TODO(fclem): remove remains of IMM. */ immBindShader(shader.shader); - /* Bind Shader and set uniforms. */ - // GPU_shader_bind(shader.shader); - GPU_shader_uniform_float(shader.shader, shader.scale_loc, scale); - GPU_shader_uniform_float(shader.shader, shader.exponent_loc, exponent); - GPU_shader_uniform_float(shader.shader, shader.dither_loc, dither); - GPU_shader_uniform_int(shader.shader, shader.overlay_loc, use_overlay); - GPU_shader_uniform_int(shader.shader, shader.predivide_loc, use_predivide); - return true; } diff --git a/intern/opencolorio/ocio_shader_shared.hh b/intern/opencolorio/ocio_shader_shared.hh new file mode 100644 index 00000000000..c7045217196 --- /dev/null +++ b/intern/opencolorio/ocio_shader_shared.hh @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later + * Copyright 2022 Blender Foundation. All rights reserved. */ + +#ifndef GPU_SHADER +# include "GPU_shader_shared_utils.h" +#endif + +struct OCIO_GPUCurveMappingParameters { + /* Curve mapping parameters + * + * See documentation for OCIO_CurveMappingSettings to get fields descriptions. + * (this ones pretty much copies stuff from C structure.) + */ + float4 mintable; + float4 range; + float4 ext_in_x; + float4 ext_in_y; + float4 ext_out_x; + float4 ext_out_y; + float4 first_x; + float4 first_y; + float4 last_x; + float4 last_y; + float4 black; + float4 bwmul; + int lut_size; + int use_extend_extrapolate; + int _pad0; + int _pad1; +}; + +struct OCIO_GPUParameters { + float dither; + float scale; + float exponent; + bool1 use_predivide; + bool1 use_overlay; + int _pad0; + int _pad1; + int _pad2; +}; diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index e883a12a5b2..f2e189777f0 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -452,12 +452,21 @@ if(WITH_IMAGE_DDS) add_definitions(-DWITH_DDS) endif() +if(WITH_OPENCOLORIO) + add_definitions(-DWITH_OCIO) +endif() + blender_add_lib(bf_gpu "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") target_link_libraries(bf_gpu PUBLIC bf_draw_shaders bf_gpu_shaders ) +if(WITH_OPENCOLORIO) + target_link_libraries(bf_gpu PUBLIC bf_ocio_shaders) +endif() + + if(CXX_WARN_NO_SUGGEST_OVERRIDE) target_compile_options(bf_gpu PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-Wsuggest-override>) endif() diff --git a/source/blender/gpu/intern/gpu_shader_dependency.cc b/source/blender/gpu/intern/gpu_shader_dependency.cc index 8a842ef4d7c..5b7df035acd 100644 --- a/source/blender/gpu/intern/gpu_shader_dependency.cc +++ b/source/blender/gpu/intern/gpu_shader_dependency.cc @@ -21,6 +21,9 @@ extern "C" { #define SHADER_SOURCE(datatoc, filename, filepath) extern char datatoc[]; #include "glsl_draw_source_list.h" #include "glsl_gpu_source_list.h" +#ifdef WITH_OCIO +# include "glsl_ocio_source_list.h" +#endif #undef SHADER_SOURCE } @@ -348,6 +351,9 @@ void gpu_shader_dependency_init() g_sources->add_new(filename, new GPUSource(filepath, filename, datatoc)); #include "glsl_draw_source_list.h" #include "glsl_gpu_source_list.h" +#ifdef WITH_OCIO +# include "glsl_ocio_source_list.h" +#endif #undef SHADER_SOURCE int errors = 0; |